Ejemplo n.º 1
0
Value Entry::shelter_storm(const Position& pos, Square ksq) {

    const Color Them = (Us == WHITE ? BLACK : WHITE);
    const Bitboard Edges = (FileABB | FileHBB) & (Rank2BB | Rank3BB);

    Bitboard b = pos.pieces(PAWN) & (in_front_bb(Us, rank_of(ksq)) | rank_bb(ksq));
    Bitboard ourPawns = b & pos.pieces(Us);
    Bitboard theirPawns = b & pos.pieces(Them);
    Value safety = MaxSafetyBonus;
    File kf = std::max(FILE_B, std::min(FILE_G, file_of(ksq)));

    for (File f = kf - File(1); f <= kf + File(1); ++f)
    {
        b = ourPawns & file_bb(f);
        Rank rkUs = b ? relative_rank(Us, backmost_sq(Us, b)) : RANK_1;

        b  = theirPawns & file_bb(f);
        Rank rkThem = b ? relative_rank(Us, frontmost_sq(Them, b)) : RANK_1;

        if (   (Edges & make_square(f, rkThem))
                && file_of(ksq) == f
                && relative_rank(Us, ksq) == rkThem - 1)
            safety += 200;
        else
            safety -=  ShelterWeakness[rkUs]
                       + StormDanger[rkUs   == RANK_1   ? 0 :
                                     rkThem != rkUs + 1 ? 1 : 2][rkThem];
    }

    return safety;
}
Ejemplo n.º 2
0
Value Entry::shelter_storm(const Position& pos, Square ksq) {

  const Color Them = (Us == WHITE ? BLACK : WHITE);

  enum { NoFriendlyPawn, Unblocked, BlockedByPawn, BlockedByKing };

  Bitboard b = pos.pieces(PAWN) & (in_front_bb(Us, rank_of(ksq)) | rank_bb(ksq));
  Bitboard ourPawns = b & pos.pieces(Us);
  Bitboard theirPawns = b & pos.pieces(Them);
  Value safety = MaxSafetyBonus;
  File center = std::max(FILE_B, std::min(FILE_G, file_of(ksq)));

  for (File f = center - File(1); f <= center + File(1); ++f)
  {
      b = ourPawns & file_bb(f);
      Rank rkUs = b ? relative_rank(Us, backmost_sq(Us, b)) : RANK_1;

      b  = theirPawns & file_bb(f);
      Rank rkThem = b ? relative_rank(Us, frontmost_sq(Them, b)) : RANK_1;

      safety -=  ShelterWeakness[std::min(f, FILE_H - f)][rkUs]
               + StormDanger
                 [f == file_of(ksq) && rkThem == relative_rank(Us, ksq) + 1 ? BlockedByKing  :
                  rkUs   == RANK_1                                          ? NoFriendlyPawn :
                  rkThem == rkUs + 1                                        ? BlockedByPawn  : Unblocked]
                 [std::min(f, FILE_H - f)][rkThem];
  }

  return safety;
}
Ejemplo n.º 3
0
Value Entry::evaluate_shelter(const Position& pos, Square ksq) {

  constexpr Color     Them = (Us == WHITE ? BLACK : WHITE);
  constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH);
  constexpr Bitboard  BlockRanks = (Us == WHITE ? Rank1BB | Rank2BB : Rank8BB | Rank7BB);

  Bitboard b = pos.pieces(PAWN) & ~forward_ranks_bb(Them, ksq);
  Bitboard ourPawns = b & pos.pieces(Us);
  Bitboard theirPawns = b & pos.pieces(Them);

  Value safety = (shift<Down>(theirPawns) & (FileABB | FileHBB) & BlockRanks & ksq) ?
                 Value(374) : Value(5);

  File center = std::max(FILE_B, std::min(FILE_G, file_of(ksq)));
  for (File f = File(center - 1); f <= File(center + 1); ++f)
  {
      b = ourPawns & file_bb(f);
      int ourRank = b ? relative_rank(Us, backmost_sq(Us, b)) : 0;

      b = theirPawns & file_bb(f);
      int theirRank = b ? relative_rank(Us, frontmost_sq(Them, b)) : 0;

      int d = std::min(f, ~f);
      safety += ShelterStrength[d][ourRank];
      safety -= (ourRank && (ourRank == theirRank - 1)) ? BlockedStorm[theirRank]
                                                        : UnblockedStorm[d][theirRank];
  }

  return safety;
}
Ejemplo n.º 4
0
Value Entry::shelter_storm(const Position& pos, Square ksq) {

    const Color Them = (Us == WHITE ? BLACK : WHITE);

    Value safety = MaxSafetyBonus;
    Bitboard b = pos.pieces(PAWN) & (in_front_bb(Us, rank_of(ksq)) | rank_bb(ksq));
    Bitboard ourPawns = b & pos.pieces(Us);
    Bitboard theirPawns = b & pos.pieces(Them);
    Rank rkUs, rkThem;
    File kf = std::max(FILE_B, std::min(FILE_G, file_of(ksq)));

    for (int f = kf - 1; f <= kf + 1; f++)
    {
        b = ourPawns & FileBB[f];
        rkUs = b ? relative_rank(Us, backmost_sq(Us, b)) : RANK_1;
        safety -= ShelterWeakness[rkUs];

        b  = theirPawns & FileBB[f];
        rkThem = b ? relative_rank(Us, frontmost_sq(Them, b)) : RANK_1;
        safety -= StormDanger[rkUs == RANK_1 ? 0 : rkThem == rkUs + 1 ? 2 : 1][rkThem];
    }

    return safety;
}
Ejemplo n.º 5
0
Value Eval::evaluate(const Position& pos) {

  assert(!pos.checkers());

  EvalInfo ei;
  Score score, mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };

  // Initialize score by reading the incrementally updated scores included in
  // the position object (material + piece square tables). Score is computed
  // internally from the white point of view.
  score = pos.psq_score();

  // Probe the material hash table
  ei.me = Material::probe(pos);
  score += ei.me->imbalance();

  // If we have a specialized evaluation function for the current material
  // configuration, call it and return.
  if (ei.me->specialized_eval_exists())
      return ei.me->evaluate(pos);

  // Probe the pawn hash table
  ei.pi = Pawns::probe(pos);
  score += ei.pi->pawns_score();

  // Initialize attack and king safety bitboards
  ei.attackedBy[WHITE][ALL_PIECES] = ei.attackedBy[BLACK][ALL_PIECES] = 0;
  eval_init<WHITE>(pos, ei);
  eval_init<BLACK>(pos, ei);

  // Pawns blocked or on ranks 2 and 3 will be excluded from the mobility area
  Bitboard blockedPawns[] = {
    pos.pieces(WHITE, PAWN) & (shift_bb<DELTA_S>(pos.pieces()) | Rank2BB | Rank3BB),
    pos.pieces(BLACK, PAWN) & (shift_bb<DELTA_N>(pos.pieces()) | Rank7BB | Rank6BB)
  };

  // Do not include in mobility area squares protected by enemy pawns, or occupied
  // by our blocked pawns or king.
  Bitboard mobilityArea[] = {
    ~(ei.attackedBy[BLACK][PAWN] | blockedPawns[WHITE] | pos.square<KING>(WHITE)),
    ~(ei.attackedBy[WHITE][PAWN] | blockedPawns[BLACK] | pos.square<KING>(BLACK))
  };

  // Evaluate all pieces but king and pawns
  score += evaluate_pieces<DoTrace>(pos, ei, mobility, mobilityArea);
  score += mobility[WHITE] - mobility[BLACK];

  // Evaluate kings after all other pieces because we need full attack
  // information when computing the king safety evaluation.
  score +=  evaluate_king<WHITE, DoTrace>(pos, ei)
          - evaluate_king<BLACK, DoTrace>(pos, ei);

  // Evaluate tactical threats, we need full attack information including king
  score +=  evaluate_threats<WHITE, DoTrace>(pos, ei)
          - evaluate_threats<BLACK, DoTrace>(pos, ei);

  // Evaluate passed pawns, we need full attack information including king
  score +=  evaluate_passed_pawns<WHITE, DoTrace>(pos, ei)
          - evaluate_passed_pawns<BLACK, DoTrace>(pos, ei);

  // If both sides have only pawns, score for potential unstoppable pawns
  if (!pos.non_pawn_material(WHITE) && !pos.non_pawn_material(BLACK))
  {
      Bitboard b;
      if ((b = ei.pi->passed_pawns(WHITE)) != 0)
          score += Unstoppable * int(relative_rank(WHITE, frontmost_sq(WHITE, b)));

      if ((b = ei.pi->passed_pawns(BLACK)) != 0)
          score -= Unstoppable * int(relative_rank(BLACK, frontmost_sq(BLACK, b)));
  }

  // Evaluate space for both sides, only during opening
  if (pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) >= 12222)
      score +=  evaluate_space<WHITE>(pos, ei)
              - evaluate_space<BLACK>(pos, ei);

  // Evaluate position potential for the winning side
  score += evaluate_initiative(pos, ei.pi->pawn_asymmetry(), eg_value(score));

  // Evaluate scale factor for the winning side
  ScaleFactor sf = evaluate_scale_factor(pos, ei, eg_value(score));

  // Interpolate between a middlegame and a (scaled by 'sf') endgame score
  Value v =  mg_value(score) * int(ei.me->game_phase())
           + eg_value(score) * int(PHASE_MIDGAME - ei.me->game_phase()) * sf / SCALE_FACTOR_NORMAL;

  v /= int(PHASE_MIDGAME);

  // In case of tracing add all remaining individual evaluation terms
  if (DoTrace)
  {
      Trace::add(MATERIAL, pos.psq_score());
      Trace::add(IMBALANCE, ei.me->imbalance());
      Trace::add(PAWN, ei.pi->pawns_score());
      Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
      Trace::add(SPACE, evaluate_space<WHITE>(pos, ei)
                      , evaluate_space<BLACK>(pos, ei));
      Trace::add(TOTAL, score);
  }

  return (pos.side_to_move() == WHITE ? v : -v) + Eval::Tempo; // Side to move point of view
}