2 Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3 Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
5 Stockfish is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 Stockfish is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <cstring> // For std::memset
38 #include "incbin/incbin.h"
41 // Macro to embed the default efficiently updatable neural network (NNUE) file
42 // data in the engine binary (using incbin.h, by Dale Weiler).
43 // This macro invocation will declare the following three variables
44 // const unsigned char gEmbeddedNNUEData[]; // a pointer to the embedded data
45 // const unsigned char *const gEmbeddedNNUEEnd; // a marker to the end
46 // const unsigned int gEmbeddedNNUESize; // the size of the embedded file
47 // Note that this does not work in Microsoft Visual Studio.
48 #if !defined(_MSC_VER) && !defined(NNUE_EMBEDDING_OFF)
49 INCBIN(EmbeddedNNUE, EvalFileDefaultName);
51 const unsigned char gEmbeddedNNUEData[1] = {0x0};
52 const unsigned char *const gEmbeddedNNUEEnd = &gEmbeddedNNUEData[1];
53 const unsigned int gEmbeddedNNUESize = 1;
58 using namespace Stockfish::Eval::NNUE;
65 string eval_file_loaded = "None";
67 /// NNUE::init() tries to load a NNUE network at startup time, or when the engine
68 /// receives a UCI command "setoption name EvalFile value nn-[a-z0-9]{12}.nnue"
69 /// The name of the NNUE network is always retrieved from the EvalFile option.
70 /// We search the given network in three locations: internally (the default
71 /// network may be embedded in the binary), in the active working directory and
72 /// in the engine directory. Distro packagers may define the DEFAULT_NNUE_DIRECTORY
73 /// variable to have the engine search in a special directory in their distro.
77 useNNUE = Options["Use NNUE"];
81 string eval_file = string(Options["EvalFile"]);
83 #if defined(DEFAULT_NNUE_DIRECTORY)
84 #define stringify2(x) #x
85 #define stringify(x) stringify2(x)
86 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) };
88 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory };
91 for (string directory : dirs)
92 if (eval_file_loaded != eval_file)
94 if (directory != "<internal>")
96 ifstream stream(directory + eval_file, ios::binary);
97 if (load_eval(eval_file, stream))
98 eval_file_loaded = eval_file;
101 if (directory == "<internal>" && eval_file == EvalFileDefaultName)
103 // C++ way to prepare a buffer for a memory stream
104 class MemoryBuffer : public basic_streambuf<char> {
105 public: MemoryBuffer(char* p, size_t n) { setg(p, p, p + n); setp(p, p + n); }
108 MemoryBuffer buffer(const_cast<char*>(reinterpret_cast<const char*>(gEmbeddedNNUEData)),
109 size_t(gEmbeddedNNUESize));
111 istream stream(&buffer);
112 if (load_eval(eval_file, stream))
113 eval_file_loaded = 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"]);
123 if (useNNUE && eval_file_loaded != eval_file)
125 UCI::OptionsMap defaults;
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/" + string(defaults["EvalFile"]);
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;
143 if (Cluster::is_root())
146 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
148 sync_cout << "info string classical evaluation enabled" << sync_endl;
155 enum Tracing { NO_TRACE, TRACE };
157 enum Term { // The first 8 entries are reserved for PieceType
158 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
161 Score scores[TERM_NB][COLOR_NB];
163 double to_cp(Value v) { return double(v) / PawnValueEg; }
165 void add(int idx, Color c, Score s) {
169 void add(int idx, Score w, Score b = SCORE_ZERO) {
170 scores[idx][WHITE] = w;
171 scores[idx][BLACK] = b;
174 std::ostream& operator<<(std::ostream& os, Score s) {
175 os << std::setw(5) << to_cp(mg_value(s)) << " "
176 << std::setw(5) << to_cp(eg_value(s));
180 std::ostream& operator<<(std::ostream& os, Term t) {
182 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
183 os << " ---- ----" << " | " << " ---- ----";
185 os << scores[t][WHITE] << " | " << scores[t][BLACK];
187 os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
192 using namespace Trace;
196 // Threshold for lazy and space evaluation
197 constexpr Value LazyThreshold1 = Value(1565);
198 constexpr Value LazyThreshold2 = Value(1102);
199 constexpr Value SpaceThreshold = Value(11551);
200 constexpr Value NNUEThreshold1 = Value(682);
201 constexpr Value NNUEThreshold2 = Value(176);
203 // KingAttackWeights[PieceType] contains king attack weights by piece type
204 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
206 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
207 // higher if multiple safe checks are possible for that piece type.
208 constexpr int SafeCheck[][2] = {
209 {}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
212 #define S(mg, eg) make_score(mg, eg)
214 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
215 // indexed by piece type and number of attacked squares in the mobility area.
216 constexpr Score MobilityBonus[][32] = {
217 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
218 S( 21, 16), S( 28, 21), S( 37, 26) },
219 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
220 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
221 S( 91, 88), S( 96, 98) },
222 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
223 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
224 S( 57,165), S( 58,170), S( 67,175) },
225 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
226 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
227 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
228 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
229 S(112,178), S(114,185), S(114,187), S(119,221) }
232 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
233 // squares of the same color as our bishop.
234 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
235 S(3, 8), S(3, 9), S(2, 8), S(3, 8)
238 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
239 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
241 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
242 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
243 constexpr Score Outpost[] = { S(57, 38), S(31, 24) };
245 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
246 constexpr Score PassedRank[RANK_NB] = {
247 S(0, 0), S(7, 27), S(16, 32), S(17, 40), S(64, 71), S(170, 174), S(278, 262)
250 constexpr Score RookOnClosedFile = S(10, 5);
251 constexpr Score RookOnOpenFile[] = { S(19, 6), S(47, 26) };
253 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
254 // which piece type attacks which one. Attacks on lesser pieces which are
255 // pawn-defended are not considered.
256 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
257 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
260 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
261 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
264 // Assorted bonuses and penalties
265 constexpr Score UncontestedOutpost = S( 1, 10);
266 constexpr Score BishopOnKingRing = S( 24, 0);
267 constexpr Score BishopXRayPawns = S( 4, 5);
268 constexpr Score CorneredBishop = S( 50, 50);
269 constexpr Score FlankAttacks = S( 8, 0);
270 constexpr Score Hanging = S( 69, 36);
271 constexpr Score KnightOnQueen = S( 16, 11);
272 constexpr Score LongDiagonalBishop = S( 45, 0);
273 constexpr Score MinorBehindPawn = S( 18, 3);
274 constexpr Score PassedFile = S( 11, 8);
275 constexpr Score PawnlessFlank = S( 17, 95);
276 constexpr Score ReachableOutpost = S( 31, 22);
277 constexpr Score RestrictedPiece = S( 7, 7);
278 constexpr Score RookOnKingRing = S( 16, 0);
279 constexpr Score SliderOnQueen = S( 60, 18);
280 constexpr Score ThreatByKing = S( 24, 89);
281 constexpr Score ThreatByPawnPush = S( 48, 39);
282 constexpr Score ThreatBySafePawn = S(173, 94);
283 constexpr Score TrappedRook = S( 55, 13);
284 constexpr Score WeakQueenProtection = S( 14, 0);
285 constexpr Score WeakQueen = S( 56, 15);
290 // Evaluation class computes and stores attacks tables and other working data
295 Evaluation() = delete;
296 explicit Evaluation(const Position& p) : pos(p) {}
297 Evaluation& operator=(const Evaluation&) = delete;
301 template<Color Us> void initialize();
302 template<Color Us, PieceType Pt> Score pieces();
303 template<Color Us> Score king() const;
304 template<Color Us> Score threats() const;
305 template<Color Us> Score passed() const;
306 template<Color Us> Score space() const;
307 Value winnable(Score score) const;
312 Bitboard mobilityArea[COLOR_NB];
313 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
315 // attackedBy[color][piece type] is a bitboard representing all squares
316 // attacked by a given color and piece type. Special "piece types" which
317 // is also calculated is ALL_PIECES.
318 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
320 // attackedBy2[color] are the squares attacked by at least 2 units of a given
321 // color, including x-rays. But diagonal x-rays through pawns are not computed.
322 Bitboard attackedBy2[COLOR_NB];
324 // kingRing[color] are the squares adjacent to the king plus some other
325 // very near squares, depending on king position.
326 Bitboard kingRing[COLOR_NB];
328 // kingAttackersCount[color] is the number of pieces of the given color
329 // which attack a square in the kingRing of the enemy king.
330 int kingAttackersCount[COLOR_NB];
332 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
333 // the given color which attack a square in the kingRing of the enemy king.
334 // The weights of the individual piece types are given by the elements in
335 // the KingAttackWeights array.
336 int kingAttackersWeight[COLOR_NB];
338 // kingAttacksCount[color] is the number of attacks by the given color to
339 // squares directly adjacent to the enemy king. Pieces which attack more
340 // than one square are counted multiple times. For instance, if there is
341 // a white knight on g5 and black's king is on g8, this white knight adds 2
342 // to kingAttacksCount[WHITE].
343 int kingAttacksCount[COLOR_NB];
347 // Evaluation::initialize() computes king and pawn attacks, and the king ring
348 // bitboard for a given color. This is done at the beginning of the evaluation.
350 template<Tracing T> template<Color Us>
351 void Evaluation<T>::initialize() {
353 constexpr Color Them = ~Us;
354 constexpr Direction Up = pawn_push(Us);
355 constexpr Direction Down = -Up;
356 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
358 const Square ksq = pos.square<KING>(Us);
360 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
362 // Find our pawns that are blocked or on the first two ranks
363 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
365 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
366 // or controlled by enemy pawns are excluded from the mobility area.
367 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
369 // Initialize attackedBy[] for king and pawns
370 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
371 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
372 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
373 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
375 // Init our king safety tables
376 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
377 std::clamp(rank_of(ksq), RANK_2, RANK_7));
378 kingRing[Us] = attacks_bb<KING>(s) | s;
380 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
381 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
383 // Remove from kingRing[] the squares defended by two pawns
384 kingRing[Us] &= ~dblAttackByPawn;
388 // Evaluation::pieces() scores pieces of a given color and type
390 template<Tracing T> template<Color Us, PieceType Pt>
391 Score Evaluation<T>::pieces() {
393 constexpr Color Them = ~Us;
394 constexpr Direction Down = -pawn_push(Us);
395 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
396 : Rank5BB | Rank4BB | Rank3BB);
397 Bitboard b1 = pos.pieces(Us, Pt);
399 Score score = SCORE_ZERO;
401 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)) ? CorneredBishop * 4
485 : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
491 if constexpr (Pt == ROOK)
493 // Bonuses for rook on a (semi-)open or closed file
494 if (pos.is_on_semiopen_file(Us, s))
496 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
500 // If our pawn on this file is blocked, increase penalty
501 if ( pos.pieces(Us, PAWN)
502 & shift<Down>(pos.pieces())
505 score -= RookOnClosedFile;
508 // Penalty when trapped by the king, even more if the king cannot castle
511 File kf = file_of(pos.square<KING>(Us));
512 if ((kf < FILE_E) == (file_of(s) < kf))
513 score -= TrappedRook * (1 + !pos.castling_rights(Us));
518 if constexpr (Pt == QUEEN)
520 // Penalty if any relative pin or discovered attack against the queen
521 Bitboard queenPinners;
522 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
527 Trace::add(Pt, Us, score);
533 // Evaluation::king() assigns bonuses and penalties to a king of a given color
535 template<Tracing T> template<Color Us>
536 Score Evaluation<T>::king() const {
538 constexpr Color Them = ~Us;
539 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
540 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
542 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
543 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
545 const Square ksq = pos.square<KING>(Us);
547 // Init the score with king shelter and enemy pawns storm
548 Score score = pe->king_safety<Us>(pos);
550 // Attacked squares defended at most once by our queen or king
551 weak = attackedBy[Them][ALL_PIECES]
553 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
555 // Analyse the safe enemy's checks which are possible on next move
556 safe = ~pos.pieces(Them);
557 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
559 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
560 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
562 // Enemy rooks checks
563 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
565 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
567 unsafeChecks |= b1 & attackedBy[Them][ROOK];
569 // Enemy queen safe checks: count them only if the checks are from squares from
570 // which opponent cannot give a rook check, because rook checks are more valuable.
571 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
572 & ~(attackedBy[Us][QUEEN] | rookChecks);
574 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
576 // Enemy bishops checks: count them only if they are from squares from which
577 // opponent cannot give a queen check, because queen checks are more valuable.
578 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
581 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
584 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
586 // Enemy knights checks
587 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
588 if (knightChecks & safe)
589 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
591 unsafeChecks |= knightChecks;
593 // Find the squares that opponent attacks in our king flank, the squares
594 // which they attack twice in that flank, and the squares that we defend.
595 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
596 b2 = b1 & attackedBy2[Them];
597 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
599 int kingFlankAttack = popcount(b1) + popcount(b2);
600 int kingFlankDefense = popcount(b3);
602 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
603 + 183 * popcount(kingRing[Us] & weak) // (~15 Elo)
604 + 148 * popcount(unsafeChecks) // (~4 Elo)
605 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
606 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
607 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
608 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
609 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
610 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
611 - 6 * mg_value(score) / 8 // (~8 Elo)
612 - 4 * kingFlankDefense // (~5 Elo)
615 // Transform the kingDanger units into a Score, and subtract it from the evaluation
616 if (kingDanger > 100)
617 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
619 // Penalty when our king is on a pawnless flank
620 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
621 score -= PawnlessFlank;
623 // Penalty if king flank is under attack, potentially moving toward the king
624 score -= FlankAttacks * kingFlankAttack;
627 Trace::add(KING, Us, score);
633 // Evaluation::threats() assigns bonuses according to the types of the
634 // attacking and the attacked pieces.
636 template<Tracing T> template<Color Us>
637 Score Evaluation<T>::threats() const {
639 constexpr Color Them = ~Us;
640 constexpr Direction Up = pawn_push(Us);
641 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
643 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
644 Score score = SCORE_ZERO;
647 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
649 // Squares strongly protected by the enemy, either because they defend the
650 // square with a pawn, or because they defend the square twice and we don't.
651 stronglyProtected = attackedBy[Them][PAWN]
652 | (attackedBy2[Them] & ~attackedBy2[Us]);
654 // Non-pawn enemies, strongly protected
655 defended = nonPawnEnemies & stronglyProtected;
657 // Enemies not strongly protected and under our attack
658 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
660 // Bonus according to the kind of attacking pieces
663 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
665 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
667 b = weak & attackedBy[Us][ROOK];
669 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
671 if (weak & attackedBy[Us][KING])
672 score += ThreatByKing;
674 b = ~attackedBy[Them][ALL_PIECES]
675 | (nonPawnEnemies & attackedBy2[Us]);
676 score += Hanging * popcount(weak & b);
678 // Additional bonus if weak piece is only protected by a queen
679 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
682 // Bonus for restricting their piece moves
683 b = attackedBy[Them][ALL_PIECES]
685 & attackedBy[Us][ALL_PIECES];
686 score += RestrictedPiece * popcount(b);
688 // Protected or unattacked squares
689 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
691 // Bonus for attacking enemy pieces with our relatively safe pawns
692 b = pos.pieces(Us, PAWN) & safe;
693 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
694 score += ThreatBySafePawn * popcount(b);
696 // Find squares where our pawns can push on the next move
697 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
698 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
700 // Keep only the squares which are relatively safe
701 b &= ~attackedBy[Them][PAWN] & safe;
703 // Bonus for safe pawn threats on the next move
704 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
705 score += ThreatByPawnPush * popcount(b);
707 // Bonus for threats on the next moves against enemy queen
708 if (pos.count<QUEEN>(Them) == 1)
710 bool queenImbalance = pos.count<QUEEN>() == 1;
712 Square s = pos.square<QUEEN>(Them);
713 safe = mobilityArea[Us]
714 & ~pos.pieces(Us, PAWN)
715 & ~stronglyProtected;
717 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
719 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
721 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
722 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
724 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
728 Trace::add(THREAT, Us, score);
733 // Evaluation::passed() evaluates the passed pawns and candidate passed
734 // pawns of the given color.
736 template<Tracing T> template<Color Us>
737 Score Evaluation<T>::passed() const {
739 constexpr Color Them = ~Us;
740 constexpr Direction Up = pawn_push(Us);
741 constexpr Direction Down = -Up;
743 auto king_proximity = [&](Color c, Square s) {
744 return std::min(distance(pos.square<KING>(c), s), 5);
747 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
748 Score score = SCORE_ZERO;
750 b = pe->passed_pawns(Us);
752 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
755 helpers = shift<Up>(pos.pieces(Us, PAWN))
757 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
759 // Remove blocked candidate passers that don't have help to pass
761 | shift<WEST>(helpers)
762 | shift<EAST>(helpers);
767 Square s = pop_lsb(&b);
769 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
771 int r = relative_rank(Us, s);
773 Score bonus = PassedRank[r];
778 Square blockSq = s + Up;
780 // Adjust bonus based on the king's proximity
781 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
782 - king_proximity(Us, blockSq) * 2) * w);
784 // If blockSq is not the queening square then consider also a second push
786 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
788 // If the pawn is free to advance, then increase the bonus
789 if (pos.empty(blockSq))
791 squaresToQueen = forward_file_bb(Us, s);
792 unsafeSquares = passed_pawn_span(Us, s);
794 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
796 if (!(pos.pieces(Them) & bb))
797 unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
799 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
800 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
801 // Otherwise assign a smaller bonus if the path to queen is not attacked
802 // and even smaller bonus if it is attacked but block square is not.
803 int k = !unsafeSquares ? 36 :
804 !(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
805 !(unsafeSquares & squaresToQueen) ? 17 :
806 !(unsafeSquares & blockSq) ? 7 :
809 // Assign a larger bonus if the block square is defended
810 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
813 bonus += make_score(k * w, k * w);
817 score += bonus - PassedFile * edge_distance(file_of(s));
821 Trace::add(PASSED, Us, score);
827 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
828 // play in the opening. It is based on the number of safe squares on the four central files
829 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
830 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
832 template<Tracing T> template<Color Us>
833 Score Evaluation<T>::space() const {
835 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
836 if (pos.non_pawn_material() < SpaceThreshold)
839 constexpr Color Them = ~Us;
840 constexpr Direction Down = -pawn_push(Us);
841 constexpr Bitboard SpaceMask =
842 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
843 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
845 // Find the available squares for our pieces inside the area defined by SpaceMask
846 Bitboard safe = SpaceMask
847 & ~pos.pieces(Us, PAWN)
848 & ~attackedBy[Them][PAWN];
850 // Find all squares which are at most three squares behind some friendly pawn
851 Bitboard behind = pos.pieces(Us, PAWN);
852 behind |= shift<Down>(behind);
853 behind |= shift<Down+Down>(behind);
855 // Compute space score based on the number of safe squares and number of our pieces
856 // increased with number of total blocked pawns in position.
857 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
858 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
859 Score score = make_score(bonus * weight * weight / 16, 0);
862 Trace::add(SPACE, Us, score);
868 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
869 // the known attacking/defending status of the players. The final value is derived
870 // by interpolation from the midgame and endgame values.
873 Value Evaluation<T>::winnable(Score score) const {
875 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
876 + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
878 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
879 && (pos.pieces(PAWN) & KingSide);
881 bool almostUnwinnable = outflanking < 0
882 && !pawnsOnBothFlanks;
884 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
885 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
887 // Compute the initiative bonus for the attacking side
888 int complexity = 9 * pe->passed_count()
889 + 12 * pos.count<PAWN>()
891 + 21 * pawnsOnBothFlanks
893 + 51 * !pos.non_pawn_material()
894 - 43 * almostUnwinnable
897 Value mg = mg_value(score);
898 Value eg = eg_value(score);
900 // Now apply the bonus: note that we find the attacking side by extracting the
901 // sign of the midgame or endgame values, and that we carefully cap the bonus
902 // so that the midgame and endgame scores do not change sign after the bonus.
903 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
904 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
909 // Compute the scale factor for the winning side
910 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
911 int sf = me->scale_factor(pos, strongSide);
913 // If scale factor is not already specific, scale down via general heuristics
914 if (sf == SCALE_FACTOR_NORMAL)
916 if (pos.opposite_bishops())
918 // For pure opposite colored bishops endgames use scale factor
919 // based on the number of passed pawns of the strong side.
920 if ( pos.non_pawn_material(WHITE) == BishopValueMg
921 && pos.non_pawn_material(BLACK) == BishopValueMg)
922 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
923 // For every other opposite colored bishops endgames use scale factor
924 // based on the number of all pieces of the strong side.
926 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
928 // For rook endgames with strong side not having overwhelming pawn number advantage
929 // and its pawns being on one flank and weak side protecting its pieces with a king
930 // use lower scale factor.
931 else if ( pos.non_pawn_material(WHITE) == RookValueMg
932 && pos.non_pawn_material(BLACK) == RookValueMg
933 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
934 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
935 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
937 // For queen vs no queen endgames use scale factor
938 // based on number of minors of side that doesn't have queen.
939 else if (pos.count<QUEEN>() == 1)
940 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
941 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
942 // In every other case use scale factor based on
943 // the number of pawns of the strong side reduced if pawns are on a single flank.
945 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
947 // Reduce scale factor in case of pawns being on a single flank
948 sf -= 4 * !pawnsOnBothFlanks;
951 // Interpolate between the middlegame and (scaled by 'sf') endgame score
952 v = mg * int(me->game_phase())
953 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
958 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
959 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
966 // Evaluation::value() is the main function of the class. It computes the various
967 // parts of the evaluation and returns the value of the position from the point
968 // of view of the side to move.
971 Value Evaluation<T>::value() {
973 assert(!pos.checkers());
975 // Probe the material hash table
976 me = Material::probe(pos);
978 // If we have a specialized evaluation function for the current material
979 // configuration, call it and return.
980 if (me->specialized_eval_exists())
981 return me->evaluate(pos);
983 // Initialize score by reading the incrementally updated scores included in
984 // the position object (material + piece square tables) and the material
985 // imbalance. Score is computed internally from the white point of view.
986 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
988 // Probe the pawn hash table
989 pe = Pawns::probe(pos);
990 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
992 // Early exit if score is high
993 auto lazy_skip = [&](Value lazyThreshold) {
994 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
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) + Tempo;
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) {
1056 v = Evaluation<NO_TRACE>(pos).value();
1059 // Scale and shift NNUE for compatibility with search and classical evaluation
1060 auto adjusted_NNUE = [&](){
1061 int mat = pos.non_pawn_material() + 2 * PawnValueMg * pos.count<PAWN>();
1062 return NNUE::evaluate(pos) * (641 + mat / 32 - 4 * pos.rule50_count()) / 1024 + Tempo;
1065 // If there is PSQ imbalance use classical eval, with small probability if it is small
1066 Value psq = Value(abs(eg_value(pos.psq_score())));
1067 int r50 = 16 + pos.rule50_count();
1068 bool largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50;
1069 bool classical = largePsq || (psq > PawnValueMg / 4 && !(pos.this_thread()->nodes & 0xB));
1071 // Use classical evaluation for really low piece endgames.
1072 // The most critical case is a bishop + A/H file pawn vs naked king draw.
1073 bool strongClassical = pos.non_pawn_material() < 2 * RookValueMg && pos.count<PAWN>() < 2;
1075 v = classical || strongClassical ? Evaluation<NO_TRACE>(pos).value() : adjusted_NNUE();
1077 // If the classical eval is small and imbalance large, use NNUE nevertheless.
1078 // For the case of opposite colored bishops, switch to NNUE eval with
1079 // small probability if the classical eval is less than the threshold.
1080 if ( largePsq && !strongClassical
1081 && ( abs(v) * 16 < NNUEThreshold2 * r50
1082 || ( pos.opposite_bishops()
1083 && abs(v) * 16 < (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50
1084 && !(pos.this_thread()->nodes & 0xB))))
1085 v = adjusted_NNUE();
1088 // Damp down the evaluation linearly when shuffling
1089 v = v * (100 - pos.rule50_count()) / 100;
1091 // Guarantee evaluation does not hit the tablebase range
1092 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1097 /// trace() is like evaluate(), but instead of returning a value, it returns
1098 /// a string (suitable for outputting to stdout) that contains the detailed
1099 /// descriptions and values of each evaluation term. Useful for debugging.
1100 /// Trace scores are from white's point of view
1102 std::string Eval::trace(const Position& pos) {
1105 return "Final evaluation: none (in check)";
1107 std::stringstream ss;
1108 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1112 std::memset(scores, 0, sizeof(scores));
1114 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
1116 v = Evaluation<TRACE>(pos).value();
1118 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1119 << " Term | White | Black | Total \n"
1120 << " | MG EG | MG EG | MG EG \n"
1121 << " ------------+-------------+-------------+------------\n"
1122 << " Material | " << Term(MATERIAL)
1123 << " Imbalance | " << Term(IMBALANCE)
1124 << " Pawns | " << Term(PAWN)
1125 << " Knights | " << Term(KNIGHT)
1126 << " Bishops | " << Term(BISHOP)
1127 << " Rooks | " << Term(ROOK)
1128 << " Queens | " << Term(QUEEN)
1129 << " Mobility | " << Term(MOBILITY)
1130 << " King safety | " << Term(KING)
1131 << " Threats | " << Term(THREAT)
1132 << " Passed | " << Term(PASSED)
1133 << " Space | " << Term(SPACE)
1134 << " Winnable | " << Term(WINNABLE)
1135 << " ------------+-------------+-------------+------------\n"
1136 << " Total | " << Term(TOTAL);
1138 v = pos.side_to_move() == WHITE ? v : -v;
1140 ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n";
1144 v = NNUE::evaluate(pos);
1145 v = pos.side_to_move() == WHITE ? v : -v;
1146 ss << "\nNNUE evaluation: " << to_cp(v) << " (white side)\n";
1150 v = pos.side_to_move() == WHITE ? v : -v;
1151 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";
1156 } // namespace Stockfish