2 Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3 Copyright (C) 2004-2022 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 currentEvalFileName = "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"]);
81 if (eval_file.empty())
82 eval_file = EvalFileDefaultName;
84 #if defined(DEFAULT_NNUE_DIRECTORY)
85 #define stringify2(x) #x
86 #define stringify(x) stringify2(x)
87 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) };
89 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory };
92 for (string directory : dirs)
93 if (currentEvalFileName != eval_file)
95 if (directory != "<internal>")
97 ifstream stream(directory + eval_file, ios::binary);
98 if (load_eval(eval_file, stream))
99 currentEvalFileName = eval_file;
102 if (directory == "<internal>" && eval_file == EvalFileDefaultName)
104 // C++ way to prepare a buffer for a memory stream
105 class MemoryBuffer : public basic_streambuf<char> {
106 public: MemoryBuffer(char* p, size_t n) { setg(p, p, p + n); setp(p, p + n); }
109 MemoryBuffer buffer(const_cast<char*>(reinterpret_cast<const char*>(gEmbeddedNNUEData)),
110 size_t(gEmbeddedNNUESize));
112 istream stream(&buffer);
113 if (load_eval(eval_file, stream))
114 currentEvalFileName = eval_file;
119 /// NNUE::verify() verifies that the last net used was loaded successfully
120 void NNUE::verify() {
122 string eval_file = string(Options["EvalFile"]);
123 if (eval_file.empty())
124 eval_file = EvalFileDefaultName;
126 if (useNNUE && currentEvalFileName != eval_file)
129 string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
130 string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
131 string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
132 string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + std::string(EvalFileDefaultName);
133 string msg5 = "The engine will be terminated now.";
135 sync_cout << "info string ERROR: " << msg1 << sync_endl;
136 sync_cout << "info string ERROR: " << msg2 << sync_endl;
137 sync_cout << "info string ERROR: " << msg3 << sync_endl;
138 sync_cout << "info string ERROR: " << msg4 << sync_endl;
139 sync_cout << "info string ERROR: " << msg5 << sync_endl;
145 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
147 sync_cout << "info string classical evaluation enabled" << sync_endl;
153 enum Tracing { NO_TRACE, TRACE };
155 enum Term { // The first 8 entries are reserved for PieceType
156 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
159 Score scores[TERM_NB][COLOR_NB];
161 double to_cp(Value v) { return double(v) / PawnValueEg; }
163 void add(int idx, Color c, Score s) {
167 void add(int idx, Score w, Score b = SCORE_ZERO) {
168 scores[idx][WHITE] = w;
169 scores[idx][BLACK] = b;
172 std::ostream& operator<<(std::ostream& os, Score s) {
173 os << std::setw(5) << to_cp(mg_value(s)) << " "
174 << std::setw(5) << to_cp(eg_value(s));
178 std::ostream& operator<<(std::ostream& os, Term t) {
180 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
181 os << " ---- ----" << " | " << " ---- ----";
183 os << scores[t][WHITE] << " | " << scores[t][BLACK];
185 os << " | " << scores[t][WHITE] - scores[t][BLACK] << " |\n";
190 using namespace Trace;
194 // Threshold for lazy and space evaluation
195 constexpr Value LazyThreshold1 = Value(3631);
196 constexpr Value LazyThreshold2 = Value(2084);
197 constexpr Value SpaceThreshold = Value(11551);
199 // KingAttackWeights[PieceType] contains king attack weights by piece type
200 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
202 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
203 // higher if multiple safe checks are possible for that piece type.
204 constexpr int SafeCheck[][2] = {
205 {}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
208 #define S(mg, eg) make_score(mg, eg)
210 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
211 // indexed by piece type and number of attacked squares in the mobility area.
212 constexpr Score MobilityBonus[][32] = {
213 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
214 S( 21, 16), S( 28, 21), S( 37, 26) },
215 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
216 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
217 S( 91, 88), S( 96, 98) },
218 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
219 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
220 S( 57,165), S( 58,170), S( 67,175) },
221 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
222 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
223 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
224 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
225 S(112,178), S(114,185), S(114,187), S(119,221) }
228 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
229 // squares of the same color as our bishop.
230 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
231 S(3, 8), S(3, 9), S(2, 8), S(3, 8)
234 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
235 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
237 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
238 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
239 constexpr Score Outpost[] = { S(57, 38), S(31, 24) };
241 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
242 constexpr Score PassedRank[RANK_NB] = {
243 S(0, 0), S(7, 27), S(16, 32), S(17, 40), S(64, 71), S(170, 174), S(278, 262)
246 constexpr Score RookOnClosedFile = S(10, 5);
247 constexpr Score RookOnOpenFile[] = { S(19, 6), S(47, 26) };
249 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
250 // which piece type attacks which one. Attacks on lesser pieces which are
251 // pawn-defended are not considered.
252 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
253 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
256 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
257 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
260 constexpr Value CorneredBishop = Value(50);
262 // Assorted bonuses and penalties
263 constexpr Score UncontestedOutpost = S( 1, 10);
264 constexpr Score BishopOnKingRing = S( 24, 0);
265 constexpr Score BishopXRayPawns = S( 4, 5);
266 constexpr Score FlankAttacks = S( 8, 0);
267 constexpr Score Hanging = S( 69, 36);
268 constexpr Score KnightOnQueen = S( 16, 11);
269 constexpr Score LongDiagonalBishop = S( 45, 0);
270 constexpr Score MinorBehindPawn = S( 18, 3);
271 constexpr Score PassedFile = S( 11, 8);
272 constexpr Score PawnlessFlank = S( 17, 95);
273 constexpr Score ReachableOutpost = S( 31, 22);
274 constexpr Score RestrictedPiece = S( 7, 7);
275 constexpr Score RookOnKingRing = S( 16, 0);
276 constexpr Score SliderOnQueen = S( 60, 18);
277 constexpr Score ThreatByKing = S( 24, 89);
278 constexpr Score ThreatByPawnPush = S( 48, 39);
279 constexpr Score ThreatBySafePawn = S(173, 94);
280 constexpr Score TrappedRook = S( 55, 13);
281 constexpr Score WeakQueenProtection = S( 14, 0);
282 constexpr Score WeakQueen = S( 56, 15);
287 // Evaluation class computes and stores attacks tables and other working data
292 Evaluation() = delete;
293 explicit Evaluation(const Position& p) : pos(p) {}
294 Evaluation& operator=(const Evaluation&) = delete;
298 template<Color Us> void initialize();
299 template<Color Us, PieceType Pt> Score pieces();
300 template<Color Us> Score king() const;
301 template<Color Us> Score threats() const;
302 template<Color Us> Score passed() const;
303 template<Color Us> Score space() const;
304 Value winnable(Score score) const;
309 Bitboard mobilityArea[COLOR_NB];
310 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
312 // attackedBy[color][piece type] is a bitboard representing all squares
313 // attacked by a given color and piece type. Special "piece types" which
314 // is also calculated is ALL_PIECES.
315 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
317 // attackedBy2[color] are the squares attacked by at least 2 units of a given
318 // color, including x-rays. But diagonal x-rays through pawns are not computed.
319 Bitboard attackedBy2[COLOR_NB];
321 // kingRing[color] are the squares adjacent to the king plus some other
322 // very near squares, depending on king position.
323 Bitboard kingRing[COLOR_NB];
325 // kingAttackersCount[color] is the number of pieces of the given color
326 // which attack a square in the kingRing of the enemy king.
327 int kingAttackersCount[COLOR_NB];
329 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
330 // the given color which attack a square in the kingRing of the enemy king.
331 // The weights of the individual piece types are given by the elements in
332 // the KingAttackWeights array.
333 int kingAttackersWeight[COLOR_NB];
335 // kingAttacksCount[color] is the number of attacks by the given color to
336 // squares directly adjacent to the enemy king. Pieces which attack more
337 // than one square are counted multiple times. For instance, if there is
338 // a white knight on g5 and black's king is on g8, this white knight adds 2
339 // to kingAttacksCount[WHITE].
340 int kingAttacksCount[COLOR_NB];
344 // Evaluation::initialize() computes king and pawn attacks, and the king ring
345 // bitboard for a given color. This is done at the beginning of the evaluation.
347 template<Tracing T> template<Color Us>
348 void Evaluation<T>::initialize() {
350 constexpr Color Them = ~Us;
351 constexpr Direction Up = pawn_push(Us);
352 constexpr Direction Down = -Up;
353 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
355 const Square ksq = pos.square<KING>(Us);
357 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
359 // Find our pawns that are blocked or on the first two ranks
360 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
362 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
363 // or controlled by enemy pawns are excluded from the mobility area.
364 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
366 // Initialize attackedBy[] for king and pawns
367 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
368 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
369 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
370 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
372 // Init our king safety tables
373 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
374 std::clamp(rank_of(ksq), RANK_2, RANK_7));
375 kingRing[Us] = attacks_bb<KING>(s) | s;
377 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
378 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
380 // Remove from kingRing[] the squares defended by two pawns
381 kingRing[Us] &= ~dblAttackByPawn;
385 // Evaluation::pieces() scores pieces of a given color and type
387 template<Tracing T> template<Color Us, PieceType Pt>
388 Score Evaluation<T>::pieces() {
390 constexpr Color Them = ~Us;
391 constexpr Direction Down = -pawn_push(Us);
392 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
393 : Rank5BB | Rank4BB | Rank3BB);
394 Bitboard b1 = pos.pieces(Us, Pt);
396 Score score = SCORE_ZERO;
398 attackedBy[Us][Pt] = 0;
402 Square s = pop_lsb(b1);
404 // Find attacked squares, including x-ray attacks for bishops and rooks
405 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
406 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
407 : attacks_bb<Pt>(s, pos.pieces());
409 if (pos.blockers_for_king(Us) & s)
410 b &= line_bb(pos.square<KING>(Us), s);
412 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
413 attackedBy[Us][Pt] |= b;
414 attackedBy[Us][ALL_PIECES] |= b;
416 if (b & kingRing[Them])
418 kingAttackersCount[Us]++;
419 kingAttackersWeight[Us] += KingAttackWeights[Pt];
420 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
423 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
424 score += RookOnKingRing;
426 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
427 score += BishopOnKingRing;
429 int mob = popcount(b & mobilityArea[Us]);
430 mobility[Us] += MobilityBonus[Pt - 2][mob];
432 if (Pt == BISHOP || Pt == KNIGHT)
434 // Bonus if the piece is on an outpost square or can reach one
435 // Bonus for knights (UncontestedOutpost) if few relevant targets
436 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
437 & ~pe->pawn_attacks_span(Them);
438 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
441 && bb & s & ~CenterFiles // on a side outpost
442 && !(b & targets) // no relevant attacks
443 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
444 score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
446 score += Outpost[Pt == BISHOP];
447 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
448 score += ReachableOutpost;
450 // Bonus for a knight or bishop shielded by pawn
451 if (shift<Down>(pos.pieces(PAWN)) & s)
452 score += MinorBehindPawn;
454 // Penalty if the piece is far from the king
455 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
457 if constexpr (Pt == BISHOP)
459 // Penalty according to the number of our pawns on the same color square as the
460 // bishop, bigger when the center files are blocked with pawns and smaller
461 // when the bishop is outside the pawn chain.
462 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
464 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
465 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
467 // Penalty for all enemy pawns x-rayed
468 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
470 // Bonus for bishop on a long diagonal which can "see" both center squares
471 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
472 score += LongDiagonalBishop;
474 // An important Chess960 pattern: a cornered bishop blocked by a friendly
475 // pawn diagonally in front of it is a very serious problem, especially
476 // when that pawn is also blocked.
477 if ( pos.is_chess960()
478 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
480 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
481 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
482 score -= !pos.empty(s + d + pawn_push(Us)) ? 4 * make_score(CorneredBishop, CorneredBishop)
483 : 3 * make_score(CorneredBishop, CorneredBishop);
488 if constexpr (Pt == ROOK)
490 // Bonuses for rook on a (semi-)open or closed file
491 if (pos.is_on_semiopen_file(Us, s))
493 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
497 // If our pawn on this file is blocked, increase penalty
498 if ( pos.pieces(Us, PAWN)
499 & shift<Down>(pos.pieces())
502 score -= RookOnClosedFile;
505 // Penalty when trapped by the king, even more if the king cannot castle
508 File kf = file_of(pos.square<KING>(Us));
509 if ((kf < FILE_E) == (file_of(s) < kf))
510 score -= TrappedRook * (1 + !pos.castling_rights(Us));
515 if constexpr (Pt == QUEEN)
517 // Penalty if any relative pin or discovered attack against the queen
518 Bitboard queenPinners;
519 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
524 Trace::add(Pt, Us, score);
530 // Evaluation::king() assigns bonuses and penalties to a king of a given color
532 template<Tracing T> template<Color Us>
533 Score Evaluation<T>::king() const {
535 constexpr Color Them = ~Us;
536 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
537 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
539 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
540 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
542 const Square ksq = pos.square<KING>(Us);
544 // Init the score with king shelter and enemy pawns storm
545 Score score = pe->king_safety<Us>(pos);
547 // Attacked squares defended at most once by our queen or king
548 weak = attackedBy[Them][ALL_PIECES]
550 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
552 // Analyse the safe enemy's checks which are possible on next move
553 safe = ~pos.pieces(Them);
554 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
556 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
557 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
559 // Enemy rooks checks
560 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
562 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
564 unsafeChecks |= b1 & attackedBy[Them][ROOK];
566 // Enemy queen safe checks: count them only if the checks are from squares from
567 // which opponent cannot give a rook check, because rook checks are more valuable.
568 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
569 & ~(attackedBy[Us][QUEEN] | rookChecks);
571 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
573 // Enemy bishops checks: count them only if they are from squares from which
574 // opponent cannot give a queen check, because queen checks are more valuable.
575 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
578 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
581 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
583 // Enemy knights checks
584 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
585 if (knightChecks & safe)
586 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
588 unsafeChecks |= knightChecks;
590 // Find the squares that opponent attacks in our king flank, the squares
591 // which they attack twice in that flank, and the squares that we defend.
592 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
593 b2 = b1 & attackedBy2[Them];
594 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
596 int kingFlankAttack = popcount(b1) + popcount(b2);
597 int kingFlankDefense = popcount(b3);
599 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
600 + 183 * popcount(kingRing[Us] & weak) // (~15 Elo)
601 + 148 * popcount(unsafeChecks) // (~4 Elo)
602 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
603 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
604 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
605 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
606 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
607 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
608 - 6 * mg_value(score) / 8 // (~8 Elo)
609 - 4 * kingFlankDefense // (~5 Elo)
612 // Transform the kingDanger units into a Score, and subtract it from the evaluation
613 if (kingDanger > 100)
614 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
616 // Penalty when our king is on a pawnless flank
617 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
618 score -= PawnlessFlank;
620 // Penalty if king flank is under attack, potentially moving toward the king
621 score -= FlankAttacks * kingFlankAttack;
624 Trace::add(KING, Us, score);
630 // Evaluation::threats() assigns bonuses according to the types of the
631 // attacking and the attacked pieces.
633 template<Tracing T> template<Color Us>
634 Score Evaluation<T>::threats() const {
636 constexpr Color Them = ~Us;
637 constexpr Direction Up = pawn_push(Us);
638 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
640 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
641 Score score = SCORE_ZERO;
644 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
646 // Squares strongly protected by the enemy, either because they defend the
647 // square with a pawn, or because they defend the square twice and we don't.
648 stronglyProtected = attackedBy[Them][PAWN]
649 | (attackedBy2[Them] & ~attackedBy2[Us]);
651 // Non-pawn enemies, strongly protected
652 defended = nonPawnEnemies & stronglyProtected;
654 // Enemies not strongly protected and under our attack
655 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
657 // Bonus according to the kind of attacking pieces
660 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
662 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(b)))];
664 b = weak & attackedBy[Us][ROOK];
666 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(b)))];
668 if (weak & attackedBy[Us][KING])
669 score += ThreatByKing;
671 b = ~attackedBy[Them][ALL_PIECES]
672 | (nonPawnEnemies & attackedBy2[Us]);
673 score += Hanging * popcount(weak & b);
675 // Additional bonus if weak piece is only protected by a queen
676 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
679 // Bonus for restricting their piece moves
680 b = attackedBy[Them][ALL_PIECES]
682 & attackedBy[Us][ALL_PIECES];
683 score += RestrictedPiece * popcount(b);
685 // Protected or unattacked squares
686 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
688 // Bonus for attacking enemy pieces with our relatively safe pawns
689 b = pos.pieces(Us, PAWN) & safe;
690 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
691 score += ThreatBySafePawn * popcount(b);
693 // Find squares where our pawns can push on the next move
694 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
695 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
697 // Keep only the squares which are relatively safe
698 b &= ~attackedBy[Them][PAWN] & safe;
700 // Bonus for safe pawn threats on the next move
701 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
702 score += ThreatByPawnPush * popcount(b);
704 // Bonus for threats on the next moves against enemy queen
705 if (pos.count<QUEEN>(Them) == 1)
707 bool queenImbalance = pos.count<QUEEN>() == 1;
709 Square s = pos.square<QUEEN>(Them);
710 safe = mobilityArea[Us]
711 & ~pos.pieces(Us, PAWN)
712 & ~stronglyProtected;
714 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
716 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
718 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
719 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
721 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
725 Trace::add(THREAT, Us, score);
730 // Evaluation::passed() evaluates the passed pawns and candidate passed
731 // pawns of the given color.
733 template<Tracing T> template<Color Us>
734 Score Evaluation<T>::passed() const {
736 constexpr Color Them = ~Us;
737 constexpr Direction Up = pawn_push(Us);
738 constexpr Direction Down = -Up;
740 auto king_proximity = [&](Color c, Square s) {
741 return std::min(distance(pos.square<KING>(c), s), 5);
744 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
745 Score score = SCORE_ZERO;
747 b = pe->passed_pawns(Us);
749 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
752 helpers = shift<Up>(pos.pieces(Us, PAWN))
754 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
756 // Remove blocked candidate passers that don't have help to pass
758 | shift<WEST>(helpers)
759 | shift<EAST>(helpers);
764 Square s = pop_lsb(b);
766 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
768 int r = relative_rank(Us, s);
770 Score bonus = PassedRank[r];
775 Square blockSq = s + Up;
777 // Adjust bonus based on the king's proximity
778 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
779 - king_proximity(Us, blockSq) * 2) * w);
781 // If blockSq is not the queening square then consider also a second push
783 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
785 // If the pawn is free to advance, then increase the bonus
786 if (pos.empty(blockSq))
788 squaresToQueen = forward_file_bb(Us, s);
789 unsafeSquares = passed_pawn_span(Us, s);
791 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
793 if (!(pos.pieces(Them) & bb))
794 unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
796 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
797 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
798 // Otherwise assign a smaller bonus if the path to queen is not attacked
799 // and even smaller bonus if it is attacked but block square is not.
800 int k = !unsafeSquares ? 36 :
801 !(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
802 !(unsafeSquares & squaresToQueen) ? 17 :
803 !(unsafeSquares & blockSq) ? 7 :
806 // Assign a larger bonus if the block square is defended
807 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
810 bonus += make_score(k * w, k * w);
814 score += bonus - PassedFile * edge_distance(file_of(s));
818 Trace::add(PASSED, Us, score);
824 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
825 // play in the opening. It is based on the number of safe squares on the four central files
826 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
827 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
829 template<Tracing T> template<Color Us>
830 Score Evaluation<T>::space() const {
832 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
833 if (pos.non_pawn_material() < SpaceThreshold)
836 constexpr Color Them = ~Us;
837 constexpr Direction Down = -pawn_push(Us);
838 constexpr Bitboard SpaceMask =
839 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
840 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
842 // Find the available squares for our pieces inside the area defined by SpaceMask
843 Bitboard safe = SpaceMask
844 & ~pos.pieces(Us, PAWN)
845 & ~attackedBy[Them][PAWN];
847 // Find all squares which are at most three squares behind some friendly pawn
848 Bitboard behind = pos.pieces(Us, PAWN);
849 behind |= shift<Down>(behind);
850 behind |= shift<Down+Down>(behind);
852 // Compute space score based on the number of safe squares and number of our pieces
853 // increased with number of total blocked pawns in position.
854 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
855 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
856 Score score = make_score(bonus * weight * weight / 16, 0);
859 Trace::add(SPACE, Us, score);
865 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
866 // the known attacking/defending status of the players. The final value is derived
867 // by interpolation from the midgame and endgame values.
870 Value Evaluation<T>::winnable(Score score) const {
872 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
873 + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
875 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
876 && (pos.pieces(PAWN) & KingSide);
878 bool almostUnwinnable = outflanking < 0
879 && !pawnsOnBothFlanks;
881 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
882 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
884 // Compute the initiative bonus for the attacking side
885 int complexity = 9 * pe->passed_count()
886 + 12 * pos.count<PAWN>()
888 + 21 * pawnsOnBothFlanks
890 + 51 * !pos.non_pawn_material()
891 - 43 * almostUnwinnable
894 Value mg = mg_value(score);
895 Value eg = eg_value(score);
897 // Now apply the bonus: note that we find the attacking side by extracting the
898 // sign of the midgame or endgame values, and that we carefully cap the bonus
899 // so that the midgame and endgame scores do not change sign after the bonus.
900 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
901 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
906 // Compute the scale factor for the winning side
907 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
908 int sf = me->scale_factor(pos, strongSide);
910 // If scale factor is not already specific, scale up/down via general heuristics
911 if (sf == SCALE_FACTOR_NORMAL)
913 if (pos.opposite_bishops())
915 // For pure opposite colored bishops endgames use scale factor
916 // based on the number of passed pawns of the strong side.
917 if ( pos.non_pawn_material(WHITE) == BishopValueMg
918 && pos.non_pawn_material(BLACK) == BishopValueMg)
919 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
920 // For every other opposite colored bishops endgames use scale factor
921 // based on the number of all pieces of the strong side.
923 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
925 // For rook endgames with strong side not having overwhelming pawn number advantage
926 // and its pawns being on one flank and weak side protecting its pieces with a king
927 // use lower scale factor.
928 else if ( pos.non_pawn_material(WHITE) == RookValueMg
929 && pos.non_pawn_material(BLACK) == RookValueMg
930 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
931 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
932 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
934 // For queen vs no queen endgames use scale factor
935 // based on number of minors of side that doesn't have queen.
936 else if (pos.count<QUEEN>() == 1)
937 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
938 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
939 // In every other case use scale factor based on
940 // the number of pawns of the strong side reduced if pawns are on a single flank.
942 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
944 // Reduce scale factor in case of pawns being on a single flank
945 sf -= 4 * !pawnsOnBothFlanks;
948 // Interpolate between the middlegame and (scaled by 'sf') endgame score
949 v = mg * int(me->game_phase())
950 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
955 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
956 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
963 // Evaluation::value() is the main function of the class. It computes the various
964 // parts of the evaluation and returns the value of the position from the point
965 // of view of the side to move.
968 Value Evaluation<T>::value() {
970 assert(!pos.checkers());
972 // Probe the material hash table
973 me = Material::probe(pos);
975 // If we have a specialized evaluation function for the current material
976 // configuration, call it and return.
977 if (me->specialized_eval_exists())
978 return me->evaluate(pos);
980 // Initialize score by reading the incrementally updated scores included in
981 // the position object (material + piece square tables) and the material
982 // imbalance. Score is computed internally from the white point of view.
983 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->trend;
985 // Probe the pawn hash table
986 pe = Pawns::probe(pos);
987 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
989 // Early exit if score is high
990 auto lazy_skip = [&](Value lazyThreshold) {
991 return abs(mg_value(score) + eg_value(score)) > lazyThreshold
992 + std::abs(pos.this_thread()->bestValue) * 5 / 4
993 + pos.non_pawn_material() / 32;
996 if (lazy_skip(LazyThreshold1))
999 // Main evaluation begins here
1000 initialize<WHITE>();
1001 initialize<BLACK>();
1003 // Pieces evaluated first (also populates attackedBy, attackedBy2).
1004 // Note that the order of evaluation of the terms is left unspecified.
1005 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
1006 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
1007 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
1008 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
1010 score += mobility[WHITE] - mobility[BLACK];
1012 // More complex interactions that require fully populated attack bitboards
1013 score += king< WHITE>() - king< BLACK>()
1014 + passed< WHITE>() - passed< BLACK>();
1016 if (lazy_skip(LazyThreshold2))
1019 score += threats<WHITE>() - threats<BLACK>()
1020 + space< WHITE>() - space< BLACK>();
1023 // Derive single value from mg and eg parts of score
1024 Value v = winnable(score);
1026 // In case of tracing add all remaining individual evaluation terms
1029 Trace::add(MATERIAL, pos.psq_score());
1030 Trace::add(IMBALANCE, me->imbalance());
1031 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1032 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1038 // Side to move point of view
1039 v = (pos.side_to_move() == WHITE ? v : -v);
1045 /// Fisher Random Chess: correction for cornered bishops, to fix chess960 play with NNUE
1047 Value fix_FRC(const Position& pos) {
1049 constexpr Bitboard Corners = 1ULL << SQ_A1 | 1ULL << SQ_H1 | 1ULL << SQ_A8 | 1ULL << SQ_H8;
1051 if (!(pos.pieces(BISHOP) & Corners))
1056 if ( pos.piece_on(SQ_A1) == W_BISHOP
1057 && pos.piece_on(SQ_B2) == W_PAWN)
1058 correction -= CorneredBishop;
1060 if ( pos.piece_on(SQ_H1) == W_BISHOP
1061 && pos.piece_on(SQ_G2) == W_PAWN)
1062 correction -= CorneredBishop;
1064 if ( pos.piece_on(SQ_A8) == B_BISHOP
1065 && pos.piece_on(SQ_B7) == B_PAWN)
1066 correction += CorneredBishop;
1068 if ( pos.piece_on(SQ_H8) == B_BISHOP
1069 && pos.piece_on(SQ_G7) == B_PAWN)
1070 correction += CorneredBishop;
1072 return pos.side_to_move() == WHITE ? Value(3 * correction)
1073 : -Value(3 * correction);
1079 /// evaluate() is the evaluator for the outer world. It returns a static
1080 /// evaluation of the position from the point of view of the side to move.
1082 Value Eval::evaluate(const Position& pos) {
1085 bool useClassical = false;
1087 // Deciding between classical and NNUE eval (~10 Elo): for high PSQ imbalance we use classical,
1088 // but we switch to NNUE during long shuffling or with high material on the board.
1090 || abs(eg_value(pos.psq_score())) * 5 > (849 + pos.non_pawn_material() / 64) * (5 + pos.rule50_count()))
1092 v = Evaluation<NO_TRACE>(pos).value(); // classical
1093 useClassical = abs(v) >= 298;
1096 // If result of a classical evaluation is much lower than threshold fall back to NNUE
1097 if (useNNUE && !useClassical)
1099 Value nnue = NNUE::evaluate(pos, true); // NNUE
1100 int scale = 1136 + 20 * pos.non_pawn_material() / 1024;
1101 Color stm = pos.side_to_move();
1102 Value optimism = pos.this_thread()->optimism[stm];
1103 Value psq = (stm == WHITE ? 1 : -1) * eg_value(pos.psq_score());
1104 int complexity = 35 * abs(nnue - psq) / 256;
1106 optimism = optimism * (44 + complexity) / 32;
1107 v = (nnue + optimism) * scale / 1024 - optimism;
1109 if (pos.is_chess960())
1113 // Damp down the evaluation linearly when shuffling
1114 v = v * (208 - pos.rule50_count()) / 208;
1116 // Guarantee evaluation does not hit the tablebase range
1117 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1122 /// trace() is like evaluate(), but instead of returning a value, it returns
1123 /// a string (suitable for outputting to stdout) that contains the detailed
1124 /// descriptions and values of each evaluation term. Useful for debugging.
1125 /// Trace scores are from white's point of view
1127 std::string Eval::trace(Position& pos) {
1130 return "Final evaluation: none (in check)";
1132 std::stringstream ss;
1133 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1137 std::memset(scores, 0, sizeof(scores));
1139 // Reset any global variable used in eval
1140 pos.this_thread()->trend = SCORE_ZERO;
1141 pos.this_thread()->bestValue = VALUE_ZERO;
1142 pos.this_thread()->optimism[WHITE] = VALUE_ZERO;
1143 pos.this_thread()->optimism[BLACK] = VALUE_ZERO;
1145 v = Evaluation<TRACE>(pos).value();
1147 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1148 << " Contributing terms for the classical eval:\n"
1149 << "+------------+-------------+-------------+-------------+\n"
1150 << "| Term | White | Black | Total |\n"
1151 << "| | MG EG | MG EG | MG EG |\n"
1152 << "+------------+-------------+-------------+-------------+\n"
1153 << "| Material | " << Term(MATERIAL)
1154 << "| Imbalance | " << Term(IMBALANCE)
1155 << "| Pawns | " << Term(PAWN)
1156 << "| Knights | " << Term(KNIGHT)
1157 << "| Bishops | " << Term(BISHOP)
1158 << "| Rooks | " << Term(ROOK)
1159 << "| Queens | " << Term(QUEEN)
1160 << "| Mobility | " << Term(MOBILITY)
1161 << "|King safety | " << Term(KING)
1162 << "| Threats | " << Term(THREAT)
1163 << "| Passed | " << Term(PASSED)
1164 << "| Space | " << Term(SPACE)
1165 << "| Winnable | " << Term(WINNABLE)
1166 << "+------------+-------------+-------------+-------------+\n"
1167 << "| Total | " << Term(TOTAL)
1168 << "+------------+-------------+-------------+-------------+\n";
1171 ss << '\n' << NNUE::trace(pos) << '\n';
1173 ss << std::showpoint << std::showpos << std::fixed << std::setprecision(2) << std::setw(15);
1175 v = pos.side_to_move() == WHITE ? v : -v;
1176 ss << "\nClassical evaluation " << to_cp(v) << " (white side)\n";
1179 v = NNUE::evaluate(pos, false);
1180 v = pos.side_to_move() == WHITE ? v : -v;
1181 ss << "NNUE evaluation " << to_cp(v) << " (white side)\n";
1185 v = pos.side_to_move() == WHITE ? v : -v;
1186 ss << "Final evaluation " << to_cp(v) << " (white side)";
1188 ss << " [with scaled NNUE, hybrid, ...]";
1194 } // namespace Stockfish