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;
64 string eval_file_loaded = "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"]);
82 #if defined(DEFAULT_NNUE_DIRECTORY)
83 #define stringify2(x) #x
84 #define stringify(x) stringify2(x)
85 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) };
87 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory };
90 for (string directory : dirs)
91 if (eval_file_loaded != eval_file)
93 if (directory != "<internal>")
95 ifstream stream(directory + eval_file, ios::binary);
96 if (load_eval(eval_file, stream))
97 eval_file_loaded = 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));
110 istream stream(&buffer);
111 if (load_eval(eval_file, stream))
112 eval_file_loaded = eval_file;
117 /// NNUE::export_net() exports the currently loaded network to a file
118 void NNUE::export_net(const std::optional<std::string>& filename) {
119 std::string actualFilename;
121 if (filename.has_value())
122 actualFilename = filename.value();
125 if (eval_file_loaded != EvalFileDefaultName)
127 sync_cout << "Failed to export a net. A non-embedded net can only be saved if the filename is specified." << sync_endl;
130 actualFilename = EvalFileDefaultName;
133 ofstream stream(actualFilename, std::ios_base::binary);
135 if (save_eval(stream))
136 sync_cout << "Network saved successfully to " << actualFilename << "." << sync_endl;
138 sync_cout << "Failed to export a net." << sync_endl;
141 /// NNUE::verify() verifies that the last net used was loaded successfully
142 void NNUE::verify() {
144 string eval_file = string(Options["EvalFile"]);
146 if (useNNUE && eval_file_loaded != eval_file)
148 UCI::OptionsMap defaults;
151 string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
152 string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
153 string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
154 string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + string(defaults["EvalFile"]);
155 string msg5 = "The engine will be terminated now.";
157 sync_cout << "info string ERROR: " << msg1 << sync_endl;
158 sync_cout << "info string ERROR: " << msg2 << sync_endl;
159 sync_cout << "info string ERROR: " << msg3 << sync_endl;
160 sync_cout << "info string ERROR: " << msg4 << sync_endl;
161 sync_cout << "info string ERROR: " << msg5 << sync_endl;
167 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
169 sync_cout << "info string classical evaluation enabled" << sync_endl;
175 enum Tracing { NO_TRACE, TRACE };
177 enum Term { // The first 8 entries are reserved for PieceType
178 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
181 Score scores[TERM_NB][COLOR_NB];
183 double to_cp(Value v) { return double(v) / PawnValueEg; }
185 void add(int idx, Color c, Score s) {
189 void add(int idx, Score w, Score b = SCORE_ZERO) {
190 scores[idx][WHITE] = w;
191 scores[idx][BLACK] = b;
194 std::ostream& operator<<(std::ostream& os, Score s) {
195 os << std::setw(5) << to_cp(mg_value(s)) << " "
196 << std::setw(5) << to_cp(eg_value(s));
200 std::ostream& operator<<(std::ostream& os, Term t) {
202 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
203 os << " ---- ----" << " | " << " ---- ----";
205 os << scores[t][WHITE] << " | " << scores[t][BLACK];
207 os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
212 using namespace Trace;
216 // Threshold for lazy and space evaluation
217 constexpr Value LazyThreshold1 = Value(1565);
218 constexpr Value LazyThreshold2 = Value(1102);
219 constexpr Value LazyThresholdNNUE = Value(1400);
220 constexpr Value SpaceThreshold = Value(11551);
221 constexpr Value NNUEThreshold1 = Value(682);
222 constexpr Value NNUEThreshold2 = Value(176);
224 // KingAttackWeights[PieceType] contains king attack weights by piece type
225 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
227 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
228 // higher if multiple safe checks are possible for that piece type.
229 constexpr int SafeCheck[][2] = {
230 {}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
233 #define S(mg, eg) make_score(mg, eg)
235 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
236 // indexed by piece type and number of attacked squares in the mobility area.
237 constexpr Score MobilityBonus[][32] = {
238 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
239 S( 21, 16), S( 28, 21), S( 37, 26) },
240 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
241 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
242 S( 91, 88), S( 96, 98) },
243 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
244 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
245 S( 57,165), S( 58,170), S( 67,175) },
246 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
247 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
248 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
249 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
250 S(112,178), S(114,185), S(114,187), S(119,221) }
253 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
254 // squares of the same color as our bishop.
255 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
256 S(3, 8), S(3, 9), S(2, 8), S(3, 8)
259 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
260 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
262 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
263 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
264 constexpr Score Outpost[] = { S(57, 38), S(31, 24) };
266 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
267 constexpr Score PassedRank[RANK_NB] = {
268 S(0, 0), S(7, 27), S(16, 32), S(17, 40), S(64, 71), S(170, 174), S(278, 262)
271 constexpr Score RookOnClosedFile = S(10, 5);
272 constexpr Score RookOnOpenFile[] = { S(19, 6), S(47, 26) };
274 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
275 // which piece type attacks which one. Attacks on lesser pieces which are
276 // pawn-defended are not considered.
277 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
278 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
281 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
282 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
285 constexpr Value CorneredBishop = Value(50);
287 // Assorted bonuses and penalties
288 constexpr Score UncontestedOutpost = S( 1, 10);
289 constexpr Score BishopOnKingRing = S( 24, 0);
290 constexpr Score BishopXRayPawns = S( 4, 5);
291 constexpr Score FlankAttacks = S( 8, 0);
292 constexpr Score Hanging = S( 69, 36);
293 constexpr Score KnightOnQueen = S( 16, 11);
294 constexpr Score LongDiagonalBishop = S( 45, 0);
295 constexpr Score MinorBehindPawn = S( 18, 3);
296 constexpr Score PassedFile = S( 11, 8);
297 constexpr Score PawnlessFlank = S( 17, 95);
298 constexpr Score ReachableOutpost = S( 31, 22);
299 constexpr Score RestrictedPiece = S( 7, 7);
300 constexpr Score RookOnKingRing = S( 16, 0);
301 constexpr Score SliderOnQueen = S( 60, 18);
302 constexpr Score ThreatByKing = S( 24, 89);
303 constexpr Score ThreatByPawnPush = S( 48, 39);
304 constexpr Score ThreatBySafePawn = S(173, 94);
305 constexpr Score TrappedRook = S( 55, 13);
306 constexpr Score WeakQueenProtection = S( 14, 0);
307 constexpr Score WeakQueen = S( 56, 15);
312 // Evaluation class computes and stores attacks tables and other working data
317 Evaluation() = delete;
318 explicit Evaluation(const Position& p) : pos(p) {}
319 Evaluation& operator=(const Evaluation&) = delete;
323 template<Color Us> void initialize();
324 template<Color Us, PieceType Pt> Score pieces();
325 template<Color Us> Score king() const;
326 template<Color Us> Score threats() const;
327 template<Color Us> Score passed() const;
328 template<Color Us> Score space() const;
329 Value winnable(Score score) const;
334 Bitboard mobilityArea[COLOR_NB];
335 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
337 // attackedBy[color][piece type] is a bitboard representing all squares
338 // attacked by a given color and piece type. Special "piece types" which
339 // is also calculated is ALL_PIECES.
340 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
342 // attackedBy2[color] are the squares attacked by at least 2 units of a given
343 // color, including x-rays. But diagonal x-rays through pawns are not computed.
344 Bitboard attackedBy2[COLOR_NB];
346 // kingRing[color] are the squares adjacent to the king plus some other
347 // very near squares, depending on king position.
348 Bitboard kingRing[COLOR_NB];
350 // kingAttackersCount[color] is the number of pieces of the given color
351 // which attack a square in the kingRing of the enemy king.
352 int kingAttackersCount[COLOR_NB];
354 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
355 // the given color which attack a square in the kingRing of the enemy king.
356 // The weights of the individual piece types are given by the elements in
357 // the KingAttackWeights array.
358 int kingAttackersWeight[COLOR_NB];
360 // kingAttacksCount[color] is the number of attacks by the given color to
361 // squares directly adjacent to the enemy king. Pieces which attack more
362 // than one square are counted multiple times. For instance, if there is
363 // a white knight on g5 and black's king is on g8, this white knight adds 2
364 // to kingAttacksCount[WHITE].
365 int kingAttacksCount[COLOR_NB];
369 // Evaluation::initialize() computes king and pawn attacks, and the king ring
370 // bitboard for a given color. This is done at the beginning of the evaluation.
372 template<Tracing T> template<Color Us>
373 void Evaluation<T>::initialize() {
375 constexpr Color Them = ~Us;
376 constexpr Direction Up = pawn_push(Us);
377 constexpr Direction Down = -Up;
378 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
380 const Square ksq = pos.square<KING>(Us);
382 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
384 // Find our pawns that are blocked or on the first two ranks
385 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
387 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
388 // or controlled by enemy pawns are excluded from the mobility area.
389 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
391 // Initialize attackedBy[] for king and pawns
392 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
393 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
394 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
395 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
397 // Init our king safety tables
398 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
399 std::clamp(rank_of(ksq), RANK_2, RANK_7));
400 kingRing[Us] = attacks_bb<KING>(s) | s;
402 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
403 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
405 // Remove from kingRing[] the squares defended by two pawns
406 kingRing[Us] &= ~dblAttackByPawn;
410 // Evaluation::pieces() scores pieces of a given color and type
412 template<Tracing T> template<Color Us, PieceType Pt>
413 Score Evaluation<T>::pieces() {
415 constexpr Color Them = ~Us;
416 constexpr Direction Down = -pawn_push(Us);
417 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
418 : Rank5BB | Rank4BB | Rank3BB);
419 Bitboard b1 = pos.pieces(Us, Pt);
421 Score score = SCORE_ZERO;
423 attackedBy[Us][Pt] = 0;
427 Square s = pop_lsb(b1);
429 // Find attacked squares, including x-ray attacks for bishops and rooks
430 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
431 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
432 : attacks_bb<Pt>(s, pos.pieces());
434 if (pos.blockers_for_king(Us) & s)
435 b &= line_bb(pos.square<KING>(Us), s);
437 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
438 attackedBy[Us][Pt] |= b;
439 attackedBy[Us][ALL_PIECES] |= b;
441 if (b & kingRing[Them])
443 kingAttackersCount[Us]++;
444 kingAttackersWeight[Us] += KingAttackWeights[Pt];
445 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
448 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
449 score += RookOnKingRing;
451 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
452 score += BishopOnKingRing;
454 int mob = popcount(b & mobilityArea[Us]);
455 mobility[Us] += MobilityBonus[Pt - 2][mob];
457 if (Pt == BISHOP || Pt == KNIGHT)
459 // Bonus if the piece is on an outpost square or can reach one
460 // Bonus for knights (UncontestedOutpost) if few relevant targets
461 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
462 & ~pe->pawn_attacks_span(Them);
463 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
466 && bb & s & ~CenterFiles // on a side outpost
467 && !(b & targets) // no relevant attacks
468 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
469 score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
471 score += Outpost[Pt == BISHOP];
472 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
473 score += ReachableOutpost;
475 // Bonus for a knight or bishop shielded by pawn
476 if (shift<Down>(pos.pieces(PAWN)) & s)
477 score += MinorBehindPawn;
479 // Penalty if the piece is far from the king
480 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
482 if constexpr (Pt == BISHOP)
484 // Penalty according to the number of our pawns on the same color square as the
485 // bishop, bigger when the center files are blocked with pawns and smaller
486 // when the bishop is outside the pawn chain.
487 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
489 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
490 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
492 // Penalty for all enemy pawns x-rayed
493 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
495 // Bonus for bishop on a long diagonal which can "see" both center squares
496 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
497 score += LongDiagonalBishop;
499 // An important Chess960 pattern: a cornered bishop blocked by a friendly
500 // pawn diagonally in front of it is a very serious problem, especially
501 // when that pawn is also blocked.
502 if ( pos.is_chess960()
503 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
505 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
506 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
507 score -= !pos.empty(s + d + pawn_push(Us)) ? 4 * make_score(CorneredBishop, CorneredBishop)
508 : 3 * make_score(CorneredBishop, CorneredBishop);
513 if constexpr (Pt == ROOK)
515 // Bonuses for rook on a (semi-)open or closed file
516 if (pos.is_on_semiopen_file(Us, s))
518 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
522 // If our pawn on this file is blocked, increase penalty
523 if ( pos.pieces(Us, PAWN)
524 & shift<Down>(pos.pieces())
527 score -= RookOnClosedFile;
530 // Penalty when trapped by the king, even more if the king cannot castle
533 File kf = file_of(pos.square<KING>(Us));
534 if ((kf < FILE_E) == (file_of(s) < kf))
535 score -= TrappedRook * (1 + !pos.castling_rights(Us));
540 if constexpr (Pt == QUEEN)
542 // Penalty if any relative pin or discovered attack against the queen
543 Bitboard queenPinners;
544 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
549 Trace::add(Pt, Us, score);
555 // Evaluation::king() assigns bonuses and penalties to a king of a given color
557 template<Tracing T> template<Color Us>
558 Score Evaluation<T>::king() const {
560 constexpr Color Them = ~Us;
561 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
562 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
564 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
565 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
567 const Square ksq = pos.square<KING>(Us);
569 // Init the score with king shelter and enemy pawns storm
570 Score score = pe->king_safety<Us>(pos);
572 // Attacked squares defended at most once by our queen or king
573 weak = attackedBy[Them][ALL_PIECES]
575 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
577 // Analyse the safe enemy's checks which are possible on next move
578 safe = ~pos.pieces(Them);
579 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
581 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
582 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
584 // Enemy rooks checks
585 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
587 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
589 unsafeChecks |= b1 & attackedBy[Them][ROOK];
591 // Enemy queen safe checks: count them only if the checks are from squares from
592 // which opponent cannot give a rook check, because rook checks are more valuable.
593 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
594 & ~(attackedBy[Us][QUEEN] | rookChecks);
596 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
598 // Enemy bishops checks: count them only if they are from squares from which
599 // opponent cannot give a queen check, because queen checks are more valuable.
600 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
603 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
606 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
608 // Enemy knights checks
609 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
610 if (knightChecks & safe)
611 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
613 unsafeChecks |= knightChecks;
615 // Find the squares that opponent attacks in our king flank, the squares
616 // which they attack twice in that flank, and the squares that we defend.
617 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
618 b2 = b1 & attackedBy2[Them];
619 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
621 int kingFlankAttack = popcount(b1) + popcount(b2);
622 int kingFlankDefense = popcount(b3);
624 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
625 + 183 * popcount(kingRing[Us] & weak) // (~15 Elo)
626 + 148 * popcount(unsafeChecks) // (~4 Elo)
627 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
628 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
629 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
630 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
631 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
632 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
633 - 6 * mg_value(score) / 8 // (~8 Elo)
634 - 4 * kingFlankDefense // (~5 Elo)
637 // Transform the kingDanger units into a Score, and subtract it from the evaluation
638 if (kingDanger > 100)
639 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
641 // Penalty when our king is on a pawnless flank
642 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
643 score -= PawnlessFlank;
645 // Penalty if king flank is under attack, potentially moving toward the king
646 score -= FlankAttacks * kingFlankAttack;
649 Trace::add(KING, Us, score);
655 // Evaluation::threats() assigns bonuses according to the types of the
656 // attacking and the attacked pieces.
658 template<Tracing T> template<Color Us>
659 Score Evaluation<T>::threats() const {
661 constexpr Color Them = ~Us;
662 constexpr Direction Up = pawn_push(Us);
663 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
665 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
666 Score score = SCORE_ZERO;
669 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
671 // Squares strongly protected by the enemy, either because they defend the
672 // square with a pawn, or because they defend the square twice and we don't.
673 stronglyProtected = attackedBy[Them][PAWN]
674 | (attackedBy2[Them] & ~attackedBy2[Us]);
676 // Non-pawn enemies, strongly protected
677 defended = nonPawnEnemies & stronglyProtected;
679 // Enemies not strongly protected and under our attack
680 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
682 // Bonus according to the kind of attacking pieces
685 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
687 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(b)))];
689 b = weak & attackedBy[Us][ROOK];
691 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(b)))];
693 if (weak & attackedBy[Us][KING])
694 score += ThreatByKing;
696 b = ~attackedBy[Them][ALL_PIECES]
697 | (nonPawnEnemies & attackedBy2[Us]);
698 score += Hanging * popcount(weak & b);
700 // Additional bonus if weak piece is only protected by a queen
701 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
704 // Bonus for restricting their piece moves
705 b = attackedBy[Them][ALL_PIECES]
707 & attackedBy[Us][ALL_PIECES];
708 score += RestrictedPiece * popcount(b);
710 // Protected or unattacked squares
711 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
713 // Bonus for attacking enemy pieces with our relatively safe pawns
714 b = pos.pieces(Us, PAWN) & safe;
715 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
716 score += ThreatBySafePawn * popcount(b);
718 // Find squares where our pawns can push on the next move
719 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
720 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
722 // Keep only the squares which are relatively safe
723 b &= ~attackedBy[Them][PAWN] & safe;
725 // Bonus for safe pawn threats on the next move
726 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
727 score += ThreatByPawnPush * popcount(b);
729 // Bonus for threats on the next moves against enemy queen
730 if (pos.count<QUEEN>(Them) == 1)
732 bool queenImbalance = pos.count<QUEEN>() == 1;
734 Square s = pos.square<QUEEN>(Them);
735 safe = mobilityArea[Us]
736 & ~pos.pieces(Us, PAWN)
737 & ~stronglyProtected;
739 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
741 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
743 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
744 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
746 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
750 Trace::add(THREAT, Us, score);
755 // Evaluation::passed() evaluates the passed pawns and candidate passed
756 // pawns of the given color.
758 template<Tracing T> template<Color Us>
759 Score Evaluation<T>::passed() const {
761 constexpr Color Them = ~Us;
762 constexpr Direction Up = pawn_push(Us);
763 constexpr Direction Down = -Up;
765 auto king_proximity = [&](Color c, Square s) {
766 return std::min(distance(pos.square<KING>(c), s), 5);
769 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
770 Score score = SCORE_ZERO;
772 b = pe->passed_pawns(Us);
774 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
777 helpers = shift<Up>(pos.pieces(Us, PAWN))
779 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
781 // Remove blocked candidate passers that don't have help to pass
783 | shift<WEST>(helpers)
784 | shift<EAST>(helpers);
789 Square s = pop_lsb(b);
791 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
793 int r = relative_rank(Us, s);
795 Score bonus = PassedRank[r];
800 Square blockSq = s + Up;
802 // Adjust bonus based on the king's proximity
803 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
804 - king_proximity(Us, blockSq) * 2) * w);
806 // If blockSq is not the queening square then consider also a second push
808 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
810 // If the pawn is free to advance, then increase the bonus
811 if (pos.empty(blockSq))
813 squaresToQueen = forward_file_bb(Us, s);
814 unsafeSquares = passed_pawn_span(Us, s);
816 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
818 if (!(pos.pieces(Them) & bb))
819 unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
821 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
822 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
823 // Otherwise assign a smaller bonus if the path to queen is not attacked
824 // and even smaller bonus if it is attacked but block square is not.
825 int k = !unsafeSquares ? 36 :
826 !(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
827 !(unsafeSquares & squaresToQueen) ? 17 :
828 !(unsafeSquares & blockSq) ? 7 :
831 // Assign a larger bonus if the block square is defended
832 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
835 bonus += make_score(k * w, k * w);
839 score += bonus - PassedFile * edge_distance(file_of(s));
843 Trace::add(PASSED, Us, score);
849 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
850 // play in the opening. It is based on the number of safe squares on the four central files
851 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
852 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
854 template<Tracing T> template<Color Us>
855 Score Evaluation<T>::space() const {
857 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
858 if (pos.non_pawn_material() < SpaceThreshold)
861 constexpr Color Them = ~Us;
862 constexpr Direction Down = -pawn_push(Us);
863 constexpr Bitboard SpaceMask =
864 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
865 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
867 // Find the available squares for our pieces inside the area defined by SpaceMask
868 Bitboard safe = SpaceMask
869 & ~pos.pieces(Us, PAWN)
870 & ~attackedBy[Them][PAWN];
872 // Find all squares which are at most three squares behind some friendly pawn
873 Bitboard behind = pos.pieces(Us, PAWN);
874 behind |= shift<Down>(behind);
875 behind |= shift<Down+Down>(behind);
877 // Compute space score based on the number of safe squares and number of our pieces
878 // increased with number of total blocked pawns in position.
879 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
880 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
881 Score score = make_score(bonus * weight * weight / 16, 0);
884 Trace::add(SPACE, Us, score);
890 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
891 // the known attacking/defending status of the players. The final value is derived
892 // by interpolation from the midgame and endgame values.
895 Value Evaluation<T>::winnable(Score score) const {
897 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
898 + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
900 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
901 && (pos.pieces(PAWN) & KingSide);
903 bool almostUnwinnable = outflanking < 0
904 && !pawnsOnBothFlanks;
906 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
907 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
909 // Compute the initiative bonus for the attacking side
910 int complexity = 9 * pe->passed_count()
911 + 12 * pos.count<PAWN>()
913 + 21 * pawnsOnBothFlanks
915 + 51 * !pos.non_pawn_material()
916 - 43 * almostUnwinnable
919 Value mg = mg_value(score);
920 Value eg = eg_value(score);
922 // Now apply the bonus: note that we find the attacking side by extracting the
923 // sign of the midgame or endgame values, and that we carefully cap the bonus
924 // so that the midgame and endgame scores do not change sign after the bonus.
925 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
926 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
931 // Compute the scale factor for the winning side
932 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
933 int sf = me->scale_factor(pos, strongSide);
935 // If scale factor is not already specific, scale up/down via general heuristics
936 if (sf == SCALE_FACTOR_NORMAL)
938 if (pos.opposite_bishops())
940 // For pure opposite colored bishops endgames use scale factor
941 // based on the number of passed pawns of the strong side.
942 if ( pos.non_pawn_material(WHITE) == BishopValueMg
943 && pos.non_pawn_material(BLACK) == BishopValueMg)
944 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
945 // For every other opposite colored bishops endgames use scale factor
946 // based on the number of all pieces of the strong side.
948 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
950 // For rook endgames with strong side not having overwhelming pawn number advantage
951 // and its pawns being on one flank and weak side protecting its pieces with a king
952 // use lower scale factor.
953 else if ( pos.non_pawn_material(WHITE) == RookValueMg
954 && pos.non_pawn_material(BLACK) == RookValueMg
955 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
956 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
957 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
959 // For queen vs no queen endgames use scale factor
960 // based on number of minors of side that doesn't have queen.
961 else if (pos.count<QUEEN>() == 1)
962 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
963 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
964 // In every other case use scale factor based on
965 // the number of pawns of the strong side reduced if pawns are on a single flank.
967 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
969 // Reduce scale factor in case of pawns being on a single flank
970 sf -= 4 * !pawnsOnBothFlanks;
973 // Interpolate between the middlegame and (scaled by 'sf') endgame score
974 v = mg * int(me->game_phase())
975 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
980 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
981 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
988 // Evaluation::value() is the main function of the class. It computes the various
989 // parts of the evaluation and returns the value of the position from the point
990 // of view of the side to move.
993 Value Evaluation<T>::value() {
995 assert(!pos.checkers());
997 // Probe the material hash table
998 me = Material::probe(pos);
1000 // If we have a specialized evaluation function for the current material
1001 // configuration, call it and return.
1002 if (me->specialized_eval_exists())
1003 return me->evaluate(pos);
1005 // Initialize score by reading the incrementally updated scores included in
1006 // the position object (material + piece square tables) and the material
1007 // imbalance. Score is computed internally from the white point of view.
1008 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
1010 // Probe the pawn hash table
1011 pe = Pawns::probe(pos);
1012 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
1014 // Early exit if score is high
1015 auto lazy_skip = [&](Value lazyThreshold) {
1016 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
1019 if (lazy_skip(LazyThreshold1))
1022 // Main evaluation begins here
1023 initialize<WHITE>();
1024 initialize<BLACK>();
1026 // Pieces evaluated first (also populates attackedBy, attackedBy2).
1027 // Note that the order of evaluation of the terms is left unspecified.
1028 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
1029 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
1030 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
1031 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
1033 score += mobility[WHITE] - mobility[BLACK];
1035 // More complex interactions that require fully populated attack bitboards
1036 score += king< WHITE>() - king< BLACK>()
1037 + passed< WHITE>() - passed< BLACK>();
1039 if (lazy_skip(LazyThreshold2))
1042 score += threats<WHITE>() - threats<BLACK>()
1043 + space< WHITE>() - space< BLACK>();
1046 // Derive single value from mg and eg parts of score
1047 Value v = winnable(score);
1049 // In case of tracing add all remaining individual evaluation terms
1052 Trace::add(MATERIAL, pos.psq_score());
1053 Trace::add(IMBALANCE, me->imbalance());
1054 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1055 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1061 // Side to move point of view
1062 v = (pos.side_to_move() == WHITE ? v : -v);
1068 /// Fisher Random Chess: correction for cornered bishops, to fix chess960 play with NNUE
1070 Value fix_FRC(const Position& pos) {
1072 constexpr Bitboard Corners = 1ULL << SQ_A1 | 1ULL << SQ_H1 | 1ULL << SQ_A8 | 1ULL << SQ_H8;
1074 if (!(pos.pieces(BISHOP) & Corners))
1079 if ( pos.piece_on(SQ_A1) == W_BISHOP
1080 && pos.piece_on(SQ_B2) == W_PAWN)
1081 correction += !pos.empty(SQ_B3) ? -CorneredBishop * 4
1082 : -CorneredBishop * 3;
1084 if ( pos.piece_on(SQ_H1) == W_BISHOP
1085 && pos.piece_on(SQ_G2) == W_PAWN)
1086 correction += !pos.empty(SQ_G3) ? -CorneredBishop * 4
1087 : -CorneredBishop * 3;
1089 if ( pos.piece_on(SQ_A8) == B_BISHOP
1090 && pos.piece_on(SQ_B7) == B_PAWN)
1091 correction += !pos.empty(SQ_B6) ? CorneredBishop * 4
1092 : CorneredBishop * 3;
1094 if ( pos.piece_on(SQ_H8) == B_BISHOP
1095 && pos.piece_on(SQ_G7) == B_PAWN)
1096 correction += !pos.empty(SQ_G6) ? CorneredBishop * 4
1097 : CorneredBishop * 3;
1099 return pos.side_to_move() == WHITE ? Value(correction)
1100 : -Value(correction);
1106 /// evaluate() is the evaluator for the outer world. It returns a static
1107 /// evaluation of the position from the point of view of the side to move.
1109 Value Eval::evaluate(const Position& pos) {
1114 v = Evaluation<NO_TRACE>(pos).value();
1117 // Scale and shift NNUE for compatibility with search and classical evaluation
1118 auto adjusted_NNUE = [&]()
1121 int scale = 903 + 28 * pos.count<PAWN>() + 28 * pos.non_pawn_material() / 1024;
1123 Value nnue = NNUE::evaluate(pos, true, LazyThresholdNNUE) * scale / 1024;
1125 if (pos.is_chess960())
1126 nnue += fix_FRC(pos);
1131 // If there is PSQ imbalance we use the classical eval. We also introduce
1132 // a small probability of using the classical eval when PSQ imbalance is small.
1133 Value psq = Value(abs(eg_value(pos.psq_score())));
1134 int r50 = 16 + pos.rule50_count();
1135 bool largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50;
1136 bool classical = largePsq;
1138 // Use classical evaluation for really low piece endgames.
1139 // One critical case is the draw for bishop + A/H file pawn vs naked king.
1140 bool lowPieceEndgame = pos.non_pawn_material() == BishopValueMg
1141 || (pos.non_pawn_material() < 2 * RookValueMg && pos.count<PAWN>() < 2);
1143 v = classical || lowPieceEndgame ? Evaluation<NO_TRACE>(pos).value()
1146 // If the classical eval is small and imbalance large, use NNUE nevertheless.
1147 // For the case of opposite colored bishops, switch to NNUE eval with small
1148 // probability if the classical eval is less than the threshold.
1151 && ( abs(v) * 16 < NNUEThreshold2 * r50
1152 || ( pos.opposite_bishops()
1153 && abs(v) * 16 < (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50)))
1154 v = adjusted_NNUE();
1157 // Damp down the evaluation linearly when shuffling
1158 v = v * (100 - pos.rule50_count()) / 100;
1160 // Guarantee evaluation does not hit the tablebase range
1161 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1166 /// trace() is like evaluate(), but instead of returning a value, it returns
1167 /// a string (suitable for outputting to stdout) that contains the detailed
1168 /// descriptions and values of each evaluation term. Useful for debugging.
1169 /// Trace scores are from white's point of view
1171 std::string Eval::trace(const Position& pos) {
1174 return "Final evaluation: none (in check)";
1176 std::stringstream ss;
1177 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1181 std::memset(scores, 0, sizeof(scores));
1183 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
1185 v = Evaluation<TRACE>(pos).value();
1187 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1188 << " Term | White | Black | Total \n"
1189 << " | MG EG | MG EG | MG EG \n"
1190 << " ------------+-------------+-------------+------------\n"
1191 << " Material | " << Term(MATERIAL)
1192 << " Imbalance | " << Term(IMBALANCE)
1193 << " Pawns | " << Term(PAWN)
1194 << " Knights | " << Term(KNIGHT)
1195 << " Bishops | " << Term(BISHOP)
1196 << " Rooks | " << Term(ROOK)
1197 << " Queens | " << Term(QUEEN)
1198 << " Mobility | " << Term(MOBILITY)
1199 << " King safety | " << Term(KING)
1200 << " Threats | " << Term(THREAT)
1201 << " Passed | " << Term(PASSED)
1202 << " Space | " << Term(SPACE)
1203 << " Winnable | " << Term(WINNABLE)
1204 << " ------------+-------------+-------------+------------\n"
1205 << " Total | " << Term(TOTAL);
1207 v = pos.side_to_move() == WHITE ? v : -v;
1209 ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n";
1213 v = NNUE::evaluate(pos);
1214 v = pos.side_to_move() == WHITE ? v : -v;
1215 ss << "\nNNUE evaluation: " << to_cp(v) << " (white side)\n";
1219 v = pos.side_to_move() == WHITE ? v : -v;
1220 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";
1225 } // namespace Stockfish