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));
111 (void) gEmbeddedNNUEEnd; // Silence warning on unused variable
113 istream stream(&buffer);
114 if (load_eval(eval_file, stream))
115 currentEvalFileName = eval_file;
120 /// NNUE::verify() verifies that the last net used was loaded successfully
121 void NNUE::verify() {
123 string eval_file = string(Options["EvalFile"]);
124 if (eval_file.empty())
125 eval_file = EvalFileDefaultName;
127 if (useNNUE && currentEvalFileName != eval_file)
130 string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
131 string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
132 string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
133 string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + std::string(EvalFileDefaultName);
134 string msg5 = "The engine will be terminated now.";
136 sync_cout << "info string ERROR: " << msg1 << sync_endl;
137 sync_cout << "info string ERROR: " << msg2 << sync_endl;
138 sync_cout << "info string ERROR: " << msg3 << sync_endl;
139 sync_cout << "info string ERROR: " << msg4 << sync_endl;
140 sync_cout << "info string ERROR: " << msg5 << sync_endl;
146 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
148 sync_cout << "info string classical evaluation enabled" << sync_endl;
154 enum Tracing { NO_TRACE, TRACE };
156 enum Term { // The first 8 entries are reserved for PieceType
157 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
160 Score scores[TERM_NB][COLOR_NB];
162 double to_cp(Value v) { return double(v) / PawnValueEg; }
164 void add(int idx, Color c, Score s) {
168 void add(int idx, Score w, Score b = SCORE_ZERO) {
169 scores[idx][WHITE] = w;
170 scores[idx][BLACK] = b;
173 std::ostream& operator<<(std::ostream& os, Score s) {
174 os << std::setw(5) << to_cp(mg_value(s)) << " "
175 << std::setw(5) << to_cp(eg_value(s));
179 std::ostream& operator<<(std::ostream& os, Term t) {
181 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
182 os << " ---- ----" << " | " << " ---- ----";
184 os << scores[t][WHITE] << " | " << scores[t][BLACK];
186 os << " | " << scores[t][WHITE] - scores[t][BLACK] << " |\n";
191 using namespace Trace;
195 // Threshold for lazy and space evaluation
196 constexpr Value LazyThreshold1 = Value(3631);
197 constexpr Value LazyThreshold2 = Value(2084);
198 constexpr Value SpaceThreshold = Value(11551);
200 // KingAttackWeights[PieceType] contains king attack weights by piece type
201 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 76, 46, 45, 14 };
203 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
204 // higher if multiple safe checks are possible for that piece type.
205 constexpr int SafeCheck[][2] = {
206 {}, {}, {805, 1292}, {650, 984}, {1071, 1886}, {730, 1128}
209 #define S(mg, eg) make_score(mg, eg)
211 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
212 // indexed by piece type and number of attacked squares in the mobility area.
213 constexpr Score MobilityBonus[][32] = {
214 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
215 S( 21, 16), S( 28, 21), S( 37, 26) },
216 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
217 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
218 S( 91, 88), S( 96, 98) },
219 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
220 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
221 S( 57,165), S( 58,170), S( 67,175) },
222 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
223 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
224 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
225 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
226 S(112,178), S(114,185), S(114,187), S(119,221) }
229 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
230 // squares of the same color as our bishop.
231 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
232 S(3, 8), S(3, 9), S(2, 7), S(3, 7)
235 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
236 constexpr Score KingProtector[] = { S(9, 9), S(7, 9) };
238 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
239 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
240 constexpr Score Outpost[] = { S(54, 34), S(31, 25) };
242 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
243 constexpr Score PassedRank[RANK_NB] = {
244 S(0, 0), S(2, 38), S(15, 36), S(22, 50), S(64, 81), S(166, 184), S(284, 269)
247 constexpr Score RookOnClosedFile = S(10, 5);
248 constexpr Score RookOnOpenFile[] = { S(18, 8), S(49, 26) };
250 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
251 // which piece type attacks which one. Attacks on lesser pieces which are
252 // pawn-defended are not considered.
253 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
254 S(0, 0), S(6, 37), S(64, 50), S(82, 57), S(103, 130), S(81, 163)
257 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
258 S(0, 0), S(3, 44), S(36, 71), S(44, 59), S(0, 39), S(60, 39)
261 constexpr Value CorneredBishop = Value(50);
263 // Assorted bonuses and penalties
264 constexpr Score UncontestedOutpost = S( 0, 10);
265 constexpr Score BishopOnKingRing = S( 24, 0);
266 constexpr Score BishopXRayPawns = S( 4, 5);
267 constexpr Score FlankAttacks = S( 8, 0);
268 constexpr Score Hanging = S( 72, 40);
269 constexpr Score KnightOnQueen = S( 16, 11);
270 constexpr Score LongDiagonalBishop = S( 45, 0);
271 constexpr Score MinorBehindPawn = S( 18, 3);
272 constexpr Score PassedFile = S( 13, 8);
273 constexpr Score PawnlessFlank = S( 19, 97);
274 constexpr Score ReachableOutpost = S( 33, 19);
275 constexpr Score RestrictedPiece = S( 6, 7);
276 constexpr Score RookOnKingRing = S( 16, 0);
277 constexpr Score SliderOnQueen = S( 62, 21);
278 constexpr Score ThreatByKing = S( 24, 87);
279 constexpr Score ThreatByPawnPush = S( 48, 39);
280 constexpr Score ThreatBySafePawn = S(167, 99);
281 constexpr Score TrappedRook = S( 55, 13);
282 constexpr Score WeakQueenProtection = S( 14, 0);
283 constexpr Score WeakQueen = S( 57, 19);
288 // Evaluation class computes and stores attacks tables and other working data
293 Evaluation() = delete;
294 explicit Evaluation(const Position& p) : pos(p) {}
295 Evaluation& operator=(const Evaluation&) = delete;
299 template<Color Us> void initialize();
300 template<Color Us, PieceType Pt> Score pieces();
301 template<Color Us> Score king() const;
302 template<Color Us> Score threats() const;
303 template<Color Us> Score passed() const;
304 template<Color Us> Score space() const;
305 Value winnable(Score score) const;
310 Bitboard mobilityArea[COLOR_NB];
311 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
313 // attackedBy[color][piece type] is a bitboard representing all squares
314 // attacked by a given color and piece type. Special "piece types" which
315 // is also calculated is ALL_PIECES.
316 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
318 // attackedBy2[color] are the squares attacked by at least 2 units of a given
319 // color, including x-rays. But diagonal x-rays through pawns are not computed.
320 Bitboard attackedBy2[COLOR_NB];
322 // kingRing[color] are the squares adjacent to the king plus some other
323 // very near squares, depending on king position.
324 Bitboard kingRing[COLOR_NB];
326 // kingAttackersCount[color] is the number of pieces of the given color
327 // which attack a square in the kingRing of the enemy king.
328 int kingAttackersCount[COLOR_NB];
330 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
331 // the given color which attack a square in the kingRing of the enemy king.
332 // The weights of the individual piece types are given by the elements in
333 // the KingAttackWeights array.
334 int kingAttackersWeight[COLOR_NB];
336 // kingAttacksCount[color] is the number of attacks by the given color to
337 // squares directly adjacent to the enemy king. Pieces which attack more
338 // than one square are counted multiple times. For instance, if there is
339 // a white knight on g5 and black's king is on g8, this white knight adds 2
340 // to kingAttacksCount[WHITE].
341 int kingAttacksCount[COLOR_NB];
345 // Evaluation::initialize() computes king and pawn attacks, and the king ring
346 // bitboard for a given color. This is done at the beginning of the evaluation.
348 template<Tracing T> template<Color Us>
349 void Evaluation<T>::initialize() {
351 constexpr Color Them = ~Us;
352 constexpr Direction Up = pawn_push(Us);
353 constexpr Direction Down = -Up;
354 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
356 const Square ksq = pos.square<KING>(Us);
358 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
360 // Find our pawns that are blocked or on the first two ranks
361 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
363 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
364 // or controlled by enemy pawns are excluded from the mobility area.
365 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
367 // Initialize attackedBy[] for king and pawns
368 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
369 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
370 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
371 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
373 // Init our king safety tables
374 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
375 std::clamp(rank_of(ksq), RANK_2, RANK_7));
376 kingRing[Us] = attacks_bb<KING>(s) | s;
378 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
379 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
381 // Remove from kingRing[] the squares defended by two pawns
382 kingRing[Us] &= ~dblAttackByPawn;
386 // Evaluation::pieces() scores pieces of a given color and type
388 template<Tracing T> template<Color Us, PieceType Pt>
389 Score Evaluation<T>::pieces() {
391 constexpr Color Them = ~Us;
392 constexpr Direction Down = -pawn_push(Us);
393 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
394 : Rank5BB | Rank4BB | Rank3BB);
395 Bitboard b1 = pos.pieces(Us, Pt);
397 Score score = SCORE_ZERO;
399 attackedBy[Us][Pt] = 0;
403 Square s = pop_lsb(b1);
405 // Find attacked squares, including x-ray attacks for bishops and rooks
406 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
407 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
408 : attacks_bb<Pt>(s, pos.pieces());
410 if (pos.blockers_for_king(Us) & s)
411 b &= line_bb(pos.square<KING>(Us), s);
413 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
414 attackedBy[Us][Pt] |= b;
415 attackedBy[Us][ALL_PIECES] |= b;
417 if (b & kingRing[Them])
419 kingAttackersCount[Us]++;
420 kingAttackersWeight[Us] += KingAttackWeights[Pt];
421 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
424 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
425 score += RookOnKingRing;
427 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
428 score += BishopOnKingRing;
430 int mob = popcount(b & mobilityArea[Us]);
431 mobility[Us] += MobilityBonus[Pt - 2][mob];
433 if (Pt == BISHOP || Pt == KNIGHT)
435 // Bonus if the piece is on an outpost square or can reach one
436 // Bonus for knights (UncontestedOutpost) if few relevant targets
437 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
438 & ~pe->pawn_attacks_span(Them);
439 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
442 && bb & s & ~CenterFiles // on a side outpost
443 && !(b & targets) // no relevant attacks
444 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
445 score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
447 score += Outpost[Pt == BISHOP];
448 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
449 score += ReachableOutpost;
451 // Bonus for a knight or bishop shielded by pawn
452 if (shift<Down>(pos.pieces(PAWN)) & s)
453 score += MinorBehindPawn;
455 // Penalty if the piece is far from the king
456 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
458 if constexpr (Pt == BISHOP)
460 // Penalty according to the number of our pawns on the same color square as the
461 // bishop, bigger when the center files are blocked with pawns and smaller
462 // when the bishop is outside the pawn chain.
463 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
465 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
466 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
468 // Penalty for all enemy pawns x-rayed
469 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
471 // Bonus for bishop on a long diagonal which can "see" both center squares
472 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
473 score += LongDiagonalBishop;
475 // An important Chess960 pattern: a cornered bishop blocked by a friendly
476 // pawn diagonally in front of it is a very serious problem, especially
477 // when that pawn is also blocked.
478 if ( pos.is_chess960()
479 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
481 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
482 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
483 score -= !pos.empty(s + d + pawn_push(Us)) ? 4 * make_score(CorneredBishop, CorneredBishop)
484 : 3 * make_score(CorneredBishop, CorneredBishop);
489 if constexpr (Pt == ROOK)
491 // Bonuses for rook on a (semi-)open or closed file
492 if (pos.is_on_semiopen_file(Us, s))
494 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
498 // If our pawn on this file is blocked, increase penalty
499 if ( pos.pieces(Us, PAWN)
500 & shift<Down>(pos.pieces())
503 score -= RookOnClosedFile;
506 // Penalty when trapped by the king, even more if the king cannot castle
509 File kf = file_of(pos.square<KING>(Us));
510 if ((kf < FILE_E) == (file_of(s) < kf))
511 score -= TrappedRook * (1 + !pos.castling_rights(Us));
516 if constexpr (Pt == QUEEN)
518 // Penalty if any relative pin or discovered attack against the queen
519 Bitboard queenPinners;
520 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
525 Trace::add(Pt, Us, score);
531 // Evaluation::king() assigns bonuses and penalties to a king of a given color
533 template<Tracing T> template<Color Us>
534 Score Evaluation<T>::king() const {
536 constexpr Color Them = ~Us;
537 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
538 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
540 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
541 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
543 const Square ksq = pos.square<KING>(Us);
545 // Init the score with king shelter and enemy pawns storm
546 Score score = pe->king_safety<Us>(pos);
548 // Attacked squares defended at most once by our queen or king
549 weak = attackedBy[Them][ALL_PIECES]
551 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
553 // Analyse the safe enemy's checks which are possible on next move
554 safe = ~pos.pieces(Them);
555 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
557 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
558 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
560 // Enemy rooks checks
561 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
563 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
565 unsafeChecks |= b1 & attackedBy[Them][ROOK];
567 // Enemy queen safe checks: count them only if the checks are from squares from
568 // which opponent cannot give a rook check, because rook checks are more valuable.
569 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
570 & ~(attackedBy[Us][QUEEN] | rookChecks);
572 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
574 // Enemy bishops checks: count them only if they are from squares from which
575 // opponent cannot give a queen check, because queen checks are more valuable.
576 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
579 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
582 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
584 // Enemy knights checks
585 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
586 if (knightChecks & safe)
587 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
589 unsafeChecks |= knightChecks;
591 // Find the squares that opponent attacks in our king flank, the squares
592 // which they attack twice in that flank, and the squares that we defend.
593 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
594 b2 = b1 & attackedBy2[Them];
595 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
597 int kingFlankAttack = popcount(b1) + popcount(b2);
598 int kingFlankDefense = popcount(b3);
600 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
601 + 183 * popcount(kingRing[Us] & weak) // (~15 Elo)
602 + 148 * popcount(unsafeChecks) // (~4 Elo)
603 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
604 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
605 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
606 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
607 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
608 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
609 - 6 * mg_value(score) / 8 // (~8 Elo)
610 - 4 * kingFlankDefense // (~5 Elo)
613 // Transform the kingDanger units into a Score, and subtract it from the evaluation
614 if (kingDanger > 100)
615 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
617 // Penalty when our king is on a pawnless flank
618 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
619 score -= PawnlessFlank;
621 // Penalty if king flank is under attack, potentially moving toward the king
622 score -= FlankAttacks * kingFlankAttack;
625 Trace::add(KING, Us, score);
631 // Evaluation::threats() assigns bonuses according to the types of the
632 // attacking and the attacked pieces.
634 template<Tracing T> template<Color Us>
635 Score Evaluation<T>::threats() const {
637 constexpr Color Them = ~Us;
638 constexpr Direction Up = pawn_push(Us);
639 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
641 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
642 Score score = SCORE_ZERO;
645 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
647 // Squares strongly protected by the enemy, either because they defend the
648 // square with a pawn, or because they defend the square twice and we don't.
649 stronglyProtected = attackedBy[Them][PAWN]
650 | (attackedBy2[Them] & ~attackedBy2[Us]);
652 // Non-pawn enemies, strongly protected
653 defended = nonPawnEnemies & stronglyProtected;
655 // Enemies not strongly protected and under our attack
656 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
658 // Bonus according to the kind of attacking pieces
661 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
663 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(b)))];
665 b = weak & attackedBy[Us][ROOK];
667 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(b)))];
669 if (weak & attackedBy[Us][KING])
670 score += ThreatByKing;
672 b = ~attackedBy[Them][ALL_PIECES]
673 | (nonPawnEnemies & attackedBy2[Us]);
674 score += Hanging * popcount(weak & b);
676 // Additional bonus if weak piece is only protected by a queen
677 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
680 // Bonus for restricting their piece moves
681 b = attackedBy[Them][ALL_PIECES]
683 & attackedBy[Us][ALL_PIECES];
684 score += RestrictedPiece * popcount(b);
686 // Protected or unattacked squares
687 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
689 // Bonus for attacking enemy pieces with our relatively safe pawns
690 b = pos.pieces(Us, PAWN) & safe;
691 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
692 score += ThreatBySafePawn * popcount(b);
694 // Find squares where our pawns can push on the next move
695 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
696 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
698 // Keep only the squares which are relatively safe
699 b &= ~attackedBy[Them][PAWN] & safe;
701 // Bonus for safe pawn threats on the next move
702 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
703 score += ThreatByPawnPush * popcount(b);
705 // Bonus for threats on the next moves against enemy queen
706 if (pos.count<QUEEN>(Them) == 1)
708 bool queenImbalance = pos.count<QUEEN>() == 1;
710 Square s = pos.square<QUEEN>(Them);
711 safe = mobilityArea[Us]
712 & ~pos.pieces(Us, PAWN)
713 & ~stronglyProtected;
715 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
717 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
719 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
720 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
722 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
726 Trace::add(THREAT, Us, score);
731 // Evaluation::passed() evaluates the passed pawns and candidate passed
732 // pawns of the given color.
734 template<Tracing T> template<Color Us>
735 Score Evaluation<T>::passed() const {
737 constexpr Color Them = ~Us;
738 constexpr Direction Up = pawn_push(Us);
739 constexpr Direction Down = -Up;
741 auto king_proximity = [&](Color c, Square s) {
742 return std::min(distance(pos.square<KING>(c), s), 5);
745 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
746 Score score = SCORE_ZERO;
748 b = pe->passed_pawns(Us);
750 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
753 helpers = shift<Up>(pos.pieces(Us, PAWN))
755 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
757 // Remove blocked candidate passers that don't have help to pass
759 | shift<WEST>(helpers)
760 | shift<EAST>(helpers);
765 Square s = pop_lsb(b);
767 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
769 int r = relative_rank(Us, s);
771 Score bonus = PassedRank[r];
776 Square blockSq = s + Up;
778 // Adjust bonus based on the king's proximity
779 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
780 - king_proximity(Us, blockSq) * 2) * w);
782 // If blockSq is not the queening square then consider also a second push
784 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
786 // If the pawn is free to advance, then increase the bonus
787 if (pos.empty(blockSq))
789 squaresToQueen = forward_file_bb(Us, s);
790 unsafeSquares = passed_pawn_span(Us, s);
792 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
794 if (!(pos.pieces(Them) & bb))
795 unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
797 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
798 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
799 // Otherwise assign a smaller bonus if the path to queen is not attacked
800 // and even smaller bonus if it is attacked but block square is not.
801 int k = !unsafeSquares ? 36 :
802 !(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
803 !(unsafeSquares & squaresToQueen) ? 17 :
804 !(unsafeSquares & blockSq) ? 7 :
807 // Assign a larger bonus if the block square is defended
808 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
811 bonus += make_score(k * w, k * w);
815 score += bonus - PassedFile * edge_distance(file_of(s));
819 Trace::add(PASSED, Us, score);
825 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
826 // play in the opening. It is based on the number of safe squares on the four central files
827 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
828 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
830 template<Tracing T> template<Color Us>
831 Score Evaluation<T>::space() const {
833 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
834 if (pos.non_pawn_material() < SpaceThreshold)
837 constexpr Color Them = ~Us;
838 constexpr Direction Down = -pawn_push(Us);
839 constexpr Bitboard SpaceMask =
840 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
841 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
843 // Find the available squares for our pieces inside the area defined by SpaceMask
844 Bitboard safe = SpaceMask
845 & ~pos.pieces(Us, PAWN)
846 & ~attackedBy[Them][PAWN];
848 // Find all squares which are at most three squares behind some friendly pawn
849 Bitboard behind = pos.pieces(Us, PAWN);
850 behind |= shift<Down>(behind);
851 behind |= shift<Down+Down>(behind);
853 // Compute space score based on the number of safe squares and number of our pieces
854 // increased with number of total blocked pawns in position.
855 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
856 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
857 Score score = make_score(bonus * weight * weight / 16, 0);
860 Trace::add(SPACE, Us, score);
866 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
867 // the known attacking/defending status of the players. The final value is derived
868 // by interpolation from the midgame and endgame values.
871 Value Evaluation<T>::winnable(Score score) const {
873 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
874 + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
876 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
877 && (pos.pieces(PAWN) & KingSide);
879 bool almostUnwinnable = outflanking < 0
880 && !pawnsOnBothFlanks;
882 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
883 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
885 // Compute the initiative bonus for the attacking side
886 int complexity = 9 * pe->passed_count()
887 + 12 * pos.count<PAWN>()
889 + 21 * pawnsOnBothFlanks
891 + 51 * !pos.non_pawn_material()
892 - 43 * almostUnwinnable
895 Value mg = mg_value(score);
896 Value eg = eg_value(score);
898 // Now apply the bonus: note that we find the attacking side by extracting the
899 // sign of the midgame or endgame values, and that we carefully cap the bonus
900 // so that the midgame and endgame scores do not change sign after the bonus.
901 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
902 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
907 // Compute the scale factor for the winning side
908 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
909 int sf = me->scale_factor(pos, strongSide);
911 // If scale factor is not already specific, scale up/down via general heuristics
912 if (sf == SCALE_FACTOR_NORMAL)
914 if (pos.opposite_bishops())
916 // For pure opposite colored bishops endgames use scale factor
917 // based on the number of passed pawns of the strong side.
918 if ( pos.non_pawn_material(WHITE) == BishopValueMg
919 && pos.non_pawn_material(BLACK) == BishopValueMg)
920 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
921 // For every other opposite colored bishops endgames use scale factor
922 // based on the number of all pieces of the strong side.
924 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
926 // For rook endgames with strong side not having overwhelming pawn number advantage
927 // and its pawns being on one flank and weak side protecting its pieces with a king
928 // use lower scale factor.
929 else if ( pos.non_pawn_material(WHITE) == RookValueMg
930 && pos.non_pawn_material(BLACK) == RookValueMg
931 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
932 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
933 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
935 // For queen vs no queen endgames use scale factor
936 // based on number of minors of side that doesn't have queen.
937 else if (pos.count<QUEEN>() == 1)
938 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
939 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
940 // In every other case use scale factor based on
941 // the number of pawns of the strong side reduced if pawns are on a single flank.
943 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
945 // Reduce scale factor in case of pawns being on a single flank
946 sf -= 4 * !pawnsOnBothFlanks;
949 // Interpolate between the middlegame and (scaled by 'sf') endgame score
950 v = mg * int(me->game_phase())
951 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
956 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
957 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
964 // Evaluation::value() is the main function of the class. It computes the various
965 // parts of the evaluation and returns the value of the position from the point
966 // of view of the side to move.
969 Value Evaluation<T>::value() {
971 assert(!pos.checkers());
973 // Probe the material hash table
974 me = Material::probe(pos);
976 // If we have a specialized evaluation function for the current material
977 // configuration, call it and return.
978 if (me->specialized_eval_exists())
979 return me->evaluate(pos);
981 // Initialize score by reading the incrementally updated scores included in
982 // the position object (material + piece square tables) and the material
983 // imbalance. Score is computed internally from the white point of view.
984 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->trend;
986 // Probe the pawn hash table
987 pe = Pawns::probe(pos);
988 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
990 // Early exit if score is high
991 auto lazy_skip = [&](Value lazyThreshold) {
992 return abs(mg_value(score) + eg_value(score)) > lazyThreshold
993 + std::abs(pos.this_thread()->bestValue) * 5 / 4
994 + pos.non_pawn_material() / 32;
997 if (lazy_skip(LazyThreshold1))
1000 // Main evaluation begins here
1001 initialize<WHITE>();
1002 initialize<BLACK>();
1004 // Pieces evaluated first (also populates attackedBy, attackedBy2).
1005 // Note that the order of evaluation of the terms is left unspecified.
1006 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
1007 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
1008 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
1009 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
1011 score += mobility[WHITE] - mobility[BLACK];
1013 // More complex interactions that require fully populated attack bitboards
1014 score += king< WHITE>() - king< BLACK>()
1015 + passed< WHITE>() - passed< BLACK>();
1017 if (lazy_skip(LazyThreshold2))
1020 score += threats<WHITE>() - threats<BLACK>()
1021 + space< WHITE>() - space< BLACK>();
1024 // Derive single value from mg and eg parts of score
1025 Value v = winnable(score);
1027 // In case of tracing add all remaining individual evaluation terms
1030 Trace::add(MATERIAL, pos.psq_score());
1031 Trace::add(IMBALANCE, me->imbalance());
1032 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1033 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1039 // Side to move point of view
1040 v = (pos.side_to_move() == WHITE ? v : -v);
1048 /// evaluate() is the evaluator for the outer world. It returns a static
1049 /// evaluation of the position from the point of view of the side to move.
1051 Value Eval::evaluate(const Position& pos, int* complexity) {
1054 Color stm = pos.side_to_move();
1055 Value psq = pos.psq_eg_stm();
1057 // Deciding between classical and NNUE eval: for high PSQ imbalance we use classical,
1058 // but we switch to NNUE during long shuffling or with high material on the board.
1059 bool useClassical = !useNNUE ||
1060 ((pos.count<ALL_PIECES>() > 7)
1061 && abs(psq) * 5 > (856 + pos.non_pawn_material() / 64) * (10 + pos.rule50_count()));
1064 v = Evaluation<NO_TRACE>(pos).value();
1068 int scale = 1064 + 106 * pos.non_pawn_material() / 5120;
1069 Value optimism = pos.this_thread()->optimism[stm];
1071 Value nnue = NNUE::evaluate(pos, true, &nnueComplexity);
1072 // Blend nnue complexity with (semi)classical complexity
1073 nnueComplexity = (104 * nnueComplexity + 131 * abs(nnue - psq)) / 256;
1074 if (complexity) // Return hybrid NNUE complexity to caller
1075 *complexity = nnueComplexity;
1077 optimism = optimism * (269 + nnueComplexity) / 256;
1078 v = (nnue * scale + optimism * (scale - 754)) / 1024;
1081 // Damp down the evaluation linearly when shuffling
1082 v = v * (195 - pos.rule50_count()) / 211;
1084 // Guarantee evaluation does not hit the tablebase range
1085 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1087 // When not using NNUE, return classical complexity to caller
1088 if (complexity && (!useNNUE || useClassical))
1089 *complexity = abs(v - psq);
1094 /// trace() is like evaluate(), but instead of returning a value, it returns
1095 /// a string (suitable for outputting to stdout) that contains the detailed
1096 /// descriptions and values of each evaluation term. Useful for debugging.
1097 /// Trace scores are from white's point of view
1099 std::string Eval::trace(Position& pos) {
1102 return "Final evaluation: none (in check)";
1104 std::stringstream ss;
1105 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1109 std::memset(scores, 0, sizeof(scores));
1111 // Reset any global variable used in eval
1112 pos.this_thread()->trend = SCORE_ZERO;
1113 pos.this_thread()->bestValue = VALUE_ZERO;
1114 pos.this_thread()->optimism[WHITE] = VALUE_ZERO;
1115 pos.this_thread()->optimism[BLACK] = VALUE_ZERO;
1117 v = Evaluation<TRACE>(pos).value();
1119 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1120 << " Contributing terms for the classical eval:\n"
1121 << "+------------+-------------+-------------+-------------+\n"
1122 << "| Term | White | Black | Total |\n"
1123 << "| | MG EG | MG EG | MG EG |\n"
1124 << "+------------+-------------+-------------+-------------+\n"
1125 << "| Material | " << Term(MATERIAL)
1126 << "| Imbalance | " << Term(IMBALANCE)
1127 << "| Pawns | " << Term(PAWN)
1128 << "| Knights | " << Term(KNIGHT)
1129 << "| Bishops | " << Term(BISHOP)
1130 << "| Rooks | " << Term(ROOK)
1131 << "| Queens | " << Term(QUEEN)
1132 << "| Mobility | " << Term(MOBILITY)
1133 << "|King safety | " << Term(KING)
1134 << "| Threats | " << Term(THREAT)
1135 << "| Passed | " << Term(PASSED)
1136 << "| Space | " << Term(SPACE)
1137 << "| Winnable | " << Term(WINNABLE)
1138 << "+------------+-------------+-------------+-------------+\n"
1139 << "| Total | " << Term(TOTAL)
1140 << "+------------+-------------+-------------+-------------+\n";
1143 ss << '\n' << NNUE::trace(pos) << '\n';
1145 ss << std::showpoint << std::showpos << std::fixed << std::setprecision(2) << std::setw(15);
1147 v = pos.side_to_move() == WHITE ? v : -v;
1148 ss << "\nClassical evaluation " << to_cp(v) << " (white side)\n";
1151 v = NNUE::evaluate(pos, false);
1152 v = pos.side_to_move() == WHITE ? v : -v;
1153 ss << "NNUE evaluation " << to_cp(v) << " (white side)\n";
1157 v = pos.side_to_move() == WHITE ? v : -v;
1158 ss << "Final evaluation " << to_cp(v) << " (white side)";
1160 ss << " [with scaled NNUE, hybrid, ...]";
1166 } // namespace Stockfish