namespace {
- constexpr Bitboard QueenSide = FileABB | FileBBB | FileCBB | FileDBB;
- constexpr Bitboard CenterFiles = FileCBB | FileDBB | FileEBB | FileFBB;
- constexpr Bitboard KingSide = FileEBB | FileFBB | FileGBB | FileHBB;
- constexpr Bitboard Center = (FileDBB | FileEBB) & (Rank4BB | Rank5BB);
-
- constexpr Bitboard KingFlank[FILE_NB] = {
- QueenSide ^ FileDBB, QueenSide, QueenSide,
- CenterFiles, CenterFiles,
- KingSide, KingSide, KingSide ^ FileEBB
- };
-
// Threshold for lazy and space evaluation
constexpr Value LazyThreshold = Value(1500);
constexpr Value SpaceThreshold = Value(12222);
S(106,184), S(109,191), S(113,206), S(116,212) }
};
- // Outpost[knight/bishop][supported by pawn] contains bonuses for minor
- // pieces if they occupy or can reach an outpost square, bigger if that
- // square is supported by a pawn.
- constexpr Score Outpost[][2] = {
- { S(22, 6), S(36,12) }, // Knight
- { S( 9, 2), S(15, 5) } // Bishop
- };
-
// RookOnFile[semiopen/open] contains bonuses for each rook when there is
// no (friendly) pawn on the rook file.
constexpr Score RookOnFile[] = { S(18, 7), S(44, 20) };
constexpr Score KnightOnQueen = S( 16, 12);
constexpr Score LongDiagonalBishop = S( 45, 0);
constexpr Score MinorBehindPawn = S( 18, 3);
+ constexpr Score Outpost = S( 9, 3);
constexpr Score PawnlessFlank = S( 17, 95);
constexpr Score RestrictedPiece = S( 7, 7);
constexpr Score RookOnPawn = S( 10, 32);
// Bonus if piece is on an outpost square or can reach one
bb = OutpostRanks & ~pe->pawn_attacks_span(Them);
if (bb & s)
- score += Outpost[Pt == BISHOP][bool(attackedBy[Us][PAWN] & s)] * 2;
+ score += Outpost * (Pt == KNIGHT ? 4 : 2)
+ * (1 + bool(attackedBy[Us][PAWN] & s));
else if (bb &= b & ~pos.pieces(Us))
- score += Outpost[Pt == BISHOP][bool(attackedBy[Us][PAWN] & bb)];
+ score += Outpost * (Pt == KNIGHT ? 2 : 1)
+ * (1 + bool(attackedBy[Us][PAWN] & bb));
// Knight and Bishop bonus for being right behind a pawn
if (shift<Down>(pos.pieces(PAWN)) & s)
constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
: AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
- Bitboard weak, b, b1, b2, safe, unsafeChecks = 0;
+ Bitboard weak, b1, b2, safe, unsafeChecks = 0;
+ Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
int kingDanger = 0;
const Square ksq = pos.square<KING>(Us);
b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
// Enemy rooks checks
- Bitboard RookCheck = b1
- & safe
- & attackedBy[Them][ROOK];
+ rookChecks = b1 & safe & attackedBy[Them][ROOK];
- if (RookCheck)
+ if (rookChecks)
kingDanger += RookSafeCheck;
else
unsafeChecks |= b1 & attackedBy[Them][ROOK];
// Enemy queen safe checks: we count them only if they are from squares from
// which we can't give a rook check, because rook checks are more valuable.
- Bitboard QueenCheck = (b1 | b2)
- & attackedBy[Them][QUEEN]
- & safe
- & ~attackedBy[Us][QUEEN]
- & ~RookCheck;
+ queenChecks = (b1 | b2)
+ & attackedBy[Them][QUEEN]
+ & safe
+ & ~attackedBy[Us][QUEEN]
+ & ~rookChecks;
- if (QueenCheck)
+ if (queenChecks)
kingDanger += QueenSafeCheck;
// Enemy bishops checks: we count them only if they are from squares from
// which we can't give a queen check, because queen checks are more valuable.
- Bitboard BishopCheck = b2
- & attackedBy[Them][BISHOP]
- & safe
- & ~QueenCheck;
+ bishopChecks = b2
+ & attackedBy[Them][BISHOP]
+ & safe
+ & ~queenChecks;
- if (BishopCheck)
+ if (bishopChecks)
kingDanger += BishopSafeCheck;
else
unsafeChecks |= b2 & attackedBy[Them][BISHOP];
// Enemy knights checks
- b = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
+ knightChecks = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
- if (b & safe)
+ if (knightChecks & safe)
kingDanger += KnightSafeCheck;
else
- unsafeChecks |= b;
+ unsafeChecks |= knightChecks;
// Unsafe or occupied checking squares will also be considered, as long as
// the square is in the attacker's mobility area.
constexpr Direction Up = (Us == WHITE ? NORTH : SOUTH);
constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
- Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe, restricted;
+ Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
Score score = SCORE_ZERO;
// Non-pawn enemies
}
// Bonus for restricting their piece moves
- restricted = attackedBy[Them][ALL_PIECES]
- & ~stronglyProtected
- & attackedBy[Us][ALL_PIECES];
- score += RestrictedPiece * popcount(restricted);
+ b = attackedBy[Them][ALL_PIECES]
+ & ~stronglyProtected
+ & attackedBy[Us][ALL_PIECES];
+
+ score += RestrictedPiece * popcount(b);
// Bonus for enemy unopposed weak pawns
if (pos.pieces(Us, ROOK, QUEEN))
&& (pos.pieces(PAWN) & KingSide);
// Compute the initiative bonus for the attacking side
- int complexity = 9 * pe->pawn_asymmetry()
+ int complexity = 9 * pe->passed_count()
+ 11 * pos.count<PAWN>()
+ 9 * outflanking
+ 18 * pawnsOnBothFlanks
+ 49 * !pos.non_pawn_material()
- -121 ;
+ -103 ;
// Now apply the bonus: note that we find the attacking side by extracting
// the sign of the endgame value, and that we carefully cap the bonus so
if ( pos.opposite_bishops()
&& pos.non_pawn_material(WHITE) == BishopValueMg
&& pos.non_pawn_material(BLACK) == BishopValueMg)
- sf = 8 + 4 * pe->pawn_asymmetry();
+ sf = 16 + 4 * pe->passed_count();
else
sf = std::min(40 + (pos.opposite_bishops() ? 2 : 7) * pos.count<PAWN>(strongSide), sf);
<< " ------------+-------------+-------------+------------\n"
<< " Material | " << Term(MATERIAL)
<< " Imbalance | " << Term(IMBALANCE)
- << " Initiative | " << Term(INITIATIVE)
<< " Pawns | " << Term(PAWN)
<< " Knights | " << Term(KNIGHT)
<< " Bishops | " << Term(BISHOP)
<< " Threats | " << Term(THREAT)
<< " Passed | " << Term(PASSED)
<< " Space | " << Term(SPACE)
+ << " Initiative | " << Term(INITIATIVE)
<< " ------------+-------------+-------------+------------\n"
<< " Total | " << Term(TOTAL);