constexpr Score KnightOnQueen = S( 21, 11);
constexpr Score LongDiagonalBishop = S( 22, 0);
constexpr Score MinorBehindPawn = S( 16, 0);
constexpr Score KnightOnQueen = S( 21, 11);
constexpr Score LongDiagonalBishop = S( 22, 0);
constexpr Score MinorBehindPawn = S( 16, 0);
constexpr Score PawnlessFlank = S( 20, 80);
constexpr Score RookOnPawn = S( 8, 24);
constexpr Score SliderOnQueen = S( 42, 21);
constexpr Score PawnlessFlank = S( 20, 80);
constexpr Score RookOnPawn = S( 8, 24);
constexpr Score SliderOnQueen = S( 42, 21);
if (relative_rank(Us, s) >= RANK_5)
score += RookOnPawn * popcount(pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s]);
if (relative_rank(Us, s) >= RANK_5)
score += RookOnPawn * popcount(pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s]);
Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safeThreats;
Score score = SCORE_ZERO;
Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safeThreats;
Score score = SCORE_ZERO;
- if (weak)
- {
- // Our safe or protected pawns
- b = pos.pieces(Us, PAWN)
- & (~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES]);
+ // Our safe or protected pawns
+ b = pos.pieces(Us, PAWN)
+ & (~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES]);
- safeThreats = pawn_attacks_bb<Us>(b) & weak;
- score += ThreatBySafePawn * popcount(safeThreats);
- }
+ safeThreats = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
+ score += ThreatBySafePawn * popcount(safeThreats);
// Squares strongly protected by the enemy, either because they defend the
// square with a pawn, or because they defend the square twice and we don't.
// Squares strongly protected by the enemy, either because they defend the
// square with a pawn, or because they defend the square twice and we don't.
b = (pos.pieces(Us) ^ pos.pieces(Us, PAWN, KING)) & attackedBy[Us][ALL_PIECES];
score += Connectivity * popcount(b);
b = (pos.pieces(Us) ^ pos.pieces(Us, PAWN, KING)) & attackedBy[Us][ALL_PIECES];
score += Connectivity * popcount(b);
+ // Bonus for overload (non-pawn enemies attacked and defended exactly once)
+ b = nonPawnEnemies
+ & attackedBy[Us][ALL_PIECES] & ~attackedBy2[Us]
+ & attackedBy[Them][ALL_PIECES] & ~attackedBy2[Them];
+ score += Overload * popcount(b);
+
}
else if (pos.pieces(Us) & blockSq)
bonus += make_score(w + r * 2, w + r * 2);
}
else if (pos.pieces(Us) & blockSq)
bonus += make_score(w + r * 2, w + r * 2);
// Scale down bonus for candidate passers which need more than one
// pawn push to become passed or have a pawn in front of them.
// Scale down bonus for candidate passers which need more than one
// pawn push to become passed or have a pawn in front of them.
// pawn, or if it is undefended and attacked by an enemy piece.
Bitboard safe = SpaceMask
& ~pos.pieces(Us, PAWN)
// pawn, or if it is undefended and attacked by an enemy piece.
Bitboard safe = SpaceMask
& ~pos.pieces(Us, PAWN)
// Find all squares which are at most three squares behind some friendly pawn
Bitboard behind = pos.pieces(Us, PAWN);
// Find all squares which are at most three squares behind some friendly pawn
Bitboard behind = pos.pieces(Us, PAWN);
- // Endgame with opposite-colored bishops and no other pieces (ignoring pawns)
- // is almost a draw, in case of KBP vs KB, it is even more a draw.
+ // Endgame with opposite-colored bishops and no other pieces is almost a draw
// Endgame with opposite-colored bishops, but also other pieces. Still
// a bit drawish, but not as drawish as with only the two bishops.
// Endgame with opposite-colored bishops, but also other pieces. Still
// a bit drawish, but not as drawish as with only the two bishops.
// Initialize score by reading the incrementally updated scores included in
// the position object (material + piece square tables) and the material
// imbalance. Score is computed internally from the white point of view.
// Initialize score by reading the incrementally updated scores included in
// the position object (material + piece square tables) and the material
// imbalance. Score is computed internally from the white point of view.