constexpr Score PawnlessFlank = S( 17, 95);
constexpr Score RestrictedPiece = S( 7, 7);
constexpr Score RookOnPawn = S( 10, 32);
+ constexpr Score RookOnQueenFile = S( 11, 4);
constexpr Score SliderOnQueen = S( 59, 18);
constexpr Score ThreatByKing = S( 24, 89);
constexpr Score ThreatByPawnPush = S( 48, 39);
if (relative_rank(Us, s) >= RANK_5)
score += RookOnPawn * popcount(pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s]);
+ // Bonus for rook on same file as their queen
+ if (file_bb(s) & pos.pieces(Them, QUEEN))
+ score += RookOnQueenFile;
+
// Bonus for rook on an open or semi-open file
if (pos.is_on_semiopen_file(Us, s))
score += RookOnFile[bool(pos.is_on_semiopen_file(Them, s))];
// Enemies not strongly protected and under our attack
weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
- // Safe or protected squares
- safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
-
// Bonus according to the kind of attacking pieces
if (defended | weak)
{
score += RestrictedPiece * popcount(b);
+ // Protected or unattacked squares
+ safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
+
+ // Bonus for attacking enemy pieces with our relatively safe pawns
+ b = pos.pieces(Us, PAWN) & safe;
+ b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
+ score += ThreatBySafePawn * popcount(b);
+
// Find squares where our pawns can push on the next move
b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
score += ThreatByPawnPush * popcount(b);
- // Our safe or protected pawns
- b = pos.pieces(Us, PAWN) & safe;
-
- b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
- score += ThreatBySafePawn * popcount(b);
-
// Bonus for threats on the next moves against enemy queen
if (pos.count<QUEEN>(Them) == 1)
{
bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
&& (pos.pieces(PAWN) & KingSide);
+ bool almostUnwinnable = !pe->passed_count()
+ && outflanking < 0
+ && !pawnsOnBothFlanks;
+
// Compute the initiative bonus for the attacking side
int complexity = 9 * pe->passed_count()
+ 11 * pos.count<PAWN>()
+ 9 * outflanking
+ 18 * pawnsOnBothFlanks
+ 49 * !pos.non_pawn_material()
+ - 36 * almostUnwinnable
-103 ;
// Now apply the bonus: note that we find the attacking side by extracting