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;
196 // Threshold for lazy and space evaluation
197 constexpr Value LazyThreshold1 = Value(3631);
198 constexpr Value LazyThreshold2 = Value(2084);
199 constexpr Value SpaceThreshold = Value(11551);
201 // KingAttackWeights[PieceType] contains king attack weights by piece type
202 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 76, 46, 45, 14 };
204 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
205 // higher if multiple safe checks are possible for that piece type.
206 constexpr int SafeCheck[][2] = {
207 {}, {}, {805, 1292}, {650, 984}, {1071, 1886}, {730, 1128}
210 #define S(mg, eg) make_score(mg, eg)
212 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
213 // indexed by piece type and number of attacked squares in the mobility area.
214 constexpr Score MobilityBonus[][32] = {
215 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
216 S( 21, 16), S( 28, 21), S( 37, 26) },
217 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
218 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
219 S( 91, 88), S( 96, 98) },
220 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
221 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
222 S( 57,165), S( 58,170), S( 67,175) },
223 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
224 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
225 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
226 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
227 S(112,178), S(114,185), S(114,187), S(119,221) }
230 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
231 // squares of the same color as our bishop.
232 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
233 S(3, 8), S(3, 9), S(2, 7), S(3, 7)
236 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
237 constexpr Score KingProtector[] = { S(9, 9), S(7, 9) };
239 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
240 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
241 constexpr Score Outpost[] = { S(54, 34), S(31, 25) };
243 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
244 constexpr Score PassedRank[RANK_NB] = {
245 S(0, 0), S(2, 38), S(15, 36), S(22, 50), S(64, 81), S(166, 184), S(284, 269)
248 constexpr Score RookOnClosedFile = S(10, 5);
249 constexpr Score RookOnOpenFile[] = { S(18, 8), S(49, 26) };
251 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
252 // which piece type attacks which one. Attacks on lesser pieces which are
253 // pawn-defended are not considered.
254 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
255 S(0, 0), S(6, 37), S(64, 50), S(82, 57), S(103, 130), S(81, 163)
258 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
259 S(0, 0), S(3, 44), S(36, 71), S(44, 59), S(0, 39), S(60, 39)
262 constexpr Value CorneredBishop = Value(50);
264 // Assorted bonuses and penalties
265 constexpr Score UncontestedOutpost = S( 0, 10);
266 constexpr Score BishopOnKingRing = S( 24, 0);
267 constexpr Score BishopXRayPawns = S( 4, 5);
268 constexpr Score FlankAttacks = S( 8, 0);
269 constexpr Score Hanging = S( 72, 40);
270 constexpr Score KnightOnQueen = S( 16, 11);
271 constexpr Score LongDiagonalBishop = S( 45, 0);
272 constexpr Score MinorBehindPawn = S( 18, 3);
273 constexpr Score PassedFile = S( 13, 8);
274 constexpr Score PawnlessFlank = S( 19, 97);
275 constexpr Score ReachableOutpost = S( 33, 19);
276 constexpr Score RestrictedPiece = S( 6, 7);
277 constexpr Score RookOnKingRing = S( 16, 0);
278 constexpr Score SliderOnQueen = S( 62, 21);
279 constexpr Score ThreatByKing = S( 24, 87);
280 constexpr Score ThreatByPawnPush = S( 48, 39);
281 constexpr Score ThreatBySafePawn = S(167, 99);
282 constexpr Score TrappedRook = S( 55, 13);
283 constexpr Score WeakQueenProtection = S( 14, 0);
284 constexpr Score WeakQueen = S( 57, 19);
289 // Evaluation class computes and stores attacks tables and other working data
294 Evaluation() = delete;
295 explicit Evaluation(const Position& p) : pos(p) {}
296 Evaluation& operator=(const Evaluation&) = delete;
300 template<Color Us> void initialize();
301 template<Color Us, PieceType Pt> Score pieces();
302 template<Color Us> Score king() const;
303 template<Color Us> Score threats() const;
304 template<Color Us> Score passed() const;
305 template<Color Us> Score space() const;
306 Value winnable(Score score) const;
311 Bitboard mobilityArea[COLOR_NB];
312 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
314 // attackedBy[color][piece type] is a bitboard representing all squares
315 // attacked by a given color and piece type. Special "piece types" which
316 // is also calculated is ALL_PIECES.
317 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
319 // attackedBy2[color] are the squares attacked by at least 2 units of a given
320 // color, including x-rays. But diagonal x-rays through pawns are not computed.
321 Bitboard attackedBy2[COLOR_NB];
323 // kingRing[color] are the squares adjacent to the king plus some other
324 // very near squares, depending on king position.
325 Bitboard kingRing[COLOR_NB];
327 // kingAttackersCount[color] is the number of pieces of the given color
328 // which attack a square in the kingRing of the enemy king.
329 int kingAttackersCount[COLOR_NB];
331 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
332 // the given color which attack a square in the kingRing of the enemy king.
333 // The weights of the individual piece types are given by the elements in
334 // the KingAttackWeights array.
335 int kingAttackersWeight[COLOR_NB];
337 // kingAttacksCount[color] is the number of attacks by the given color to
338 // squares directly adjacent to the enemy king. Pieces which attack more
339 // than one square are counted multiple times. For instance, if there is
340 // a white knight on g5 and black's king is on g8, this white knight adds 2
341 // to kingAttacksCount[WHITE].
342 int kingAttacksCount[COLOR_NB];
346 // Evaluation::initialize() computes king and pawn attacks, and the king ring
347 // bitboard for a given color. This is done at the beginning of the evaluation.
349 template<Tracing T> template<Color Us>
350 void Evaluation<T>::initialize() {
352 constexpr Color Them = ~Us;
353 constexpr Direction Up = pawn_push(Us);
354 constexpr Direction Down = -Up;
355 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
357 const Square ksq = pos.square<KING>(Us);
359 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
361 // Find our pawns that are blocked or on the first two ranks
362 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
364 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
365 // or controlled by enemy pawns are excluded from the mobility area.
366 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
368 // Initialize attackedBy[] for king and pawns
369 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
370 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
371 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
372 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
374 // Init our king safety tables
375 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
376 std::clamp(rank_of(ksq), RANK_2, RANK_7));
377 kingRing[Us] = attacks_bb<KING>(s) | s;
379 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
380 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
382 // Remove from kingRing[] the squares defended by two pawns
383 kingRing[Us] &= ~dblAttackByPawn;
387 // Evaluation::pieces() scores pieces of a given color and type
389 template<Tracing T> template<Color Us, PieceType Pt>
390 Score Evaluation<T>::pieces() {
392 constexpr Color Them = ~Us;
393 constexpr Direction Down = -pawn_push(Us);
394 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
395 : Rank5BB | Rank4BB | Rank3BB);
396 Bitboard b1 = pos.pieces(Us, Pt);
398 Score score = SCORE_ZERO;
400 attackedBy[Us][Pt] = 0;
404 Square s = pop_lsb(b1);
406 // Find attacked squares, including x-ray attacks for bishops and rooks
407 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
408 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
409 : attacks_bb<Pt>(s, pos.pieces());
411 if (pos.blockers_for_king(Us) & s)
412 b &= line_bb(pos.square<KING>(Us), s);
414 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
415 attackedBy[Us][Pt] |= b;
416 attackedBy[Us][ALL_PIECES] |= b;
418 if (b & kingRing[Them])
420 kingAttackersCount[Us]++;
421 kingAttackersWeight[Us] += KingAttackWeights[Pt];
422 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
425 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
426 score += RookOnKingRing;
428 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
429 score += BishopOnKingRing;
431 int mob = popcount(b & mobilityArea[Us]);
432 mobility[Us] += MobilityBonus[Pt - 2][mob];
434 if (Pt == BISHOP || Pt == KNIGHT)
436 // Bonus if the piece is on an outpost square or can reach one
437 // Bonus for knights (UncontestedOutpost) if few relevant targets
438 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
439 & ~pe->pawn_attacks_span(Them);
440 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
443 && bb & s & ~CenterFiles // on a side outpost
444 && !(b & targets) // no relevant attacks
445 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
446 score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
448 score += Outpost[Pt == BISHOP];
449 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
450 score += ReachableOutpost;
452 // Bonus for a knight or bishop shielded by pawn
453 if (shift<Down>(pos.pieces(PAWN)) & s)
454 score += MinorBehindPawn;
456 // Penalty if the piece is far from the king
457 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
459 if constexpr (Pt == BISHOP)
461 // Penalty according to the number of our pawns on the same color square as the
462 // bishop, bigger when the center files are blocked with pawns and smaller
463 // when the bishop is outside the pawn chain.
464 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
466 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
467 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
469 // Penalty for all enemy pawns x-rayed
470 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
472 // Bonus for bishop on a long diagonal which can "see" both center squares
473 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
474 score += LongDiagonalBishop;
476 // An important Chess960 pattern: a cornered bishop blocked by a friendly
477 // pawn diagonally in front of it is a very serious problem, especially
478 // when that pawn is also blocked.
479 if ( pos.is_chess960()
480 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
482 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
483 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
484 score -= !pos.empty(s + d + pawn_push(Us)) ? 4 * make_score(CorneredBishop, CorneredBishop)
485 : 3 * make_score(CorneredBishop, CorneredBishop);
490 if constexpr (Pt == ROOK)
492 // Bonuses for rook on a (semi-)open or closed file
493 if (pos.is_on_semiopen_file(Us, s))
495 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
499 // If our pawn on this file is blocked, increase penalty
500 if ( pos.pieces(Us, PAWN)
501 & shift<Down>(pos.pieces())
504 score -= RookOnClosedFile;
507 // Penalty when trapped by the king, even more if the king cannot castle
510 File kf = file_of(pos.square<KING>(Us));
511 if ((kf < FILE_E) == (file_of(s) < kf))
512 score -= TrappedRook * (1 + !pos.castling_rights(Us));
517 if constexpr (Pt == QUEEN)
519 // Penalty if any relative pin or discovered attack against the queen
520 Bitboard queenPinners;
521 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
526 Trace::add(Pt, Us, score);
532 // Evaluation::king() assigns bonuses and penalties to a king of a given color
534 template<Tracing T> template<Color Us>
535 Score Evaluation<T>::king() const {
537 constexpr Color Them = ~Us;
538 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
539 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
541 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
542 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
544 const Square ksq = pos.square<KING>(Us);
546 // Init the score with king shelter and enemy pawns storm
547 Score score = pe->king_safety<Us>(pos);
549 // Attacked squares defended at most once by our queen or king
550 weak = attackedBy[Them][ALL_PIECES]
552 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
554 // Analyse the safe enemy's checks which are possible on next move
555 safe = ~pos.pieces(Them);
556 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
558 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
559 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
561 // Enemy rooks checks
562 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
564 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
566 unsafeChecks |= b1 & attackedBy[Them][ROOK];
568 // Enemy queen safe checks: count them only if the checks are from squares from
569 // which opponent cannot give a rook check, because rook checks are more valuable.
570 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
571 & ~(attackedBy[Us][QUEEN] | rookChecks);
573 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
575 // Enemy bishops checks: count them only if they are from squares from which
576 // opponent cannot give a queen check, because queen checks are more valuable.
577 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
580 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
583 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
585 // Enemy knights checks
586 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
587 if (knightChecks & safe)
588 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
590 unsafeChecks |= knightChecks;
592 // Find the squares that opponent attacks in our king flank, the squares
593 // which they attack twice in that flank, and the squares that we defend.
594 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
595 b2 = b1 & attackedBy2[Them];
596 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
598 int kingFlankAttack = popcount(b1) + popcount(b2);
599 int kingFlankDefense = popcount(b3);
601 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
602 + 183 * popcount(kingRing[Us] & weak) // (~15 Elo)
603 + 148 * popcount(unsafeChecks) // (~4 Elo)
604 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
605 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
606 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
607 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
608 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
609 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
610 - 6 * mg_value(score) / 8 // (~8 Elo)
611 - 4 * kingFlankDefense // (~5 Elo)
614 // Transform the kingDanger units into a Score, and subtract it from the evaluation
615 if (kingDanger > 100)
616 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
618 // Penalty when our king is on a pawnless flank
619 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
620 score -= PawnlessFlank;
622 // Penalty if king flank is under attack, potentially moving toward the king
623 score -= FlankAttacks * kingFlankAttack;
626 Trace::add(KING, Us, score);
632 // Evaluation::threats() assigns bonuses according to the types of the
633 // attacking and the attacked pieces.
635 template<Tracing T> template<Color Us>
636 Score Evaluation<T>::threats() const {
638 constexpr Color Them = ~Us;
639 constexpr Direction Up = pawn_push(Us);
640 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
642 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
643 Score score = SCORE_ZERO;
646 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
648 // Squares strongly protected by the enemy, either because they defend the
649 // square with a pawn, or because they defend the square twice and we don't.
650 stronglyProtected = attackedBy[Them][PAWN]
651 | (attackedBy2[Them] & ~attackedBy2[Us]);
653 // Non-pawn enemies, strongly protected
654 defended = nonPawnEnemies & stronglyProtected;
656 // Enemies not strongly protected and under our attack
657 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
659 // Bonus according to the kind of attacking pieces
662 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
664 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(b)))];
666 b = weak & attackedBy[Us][ROOK];
668 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(b)))];
670 if (weak & attackedBy[Us][KING])
671 score += ThreatByKing;
673 b = ~attackedBy[Them][ALL_PIECES]
674 | (nonPawnEnemies & attackedBy2[Us]);
675 score += Hanging * popcount(weak & b);
677 // Additional bonus if weak piece is only protected by a queen
678 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
681 // Bonus for restricting their piece moves
682 b = attackedBy[Them][ALL_PIECES]
684 & attackedBy[Us][ALL_PIECES];
685 score += RestrictedPiece * popcount(b);
687 // Protected or unattacked squares
688 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
690 // Bonus for attacking enemy pieces with our relatively safe pawns
691 b = pos.pieces(Us, PAWN) & safe;
692 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
693 score += ThreatBySafePawn * popcount(b);
695 // Find squares where our pawns can push on the next move
696 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
697 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
699 // Keep only the squares which are relatively safe
700 b &= ~attackedBy[Them][PAWN] & safe;
702 // Bonus for safe pawn threats on the next move
703 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
704 score += ThreatByPawnPush * popcount(b);
706 // Bonus for threats on the next moves against enemy queen
707 if (pos.count<QUEEN>(Them) == 1)
709 bool queenImbalance = pos.count<QUEEN>() == 1;
711 Square s = pos.square<QUEEN>(Them);
712 safe = mobilityArea[Us]
713 & ~pos.pieces(Us, PAWN)
714 & ~stronglyProtected;
716 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
718 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
720 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
721 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
723 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
727 Trace::add(THREAT, Us, score);
732 // Evaluation::passed() evaluates the passed pawns and candidate passed
733 // pawns of the given color.
735 template<Tracing T> template<Color Us>
736 Score Evaluation<T>::passed() const {
738 constexpr Color Them = ~Us;
739 constexpr Direction Up = pawn_push(Us);
740 constexpr Direction Down = -Up;
742 auto king_proximity = [&](Color c, Square s) {
743 return std::min(distance(pos.square<KING>(c), s), 5);
746 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
747 Score score = SCORE_ZERO;
749 b = pe->passed_pawns(Us);
751 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
754 helpers = shift<Up>(pos.pieces(Us, PAWN))
756 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
758 // Remove blocked candidate passers that don't have help to pass
760 | shift<WEST>(helpers)
761 | shift<EAST>(helpers);
766 Square s = pop_lsb(b);
768 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
770 int r = relative_rank(Us, s);
772 Score bonus = PassedRank[r];
777 Square blockSq = s + Up;
779 // Adjust bonus based on the king's proximity
780 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
781 - king_proximity(Us, blockSq) * 2) * w);
783 // If blockSq is not the queening square then consider also a second push
785 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
787 // If the pawn is free to advance, then increase the bonus
788 if (pos.empty(blockSq))
790 squaresToQueen = forward_file_bb(Us, s);
791 unsafeSquares = passed_pawn_span(Us, s);
793 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
795 if (!(pos.pieces(Them) & bb))
796 unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
798 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
799 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
800 // Otherwise assign a smaller bonus if the path to queen is not attacked
801 // and even smaller bonus if it is attacked but block square is not.
802 int k = !unsafeSquares ? 36 :
803 !(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
804 !(unsafeSquares & squaresToQueen) ? 17 :
805 !(unsafeSquares & blockSq) ? 7 :
808 // Assign a larger bonus if the block square is defended
809 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
812 bonus += make_score(k * w, k * w);
816 score += bonus - PassedFile * edge_distance(file_of(s));
820 Trace::add(PASSED, Us, score);
826 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
827 // play in the opening. It is based on the number of safe squares on the four central files
828 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
829 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
831 template<Tracing T> template<Color Us>
832 Score Evaluation<T>::space() const {
834 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
835 if (pos.non_pawn_material() < SpaceThreshold)
838 constexpr Color Them = ~Us;
839 constexpr Direction Down = -pawn_push(Us);
840 constexpr Bitboard SpaceMask =
841 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
842 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
844 // Find the available squares for our pieces inside the area defined by SpaceMask
845 Bitboard safe = SpaceMask
846 & ~pos.pieces(Us, PAWN)
847 & ~attackedBy[Them][PAWN];
849 // Find all squares which are at most three squares behind some friendly pawn
850 Bitboard behind = pos.pieces(Us, PAWN);
851 behind |= shift<Down>(behind);
852 behind |= shift<Down+Down>(behind);
854 // Compute space score based on the number of safe squares and number of our pieces
855 // increased with number of total blocked pawns in position.
856 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
857 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
858 Score score = make_score(bonus * weight * weight / 16, 0);
861 Trace::add(SPACE, Us, score);
867 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
868 // the known attacking/defending status of the players. The final value is derived
869 // by interpolation from the midgame and endgame values.
872 Value Evaluation<T>::winnable(Score score) const {
874 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
875 + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
877 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
878 && (pos.pieces(PAWN) & KingSide);
880 bool almostUnwinnable = outflanking < 0
881 && !pawnsOnBothFlanks;
883 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
884 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
886 // Compute the initiative bonus for the attacking side
887 int complexity = 9 * pe->passed_count()
888 + 12 * pos.count<PAWN>()
890 + 21 * pawnsOnBothFlanks
892 + 51 * !pos.non_pawn_material()
893 - 43 * almostUnwinnable
896 Value mg = mg_value(score);
897 Value eg = eg_value(score);
899 // Now apply the bonus: note that we find the attacking side by extracting the
900 // sign of the midgame or endgame values, and that we carefully cap the bonus
901 // so that the midgame and endgame scores do not change sign after the bonus.
902 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
903 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
908 // Compute the scale factor for the winning side
909 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
910 int sf = me->scale_factor(pos, strongSide);
912 // If scale factor is not already specific, scale up/down via general heuristics
913 if (sf == SCALE_FACTOR_NORMAL)
915 if (pos.opposite_bishops())
917 // For pure opposite colored bishops endgames use scale factor
918 // based on the number of passed pawns of the strong side.
919 if ( pos.non_pawn_material(WHITE) == BishopValueMg
920 && pos.non_pawn_material(BLACK) == BishopValueMg)
921 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
922 // For every other opposite colored bishops endgames use scale factor
923 // based on the number of all pieces of the strong side.
925 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
927 // For rook endgames with strong side not having overwhelming pawn number advantage
928 // and its pawns being on one flank and weak side protecting its pieces with a king
929 // use lower scale factor.
930 else if ( pos.non_pawn_material(WHITE) == RookValueMg
931 && pos.non_pawn_material(BLACK) == RookValueMg
932 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
933 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
934 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
936 // For queen vs no queen endgames use scale factor
937 // based on number of minors of side that doesn't have queen.
938 else if (pos.count<QUEEN>() == 1)
939 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
940 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
941 // In every other case use scale factor based on
942 // the number of pawns of the strong side reduced if pawns are on a single flank.
944 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
946 // Reduce scale factor in case of pawns being on a single flank
947 sf -= 4 * !pawnsOnBothFlanks;
950 // Interpolate between the middlegame and (scaled by 'sf') endgame score
951 v = mg * int(me->game_phase())
952 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
957 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
958 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
965 // Evaluation::value() is the main function of the class. It computes the various
966 // parts of the evaluation and returns the value of the position from the point
967 // of view of the side to move.
970 Value Evaluation<T>::value() {
972 assert(!pos.checkers());
974 // Probe the material hash table
975 me = Material::probe(pos);
977 // If we have a specialized evaluation function for the current material
978 // configuration, call it and return.
979 if (me->specialized_eval_exists())
980 return me->evaluate(pos);
982 // Initialize score by reading the incrementally updated scores included in
983 // the position object (material + piece square tables) and the material
984 // imbalance. Score is computed internally from the white point of view.
985 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->trend;
987 // Probe the pawn hash table
988 pe = Pawns::probe(pos);
989 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
991 // Early exit if score is high
992 auto lazy_skip = [&](Value lazyThreshold) {
993 return abs(mg_value(score) + eg_value(score)) > lazyThreshold
994 + std::abs(pos.this_thread()->bestValue) * 5 / 4
995 + pos.non_pawn_material() / 32;
998 if (lazy_skip(LazyThreshold1))
1001 // Main evaluation begins here
1002 initialize<WHITE>();
1003 initialize<BLACK>();
1005 // Pieces evaluated first (also populates attackedBy, attackedBy2).
1006 // Note that the order of evaluation of the terms is left unspecified.
1007 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
1008 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
1009 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
1010 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
1012 score += mobility[WHITE] - mobility[BLACK];
1014 // More complex interactions that require fully populated attack bitboards
1015 score += king< WHITE>() - king< BLACK>()
1016 + passed< WHITE>() - passed< BLACK>();
1018 if (lazy_skip(LazyThreshold2))
1021 score += threats<WHITE>() - threats<BLACK>()
1022 + space< WHITE>() - space< BLACK>();
1025 // Derive single value from mg and eg parts of score
1026 Value v = winnable(score);
1028 // In case of tracing add all remaining individual evaluation terms
1031 Trace::add(MATERIAL, pos.psq_score());
1032 Trace::add(IMBALANCE, me->imbalance());
1033 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1034 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1040 // Side to move point of view
1041 v = (pos.side_to_move() == WHITE ? v : -v);
1047 /// Fisher Random Chess: correction for cornered bishops, to fix chess960 play with NNUE
1049 Value fix_FRC(const Position& pos) {
1051 constexpr Bitboard Corners = 1ULL << SQ_A1 | 1ULL << SQ_H1 | 1ULL << SQ_A8 | 1ULL << SQ_H8;
1053 if (!(pos.pieces(BISHOP) & Corners))
1058 if ( pos.piece_on(SQ_A1) == W_BISHOP
1059 && pos.piece_on(SQ_B2) == W_PAWN)
1060 correction -= CorneredBishop;
1062 if ( pos.piece_on(SQ_H1) == W_BISHOP
1063 && pos.piece_on(SQ_G2) == W_PAWN)
1064 correction -= CorneredBishop;
1066 if ( pos.piece_on(SQ_A8) == B_BISHOP
1067 && pos.piece_on(SQ_B7) == B_PAWN)
1068 correction += CorneredBishop;
1070 if ( pos.piece_on(SQ_H8) == B_BISHOP
1071 && pos.piece_on(SQ_G7) == B_PAWN)
1072 correction += CorneredBishop;
1074 return pos.side_to_move() == WHITE ? Value(3 * correction)
1075 : -Value(3 * correction);
1081 /// evaluate() is the evaluator for the outer world. It returns a static
1082 /// evaluation of the position from the point of view of the side to move.
1084 Value Eval::evaluate(const Position& pos) {
1087 bool useClassical = false;
1089 // Deciding between classical and NNUE eval (~10 Elo): for high PSQ imbalance we use classical,
1090 // but we switch to NNUE during long shuffling or with high material on the board.
1092 || ((pos.this_thread()->depth > 9 || pos.count<ALL_PIECES>() > 7) &&
1093 abs(eg_value(pos.psq_score())) * 5 > (856 + pos.non_pawn_material() / 64) * (10 + pos.rule50_count())))
1095 v = Evaluation<NO_TRACE>(pos).value(); // classical
1096 useClassical = abs(v) >= 297;
1099 // If result of a classical evaluation is much lower than threshold fall back to NNUE
1100 if (useNNUE && !useClassical)
1102 Value nnue = NNUE::evaluate(pos, true); // NNUE
1103 int scale = 1014 + 21 * pos.non_pawn_material() / 1024;
1104 Color stm = pos.side_to_move();
1105 Value optimism = pos.this_thread()->optimism[stm];
1106 Value psq = (stm == WHITE ? 1 : -1) * eg_value(pos.psq_score());
1107 int complexity = 35 * abs(nnue - psq) / 256;
1109 optimism = optimism * (32 + complexity) / 32;
1110 v = (nnue * scale + optimism * (scale - 846)) / 1024;
1112 if (pos.is_chess960())
1116 // Damp down the evaluation linearly when shuffling
1117 v = v * (195 - pos.rule50_count()) / 211;
1119 // Guarantee evaluation does not hit the tablebase range
1120 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1125 /// trace() is like evaluate(), but instead of returning a value, it returns
1126 /// a string (suitable for outputting to stdout) that contains the detailed
1127 /// descriptions and values of each evaluation term. Useful for debugging.
1128 /// Trace scores are from white's point of view
1130 std::string Eval::trace(Position& pos) {
1133 return "Final evaluation: none (in check)";
1135 std::stringstream ss;
1136 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1140 std::memset(scores, 0, sizeof(scores));
1142 // Reset any global variable used in eval
1143 pos.this_thread()->depth = 0;
1144 pos.this_thread()->trend = SCORE_ZERO;
1145 pos.this_thread()->bestValue = VALUE_ZERO;
1146 pos.this_thread()->optimism[WHITE] = VALUE_ZERO;
1147 pos.this_thread()->optimism[BLACK] = VALUE_ZERO;
1149 v = Evaluation<TRACE>(pos).value();
1151 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1152 << " Contributing terms for the classical eval:\n"
1153 << "+------------+-------------+-------------+-------------+\n"
1154 << "| Term | White | Black | Total |\n"
1155 << "| | MG EG | MG EG | MG EG |\n"
1156 << "+------------+-------------+-------------+-------------+\n"
1157 << "| Material | " << Term(MATERIAL)
1158 << "| Imbalance | " << Term(IMBALANCE)
1159 << "| Pawns | " << Term(PAWN)
1160 << "| Knights | " << Term(KNIGHT)
1161 << "| Bishops | " << Term(BISHOP)
1162 << "| Rooks | " << Term(ROOK)
1163 << "| Queens | " << Term(QUEEN)
1164 << "| Mobility | " << Term(MOBILITY)
1165 << "|King safety | " << Term(KING)
1166 << "| Threats | " << Term(THREAT)
1167 << "| Passed | " << Term(PASSED)
1168 << "| Space | " << Term(SPACE)
1169 << "| Winnable | " << Term(WINNABLE)
1170 << "+------------+-------------+-------------+-------------+\n"
1171 << "| Total | " << Term(TOTAL)
1172 << "+------------+-------------+-------------+-------------+\n";
1175 ss << '\n' << NNUE::trace(pos) << '\n';
1177 ss << std::showpoint << std::showpos << std::fixed << std::setprecision(2) << std::setw(15);
1179 v = pos.side_to_move() == WHITE ? v : -v;
1180 ss << "\nClassical evaluation " << to_cp(v) << " (white side)\n";
1183 v = NNUE::evaluate(pos, false);
1184 v = pos.side_to_move() == WHITE ? v : -v;
1185 ss << "NNUE evaluation " << to_cp(v) << " (white side)\n";
1189 v = pos.side_to_move() == WHITE ? v : -v;
1190 ss << "Final evaluation " << to_cp(v) << " (white side)";
1192 ss << " [with scaled NNUE, hybrid, ...]";
1198 } // namespace Stockfish