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 void NNUE::export_net(const std::optional<std::string>& filename) {
118 std::string actualFilename;
119 if (filename.has_value()) {
120 actualFilename = filename.value();
122 if (eval_file_loaded != EvalFileDefaultName) {
123 sync_cout << "Failed to export a net. A non-embedded net can only be saved if the filename is specified." << sync_endl;
126 actualFilename = EvalFileDefaultName;
129 ofstream stream(actualFilename, std::ios_base::binary);
130 if (save_eval(stream)) {
131 sync_cout << "Network saved successfully to " << actualFilename << "." << sync_endl;
133 sync_cout << "Failed to export a net." << sync_endl;
137 /// NNUE::verify() verifies that the last net used was loaded successfully
138 void NNUE::verify() {
140 string eval_file = string(Options["EvalFile"]);
142 if (useNNUE && eval_file_loaded != eval_file)
144 UCI::OptionsMap defaults;
147 string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
148 string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
149 string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
150 string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + string(defaults["EvalFile"]);
151 string msg5 = "The engine will be terminated now.";
153 sync_cout << "info string ERROR: " << msg1 << sync_endl;
154 sync_cout << "info string ERROR: " << msg2 << sync_endl;
155 sync_cout << "info string ERROR: " << msg3 << sync_endl;
156 sync_cout << "info string ERROR: " << msg4 << sync_endl;
157 sync_cout << "info string ERROR: " << msg5 << sync_endl;
163 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
165 sync_cout << "info string classical evaluation enabled" << sync_endl;
171 enum Tracing { NO_TRACE, TRACE };
173 enum Term { // The first 8 entries are reserved for PieceType
174 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
177 Score scores[TERM_NB][COLOR_NB];
179 double to_cp(Value v) { return double(v) / PawnValueEg; }
181 void add(int idx, Color c, Score s) {
185 void add(int idx, Score w, Score b = SCORE_ZERO) {
186 scores[idx][WHITE] = w;
187 scores[idx][BLACK] = b;
190 std::ostream& operator<<(std::ostream& os, Score s) {
191 os << std::setw(5) << to_cp(mg_value(s)) << " "
192 << std::setw(5) << to_cp(eg_value(s));
196 std::ostream& operator<<(std::ostream& os, Term t) {
198 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
199 os << " ---- ----" << " | " << " ---- ----";
201 os << scores[t][WHITE] << " | " << scores[t][BLACK];
203 os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
208 using namespace Trace;
212 // Threshold for lazy and space evaluation
213 constexpr Value LazyThreshold1 = Value(1565);
214 constexpr Value LazyThreshold2 = Value(1102);
215 constexpr Value SpaceThreshold = Value(11551);
216 constexpr Value NNUEThreshold1 = Value(682);
217 constexpr Value NNUEThreshold2 = Value(176);
219 // KingAttackWeights[PieceType] contains king attack weights by piece type
220 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
222 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
223 // higher if multiple safe checks are possible for that piece type.
224 constexpr int SafeCheck[][2] = {
225 {}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
228 #define S(mg, eg) make_score(mg, eg)
230 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
231 // indexed by piece type and number of attacked squares in the mobility area.
232 constexpr Score MobilityBonus[][32] = {
233 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
234 S( 21, 16), S( 28, 21), S( 37, 26) },
235 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
236 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
237 S( 91, 88), S( 96, 98) },
238 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
239 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
240 S( 57,165), S( 58,170), S( 67,175) },
241 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
242 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
243 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
244 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
245 S(112,178), S(114,185), S(114,187), S(119,221) }
248 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
249 // squares of the same color as our bishop.
250 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
251 S(3, 8), S(3, 9), S(2, 8), S(3, 8)
254 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
255 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
257 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
258 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
259 constexpr Score Outpost[] = { S(57, 38), S(31, 24) };
261 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
262 constexpr Score PassedRank[RANK_NB] = {
263 S(0, 0), S(7, 27), S(16, 32), S(17, 40), S(64, 71), S(170, 174), S(278, 262)
266 constexpr Score RookOnClosedFile = S(10, 5);
267 constexpr Score RookOnOpenFile[] = { S(19, 6), S(47, 26) };
269 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
270 // which piece type attacks which one. Attacks on lesser pieces which are
271 // pawn-defended are not considered.
272 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
273 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
276 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
277 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
280 constexpr Value CorneredBishop = Value(50);
282 // Assorted bonuses and penalties
283 constexpr Score UncontestedOutpost = S( 1, 10);
284 constexpr Score BishopOnKingRing = S( 24, 0);
285 constexpr Score BishopXRayPawns = S( 4, 5);
286 constexpr Score FlankAttacks = S( 8, 0);
287 constexpr Score Hanging = S( 69, 36);
288 constexpr Score KnightOnQueen = S( 16, 11);
289 constexpr Score LongDiagonalBishop = S( 45, 0);
290 constexpr Score MinorBehindPawn = S( 18, 3);
291 constexpr Score PassedFile = S( 11, 8);
292 constexpr Score PawnlessFlank = S( 17, 95);
293 constexpr Score ReachableOutpost = S( 31, 22);
294 constexpr Score RestrictedPiece = S( 7, 7);
295 constexpr Score RookOnKingRing = S( 16, 0);
296 constexpr Score SliderOnQueen = S( 60, 18);
297 constexpr Score ThreatByKing = S( 24, 89);
298 constexpr Score ThreatByPawnPush = S( 48, 39);
299 constexpr Score ThreatBySafePawn = S(173, 94);
300 constexpr Score TrappedRook = S( 55, 13);
301 constexpr Score WeakQueenProtection = S( 14, 0);
302 constexpr Score WeakQueen = S( 56, 15);
307 // Evaluation class computes and stores attacks tables and other working data
312 Evaluation() = delete;
313 explicit Evaluation(const Position& p) : pos(p) {}
314 Evaluation& operator=(const Evaluation&) = delete;
318 template<Color Us> void initialize();
319 template<Color Us, PieceType Pt> Score pieces();
320 template<Color Us> Score king() const;
321 template<Color Us> Score threats() const;
322 template<Color Us> Score passed() const;
323 template<Color Us> Score space() const;
324 Value winnable(Score score) const;
329 Bitboard mobilityArea[COLOR_NB];
330 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
332 // attackedBy[color][piece type] is a bitboard representing all squares
333 // attacked by a given color and piece type. Special "piece types" which
334 // is also calculated is ALL_PIECES.
335 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
337 // attackedBy2[color] are the squares attacked by at least 2 units of a given
338 // color, including x-rays. But diagonal x-rays through pawns are not computed.
339 Bitboard attackedBy2[COLOR_NB];
341 // kingRing[color] are the squares adjacent to the king plus some other
342 // very near squares, depending on king position.
343 Bitboard kingRing[COLOR_NB];
345 // kingAttackersCount[color] is the number of pieces of the given color
346 // which attack a square in the kingRing of the enemy king.
347 int kingAttackersCount[COLOR_NB];
349 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
350 // the given color which attack a square in the kingRing of the enemy king.
351 // The weights of the individual piece types are given by the elements in
352 // the KingAttackWeights array.
353 int kingAttackersWeight[COLOR_NB];
355 // kingAttacksCount[color] is the number of attacks by the given color to
356 // squares directly adjacent to the enemy king. Pieces which attack more
357 // than one square are counted multiple times. For instance, if there is
358 // a white knight on g5 and black's king is on g8, this white knight adds 2
359 // to kingAttacksCount[WHITE].
360 int kingAttacksCount[COLOR_NB];
364 // Evaluation::initialize() computes king and pawn attacks, and the king ring
365 // bitboard for a given color. This is done at the beginning of the evaluation.
367 template<Tracing T> template<Color Us>
368 void Evaluation<T>::initialize() {
370 constexpr Color Them = ~Us;
371 constexpr Direction Up = pawn_push(Us);
372 constexpr Direction Down = -Up;
373 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
375 const Square ksq = pos.square<KING>(Us);
377 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
379 // Find our pawns that are blocked or on the first two ranks
380 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
382 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
383 // or controlled by enemy pawns are excluded from the mobility area.
384 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
386 // Initialize attackedBy[] for king and pawns
387 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
388 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
389 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
390 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
392 // Init our king safety tables
393 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
394 std::clamp(rank_of(ksq), RANK_2, RANK_7));
395 kingRing[Us] = attacks_bb<KING>(s) | s;
397 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
398 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
400 // Remove from kingRing[] the squares defended by two pawns
401 kingRing[Us] &= ~dblAttackByPawn;
405 // Evaluation::pieces() scores pieces of a given color and type
407 template<Tracing T> template<Color Us, PieceType Pt>
408 Score Evaluation<T>::pieces() {
410 constexpr Color Them = ~Us;
411 constexpr Direction Down = -pawn_push(Us);
412 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
413 : Rank5BB | Rank4BB | Rank3BB);
414 Bitboard b1 = pos.pieces(Us, Pt);
416 Score score = SCORE_ZERO;
418 attackedBy[Us][Pt] = 0;
422 Square s = pop_lsb(b1);
424 // Find attacked squares, including x-ray attacks for bishops and rooks
425 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
426 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
427 : attacks_bb<Pt>(s, pos.pieces());
429 if (pos.blockers_for_king(Us) & s)
430 b &= line_bb(pos.square<KING>(Us), s);
432 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
433 attackedBy[Us][Pt] |= b;
434 attackedBy[Us][ALL_PIECES] |= b;
436 if (b & kingRing[Them])
438 kingAttackersCount[Us]++;
439 kingAttackersWeight[Us] += KingAttackWeights[Pt];
440 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
443 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
444 score += RookOnKingRing;
446 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
447 score += BishopOnKingRing;
449 int mob = popcount(b & mobilityArea[Us]);
450 mobility[Us] += MobilityBonus[Pt - 2][mob];
452 if (Pt == BISHOP || Pt == KNIGHT)
454 // Bonus if the piece is on an outpost square or can reach one
455 // Bonus for knights (UncontestedOutpost) if few relevant targets
456 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
457 & ~pe->pawn_attacks_span(Them);
458 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
461 && bb & s & ~CenterFiles // on a side outpost
462 && !(b & targets) // no relevant attacks
463 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
464 score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
466 score += Outpost[Pt == BISHOP];
467 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
468 score += ReachableOutpost;
470 // Bonus for a knight or bishop shielded by pawn
471 if (shift<Down>(pos.pieces(PAWN)) & s)
472 score += MinorBehindPawn;
474 // Penalty if the piece is far from the king
475 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
477 if constexpr (Pt == BISHOP)
479 // Penalty according to the number of our pawns on the same color square as the
480 // bishop, bigger when the center files are blocked with pawns and smaller
481 // when the bishop is outside the pawn chain.
482 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
484 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
485 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
487 // Penalty for all enemy pawns x-rayed
488 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
490 // Bonus for bishop on a long diagonal which can "see" both center squares
491 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
492 score += LongDiagonalBishop;
494 // An important Chess960 pattern: a cornered bishop blocked by a friendly
495 // pawn diagonally in front of it is a very serious problem, especially
496 // when that pawn is also blocked.
497 if ( pos.is_chess960()
498 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
500 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
501 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
502 score -= !pos.empty(s + d + pawn_push(Us)) ? 4 * make_score(CorneredBishop, CorneredBishop)
503 : 3 * make_score(CorneredBishop, CorneredBishop);
508 if constexpr (Pt == ROOK)
510 // Bonuses for rook on a (semi-)open or closed file
511 if (pos.is_on_semiopen_file(Us, s))
513 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
517 // If our pawn on this file is blocked, increase penalty
518 if ( pos.pieces(Us, PAWN)
519 & shift<Down>(pos.pieces())
522 score -= RookOnClosedFile;
525 // Penalty when trapped by the king, even more if the king cannot castle
528 File kf = file_of(pos.square<KING>(Us));
529 if ((kf < FILE_E) == (file_of(s) < kf))
530 score -= TrappedRook * (1 + !pos.castling_rights(Us));
535 if constexpr (Pt == QUEEN)
537 // Penalty if any relative pin or discovered attack against the queen
538 Bitboard queenPinners;
539 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
544 Trace::add(Pt, Us, score);
550 // Evaluation::king() assigns bonuses and penalties to a king of a given color
552 template<Tracing T> template<Color Us>
553 Score Evaluation<T>::king() const {
555 constexpr Color Them = ~Us;
556 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
557 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
559 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
560 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
562 const Square ksq = pos.square<KING>(Us);
564 // Init the score with king shelter and enemy pawns storm
565 Score score = pe->king_safety<Us>(pos);
567 // Attacked squares defended at most once by our queen or king
568 weak = attackedBy[Them][ALL_PIECES]
570 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
572 // Analyse the safe enemy's checks which are possible on next move
573 safe = ~pos.pieces(Them);
574 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
576 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
577 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
579 // Enemy rooks checks
580 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
582 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
584 unsafeChecks |= b1 & attackedBy[Them][ROOK];
586 // Enemy queen safe checks: count them only if the checks are from squares from
587 // which opponent cannot give a rook check, because rook checks are more valuable.
588 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
589 & ~(attackedBy[Us][QUEEN] | rookChecks);
591 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
593 // Enemy bishops checks: count them only if they are from squares from which
594 // opponent cannot give a queen check, because queen checks are more valuable.
595 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
598 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
601 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
603 // Enemy knights checks
604 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
605 if (knightChecks & safe)
606 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
608 unsafeChecks |= knightChecks;
610 // Find the squares that opponent attacks in our king flank, the squares
611 // which they attack twice in that flank, and the squares that we defend.
612 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
613 b2 = b1 & attackedBy2[Them];
614 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
616 int kingFlankAttack = popcount(b1) + popcount(b2);
617 int kingFlankDefense = popcount(b3);
619 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
620 + 183 * popcount(kingRing[Us] & weak) // (~15 Elo)
621 + 148 * popcount(unsafeChecks) // (~4 Elo)
622 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
623 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
624 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
625 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
626 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
627 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
628 - 6 * mg_value(score) / 8 // (~8 Elo)
629 - 4 * kingFlankDefense // (~5 Elo)
632 // Transform the kingDanger units into a Score, and subtract it from the evaluation
633 if (kingDanger > 100)
634 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
636 // Penalty when our king is on a pawnless flank
637 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
638 score -= PawnlessFlank;
640 // Penalty if king flank is under attack, potentially moving toward the king
641 score -= FlankAttacks * kingFlankAttack;
644 Trace::add(KING, Us, score);
650 // Evaluation::threats() assigns bonuses according to the types of the
651 // attacking and the attacked pieces.
653 template<Tracing T> template<Color Us>
654 Score Evaluation<T>::threats() const {
656 constexpr Color Them = ~Us;
657 constexpr Direction Up = pawn_push(Us);
658 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
660 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
661 Score score = SCORE_ZERO;
664 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
666 // Squares strongly protected by the enemy, either because they defend the
667 // square with a pawn, or because they defend the square twice and we don't.
668 stronglyProtected = attackedBy[Them][PAWN]
669 | (attackedBy2[Them] & ~attackedBy2[Us]);
671 // Non-pawn enemies, strongly protected
672 defended = nonPawnEnemies & stronglyProtected;
674 // Enemies not strongly protected and under our attack
675 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
677 // Bonus according to the kind of attacking pieces
680 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
682 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(b)))];
684 b = weak & attackedBy[Us][ROOK];
686 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(b)))];
688 if (weak & attackedBy[Us][KING])
689 score += ThreatByKing;
691 b = ~attackedBy[Them][ALL_PIECES]
692 | (nonPawnEnemies & attackedBy2[Us]);
693 score += Hanging * popcount(weak & b);
695 // Additional bonus if weak piece is only protected by a queen
696 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
699 // Bonus for restricting their piece moves
700 b = attackedBy[Them][ALL_PIECES]
702 & attackedBy[Us][ALL_PIECES];
703 score += RestrictedPiece * popcount(b);
705 // Protected or unattacked squares
706 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
708 // Bonus for attacking enemy pieces with our relatively safe pawns
709 b = pos.pieces(Us, PAWN) & safe;
710 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
711 score += ThreatBySafePawn * popcount(b);
713 // Find squares where our pawns can push on the next move
714 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
715 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
717 // Keep only the squares which are relatively safe
718 b &= ~attackedBy[Them][PAWN] & safe;
720 // Bonus for safe pawn threats on the next move
721 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
722 score += ThreatByPawnPush * popcount(b);
724 // Bonus for threats on the next moves against enemy queen
725 if (pos.count<QUEEN>(Them) == 1)
727 bool queenImbalance = pos.count<QUEEN>() == 1;
729 Square s = pos.square<QUEEN>(Them);
730 safe = mobilityArea[Us]
731 & ~pos.pieces(Us, PAWN)
732 & ~stronglyProtected;
734 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
736 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
738 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
739 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
741 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
745 Trace::add(THREAT, Us, score);
750 // Evaluation::passed() evaluates the passed pawns and candidate passed
751 // pawns of the given color.
753 template<Tracing T> template<Color Us>
754 Score Evaluation<T>::passed() const {
756 constexpr Color Them = ~Us;
757 constexpr Direction Up = pawn_push(Us);
758 constexpr Direction Down = -Up;
760 auto king_proximity = [&](Color c, Square s) {
761 return std::min(distance(pos.square<KING>(c), s), 5);
764 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
765 Score score = SCORE_ZERO;
767 b = pe->passed_pawns(Us);
769 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
772 helpers = shift<Up>(pos.pieces(Us, PAWN))
774 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
776 // Remove blocked candidate passers that don't have help to pass
778 | shift<WEST>(helpers)
779 | shift<EAST>(helpers);
784 Square s = pop_lsb(b);
786 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
788 int r = relative_rank(Us, s);
790 Score bonus = PassedRank[r];
795 Square blockSq = s + Up;
797 // Adjust bonus based on the king's proximity
798 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
799 - king_proximity(Us, blockSq) * 2) * w);
801 // If blockSq is not the queening square then consider also a second push
803 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
805 // If the pawn is free to advance, then increase the bonus
806 if (pos.empty(blockSq))
808 squaresToQueen = forward_file_bb(Us, s);
809 unsafeSquares = passed_pawn_span(Us, s);
811 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
813 if (!(pos.pieces(Them) & bb))
814 unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
816 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
817 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
818 // Otherwise assign a smaller bonus if the path to queen is not attacked
819 // and even smaller bonus if it is attacked but block square is not.
820 int k = !unsafeSquares ? 36 :
821 !(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
822 !(unsafeSquares & squaresToQueen) ? 17 :
823 !(unsafeSquares & blockSq) ? 7 :
826 // Assign a larger bonus if the block square is defended
827 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
830 bonus += make_score(k * w, k * w);
834 score += bonus - PassedFile * edge_distance(file_of(s));
838 Trace::add(PASSED, Us, score);
844 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
845 // play in the opening. It is based on the number of safe squares on the four central files
846 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
847 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
849 template<Tracing T> template<Color Us>
850 Score Evaluation<T>::space() const {
852 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
853 if (pos.non_pawn_material() < SpaceThreshold)
856 constexpr Color Them = ~Us;
857 constexpr Direction Down = -pawn_push(Us);
858 constexpr Bitboard SpaceMask =
859 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
860 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
862 // Find the available squares for our pieces inside the area defined by SpaceMask
863 Bitboard safe = SpaceMask
864 & ~pos.pieces(Us, PAWN)
865 & ~attackedBy[Them][PAWN];
867 // Find all squares which are at most three squares behind some friendly pawn
868 Bitboard behind = pos.pieces(Us, PAWN);
869 behind |= shift<Down>(behind);
870 behind |= shift<Down+Down>(behind);
872 // Compute space score based on the number of safe squares and number of our pieces
873 // increased with number of total blocked pawns in position.
874 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
875 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
876 Score score = make_score(bonus * weight * weight / 16, 0);
879 Trace::add(SPACE, Us, score);
885 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
886 // the known attacking/defending status of the players. The final value is derived
887 // by interpolation from the midgame and endgame values.
890 Value Evaluation<T>::winnable(Score score) const {
892 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
893 + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
895 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
896 && (pos.pieces(PAWN) & KingSide);
898 bool almostUnwinnable = outflanking < 0
899 && !pawnsOnBothFlanks;
901 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
902 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
904 // Compute the initiative bonus for the attacking side
905 int complexity = 9 * pe->passed_count()
906 + 12 * pos.count<PAWN>()
908 + 21 * pawnsOnBothFlanks
910 + 51 * !pos.non_pawn_material()
911 - 43 * almostUnwinnable
914 Value mg = mg_value(score);
915 Value eg = eg_value(score);
917 // Now apply the bonus: note that we find the attacking side by extracting the
918 // sign of the midgame or endgame values, and that we carefully cap the bonus
919 // so that the midgame and endgame scores do not change sign after the bonus.
920 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
921 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
926 // Compute the scale factor for the winning side
927 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
928 int sf = me->scale_factor(pos, strongSide);
930 // If scale factor is not already specific, scale down via general heuristics
931 if (sf == SCALE_FACTOR_NORMAL)
933 if (pos.opposite_bishops())
935 // For pure opposite colored bishops endgames use scale factor
936 // based on the number of passed pawns of the strong side.
937 if ( pos.non_pawn_material(WHITE) == BishopValueMg
938 && pos.non_pawn_material(BLACK) == BishopValueMg)
939 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
940 // For every other opposite colored bishops endgames use scale factor
941 // based on the number of all pieces of the strong side.
943 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
945 // For rook endgames with strong side not having overwhelming pawn number advantage
946 // and its pawns being on one flank and weak side protecting its pieces with a king
947 // use lower scale factor.
948 else if ( pos.non_pawn_material(WHITE) == RookValueMg
949 && pos.non_pawn_material(BLACK) == RookValueMg
950 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
951 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
952 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
954 // For queen vs no queen endgames use scale factor
955 // based on number of minors of side that doesn't have queen.
956 else if (pos.count<QUEEN>() == 1)
957 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
958 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
959 // In every other case use scale factor based on
960 // the number of pawns of the strong side reduced if pawns are on a single flank.
962 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
964 // Reduce scale factor in case of pawns being on a single flank
965 sf -= 4 * !pawnsOnBothFlanks;
968 // Interpolate between the middlegame and (scaled by 'sf') endgame score
969 v = mg * int(me->game_phase())
970 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
975 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
976 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
983 // Evaluation::value() is the main function of the class. It computes the various
984 // parts of the evaluation and returns the value of the position from the point
985 // of view of the side to move.
988 Value Evaluation<T>::value() {
990 assert(!pos.checkers());
992 // Probe the material hash table
993 me = Material::probe(pos);
995 // If we have a specialized evaluation function for the current material
996 // configuration, call it and return.
997 if (me->specialized_eval_exists())
998 return me->evaluate(pos);
1000 // Initialize score by reading the incrementally updated scores included in
1001 // the position object (material + piece square tables) and the material
1002 // imbalance. Score is computed internally from the white point of view.
1003 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
1005 // Probe the pawn hash table
1006 pe = Pawns::probe(pos);
1007 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
1009 // Early exit if score is high
1010 auto lazy_skip = [&](Value lazyThreshold) {
1011 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
1014 if (lazy_skip(LazyThreshold1))
1017 // Main evaluation begins here
1018 initialize<WHITE>();
1019 initialize<BLACK>();
1021 // Pieces evaluated first (also populates attackedBy, attackedBy2).
1022 // Note that the order of evaluation of the terms is left unspecified.
1023 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
1024 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
1025 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
1026 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
1028 score += mobility[WHITE] - mobility[BLACK];
1030 // More complex interactions that require fully populated attack bitboards
1031 score += king< WHITE>() - king< BLACK>()
1032 + passed< WHITE>() - passed< BLACK>();
1034 if (lazy_skip(LazyThreshold2))
1037 score += threats<WHITE>() - threats<BLACK>()
1038 + space< WHITE>() - space< BLACK>();
1041 // Derive single value from mg and eg parts of score
1042 Value v = winnable(score);
1044 // In case of tracing add all remaining individual evaluation terms
1047 Trace::add(MATERIAL, pos.psq_score());
1048 Trace::add(IMBALANCE, me->imbalance());
1049 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1050 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1056 // Side to move point of view
1057 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
1063 /// Fisher Random Chess: correction for cornered bishops, to fix chess960 play with NNUE
1065 Value fix_FRC(const Position& pos) {
1067 constexpr Bitboard Corners = 1ULL << SQ_A1 | 1ULL << SQ_H1 | 1ULL << SQ_A8 | 1ULL << SQ_H8;
1069 if (!(pos.pieces(BISHOP) & Corners))
1074 if ( pos.piece_on(SQ_A1) == W_BISHOP
1075 && pos.piece_on(SQ_B2) == W_PAWN)
1076 correction += !pos.empty(SQ_B3) ? -CorneredBishop * 4
1077 : -CorneredBishop * 3;
1079 if ( pos.piece_on(SQ_H1) == W_BISHOP
1080 && pos.piece_on(SQ_G2) == W_PAWN)
1081 correction += !pos.empty(SQ_G3) ? -CorneredBishop * 4
1082 : -CorneredBishop * 3;
1084 if ( pos.piece_on(SQ_A8) == B_BISHOP
1085 && pos.piece_on(SQ_B7) == B_PAWN)
1086 correction += !pos.empty(SQ_B6) ? CorneredBishop * 4
1087 : CorneredBishop * 3;
1089 if ( pos.piece_on(SQ_H8) == B_BISHOP
1090 && pos.piece_on(SQ_G7) == B_PAWN)
1091 correction += !pos.empty(SQ_G6) ? CorneredBishop * 4
1092 : CorneredBishop * 3;
1094 return pos.side_to_move() == WHITE ? Value(correction)
1095 : -Value(correction);
1101 /// evaluate() is the evaluator for the outer world. It returns a static
1102 /// evaluation of the position from the point of view of the side to move.
1104 Value Eval::evaluate(const Position& pos) {
1109 v = Evaluation<NO_TRACE>(pos).value();
1112 // Scale and shift NNUE for compatibility with search and classical evaluation
1113 auto adjusted_NNUE = [&]()
1115 int material = pos.non_pawn_material() + 4 * PawnValueMg * pos.count<PAWN>();
1118 - 4 * pos.rule50_count();
1120 Value nnue = NNUE::evaluate(pos) * scale / 1024 + Time.tempoNNUE;
1122 if (pos.is_chess960())
1123 nnue += fix_FRC(pos);
1128 // If there is PSQ imbalance we use the classical eval. We also introduce
1129 // a small probability of using the classical eval when PSQ imbalance is small.
1130 Value psq = Value(abs(eg_value(pos.psq_score())));
1131 int r50 = 16 + pos.rule50_count();
1132 bool largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50;
1133 bool classical = largePsq || (psq > PawnValueMg / 4 && !(pos.this_thread()->nodes & 0xB));
1135 // Use classical evaluation for really low piece endgames.
1136 // One critical case is the draw for bishop + A/H file pawn vs naked king.
1137 bool lowPieceEndgame = pos.non_pawn_material() == BishopValueMg
1138 || (pos.non_pawn_material() < 2 * RookValueMg && pos.count<PAWN>() < 2);
1140 v = classical || lowPieceEndgame ? Evaluation<NO_TRACE>(pos).value()
1143 // If the classical eval is small and imbalance large, use NNUE nevertheless.
1144 // For the case of opposite colored bishops, switch to NNUE eval with small
1145 // probability if the classical eval is less than the threshold.
1148 && ( abs(v) * 16 < NNUEThreshold2 * r50
1149 || ( pos.opposite_bishops()
1150 && abs(v) * 16 < (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50
1151 && !(pos.this_thread()->nodes & 0xB))))
1152 v = adjusted_NNUE();
1155 // Damp down the evaluation linearly when shuffling
1156 v = v * (100 - pos.rule50_count()) / 100;
1158 // Guarantee evaluation does not hit the tablebase range
1159 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1164 /// trace() is like evaluate(), but instead of returning a value, it returns
1165 /// a string (suitable for outputting to stdout) that contains the detailed
1166 /// descriptions and values of each evaluation term. Useful for debugging.
1167 /// Trace scores are from white's point of view
1169 std::string Eval::trace(const Position& pos) {
1172 return "Final evaluation: none (in check)";
1174 std::stringstream ss;
1175 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1179 std::memset(scores, 0, sizeof(scores));
1181 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
1183 v = Evaluation<TRACE>(pos).value();
1185 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1186 << " Term | White | Black | Total \n"
1187 << " | MG EG | MG EG | MG EG \n"
1188 << " ------------+-------------+-------------+------------\n"
1189 << " Material | " << Term(MATERIAL)
1190 << " Imbalance | " << Term(IMBALANCE)
1191 << " Pawns | " << Term(PAWN)
1192 << " Knights | " << Term(KNIGHT)
1193 << " Bishops | " << Term(BISHOP)
1194 << " Rooks | " << Term(ROOK)
1195 << " Queens | " << Term(QUEEN)
1196 << " Mobility | " << Term(MOBILITY)
1197 << " King safety | " << Term(KING)
1198 << " Threats | " << Term(THREAT)
1199 << " Passed | " << Term(PASSED)
1200 << " Space | " << Term(SPACE)
1201 << " Winnable | " << Term(WINNABLE)
1202 << " ------------+-------------+-------------+------------\n"
1203 << " Total | " << Term(TOTAL);
1205 v = pos.side_to_move() == WHITE ? v : -v;
1207 ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n";
1211 v = NNUE::evaluate(pos);
1212 v = pos.side_to_move() == WHITE ? v : -v;
1213 ss << "\nNNUE evaluation: " << to_cp(v) << " (white side)\n";
1217 v = pos.side_to_move() == WHITE ? v : -v;
1218 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";
1223 } // namespace Stockfish