2 Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3 Copyright (C) 2004-2021 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
38 #include "incbin/incbin.h"
41 // Macro to embed the default efficiently updatable neural network (NNUE) file
42 // data in the engine binary (using incbin.h, by Dale Weiler).
43 // This macro invocation will declare the following three variables
44 // const unsigned char gEmbeddedNNUEData[]; // a pointer to the embedded data
45 // const unsigned char *const gEmbeddedNNUEEnd; // a marker to the end
46 // const unsigned int gEmbeddedNNUESize; // the size of the embedded file
47 // Note that this does not work in Microsoft Visual Studio.
48 #if !defined(_MSC_VER) && !defined(NNUE_EMBEDDING_OFF)
49 INCBIN(EmbeddedNNUE, EvalFileDefaultName);
51 const unsigned char gEmbeddedNNUEData[1] = {0x0};
52 const unsigned char *const gEmbeddedNNUEEnd = &gEmbeddedNNUEData[1];
53 const unsigned int gEmbeddedNNUESize = 1;
64 string eval_file_loaded = "None";
66 /// NNUE::init() tries to load a NNUE network at startup time, or when the engine
67 /// receives a UCI command "setoption name EvalFile value nn-[a-z0-9]{12}.nnue"
68 /// The name of the NNUE network is always retrieved from the EvalFile option.
69 /// We search the given network in three locations: internally (the default
70 /// network may be embedded in the binary), in the active working directory and
71 /// in the engine directory. Distro packagers may define the DEFAULT_NNUE_DIRECTORY
72 /// variable to have the engine search in a special directory in their distro.
76 useNNUE = Options["Use NNUE"];
80 string eval_file = string(Options["EvalFile"]);
82 #if defined(DEFAULT_NNUE_DIRECTORY)
83 #define stringify2(x) #x
84 #define stringify(x) stringify2(x)
85 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) };
87 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory };
90 for (string directory : dirs)
91 if (eval_file_loaded != eval_file)
93 if (directory != "<internal>")
95 ifstream stream(directory + eval_file, ios::binary);
96 if (load_eval(eval_file, stream))
97 eval_file_loaded = eval_file;
100 if (directory == "<internal>" && eval_file == EvalFileDefaultName)
102 // C++ way to prepare a buffer for a memory stream
103 class MemoryBuffer : public basic_streambuf<char> {
104 public: MemoryBuffer(char* p, size_t n) { setg(p, p, p + n); setp(p, p + n); }
107 MemoryBuffer buffer(const_cast<char*>(reinterpret_cast<const char*>(gEmbeddedNNUEData)),
108 size_t(gEmbeddedNNUESize));
110 istream stream(&buffer);
111 if (load_eval(eval_file, stream))
112 eval_file_loaded = eval_file;
117 /// NNUE::export_net() exports the currently loaded network to a file
118 void NNUE::export_net(const std::optional<std::string>& filename) {
119 std::string actualFilename;
121 if (filename.has_value())
122 actualFilename = filename.value();
125 if (eval_file_loaded != EvalFileDefaultName)
127 sync_cout << "Failed to export a net. A non-embedded net can only be saved if the filename is specified." << sync_endl;
130 actualFilename = EvalFileDefaultName;
133 ofstream stream(actualFilename, std::ios_base::binary);
135 if (save_eval(stream))
136 sync_cout << "Network saved successfully to " << actualFilename << "." << sync_endl;
138 sync_cout << "Failed to export a net." << sync_endl;
141 /// NNUE::verify() verifies that the last net used was loaded successfully
142 void NNUE::verify() {
144 string eval_file = string(Options["EvalFile"]);
146 if (useNNUE && eval_file_loaded != eval_file)
148 UCI::OptionsMap defaults;
151 string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
152 string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
153 string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
154 string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + string(defaults["EvalFile"]);
155 string msg5 = "The engine will be terminated now.";
157 sync_cout << "info string ERROR: " << msg1 << sync_endl;
158 sync_cout << "info string ERROR: " << msg2 << sync_endl;
159 sync_cout << "info string ERROR: " << msg3 << sync_endl;
160 sync_cout << "info string ERROR: " << msg4 << sync_endl;
161 sync_cout << "info string ERROR: " << msg5 << sync_endl;
167 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
169 sync_cout << "info string classical evaluation enabled" << sync_endl;
175 enum Tracing { NO_TRACE, TRACE };
177 enum Term { // The first 8 entries are reserved for PieceType
178 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
181 Score scores[TERM_NB][COLOR_NB];
183 double to_cp(Value v) { return double(v) / PawnValueEg; }
185 void add(int idx, Color c, Score s) {
189 void add(int idx, Score w, Score b = SCORE_ZERO) {
190 scores[idx][WHITE] = w;
191 scores[idx][BLACK] = b;
194 std::ostream& operator<<(std::ostream& os, Score s) {
195 os << std::setw(5) << to_cp(mg_value(s)) << " "
196 << std::setw(5) << to_cp(eg_value(s));
200 std::ostream& operator<<(std::ostream& os, Term t) {
202 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
203 os << " ---- ----" << " | " << " ---- ----";
205 os << scores[t][WHITE] << " | " << scores[t][BLACK];
207 os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
212 using namespace Trace;
216 // Threshold for lazy and space evaluation
217 constexpr Value LazyThreshold1 = Value(1565);
218 constexpr Value LazyThreshold2 = Value(1102);
219 constexpr Value SpaceThreshold = Value(11551);
220 constexpr Value NNUEThreshold1 = Value(682);
221 constexpr Value NNUEThreshold2 = Value(176);
223 // KingAttackWeights[PieceType] contains king attack weights by piece type
224 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
226 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
227 // higher if multiple safe checks are possible for that piece type.
228 constexpr int SafeCheck[][2] = {
229 {}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
232 #define S(mg, eg) make_score(mg, eg)
234 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
235 // indexed by piece type and number of attacked squares in the mobility area.
236 constexpr Score MobilityBonus[][32] = {
237 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
238 S( 21, 16), S( 28, 21), S( 37, 26) },
239 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
240 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
241 S( 91, 88), S( 96, 98) },
242 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
243 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
244 S( 57,165), S( 58,170), S( 67,175) },
245 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
246 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
247 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
248 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
249 S(112,178), S(114,185), S(114,187), S(119,221) }
252 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
253 // squares of the same color as our bishop.
254 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
255 S(3, 8), S(3, 9), S(2, 8), S(3, 8)
258 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
259 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
261 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
262 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
263 constexpr Score Outpost[] = { S(57, 38), S(31, 24) };
265 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
266 constexpr Score PassedRank[RANK_NB] = {
267 S(0, 0), S(7, 27), S(16, 32), S(17, 40), S(64, 71), S(170, 174), S(278, 262)
270 constexpr Score RookOnClosedFile = S(10, 5);
271 constexpr Score RookOnOpenFile[] = { S(19, 6), S(47, 26) };
273 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
274 // which piece type attacks which one. Attacks on lesser pieces which are
275 // pawn-defended are not considered.
276 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
277 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
280 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
281 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
284 constexpr Value CorneredBishop = Value(50);
286 // Assorted bonuses and penalties
287 constexpr Score UncontestedOutpost = S( 1, 10);
288 constexpr Score BishopOnKingRing = S( 24, 0);
289 constexpr Score BishopXRayPawns = S( 4, 5);
290 constexpr Score FlankAttacks = S( 8, 0);
291 constexpr Score Hanging = S( 69, 36);
292 constexpr Score KnightOnQueen = S( 16, 11);
293 constexpr Score LongDiagonalBishop = S( 45, 0);
294 constexpr Score MinorBehindPawn = S( 18, 3);
295 constexpr Score PassedFile = S( 11, 8);
296 constexpr Score PawnlessFlank = S( 17, 95);
297 constexpr Score ReachableOutpost = S( 31, 22);
298 constexpr Score RestrictedPiece = S( 7, 7);
299 constexpr Score RookOnKingRing = S( 16, 0);
300 constexpr Score SliderOnQueen = S( 60, 18);
301 constexpr Score ThreatByKing = S( 24, 89);
302 constexpr Score ThreatByPawnPush = S( 48, 39);
303 constexpr Score ThreatBySafePawn = S(173, 94);
304 constexpr Score TrappedRook = S( 55, 13);
305 constexpr Score WeakQueenProtection = S( 14, 0);
306 constexpr Score WeakQueen = S( 56, 15);
311 // Evaluation class computes and stores attacks tables and other working data
316 Evaluation() = delete;
317 explicit Evaluation(const Position& p) : pos(p) {}
318 Evaluation& operator=(const Evaluation&) = delete;
322 template<Color Us> void initialize();
323 template<Color Us, PieceType Pt> Score pieces();
324 template<Color Us> Score king() const;
325 template<Color Us> Score threats() const;
326 template<Color Us> Score passed() const;
327 template<Color Us> Score space() const;
328 Value winnable(Score score) const;
333 Bitboard mobilityArea[COLOR_NB];
334 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
336 // attackedBy[color][piece type] is a bitboard representing all squares
337 // attacked by a given color and piece type. Special "piece types" which
338 // is also calculated is ALL_PIECES.
339 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
341 // attackedBy2[color] are the squares attacked by at least 2 units of a given
342 // color, including x-rays. But diagonal x-rays through pawns are not computed.
343 Bitboard attackedBy2[COLOR_NB];
345 // kingRing[color] are the squares adjacent to the king plus some other
346 // very near squares, depending on king position.
347 Bitboard kingRing[COLOR_NB];
349 // kingAttackersCount[color] is the number of pieces of the given color
350 // which attack a square in the kingRing of the enemy king.
351 int kingAttackersCount[COLOR_NB];
353 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
354 // the given color which attack a square in the kingRing of the enemy king.
355 // The weights of the individual piece types are given by the elements in
356 // the KingAttackWeights array.
357 int kingAttackersWeight[COLOR_NB];
359 // kingAttacksCount[color] is the number of attacks by the given color to
360 // squares directly adjacent to the enemy king. Pieces which attack more
361 // than one square are counted multiple times. For instance, if there is
362 // a white knight on g5 and black's king is on g8, this white knight adds 2
363 // to kingAttacksCount[WHITE].
364 int kingAttacksCount[COLOR_NB];
368 // Evaluation::initialize() computes king and pawn attacks, and the king ring
369 // bitboard for a given color. This is done at the beginning of the evaluation.
371 template<Tracing T> template<Color Us>
372 void Evaluation<T>::initialize() {
374 constexpr Color Them = ~Us;
375 constexpr Direction Up = pawn_push(Us);
376 constexpr Direction Down = -Up;
377 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
379 const Square ksq = pos.square<KING>(Us);
381 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
383 // Find our pawns that are blocked or on the first two ranks
384 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
386 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
387 // or controlled by enemy pawns are excluded from the mobility area.
388 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
390 // Initialize attackedBy[] for king and pawns
391 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
392 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
393 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
394 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
396 // Init our king safety tables
397 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
398 std::clamp(rank_of(ksq), RANK_2, RANK_7));
399 kingRing[Us] = attacks_bb<KING>(s) | s;
401 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
402 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
404 // Remove from kingRing[] the squares defended by two pawns
405 kingRing[Us] &= ~dblAttackByPawn;
409 // Evaluation::pieces() scores pieces of a given color and type
411 template<Tracing T> template<Color Us, PieceType Pt>
412 Score Evaluation<T>::pieces() {
414 constexpr Color Them = ~Us;
415 constexpr Direction Down = -pawn_push(Us);
416 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
417 : Rank5BB | Rank4BB | Rank3BB);
418 Bitboard b1 = pos.pieces(Us, Pt);
420 Score score = SCORE_ZERO;
422 attackedBy[Us][Pt] = 0;
426 Square s = pop_lsb(b1);
428 // Find attacked squares, including x-ray attacks for bishops and rooks
429 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
430 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
431 : attacks_bb<Pt>(s, pos.pieces());
433 if (pos.blockers_for_king(Us) & s)
434 b &= line_bb(pos.square<KING>(Us), s);
436 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
437 attackedBy[Us][Pt] |= b;
438 attackedBy[Us][ALL_PIECES] |= b;
440 if (b & kingRing[Them])
442 kingAttackersCount[Us]++;
443 kingAttackersWeight[Us] += KingAttackWeights[Pt];
444 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
447 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
448 score += RookOnKingRing;
450 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
451 score += BishopOnKingRing;
453 int mob = popcount(b & mobilityArea[Us]);
454 mobility[Us] += MobilityBonus[Pt - 2][mob];
456 if (Pt == BISHOP || Pt == KNIGHT)
458 // Bonus if the piece is on an outpost square or can reach one
459 // Bonus for knights (UncontestedOutpost) if few relevant targets
460 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
461 & ~pe->pawn_attacks_span(Them);
462 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
465 && bb & s & ~CenterFiles // on a side outpost
466 && !(b & targets) // no relevant attacks
467 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
468 score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
470 score += Outpost[Pt == BISHOP];
471 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
472 score += ReachableOutpost;
474 // Bonus for a knight or bishop shielded by pawn
475 if (shift<Down>(pos.pieces(PAWN)) & s)
476 score += MinorBehindPawn;
478 // Penalty if the piece is far from the king
479 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
481 if constexpr (Pt == BISHOP)
483 // Penalty according to the number of our pawns on the same color square as the
484 // bishop, bigger when the center files are blocked with pawns and smaller
485 // when the bishop is outside the pawn chain.
486 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
488 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
489 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
491 // Penalty for all enemy pawns x-rayed
492 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
494 // Bonus for bishop on a long diagonal which can "see" both center squares
495 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
496 score += LongDiagonalBishop;
498 // An important Chess960 pattern: a cornered bishop blocked by a friendly
499 // pawn diagonally in front of it is a very serious problem, especially
500 // when that pawn is also blocked.
501 if ( pos.is_chess960()
502 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
504 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
505 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
506 score -= !pos.empty(s + d + pawn_push(Us)) ? 4 * make_score(CorneredBishop, CorneredBishop)
507 : 3 * make_score(CorneredBishop, CorneredBishop);
512 if constexpr (Pt == ROOK)
514 // Bonuses for rook on a (semi-)open or closed file
515 if (pos.is_on_semiopen_file(Us, s))
517 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
521 // If our pawn on this file is blocked, increase penalty
522 if ( pos.pieces(Us, PAWN)
523 & shift<Down>(pos.pieces())
526 score -= RookOnClosedFile;
529 // Penalty when trapped by the king, even more if the king cannot castle
532 File kf = file_of(pos.square<KING>(Us));
533 if ((kf < FILE_E) == (file_of(s) < kf))
534 score -= TrappedRook * (1 + !pos.castling_rights(Us));
539 if constexpr (Pt == QUEEN)
541 // Penalty if any relative pin or discovered attack against the queen
542 Bitboard queenPinners;
543 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
548 Trace::add(Pt, Us, score);
554 // Evaluation::king() assigns bonuses and penalties to a king of a given color
556 template<Tracing T> template<Color Us>
557 Score Evaluation<T>::king() const {
559 constexpr Color Them = ~Us;
560 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
561 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
563 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
564 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
566 const Square ksq = pos.square<KING>(Us);
568 // Init the score with king shelter and enemy pawns storm
569 Score score = pe->king_safety<Us>(pos);
571 // Attacked squares defended at most once by our queen or king
572 weak = attackedBy[Them][ALL_PIECES]
574 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
576 // Analyse the safe enemy's checks which are possible on next move
577 safe = ~pos.pieces(Them);
578 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
580 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
581 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
583 // Enemy rooks checks
584 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
586 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
588 unsafeChecks |= b1 & attackedBy[Them][ROOK];
590 // Enemy queen safe checks: count them only if the checks are from squares from
591 // which opponent cannot give a rook check, because rook checks are more valuable.
592 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
593 & ~(attackedBy[Us][QUEEN] | rookChecks);
595 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
597 // Enemy bishops checks: count them only if they are from squares from which
598 // opponent cannot give a queen check, because queen checks are more valuable.
599 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
602 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
605 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
607 // Enemy knights checks
608 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
609 if (knightChecks & safe)
610 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
612 unsafeChecks |= knightChecks;
614 // Find the squares that opponent attacks in our king flank, the squares
615 // which they attack twice in that flank, and the squares that we defend.
616 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
617 b2 = b1 & attackedBy2[Them];
618 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
620 int kingFlankAttack = popcount(b1) + popcount(b2);
621 int kingFlankDefense = popcount(b3);
623 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
624 + 183 * popcount(kingRing[Us] & weak) // (~15 Elo)
625 + 148 * popcount(unsafeChecks) // (~4 Elo)
626 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
627 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
628 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
629 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
630 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
631 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
632 - 6 * mg_value(score) / 8 // (~8 Elo)
633 - 4 * kingFlankDefense // (~5 Elo)
636 // Transform the kingDanger units into a Score, and subtract it from the evaluation
637 if (kingDanger > 100)
638 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
640 // Penalty when our king is on a pawnless flank
641 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
642 score -= PawnlessFlank;
644 // Penalty if king flank is under attack, potentially moving toward the king
645 score -= FlankAttacks * kingFlankAttack;
648 Trace::add(KING, Us, score);
654 // Evaluation::threats() assigns bonuses according to the types of the
655 // attacking and the attacked pieces.
657 template<Tracing T> template<Color Us>
658 Score Evaluation<T>::threats() const {
660 constexpr Color Them = ~Us;
661 constexpr Direction Up = pawn_push(Us);
662 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
664 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
665 Score score = SCORE_ZERO;
668 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
670 // Squares strongly protected by the enemy, either because they defend the
671 // square with a pawn, or because they defend the square twice and we don't.
672 stronglyProtected = attackedBy[Them][PAWN]
673 | (attackedBy2[Them] & ~attackedBy2[Us]);
675 // Non-pawn enemies, strongly protected
676 defended = nonPawnEnemies & stronglyProtected;
678 // Enemies not strongly protected and under our attack
679 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
681 // Bonus according to the kind of attacking pieces
684 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
686 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(b)))];
688 b = weak & attackedBy[Us][ROOK];
690 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(b)))];
692 if (weak & attackedBy[Us][KING])
693 score += ThreatByKing;
695 b = ~attackedBy[Them][ALL_PIECES]
696 | (nonPawnEnemies & attackedBy2[Us]);
697 score += Hanging * popcount(weak & b);
699 // Additional bonus if weak piece is only protected by a queen
700 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
703 // Bonus for restricting their piece moves
704 b = attackedBy[Them][ALL_PIECES]
706 & attackedBy[Us][ALL_PIECES];
707 score += RestrictedPiece * popcount(b);
709 // Protected or unattacked squares
710 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
712 // Bonus for attacking enemy pieces with our relatively safe pawns
713 b = pos.pieces(Us, PAWN) & safe;
714 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
715 score += ThreatBySafePawn * popcount(b);
717 // Find squares where our pawns can push on the next move
718 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
719 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
721 // Keep only the squares which are relatively safe
722 b &= ~attackedBy[Them][PAWN] & safe;
724 // Bonus for safe pawn threats on the next move
725 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
726 score += ThreatByPawnPush * popcount(b);
728 // Bonus for threats on the next moves against enemy queen
729 if (pos.count<QUEEN>(Them) == 1)
731 bool queenImbalance = pos.count<QUEEN>() == 1;
733 Square s = pos.square<QUEEN>(Them);
734 safe = mobilityArea[Us]
735 & ~pos.pieces(Us, PAWN)
736 & ~stronglyProtected;
738 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
740 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
742 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
743 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
745 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
749 Trace::add(THREAT, Us, score);
754 // Evaluation::passed() evaluates the passed pawns and candidate passed
755 // pawns of the given color.
757 template<Tracing T> template<Color Us>
758 Score Evaluation<T>::passed() const {
760 constexpr Color Them = ~Us;
761 constexpr Direction Up = pawn_push(Us);
762 constexpr Direction Down = -Up;
764 auto king_proximity = [&](Color c, Square s) {
765 return std::min(distance(pos.square<KING>(c), s), 5);
768 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
769 Score score = SCORE_ZERO;
771 b = pe->passed_pawns(Us);
773 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
776 helpers = shift<Up>(pos.pieces(Us, PAWN))
778 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
780 // Remove blocked candidate passers that don't have help to pass
782 | shift<WEST>(helpers)
783 | shift<EAST>(helpers);
788 Square s = pop_lsb(b);
790 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
792 int r = relative_rank(Us, s);
794 Score bonus = PassedRank[r];
799 Square blockSq = s + Up;
801 // Adjust bonus based on the king's proximity
802 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
803 - king_proximity(Us, blockSq) * 2) * w);
805 // If blockSq is not the queening square then consider also a second push
807 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
809 // If the pawn is free to advance, then increase the bonus
810 if (pos.empty(blockSq))
812 squaresToQueen = forward_file_bb(Us, s);
813 unsafeSquares = passed_pawn_span(Us, s);
815 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
817 if (!(pos.pieces(Them) & bb))
818 unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
820 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
821 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
822 // Otherwise assign a smaller bonus if the path to queen is not attacked
823 // and even smaller bonus if it is attacked but block square is not.
824 int k = !unsafeSquares ? 36 :
825 !(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
826 !(unsafeSquares & squaresToQueen) ? 17 :
827 !(unsafeSquares & blockSq) ? 7 :
830 // Assign a larger bonus if the block square is defended
831 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
834 bonus += make_score(k * w, k * w);
838 score += bonus - PassedFile * edge_distance(file_of(s));
842 Trace::add(PASSED, Us, score);
848 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
849 // play in the opening. It is based on the number of safe squares on the four central files
850 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
851 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
853 template<Tracing T> template<Color Us>
854 Score Evaluation<T>::space() const {
856 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
857 if (pos.non_pawn_material() < SpaceThreshold)
860 constexpr Color Them = ~Us;
861 constexpr Direction Down = -pawn_push(Us);
862 constexpr Bitboard SpaceMask =
863 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
864 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
866 // Find the available squares for our pieces inside the area defined by SpaceMask
867 Bitboard safe = SpaceMask
868 & ~pos.pieces(Us, PAWN)
869 & ~attackedBy[Them][PAWN];
871 // Find all squares which are at most three squares behind some friendly pawn
872 Bitboard behind = pos.pieces(Us, PAWN);
873 behind |= shift<Down>(behind);
874 behind |= shift<Down+Down>(behind);
876 // Compute space score based on the number of safe squares and number of our pieces
877 // increased with number of total blocked pawns in position.
878 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
879 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
880 Score score = make_score(bonus * weight * weight / 16, 0);
883 Trace::add(SPACE, Us, score);
889 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
890 // the known attacking/defending status of the players. The final value is derived
891 // by interpolation from the midgame and endgame values.
894 Value Evaluation<T>::winnable(Score score) const {
896 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
897 + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
899 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
900 && (pos.pieces(PAWN) & KingSide);
902 bool almostUnwinnable = outflanking < 0
903 && !pawnsOnBothFlanks;
905 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
906 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
908 // Compute the initiative bonus for the attacking side
909 int complexity = 9 * pe->passed_count()
910 + 12 * pos.count<PAWN>()
912 + 21 * pawnsOnBothFlanks
914 + 51 * !pos.non_pawn_material()
915 - 43 * almostUnwinnable
918 Value mg = mg_value(score);
919 Value eg = eg_value(score);
921 // Now apply the bonus: note that we find the attacking side by extracting the
922 // sign of the midgame or endgame values, and that we carefully cap the bonus
923 // so that the midgame and endgame scores do not change sign after the bonus.
924 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
925 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
930 // Compute the scale factor for the winning side
931 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
932 int sf = me->scale_factor(pos, strongSide);
934 // If scale factor is not already specific, scale up/down via general heuristics
935 if (sf == SCALE_FACTOR_NORMAL)
937 if (pos.opposite_bishops())
939 // For pure opposite colored bishops endgames use scale factor
940 // based on the number of passed pawns of the strong side.
941 if ( pos.non_pawn_material(WHITE) == BishopValueMg
942 && pos.non_pawn_material(BLACK) == BishopValueMg)
943 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
944 // For every other opposite colored bishops endgames use scale factor
945 // based on the number of all pieces of the strong side.
947 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
949 // For rook endgames with strong side not having overwhelming pawn number advantage
950 // and its pawns being on one flank and weak side protecting its pieces with a king
951 // use lower scale factor.
952 else if ( pos.non_pawn_material(WHITE) == RookValueMg
953 && pos.non_pawn_material(BLACK) == RookValueMg
954 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
955 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
956 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
958 // For queen vs no queen endgames use scale factor
959 // based on number of minors of side that doesn't have queen.
960 else if (pos.count<QUEEN>() == 1)
961 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
962 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
963 // In every other case use scale factor based on
964 // the number of pawns of the strong side reduced if pawns are on a single flank.
966 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
968 // Reduce scale factor in case of pawns being on a single flank
969 sf -= 4 * !pawnsOnBothFlanks;
972 // Interpolate between the middlegame and (scaled by 'sf') endgame score
973 v = mg * int(me->game_phase())
974 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
979 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
980 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
987 // Evaluation::value() is the main function of the class. It computes the various
988 // parts of the evaluation and returns the value of the position from the point
989 // of view of the side to move.
992 Value Evaluation<T>::value() {
994 assert(!pos.checkers());
996 // Probe the material hash table
997 me = Material::probe(pos);
999 // If we have a specialized evaluation function for the current material
1000 // configuration, call it and return.
1001 if (me->specialized_eval_exists())
1002 return me->evaluate(pos);
1004 // Initialize score by reading the incrementally updated scores included in
1005 // the position object (material + piece square tables) and the material
1006 // imbalance. Score is computed internally from the white point of view.
1007 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
1009 // Probe the pawn hash table
1010 pe = Pawns::probe(pos);
1011 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
1013 // Early exit if score is high
1014 auto lazy_skip = [&](Value lazyThreshold) {
1015 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
1018 if (lazy_skip(LazyThreshold1))
1021 // Main evaluation begins here
1022 initialize<WHITE>();
1023 initialize<BLACK>();
1025 // Pieces evaluated first (also populates attackedBy, attackedBy2).
1026 // Note that the order of evaluation of the terms is left unspecified.
1027 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
1028 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
1029 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
1030 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
1032 score += mobility[WHITE] - mobility[BLACK];
1034 // More complex interactions that require fully populated attack bitboards
1035 score += king< WHITE>() - king< BLACK>()
1036 + passed< WHITE>() - passed< BLACK>();
1038 if (lazy_skip(LazyThreshold2))
1041 score += threats<WHITE>() - threats<BLACK>()
1042 + space< WHITE>() - space< BLACK>();
1045 // Derive single value from mg and eg parts of score
1046 Value v = winnable(score);
1048 // In case of tracing add all remaining individual evaluation terms
1051 Trace::add(MATERIAL, pos.psq_score());
1052 Trace::add(IMBALANCE, me->imbalance());
1053 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1054 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1060 // Side to move point of view
1061 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
1067 /// Fisher Random Chess: correction for cornered bishops, to fix chess960 play with NNUE
1069 Value fix_FRC(const Position& pos) {
1071 constexpr Bitboard Corners = 1ULL << SQ_A1 | 1ULL << SQ_H1 | 1ULL << SQ_A8 | 1ULL << SQ_H8;
1073 if (!(pos.pieces(BISHOP) & Corners))
1078 if ( pos.piece_on(SQ_A1) == W_BISHOP
1079 && pos.piece_on(SQ_B2) == W_PAWN)
1080 correction += !pos.empty(SQ_B3) ? -CorneredBishop * 4
1081 : -CorneredBishop * 3;
1083 if ( pos.piece_on(SQ_H1) == W_BISHOP
1084 && pos.piece_on(SQ_G2) == W_PAWN)
1085 correction += !pos.empty(SQ_G3) ? -CorneredBishop * 4
1086 : -CorneredBishop * 3;
1088 if ( pos.piece_on(SQ_A8) == B_BISHOP
1089 && pos.piece_on(SQ_B7) == B_PAWN)
1090 correction += !pos.empty(SQ_B6) ? CorneredBishop * 4
1091 : CorneredBishop * 3;
1093 if ( pos.piece_on(SQ_H8) == B_BISHOP
1094 && pos.piece_on(SQ_G7) == B_PAWN)
1095 correction += !pos.empty(SQ_G6) ? CorneredBishop * 4
1096 : CorneredBishop * 3;
1098 return pos.side_to_move() == WHITE ? Value(correction)
1099 : -Value(correction);
1105 /// evaluate() is the evaluator for the outer world. It returns a static
1106 /// evaluation of the position from the point of view of the side to move.
1108 Value Eval::evaluate(const Position& pos) {
1113 v = Evaluation<NO_TRACE>(pos).value();
1116 // Scale and shift NNUE for compatibility with search and classical evaluation
1117 auto adjusted_NNUE = [&]()
1120 int scale = 903 + 28 * pos.count<PAWN>() + 28 * pos.non_pawn_material() / 1024;
1122 Value nnue = NNUE::evaluate(pos) * scale / 1024 + Time.tempoNNUE;
1124 if (pos.is_chess960())
1125 nnue += fix_FRC(pos);
1130 // If there is PSQ imbalance we use the classical eval. We also introduce
1131 // a small probability of using the classical eval when PSQ imbalance is small.
1132 Value psq = Value(abs(eg_value(pos.psq_score())));
1133 int r50 = 16 + pos.rule50_count();
1134 bool largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50;
1135 bool classical = largePsq;
1137 // Use classical evaluation for really low piece endgames.
1138 // One critical case is the draw for bishop + A/H file pawn vs naked king.
1139 bool lowPieceEndgame = pos.non_pawn_material() == BishopValueMg
1140 || (pos.non_pawn_material() < 2 * RookValueMg && pos.count<PAWN>() < 2);
1142 v = classical || lowPieceEndgame ? Evaluation<NO_TRACE>(pos).value()
1145 // If the classical eval is small and imbalance large, use NNUE nevertheless.
1146 // For the case of opposite colored bishops, switch to NNUE eval with small
1147 // probability if the classical eval is less than the threshold.
1150 && ( abs(v) * 16 < NNUEThreshold2 * r50
1151 || ( pos.opposite_bishops()
1152 && abs(v) * 16 < (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50)))
1153 v = adjusted_NNUE();
1156 // Damp down the evaluation linearly when shuffling
1157 v = v * (100 - pos.rule50_count()) / 100;
1159 // Guarantee evaluation does not hit the tablebase range
1160 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1165 /// trace() is like evaluate(), but instead of returning a value, it returns
1166 /// a string (suitable for outputting to stdout) that contains the detailed
1167 /// descriptions and values of each evaluation term. Useful for debugging.
1168 /// Trace scores are from white's point of view
1170 std::string Eval::trace(const Position& pos) {
1173 return "Final evaluation: none (in check)";
1175 std::stringstream ss;
1176 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1180 std::memset(scores, 0, sizeof(scores));
1182 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
1184 v = Evaluation<TRACE>(pos).value();
1186 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1187 << " Term | White | Black | Total \n"
1188 << " | MG EG | MG EG | MG EG \n"
1189 << " ------------+-------------+-------------+------------\n"
1190 << " Material | " << Term(MATERIAL)
1191 << " Imbalance | " << Term(IMBALANCE)
1192 << " Pawns | " << Term(PAWN)
1193 << " Knights | " << Term(KNIGHT)
1194 << " Bishops | " << Term(BISHOP)
1195 << " Rooks | " << Term(ROOK)
1196 << " Queens | " << Term(QUEEN)
1197 << " Mobility | " << Term(MOBILITY)
1198 << " King safety | " << Term(KING)
1199 << " Threats | " << Term(THREAT)
1200 << " Passed | " << Term(PASSED)
1201 << " Space | " << Term(SPACE)
1202 << " Winnable | " << Term(WINNABLE)
1203 << " ------------+-------------+-------------+------------\n"
1204 << " Total | " << Term(TOTAL);
1206 v = pos.side_to_move() == WHITE ? v : -v;
1208 ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n";
1212 v = NNUE::evaluate(pos);
1213 v = pos.side_to_move() == WHITE ? v : -v;
1214 ss << "\nNNUE evaluation: " << to_cp(v) << " (white side)\n";
1218 v = pos.side_to_move() == WHITE ? v : -v;
1219 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";
1224 } // namespace Stockfish