};
// Assorted bonuses and penalties
+ constexpr Score AttacksOnSpaceArea = S( 4, 0);
constexpr Score BishopPawns = S( 3, 7);
constexpr Score CorneredBishop = S( 50, 50);
constexpr Score FlankAttacks = S( 8, 0);
constexpr Score KnightOnQueen = S( 16, 12);
constexpr Score LongDiagonalBishop = S( 45, 0);
constexpr Score MinorBehindPawn = S( 18, 3);
- constexpr Score Outpost = S( 36, 12);
+ constexpr Score Outpost = S( 18, 6);
constexpr Score PawnlessFlank = S( 17, 95);
constexpr Score RestrictedPiece = S( 7, 7);
constexpr Score RookOnPawn = S( 10, 32);
constexpr Color Them = (Us == WHITE ? BLACK : WHITE);
constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH);
constexpr Direction Down = (Us == WHITE ? SOUTH : NORTH);
- constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB: Rank7BB | Rank6BB);
+ constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
const Square ksq = pos.square<KING>(Us);
// Bonus if piece is on an outpost square or can reach one
bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them);
if (bb & s)
- score += Outpost * (Pt == KNIGHT ? 2 : 1);
+ score += Outpost * (Pt == KNIGHT ? 4 : 2);
else if (bb & b & ~pos.pieces(Us))
- score += Outpost / (Pt == KNIGHT ? 1 : 2);
+ score += Outpost * (Pt == KNIGHT ? 2 : 1);
// Knight and Bishop bonus for being right behind a pawn
if (shift<Down>(pos.pieces(PAWN)) & s)
b &= ~attackedBy[Them][PAWN] & safe;
// Bonus for safe pawn threats on the next move
- b = pawn_attacks_bb<Us>(b) & pos.pieces(Them);
+ b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
score += ThreatByPawnPush * popcount(b);
// Our safe or protected pawns
return std::min(distance(pos.square<KING>(c), s), 5);
};
- Bitboard b, bb, squaresToQueen, defendedSquares, unsafeSquares;
- Bitboard wideUnsafeSquares;
+ Bitboard b, bb, squaresToQueen, unsafeSquares;
Score score = SCORE_ZERO;
b = pe->passed_pawns(Us);
if (r > RANK_3)
{
- int w = (r-2) * (r-2) + 2;
+ int w = 5 * r - 13;
Square blockSq = s + Up;
// Adjust bonus based on the king's proximity
// If the pawn is free to advance, then increase the bonus
if (pos.empty(blockSq))
{
- // If there is a rook or queen attacking/defending the pawn from behind,
- // consider all the squaresToQueen. Otherwise consider only the squares
- // in the pawn's path attacked or occupied by the enemy.
- defendedSquares = unsafeSquares = squaresToQueen = forward_file_bb(Us, s);
- wideUnsafeSquares = AllSquares;
+ squaresToQueen = forward_file_bb(Us, s);
+ unsafeSquares = passed_pawn_span(Us, s);
bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
- if (!(pos.pieces(Us) & bb))
- defendedSquares &= attackedBy[Us][ALL_PIECES];
-
if (!(pos.pieces(Them) & bb))
unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
-
- if (!unsafeSquares)
- wideUnsafeSquares = (attackedBy[Them][ALL_PIECES] | pos.pieces(Them))
- & (shift<WEST>(squaresToQueen) | shift<EAST>(squaresToQueen));
- // If there aren't any enemy attacks, assign a big bonus. Otherwise
- // assign a smaller bonus if the block square isn't attacked.
- int k = !wideUnsafeSquares ? 35 : !unsafeSquares ? 20 : !(unsafeSquares & blockSq) ? 9 : 0;
+ // If there are no enemy attacks on passed pawn span, assign a big bonus.
+ // Otherwise assign a smaller bonus if the path to queen is not attacked
+ // and even smaller bonus if it is attacked but block square is not.
+ int k = !unsafeSquares ? 35 :
+ !(unsafeSquares & squaresToQueen) ? 20 :
+ !(unsafeSquares & blockSq) ? 9 :
+ 0 ;
- // Assign a larger bonus if the block square is defended.
- if (defendedSquares & blockSq)
+ // Assign a larger bonus if the block square is defended
+ if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
k += 5;
bonus += make_score(k * w, k * w);
int weight = pos.count<ALL_PIECES>(Us) - 1;
Score score = make_score(bonus * weight * weight / 16, 0);
+ score -= AttacksOnSpaceArea * popcount(attackedBy[Them][ALL_PIECES] & behind & safe);
+
if (T)
Trace::add(SPACE, Us, score);