// by the king safety evaluation. This consists of the squares directly
// adjacent to the king, and the three (or two, for a king on an edge file)
// squares two ranks in front of the king. For instance, if black's king
// by the king safety evaluation. This consists of the squares directly
// adjacent to the king, and the three (or two, for a king on an edge file)
// squares two ranks in front of the king. For instance, if black's king
- // is on g8, kingZone[WHITE] is a bitboard containing the squares f8, h8,
+ // is on g8, kingRing[BLACK] is a bitboard containing the squares f8, h8,
// f7, g7, h7, f6, g6 and h6.
// f7, g7, h7, f6, g6 and h6.
int kingAttackersCount[2];
// kingAttackersWeight[color] is the sum of the "weight" of the pieces of the
int kingAttackersCount[2];
// kingAttackersWeight[color] is the sum of the "weight" of the pieces of the
// weights of the individual piece types are given by the variables
// QueenAttackWeight, RookAttackWeight, BishopAttackWeight and
// KnightAttackWeight in evaluate.cpp
// weights of the individual piece types are given by the variables
// QueenAttackWeight, RookAttackWeight, BishopAttackWeight and
// KnightAttackWeight in evaluate.cpp
- S(248, 271), S(252, 259), S(46, 0), S(247, 0), S(259, 0)
+ S(252, 344), S(216, 266), S(46, 0), S(247, 0), S(259, 0)
{ S(0, 0), S(15, 39), S(15, 39), S(15, 39), S(15, 39), S( 0, 0) } // QUEEN
};
{ S(0, 0), S(15, 39), S(15, 39), S(15, 39), S(15, 39), S( 0, 0) } // QUEEN
};
S(0, 0), S(0, 0), S(56, 70), S(56, 70), S(76, 99), S(86, 118)
};
S(0, 0), S(0, 0), S(56, 70), S(56, 70), S(76, 99), S(86, 118)
};
score += ei.mi->material_value();
// If we have a specialized evaluation function for the current material
score += ei.mi->material_value();
// If we have a specialized evaluation function for the current material
if ( pos.piece_count(Us, QUEEN)
&& pos.non_pawn_material(Us) >= QueenValueMidgame + RookValueMidgame)
{
if ( pos.piece_count(Us, QUEEN)
&& pos.non_pawn_material(Us) >= QueenValueMidgame + RookValueMidgame)
{
b &= ei.attackedBy[Us][PAWN];
ei.kingAttackersCount[Us] = b ? count_1s<Max15>(b) / 2 : 0;
ei.kingAdjacentZoneAttacksCount[Us] = ei.kingAttackersWeight[Us] = 0;
} else
b &= ei.attackedBy[Us][PAWN];
ei.kingAttackersCount[Us] = b ? count_1s<Max15>(b) / 2 : 0;
ei.kingAdjacentZoneAttacksCount[Us] = ei.kingAttackersWeight[Us] = 0;
} else
// no minor piece which can exchange the outpost piece.
if (bonus && bit_is_set(ei.attackedBy[Us][PAWN], s))
{
// no minor piece which can exchange the outpost piece.
if (bonus && bit_is_set(ei.attackedBy[Us][PAWN], s))
{
- if ( pos.pieces(KNIGHT, Them) == EmptyBoardBB
- && (SquaresByColorBB[square_color(s)] & pos.pieces(BISHOP, Them)) == EmptyBoardBB)
+ if ( !pos.pieces(KNIGHT, Them)
+ && !(SquaresByColorBB[color_of(s)] & pos.pieces(BISHOP, Them)))
const BitCountType Full = HasPopCnt ? CNT_POPCNT : CpuIs64Bit ? CNT64 : CNT32;
const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : CpuIs64Bit ? CNT64_MAX15 : CNT32_MAX15;
const Color Them = (Us == WHITE ? BLACK : WHITE);
const BitCountType Full = HasPopCnt ? CNT_POPCNT : CpuIs64Bit ? CNT64 : CNT32;
const BitCountType Max15 = HasPopCnt ? CNT_POPCNT : CpuIs64Bit ? CNT64_MAX15 : CNT32_MAX15;
const Color Them = (Us == WHITE ? BLACK : WHITE);
{
// Find attacked squares, including x-ray attacks for bishops and rooks
if (Piece == KNIGHT || Piece == QUEEN)
{
// Find attacked squares, including x-ray attacks for bishops and rooks
if (Piece == KNIGHT || Piece == QUEEN)
// Decrease score if we are attacked by an enemy pawn. Remaining part
// of threat evaluation must be done later when we have full attack info.
if (bit_is_set(ei.attackedBy[Them][PAWN], s))
// Decrease score if we are attacked by an enemy pawn. Remaining part
// of threat evaluation must be done later when we have full attack info.
if (bit_is_set(ei.attackedBy[Them][PAWN], s))
- if ((Piece == BISHOP || Piece == KNIGHT) && pos.square_is_weak(s, Us))
+ if ( (Piece == BISHOP || Piece == KNIGHT)
+ && !(pos.pieces(PAWN, Them) & attack_span_mask(Us, s)))
score += evaluate_outposts<Piece, Us>(pos, ei, s);
// Queen or rook on 7th rank
score += evaluate_outposts<Piece, Us>(pos, ei, s);
// Queen or rook on 7th rank
// problem, especially when that pawn is also blocked.
if (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1))
{
// problem, especially when that pawn is also blocked.
if (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1))
{
if (pos.piece_on(s + d) == make_piece(Us, PAWN))
{
if (!pos.square_is_empty(s + d + pawn_push(Us)))
if (pos.piece_on(s + d) == make_piece(Us, PAWN))
{
if (!pos.square_is_empty(s + d + pawn_push(Us)))
if (ei.pi->file_is_half_open(Us, f))
{
if (ei.pi->file_is_half_open(Them, f))
if (ei.pi->file_is_half_open(Us, f))
{
if (ei.pi->file_is_half_open(Them, f))
- if ( square_file(ksq) >= FILE_E
- && square_file(s) > square_file(ksq)
- && (relative_rank(Us, ksq) == RANK_1 || square_rank(ksq) == square_rank(s)))
+ if ( file_of(ksq) >= FILE_E
+ && file_of(s) > file_of(ksq)
+ && (relative_rank(Us, ksq) == RANK_1 || rank_of(ksq) == rank_of(s)))
score -= make_score(pos.can_castle(Us) ? (TrappedRookPenalty - mob * 16) / 2
: (TrappedRookPenalty - mob * 16), 0);
}
score -= make_score(pos.can_castle(Us) ? (TrappedRookPenalty - mob * 16) / 2
: (TrappedRookPenalty - mob * 16), 0);
}
- else if ( square_file(ksq) <= FILE_D
- && square_file(s) < square_file(ksq)
- && (relative_rank(Us, ksq) == RANK_1 || square_rank(ksq) == square_rank(s)))
+ else if ( file_of(ksq) <= FILE_D
+ && file_of(s) < file_of(ksq)
+ && (relative_rank(Us, ksq) == RANK_1 || rank_of(ksq) == rank_of(s)))
score -= make_score(pos.can_castle(Us) ? (TrappedRookPenalty - mob * 16) / 2
: (TrappedRookPenalty - mob * 16), 0);
}
score -= make_score(pos.can_castle(Us) ? (TrappedRookPenalty - mob * 16) / 2
: (TrappedRookPenalty - mob * 16), 0);
}
Score score = mobility = SCORE_ZERO;
// Do not include in mobility squares protected by enemy pawns or occupied by our pieces
Score score = mobility = SCORE_ZERO;
// Do not include in mobility squares protected by enemy pawns or occupied by our pieces
score += evaluate_pieces<KNIGHT, Us, HasPopCnt, Trace>(pos, ei, mobility, mobilityArea);
score += evaluate_pieces<BISHOP, Us, HasPopCnt, Trace>(pos, ei, mobility, mobilityArea);
score += evaluate_pieces<KNIGHT, Us, HasPopCnt, Trace>(pos, ei, mobility, mobilityArea);
score += evaluate_pieces<BISHOP, Us, HasPopCnt, Trace>(pos, ei, mobility, mobilityArea);
// the number and types of the enemy's attacking pieces, the number of
// attacked and undefended squares around our king, the square of the
// king, and the quality of the pawn shelter.
// the number and types of the enemy's attacking pieces, the number of
// attacked and undefended squares around our king, the square of the
// king, and the quality of the pawn shelter.
+ 3 * (ei.kingAdjacentZoneAttacksCount[Them] + count_1s<Max15>(undefended))
+ InitKingDanger[relative_square(Us, ksq)]
- mg_value(ei.pi->king_shelter<Us>(pos, ksq)) / 32;
// Analyse enemy's safe queen contact checks. First find undefended
// squares around the king attacked by enemy queen...
+ 3 * (ei.kingAdjacentZoneAttacksCount[Them] + count_1s<Max15>(undefended))
+ InitKingDanger[relative_square(Us, ksq)]
- mg_value(ei.pi->king_shelter<Us>(pos, ksq)) / 32;
// Analyse enemy's safe queen contact checks. First find undefended
// squares around the king attacked by enemy queen...
// Analyse enemy's safe rook contact checks. First find undefended
// squares around the king attacked by enemy rooks...
// Analyse enemy's safe rook contact checks. First find undefended
// squares around the king attacked by enemy rooks...
attackUnits += KnightCheckBonus * count_1s<Max15>(b);
// To index KingDangerTable[] attackUnits must be in [0, 99] range
attackUnits += KnightCheckBonus * count_1s<Max15>(b);
// To index KingDangerTable[] attackUnits must be in [0, 99] range
// Finally, extract the king danger score from the KingDangerTable[]
// array and subtract the score from evaluation. Set also margins[]
// Finally, extract the king danger score from the KingDangerTable[]
// array and subtract the score from evaluation. Set also margins[]
- ebonus += Value(square_distance(pos.king_square(Them), blockSq) * 6 * rr);
- ebonus -= Value(square_distance(pos.king_square(Us), blockSq) * 3 * rr);
+ ebonus += Value(square_distance(pos.king_square(Them), blockSq) * 5 * rr);
+ ebonus -= Value(square_distance(pos.king_square(Us), blockSq) * 2 * rr);
ebonus -= Value(square_distance(pos.king_square(Us), blockSq + pawn_push(Us)) * rr);
// If the pawn is free to advance, increase bonus
ebonus -= Value(square_distance(pos.king_square(Us), blockSq + pawn_push(Us)) * rr);
// If the pawn is free to advance, increase bonus
&& (squares_in_front_of(Them, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from<ROOK>(s)))
unsafeSquares = squaresToQueen;
else
&& (squares_in_front_of(Them, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from<ROOK>(s)))
unsafeSquares = squaresToQueen;
else
// If there aren't enemy attacks or pieces along the path to queen give
// huge bonus. Even bigger if we protect the pawn's path.
// If there aren't enemy attacks or pieces along the path to queen give
// huge bonus. Even bigger if we protect the pawn's path.
// If yes, big bonus (but smaller than when there are no enemy attacks),
// if no, somewhat smaller bonus.
ebonus += Value(rr * ((unsafeSquares & defendedSquares) == unsafeSquares ? 13 : 8));
// If yes, big bonus (but smaller than when there are no enemy attacks),
// if no, somewhat smaller bonus.
ebonus += Value(rr * ((unsafeSquares & defendedSquares) == unsafeSquares ? 13 : 8));
}
} // rr != 0
// Increase the bonus if the passed pawn is supported by a friendly pawn
// on the same rank and a bit smaller if it's on the previous rank.
}
} // rr != 0
// Increase the bonus if the passed pawn is supported by a friendly pawn
// on the same rank and a bit smaller if it's on the previous rank.
// we try the following: Increase the value for rook pawns if the
// other side has no pieces apart from a knight, and decrease the
// value if the other side has a rook or queen.
// we try the following: Increase the value for rook pawns if the
// other side has no pieces apart from a knight, and decrease the
// value if the other side has a rook or queen.
queeningPath = squares_in_front_of(c, s);
// Compute plies to queening and check direct advancement
movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(c, s) == RANK_2);
queeningPath = squares_in_front_of(c, s);
// Compute plies to queening and check direct advancement
movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(c, s) == RANK_2);
pathDefended = ((ei.attackedBy[c][0] & queeningPath) == queeningPath);
if (movesToGo >= oppMovesToGo && !pathDefended)
pathDefended = ((ei.attackedBy[c][0] & queeningPath) == queeningPath);
if (movesToGo >= oppMovesToGo && !pathDefended)
// Opponent king cannot block because path is defended and position
// is not in check. So only friendly pieces can be blockers.
assert(!pos.in_check());
// Opponent king cannot block because path is defended and position
// is not in check. So only friendly pieces can be blockers.
assert(!pos.in_check());
if (movesToGo >= oppMovesToGo && !pathDefended)
continue;
pliesToGo = 2 * movesToGo - int(c == pos.side_to_move());
if (movesToGo >= oppMovesToGo && !pathDefended)
continue;
pliesToGo = 2 * movesToGo - int(c == pos.side_to_move());
// Step 3. Can the losing side possibly create a new passed pawn and thus prevent the loss?
b = candidates = pos.pieces(PAWN, loserSide);
// Step 3. Can the losing side possibly create a new passed pawn and thus prevent the loss?
b = candidates = pos.pieces(PAWN, loserSide);
movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(loserSide, s) == RANK_2);
pliesToGo = 2 * movesToGo - int(loserSide == pos.side_to_move());
movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(loserSide, s) == RANK_2);
pliesToGo = 2 * movesToGo - int(loserSide == pos.side_to_move());
movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(loserSide, s) == RANK_2);
pliesToGo = 2 * movesToGo - int(loserSide == pos.side_to_move());
// Generate list of blocking pawns and supporters
movesToGo = rank_distance(s, queeningSquare) - int(relative_rank(loserSide, s) == RANK_2);
pliesToGo = 2 * movesToGo - int(loserSide == pos.side_to_move());
// Generate list of blocking pawns and supporters
opposed = squares_in_front_of(loserSide, s) & pos.pieces(PAWN, winnerSide);
blockers = passed_pawn_mask(loserSide, s) & pos.pieces(PAWN, winnerSide);
opposed = squares_in_front_of(loserSide, s) & pos.pieces(PAWN, winnerSide);
blockers = passed_pawn_mask(loserSide, s) & pos.pieces(PAWN, winnerSide);
while (b2) // This while-loop could be replaced with LSB/MSB (depending on color)
{
d = square_distance(blockSq, pop_1st_bit(&b2)) - 2;
while (b2) // This while-loop could be replaced with LSB/MSB (depending on color)
{
d = square_distance(blockSq, pop_1st_bit(&b2)) - 2;
while (b2) // This while-loop could be replaced with LSB/MSB (depending on color)
{
d = square_distance(blockSq, pop_1st_bit(&b2)) - 2;
while (b2) // This while-loop could be replaced with LSB/MSB (depending on color)
{
d = square_distance(blockSq, pop_1st_bit(&b2)) - 2;
// Plies needed for the king to capture all the blocking pawns
d = square_distance(pos.king_square(loserSide), blockSq);
// Plies needed for the king to capture all the blocking pawns
d = square_distance(pos.king_square(loserSide), blockSq);