2 Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3 Copyright (C) 2004-2020 The Stockfish developers (see AUTHORS file)
5 Stockfish is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 Stockfish is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <cstring> // For std::memset
37 std::string eval_file_loaded="None";
41 useNNUE = Options["Use NNUE"];
42 std::string eval_file = std::string(Options["EvalFile"]);
43 if (useNNUE && eval_file_loaded != eval_file)
44 if (Eval::NNUE::load_eval_file(eval_file))
45 eval_file_loaded = eval_file;
50 std::string eval_file = std::string(Options["EvalFile"]);
51 if (useNNUE && eval_file_loaded != eval_file)
53 UCI::OptionsMap defaults;
56 std::cerr << "NNUE evaluation used, but the network file " << eval_file << " was not loaded successfully. "
57 << "These network evaluation parameters must be available, and compatible with this version of the code. "
58 << "The UCI option EvalFile might need to specify the full path, including the directory/folder name, to the file. "
59 << "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/"+std::string(defaults["EvalFile"]) << std::endl;
60 std::exit(EXIT_FAILURE);
64 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled." << sync_endl;
66 sync_cout << "info string classical evaluation enabled." << sync_endl;
72 enum Tracing { NO_TRACE, TRACE };
74 enum Term { // The first 8 entries are reserved for PieceType
75 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
78 Score scores[TERM_NB][COLOR_NB];
80 double to_cp(Value v) { return double(v) / PawnValueEg; }
82 void add(int idx, Color c, Score s) {
86 void add(int idx, Score w, Score b = SCORE_ZERO) {
87 scores[idx][WHITE] = w;
88 scores[idx][BLACK] = b;
91 std::ostream& operator<<(std::ostream& os, Score s) {
92 os << std::setw(5) << to_cp(mg_value(s)) << " "
93 << std::setw(5) << to_cp(eg_value(s));
97 std::ostream& operator<<(std::ostream& os, Term t) {
99 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
100 os << " ---- ----" << " | " << " ---- ----";
102 os << scores[t][WHITE] << " | " << scores[t][BLACK];
104 os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
109 using namespace Trace;
113 // Threshold for lazy and space evaluation
114 constexpr Value LazyThreshold1 = Value(1400);
115 constexpr Value LazyThreshold2 = Value(1300);
116 constexpr Value SpaceThreshold = Value(12222);
117 constexpr Value NNUEThreshold = Value(575);
119 // KingAttackWeights[PieceType] contains king attack weights by piece type
120 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
122 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
123 // higher if multiple safe checks are possible for that piece type.
124 constexpr int SafeCheck[][2] = {
125 {}, {}, {792, 1283}, {645, 967}, {1084, 1897}, {772, 1119}
128 #define S(mg, eg) make_score(mg, eg)
130 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
131 // indexed by piece type and number of attacked squares in the mobility area.
132 constexpr Score MobilityBonus[][32] = {
133 { S(-62,-81), S(-53,-56), S(-12,-31), S( -4,-16), S( 3, 5), S( 13, 11), // Knight
134 S( 22, 17), S( 28, 20), S( 33, 25) },
135 { S(-48,-59), S(-20,-23), S( 16, -3), S( 26, 13), S( 38, 24), S( 51, 42), // Bishop
136 S( 55, 54), S( 63, 57), S( 63, 65), S( 68, 73), S( 81, 78), S( 81, 86),
137 S( 91, 88), S( 98, 97) },
138 { S(-60,-78), S(-20,-17), S( 2, 23), S( 3, 39), S( 3, 70), S( 11, 99), // Rook
139 S( 22,103), S( 31,121), S( 40,134), S( 40,139), S( 41,158), S( 48,164),
140 S( 57,168), S( 57,169), S( 62,172) },
141 { S(-30,-48), S(-12,-30), S( -8, -7), S( -9, 19), S( 20, 40), S( 23, 55), // Queen
142 S( 23, 59), S( 35, 75), S( 38, 78), S( 53, 96), S( 64, 96), S( 65,100),
143 S( 65,121), S( 66,127), S( 67,131), S( 67,133), S( 72,136), S( 72,141),
144 S( 77,147), S( 79,150), S( 93,151), S(108,168), S(108,168), S(108,171),
145 S(110,182), S(114,182), S(114,192), S(116,219) }
148 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
149 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
151 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
152 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
153 constexpr Score Outpost[] = { S(56, 36), S(30, 23) };
155 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
156 constexpr Score PassedRank[RANK_NB] = {
157 S(0, 0), S(10, 28), S(17, 33), S(15, 41), S(62, 72), S(168, 177), S(276, 260)
160 // RookOnFile[semiopen/open] contains bonuses for each rook when there is
161 // no (friendly) pawn on the rook file.
162 constexpr Score RookOnFile[] = { S(19, 7), S(48, 29) };
164 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
165 // which piece type attacks which one. Attacks on lesser pieces which are
166 // pawn-defended are not considered.
167 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
168 S(0, 0), S(5, 32), S(57, 41), S(77, 56), S(88, 119), S(79, 161)
171 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
172 S(0, 0), S(3, 46), S(37, 68), S(42, 60), S(0, 38), S(58, 41)
175 // Assorted bonuses and penalties
176 constexpr Score BadOutpost = S( -7, 36);
177 constexpr Score BishopOnKingRing = S( 24, 0);
178 constexpr Score BishopPawns = S( 3, 7);
179 constexpr Score BishopXRayPawns = S( 4, 5);
180 constexpr Score CorneredBishop = S( 50, 50);
181 constexpr Score FlankAttacks = S( 8, 0);
182 constexpr Score Hanging = S( 69, 36);
183 constexpr Score KnightOnQueen = S( 16, 11);
184 constexpr Score LongDiagonalBishop = S( 45, 0);
185 constexpr Score MinorBehindPawn = S( 18, 3);
186 constexpr Score PassedFile = S( 11, 8);
187 constexpr Score PawnlessFlank = S( 17, 95);
188 constexpr Score ReachableOutpost = S( 31, 22);
189 constexpr Score RestrictedPiece = S( 7, 7);
190 constexpr Score RookOnKingRing = S( 16, 0);
191 constexpr Score RookOnQueenFile = S( 6, 11);
192 constexpr Score SliderOnQueen = S( 60, 18);
193 constexpr Score ThreatByKing = S( 24, 89);
194 constexpr Score ThreatByPawnPush = S( 48, 39);
195 constexpr Score ThreatBySafePawn = S(173, 94);
196 constexpr Score TrappedRook = S( 55, 13);
197 constexpr Score WeakQueenProtection = S( 14, 0);
198 constexpr Score WeakQueen = S( 56, 15);
203 // Evaluation class computes and stores attacks tables and other working data
208 Evaluation() = delete;
209 explicit Evaluation(const Position& p) : pos(p) {}
210 Evaluation& operator=(const Evaluation&) = delete;
214 template<Color Us> void initialize();
215 template<Color Us, PieceType Pt> Score pieces();
216 template<Color Us> Score king() const;
217 template<Color Us> Score threats() const;
218 template<Color Us> Score passed() const;
219 template<Color Us> Score space() const;
220 Value winnable(Score score) const;
225 Bitboard mobilityArea[COLOR_NB];
226 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
228 // attackedBy[color][piece type] is a bitboard representing all squares
229 // attacked by a given color and piece type. Special "piece types" which
230 // is also calculated is ALL_PIECES.
231 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
233 // attackedBy2[color] are the squares attacked by at least 2 units of a given
234 // color, including x-rays. But diagonal x-rays through pawns are not computed.
235 Bitboard attackedBy2[COLOR_NB];
237 // kingRing[color] are the squares adjacent to the king plus some other
238 // very near squares, depending on king position.
239 Bitboard kingRing[COLOR_NB];
241 // kingAttackersCount[color] is the number of pieces of the given color
242 // which attack a square in the kingRing of the enemy king.
243 int kingAttackersCount[COLOR_NB];
245 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
246 // the given color which attack a square in the kingRing of the enemy king.
247 // The weights of the individual piece types are given by the elements in
248 // the KingAttackWeights array.
249 int kingAttackersWeight[COLOR_NB];
251 // kingAttacksCount[color] is the number of attacks by the given color to
252 // squares directly adjacent to the enemy king. Pieces which attack more
253 // than one square are counted multiple times. For instance, if there is
254 // a white knight on g5 and black's king is on g8, this white knight adds 2
255 // to kingAttacksCount[WHITE].
256 int kingAttacksCount[COLOR_NB];
260 // Evaluation::initialize() computes king and pawn attacks, and the king ring
261 // bitboard for a given color. This is done at the beginning of the evaluation.
263 template<Tracing T> template<Color Us>
264 void Evaluation<T>::initialize() {
266 constexpr Color Them = ~Us;
267 constexpr Direction Up = pawn_push(Us);
268 constexpr Direction Down = -Up;
269 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
271 const Square ksq = pos.square<KING>(Us);
273 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
275 // Find our pawns that are blocked or on the first two ranks
276 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
278 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
279 // or controlled by enemy pawns are excluded from the mobility area.
280 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
282 // Initialize attackedBy[] for king and pawns
283 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
284 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
285 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
286 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
288 // Init our king safety tables
289 Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, FILE_G),
290 Utility::clamp(rank_of(ksq), RANK_2, RANK_7));
291 kingRing[Us] = attacks_bb<KING>(s) | s;
293 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
294 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
296 // Remove from kingRing[] the squares defended by two pawns
297 kingRing[Us] &= ~dblAttackByPawn;
301 // Evaluation::pieces() scores pieces of a given color and type
303 template<Tracing T> template<Color Us, PieceType Pt>
304 Score Evaluation<T>::pieces() {
306 constexpr Color Them = ~Us;
307 constexpr Direction Down = -pawn_push(Us);
308 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
309 : Rank5BB | Rank4BB | Rank3BB);
310 const Square* pl = pos.squares<Pt>(Us);
313 Score score = SCORE_ZERO;
315 attackedBy[Us][Pt] = 0;
317 for (Square s = *pl; s != SQ_NONE; s = *++pl)
319 // Find attacked squares, including x-ray attacks for bishops and rooks
320 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
321 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
322 : attacks_bb<Pt>(s, pos.pieces());
324 if (pos.blockers_for_king(Us) & s)
325 b &= line_bb(pos.square<KING>(Us), s);
327 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
328 attackedBy[Us][Pt] |= b;
329 attackedBy[Us][ALL_PIECES] |= b;
331 if (b & kingRing[Them])
333 kingAttackersCount[Us]++;
334 kingAttackersWeight[Us] += KingAttackWeights[Pt];
335 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
338 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
339 score += RookOnKingRing;
341 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
342 score += BishopOnKingRing;
344 int mob = popcount(b & mobilityArea[Us]);
346 mobility[Us] += MobilityBonus[Pt - 2][mob];
348 if (Pt == BISHOP || Pt == KNIGHT)
350 // Bonus if the piece is on an outpost square or can reach one
351 // Reduced bonus for knights (BadOutpost) if few relevant targets
352 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
353 & ~pe->pawn_attacks_span(Them);
354 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
357 && bb & s & ~CenterFiles // on a side outpost
358 && !(b & targets) // no relevant attacks
359 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
362 score += Outpost[Pt == BISHOP];
363 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
364 score += ReachableOutpost;
366 // Bonus for a knight or bishop shielded by pawn
367 if (shift<Down>(pos.pieces(PAWN)) & s)
368 score += MinorBehindPawn;
370 // Penalty if the piece is far from the king
371 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
375 // Penalty according to the number of our pawns on the same color square as the
376 // bishop, bigger when the center files are blocked with pawns and smaller
377 // when the bishop is outside the pawn chain.
378 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
380 score -= BishopPawns * pos.pawns_on_same_color_squares(Us, s)
381 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
383 // Penalty for all enemy pawns x-rayed
384 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
386 // Bonus for bishop on a long diagonal which can "see" both center squares
387 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
388 score += LongDiagonalBishop;
390 // An important Chess960 pattern: a cornered bishop blocked by a friendly
391 // pawn diagonally in front of it is a very serious problem, especially
392 // when that pawn is also blocked.
393 if ( pos.is_chess960()
394 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
396 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
397 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
398 score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
399 : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
407 // Bonus for rook on the same file as a queen
408 if (file_bb(s) & pos.pieces(QUEEN))
409 score += RookOnQueenFile;
411 // Bonus for rook on an open or semi-open file
412 if (pos.is_on_semiopen_file(Us, s))
413 score += RookOnFile[pos.is_on_semiopen_file(Them, s)];
415 // Penalty when trapped by the king, even more if the king cannot castle
418 File kf = file_of(pos.square<KING>(Us));
419 if ((kf < FILE_E) == (file_of(s) < kf))
420 score -= TrappedRook * (1 + !pos.castling_rights(Us));
426 // Penalty if any relative pin or discovered attack against the queen
427 Bitboard queenPinners;
428 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
433 Trace::add(Pt, Us, score);
439 // Evaluation::king() assigns bonuses and penalties to a king of a given color
441 template<Tracing T> template<Color Us>
442 Score Evaluation<T>::king() const {
444 constexpr Color Them = ~Us;
445 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
446 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
448 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
449 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
451 const Square ksq = pos.square<KING>(Us);
453 // Init the score with king shelter and enemy pawns storm
454 Score score = pe->king_safety<Us>(pos);
456 // Attacked squares defended at most once by our queen or king
457 weak = attackedBy[Them][ALL_PIECES]
459 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
461 // Analyse the safe enemy's checks which are possible on next move
462 safe = ~pos.pieces(Them);
463 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
465 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
466 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
468 // Enemy rooks checks
469 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
471 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
473 unsafeChecks |= b1 & attackedBy[Them][ROOK];
475 // Enemy queen safe checks: count them only if the checks are from squares from
476 // which opponent cannot give a rook check, because rook checks are more valuable.
477 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
478 & ~(attackedBy[Us][QUEEN] | rookChecks);
480 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
482 // Enemy bishops checks: count them only if they are from squares from which
483 // opponent cannot give a queen check, because queen checks are more valuable.
484 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
487 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
490 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
492 // Enemy knights checks
493 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
494 if (knightChecks & safe)
495 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
497 unsafeChecks |= knightChecks;
499 // Find the squares that opponent attacks in our king flank, the squares
500 // which they attack twice in that flank, and the squares that we defend.
501 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
502 b2 = b1 & attackedBy2[Them];
503 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
505 int kingFlankAttack = popcount(b1) + popcount(b2);
506 int kingFlankDefense = popcount(b3);
508 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
509 + 185 * popcount(kingRing[Us] & weak)
510 + 148 * popcount(unsafeChecks)
511 + 98 * popcount(pos.blockers_for_king(Us))
512 + 69 * kingAttacksCount[Them]
513 + 3 * kingFlankAttack * kingFlankAttack / 8
514 + mg_value(mobility[Them] - mobility[Us])
515 - 873 * !pos.count<QUEEN>(Them)
516 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
517 - 6 * mg_value(score) / 8
518 - 4 * kingFlankDefense
521 // Transform the kingDanger units into a Score, and subtract it from the evaluation
522 if (kingDanger > 100)
523 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
525 // Penalty when our king is on a pawnless flank
526 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
527 score -= PawnlessFlank;
529 // Penalty if king flank is under attack, potentially moving toward the king
530 score -= FlankAttacks * kingFlankAttack;
533 Trace::add(KING, Us, score);
539 // Evaluation::threats() assigns bonuses according to the types of the
540 // attacking and the attacked pieces.
542 template<Tracing T> template<Color Us>
543 Score Evaluation<T>::threats() const {
545 constexpr Color Them = ~Us;
546 constexpr Direction Up = pawn_push(Us);
547 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
549 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
550 Score score = SCORE_ZERO;
553 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
555 // Squares strongly protected by the enemy, either because they defend the
556 // square with a pawn, or because they defend the square twice and we don't.
557 stronglyProtected = attackedBy[Them][PAWN]
558 | (attackedBy2[Them] & ~attackedBy2[Us]);
560 // Non-pawn enemies, strongly protected
561 defended = nonPawnEnemies & stronglyProtected;
563 // Enemies not strongly protected and under our attack
564 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
566 // Bonus according to the kind of attacking pieces
569 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
571 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
573 b = weak & attackedBy[Us][ROOK];
575 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
577 if (weak & attackedBy[Us][KING])
578 score += ThreatByKing;
580 b = ~attackedBy[Them][ALL_PIECES]
581 | (nonPawnEnemies & attackedBy2[Us]);
582 score += Hanging * popcount(weak & b);
584 // Additional bonus if weak piece is only protected by a queen
585 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
588 // Bonus for restricting their piece moves
589 b = attackedBy[Them][ALL_PIECES]
591 & attackedBy[Us][ALL_PIECES];
592 score += RestrictedPiece * popcount(b);
594 // Protected or unattacked squares
595 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
597 // Bonus for attacking enemy pieces with our relatively safe pawns
598 b = pos.pieces(Us, PAWN) & safe;
599 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
600 score += ThreatBySafePawn * popcount(b);
602 // Find squares where our pawns can push on the next move
603 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
604 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
606 // Keep only the squares which are relatively safe
607 b &= ~attackedBy[Them][PAWN] & safe;
609 // Bonus for safe pawn threats on the next move
610 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
611 score += ThreatByPawnPush * popcount(b);
613 // Bonus for threats on the next moves against enemy queen
614 if (pos.count<QUEEN>(Them) == 1)
616 bool queenImbalance = pos.count<QUEEN>() == 1;
618 Square s = pos.square<QUEEN>(Them);
619 safe = mobilityArea[Us]
620 & ~pos.pieces(Us, PAWN)
621 & ~stronglyProtected;
623 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
625 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
627 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
628 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
630 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
634 Trace::add(THREAT, Us, score);
639 // Evaluation::passed() evaluates the passed pawns and candidate passed
640 // pawns of the given color.
642 template<Tracing T> template<Color Us>
643 Score Evaluation<T>::passed() const {
645 constexpr Color Them = ~Us;
646 constexpr Direction Up = pawn_push(Us);
647 constexpr Direction Down = -Up;
649 auto king_proximity = [&](Color c, Square s) {
650 return std::min(distance(pos.square<KING>(c), s), 5);
653 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
654 Score score = SCORE_ZERO;
656 b = pe->passed_pawns(Us);
658 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
661 helpers = shift<Up>(pos.pieces(Us, PAWN))
663 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
665 // Remove blocked candidate passers that don't have help to pass
667 | shift<WEST>(helpers)
668 | shift<EAST>(helpers);
673 Square s = pop_lsb(&b);
675 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
677 int r = relative_rank(Us, s);
679 Score bonus = PassedRank[r];
684 Square blockSq = s + Up;
686 // Adjust bonus based on the king's proximity
687 bonus += make_score(0, ( (king_proximity(Them, blockSq) * 19) / 4
688 - king_proximity(Us, blockSq) * 2) * w);
690 // If blockSq is not the queening square then consider also a second push
692 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
694 // If the pawn is free to advance, then increase the bonus
695 if (pos.empty(blockSq))
697 squaresToQueen = forward_file_bb(Us, s);
698 unsafeSquares = passed_pawn_span(Us, s);
700 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
702 if (!(pos.pieces(Them) & bb))
703 unsafeSquares &= attackedBy[Them][ALL_PIECES];
705 // If there are no enemy attacks on passed pawn span, assign a big bonus.
706 // Otherwise assign a smaller bonus if the path to queen is not attacked
707 // and even smaller bonus if it is attacked but block square is not.
708 int k = !unsafeSquares ? 35 :
709 !(unsafeSquares & squaresToQueen) ? 20 :
710 !(unsafeSquares & blockSq) ? 9 :
713 // Assign a larger bonus if the block square is defended
714 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
717 bonus += make_score(k * w, k * w);
721 score += bonus - PassedFile * edge_distance(file_of(s));
725 Trace::add(PASSED, Us, score);
731 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
732 // play in the opening. It is based on the number of safe squares on the 4 central files
733 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
734 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
736 template<Tracing T> template<Color Us>
737 Score Evaluation<T>::space() const {
739 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
740 if (pos.non_pawn_material() < SpaceThreshold)
743 constexpr Color Them = ~Us;
744 constexpr Direction Down = -pawn_push(Us);
745 constexpr Bitboard SpaceMask =
746 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
747 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
749 // Find the available squares for our pieces inside the area defined by SpaceMask
750 Bitboard safe = SpaceMask
751 & ~pos.pieces(Us, PAWN)
752 & ~attackedBy[Them][PAWN];
754 // Find all squares which are at most three squares behind some friendly pawn
755 Bitboard behind = pos.pieces(Us, PAWN);
756 behind |= shift<Down>(behind);
757 behind |= shift<Down+Down>(behind);
759 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
760 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
761 Score score = make_score(bonus * weight * weight / 16, 0);
764 Trace::add(SPACE, Us, score);
770 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
771 // the known attacking/defending status of the players. The final value is derived
772 // by interpolation from the midgame and endgame values.
775 Value Evaluation<T>::winnable(Score score) const {
777 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
778 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
780 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
781 && (pos.pieces(PAWN) & KingSide);
783 bool almostUnwinnable = outflanking < 0
784 && !pawnsOnBothFlanks;
786 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
787 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
789 // Compute the initiative bonus for the attacking side
790 int complexity = 9 * pe->passed_count()
791 + 12 * pos.count<PAWN>()
793 + 21 * pawnsOnBothFlanks
795 + 51 * !pos.non_pawn_material()
796 - 43 * almostUnwinnable
799 Value mg = mg_value(score);
800 Value eg = eg_value(score);
802 // Now apply the bonus: note that we find the attacking side by extracting the
803 // sign of the midgame or endgame values, and that we carefully cap the bonus
804 // so that the midgame and endgame scores do not change sign after the bonus.
805 int u = ((mg > 0) - (mg < 0)) * Utility::clamp(complexity + 50, -abs(mg), 0);
806 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
811 // Compute the scale factor for the winning side
812 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
813 int sf = me->scale_factor(pos, strongSide);
815 // If scale factor is not already specific, scale down via general heuristics
816 if (sf == SCALE_FACTOR_NORMAL)
818 if (pos.opposite_bishops())
820 if ( pos.non_pawn_material(WHITE) == BishopValueMg
821 && pos.non_pawn_material(BLACK) == BishopValueMg)
822 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
824 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
826 else if ( pos.non_pawn_material(WHITE) == RookValueMg
827 && pos.non_pawn_material(BLACK) == RookValueMg
828 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
829 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
830 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
832 else if (pos.count<QUEEN>() == 1)
833 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
834 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
836 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide));
839 // Interpolate between the middlegame and (scaled by 'sf') endgame score
840 v = mg * int(me->game_phase())
841 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
846 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
847 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
854 // Evaluation::value() is the main function of the class. It computes the various
855 // parts of the evaluation and returns the value of the position from the point
856 // of view of the side to move.
859 Value Evaluation<T>::value() {
861 assert(!pos.checkers());
863 // Probe the material hash table
864 me = Material::probe(pos);
866 // If we have a specialized evaluation function for the current material
867 // configuration, call it and return.
868 if (me->specialized_eval_exists())
869 return me->evaluate(pos);
871 // Initialize score by reading the incrementally updated scores included in
872 // the position object (material + piece square tables) and the material
873 // imbalance. Score is computed internally from the white point of view.
874 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
876 // Probe the pawn hash table
877 pe = Pawns::probe(pos);
878 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
880 // Early exit if score is high
881 auto lazy_skip = [&](Value lazyThreshold) {
882 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
885 if (lazy_skip(LazyThreshold1))
888 // Main evaluation begins here
892 // Pieces evaluated first (also populates attackedBy, attackedBy2).
893 // Note that the order of evaluation of the terms is left unspecified.
894 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
895 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
896 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
897 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
899 score += mobility[WHITE] - mobility[BLACK];
901 // More complex interactions that require fully populated attack bitboards
902 score += king< WHITE>() - king< BLACK>()
903 + passed< WHITE>() - passed< BLACK>();
905 if (lazy_skip(LazyThreshold2))
908 score += threats<WHITE>() - threats<BLACK>()
909 + space< WHITE>() - space< BLACK>();
912 // Derive single value from mg and eg parts of score
913 Value v = winnable(score);
915 // In case of tracing add all remaining individual evaluation terms
918 Trace::add(MATERIAL, pos.psq_score());
919 Trace::add(IMBALANCE, me->imbalance());
920 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
921 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
927 // Side to move point of view
928 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
930 // Damp down the evaluation linearly when shuffling
931 v = v * (100 - pos.rule50_count()) / 100;
939 /// evaluate() is the evaluator for the outer world. It returns a static
940 /// evaluation of the position from the point of view of the side to move.
942 Value Eval::evaluate(const Position& pos) {
946 Value v = eg_value(pos.psq_score());
947 // Take NNUE eval only on balanced positions
948 if (abs(v) < NNUEThreshold)
949 return NNUE::evaluate(pos) + Tempo;
951 return Evaluation<NO_TRACE>(pos).value();
954 /// trace() is like evaluate(), but instead of returning a value, it returns
955 /// a string (suitable for outputting to stdout) that contains the detailed
956 /// descriptions and values of each evaluation term. Useful for debugging.
957 /// Trace scores are from white's point of view
959 std::string Eval::trace(const Position& pos) {
962 return "Final evaluation: none (in check)";
964 std::stringstream ss;
965 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
971 v = NNUE::evaluate(pos);
975 std::memset(scores, 0, sizeof(scores));
977 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
979 v = Evaluation<TRACE>(pos).value();
981 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
982 << " Term | White | Black | Total \n"
983 << " | MG EG | MG EG | MG EG \n"
984 << " ------------+-------------+-------------+------------\n"
985 << " Material | " << Term(MATERIAL)
986 << " Imbalance | " << Term(IMBALANCE)
987 << " Pawns | " << Term(PAWN)
988 << " Knights | " << Term(KNIGHT)
989 << " Bishops | " << Term(BISHOP)
990 << " Rooks | " << Term(ROOK)
991 << " Queens | " << Term(QUEEN)
992 << " Mobility | " << Term(MOBILITY)
993 << " King safety | " << Term(KING)
994 << " Threats | " << Term(THREAT)
995 << " Passed | " << Term(PASSED)
996 << " Space | " << Term(SPACE)
997 << " Winnable | " << Term(WINNABLE)
998 << " ------------+-------------+-------------+------------\n"
999 << " Total | " << Term(TOTAL);
1002 v = pos.side_to_move() == WHITE ? v : -v;
1004 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";