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 #include "incbin/incbin.h"
40 // Macro to embed the default NNUE file data in the engine binary (using incbin.h, by Dale Weiler).
41 // This macro invocation will declare the following three variables
42 // const unsigned char gEmbeddedNNUEData[]; // a pointer to the embedded data
43 // const unsigned char *const gEmbeddedNNUEEnd; // a marker to the end
44 // const unsigned int gEmbeddedNNUESize; // the size of the embedded file
45 // Note that this does not work in Microsof Visual Studio.
46 #if !defined(_MSC_VER) && !defined(NNUE_EMBEDDING_OFF)
47 INCBIN(EmbeddedNNUE, EvalFileDefaultName);
49 const unsigned char gEmbeddedNNUEData[1] = {0x0};
50 const unsigned char *const gEmbeddedNNUEEnd = &gEmbeddedNNUEData[1];
51 const unsigned int gEmbeddedNNUESize = 1;
56 using namespace Eval::NNUE;
61 string eval_file_loaded = "None";
63 /// NNUE::init() tries to load a nnue network at startup time, or when the engine
64 /// receives a UCI command "setoption name EvalFile value nn-[a-z0-9]{12}.nnue"
65 /// The name of the nnue network is always retrieved from the EvalFile option.
66 /// We search the given network in three locations: internally (the default
67 /// network may be embedded in the binary), in the active working directory and
68 /// in the engine directory. Distro packagers may define the DEFAULT_NNUE_DIRECTORY
69 /// variable to have the engine search in a special directory in their distro.
73 useNNUE = Options["Use NNUE"];
77 string eval_file = string(Options["EvalFile"]);
79 #if defined(DEFAULT_NNUE_DIRECTORY)
80 #define stringify2(x) #x
81 #define stringify(x) stringify2(x)
82 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) };
84 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory };
87 for (string directory : dirs)
88 if (eval_file_loaded != eval_file)
90 if (directory != "<internal>")
92 ifstream stream(directory + eval_file, ios::binary);
93 if (load_eval(eval_file, stream))
94 eval_file_loaded = eval_file;
97 if (directory == "<internal>" && eval_file == EvalFileDefaultName)
99 // C++ way to prepare a buffer for a memory stream
100 class MemoryBuffer : public basic_streambuf<char> {
101 public: MemoryBuffer(char* p, size_t n) { setg(p, p, p + n); setp(p, p + n); }
104 MemoryBuffer buffer(const_cast<char*>(reinterpret_cast<const char*>(gEmbeddedNNUEData)),
105 size_t(gEmbeddedNNUESize));
107 istream stream(&buffer);
108 if (load_eval(eval_file, stream))
109 eval_file_loaded = eval_file;
114 /// NNUE::verify() verifies that the last net used was loaded successfully
115 void NNUE::verify() {
117 string eval_file = string(Options["EvalFile"]);
119 if (useNNUE && eval_file_loaded != eval_file)
121 UCI::OptionsMap defaults;
124 string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
125 string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
126 string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
127 string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + string(defaults["EvalFile"]);
128 string msg5 = "The engine will be terminated now.";
130 sync_cout << "info string ERROR: " << msg1 << sync_endl;
131 sync_cout << "info string ERROR: " << msg2 << sync_endl;
132 sync_cout << "info string ERROR: " << msg3 << sync_endl;
133 sync_cout << "info string ERROR: " << msg4 << sync_endl;
134 sync_cout << "info string ERROR: " << msg5 << sync_endl;
140 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
142 sync_cout << "info string classical evaluation enabled" << sync_endl;
148 enum Tracing { NO_TRACE, TRACE };
150 enum Term { // The first 8 entries are reserved for PieceType
151 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
154 Score scores[TERM_NB][COLOR_NB];
156 double to_cp(Value v) { return double(v) / PawnValueEg; }
158 void add(int idx, Color c, Score s) {
162 void add(int idx, Score w, Score b = SCORE_ZERO) {
163 scores[idx][WHITE] = w;
164 scores[idx][BLACK] = b;
167 std::ostream& operator<<(std::ostream& os, Score s) {
168 os << std::setw(5) << to_cp(mg_value(s)) << " "
169 << std::setw(5) << to_cp(eg_value(s));
173 std::ostream& operator<<(std::ostream& os, Term t) {
175 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
176 os << " ---- ----" << " | " << " ---- ----";
178 os << scores[t][WHITE] << " | " << scores[t][BLACK];
180 os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
185 using namespace Trace;
189 // Threshold for lazy and space evaluation
190 constexpr Value LazyThreshold1 = Value(1565);
191 constexpr Value LazyThreshold2 = Value(1102);
192 constexpr Value SpaceThreshold = Value(11551);
193 constexpr Value NNUEThreshold1 = Value(682);
194 constexpr Value NNUEThreshold2 = Value(176);
196 // KingAttackWeights[PieceType] contains king attack weights by piece type
197 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
199 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
200 // higher if multiple safe checks are possible for that piece type.
201 constexpr int SafeCheck[][2] = {
202 {}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
205 #define S(mg, eg) make_score(mg, eg)
207 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
208 // indexed by piece type and number of attacked squares in the mobility area.
209 constexpr Score MobilityBonus[][32] = {
210 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
211 S( 21, 16), S( 28, 21), S( 37, 26) },
212 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
213 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
214 S( 91, 88), S( 96, 98) },
215 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
216 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
217 S( 57,165), S( 58,170), S( 67,175) },
218 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
219 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
220 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
221 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
222 S(112,178), S(114,185), S(114,187), S(119,221) }
225 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
226 // squares of the same color as our bishop.
227 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
228 S(3, 8), S(3, 9), S(1, 8), S(3, 7)
231 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
232 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
234 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
235 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
236 constexpr Score Outpost[] = { S(56, 34), S(31, 23) };
238 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
239 constexpr Score PassedRank[RANK_NB] = {
240 S(0, 0), S(9, 28), S(15, 31), S(17, 39), S(64, 70), S(171, 177), S(277, 260)
243 constexpr Score RookOnClosedFile = S(10, 5);
244 constexpr Score RookOnOpenFile[] = { S(19, 7), S(48, 27) };
246 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
247 // which piece type attacks which one. Attacks on lesser pieces which are
248 // pawn-defended are not considered.
249 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
250 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
253 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
254 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
257 // Assorted bonuses and penalties
258 constexpr Score BadOutpost = S( -7, 36);
259 constexpr Score BishopOnKingRing = S( 24, 0);
260 constexpr Score BishopXRayPawns = S( 4, 5);
261 constexpr Score CorneredBishop = S( 50, 50);
262 constexpr Score FlankAttacks = S( 8, 0);
263 constexpr Score Hanging = S( 69, 36);
264 constexpr Score KnightOnQueen = S( 16, 11);
265 constexpr Score LongDiagonalBishop = S( 45, 0);
266 constexpr Score MinorBehindPawn = S( 18, 3);
267 constexpr Score PassedFile = S( 11, 8);
268 constexpr Score PawnlessFlank = S( 17, 95);
269 constexpr Score ReachableOutpost = S( 31, 22);
270 constexpr Score RestrictedPiece = S( 7, 7);
271 constexpr Score RookOnKingRing = S( 16, 0);
272 constexpr Score SliderOnQueen = S( 60, 18);
273 constexpr Score ThreatByKing = S( 24, 89);
274 constexpr Score ThreatByPawnPush = S( 48, 39);
275 constexpr Score ThreatBySafePawn = S(173, 94);
276 constexpr Score TrappedRook = S( 55, 13);
277 constexpr Score WeakQueenProtection = S( 14, 0);
278 constexpr Score WeakQueen = S( 56, 15);
283 // Evaluation class computes and stores attacks tables and other working data
288 Evaluation() = delete;
289 explicit Evaluation(const Position& p) : pos(p) {}
290 Evaluation& operator=(const Evaluation&) = delete;
294 template<Color Us> void initialize();
295 template<Color Us, PieceType Pt> Score pieces();
296 template<Color Us> Score king() const;
297 template<Color Us> Score threats() const;
298 template<Color Us> Score passed() const;
299 template<Color Us> Score space() const;
300 Value winnable(Score score) const;
305 Bitboard mobilityArea[COLOR_NB];
306 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
308 // attackedBy[color][piece type] is a bitboard representing all squares
309 // attacked by a given color and piece type. Special "piece types" which
310 // is also calculated is ALL_PIECES.
311 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
313 // attackedBy2[color] are the squares attacked by at least 2 units of a given
314 // color, including x-rays. But diagonal x-rays through pawns are not computed.
315 Bitboard attackedBy2[COLOR_NB];
317 // kingRing[color] are the squares adjacent to the king plus some other
318 // very near squares, depending on king position.
319 Bitboard kingRing[COLOR_NB];
321 // kingAttackersCount[color] is the number of pieces of the given color
322 // which attack a square in the kingRing of the enemy king.
323 int kingAttackersCount[COLOR_NB];
325 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
326 // the given color which attack a square in the kingRing of the enemy king.
327 // The weights of the individual piece types are given by the elements in
328 // the KingAttackWeights array.
329 int kingAttackersWeight[COLOR_NB];
331 // kingAttacksCount[color] is the number of attacks by the given color to
332 // squares directly adjacent to the enemy king. Pieces which attack more
333 // than one square are counted multiple times. For instance, if there is
334 // a white knight on g5 and black's king is on g8, this white knight adds 2
335 // to kingAttacksCount[WHITE].
336 int kingAttacksCount[COLOR_NB];
340 // Evaluation::initialize() computes king and pawn attacks, and the king ring
341 // bitboard for a given color. This is done at the beginning of the evaluation.
343 template<Tracing T> template<Color Us>
344 void Evaluation<T>::initialize() {
346 constexpr Color Them = ~Us;
347 constexpr Direction Up = pawn_push(Us);
348 constexpr Direction Down = -Up;
349 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
351 const Square ksq = pos.square<KING>(Us);
353 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
355 // Find our pawns that are blocked or on the first two ranks
356 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
358 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
359 // or controlled by enemy pawns are excluded from the mobility area.
360 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
362 // Initialize attackedBy[] for king and pawns
363 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
364 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
365 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
366 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
368 // Init our king safety tables
369 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
370 std::clamp(rank_of(ksq), RANK_2, RANK_7));
371 kingRing[Us] = attacks_bb<KING>(s) | s;
373 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
374 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
376 // Remove from kingRing[] the squares defended by two pawns
377 kingRing[Us] &= ~dblAttackByPawn;
381 // Evaluation::pieces() scores pieces of a given color and type
383 template<Tracing T> template<Color Us, PieceType Pt>
384 Score Evaluation<T>::pieces() {
386 constexpr Color Them = ~Us;
387 constexpr Direction Down = -pawn_push(Us);
388 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
389 : Rank5BB | Rank4BB | Rank3BB);
390 const Square* pl = pos.squares<Pt>(Us);
393 Score score = SCORE_ZERO;
395 attackedBy[Us][Pt] = 0;
397 for (Square s = *pl; s != SQ_NONE; s = *++pl)
399 // Find attacked squares, including x-ray attacks for bishops and rooks
400 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
401 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
402 : attacks_bb<Pt>(s, pos.pieces());
404 if (pos.blockers_for_king(Us) & s)
405 b &= line_bb(pos.square<KING>(Us), s);
407 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
408 attackedBy[Us][Pt] |= b;
409 attackedBy[Us][ALL_PIECES] |= b;
411 if (b & kingRing[Them])
413 kingAttackersCount[Us]++;
414 kingAttackersWeight[Us] += KingAttackWeights[Pt];
415 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
418 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
419 score += RookOnKingRing;
421 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
422 score += BishopOnKingRing;
424 int mob = popcount(b & mobilityArea[Us]);
426 mobility[Us] += MobilityBonus[Pt - 2][mob];
428 if (Pt == BISHOP || Pt == KNIGHT)
430 // Bonus if the piece is on an outpost square or can reach one
431 // Reduced bonus for knights (BadOutpost) if few relevant targets
432 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
433 & ~pe->pawn_attacks_span(Them);
434 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
437 && bb & s & ~CenterFiles // on a side outpost
438 && !(b & targets) // no relevant attacks
439 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
442 score += Outpost[Pt == BISHOP];
443 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
444 score += ReachableOutpost;
446 // Bonus for a knight or bishop shielded by pawn
447 if (shift<Down>(pos.pieces(PAWN)) & s)
448 score += MinorBehindPawn;
450 // Penalty if the piece is far from the king
451 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
455 // Penalty according to the number of our pawns on the same color square as the
456 // bishop, bigger when the center files are blocked with pawns and smaller
457 // when the bishop is outside the pawn chain.
458 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
460 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
461 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
463 // Penalty for all enemy pawns x-rayed
464 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
466 // Bonus for bishop on a long diagonal which can "see" both center squares
467 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
468 score += LongDiagonalBishop;
470 // An important Chess960 pattern: a cornered bishop blocked by a friendly
471 // pawn diagonally in front of it is a very serious problem, especially
472 // when that pawn is also blocked.
473 if ( pos.is_chess960()
474 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
476 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
477 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
478 score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
479 : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
487 // Bonuses for rook on a (semi-)open or closed file
488 if (pos.is_on_semiopen_file(Us, s))
490 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
494 // If our pawn on this file is blocked, increase penalty
495 if ( pos.pieces(Us, PAWN)
496 & shift<Down>(pos.pieces())
499 score -= RookOnClosedFile;
502 // Penalty when trapped by the king, even more if the king cannot castle
505 File kf = file_of(pos.square<KING>(Us));
506 if ((kf < FILE_E) == (file_of(s) < kf))
507 score -= TrappedRook * (1 + !pos.castling_rights(Us));
514 // Penalty if any relative pin or discovered attack against the queen
515 Bitboard queenPinners;
516 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
521 Trace::add(Pt, Us, score);
527 // Evaluation::king() assigns bonuses and penalties to a king of a given color
529 template<Tracing T> template<Color Us>
530 Score Evaluation<T>::king() const {
532 constexpr Color Them = ~Us;
533 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
534 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
536 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
537 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
539 const Square ksq = pos.square<KING>(Us);
541 // Init the score with king shelter and enemy pawns storm
542 Score score = pe->king_safety<Us>(pos);
544 // Attacked squares defended at most once by our queen or king
545 weak = attackedBy[Them][ALL_PIECES]
547 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
549 // Analyse the safe enemy's checks which are possible on next move
550 safe = ~pos.pieces(Them);
551 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
553 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
554 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
556 // Enemy rooks checks
557 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
559 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
561 unsafeChecks |= b1 & attackedBy[Them][ROOK];
563 // Enemy queen safe checks: count them only if the checks are from squares from
564 // which opponent cannot give a rook check, because rook checks are more valuable.
565 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
566 & ~(attackedBy[Us][QUEEN] | rookChecks);
568 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
570 // Enemy bishops checks: count them only if they are from squares from which
571 // opponent cannot give a queen check, because queen checks are more valuable.
572 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
575 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
578 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
580 // Enemy knights checks
581 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
582 if (knightChecks & safe)
583 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
585 unsafeChecks |= knightChecks;
587 // Find the squares that opponent attacks in our king flank, the squares
588 // which they attack twice in that flank, and the squares that we defend.
589 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
590 b2 = b1 & attackedBy2[Them];
591 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
593 int kingFlankAttack = popcount(b1) + popcount(b2);
594 int kingFlankDefense = popcount(b3);
596 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
597 + 185 * popcount(kingRing[Us] & weak) // (~15 Elo)
598 + 148 * popcount(unsafeChecks) // (~4 Elo)
599 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
600 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
601 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
602 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
603 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
604 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
605 - 6 * mg_value(score) / 8 // (~8 Elo)
606 - 4 * kingFlankDefense // (~5 Elo)
609 // Transform the kingDanger units into a Score, and subtract it from the evaluation
610 if (kingDanger > 100)
611 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
613 // Penalty when our king is on a pawnless flank
614 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
615 score -= PawnlessFlank;
617 // Penalty if king flank is under attack, potentially moving toward the king
618 score -= FlankAttacks * kingFlankAttack;
621 Trace::add(KING, Us, score);
627 // Evaluation::threats() assigns bonuses according to the types of the
628 // attacking and the attacked pieces.
630 template<Tracing T> template<Color Us>
631 Score Evaluation<T>::threats() const {
633 constexpr Color Them = ~Us;
634 constexpr Direction Up = pawn_push(Us);
635 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
637 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
638 Score score = SCORE_ZERO;
641 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
643 // Squares strongly protected by the enemy, either because they defend the
644 // square with a pawn, or because they defend the square twice and we don't.
645 stronglyProtected = attackedBy[Them][PAWN]
646 | (attackedBy2[Them] & ~attackedBy2[Us]);
648 // Non-pawn enemies, strongly protected
649 defended = nonPawnEnemies & stronglyProtected;
651 // Enemies not strongly protected and under our attack
652 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
654 // Bonus according to the kind of attacking pieces
657 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
659 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
661 b = weak & attackedBy[Us][ROOK];
663 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
665 if (weak & attackedBy[Us][KING])
666 score += ThreatByKing;
668 b = ~attackedBy[Them][ALL_PIECES]
669 | (nonPawnEnemies & attackedBy2[Us]);
670 score += Hanging * popcount(weak & b);
672 // Additional bonus if weak piece is only protected by a queen
673 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
676 // Bonus for restricting their piece moves
677 b = attackedBy[Them][ALL_PIECES]
679 & attackedBy[Us][ALL_PIECES];
680 score += RestrictedPiece * popcount(b);
682 // Protected or unattacked squares
683 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
685 // Bonus for attacking enemy pieces with our relatively safe pawns
686 b = pos.pieces(Us, PAWN) & safe;
687 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
688 score += ThreatBySafePawn * popcount(b);
690 // Find squares where our pawns can push on the next move
691 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
692 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
694 // Keep only the squares which are relatively safe
695 b &= ~attackedBy[Them][PAWN] & safe;
697 // Bonus for safe pawn threats on the next move
698 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
699 score += ThreatByPawnPush * popcount(b);
701 // Bonus for threats on the next moves against enemy queen
702 if (pos.count<QUEEN>(Them) == 1)
704 bool queenImbalance = pos.count<QUEEN>() == 1;
706 Square s = pos.square<QUEEN>(Them);
707 safe = mobilityArea[Us]
708 & ~pos.pieces(Us, PAWN)
709 & ~stronglyProtected;
711 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
713 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
715 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
716 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
718 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
722 Trace::add(THREAT, Us, score);
727 // Evaluation::passed() evaluates the passed pawns and candidate passed
728 // pawns of the given color.
730 template<Tracing T> template<Color Us>
731 Score Evaluation<T>::passed() const {
733 constexpr Color Them = ~Us;
734 constexpr Direction Up = pawn_push(Us);
735 constexpr Direction Down = -Up;
737 auto king_proximity = [&](Color c, Square s) {
738 return std::min(distance(pos.square<KING>(c), s), 5);
741 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
742 Score score = SCORE_ZERO;
744 b = pe->passed_pawns(Us);
746 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
749 helpers = shift<Up>(pos.pieces(Us, PAWN))
751 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
753 // Remove blocked candidate passers that don't have help to pass
755 | shift<WEST>(helpers)
756 | shift<EAST>(helpers);
761 Square s = pop_lsb(&b);
763 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
765 int r = relative_rank(Us, s);
767 Score bonus = PassedRank[r];
772 Square blockSq = s + Up;
774 // Adjust bonus based on the king's proximity
775 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
776 - king_proximity(Us, blockSq) * 2) * w);
778 // If blockSq is not the queening square then consider also a second push
780 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
782 // If the pawn is free to advance, then increase the bonus
783 if (pos.empty(blockSq))
785 squaresToQueen = forward_file_bb(Us, s);
786 unsafeSquares = passed_pawn_span(Us, s);
788 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
790 if (!(pos.pieces(Them) & bb))
791 unsafeSquares &= attackedBy[Them][ALL_PIECES];
793 // If there are no enemy attacks on passed pawn span, assign a big bonus.
794 // Otherwise assign a smaller bonus if the path to queen is not attacked
795 // and even smaller bonus if it is attacked but block square is not.
796 int k = !unsafeSquares ? 35 :
797 !(unsafeSquares & squaresToQueen) ? 20 :
798 !(unsafeSquares & blockSq) ? 9 :
801 // Assign a larger bonus if the block square is defended
802 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
805 bonus += make_score(k * w, k * w);
809 score += bonus - PassedFile * edge_distance(file_of(s));
813 Trace::add(PASSED, Us, score);
819 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
820 // play in the opening. It is based on the number of safe squares on the four central files
821 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
822 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
824 template<Tracing T> template<Color Us>
825 Score Evaluation<T>::space() const {
827 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
828 if (pos.non_pawn_material() < SpaceThreshold)
831 constexpr Color Them = ~Us;
832 constexpr Direction Down = -pawn_push(Us);
833 constexpr Bitboard SpaceMask =
834 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
835 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
837 // Find the available squares for our pieces inside the area defined by SpaceMask
838 Bitboard safe = SpaceMask
839 & ~pos.pieces(Us, PAWN)
840 & ~attackedBy[Them][PAWN];
842 // Find all squares which are at most three squares behind some friendly pawn
843 Bitboard behind = pos.pieces(Us, PAWN);
844 behind |= shift<Down>(behind);
845 behind |= shift<Down+Down>(behind);
847 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
848 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
849 Score score = make_score(bonus * weight * weight / 16, 0);
852 Trace::add(SPACE, Us, score);
858 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
859 // the known attacking/defending status of the players. The final value is derived
860 // by interpolation from the midgame and endgame values.
863 Value Evaluation<T>::winnable(Score score) const {
865 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
866 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
868 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
869 && (pos.pieces(PAWN) & KingSide);
871 bool almostUnwinnable = outflanking < 0
872 && !pawnsOnBothFlanks;
874 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
875 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
877 // Compute the initiative bonus for the attacking side
878 int complexity = 9 * pe->passed_count()
879 + 12 * pos.count<PAWN>()
881 + 21 * pawnsOnBothFlanks
883 + 51 * !pos.non_pawn_material()
884 - 43 * almostUnwinnable
887 Value mg = mg_value(score);
888 Value eg = eg_value(score);
890 // Now apply the bonus: note that we find the attacking side by extracting the
891 // sign of the midgame or endgame values, and that we carefully cap the bonus
892 // so that the midgame and endgame scores do not change sign after the bonus.
893 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
894 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
899 // Compute the scale factor for the winning side
900 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
901 int sf = me->scale_factor(pos, strongSide);
903 // If scale factor is not already specific, scale down via general heuristics
904 if (sf == SCALE_FACTOR_NORMAL)
906 if (pos.opposite_bishops())
908 if ( pos.non_pawn_material(WHITE) == BishopValueMg
909 && pos.non_pawn_material(BLACK) == BishopValueMg)
910 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
912 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
914 else if ( pos.non_pawn_material(WHITE) == RookValueMg
915 && pos.non_pawn_material(BLACK) == RookValueMg
916 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
917 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
918 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
920 else if (pos.count<QUEEN>() == 1)
921 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
922 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
924 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
926 sf -= 4 * !pawnsOnBothFlanks;
929 // Interpolate between the middlegame and (scaled by 'sf') endgame score
930 v = mg * int(me->game_phase())
931 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
936 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
937 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
944 // Evaluation::value() is the main function of the class. It computes the various
945 // parts of the evaluation and returns the value of the position from the point
946 // of view of the side to move.
949 Value Evaluation<T>::value() {
951 assert(!pos.checkers());
953 // Probe the material hash table
954 me = Material::probe(pos);
956 // If we have a specialized evaluation function for the current material
957 // configuration, call it and return.
958 if (me->specialized_eval_exists())
959 return me->evaluate(pos);
961 // Initialize score by reading the incrementally updated scores included in
962 // the position object (material + piece square tables) and the material
963 // imbalance. Score is computed internally from the white point of view.
964 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
966 // Probe the pawn hash table
967 pe = Pawns::probe(pos);
968 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
970 // Early exit if score is high
971 auto lazy_skip = [&](Value lazyThreshold) {
972 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
975 if (lazy_skip(LazyThreshold1))
978 // Main evaluation begins here
982 // Pieces evaluated first (also populates attackedBy, attackedBy2).
983 // Note that the order of evaluation of the terms is left unspecified.
984 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
985 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
986 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
987 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
989 score += mobility[WHITE] - mobility[BLACK];
991 // More complex interactions that require fully populated attack bitboards
992 score += king< WHITE>() - king< BLACK>()
993 + passed< WHITE>() - passed< BLACK>();
995 if (lazy_skip(LazyThreshold2))
998 score += threats<WHITE>() - threats<BLACK>()
999 + space< WHITE>() - space< BLACK>();
1002 // Derive single value from mg and eg parts of score
1003 Value v = winnable(score);
1005 // In case of tracing add all remaining individual evaluation terms
1008 Trace::add(MATERIAL, pos.psq_score());
1009 Trace::add(IMBALANCE, me->imbalance());
1010 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1011 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1017 // Side to move point of view
1018 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
1026 /// evaluate() is the evaluator for the outer world. It returns a static
1027 /// evaluation of the position from the point of view of the side to move.
1029 Value Eval::evaluate(const Position& pos) {
1034 v = Evaluation<NO_TRACE>(pos).value();
1037 // Scale and shift NNUE for compatibility with search and classical evaluation
1038 auto adjusted_NNUE = [&](){
1039 int mat = pos.non_pawn_material() + PawnValueMg * pos.count<PAWN>();
1040 return NNUE::evaluate(pos) * (720 + mat / 32) / 1024 + Tempo;
1043 // If there is PSQ imbalance use classical eval, with small probability if it is small
1044 Value psq = Value(abs(eg_value(pos.psq_score())));
1045 int r50 = 16 + pos.rule50_count();
1046 bool largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50;
1047 bool classical = largePsq || (psq > PawnValueMg / 4 && !(pos.this_thread()->nodes & 0xB));
1049 bool strongClassical = pos.non_pawn_material() < 2 * RookValueMg && pos.count<PAWN>() < 2;
1051 v = classical || strongClassical ? Evaluation<NO_TRACE>(pos).value() : adjusted_NNUE();
1053 // If the classical eval is small and imbalance large, use NNUE nevertheless.
1054 // For the case of opposite colored bishops, switch to NNUE eval with
1055 // small probability if the classical eval is less than the threshold.
1056 if ( largePsq && !strongClassical
1057 && ( abs(v) * 16 < NNUEThreshold2 * r50
1058 || ( pos.opposite_bishops()
1059 && abs(v) * 16 < (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50
1060 && !(pos.this_thread()->nodes & 0xB))))
1061 v = adjusted_NNUE();
1064 // Damp down the evaluation linearly when shuffling
1065 v = v * (100 - pos.rule50_count()) / 100;
1067 // Guarantee evaluation does not hit the tablebase range
1068 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1073 /// trace() is like evaluate(), but instead of returning a value, it returns
1074 /// a string (suitable for outputting to stdout) that contains the detailed
1075 /// descriptions and values of each evaluation term. Useful for debugging.
1076 /// Trace scores are from white's point of view
1078 std::string Eval::trace(const Position& pos) {
1081 return "Final evaluation: none (in check)";
1083 std::stringstream ss;
1084 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1088 std::memset(scores, 0, sizeof(scores));
1090 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
1092 v = Evaluation<TRACE>(pos).value();
1094 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1095 << " Term | White | Black | Total \n"
1096 << " | MG EG | MG EG | MG EG \n"
1097 << " ------------+-------------+-------------+------------\n"
1098 << " Material | " << Term(MATERIAL)
1099 << " Imbalance | " << Term(IMBALANCE)
1100 << " Pawns | " << Term(PAWN)
1101 << " Knights | " << Term(KNIGHT)
1102 << " Bishops | " << Term(BISHOP)
1103 << " Rooks | " << Term(ROOK)
1104 << " Queens | " << Term(QUEEN)
1105 << " Mobility | " << Term(MOBILITY)
1106 << " King safety | " << Term(KING)
1107 << " Threats | " << Term(THREAT)
1108 << " Passed | " << Term(PASSED)
1109 << " Space | " << Term(SPACE)
1110 << " Winnable | " << Term(WINNABLE)
1111 << " ------------+-------------+-------------+------------\n"
1112 << " Total | " << Term(TOTAL);
1114 v = pos.side_to_move() == WHITE ? v : -v;
1116 ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n";
1120 v = NNUE::evaluate(pos);
1121 v = pos.side_to_move() == WHITE ? v : -v;
1122 ss << "\nNNUE evaluation: " << to_cp(v) << " (white side)\n";
1126 v = pos.side_to_move() == WHITE ? v : -v;
1127 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";