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 sync_cout << "info string ERROR: NNUE evaluation used, but the network file " << eval_file << " was not loaded successfully." << sync_endl;
57 sync_cout << "info string ERROR: The UCI option EvalFile might need to specify the full path, including the directory/folder name, to the file." << sync_endl;
58 sync_cout << "info string ERROR: The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/"+std::string(defaults["EvalFile"]) << sync_endl;
59 sync_cout << "info string ERROR: If the UCI option Use NNUE is set to true, network evaluation parameters compatible with the program must be available." << sync_endl;
60 sync_cout << "info string ERROR: The engine will be terminated now." << sync_endl;
61 std::exit(EXIT_FAILURE);
65 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled." << sync_endl;
67 sync_cout << "info string classical evaluation enabled." << sync_endl;
73 enum Tracing { NO_TRACE, TRACE };
75 enum Term { // The first 8 entries are reserved for PieceType
76 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
79 Score scores[TERM_NB][COLOR_NB];
81 double to_cp(Value v) { return double(v) / PawnValueEg; }
83 void add(int idx, Color c, Score s) {
87 void add(int idx, Score w, Score b = SCORE_ZERO) {
88 scores[idx][WHITE] = w;
89 scores[idx][BLACK] = b;
92 std::ostream& operator<<(std::ostream& os, Score s) {
93 os << std::setw(5) << to_cp(mg_value(s)) << " "
94 << std::setw(5) << to_cp(eg_value(s));
98 std::ostream& operator<<(std::ostream& os, Term t) {
100 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
101 os << " ---- ----" << " | " << " ---- ----";
103 os << scores[t][WHITE] << " | " << scores[t][BLACK];
105 os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
110 using namespace Trace;
114 // Threshold for lazy and space evaluation
115 constexpr Value LazyThreshold1 = Value(1400);
116 constexpr Value LazyThreshold2 = Value(1300);
117 constexpr Value SpaceThreshold = Value(12222);
118 constexpr Value NNUEThreshold1 = Value(550);
119 constexpr Value NNUEThreshold2 = Value(150);
121 // KingAttackWeights[PieceType] contains king attack weights by piece type
122 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
124 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
125 // higher if multiple safe checks are possible for that piece type.
126 constexpr int SafeCheck[][2] = {
127 {}, {}, {792, 1283}, {645, 967}, {1084, 1897}, {772, 1119}
130 #define S(mg, eg) make_score(mg, eg)
132 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
133 // indexed by piece type and number of attacked squares in the mobility area.
134 constexpr Score MobilityBonus[][32] = {
135 { S(-62,-81), S(-53,-56), S(-12,-31), S( -4,-16), S( 3, 5), S( 13, 11), // Knight
136 S( 22, 17), S( 28, 20), S( 33, 25) },
137 { S(-48,-59), S(-20,-23), S( 16, -3), S( 26, 13), S( 38, 24), S( 51, 42), // Bishop
138 S( 55, 54), S( 63, 57), S( 63, 65), S( 68, 73), S( 81, 78), S( 81, 86),
139 S( 91, 88), S( 98, 97) },
140 { S(-60,-78), S(-20,-17), S( 2, 23), S( 3, 39), S( 3, 70), S( 11, 99), // Rook
141 S( 22,103), S( 31,121), S( 40,134), S( 40,139), S( 41,158), S( 48,164),
142 S( 57,168), S( 57,169), S( 62,172) },
143 { S(-30,-48), S(-12,-30), S( -8, -7), S( -9, 19), S( 20, 40), S( 23, 55), // Queen
144 S( 23, 59), S( 35, 75), S( 38, 78), S( 53, 96), S( 64, 96), S( 65,100),
145 S( 65,121), S( 66,127), S( 67,131), S( 67,133), S( 72,136), S( 72,141),
146 S( 77,147), S( 79,150), S( 93,151), S(108,168), S(108,168), S(108,171),
147 S(110,182), S(114,182), S(114,192), S(116,219) }
150 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
151 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
153 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
154 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
155 constexpr Score Outpost[] = { S(56, 36), S(30, 23) };
157 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
158 constexpr Score PassedRank[RANK_NB] = {
159 S(0, 0), S(10, 28), S(17, 33), S(15, 41), S(62, 72), S(168, 177), S(276, 260)
162 // RookOnFile[semiopen/open] contains bonuses for each rook when there is
163 // no (friendly) pawn on the rook file.
164 constexpr Score RookOnFile[] = { S(19, 7), S(48, 29) };
166 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
167 // which piece type attacks which one. Attacks on lesser pieces which are
168 // pawn-defended are not considered.
169 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
170 S(0, 0), S(5, 32), S(57, 41), S(77, 56), S(88, 119), S(79, 161)
173 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
174 S(0, 0), S(3, 46), S(37, 68), S(42, 60), S(0, 38), S(58, 41)
177 // Assorted bonuses and penalties
178 constexpr Score BadOutpost = S( -7, 36);
179 constexpr Score BishopOnKingRing = S( 24, 0);
180 constexpr Score BishopPawns = S( 3, 7);
181 constexpr Score BishopXRayPawns = S( 4, 5);
182 constexpr Score CorneredBishop = S( 50, 50);
183 constexpr Score FlankAttacks = S( 8, 0);
184 constexpr Score Hanging = S( 69, 36);
185 constexpr Score KnightOnQueen = S( 16, 11);
186 constexpr Score LongDiagonalBishop = S( 45, 0);
187 constexpr Score MinorBehindPawn = S( 18, 3);
188 constexpr Score PassedFile = S( 11, 8);
189 constexpr Score PawnlessFlank = S( 17, 95);
190 constexpr Score ReachableOutpost = S( 31, 22);
191 constexpr Score RestrictedPiece = S( 7, 7);
192 constexpr Score RookOnKingRing = S( 16, 0);
193 constexpr Score RookOnQueenFile = S( 6, 11);
194 constexpr Score SliderOnQueen = S( 60, 18);
195 constexpr Score ThreatByKing = S( 24, 89);
196 constexpr Score ThreatByPawnPush = S( 48, 39);
197 constexpr Score ThreatBySafePawn = S(173, 94);
198 constexpr Score TrappedRook = S( 55, 13);
199 constexpr Score WeakQueenProtection = S( 14, 0);
200 constexpr Score WeakQueen = S( 56, 15);
205 // Evaluation class computes and stores attacks tables and other working data
210 Evaluation() = delete;
211 explicit Evaluation(const Position& p) : pos(p) {}
212 Evaluation& operator=(const Evaluation&) = delete;
216 template<Color Us> void initialize();
217 template<Color Us, PieceType Pt> Score pieces();
218 template<Color Us> Score king() const;
219 template<Color Us> Score threats() const;
220 template<Color Us> Score passed() const;
221 template<Color Us> Score space() const;
222 Value winnable(Score score) const;
227 Bitboard mobilityArea[COLOR_NB];
228 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
230 // attackedBy[color][piece type] is a bitboard representing all squares
231 // attacked by a given color and piece type. Special "piece types" which
232 // is also calculated is ALL_PIECES.
233 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
235 // attackedBy2[color] are the squares attacked by at least 2 units of a given
236 // color, including x-rays. But diagonal x-rays through pawns are not computed.
237 Bitboard attackedBy2[COLOR_NB];
239 // kingRing[color] are the squares adjacent to the king plus some other
240 // very near squares, depending on king position.
241 Bitboard kingRing[COLOR_NB];
243 // kingAttackersCount[color] is the number of pieces of the given color
244 // which attack a square in the kingRing of the enemy king.
245 int kingAttackersCount[COLOR_NB];
247 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
248 // the given color which attack a square in the kingRing of the enemy king.
249 // The weights of the individual piece types are given by the elements in
250 // the KingAttackWeights array.
251 int kingAttackersWeight[COLOR_NB];
253 // kingAttacksCount[color] is the number of attacks by the given color to
254 // squares directly adjacent to the enemy king. Pieces which attack more
255 // than one square are counted multiple times. For instance, if there is
256 // a white knight on g5 and black's king is on g8, this white knight adds 2
257 // to kingAttacksCount[WHITE].
258 int kingAttacksCount[COLOR_NB];
262 // Evaluation::initialize() computes king and pawn attacks, and the king ring
263 // bitboard for a given color. This is done at the beginning of the evaluation.
265 template<Tracing T> template<Color Us>
266 void Evaluation<T>::initialize() {
268 constexpr Color Them = ~Us;
269 constexpr Direction Up = pawn_push(Us);
270 constexpr Direction Down = -Up;
271 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
273 const Square ksq = pos.square<KING>(Us);
275 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
277 // Find our pawns that are blocked or on the first two ranks
278 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
280 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
281 // or controlled by enemy pawns are excluded from the mobility area.
282 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
284 // Initialize attackedBy[] for king and pawns
285 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
286 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
287 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
288 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
290 // Init our king safety tables
291 Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, FILE_G),
292 Utility::clamp(rank_of(ksq), RANK_2, RANK_7));
293 kingRing[Us] = attacks_bb<KING>(s) | s;
295 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
296 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
298 // Remove from kingRing[] the squares defended by two pawns
299 kingRing[Us] &= ~dblAttackByPawn;
303 // Evaluation::pieces() scores pieces of a given color and type
305 template<Tracing T> template<Color Us, PieceType Pt>
306 Score Evaluation<T>::pieces() {
308 constexpr Color Them = ~Us;
309 constexpr Direction Down = -pawn_push(Us);
310 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
311 : Rank5BB | Rank4BB | Rank3BB);
312 const Square* pl = pos.squares<Pt>(Us);
315 Score score = SCORE_ZERO;
317 attackedBy[Us][Pt] = 0;
319 for (Square s = *pl; s != SQ_NONE; s = *++pl)
321 // Find attacked squares, including x-ray attacks for bishops and rooks
322 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
323 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
324 : attacks_bb<Pt>(s, pos.pieces());
326 if (pos.blockers_for_king(Us) & s)
327 b &= line_bb(pos.square<KING>(Us), s);
329 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
330 attackedBy[Us][Pt] |= b;
331 attackedBy[Us][ALL_PIECES] |= b;
333 if (b & kingRing[Them])
335 kingAttackersCount[Us]++;
336 kingAttackersWeight[Us] += KingAttackWeights[Pt];
337 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
340 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
341 score += RookOnKingRing;
343 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
344 score += BishopOnKingRing;
346 int mob = popcount(b & mobilityArea[Us]);
348 mobility[Us] += MobilityBonus[Pt - 2][mob];
350 if (Pt == BISHOP || Pt == KNIGHT)
352 // Bonus if the piece is on an outpost square or can reach one
353 // Reduced bonus for knights (BadOutpost) if few relevant targets
354 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
355 & ~pe->pawn_attacks_span(Them);
356 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
359 && bb & s & ~CenterFiles // on a side outpost
360 && !(b & targets) // no relevant attacks
361 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
364 score += Outpost[Pt == BISHOP];
365 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
366 score += ReachableOutpost;
368 // Bonus for a knight or bishop shielded by pawn
369 if (shift<Down>(pos.pieces(PAWN)) & s)
370 score += MinorBehindPawn;
372 // Penalty if the piece is far from the king
373 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
377 // Penalty according to the number of our pawns on the same color square as the
378 // bishop, bigger when the center files are blocked with pawns and smaller
379 // when the bishop is outside the pawn chain.
380 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
382 score -= BishopPawns * pos.pawns_on_same_color_squares(Us, s)
383 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
385 // Penalty for all enemy pawns x-rayed
386 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
388 // Bonus for bishop on a long diagonal which can "see" both center squares
389 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
390 score += LongDiagonalBishop;
392 // An important Chess960 pattern: a cornered bishop blocked by a friendly
393 // pawn diagonally in front of it is a very serious problem, especially
394 // when that pawn is also blocked.
395 if ( pos.is_chess960()
396 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
398 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
399 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
400 score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
401 : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
409 // Bonus for rook on the same file as a queen
410 if (file_bb(s) & pos.pieces(QUEEN))
411 score += RookOnQueenFile;
413 // Bonus for rook on an open or semi-open file
414 if (pos.is_on_semiopen_file(Us, s))
415 score += RookOnFile[pos.is_on_semiopen_file(Them, s)];
417 // Penalty when trapped by the king, even more if the king cannot castle
420 File kf = file_of(pos.square<KING>(Us));
421 if ((kf < FILE_E) == (file_of(s) < kf))
422 score -= TrappedRook * (1 + !pos.castling_rights(Us));
428 // Penalty if any relative pin or discovered attack against the queen
429 Bitboard queenPinners;
430 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
435 Trace::add(Pt, Us, score);
441 // Evaluation::king() assigns bonuses and penalties to a king of a given color
443 template<Tracing T> template<Color Us>
444 Score Evaluation<T>::king() const {
446 constexpr Color Them = ~Us;
447 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
448 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
450 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
451 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
453 const Square ksq = pos.square<KING>(Us);
455 // Init the score with king shelter and enemy pawns storm
456 Score score = pe->king_safety<Us>(pos);
458 // Attacked squares defended at most once by our queen or king
459 weak = attackedBy[Them][ALL_PIECES]
461 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
463 // Analyse the safe enemy's checks which are possible on next move
464 safe = ~pos.pieces(Them);
465 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
467 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
468 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
470 // Enemy rooks checks
471 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
473 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
475 unsafeChecks |= b1 & attackedBy[Them][ROOK];
477 // Enemy queen safe checks: count them only if the checks are from squares from
478 // which opponent cannot give a rook check, because rook checks are more valuable.
479 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
480 & ~(attackedBy[Us][QUEEN] | rookChecks);
482 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
484 // Enemy bishops checks: count them only if they are from squares from which
485 // opponent cannot give a queen check, because queen checks are more valuable.
486 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
489 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
492 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
494 // Enemy knights checks
495 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
496 if (knightChecks & safe)
497 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
499 unsafeChecks |= knightChecks;
501 // Find the squares that opponent attacks in our king flank, the squares
502 // which they attack twice in that flank, and the squares that we defend.
503 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
504 b2 = b1 & attackedBy2[Them];
505 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
507 int kingFlankAttack = popcount(b1) + popcount(b2);
508 int kingFlankDefense = popcount(b3);
510 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
511 + 185 * popcount(kingRing[Us] & weak)
512 + 148 * popcount(unsafeChecks)
513 + 98 * popcount(pos.blockers_for_king(Us))
514 + 69 * kingAttacksCount[Them]
515 + 3 * kingFlankAttack * kingFlankAttack / 8
516 + mg_value(mobility[Them] - mobility[Us])
517 - 873 * !pos.count<QUEEN>(Them)
518 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
519 - 6 * mg_value(score) / 8
520 - 4 * kingFlankDefense
523 // Transform the kingDanger units into a Score, and subtract it from the evaluation
524 if (kingDanger > 100)
525 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
527 // Penalty when our king is on a pawnless flank
528 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
529 score -= PawnlessFlank;
531 // Penalty if king flank is under attack, potentially moving toward the king
532 score -= FlankAttacks * kingFlankAttack;
535 Trace::add(KING, Us, score);
541 // Evaluation::threats() assigns bonuses according to the types of the
542 // attacking and the attacked pieces.
544 template<Tracing T> template<Color Us>
545 Score Evaluation<T>::threats() const {
547 constexpr Color Them = ~Us;
548 constexpr Direction Up = pawn_push(Us);
549 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
551 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
552 Score score = SCORE_ZERO;
555 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
557 // Squares strongly protected by the enemy, either because they defend the
558 // square with a pawn, or because they defend the square twice and we don't.
559 stronglyProtected = attackedBy[Them][PAWN]
560 | (attackedBy2[Them] & ~attackedBy2[Us]);
562 // Non-pawn enemies, strongly protected
563 defended = nonPawnEnemies & stronglyProtected;
565 // Enemies not strongly protected and under our attack
566 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
568 // Bonus according to the kind of attacking pieces
571 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
573 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
575 b = weak & attackedBy[Us][ROOK];
577 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
579 if (weak & attackedBy[Us][KING])
580 score += ThreatByKing;
582 b = ~attackedBy[Them][ALL_PIECES]
583 | (nonPawnEnemies & attackedBy2[Us]);
584 score += Hanging * popcount(weak & b);
586 // Additional bonus if weak piece is only protected by a queen
587 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
590 // Bonus for restricting their piece moves
591 b = attackedBy[Them][ALL_PIECES]
593 & attackedBy[Us][ALL_PIECES];
594 score += RestrictedPiece * popcount(b);
596 // Protected or unattacked squares
597 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
599 // Bonus for attacking enemy pieces with our relatively safe pawns
600 b = pos.pieces(Us, PAWN) & safe;
601 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
602 score += ThreatBySafePawn * popcount(b);
604 // Find squares where our pawns can push on the next move
605 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
606 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
608 // Keep only the squares which are relatively safe
609 b &= ~attackedBy[Them][PAWN] & safe;
611 // Bonus for safe pawn threats on the next move
612 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
613 score += ThreatByPawnPush * popcount(b);
615 // Bonus for threats on the next moves against enemy queen
616 if (pos.count<QUEEN>(Them) == 1)
618 bool queenImbalance = pos.count<QUEEN>() == 1;
620 Square s = pos.square<QUEEN>(Them);
621 safe = mobilityArea[Us]
622 & ~pos.pieces(Us, PAWN)
623 & ~stronglyProtected;
625 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
627 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
629 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
630 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
632 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
636 Trace::add(THREAT, Us, score);
641 // Evaluation::passed() evaluates the passed pawns and candidate passed
642 // pawns of the given color.
644 template<Tracing T> template<Color Us>
645 Score Evaluation<T>::passed() const {
647 constexpr Color Them = ~Us;
648 constexpr Direction Up = pawn_push(Us);
649 constexpr Direction Down = -Up;
651 auto king_proximity = [&](Color c, Square s) {
652 return std::min(distance(pos.square<KING>(c), s), 5);
655 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
656 Score score = SCORE_ZERO;
658 b = pe->passed_pawns(Us);
660 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
663 helpers = shift<Up>(pos.pieces(Us, PAWN))
665 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
667 // Remove blocked candidate passers that don't have help to pass
669 | shift<WEST>(helpers)
670 | shift<EAST>(helpers);
675 Square s = pop_lsb(&b);
677 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
679 int r = relative_rank(Us, s);
681 Score bonus = PassedRank[r];
686 Square blockSq = s + Up;
688 // Adjust bonus based on the king's proximity
689 bonus += make_score(0, ( (king_proximity(Them, blockSq) * 19) / 4
690 - king_proximity(Us, blockSq) * 2) * w);
692 // If blockSq is not the queening square then consider also a second push
694 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
696 // If the pawn is free to advance, then increase the bonus
697 if (pos.empty(blockSq))
699 squaresToQueen = forward_file_bb(Us, s);
700 unsafeSquares = passed_pawn_span(Us, s);
702 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
704 if (!(pos.pieces(Them) & bb))
705 unsafeSquares &= attackedBy[Them][ALL_PIECES];
707 // If there are no enemy attacks on passed pawn span, assign a big bonus.
708 // Otherwise assign a smaller bonus if the path to queen is not attacked
709 // and even smaller bonus if it is attacked but block square is not.
710 int k = !unsafeSquares ? 35 :
711 !(unsafeSquares & squaresToQueen) ? 20 :
712 !(unsafeSquares & blockSq) ? 9 :
715 // Assign a larger bonus if the block square is defended
716 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
719 bonus += make_score(k * w, k * w);
723 score += bonus - PassedFile * edge_distance(file_of(s));
727 Trace::add(PASSED, Us, score);
733 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
734 // play in the opening. It is based on the number of safe squares on the 4 central files
735 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
736 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
738 template<Tracing T> template<Color Us>
739 Score Evaluation<T>::space() const {
741 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
742 if (pos.non_pawn_material() < SpaceThreshold)
745 constexpr Color Them = ~Us;
746 constexpr Direction Down = -pawn_push(Us);
747 constexpr Bitboard SpaceMask =
748 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
749 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
751 // Find the available squares for our pieces inside the area defined by SpaceMask
752 Bitboard safe = SpaceMask
753 & ~pos.pieces(Us, PAWN)
754 & ~attackedBy[Them][PAWN];
756 // Find all squares which are at most three squares behind some friendly pawn
757 Bitboard behind = pos.pieces(Us, PAWN);
758 behind |= shift<Down>(behind);
759 behind |= shift<Down+Down>(behind);
761 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
762 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
763 Score score = make_score(bonus * weight * weight / 16, 0);
766 Trace::add(SPACE, Us, score);
772 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
773 // the known attacking/defending status of the players. The final value is derived
774 // by interpolation from the midgame and endgame values.
777 Value Evaluation<T>::winnable(Score score) const {
779 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
780 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
782 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
783 && (pos.pieces(PAWN) & KingSide);
785 bool almostUnwinnable = outflanking < 0
786 && !pawnsOnBothFlanks;
788 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
789 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
791 // Compute the initiative bonus for the attacking side
792 int complexity = 9 * pe->passed_count()
793 + 12 * pos.count<PAWN>()
795 + 21 * pawnsOnBothFlanks
797 + 51 * !pos.non_pawn_material()
798 - 43 * almostUnwinnable
801 Value mg = mg_value(score);
802 Value eg = eg_value(score);
804 // Now apply the bonus: note that we find the attacking side by extracting the
805 // sign of the midgame or endgame values, and that we carefully cap the bonus
806 // so that the midgame and endgame scores do not change sign after the bonus.
807 int u = ((mg > 0) - (mg < 0)) * Utility::clamp(complexity + 50, -abs(mg), 0);
808 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
813 // Compute the scale factor for the winning side
814 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
815 int sf = me->scale_factor(pos, strongSide);
817 // If scale factor is not already specific, scale down via general heuristics
818 if (sf == SCALE_FACTOR_NORMAL)
820 if (pos.opposite_bishops())
822 if ( pos.non_pawn_material(WHITE) == BishopValueMg
823 && pos.non_pawn_material(BLACK) == BishopValueMg)
824 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
826 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
828 else if ( pos.non_pawn_material(WHITE) == RookValueMg
829 && pos.non_pawn_material(BLACK) == RookValueMg
830 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
831 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
832 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
834 else if (pos.count<QUEEN>() == 1)
835 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
836 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
838 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide));
841 // Interpolate between the middlegame and (scaled by 'sf') endgame score
842 v = mg * int(me->game_phase())
843 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
848 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
849 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
856 // Evaluation::value() is the main function of the class. It computes the various
857 // parts of the evaluation and returns the value of the position from the point
858 // of view of the side to move.
861 Value Evaluation<T>::value() {
863 assert(!pos.checkers());
865 // Probe the material hash table
866 me = Material::probe(pos);
868 // If we have a specialized evaluation function for the current material
869 // configuration, call it and return.
870 if (me->specialized_eval_exists())
871 return me->evaluate(pos);
873 // Initialize score by reading the incrementally updated scores included in
874 // the position object (material + piece square tables) and the material
875 // imbalance. Score is computed internally from the white point of view.
876 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
878 // Probe the pawn hash table
879 pe = Pawns::probe(pos);
880 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
882 // Early exit if score is high
883 auto lazy_skip = [&](Value lazyThreshold) {
884 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
887 if (lazy_skip(LazyThreshold1))
890 // Main evaluation begins here
894 // Pieces evaluated first (also populates attackedBy, attackedBy2).
895 // Note that the order of evaluation of the terms is left unspecified.
896 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
897 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
898 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
899 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
901 score += mobility[WHITE] - mobility[BLACK];
903 // More complex interactions that require fully populated attack bitboards
904 score += king< WHITE>() - king< BLACK>()
905 + passed< WHITE>() - passed< BLACK>();
907 if (lazy_skip(LazyThreshold2))
910 score += threats<WHITE>() - threats<BLACK>()
911 + space< WHITE>() - space< BLACK>();
914 // Derive single value from mg and eg parts of score
915 Value v = winnable(score);
917 // In case of tracing add all remaining individual evaluation terms
920 Trace::add(MATERIAL, pos.psq_score());
921 Trace::add(IMBALANCE, me->imbalance());
922 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
923 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
929 // Side to move point of view
930 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
938 /// evaluate() is the evaluator for the outer world. It returns a static
939 /// evaluation of the position from the point of view of the side to move.
941 Value Eval::evaluate(const Position& pos) {
943 bool classical = !Eval::useNNUE
944 || abs(eg_value(pos.psq_score())) * 16 > NNUEThreshold1 * (16 + pos.rule50_count());
945 Value v = classical ? Evaluation<NO_TRACE>(pos).value()
946 : NNUE::evaluate(pos) * 5 / 4 + Tempo;
948 if (classical && Eval::useNNUE && abs(v) * 16 < NNUEThreshold2 * (16 + pos.rule50_count()))
949 v = NNUE::evaluate(pos) * 5 / 4 + Tempo;
951 // Damp down the evaluation linearly when shuffling
952 v = v * (100 - pos.rule50_count()) / 100;
954 // Guarantee evalution outside of TB range
955 v = Utility::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
960 /// trace() is like evaluate(), but instead of returning a value, it returns
961 /// a string (suitable for outputting to stdout) that contains the detailed
962 /// descriptions and values of each evaluation term. Useful for debugging.
963 /// Trace scores are from white's point of view
965 std::string Eval::trace(const Position& pos) {
968 return "Final evaluation: none (in check)";
970 std::stringstream ss;
971 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
977 v = NNUE::evaluate(pos);
981 std::memset(scores, 0, sizeof(scores));
983 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
985 v = Evaluation<TRACE>(pos).value();
987 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
988 << " Term | White | Black | Total \n"
989 << " | MG EG | MG EG | MG EG \n"
990 << " ------------+-------------+-------------+------------\n"
991 << " Material | " << Term(MATERIAL)
992 << " Imbalance | " << Term(IMBALANCE)
993 << " Pawns | " << Term(PAWN)
994 << " Knights | " << Term(KNIGHT)
995 << " Bishops | " << Term(BISHOP)
996 << " Rooks | " << Term(ROOK)
997 << " Queens | " << Term(QUEEN)
998 << " Mobility | " << Term(MOBILITY)
999 << " King safety | " << Term(KING)
1000 << " Threats | " << Term(THREAT)
1001 << " Passed | " << Term(PASSED)
1002 << " Space | " << Term(SPACE)
1003 << " Winnable | " << Term(WINNABLE)
1004 << " ------------+-------------+-------------+------------\n"
1005 << " Total | " << Term(TOTAL);
1008 v = pos.side_to_move() == WHITE ? v : -v;
1010 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";