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);
50 constexpr bool gHasEmbeddedNet = true;
52 constexpr bool gHasEmbeddedNet = false;
53 const unsigned char gEmbeddedNNUEData[1] = {0x0};
54 const unsigned char *const gEmbeddedNNUEEnd = &gEmbeddedNNUEData[1];
55 const unsigned int gEmbeddedNNUESize = 1;
66 string eval_file_loaded = "None";
68 /// NNUE::init() tries to load a NNUE network at startup time, or when the engine
69 /// receives a UCI command "setoption name EvalFile value nn-[a-z0-9]{12}.nnue"
70 /// The name of the NNUE network is always retrieved from the EvalFile option.
71 /// We search the given network in three locations: internally (the default
72 /// network may be embedded in the binary), in the active working directory and
73 /// in the engine directory. Distro packagers may define the DEFAULT_NNUE_DIRECTORY
74 /// variable to have the engine search in a special directory in their distro.
78 useNNUE = Options["Use NNUE"];
82 string eval_file = string(Options["EvalFile"]);
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 (eval_file_loaded != eval_file)
95 if (directory != "<internal>")
97 ifstream stream(directory + eval_file, ios::binary);
98 if (load_eval(eval_file, stream))
99 eval_file_loaded = 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 eval_file_loaded = eval_file;
119 void NNUE::export_net() {
120 if constexpr (gHasEmbeddedNet) {
121 ofstream stream(EvalFileDefaultName, std::ios_base::binary);
122 stream.write(reinterpret_cast<const char*>(gEmbeddedNNUEData), gEmbeddedNNUESize);
124 sync_cout << "No embedded network file." << sync_endl;
128 /// NNUE::verify() verifies that the last net used was loaded successfully
129 void NNUE::verify() {
131 string eval_file = string(Options["EvalFile"]);
133 if (useNNUE && eval_file_loaded != eval_file)
135 UCI::OptionsMap defaults;
138 string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
139 string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
140 string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
141 string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + string(defaults["EvalFile"]);
142 string msg5 = "The engine will be terminated now.";
144 sync_cout << "info string ERROR: " << msg1 << sync_endl;
145 sync_cout << "info string ERROR: " << msg2 << sync_endl;
146 sync_cout << "info string ERROR: " << msg3 << sync_endl;
147 sync_cout << "info string ERROR: " << msg4 << sync_endl;
148 sync_cout << "info string ERROR: " << msg5 << sync_endl;
154 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
156 sync_cout << "info string classical evaluation enabled" << sync_endl;
162 enum Tracing { NO_TRACE, TRACE };
164 enum Term { // The first 8 entries are reserved for PieceType
165 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
168 Score scores[TERM_NB][COLOR_NB];
170 double to_cp(Value v) { return double(v) / PawnValueEg; }
172 void add(int idx, Color c, Score s) {
176 void add(int idx, Score w, Score b = SCORE_ZERO) {
177 scores[idx][WHITE] = w;
178 scores[idx][BLACK] = b;
181 std::ostream& operator<<(std::ostream& os, Score s) {
182 os << std::setw(5) << to_cp(mg_value(s)) << " "
183 << std::setw(5) << to_cp(eg_value(s));
187 std::ostream& operator<<(std::ostream& os, Term t) {
189 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
190 os << " ---- ----" << " | " << " ---- ----";
192 os << scores[t][WHITE] << " | " << scores[t][BLACK];
194 os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
199 using namespace Trace;
203 // Threshold for lazy and space evaluation
204 constexpr Value LazyThreshold1 = Value(1565);
205 constexpr Value LazyThreshold2 = Value(1102);
206 constexpr Value SpaceThreshold = Value(11551);
207 constexpr Value NNUEThreshold1 = Value(682);
208 constexpr Value NNUEThreshold2 = Value(176);
210 // KingAttackWeights[PieceType] contains king attack weights by piece type
211 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
213 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
214 // higher if multiple safe checks are possible for that piece type.
215 constexpr int SafeCheck[][2] = {
216 {}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
219 #define S(mg, eg) make_score(mg, eg)
221 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
222 // indexed by piece type and number of attacked squares in the mobility area.
223 constexpr Score MobilityBonus[][32] = {
224 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
225 S( 21, 16), S( 28, 21), S( 37, 26) },
226 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
227 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
228 S( 91, 88), S( 96, 98) },
229 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
230 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
231 S( 57,165), S( 58,170), S( 67,175) },
232 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
233 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
234 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
235 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
236 S(112,178), S(114,185), S(114,187), S(119,221) }
239 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
240 // squares of the same color as our bishop.
241 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
242 S(3, 8), S(3, 9), S(2, 8), S(3, 8)
245 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
246 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
248 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
249 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
250 constexpr Score Outpost[] = { S(57, 38), S(31, 24) };
252 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
253 constexpr Score PassedRank[RANK_NB] = {
254 S(0, 0), S(7, 27), S(16, 32), S(17, 40), S(64, 71), S(170, 174), S(278, 262)
257 constexpr Score RookOnClosedFile = S(10, 5);
258 constexpr Score RookOnOpenFile[] = { S(19, 6), S(47, 26) };
260 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
261 // which piece type attacks which one. Attacks on lesser pieces which are
262 // pawn-defended are not considered.
263 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
264 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
267 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
268 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
271 constexpr Value CorneredBishop = Value(50);
273 // Assorted bonuses and penalties
274 constexpr Score UncontestedOutpost = S( 1, 10);
275 constexpr Score BishopOnKingRing = S( 24, 0);
276 constexpr Score BishopXRayPawns = S( 4, 5);
277 constexpr Score FlankAttacks = S( 8, 0);
278 constexpr Score Hanging = S( 69, 36);
279 constexpr Score KnightOnQueen = S( 16, 11);
280 constexpr Score LongDiagonalBishop = S( 45, 0);
281 constexpr Score MinorBehindPawn = S( 18, 3);
282 constexpr Score PassedFile = S( 11, 8);
283 constexpr Score PawnlessFlank = S( 17, 95);
284 constexpr Score ReachableOutpost = S( 31, 22);
285 constexpr Score RestrictedPiece = S( 7, 7);
286 constexpr Score RookOnKingRing = S( 16, 0);
287 constexpr Score SliderOnQueen = S( 60, 18);
288 constexpr Score ThreatByKing = S( 24, 89);
289 constexpr Score ThreatByPawnPush = S( 48, 39);
290 constexpr Score ThreatBySafePawn = S(173, 94);
291 constexpr Score TrappedRook = S( 55, 13);
292 constexpr Score WeakQueenProtection = S( 14, 0);
293 constexpr Score WeakQueen = S( 56, 15);
298 // Evaluation class computes and stores attacks tables and other working data
303 Evaluation() = delete;
304 explicit Evaluation(const Position& p) : pos(p) {}
305 Evaluation& operator=(const Evaluation&) = delete;
309 template<Color Us> void initialize();
310 template<Color Us, PieceType Pt> Score pieces();
311 template<Color Us> Score king() const;
312 template<Color Us> Score threats() const;
313 template<Color Us> Score passed() const;
314 template<Color Us> Score space() const;
315 Value winnable(Score score) const;
320 Bitboard mobilityArea[COLOR_NB];
321 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
323 // attackedBy[color][piece type] is a bitboard representing all squares
324 // attacked by a given color and piece type. Special "piece types" which
325 // is also calculated is ALL_PIECES.
326 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
328 // attackedBy2[color] are the squares attacked by at least 2 units of a given
329 // color, including x-rays. But diagonal x-rays through pawns are not computed.
330 Bitboard attackedBy2[COLOR_NB];
332 // kingRing[color] are the squares adjacent to the king plus some other
333 // very near squares, depending on king position.
334 Bitboard kingRing[COLOR_NB];
336 // kingAttackersCount[color] is the number of pieces of the given color
337 // which attack a square in the kingRing of the enemy king.
338 int kingAttackersCount[COLOR_NB];
340 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
341 // the given color which attack a square in the kingRing of the enemy king.
342 // The weights of the individual piece types are given by the elements in
343 // the KingAttackWeights array.
344 int kingAttackersWeight[COLOR_NB];
346 // kingAttacksCount[color] is the number of attacks by the given color to
347 // squares directly adjacent to the enemy king. Pieces which attack more
348 // than one square are counted multiple times. For instance, if there is
349 // a white knight on g5 and black's king is on g8, this white knight adds 2
350 // to kingAttacksCount[WHITE].
351 int kingAttacksCount[COLOR_NB];
355 // Evaluation::initialize() computes king and pawn attacks, and the king ring
356 // bitboard for a given color. This is done at the beginning of the evaluation.
358 template<Tracing T> template<Color Us>
359 void Evaluation<T>::initialize() {
361 constexpr Color Them = ~Us;
362 constexpr Direction Up = pawn_push(Us);
363 constexpr Direction Down = -Up;
364 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
366 const Square ksq = pos.square<KING>(Us);
368 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
370 // Find our pawns that are blocked or on the first two ranks
371 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
373 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
374 // or controlled by enemy pawns are excluded from the mobility area.
375 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
377 // Initialize attackedBy[] for king and pawns
378 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
379 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
380 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
381 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
383 // Init our king safety tables
384 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
385 std::clamp(rank_of(ksq), RANK_2, RANK_7));
386 kingRing[Us] = attacks_bb<KING>(s) | s;
388 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
389 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
391 // Remove from kingRing[] the squares defended by two pawns
392 kingRing[Us] &= ~dblAttackByPawn;
396 // Evaluation::pieces() scores pieces of a given color and type
398 template<Tracing T> template<Color Us, PieceType Pt>
399 Score Evaluation<T>::pieces() {
401 constexpr Color Them = ~Us;
402 constexpr Direction Down = -pawn_push(Us);
403 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
404 : Rank5BB | Rank4BB | Rank3BB);
405 Bitboard b1 = pos.pieces(Us, Pt);
407 Score score = SCORE_ZERO;
409 attackedBy[Us][Pt] = 0;
413 Square s = pop_lsb(b1);
415 // Find attacked squares, including x-ray attacks for bishops and rooks
416 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
417 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
418 : attacks_bb<Pt>(s, pos.pieces());
420 if (pos.blockers_for_king(Us) & s)
421 b &= line_bb(pos.square<KING>(Us), s);
423 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
424 attackedBy[Us][Pt] |= b;
425 attackedBy[Us][ALL_PIECES] |= b;
427 if (b & kingRing[Them])
429 kingAttackersCount[Us]++;
430 kingAttackersWeight[Us] += KingAttackWeights[Pt];
431 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
434 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
435 score += RookOnKingRing;
437 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
438 score += BishopOnKingRing;
440 int mob = popcount(b & mobilityArea[Us]);
441 mobility[Us] += MobilityBonus[Pt - 2][mob];
443 if (Pt == BISHOP || Pt == KNIGHT)
445 // Bonus if the piece is on an outpost square or can reach one
446 // Bonus for knights (UncontestedOutpost) if few relevant targets
447 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
448 & ~pe->pawn_attacks_span(Them);
449 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
452 && bb & s & ~CenterFiles // on a side outpost
453 && !(b & targets) // no relevant attacks
454 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
455 score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
457 score += Outpost[Pt == BISHOP];
458 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
459 score += ReachableOutpost;
461 // Bonus for a knight or bishop shielded by pawn
462 if (shift<Down>(pos.pieces(PAWN)) & s)
463 score += MinorBehindPawn;
465 // Penalty if the piece is far from the king
466 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
468 if constexpr (Pt == BISHOP)
470 // Penalty according to the number of our pawns on the same color square as the
471 // bishop, bigger when the center files are blocked with pawns and smaller
472 // when the bishop is outside the pawn chain.
473 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
475 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
476 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
478 // Penalty for all enemy pawns x-rayed
479 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
481 // Bonus for bishop on a long diagonal which can "see" both center squares
482 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
483 score += LongDiagonalBishop;
485 // An important Chess960 pattern: a cornered bishop blocked by a friendly
486 // pawn diagonally in front of it is a very serious problem, especially
487 // when that pawn is also blocked.
488 if ( pos.is_chess960()
489 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
491 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
492 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
493 score -= !pos.empty(s + d + pawn_push(Us)) ? 4 * make_score(CorneredBishop, CorneredBishop)
494 : 3 * make_score(CorneredBishop, CorneredBishop);
499 if constexpr (Pt == ROOK)
501 // Bonuses for rook on a (semi-)open or closed file
502 if (pos.is_on_semiopen_file(Us, s))
504 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
508 // If our pawn on this file is blocked, increase penalty
509 if ( pos.pieces(Us, PAWN)
510 & shift<Down>(pos.pieces())
513 score -= RookOnClosedFile;
516 // Penalty when trapped by the king, even more if the king cannot castle
519 File kf = file_of(pos.square<KING>(Us));
520 if ((kf < FILE_E) == (file_of(s) < kf))
521 score -= TrappedRook * (1 + !pos.castling_rights(Us));
526 if constexpr (Pt == QUEEN)
528 // Penalty if any relative pin or discovered attack against the queen
529 Bitboard queenPinners;
530 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
535 Trace::add(Pt, Us, score);
541 // Evaluation::king() assigns bonuses and penalties to a king of a given color
543 template<Tracing T> template<Color Us>
544 Score Evaluation<T>::king() const {
546 constexpr Color Them = ~Us;
547 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
548 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
550 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
551 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
553 const Square ksq = pos.square<KING>(Us);
555 // Init the score with king shelter and enemy pawns storm
556 Score score = pe->king_safety<Us>(pos);
558 // Attacked squares defended at most once by our queen or king
559 weak = attackedBy[Them][ALL_PIECES]
561 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
563 // Analyse the safe enemy's checks which are possible on next move
564 safe = ~pos.pieces(Them);
565 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
567 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
568 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
570 // Enemy rooks checks
571 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
573 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
575 unsafeChecks |= b1 & attackedBy[Them][ROOK];
577 // Enemy queen safe checks: count them only if the checks are from squares from
578 // which opponent cannot give a rook check, because rook checks are more valuable.
579 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
580 & ~(attackedBy[Us][QUEEN] | rookChecks);
582 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
584 // Enemy bishops checks: count them only if they are from squares from which
585 // opponent cannot give a queen check, because queen checks are more valuable.
586 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
589 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
592 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
594 // Enemy knights checks
595 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
596 if (knightChecks & safe)
597 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
599 unsafeChecks |= knightChecks;
601 // Find the squares that opponent attacks in our king flank, the squares
602 // which they attack twice in that flank, and the squares that we defend.
603 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
604 b2 = b1 & attackedBy2[Them];
605 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
607 int kingFlankAttack = popcount(b1) + popcount(b2);
608 int kingFlankDefense = popcount(b3);
610 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
611 + 183 * popcount(kingRing[Us] & weak) // (~15 Elo)
612 + 148 * popcount(unsafeChecks) // (~4 Elo)
613 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
614 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
615 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
616 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
617 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
618 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
619 - 6 * mg_value(score) / 8 // (~8 Elo)
620 - 4 * kingFlankDefense // (~5 Elo)
623 // Transform the kingDanger units into a Score, and subtract it from the evaluation
624 if (kingDanger > 100)
625 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
627 // Penalty when our king is on a pawnless flank
628 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
629 score -= PawnlessFlank;
631 // Penalty if king flank is under attack, potentially moving toward the king
632 score -= FlankAttacks * kingFlankAttack;
635 Trace::add(KING, Us, score);
641 // Evaluation::threats() assigns bonuses according to the types of the
642 // attacking and the attacked pieces.
644 template<Tracing T> template<Color Us>
645 Score Evaluation<T>::threats() const {
647 constexpr Color Them = ~Us;
648 constexpr Direction Up = pawn_push(Us);
649 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
651 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
652 Score score = SCORE_ZERO;
655 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
657 // Squares strongly protected by the enemy, either because they defend the
658 // square with a pawn, or because they defend the square twice and we don't.
659 stronglyProtected = attackedBy[Them][PAWN]
660 | (attackedBy2[Them] & ~attackedBy2[Us]);
662 // Non-pawn enemies, strongly protected
663 defended = nonPawnEnemies & stronglyProtected;
665 // Enemies not strongly protected and under our attack
666 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
668 // Bonus according to the kind of attacking pieces
671 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
673 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(b)))];
675 b = weak & attackedBy[Us][ROOK];
677 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(b)))];
679 if (weak & attackedBy[Us][KING])
680 score += ThreatByKing;
682 b = ~attackedBy[Them][ALL_PIECES]
683 | (nonPawnEnemies & attackedBy2[Us]);
684 score += Hanging * popcount(weak & b);
686 // Additional bonus if weak piece is only protected by a queen
687 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
690 // Bonus for restricting their piece moves
691 b = attackedBy[Them][ALL_PIECES]
693 & attackedBy[Us][ALL_PIECES];
694 score += RestrictedPiece * popcount(b);
696 // Protected or unattacked squares
697 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
699 // Bonus for attacking enemy pieces with our relatively safe pawns
700 b = pos.pieces(Us, PAWN) & safe;
701 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
702 score += ThreatBySafePawn * popcount(b);
704 // Find squares where our pawns can push on the next move
705 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
706 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
708 // Keep only the squares which are relatively safe
709 b &= ~attackedBy[Them][PAWN] & safe;
711 // Bonus for safe pawn threats on the next move
712 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
713 score += ThreatByPawnPush * popcount(b);
715 // Bonus for threats on the next moves against enemy queen
716 if (pos.count<QUEEN>(Them) == 1)
718 bool queenImbalance = pos.count<QUEEN>() == 1;
720 Square s = pos.square<QUEEN>(Them);
721 safe = mobilityArea[Us]
722 & ~pos.pieces(Us, PAWN)
723 & ~stronglyProtected;
725 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
727 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
729 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
730 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
732 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
736 Trace::add(THREAT, Us, score);
741 // Evaluation::passed() evaluates the passed pawns and candidate passed
742 // pawns of the given color.
744 template<Tracing T> template<Color Us>
745 Score Evaluation<T>::passed() const {
747 constexpr Color Them = ~Us;
748 constexpr Direction Up = pawn_push(Us);
749 constexpr Direction Down = -Up;
751 auto king_proximity = [&](Color c, Square s) {
752 return std::min(distance(pos.square<KING>(c), s), 5);
755 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
756 Score score = SCORE_ZERO;
758 b = pe->passed_pawns(Us);
760 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
763 helpers = shift<Up>(pos.pieces(Us, PAWN))
765 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
767 // Remove blocked candidate passers that don't have help to pass
769 | shift<WEST>(helpers)
770 | shift<EAST>(helpers);
775 Square s = pop_lsb(b);
777 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
779 int r = relative_rank(Us, s);
781 Score bonus = PassedRank[r];
786 Square blockSq = s + Up;
788 // Adjust bonus based on the king's proximity
789 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
790 - king_proximity(Us, blockSq) * 2) * w);
792 // If blockSq is not the queening square then consider also a second push
794 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
796 // If the pawn is free to advance, then increase the bonus
797 if (pos.empty(blockSq))
799 squaresToQueen = forward_file_bb(Us, s);
800 unsafeSquares = passed_pawn_span(Us, s);
802 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
804 if (!(pos.pieces(Them) & bb))
805 unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
807 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
808 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
809 // Otherwise assign a smaller bonus if the path to queen is not attacked
810 // and even smaller bonus if it is attacked but block square is not.
811 int k = !unsafeSquares ? 36 :
812 !(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
813 !(unsafeSquares & squaresToQueen) ? 17 :
814 !(unsafeSquares & blockSq) ? 7 :
817 // Assign a larger bonus if the block square is defended
818 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
821 bonus += make_score(k * w, k * w);
825 score += bonus - PassedFile * edge_distance(file_of(s));
829 Trace::add(PASSED, Us, score);
835 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
836 // play in the opening. It is based on the number of safe squares on the four central files
837 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
838 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
840 template<Tracing T> template<Color Us>
841 Score Evaluation<T>::space() const {
843 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
844 if (pos.non_pawn_material() < SpaceThreshold)
847 constexpr Color Them = ~Us;
848 constexpr Direction Down = -pawn_push(Us);
849 constexpr Bitboard SpaceMask =
850 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
851 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
853 // Find the available squares for our pieces inside the area defined by SpaceMask
854 Bitboard safe = SpaceMask
855 & ~pos.pieces(Us, PAWN)
856 & ~attackedBy[Them][PAWN];
858 // Find all squares which are at most three squares behind some friendly pawn
859 Bitboard behind = pos.pieces(Us, PAWN);
860 behind |= shift<Down>(behind);
861 behind |= shift<Down+Down>(behind);
863 // Compute space score based on the number of safe squares and number of our pieces
864 // increased with number of total blocked pawns in position.
865 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
866 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
867 Score score = make_score(bonus * weight * weight / 16, 0);
870 Trace::add(SPACE, Us, score);
876 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
877 // the known attacking/defending status of the players. The final value is derived
878 // by interpolation from the midgame and endgame values.
881 Value Evaluation<T>::winnable(Score score) const {
883 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
884 + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
886 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
887 && (pos.pieces(PAWN) & KingSide);
889 bool almostUnwinnable = outflanking < 0
890 && !pawnsOnBothFlanks;
892 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
893 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
895 // Compute the initiative bonus for the attacking side
896 int complexity = 9 * pe->passed_count()
897 + 12 * pos.count<PAWN>()
899 + 21 * pawnsOnBothFlanks
901 + 51 * !pos.non_pawn_material()
902 - 43 * almostUnwinnable
905 Value mg = mg_value(score);
906 Value eg = eg_value(score);
908 // Now apply the bonus: note that we find the attacking side by extracting the
909 // sign of the midgame or endgame values, and that we carefully cap the bonus
910 // so that the midgame and endgame scores do not change sign after the bonus.
911 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
912 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
917 // Compute the scale factor for the winning side
918 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
919 int sf = me->scale_factor(pos, strongSide);
921 // If scale factor is not already specific, scale down via general heuristics
922 if (sf == SCALE_FACTOR_NORMAL)
924 if (pos.opposite_bishops())
926 // For pure opposite colored bishops endgames use scale factor
927 // based on the number of passed pawns of the strong side.
928 if ( pos.non_pawn_material(WHITE) == BishopValueMg
929 && pos.non_pawn_material(BLACK) == BishopValueMg)
930 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
931 // For every other opposite colored bishops endgames use scale factor
932 // based on the number of all pieces of the strong side.
934 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
936 // For rook endgames with strong side not having overwhelming pawn number advantage
937 // and its pawns being on one flank and weak side protecting its pieces with a king
938 // use lower scale factor.
939 else if ( pos.non_pawn_material(WHITE) == RookValueMg
940 && pos.non_pawn_material(BLACK) == RookValueMg
941 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
942 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
943 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
945 // For queen vs no queen endgames use scale factor
946 // based on number of minors of side that doesn't have queen.
947 else if (pos.count<QUEEN>() == 1)
948 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
949 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
950 // In every other case use scale factor based on
951 // the number of pawns of the strong side reduced if pawns are on a single flank.
953 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
955 // Reduce scale factor in case of pawns being on a single flank
956 sf -= 4 * !pawnsOnBothFlanks;
959 // Interpolate between the middlegame and (scaled by 'sf') endgame score
960 v = mg * int(me->game_phase())
961 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
966 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
967 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
974 // Evaluation::value() is the main function of the class. It computes the various
975 // parts of the evaluation and returns the value of the position from the point
976 // of view of the side to move.
979 Value Evaluation<T>::value() {
981 assert(!pos.checkers());
983 // Probe the material hash table
984 me = Material::probe(pos);
986 // If we have a specialized evaluation function for the current material
987 // configuration, call it and return.
988 if (me->specialized_eval_exists())
989 return me->evaluate(pos);
991 // Initialize score by reading the incrementally updated scores included in
992 // the position object (material + piece square tables) and the material
993 // imbalance. Score is computed internally from the white point of view.
994 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
996 // Probe the pawn hash table
997 pe = Pawns::probe(pos);
998 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
1000 // Early exit if score is high
1001 auto lazy_skip = [&](Value lazyThreshold) {
1002 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
1005 if (lazy_skip(LazyThreshold1))
1008 // Main evaluation begins here
1009 initialize<WHITE>();
1010 initialize<BLACK>();
1012 // Pieces evaluated first (also populates attackedBy, attackedBy2).
1013 // Note that the order of evaluation of the terms is left unspecified.
1014 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
1015 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
1016 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
1017 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
1019 score += mobility[WHITE] - mobility[BLACK];
1021 // More complex interactions that require fully populated attack bitboards
1022 score += king< WHITE>() - king< BLACK>()
1023 + passed< WHITE>() - passed< BLACK>();
1025 if (lazy_skip(LazyThreshold2))
1028 score += threats<WHITE>() - threats<BLACK>()
1029 + space< WHITE>() - space< BLACK>();
1032 // Derive single value from mg and eg parts of score
1033 Value v = winnable(score);
1035 // In case of tracing add all remaining individual evaluation terms
1038 Trace::add(MATERIAL, pos.psq_score());
1039 Trace::add(IMBALANCE, me->imbalance());
1040 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1041 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1047 // Side to move point of view
1048 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
1054 /// Fisher Random Chess: correction for cornered bishops, to fix chess960 play with NNUE
1056 Value fix_FRC(const Position& pos) {
1058 constexpr Bitboard Corners = 1ULL << SQ_A1 | 1ULL << SQ_H1 | 1ULL << SQ_A8 | 1ULL << SQ_H8;
1060 if (!(pos.pieces(BISHOP) & Corners))
1065 if ( pos.piece_on(SQ_A1) == W_BISHOP
1066 && pos.piece_on(SQ_B2) == W_PAWN)
1067 correction += !pos.empty(SQ_B3) ? -CorneredBishop * 4
1068 : -CorneredBishop * 3;
1070 if ( pos.piece_on(SQ_H1) == W_BISHOP
1071 && pos.piece_on(SQ_G2) == W_PAWN)
1072 correction += !pos.empty(SQ_G3) ? -CorneredBishop * 4
1073 : -CorneredBishop * 3;
1075 if ( pos.piece_on(SQ_A8) == B_BISHOP
1076 && pos.piece_on(SQ_B7) == B_PAWN)
1077 correction += !pos.empty(SQ_B6) ? CorneredBishop * 4
1078 : CorneredBishop * 3;
1080 if ( pos.piece_on(SQ_H8) == B_BISHOP
1081 && pos.piece_on(SQ_G7) == B_PAWN)
1082 correction += !pos.empty(SQ_G6) ? CorneredBishop * 4
1083 : CorneredBishop * 3;
1085 return pos.side_to_move() == WHITE ? Value(correction)
1086 : -Value(correction);
1092 /// evaluate() is the evaluator for the outer world. It returns a static
1093 /// evaluation of the position from the point of view of the side to move.
1095 Value Eval::evaluate(const Position& pos) {
1100 v = Evaluation<NO_TRACE>(pos).value();
1103 // Scale and shift NNUE for compatibility with search and classical evaluation
1104 auto adjusted_NNUE = [&]()
1106 int material = pos.non_pawn_material() + 4 * PawnValueMg * pos.count<PAWN>();
1109 - 4 * pos.rule50_count();
1111 Value nnue = NNUE::evaluate(pos) * scale / 1024 + Time.tempoNNUE;
1113 if (pos.is_chess960())
1114 nnue += fix_FRC(pos);
1119 // If there is PSQ imbalance we use the classical eval. We also introduce
1120 // a small probability of using the classical eval when PSQ imbalance is small.
1121 Value psq = Value(abs(eg_value(pos.psq_score())));
1122 int r50 = 16 + pos.rule50_count();
1123 bool largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50;
1124 bool classical = largePsq || (psq > PawnValueMg / 4 && !(pos.this_thread()->nodes & 0xB));
1126 // Use classical evaluation for really low piece endgames.
1127 // One critical case is the draw for bishop + A/H file pawn vs naked king.
1128 bool lowPieceEndgame = pos.non_pawn_material() == BishopValueMg
1129 || (pos.non_pawn_material() < 2 * RookValueMg && pos.count<PAWN>() < 2);
1131 v = classical || lowPieceEndgame ? Evaluation<NO_TRACE>(pos).value()
1134 // If the classical eval is small and imbalance large, use NNUE nevertheless.
1135 // For the case of opposite colored bishops, switch to NNUE eval with small
1136 // probability if the classical eval is less than the threshold.
1139 && ( abs(v) * 16 < NNUEThreshold2 * r50
1140 || ( pos.opposite_bishops()
1141 && abs(v) * 16 < (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50
1142 && !(pos.this_thread()->nodes & 0xB))))
1143 v = adjusted_NNUE();
1146 // Damp down the evaluation linearly when shuffling
1147 v = v * (100 - pos.rule50_count()) / 100;
1149 // Guarantee evaluation does not hit the tablebase range
1150 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1155 /// trace() is like evaluate(), but instead of returning a value, it returns
1156 /// a string (suitable for outputting to stdout) that contains the detailed
1157 /// descriptions and values of each evaluation term. Useful for debugging.
1158 /// Trace scores are from white's point of view
1160 std::string Eval::trace(const Position& pos) {
1163 return "Final evaluation: none (in check)";
1165 std::stringstream ss;
1166 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1170 std::memset(scores, 0, sizeof(scores));
1172 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
1174 v = Evaluation<TRACE>(pos).value();
1176 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1177 << " Term | White | Black | Total \n"
1178 << " | MG EG | MG EG | MG EG \n"
1179 << " ------------+-------------+-------------+------------\n"
1180 << " Material | " << Term(MATERIAL)
1181 << " Imbalance | " << Term(IMBALANCE)
1182 << " Pawns | " << Term(PAWN)
1183 << " Knights | " << Term(KNIGHT)
1184 << " Bishops | " << Term(BISHOP)
1185 << " Rooks | " << Term(ROOK)
1186 << " Queens | " << Term(QUEEN)
1187 << " Mobility | " << Term(MOBILITY)
1188 << " King safety | " << Term(KING)
1189 << " Threats | " << Term(THREAT)
1190 << " Passed | " << Term(PASSED)
1191 << " Space | " << Term(SPACE)
1192 << " Winnable | " << Term(WINNABLE)
1193 << " ------------+-------------+-------------+------------\n"
1194 << " Total | " << Term(TOTAL);
1196 v = pos.side_to_move() == WHITE ? v : -v;
1198 ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n";
1202 v = NNUE::evaluate(pos);
1203 v = pos.side_to_move() == WHITE ? v : -v;
1204 ss << "\nNNUE evaluation: " << to_cp(v) << " (white side)\n";
1208 v = pos.side_to_move() == WHITE ? v : -v;
1209 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";
1214 } // namespace Stockfish