Example #1
0
ScaleFactor ScalingFunction<KPsK>::apply(const Position& pos) const {

  assert(pos.non_pawn_material(strongerSide) == VALUE_ZERO);
  assert(pos.piece_count(strongerSide, PAWN) >= 2);
  assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
  assert(pos.piece_count(weakerSide, PAWN) == 0);

  Square ksq = pos.king_square(weakerSide);
  Bitboard pawns = pos.pieces(PAWN, strongerSide);

  // Are all pawns on the 'a' file?
  if ((pawns & ~FileABB) == EmptyBoardBB)
  {
      // Does the defending king block the pawns?
      if (   square_distance(ksq, relative_square(strongerSide, SQ_A8)) <= 1
          || (   square_file(ksq) == FILE_A
              && (in_front_bb(strongerSide, ksq) & pawns) == EmptyBoardBB))
          return SCALE_FACTOR_ZERO;
  }
  // Are all pawns on the 'h' file?
  else if ((pawns & ~FileHBB) == EmptyBoardBB)
  {
    // Does the defending king block the pawns?
    if (   square_distance(ksq, relative_square(strongerSide, SQ_H8)) <= 1
        || (   square_file(ksq) == FILE_H
            && (in_front_bb(strongerSide, ksq) & pawns) == EmptyBoardBB))
        return SCALE_FACTOR_ZERO;
  }
  return SCALE_FACTOR_NONE;
}
Score Entry::do_king_safety(const Position& pos, Square ksq) {

  kingSquares[Us] = ksq;
  castlingRights[Us] = pos.can_castle(Us);
  int minKingPawnDistance = 0;
#ifdef THREECHECK
  CheckCount checks = pos.is_three_check() ? pos.checks_given(~Us) : CHECKS_0;
#endif

  Bitboard pawns = pos.pieces(Us, PAWN);
  if (pawns)
      while (!(DistanceRingBB[ksq][minKingPawnDistance++] & pawns)) {}

  Value bonus = shelter_storm<Us>(pos, ksq);

  // If we can castle use the bonus after the castling if it is bigger
  if (pos.can_castle(MakeCastling<Us, KING_SIDE>::right))
      bonus = std::max(bonus, shelter_storm<Us>(pos, relative_square(Us, SQ_G1)));

  if (pos.can_castle(MakeCastling<Us, QUEEN_SIDE>::right))
      bonus = std::max(bonus, shelter_storm<Us>(pos, relative_square(Us, SQ_C1)));

#ifdef THREECHECK
  // Decrease score when checks have been taken
  return make_score(bonus, (-16 * minKingPawnDistance) + (-2 * checks));
#else
  return make_score(bonus, -16 * minKingPawnDistance);
#endif
}
Example #3
0
Score Entry::do_king_safety(const Position& pos, Square ksq) {

  kingSquares[Us] = ksq;
  castlingRights[Us] = pos.can_castle(Us);
  int minKingPawnDistance = 0;

  Bitboard pawns = pos.pieces(Us, PAWN);
  if (pawns)
      while (!(DistanceRingBB[ksq][minKingPawnDistance++] & pawns)) {}

  Value bonus = shelter_storm<Us>(pos, ksq);

  // If we can castle use the bonus after the castling if it is bigger
  if (pos.can_castle(MakeCastling<Us, KING_SIDE>::right))
      bonus = std::max(bonus, shelter_storm<Us>(pos, relative_square(Us, SQ_G1)));

  if (pos.can_castle(MakeCastling<Us, QUEEN_SIDE>::right))
      bonus = std::max(bonus, shelter_storm<Us>(pos, relative_square(Us, SQ_C1)));

  return make_score(bonus, -16 * minKingPawnDistance);
}
Example #4
0
ScaleFactor ScalingFunction<KNPK>::apply(const Position& pos) const {

  assert(pos.non_pawn_material(strongerSide) == KnightValueMidgame);
  assert(pos.piece_count(strongerSide, KNIGHT) == 1);
  assert(pos.piece_count(strongerSide, PAWN) == 1);
  assert(pos.non_pawn_material(weakerSide) == VALUE_ZERO);
  assert(pos.piece_count(weakerSide, PAWN) == 0);

  Square pawnSq = pos.piece_list(strongerSide, PAWN, 0);
  Square weakerKingSq = pos.king_square(weakerSide);

  if (   pawnSq == relative_square(strongerSide, SQ_A7)
      && square_distance(weakerKingSq, relative_square(strongerSide, SQ_A8)) <= 1)
      return SCALE_FACTOR_ZERO;

  if (   pawnSq == relative_square(strongerSide, SQ_H7)
      && square_distance(weakerKingSq, relative_square(strongerSide, SQ_H8)) <= 1)
      return SCALE_FACTOR_ZERO;

  return SCALE_FACTOR_NONE;
}
Example #5
0
Score Entry::do_king_safety(const Position& pos) {

  Square ksq = pos.square<KING>(Us);
  kingSquares[Us] = ksq;
  castlingRights[Us] = pos.can_castle(Us);
  int minKingPawnDistance = 0;

  Bitboard pawns = pos.pieces(Us, PAWN);
  if (pawns)
      while (!(DistanceRingBB[ksq][++minKingPawnDistance] & pawns)) {}

  Value bonus = evaluate_shelter<Us>(pos, ksq);

  // If we can castle use the bonus after the castling if it is bigger
  if (pos.can_castle(Us | KING_SIDE))
      bonus = std::max(bonus, evaluate_shelter<Us>(pos, relative_square(Us, SQ_G1)));

  if (pos.can_castle(Us | QUEEN_SIDE))
      bonus = std::max(bonus, evaluate_shelter<Us>(pos, relative_square(Us, SQ_C1)));

  return make_score(bonus, -16 * minKingPawnDistance);
}
Example #6
0
Score Entry::update_safety(const Position& pos, Square ksq) {

    kingSquares[Us] = ksq;
    castleRights[Us] = pos.can_castle(Us);
    minKPdistance[Us] = 0;

    Bitboard pawns = pos.pieces(Us, PAWN);
    if (pawns)
        while (!(DistanceRingsBB[ksq][minKPdistance[Us]++] & pawns)) {}

    if (relative_rank(Us, ksq) > RANK_4)
        return kingSafety[Us] = make_score(0, -16 * minKPdistance[Us]);

    Value bonus = shelter_storm<Us>(pos, ksq);

    // If we can castle use the bonus after the castle if is bigger
    if (pos.can_castle(make_castle_right(Us, KING_SIDE)))
        bonus = std::max(bonus, shelter_storm<Us>(pos, relative_square(Us, SQ_G1)));

    if (pos.can_castle(make_castle_right(Us, QUEEN_SIDE)))
        bonus = std::max(bonus, shelter_storm<Us>(pos, relative_square(Us, SQ_C1)));

    return kingSafety[Us] = make_score(bonus, -16 * minKPdistance[Us]);
}
Example #7
0
ScaleFactor ScalingFunction<KBPsK>::apply(const Position& pos) const {

  assert(pos.non_pawn_material(strongerSide) == BishopValueMidgame);
  assert(pos.piece_count(strongerSide, BISHOP) == 1);
  assert(pos.piece_count(strongerSide, PAWN) >= 1);

  // No assertions about the material of weakerSide, because we want draws to
  // be detected even when the weaker side has some pawns.

  Bitboard pawns = pos.pieces(PAWN, strongerSide);
  File pawnFile = square_file(pos.piece_list(strongerSide, PAWN, 0));

  // All pawns are on a single rook file ?
  if (   (pawnFile == FILE_A || pawnFile == FILE_H)
      && (pawns & ~file_bb(pawnFile)) == EmptyBoardBB)
  {
      Square bishopSq = pos.piece_list(strongerSide, BISHOP, 0);
      Square queeningSq = relative_square(strongerSide, make_square(pawnFile, RANK_8));
      Square kingSq = pos.king_square(weakerSide);

      if (  !same_color_squares(queeningSq, bishopSq)
          && file_distance(square_file(kingSq), pawnFile) <= 1)
      {
          // The bishop has the wrong color, and the defending king is on the
          // file of the pawn(s) or the neighboring file. Find the rank of the
          // frontmost pawn.
          Rank rank;
          if (strongerSide == WHITE)
          {
              for (rank = RANK_7; (rank_bb(rank) & pawns) == EmptyBoardBB; rank--) {}
              assert(rank >= RANK_2 && rank <= RANK_7);
          }
          else
          {
              for (rank = RANK_2; (rank_bb(rank) & pawns) == EmptyBoardBB; rank++) {}
              rank = Rank(rank ^ 7);  // HACK to get the relative rank
              assert(rank >= RANK_2 && rank <= RANK_7);
          }
          // If the defending king has distance 1 to the promotion square or
          // is placed somewhere in front of the pawn, it's a draw.
          if (   square_distance(kingSq, queeningSq) <= 1
              || relative_rank(strongerSide, kingSq) >= rank)
              return SCALE_FACTOR_ZERO;
      }
  }
  return SCALE_FACTOR_NONE;
}