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::verify() verifies that the last net used was loaded successfully
118 void NNUE::verify() {
120 string eval_file = string(Options["EvalFile"]);
122 if (useNNUE && eval_file_loaded != eval_file)
124 UCI::OptionsMap defaults;
127 string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
128 string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
129 string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
130 string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + string(defaults["EvalFile"]);
131 string msg5 = "The engine will be terminated now.";
133 sync_cout << "info string ERROR: " << msg1 << sync_endl;
134 sync_cout << "info string ERROR: " << msg2 << sync_endl;
135 sync_cout << "info string ERROR: " << msg3 << sync_endl;
136 sync_cout << "info string ERROR: " << msg4 << sync_endl;
137 sync_cout << "info string ERROR: " << msg5 << sync_endl;
143 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
145 sync_cout << "info string classical evaluation enabled" << sync_endl;
151 enum Tracing { NO_TRACE, TRACE };
153 enum Term { // The first 8 entries are reserved for PieceType
154 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
157 Score scores[TERM_NB][COLOR_NB];
159 double to_cp(Value v) { return double(v) / PawnValueEg; }
161 void add(int idx, Color c, Score s) {
165 void add(int idx, Score w, Score b = SCORE_ZERO) {
166 scores[idx][WHITE] = w;
167 scores[idx][BLACK] = b;
170 std::ostream& operator<<(std::ostream& os, Score s) {
171 os << std::setw(5) << to_cp(mg_value(s)) << " "
172 << std::setw(5) << to_cp(eg_value(s));
176 std::ostream& operator<<(std::ostream& os, Term t) {
178 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
179 os << " ---- ----" << " | " << " ---- ----";
181 os << scores[t][WHITE] << " | " << scores[t][BLACK];
183 os << " | " << scores[t][WHITE] - scores[t][BLACK] << " |\n";
188 using namespace Trace;
192 // Threshold for lazy and space evaluation
193 constexpr Value LazyThreshold1 = Value(3130);
194 constexpr Value LazyThreshold2 = Value(2204);
195 constexpr Value SpaceThreshold = Value(11551);
197 // KingAttackWeights[PieceType] contains king attack weights by piece type
198 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
200 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
201 // higher if multiple safe checks are possible for that piece type.
202 constexpr int SafeCheck[][2] = {
203 {}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
206 #define S(mg, eg) make_score(mg, eg)
208 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
209 // indexed by piece type and number of attacked squares in the mobility area.
210 constexpr Score MobilityBonus[][32] = {
211 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
212 S( 21, 16), S( 28, 21), S( 37, 26) },
213 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
214 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
215 S( 91, 88), S( 96, 98) },
216 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
217 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
218 S( 57,165), S( 58,170), S( 67,175) },
219 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
220 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
221 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
222 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
223 S(112,178), S(114,185), S(114,187), S(119,221) }
226 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
227 // squares of the same color as our bishop.
228 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
229 S(3, 8), S(3, 9), S(2, 8), S(3, 8)
232 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
233 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
235 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
236 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
237 constexpr Score Outpost[] = { S(57, 38), S(31, 24) };
239 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
240 constexpr Score PassedRank[RANK_NB] = {
241 S(0, 0), S(7, 27), S(16, 32), S(17, 40), S(64, 71), S(170, 174), S(278, 262)
244 constexpr Score RookOnClosedFile = S(10, 5);
245 constexpr Score RookOnOpenFile[] = { S(19, 6), S(47, 26) };
247 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
248 // which piece type attacks which one. Attacks on lesser pieces which are
249 // pawn-defended are not considered.
250 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
251 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
254 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
255 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
258 constexpr Value CorneredBishop = Value(50);
260 // Assorted bonuses and penalties
261 constexpr Score UncontestedOutpost = S( 1, 10);
262 constexpr Score BishopOnKingRing = S( 24, 0);
263 constexpr Score BishopXRayPawns = S( 4, 5);
264 constexpr Score FlankAttacks = S( 8, 0);
265 constexpr Score Hanging = S( 69, 36);
266 constexpr Score KnightOnQueen = S( 16, 11);
267 constexpr Score LongDiagonalBishop = S( 45, 0);
268 constexpr Score MinorBehindPawn = S( 18, 3);
269 constexpr Score PassedFile = S( 11, 8);
270 constexpr Score PawnlessFlank = S( 17, 95);
271 constexpr Score ReachableOutpost = S( 31, 22);
272 constexpr Score RestrictedPiece = S( 7, 7);
273 constexpr Score RookOnKingRing = S( 16, 0);
274 constexpr Score SliderOnQueen = S( 60, 18);
275 constexpr Score ThreatByKing = S( 24, 89);
276 constexpr Score ThreatByPawnPush = S( 48, 39);
277 constexpr Score ThreatBySafePawn = S(173, 94);
278 constexpr Score TrappedRook = S( 55, 13);
279 constexpr Score WeakQueenProtection = S( 14, 0);
280 constexpr Score WeakQueen = S( 56, 15);
285 // Evaluation class computes and stores attacks tables and other working data
290 Evaluation() = delete;
291 explicit Evaluation(const Position& p) : pos(p) {}
292 Evaluation& operator=(const Evaluation&) = delete;
296 template<Color Us> void initialize();
297 template<Color Us, PieceType Pt> Score pieces();
298 template<Color Us> Score king() const;
299 template<Color Us> Score threats() const;
300 template<Color Us> Score passed() const;
301 template<Color Us> Score space() const;
302 Value winnable(Score score) const;
307 Bitboard mobilityArea[COLOR_NB];
308 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
310 // attackedBy[color][piece type] is a bitboard representing all squares
311 // attacked by a given color and piece type. Special "piece types" which
312 // is also calculated is ALL_PIECES.
313 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
315 // attackedBy2[color] are the squares attacked by at least 2 units of a given
316 // color, including x-rays. But diagonal x-rays through pawns are not computed.
317 Bitboard attackedBy2[COLOR_NB];
319 // kingRing[color] are the squares adjacent to the king plus some other
320 // very near squares, depending on king position.
321 Bitboard kingRing[COLOR_NB];
323 // kingAttackersCount[color] is the number of pieces of the given color
324 // which attack a square in the kingRing of the enemy king.
325 int kingAttackersCount[COLOR_NB];
327 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
328 // the given color which attack a square in the kingRing of the enemy king.
329 // The weights of the individual piece types are given by the elements in
330 // the KingAttackWeights array.
331 int kingAttackersWeight[COLOR_NB];
333 // kingAttacksCount[color] is the number of attacks by the given color to
334 // squares directly adjacent to the enemy king. Pieces which attack more
335 // than one square are counted multiple times. For instance, if there is
336 // a white knight on g5 and black's king is on g8, this white knight adds 2
337 // to kingAttacksCount[WHITE].
338 int kingAttacksCount[COLOR_NB];
342 // Evaluation::initialize() computes king and pawn attacks, and the king ring
343 // bitboard for a given color. This is done at the beginning of the evaluation.
345 template<Tracing T> template<Color Us>
346 void Evaluation<T>::initialize() {
348 constexpr Color Them = ~Us;
349 constexpr Direction Up = pawn_push(Us);
350 constexpr Direction Down = -Up;
351 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
353 const Square ksq = pos.square<KING>(Us);
355 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
357 // Find our pawns that are blocked or on the first two ranks
358 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
360 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
361 // or controlled by enemy pawns are excluded from the mobility area.
362 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
364 // Initialize attackedBy[] for king and pawns
365 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
366 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
367 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
368 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
370 // Init our king safety tables
371 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
372 std::clamp(rank_of(ksq), RANK_2, RANK_7));
373 kingRing[Us] = attacks_bb<KING>(s) | s;
375 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
376 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
378 // Remove from kingRing[] the squares defended by two pawns
379 kingRing[Us] &= ~dblAttackByPawn;
383 // Evaluation::pieces() scores pieces of a given color and type
385 template<Tracing T> template<Color Us, PieceType Pt>
386 Score Evaluation<T>::pieces() {
388 constexpr Color Them = ~Us;
389 constexpr Direction Down = -pawn_push(Us);
390 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
391 : Rank5BB | Rank4BB | Rank3BB);
392 Bitboard b1 = pos.pieces(Us, Pt);
394 Score score = SCORE_ZERO;
396 attackedBy[Us][Pt] = 0;
400 Square s = pop_lsb(b1);
402 // Find attacked squares, including x-ray attacks for bishops and rooks
403 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
404 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
405 : attacks_bb<Pt>(s, pos.pieces());
407 if (pos.blockers_for_king(Us) & s)
408 b &= line_bb(pos.square<KING>(Us), s);
410 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
411 attackedBy[Us][Pt] |= b;
412 attackedBy[Us][ALL_PIECES] |= b;
414 if (b & kingRing[Them])
416 kingAttackersCount[Us]++;
417 kingAttackersWeight[Us] += KingAttackWeights[Pt];
418 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
421 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
422 score += RookOnKingRing;
424 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
425 score += BishopOnKingRing;
427 int mob = popcount(b & mobilityArea[Us]);
428 mobility[Us] += MobilityBonus[Pt - 2][mob];
430 if (Pt == BISHOP || Pt == KNIGHT)
432 // Bonus if the piece is on an outpost square or can reach one
433 // Bonus for knights (UncontestedOutpost) if few relevant targets
434 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
435 & ~pe->pawn_attacks_span(Them);
436 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
439 && bb & s & ~CenterFiles // on a side outpost
440 && !(b & targets) // no relevant attacks
441 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
442 score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
444 score += Outpost[Pt == BISHOP];
445 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
446 score += ReachableOutpost;
448 // Bonus for a knight or bishop shielded by pawn
449 if (shift<Down>(pos.pieces(PAWN)) & s)
450 score += MinorBehindPawn;
452 // Penalty if the piece is far from the king
453 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
455 if constexpr (Pt == BISHOP)
457 // Penalty according to the number of our pawns on the same color square as the
458 // bishop, bigger when the center files are blocked with pawns and smaller
459 // when the bishop is outside the pawn chain.
460 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
462 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
463 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
465 // Penalty for all enemy pawns x-rayed
466 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
468 // Bonus for bishop on a long diagonal which can "see" both center squares
469 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
470 score += LongDiagonalBishop;
472 // An important Chess960 pattern: a cornered bishop blocked by a friendly
473 // pawn diagonally in front of it is a very serious problem, especially
474 // when that pawn is also blocked.
475 if ( pos.is_chess960()
476 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
478 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
479 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
480 score -= !pos.empty(s + d + pawn_push(Us)) ? 4 * make_score(CorneredBishop, CorneredBishop)
481 : 3 * make_score(CorneredBishop, CorneredBishop);
486 if constexpr (Pt == ROOK)
488 // Bonuses for rook on a (semi-)open or closed file
489 if (pos.is_on_semiopen_file(Us, s))
491 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
495 // If our pawn on this file is blocked, increase penalty
496 if ( pos.pieces(Us, PAWN)
497 & shift<Down>(pos.pieces())
500 score -= RookOnClosedFile;
503 // Penalty when trapped by the king, even more if the king cannot castle
506 File kf = file_of(pos.square<KING>(Us));
507 if ((kf < FILE_E) == (file_of(s) < kf))
508 score -= TrappedRook * (1 + !pos.castling_rights(Us));
513 if constexpr (Pt == QUEEN)
515 // Penalty if any relative pin or discovered attack against the queen
516 Bitboard queenPinners;
517 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
522 Trace::add(Pt, Us, score);
528 // Evaluation::king() assigns bonuses and penalties to a king of a given color
530 template<Tracing T> template<Color Us>
531 Score Evaluation<T>::king() const {
533 constexpr Color Them = ~Us;
534 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
535 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
537 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
538 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
540 const Square ksq = pos.square<KING>(Us);
542 // Init the score with king shelter and enemy pawns storm
543 Score score = pe->king_safety<Us>(pos);
545 // Attacked squares defended at most once by our queen or king
546 weak = attackedBy[Them][ALL_PIECES]
548 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
550 // Analyse the safe enemy's checks which are possible on next move
551 safe = ~pos.pieces(Them);
552 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
554 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
555 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
557 // Enemy rooks checks
558 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
560 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
562 unsafeChecks |= b1 & attackedBy[Them][ROOK];
564 // Enemy queen safe checks: count them only if the checks are from squares from
565 // which opponent cannot give a rook check, because rook checks are more valuable.
566 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
567 & ~(attackedBy[Us][QUEEN] | rookChecks);
569 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
571 // Enemy bishops checks: count them only if they are from squares from which
572 // opponent cannot give a queen check, because queen checks are more valuable.
573 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
576 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
579 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
581 // Enemy knights checks
582 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
583 if (knightChecks & safe)
584 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
586 unsafeChecks |= knightChecks;
588 // Find the squares that opponent attacks in our king flank, the squares
589 // which they attack twice in that flank, and the squares that we defend.
590 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
591 b2 = b1 & attackedBy2[Them];
592 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
594 int kingFlankAttack = popcount(b1) + popcount(b2);
595 int kingFlankDefense = popcount(b3);
597 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
598 + 183 * popcount(kingRing[Us] & weak) // (~15 Elo)
599 + 148 * popcount(unsafeChecks) // (~4 Elo)
600 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
601 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
602 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
603 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
604 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
605 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
606 - 6 * mg_value(score) / 8 // (~8 Elo)
607 - 4 * kingFlankDefense // (~5 Elo)
610 // Transform the kingDanger units into a Score, and subtract it from the evaluation
611 if (kingDanger > 100)
612 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
614 // Penalty when our king is on a pawnless flank
615 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
616 score -= PawnlessFlank;
618 // Penalty if king flank is under attack, potentially moving toward the king
619 score -= FlankAttacks * kingFlankAttack;
622 Trace::add(KING, Us, score);
628 // Evaluation::threats() assigns bonuses according to the types of the
629 // attacking and the attacked pieces.
631 template<Tracing T> template<Color Us>
632 Score Evaluation<T>::threats() const {
634 constexpr Color Them = ~Us;
635 constexpr Direction Up = pawn_push(Us);
636 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
638 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
639 Score score = SCORE_ZERO;
642 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
644 // Squares strongly protected by the enemy, either because they defend the
645 // square with a pawn, or because they defend the square twice and we don't.
646 stronglyProtected = attackedBy[Them][PAWN]
647 | (attackedBy2[Them] & ~attackedBy2[Us]);
649 // Non-pawn enemies, strongly protected
650 defended = nonPawnEnemies & stronglyProtected;
652 // Enemies not strongly protected and under our attack
653 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
655 // Bonus according to the kind of attacking pieces
658 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
660 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(b)))];
662 b = weak & attackedBy[Us][ROOK];
664 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(b)))];
666 if (weak & attackedBy[Us][KING])
667 score += ThreatByKing;
669 b = ~attackedBy[Them][ALL_PIECES]
670 | (nonPawnEnemies & attackedBy2[Us]);
671 score += Hanging * popcount(weak & b);
673 // Additional bonus if weak piece is only protected by a queen
674 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
677 // Bonus for restricting their piece moves
678 b = attackedBy[Them][ALL_PIECES]
680 & attackedBy[Us][ALL_PIECES];
681 score += RestrictedPiece * popcount(b);
683 // Protected or unattacked squares
684 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
686 // Bonus for attacking enemy pieces with our relatively safe pawns
687 b = pos.pieces(Us, PAWN) & safe;
688 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
689 score += ThreatBySafePawn * popcount(b);
691 // Find squares where our pawns can push on the next move
692 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
693 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
695 // Keep only the squares which are relatively safe
696 b &= ~attackedBy[Them][PAWN] & safe;
698 // Bonus for safe pawn threats on the next move
699 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
700 score += ThreatByPawnPush * popcount(b);
702 // Bonus for threats on the next moves against enemy queen
703 if (pos.count<QUEEN>(Them) == 1)
705 bool queenImbalance = pos.count<QUEEN>() == 1;
707 Square s = pos.square<QUEEN>(Them);
708 safe = mobilityArea[Us]
709 & ~pos.pieces(Us, PAWN)
710 & ~stronglyProtected;
712 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
714 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
716 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
717 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
719 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
723 Trace::add(THREAT, Us, score);
728 // Evaluation::passed() evaluates the passed pawns and candidate passed
729 // pawns of the given color.
731 template<Tracing T> template<Color Us>
732 Score Evaluation<T>::passed() const {
734 constexpr Color Them = ~Us;
735 constexpr Direction Up = pawn_push(Us);
736 constexpr Direction Down = -Up;
738 auto king_proximity = [&](Color c, Square s) {
739 return std::min(distance(pos.square<KING>(c), s), 5);
742 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
743 Score score = SCORE_ZERO;
745 b = pe->passed_pawns(Us);
747 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
750 helpers = shift<Up>(pos.pieces(Us, PAWN))
752 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
754 // Remove blocked candidate passers that don't have help to pass
756 | shift<WEST>(helpers)
757 | shift<EAST>(helpers);
762 Square s = pop_lsb(b);
764 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
766 int r = relative_rank(Us, s);
768 Score bonus = PassedRank[r];
773 Square blockSq = s + Up;
775 // Adjust bonus based on the king's proximity
776 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
777 - king_proximity(Us, blockSq) * 2) * w);
779 // If blockSq is not the queening square then consider also a second push
781 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
783 // If the pawn is free to advance, then increase the bonus
784 if (pos.empty(blockSq))
786 squaresToQueen = forward_file_bb(Us, s);
787 unsafeSquares = passed_pawn_span(Us, s);
789 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
791 if (!(pos.pieces(Them) & bb))
792 unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
794 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
795 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
796 // Otherwise assign a smaller bonus if the path to queen is not attacked
797 // and even smaller bonus if it is attacked but block square is not.
798 int k = !unsafeSquares ? 36 :
799 !(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
800 !(unsafeSquares & squaresToQueen) ? 17 :
801 !(unsafeSquares & blockSq) ? 7 :
804 // Assign a larger bonus if the block square is defended
805 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
808 bonus += make_score(k * w, k * w);
812 score += bonus - PassedFile * edge_distance(file_of(s));
816 Trace::add(PASSED, Us, score);
822 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
823 // play in the opening. It is based on the number of safe squares on the four central files
824 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
825 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
827 template<Tracing T> template<Color Us>
828 Score Evaluation<T>::space() const {
830 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
831 if (pos.non_pawn_material() < SpaceThreshold)
834 constexpr Color Them = ~Us;
835 constexpr Direction Down = -pawn_push(Us);
836 constexpr Bitboard SpaceMask =
837 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
838 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
840 // Find the available squares for our pieces inside the area defined by SpaceMask
841 Bitboard safe = SpaceMask
842 & ~pos.pieces(Us, PAWN)
843 & ~attackedBy[Them][PAWN];
845 // Find all squares which are at most three squares behind some friendly pawn
846 Bitboard behind = pos.pieces(Us, PAWN);
847 behind |= shift<Down>(behind);
848 behind |= shift<Down+Down>(behind);
850 // Compute space score based on the number of safe squares and number of our pieces
851 // increased with number of total blocked pawns in position.
852 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
853 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
854 Score score = make_score(bonus * weight * weight / 16, 0);
857 Trace::add(SPACE, Us, score);
863 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
864 // the known attacking/defending status of the players. The final value is derived
865 // by interpolation from the midgame and endgame values.
868 Value Evaluation<T>::winnable(Score score) const {
870 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
871 + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
873 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
874 && (pos.pieces(PAWN) & KingSide);
876 bool almostUnwinnable = outflanking < 0
877 && !pawnsOnBothFlanks;
879 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
880 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
882 // Compute the initiative bonus for the attacking side
883 int complexity = 9 * pe->passed_count()
884 + 12 * pos.count<PAWN>()
886 + 21 * pawnsOnBothFlanks
888 + 51 * !pos.non_pawn_material()
889 - 43 * almostUnwinnable
892 Value mg = mg_value(score);
893 Value eg = eg_value(score);
895 // Now apply the bonus: note that we find the attacking side by extracting the
896 // sign of the midgame or endgame values, and that we carefully cap the bonus
897 // so that the midgame and endgame scores do not change sign after the bonus.
898 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
899 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
904 // Compute the scale factor for the winning side
905 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
906 int sf = me->scale_factor(pos, strongSide);
908 // If scale factor is not already specific, scale up/down via general heuristics
909 if (sf == SCALE_FACTOR_NORMAL)
911 if (pos.opposite_bishops())
913 // For pure opposite colored bishops endgames use scale factor
914 // based on the number of passed pawns of the strong side.
915 if ( pos.non_pawn_material(WHITE) == BishopValueMg
916 && pos.non_pawn_material(BLACK) == BishopValueMg)
917 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
918 // For every other opposite colored bishops endgames use scale factor
919 // based on the number of all pieces of the strong side.
921 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
923 // For rook endgames with strong side not having overwhelming pawn number advantage
924 // and its pawns being on one flank and weak side protecting its pieces with a king
925 // use lower scale factor.
926 else if ( pos.non_pawn_material(WHITE) == RookValueMg
927 && pos.non_pawn_material(BLACK) == RookValueMg
928 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
929 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
930 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
932 // For queen vs no queen endgames use scale factor
933 // based on number of minors of side that doesn't have queen.
934 else if (pos.count<QUEEN>() == 1)
935 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
936 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
937 // In every other case use scale factor based on
938 // the number of pawns of the strong side reduced if pawns are on a single flank.
940 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
942 // Reduce scale factor in case of pawns being on a single flank
943 sf -= 4 * !pawnsOnBothFlanks;
946 // Interpolate between the middlegame and (scaled by 'sf') endgame score
947 v = mg * int(me->game_phase())
948 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
953 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
954 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
961 // Evaluation::value() is the main function of the class. It computes the various
962 // parts of the evaluation and returns the value of the position from the point
963 // of view of the side to move.
966 Value Evaluation<T>::value() {
968 assert(!pos.checkers());
970 // Probe the material hash table
971 me = Material::probe(pos);
973 // If we have a specialized evaluation function for the current material
974 // configuration, call it and return.
975 if (me->specialized_eval_exists())
976 return me->evaluate(pos);
978 // Initialize score by reading the incrementally updated scores included in
979 // the position object (material + piece square tables) and the material
980 // imbalance. Score is computed internally from the white point of view.
981 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->trend;
983 // Probe the pawn hash table
984 pe = Pawns::probe(pos);
985 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
987 // Early exit if score is high
988 auto lazy_skip = [&](Value lazyThreshold) {
989 return abs(mg_value(score) + eg_value(score)) > lazyThreshold + pos.non_pawn_material() / 32;
992 if (lazy_skip(LazyThreshold1))
995 // Main evaluation begins here
999 // Pieces evaluated first (also populates attackedBy, attackedBy2).
1000 // Note that the order of evaluation of the terms is left unspecified.
1001 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
1002 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
1003 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
1004 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
1006 score += mobility[WHITE] - mobility[BLACK];
1008 // More complex interactions that require fully populated attack bitboards
1009 score += king< WHITE>() - king< BLACK>()
1010 + passed< WHITE>() - passed< BLACK>();
1012 if (lazy_skip(LazyThreshold2))
1015 score += threats<WHITE>() - threats<BLACK>()
1016 + space< WHITE>() - space< BLACK>();
1019 // Derive single value from mg and eg parts of score
1020 Value v = winnable(score);
1022 // In case of tracing add all remaining individual evaluation terms
1025 Trace::add(MATERIAL, pos.psq_score());
1026 Trace::add(IMBALANCE, me->imbalance());
1027 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1028 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1034 // Side to move point of view
1035 v = (pos.side_to_move() == WHITE ? v : -v);
1041 /// Fisher Random Chess: correction for cornered bishops, to fix chess960 play with NNUE
1043 Value fix_FRC(const Position& pos) {
1045 constexpr Bitboard Corners = 1ULL << SQ_A1 | 1ULL << SQ_H1 | 1ULL << SQ_A8 | 1ULL << SQ_H8;
1047 if (!(pos.pieces(BISHOP) & Corners))
1052 if ( pos.piece_on(SQ_A1) == W_BISHOP
1053 && pos.piece_on(SQ_B2) == W_PAWN)
1054 correction += !pos.empty(SQ_B3) ? -CorneredBishop * 4
1055 : -CorneredBishop * 3;
1057 if ( pos.piece_on(SQ_H1) == W_BISHOP
1058 && pos.piece_on(SQ_G2) == W_PAWN)
1059 correction += !pos.empty(SQ_G3) ? -CorneredBishop * 4
1060 : -CorneredBishop * 3;
1062 if ( pos.piece_on(SQ_A8) == B_BISHOP
1063 && pos.piece_on(SQ_B7) == B_PAWN)
1064 correction += !pos.empty(SQ_B6) ? CorneredBishop * 4
1065 : CorneredBishop * 3;
1067 if ( pos.piece_on(SQ_H8) == B_BISHOP
1068 && pos.piece_on(SQ_G7) == B_PAWN)
1069 correction += !pos.empty(SQ_G6) ? CorneredBishop * 4
1070 : CorneredBishop * 3;
1072 return pos.side_to_move() == WHITE ? Value(correction)
1073 : -Value(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) {
1087 v = Evaluation<NO_TRACE>(pos).value();
1090 // Scale and shift NNUE for compatibility with search and classical evaluation
1091 auto adjusted_NNUE = [&]()
1094 + 32 * pos.count<PAWN>()
1095 + 32 * pos.non_pawn_material() / 1024;
1097 Value nnue = NNUE::evaluate(pos, true) * scale / 1024;
1099 if (pos.is_chess960())
1100 nnue += fix_FRC(pos);
1105 // If there is PSQ imbalance we use the classical eval, but we switch to
1106 // NNUE eval faster when shuffling or if the material on the board is high.
1107 int r50 = pos.rule50_count();
1108 Value psq = Value(abs(eg_value(pos.psq_score())));
1109 bool classical = psq * 5 > (750 + pos.non_pawn_material() / 64) * (5 + r50);
1111 v = classical ? Evaluation<NO_TRACE>(pos).value() // classical
1112 : adjusted_NNUE(); // NNUE
1115 // Damp down the evaluation linearly when shuffling
1116 v = v * (100 - pos.rule50_count()) / 100;
1118 // Guarantee evaluation does not hit the tablebase range
1119 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1124 /// trace() is like evaluate(), but instead of returning a value, it returns
1125 /// a string (suitable for outputting to stdout) that contains the detailed
1126 /// descriptions and values of each evaluation term. Useful for debugging.
1127 /// Trace scores are from white's point of view
1129 std::string Eval::trace(Position& pos) {
1132 return "Final evaluation: none (in check)";
1134 std::stringstream ss;
1135 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1139 std::memset(scores, 0, sizeof(scores));
1141 pos.this_thread()->trend = SCORE_ZERO; // Reset any dynamic contempt
1143 v = Evaluation<TRACE>(pos).value();
1145 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1146 << " Contributing terms for the classical eval:\n"
1147 << "+------------+-------------+-------------+-------------+\n"
1148 << "| Term | White | Black | Total |\n"
1149 << "| | MG EG | MG EG | MG EG |\n"
1150 << "+------------+-------------+-------------+-------------+\n"
1151 << "| Material | " << Term(MATERIAL)
1152 << "| Imbalance | " << Term(IMBALANCE)
1153 << "| Pawns | " << Term(PAWN)
1154 << "| Knights | " << Term(KNIGHT)
1155 << "| Bishops | " << Term(BISHOP)
1156 << "| Rooks | " << Term(ROOK)
1157 << "| Queens | " << Term(QUEEN)
1158 << "| Mobility | " << Term(MOBILITY)
1159 << "|King safety | " << Term(KING)
1160 << "| Threats | " << Term(THREAT)
1161 << "| Passed | " << Term(PASSED)
1162 << "| Space | " << Term(SPACE)
1163 << "| Winnable | " << Term(WINNABLE)
1164 << "+------------+-------------+-------------+-------------+\n"
1165 << "| Total | " << Term(TOTAL)
1166 << "+------------+-------------+-------------+-------------+\n";
1169 ss << '\n' << NNUE::trace(pos) << '\n';
1171 ss << std::showpoint << std::showpos << std::fixed << std::setprecision(2) << std::setw(15);
1173 v = pos.side_to_move() == WHITE ? v : -v;
1174 ss << "\nClassical evaluation " << to_cp(v) << " (white side)\n";
1177 v = NNUE::evaluate(pos, false);
1178 v = pos.side_to_move() == WHITE ? v : -v;
1179 ss << "NNUE evaluation " << to_cp(v) << " (white side)\n";
1183 v = pos.side_to_move() == WHITE ? v : -v;
1184 ss << "Final evaluation " << to_cp(v) << " (white side)";
1186 ss << " [with scaled NNUE, hybrid, ...]";
1192 } // namespace Stockfish