2 Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3 Copyright (C) 2004-2023 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"
39 #include "nnue/evaluate_nnue.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 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) };
87 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory };
90 for (const string& directory : dirs)
91 if (currentEvalFileName != eval_file)
93 if (directory != "<internal>")
95 ifstream stream(directory + eval_file, ios::binary);
96 if (NNUE::load_eval(eval_file, stream))
97 currentEvalFileName = eval_file;
100 if (directory == "<internal>" && eval_file == EvalFileDefaultName)
102 // C++ way to prepare a buffer for a memory stream
103 class MemoryBuffer : public basic_streambuf<char> {
104 public: MemoryBuffer(char* p, size_t n) { setg(p, p, p + n); setp(p, p + n); }
107 MemoryBuffer buffer(const_cast<char*>(reinterpret_cast<const char*>(gEmbeddedNNUEData)),
108 size_t(gEmbeddedNNUESize));
109 (void) gEmbeddedNNUEEnd; // Silence warning on unused variable
111 istream stream(&buffer);
112 if (NNUE::load_eval(eval_file, stream))
113 currentEvalFileName = eval_file;
118 /// NNUE::verify() verifies that the last net used was loaded successfully
119 void NNUE::verify() {
121 string eval_file = string(Options["EvalFile"]);
122 if (eval_file.empty())
123 eval_file = EvalFileDefaultName;
125 if (useNNUE && currentEvalFileName != eval_file)
128 string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
129 string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
130 string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
131 string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + std::string(EvalFileDefaultName);
132 string msg5 = "The engine will be terminated now.";
134 sync_cout << "info string ERROR: " << msg1 << sync_endl;
135 sync_cout << "info string ERROR: " << msg2 << sync_endl;
136 sync_cout << "info string ERROR: " << msg3 << sync_endl;
137 sync_cout << "info string ERROR: " << msg4 << sync_endl;
138 sync_cout << "info string ERROR: " << msg5 << sync_endl;
144 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
146 sync_cout << "info string classical evaluation enabled" << sync_endl;
152 enum Tracing { NO_TRACE, TRACE };
154 enum Term { // The first 8 entries are reserved for PieceType
155 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
158 Score scores[TERM_NB][COLOR_NB];
160 static double to_cp(Value v) { return double(v) / UCI::NormalizeToPawnValue; }
162 static void add(int idx, Color c, Score s) {
166 static void add(int idx, Score w, Score b = SCORE_ZERO) {
167 scores[idx][WHITE] = w;
168 scores[idx][BLACK] = b;
171 static std::ostream& operator<<(std::ostream& os, Score s) {
172 os << std::setw(5) << to_cp(mg_value(s)) << " "
173 << std::setw(5) << to_cp(eg_value(s));
177 static std::ostream& operator<<(std::ostream& os, Term t) {
179 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
180 os << " ---- ----" << " | " << " ---- ----";
182 os << scores[t][WHITE] << " | " << scores[t][BLACK];
184 os << " | " << scores[t][WHITE] - scores[t][BLACK] << " |\n";
189 using namespace Trace;
193 // Threshold for lazy and space evaluation
194 constexpr Value LazyThreshold1 = Value(3622);
195 constexpr Value LazyThreshold2 = Value(1962);
196 constexpr Value SpaceThreshold = Value(11551);
198 // KingAttackWeights[PieceType] contains king attack weights by piece type
199 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 76, 46, 45, 14 };
201 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
202 // higher if multiple safe checks are possible for that piece type.
203 constexpr int SafeCheck[][2] = {
204 {}, {}, {805, 1292}, {650, 984}, {1071, 1886}, {730, 1128}
207 #define S(mg, eg) make_score(mg, eg)
209 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
210 // indexed by piece type and number of attacked squares in the mobility area.
211 constexpr Score MobilityBonus[][32] = {
212 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
213 S( 21, 16), S( 28, 21), S( 37, 26) },
214 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
215 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
216 S( 91, 88), S( 96, 98) },
217 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
218 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
219 S( 57,165), S( 58,170), S( 67,175) },
220 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
221 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
222 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
223 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
224 S(112,178), S(114,185), S(114,187), S(119,221) }
227 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
228 // squares of the same color as our bishop.
229 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
230 S(3, 8), S(3, 9), S(2, 7), S(3, 7)
233 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
234 constexpr Score KingProtector[] = { S(9, 9), S(7, 9) };
236 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
237 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
238 constexpr Score Outpost[] = { S(54, 34), S(31, 25) };
240 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
241 constexpr Score PassedRank[RANK_NB] = {
242 S(0, 0), S(2, 38), S(15, 36), S(22, 50), S(64, 81), S(166, 184), S(284, 269)
245 constexpr Score RookOnClosedFile = S(10, 5);
246 constexpr Score RookOnOpenFile[] = { S(18, 8), S(49, 26) };
248 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
249 // which piece type attacks which one. Attacks on lesser pieces which are
250 // pawn-defended are not considered.
251 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
252 S(0, 0), S(6, 37), S(64, 50), S(82, 57), S(103, 130), S(81, 163)
255 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
256 S(0, 0), S(3, 44), S(36, 71), S(44, 59), S(0, 39), S(60, 39)
259 constexpr Value CorneredBishop = Value(50);
261 // Assorted bonuses and penalties
262 constexpr Score UncontestedOutpost = S( 0, 10);
263 constexpr Score BishopOnKingRing = S( 24, 0);
264 constexpr Score BishopXRayPawns = S( 4, 5);
265 constexpr Score FlankAttacks = S( 8, 0);
266 constexpr Score Hanging = S( 72, 40);
267 constexpr Score KnightOnQueen = S( 16, 11);
268 constexpr Score LongDiagonalBishop = S( 45, 0);
269 constexpr Score MinorBehindPawn = S( 18, 3);
270 constexpr Score PassedFile = S( 13, 8);
271 constexpr Score PawnlessFlank = S( 19, 97);
272 constexpr Score ReachableOutpost = S( 33, 19);
273 constexpr Score RestrictedPiece = S( 6, 7);
274 constexpr Score RookOnKingRing = S( 16, 0);
275 constexpr Score SliderOnQueen = S( 62, 21);
276 constexpr Score ThreatByKing = S( 24, 87);
277 constexpr Score ThreatByPawnPush = S( 48, 39);
278 constexpr Score ThreatBySafePawn = S(167, 99);
279 constexpr Score TrappedRook = S( 55, 13);
280 constexpr Score WeakQueenProtection = S( 14, 0);
281 constexpr Score WeakQueen = S( 57, 19);
286 // Evaluation class computes and stores attacks tables and other working data
291 Evaluation() = delete;
292 explicit Evaluation(const Position& p) : pos(p) {}
293 Evaluation& operator=(const Evaluation&) = delete;
297 template<Color Us> void initialize();
298 template<Color Us, PieceType Pt> Score pieces();
299 template<Color Us> Score king() const;
300 template<Color Us> Score threats() const;
301 template<Color Us> Score passed() const;
302 template<Color Us> Score space() const;
303 Value winnable(Score score) const;
308 Bitboard mobilityArea[COLOR_NB];
309 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
311 // attackedBy[color][piece type] is a bitboard representing all squares
312 // attacked by a given color and piece type. Special "piece types" which
313 // is also calculated is ALL_PIECES.
314 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
316 // attackedBy2[color] are the squares attacked by at least 2 units of a given
317 // color, including x-rays. But diagonal x-rays through pawns are not computed.
318 Bitboard attackedBy2[COLOR_NB];
320 // kingRing[color] are the squares adjacent to the king plus some other
321 // very near squares, depending on king position.
322 Bitboard kingRing[COLOR_NB];
324 // kingAttackersCount[color] is the number of pieces of the given color
325 // which attack a square in the kingRing of the enemy king.
326 int kingAttackersCount[COLOR_NB];
328 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
329 // the given color which attack a square in the kingRing of the enemy king.
330 // The weights of the individual piece types are given by the elements in
331 // the KingAttackWeights array.
332 int kingAttackersWeight[COLOR_NB];
334 // kingAttacksCount[color] is the number of attacks by the given color to
335 // squares directly adjacent to the enemy king. Pieces which attack more
336 // than one square are counted multiple times. For instance, if there is
337 // a white knight on g5 and black's king is on g8, this white knight adds 2
338 // to kingAttacksCount[WHITE].
339 int kingAttacksCount[COLOR_NB];
343 // Evaluation::initialize() computes king and pawn attacks, and the king ring
344 // bitboard for a given color. This is done at the beginning of the evaluation.
346 template<Tracing T> template<Color Us>
347 void Evaluation<T>::initialize() {
349 constexpr Color Them = ~Us;
350 constexpr Direction Up = pawn_push(Us);
351 constexpr Direction Down = -Up;
352 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
354 const Square ksq = pos.square<KING>(Us);
356 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
358 // Find our pawns that are blocked or on the first two ranks
359 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
361 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
362 // or controlled by enemy pawns are excluded from the mobility area.
363 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
365 // Initialize attackedBy[] for king and pawns
366 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
367 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
368 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
369 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
371 // Init our king safety tables
372 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
373 std::clamp(rank_of(ksq), RANK_2, RANK_7));
374 kingRing[Us] = attacks_bb<KING>(s) | s;
376 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
377 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
379 // Remove from kingRing[] the squares defended by two pawns
380 kingRing[Us] &= ~dblAttackByPawn;
384 // Evaluation::pieces() scores pieces of a given color and type
386 template<Tracing T> template<Color Us, PieceType Pt>
387 Score Evaluation<T>::pieces() {
389 constexpr Color Them = ~Us;
390 [[maybe_unused]] constexpr Direction Down = -pawn_push(Us);
391 [[maybe_unused]] constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
392 : Rank5BB | Rank4BB | Rank3BB);
393 Bitboard b1 = pos.pieces(Us, Pt);
395 Score score = SCORE_ZERO;
397 attackedBy[Us][Pt] = 0;
401 Square s = pop_lsb(b1);
403 // Find attacked squares, including x-ray attacks for bishops and rooks
404 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
405 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
406 : attacks_bb<Pt>(s, pos.pieces());
408 if (pos.blockers_for_king(Us) & s)
409 b &= line_bb(pos.square<KING>(Us), s);
411 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
412 attackedBy[Us][Pt] |= b;
413 attackedBy[Us][ALL_PIECES] |= b;
415 if (b & kingRing[Them])
417 kingAttackersCount[Us]++;
418 kingAttackersWeight[Us] += KingAttackWeights[Pt];
419 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
422 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
423 score += RookOnKingRing;
425 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
426 score += BishopOnKingRing;
428 int mob = popcount(b & mobilityArea[Us]);
429 mobility[Us] += MobilityBonus[Pt - 2][mob];
431 if constexpr (Pt == BISHOP || Pt == KNIGHT)
433 // Bonus if the piece is on an outpost square or can reach one
434 // Bonus for knights (UncontestedOutpost) if few relevant targets
435 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
436 & ~pe->pawn_attacks_span(Them);
437 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
440 && bb & s & ~CenterFiles // on a side outpost
441 && !(b & targets) // no relevant attacks
442 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
443 score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
445 score += Outpost[Pt == BISHOP];
446 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
447 score += ReachableOutpost;
449 // Bonus for a knight or bishop shielded by pawn
450 if (shift<Down>(pos.pieces(PAWN)) & s)
451 score += MinorBehindPawn;
453 // Penalty if the piece is far from the king
454 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
456 if constexpr (Pt == BISHOP)
458 // Penalty according to the number of our pawns on the same color square as the
459 // bishop, bigger when the center files are blocked with pawns and smaller
460 // when the bishop is outside the pawn chain.
461 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
463 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
464 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
466 // Penalty for all enemy pawns x-rayed
467 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
469 // Bonus for bishop on a long diagonal which can "see" both center squares
470 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
471 score += LongDiagonalBishop;
473 // An important Chess960 pattern: a cornered bishop blocked by a friendly
474 // pawn diagonally in front of it is a very serious problem, especially
475 // when that pawn is also blocked.
476 if ( pos.is_chess960()
477 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
479 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
480 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
481 score -= !pos.empty(s + d + pawn_push(Us)) ? 4 * make_score(CorneredBishop, CorneredBishop)
482 : 3 * make_score(CorneredBishop, CorneredBishop);
487 if constexpr (Pt == ROOK)
489 // Bonuses for rook on a (semi-)open or closed file
490 if (pos.is_on_semiopen_file(Us, s))
492 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
496 // If our pawn on this file is blocked, increase penalty
497 if ( pos.pieces(Us, PAWN)
498 & shift<Down>(pos.pieces())
501 score -= RookOnClosedFile;
504 // Penalty when trapped by the king, even more if the king cannot castle
507 File kf = file_of(pos.square<KING>(Us));
508 if ((kf < FILE_E) == (file_of(s) < kf))
509 score -= TrappedRook * (1 + !pos.castling_rights(Us));
514 if constexpr (Pt == QUEEN)
516 // Penalty if any relative pin or discovered attack against the queen
517 Bitboard queenPinners;
518 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
523 Trace::add(Pt, Us, score);
529 // Evaluation::king() assigns bonuses and penalties to a king of a given color
531 template<Tracing T> template<Color Us>
532 Score Evaluation<T>::king() const {
534 constexpr Color Them = ~Us;
535 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
536 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
538 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
539 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
541 const Square ksq = pos.square<KING>(Us);
543 // Init the score with king shelter and enemy pawns storm
544 Score score = pe->king_safety<Us>(pos);
546 // Attacked squares defended at most once by our queen or king
547 weak = attackedBy[Them][ALL_PIECES]
549 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
551 // Analyse the safe enemy's checks which are possible on next move
552 safe = ~pos.pieces(Them);
553 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
555 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
556 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
558 // Enemy rooks checks
559 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
561 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
563 unsafeChecks |= b1 & attackedBy[Them][ROOK];
565 // Enemy queen safe checks: count them only if the checks are from squares from
566 // which opponent cannot give a rook check, because rook checks are more valuable.
567 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
568 & ~(attackedBy[Us][QUEEN] | rookChecks);
570 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
572 // Enemy bishops checks: count them only if they are from squares from which
573 // opponent cannot give a queen check, because queen checks are more valuable.
574 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
577 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
580 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
582 // Enemy knights checks
583 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
584 if (knightChecks & safe)
585 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
587 unsafeChecks |= knightChecks;
589 // Find the squares that opponent attacks in our king flank, the squares
590 // which they attack twice in that flank, and the squares that we defend.
591 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
592 b2 = b1 & attackedBy2[Them];
593 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
595 int kingFlankAttack = popcount(b1) + popcount(b2);
596 int kingFlankDefense = popcount(b3);
598 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
599 + 183 * popcount(kingRing[Us] & weak) // (~15 Elo)
600 + 148 * popcount(unsafeChecks) // (~4 Elo)
601 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
602 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
603 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
604 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
605 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
606 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
607 - 6 * mg_value(score) / 8 // (~8 Elo)
608 - 4 * kingFlankDefense // (~5 Elo)
611 // Transform the kingDanger units into a Score, and subtract it from the evaluation
612 if (kingDanger > 100)
613 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
615 // Penalty when our king is on a pawnless flank
616 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
617 score -= PawnlessFlank;
619 // Penalty if king flank is under attack, potentially moving toward the king
620 score -= FlankAttacks * kingFlankAttack;
623 Trace::add(KING, Us, score);
629 // Evaluation::threats() assigns bonuses according to the types of the
630 // attacking and the attacked pieces.
632 template<Tracing T> template<Color Us>
633 Score Evaluation<T>::threats() const {
635 constexpr Color Them = ~Us;
636 constexpr Direction Up = pawn_push(Us);
637 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
639 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
640 Score score = SCORE_ZERO;
643 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
645 // Squares strongly protected by the enemy, either because they defend the
646 // square with a pawn, or because they defend the square twice and we don't.
647 stronglyProtected = attackedBy[Them][PAWN]
648 | (attackedBy2[Them] & ~attackedBy2[Us]);
650 // Non-pawn enemies, strongly protected
651 defended = nonPawnEnemies & stronglyProtected;
653 // Enemies not strongly protected and under our attack
654 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
656 // Bonus according to the kind of attacking pieces
659 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
661 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(b)))];
663 b = weak & attackedBy[Us][ROOK];
665 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(b)))];
667 if (weak & attackedBy[Us][KING])
668 score += ThreatByKing;
670 b = ~attackedBy[Them][ALL_PIECES]
671 | (nonPawnEnemies & attackedBy2[Us]);
672 score += Hanging * popcount(weak & b);
674 // Additional bonus if weak piece is only protected by a queen
675 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
678 // Bonus for restricting their piece moves
679 b = attackedBy[Them][ALL_PIECES]
681 & attackedBy[Us][ALL_PIECES];
682 score += RestrictedPiece * popcount(b);
684 // Protected or unattacked squares
685 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
687 // Bonus for attacking enemy pieces with our relatively safe pawns
688 b = pos.pieces(Us, PAWN) & safe;
689 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
690 score += ThreatBySafePawn * popcount(b);
692 // Find squares where our pawns can push on the next move
693 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
694 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
696 // Keep only the squares which are relatively safe
697 b &= ~attackedBy[Them][PAWN] & safe;
699 // Bonus for safe pawn threats on the next move
700 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
701 score += ThreatByPawnPush * popcount(b);
703 // Bonus for threats on the next moves against enemy queen
704 if (pos.count<QUEEN>(Them) == 1)
706 bool queenImbalance = pos.count<QUEEN>() == 1;
708 Square s = pos.square<QUEEN>(Them);
709 safe = mobilityArea[Us]
710 & ~pos.pieces(Us, PAWN)
711 & ~stronglyProtected;
713 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
715 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
717 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
718 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
720 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
724 Trace::add(THREAT, Us, score);
729 // Evaluation::passed() evaluates the passed pawns and candidate passed
730 // pawns of the given color.
732 template<Tracing T> template<Color Us>
733 Score Evaluation<T>::passed() const {
735 constexpr Color Them = ~Us;
736 constexpr Direction Up = pawn_push(Us);
737 constexpr Direction Down = -Up;
739 auto king_proximity = [&](Color c, Square s) {
740 return std::min(distance(pos.square<KING>(c), s), 5);
743 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
744 Score score = SCORE_ZERO;
746 b = pe->passed_pawns(Us);
748 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
751 helpers = shift<Up>(pos.pieces(Us, PAWN))
753 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
755 // Remove blocked candidate passers that don't have help to pass
757 | shift<WEST>(helpers)
758 | shift<EAST>(helpers);
763 Square s = pop_lsb(b);
765 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
767 int r = relative_rank(Us, s);
769 Score bonus = PassedRank[r];
774 Square blockSq = s + Up;
776 // Adjust bonus based on the king's proximity
777 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
778 - king_proximity(Us, blockSq) * 2) * w);
780 // If blockSq is not the queening square then consider also a second push
782 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
784 // If the pawn is free to advance, then increase the bonus
785 if (pos.empty(blockSq))
787 squaresToQueen = forward_file_bb(Us, s);
788 unsafeSquares = passed_pawn_span(Us, s);
790 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
792 if (!(pos.pieces(Them) & bb))
793 unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
795 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
796 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
797 // Otherwise assign a smaller bonus if the path to queen is not attacked
798 // and even smaller bonus if it is attacked but block square is not.
799 int k = !unsafeSquares ? 36 :
800 !(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
801 !(unsafeSquares & squaresToQueen) ? 17 :
802 !(unsafeSquares & blockSq) ? 7 :
805 // Assign a larger bonus if the block square is defended
806 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
809 bonus += make_score(k * w, k * w);
813 score += bonus - PassedFile * edge_distance(file_of(s));
817 Trace::add(PASSED, Us, score);
823 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
824 // play in the opening. It is based on the number of safe squares on the four central files
825 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
826 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
828 template<Tracing T> template<Color Us>
829 Score Evaluation<T>::space() const {
831 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
832 if (pos.non_pawn_material() < SpaceThreshold)
835 constexpr Color Them = ~Us;
836 constexpr Direction Down = -pawn_push(Us);
837 constexpr Bitboard SpaceMask =
838 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
839 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
841 // Find the available squares for our pieces inside the area defined by SpaceMask
842 Bitboard safe = SpaceMask
843 & ~pos.pieces(Us, PAWN)
844 & ~attackedBy[Them][PAWN];
846 // Find all squares which are at most three squares behind some friendly pawn
847 Bitboard behind = pos.pieces(Us, PAWN);
848 behind |= shift<Down>(behind);
849 behind |= shift<Down+Down>(behind);
851 // Compute space score based on the number of safe squares and number of our pieces
852 // increased with number of total blocked pawns in position.
853 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
854 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
855 Score score = make_score(bonus * weight * weight / 16, 0);
858 Trace::add(SPACE, Us, score);
864 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
865 // the known attacking/defending status of the players. The final value is derived
866 // by interpolation from the midgame and endgame values.
869 Value Evaluation<T>::winnable(Score score) const {
871 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
872 + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
874 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
875 && (pos.pieces(PAWN) & KingSide);
877 bool almostUnwinnable = outflanking < 0
878 && !pawnsOnBothFlanks;
880 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
881 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
883 // Compute the initiative bonus for the attacking side
884 int complexity = 9 * pe->passed_count()
885 + 12 * pos.count<PAWN>()
887 + 21 * pawnsOnBothFlanks
889 + 51 * !pos.non_pawn_material()
890 - 43 * almostUnwinnable
893 Value mg = mg_value(score);
894 Value eg = eg_value(score);
896 // Now apply the bonus: note that we find the attacking side by extracting the
897 // sign of the midgame or endgame values, and that we carefully cap the bonus
898 // so that the midgame and endgame scores do not change sign after the bonus.
899 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
900 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
905 // Compute the scale factor for the winning side
906 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
907 int sf = me->scale_factor(pos, strongSide);
909 // If scale factor is not already specific, scale up/down via general heuristics
910 if (sf == SCALE_FACTOR_NORMAL)
912 if (pos.opposite_bishops())
914 // For pure opposite colored bishops endgames use scale factor
915 // based on the number of passed pawns of the strong side.
916 if ( pos.non_pawn_material(WHITE) == BishopValueMg
917 && pos.non_pawn_material(BLACK) == BishopValueMg)
918 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
919 // For every other opposite colored bishops endgames use scale factor
920 // based on the number of all pieces of the strong side.
922 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
924 // For rook endgames with strong side not having overwhelming pawn number advantage
925 // and its pawns being on one flank and weak side protecting its pieces with a king
926 // use lower scale factor.
927 else if ( pos.non_pawn_material(WHITE) == RookValueMg
928 && pos.non_pawn_material(BLACK) == RookValueMg
929 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
930 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
931 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
933 // For queen vs no queen endgames use scale factor
934 // based on number of minors of side that doesn't have queen.
935 else if (pos.count<QUEEN>() == 1)
936 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
937 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
938 // In every other case use scale factor based on
939 // the number of pawns of the strong side reduced if pawns are on a single flank.
941 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
943 // Reduce scale factor in case of pawns being on a single flank
944 sf -= 4 * !pawnsOnBothFlanks;
947 // Interpolate between the middlegame and (scaled by 'sf') endgame score
948 v = mg * int(me->game_phase())
949 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
954 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
955 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
962 // Evaluation::value() is the main function of the class. It computes the various
963 // parts of the evaluation and returns the value of the position from the point
964 // of view of the side to move.
967 Value Evaluation<T>::value() {
969 assert(!pos.checkers());
971 // Probe the material hash table
972 me = Material::probe(pos);
974 // If we have a specialized evaluation function for the current material
975 // configuration, call it and return.
976 if (me->specialized_eval_exists())
977 return me->evaluate(pos);
979 // Initialize score by reading the incrementally updated scores included in
980 // the position object (material + piece square tables) and the material
981 // imbalance. Score is computed internally from the white point of view.
982 Score score = pos.psq_score() + me->imbalance();
984 // Probe the pawn hash table
985 pe = Pawns::probe(pos);
986 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
988 // Early exit if score is high
989 auto lazy_skip = [&](Value lazyThreshold) {
990 return abs(mg_value(score) + eg_value(score)) > lazyThreshold
991 + std::abs(pos.this_thread()->bestValue) * 5 / 4
992 + pos.non_pawn_material() / 32;
995 if (lazy_skip(LazyThreshold1))
998 // Main evaluation begins here
1000 initialize<BLACK>();
1002 // Pieces evaluated first (also populates attackedBy, attackedBy2).
1003 // Note that the order of evaluation of the terms is left unspecified.
1004 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
1005 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
1006 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
1007 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
1009 score += mobility[WHITE] - mobility[BLACK];
1011 // More complex interactions that require fully populated attack bitboards
1012 score += king< WHITE>() - king< BLACK>()
1013 + passed< WHITE>() - passed< BLACK>();
1015 if (lazy_skip(LazyThreshold2))
1018 score += threats<WHITE>() - threats<BLACK>()
1019 + space< WHITE>() - space< BLACK>();
1022 // Derive single value from mg and eg parts of score
1023 Value v = winnable(score);
1025 // In case of tracing add all remaining individual evaluation terms
1028 Trace::add(MATERIAL, pos.psq_score());
1029 Trace::add(IMBALANCE, me->imbalance());
1030 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1031 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1037 // Side to move point of view
1038 v = (pos.side_to_move() == WHITE ? v : -v);
1046 /// evaluate() is the evaluator for the outer world. It returns a static
1047 /// evaluation of the position from the point of view of the side to move.
1049 Value Eval::evaluate(const Position& pos) {
1051 assert(!pos.checkers());
1054 Value psq = pos.psq_eg_stm();
1056 // We use the much less accurate but faster Classical eval when the NNUE
1057 // option is set to false. Otherwise we use the NNUE eval unless the
1058 // PSQ advantage is decisive. (~4 Elo at STC, 1 Elo at LTC)
1059 bool useClassical = !useNNUE || abs(psq) > 2048;
1062 v = Evaluation<NO_TRACE>(pos).value();
1066 int npm = pos.non_pawn_material() / 64;
1068 Color stm = pos.side_to_move();
1069 Value optimism = pos.this_thread()->optimism[stm];
1071 Value nnue = NNUE::evaluate(pos, true, &nnueComplexity);
1073 // Blend optimism with nnue complexity and (semi)classical complexity
1074 optimism += optimism * (nnueComplexity + abs(psq - nnue)) / 512;
1075 v = (nnue * (945 + npm) + optimism * (150 + npm)) / 1024;
1078 // Damp down the evaluation linearly when shuffling
1079 v = v * (200 - pos.rule50_count()) / 214;
1081 // Guarantee evaluation does not hit the tablebase range
1082 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1087 /// trace() is like evaluate(), but instead of returning a value, it returns
1088 /// a string (suitable for outputting to stdout) that contains the detailed
1089 /// descriptions and values of each evaluation term. Useful for debugging.
1090 /// Trace scores are from white's point of view
1092 std::string Eval::trace(Position& pos) {
1095 return "Final evaluation: none (in check)";
1097 std::stringstream ss;
1098 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1102 std::memset(scores, 0, sizeof(scores));
1104 // Reset any global variable used in eval
1105 pos.this_thread()->bestValue = VALUE_ZERO;
1106 pos.this_thread()->optimism[WHITE] = VALUE_ZERO;
1107 pos.this_thread()->optimism[BLACK] = VALUE_ZERO;
1109 v = Evaluation<TRACE>(pos).value();
1111 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1112 << " Contributing terms for the classical eval:\n"
1113 << "+------------+-------------+-------------+-------------+\n"
1114 << "| Term | White | Black | Total |\n"
1115 << "| | MG EG | MG EG | MG EG |\n"
1116 << "+------------+-------------+-------------+-------------+\n"
1117 << "| Material | " << Term(MATERIAL)
1118 << "| Imbalance | " << Term(IMBALANCE)
1119 << "| Pawns | " << Term(PAWN)
1120 << "| Knights | " << Term(KNIGHT)
1121 << "| Bishops | " << Term(BISHOP)
1122 << "| Rooks | " << Term(ROOK)
1123 << "| Queens | " << Term(QUEEN)
1124 << "| Mobility | " << Term(MOBILITY)
1125 << "|King safety | " << Term(KING)
1126 << "| Threats | " << Term(THREAT)
1127 << "| Passed | " << Term(PASSED)
1128 << "| Space | " << Term(SPACE)
1129 << "| Winnable | " << Term(WINNABLE)
1130 << "+------------+-------------+-------------+-------------+\n"
1131 << "| Total | " << Term(TOTAL)
1132 << "+------------+-------------+-------------+-------------+\n";
1135 ss << '\n' << NNUE::trace(pos) << '\n';
1137 ss << std::showpoint << std::showpos << std::fixed << std::setprecision(2) << std::setw(15);
1139 v = pos.side_to_move() == WHITE ? v : -v;
1140 ss << "\nClassical evaluation " << to_cp(v) << " (white side)\n";
1143 v = NNUE::evaluate(pos, false);
1144 v = pos.side_to_move() == WHITE ? v : -v;
1145 ss << "NNUE evaluation " << to_cp(v) << " (white side)\n";
1149 v = pos.side_to_move() == WHITE ? v : -v;
1150 ss << "Final evaluation " << to_cp(v) << " (white side)";
1152 ss << " [with scaled NNUE, hybrid, ...]";
1158 } // namespace Stockfish