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 SpaceThreshold = Value(11551);
220 constexpr Value NNUEThreshold1 = Value(800);
222 // KingAttackWeights[PieceType] contains king attack weights by piece type
223 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
225 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
226 // higher if multiple safe checks are possible for that piece type.
227 constexpr int SafeCheck[][2] = {
228 {}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
231 #define S(mg, eg) make_score(mg, eg)
233 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
234 // indexed by piece type and number of attacked squares in the mobility area.
235 constexpr Score MobilityBonus[][32] = {
236 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
237 S( 21, 16), S( 28, 21), S( 37, 26) },
238 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
239 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
240 S( 91, 88), S( 96, 98) },
241 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
242 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
243 S( 57,165), S( 58,170), S( 67,175) },
244 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
245 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
246 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
247 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
248 S(112,178), S(114,185), S(114,187), S(119,221) }
251 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
252 // squares of the same color as our bishop.
253 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
254 S(3, 8), S(3, 9), S(2, 8), S(3, 8)
257 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
258 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
260 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
261 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
262 constexpr Score Outpost[] = { S(57, 38), S(31, 24) };
264 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
265 constexpr Score PassedRank[RANK_NB] = {
266 S(0, 0), S(7, 27), S(16, 32), S(17, 40), S(64, 71), S(170, 174), S(278, 262)
269 constexpr Score RookOnClosedFile = S(10, 5);
270 constexpr Score RookOnOpenFile[] = { S(19, 6), S(47, 26) };
272 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
273 // which piece type attacks which one. Attacks on lesser pieces which are
274 // pawn-defended are not considered.
275 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
276 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
279 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
280 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
283 constexpr Value CorneredBishop = Value(50);
285 // Assorted bonuses and penalties
286 constexpr Score UncontestedOutpost = S( 1, 10);
287 constexpr Score BishopOnKingRing = S( 24, 0);
288 constexpr Score BishopXRayPawns = S( 4, 5);
289 constexpr Score FlankAttacks = S( 8, 0);
290 constexpr Score Hanging = S( 69, 36);
291 constexpr Score KnightOnQueen = S( 16, 11);
292 constexpr Score LongDiagonalBishop = S( 45, 0);
293 constexpr Score MinorBehindPawn = S( 18, 3);
294 constexpr Score PassedFile = S( 11, 8);
295 constexpr Score PawnlessFlank = S( 17, 95);
296 constexpr Score ReachableOutpost = S( 31, 22);
297 constexpr Score RestrictedPiece = S( 7, 7);
298 constexpr Score RookOnKingRing = S( 16, 0);
299 constexpr Score SliderOnQueen = S( 60, 18);
300 constexpr Score ThreatByKing = S( 24, 89);
301 constexpr Score ThreatByPawnPush = S( 48, 39);
302 constexpr Score ThreatBySafePawn = S(173, 94);
303 constexpr Score TrappedRook = S( 55, 13);
304 constexpr Score WeakQueenProtection = S( 14, 0);
305 constexpr Score WeakQueen = S( 56, 15);
310 // Evaluation class computes and stores attacks tables and other working data
315 Evaluation() = delete;
316 explicit Evaluation(const Position& p) : pos(p) {}
317 Evaluation& operator=(const Evaluation&) = delete;
321 template<Color Us> void initialize();
322 template<Color Us, PieceType Pt> Score pieces();
323 template<Color Us> Score king() const;
324 template<Color Us> Score threats() const;
325 template<Color Us> Score passed() const;
326 template<Color Us> Score space() const;
327 Value winnable(Score score) const;
332 Bitboard mobilityArea[COLOR_NB];
333 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
335 // attackedBy[color][piece type] is a bitboard representing all squares
336 // attacked by a given color and piece type. Special "piece types" which
337 // is also calculated is ALL_PIECES.
338 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
340 // attackedBy2[color] are the squares attacked by at least 2 units of a given
341 // color, including x-rays. But diagonal x-rays through pawns are not computed.
342 Bitboard attackedBy2[COLOR_NB];
344 // kingRing[color] are the squares adjacent to the king plus some other
345 // very near squares, depending on king position.
346 Bitboard kingRing[COLOR_NB];
348 // kingAttackersCount[color] is the number of pieces of the given color
349 // which attack a square in the kingRing of the enemy king.
350 int kingAttackersCount[COLOR_NB];
352 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
353 // the given color which attack a square in the kingRing of the enemy king.
354 // The weights of the individual piece types are given by the elements in
355 // the KingAttackWeights array.
356 int kingAttackersWeight[COLOR_NB];
358 // kingAttacksCount[color] is the number of attacks by the given color to
359 // squares directly adjacent to the enemy king. Pieces which attack more
360 // than one square are counted multiple times. For instance, if there is
361 // a white knight on g5 and black's king is on g8, this white knight adds 2
362 // to kingAttacksCount[WHITE].
363 int kingAttacksCount[COLOR_NB];
367 // Evaluation::initialize() computes king and pawn attacks, and the king ring
368 // bitboard for a given color. This is done at the beginning of the evaluation.
370 template<Tracing T> template<Color Us>
371 void Evaluation<T>::initialize() {
373 constexpr Color Them = ~Us;
374 constexpr Direction Up = pawn_push(Us);
375 constexpr Direction Down = -Up;
376 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
378 const Square ksq = pos.square<KING>(Us);
380 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
382 // Find our pawns that are blocked or on the first two ranks
383 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
385 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
386 // or controlled by enemy pawns are excluded from the mobility area.
387 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
389 // Initialize attackedBy[] for king and pawns
390 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
391 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
392 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
393 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
395 // Init our king safety tables
396 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
397 std::clamp(rank_of(ksq), RANK_2, RANK_7));
398 kingRing[Us] = attacks_bb<KING>(s) | s;
400 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
401 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
403 // Remove from kingRing[] the squares defended by two pawns
404 kingRing[Us] &= ~dblAttackByPawn;
408 // Evaluation::pieces() scores pieces of a given color and type
410 template<Tracing T> template<Color Us, PieceType Pt>
411 Score Evaluation<T>::pieces() {
413 constexpr Color Them = ~Us;
414 constexpr Direction Down = -pawn_push(Us);
415 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
416 : Rank5BB | Rank4BB | Rank3BB);
417 Bitboard b1 = pos.pieces(Us, Pt);
419 Score score = SCORE_ZERO;
421 attackedBy[Us][Pt] = 0;
425 Square s = pop_lsb(b1);
427 // Find attacked squares, including x-ray attacks for bishops and rooks
428 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
429 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
430 : attacks_bb<Pt>(s, pos.pieces());
432 if (pos.blockers_for_king(Us) & s)
433 b &= line_bb(pos.square<KING>(Us), s);
435 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
436 attackedBy[Us][Pt] |= b;
437 attackedBy[Us][ALL_PIECES] |= b;
439 if (b & kingRing[Them])
441 kingAttackersCount[Us]++;
442 kingAttackersWeight[Us] += KingAttackWeights[Pt];
443 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
446 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
447 score += RookOnKingRing;
449 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
450 score += BishopOnKingRing;
452 int mob = popcount(b & mobilityArea[Us]);
453 mobility[Us] += MobilityBonus[Pt - 2][mob];
455 if (Pt == BISHOP || Pt == KNIGHT)
457 // Bonus if the piece is on an outpost square or can reach one
458 // Bonus for knights (UncontestedOutpost) if few relevant targets
459 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
460 & ~pe->pawn_attacks_span(Them);
461 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
464 && bb & s & ~CenterFiles // on a side outpost
465 && !(b & targets) // no relevant attacks
466 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
467 score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
469 score += Outpost[Pt == BISHOP];
470 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
471 score += ReachableOutpost;
473 // Bonus for a knight or bishop shielded by pawn
474 if (shift<Down>(pos.pieces(PAWN)) & s)
475 score += MinorBehindPawn;
477 // Penalty if the piece is far from the king
478 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
480 if constexpr (Pt == BISHOP)
482 // Penalty according to the number of our pawns on the same color square as the
483 // bishop, bigger when the center files are blocked with pawns and smaller
484 // when the bishop is outside the pawn chain.
485 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
487 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
488 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
490 // Penalty for all enemy pawns x-rayed
491 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
493 // Bonus for bishop on a long diagonal which can "see" both center squares
494 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
495 score += LongDiagonalBishop;
497 // An important Chess960 pattern: a cornered bishop blocked by a friendly
498 // pawn diagonally in front of it is a very serious problem, especially
499 // when that pawn is also blocked.
500 if ( pos.is_chess960()
501 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
503 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
504 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
505 score -= !pos.empty(s + d + pawn_push(Us)) ? 4 * make_score(CorneredBishop, CorneredBishop)
506 : 3 * make_score(CorneredBishop, CorneredBishop);
511 if constexpr (Pt == ROOK)
513 // Bonuses for rook on a (semi-)open or closed file
514 if (pos.is_on_semiopen_file(Us, s))
516 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
520 // If our pawn on this file is blocked, increase penalty
521 if ( pos.pieces(Us, PAWN)
522 & shift<Down>(pos.pieces())
525 score -= RookOnClosedFile;
528 // Penalty when trapped by the king, even more if the king cannot castle
531 File kf = file_of(pos.square<KING>(Us));
532 if ((kf < FILE_E) == (file_of(s) < kf))
533 score -= TrappedRook * (1 + !pos.castling_rights(Us));
538 if constexpr (Pt == QUEEN)
540 // Penalty if any relative pin or discovered attack against the queen
541 Bitboard queenPinners;
542 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
547 Trace::add(Pt, Us, score);
553 // Evaluation::king() assigns bonuses and penalties to a king of a given color
555 template<Tracing T> template<Color Us>
556 Score Evaluation<T>::king() const {
558 constexpr Color Them = ~Us;
559 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
560 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
562 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
563 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
565 const Square ksq = pos.square<KING>(Us);
567 // Init the score with king shelter and enemy pawns storm
568 Score score = pe->king_safety<Us>(pos);
570 // Attacked squares defended at most once by our queen or king
571 weak = attackedBy[Them][ALL_PIECES]
573 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
575 // Analyse the safe enemy's checks which are possible on next move
576 safe = ~pos.pieces(Them);
577 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
579 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
580 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
582 // Enemy rooks checks
583 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
585 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
587 unsafeChecks |= b1 & attackedBy[Them][ROOK];
589 // Enemy queen safe checks: count them only if the checks are from squares from
590 // which opponent cannot give a rook check, because rook checks are more valuable.
591 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
592 & ~(attackedBy[Us][QUEEN] | rookChecks);
594 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
596 // Enemy bishops checks: count them only if they are from squares from which
597 // opponent cannot give a queen check, because queen checks are more valuable.
598 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
601 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
604 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
606 // Enemy knights checks
607 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
608 if (knightChecks & safe)
609 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
611 unsafeChecks |= knightChecks;
613 // Find the squares that opponent attacks in our king flank, the squares
614 // which they attack twice in that flank, and the squares that we defend.
615 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
616 b2 = b1 & attackedBy2[Them];
617 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
619 int kingFlankAttack = popcount(b1) + popcount(b2);
620 int kingFlankDefense = popcount(b3);
622 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
623 + 183 * popcount(kingRing[Us] & weak) // (~15 Elo)
624 + 148 * popcount(unsafeChecks) // (~4 Elo)
625 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
626 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
627 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
628 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
629 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
630 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
631 - 6 * mg_value(score) / 8 // (~8 Elo)
632 - 4 * kingFlankDefense // (~5 Elo)
635 // Transform the kingDanger units into a Score, and subtract it from the evaluation
636 if (kingDanger > 100)
637 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
639 // Penalty when our king is on a pawnless flank
640 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
641 score -= PawnlessFlank;
643 // Penalty if king flank is under attack, potentially moving toward the king
644 score -= FlankAttacks * kingFlankAttack;
647 Trace::add(KING, Us, score);
653 // Evaluation::threats() assigns bonuses according to the types of the
654 // attacking and the attacked pieces.
656 template<Tracing T> template<Color Us>
657 Score Evaluation<T>::threats() const {
659 constexpr Color Them = ~Us;
660 constexpr Direction Up = pawn_push(Us);
661 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
663 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
664 Score score = SCORE_ZERO;
667 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
669 // Squares strongly protected by the enemy, either because they defend the
670 // square with a pawn, or because they defend the square twice and we don't.
671 stronglyProtected = attackedBy[Them][PAWN]
672 | (attackedBy2[Them] & ~attackedBy2[Us]);
674 // Non-pawn enemies, strongly protected
675 defended = nonPawnEnemies & stronglyProtected;
677 // Enemies not strongly protected and under our attack
678 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
680 // Bonus according to the kind of attacking pieces
683 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
685 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(b)))];
687 b = weak & attackedBy[Us][ROOK];
689 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(b)))];
691 if (weak & attackedBy[Us][KING])
692 score += ThreatByKing;
694 b = ~attackedBy[Them][ALL_PIECES]
695 | (nonPawnEnemies & attackedBy2[Us]);
696 score += Hanging * popcount(weak & b);
698 // Additional bonus if weak piece is only protected by a queen
699 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
702 // Bonus for restricting their piece moves
703 b = attackedBy[Them][ALL_PIECES]
705 & attackedBy[Us][ALL_PIECES];
706 score += RestrictedPiece * popcount(b);
708 // Protected or unattacked squares
709 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
711 // Bonus for attacking enemy pieces with our relatively safe pawns
712 b = pos.pieces(Us, PAWN) & safe;
713 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
714 score += ThreatBySafePawn * popcount(b);
716 // Find squares where our pawns can push on the next move
717 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
718 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
720 // Keep only the squares which are relatively safe
721 b &= ~attackedBy[Them][PAWN] & safe;
723 // Bonus for safe pawn threats on the next move
724 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
725 score += ThreatByPawnPush * popcount(b);
727 // Bonus for threats on the next moves against enemy queen
728 if (pos.count<QUEEN>(Them) == 1)
730 bool queenImbalance = pos.count<QUEEN>() == 1;
732 Square s = pos.square<QUEEN>(Them);
733 safe = mobilityArea[Us]
734 & ~pos.pieces(Us, PAWN)
735 & ~stronglyProtected;
737 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
739 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
741 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
742 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
744 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
748 Trace::add(THREAT, Us, score);
753 // Evaluation::passed() evaluates the passed pawns and candidate passed
754 // pawns of the given color.
756 template<Tracing T> template<Color Us>
757 Score Evaluation<T>::passed() const {
759 constexpr Color Them = ~Us;
760 constexpr Direction Up = pawn_push(Us);
761 constexpr Direction Down = -Up;
763 auto king_proximity = [&](Color c, Square s) {
764 return std::min(distance(pos.square<KING>(c), s), 5);
767 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
768 Score score = SCORE_ZERO;
770 b = pe->passed_pawns(Us);
772 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
775 helpers = shift<Up>(pos.pieces(Us, PAWN))
777 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
779 // Remove blocked candidate passers that don't have help to pass
781 | shift<WEST>(helpers)
782 | shift<EAST>(helpers);
787 Square s = pop_lsb(b);
789 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
791 int r = relative_rank(Us, s);
793 Score bonus = PassedRank[r];
798 Square blockSq = s + Up;
800 // Adjust bonus based on the king's proximity
801 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
802 - king_proximity(Us, blockSq) * 2) * w);
804 // If blockSq is not the queening square then consider also a second push
806 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
808 // If the pawn is free to advance, then increase the bonus
809 if (pos.empty(blockSq))
811 squaresToQueen = forward_file_bb(Us, s);
812 unsafeSquares = passed_pawn_span(Us, s);
814 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
816 if (!(pos.pieces(Them) & bb))
817 unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
819 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
820 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
821 // Otherwise assign a smaller bonus if the path to queen is not attacked
822 // and even smaller bonus if it is attacked but block square is not.
823 int k = !unsafeSquares ? 36 :
824 !(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
825 !(unsafeSquares & squaresToQueen) ? 17 :
826 !(unsafeSquares & blockSq) ? 7 :
829 // Assign a larger bonus if the block square is defended
830 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
833 bonus += make_score(k * w, k * w);
837 score += bonus - PassedFile * edge_distance(file_of(s));
841 Trace::add(PASSED, Us, score);
847 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
848 // play in the opening. It is based on the number of safe squares on the four central files
849 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
850 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
852 template<Tracing T> template<Color Us>
853 Score Evaluation<T>::space() const {
855 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
856 if (pos.non_pawn_material() < SpaceThreshold)
859 constexpr Color Them = ~Us;
860 constexpr Direction Down = -pawn_push(Us);
861 constexpr Bitboard SpaceMask =
862 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
863 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
865 // Find the available squares for our pieces inside the area defined by SpaceMask
866 Bitboard safe = SpaceMask
867 & ~pos.pieces(Us, PAWN)
868 & ~attackedBy[Them][PAWN];
870 // Find all squares which are at most three squares behind some friendly pawn
871 Bitboard behind = pos.pieces(Us, PAWN);
872 behind |= shift<Down>(behind);
873 behind |= shift<Down+Down>(behind);
875 // Compute space score based on the number of safe squares and number of our pieces
876 // increased with number of total blocked pawns in position.
877 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
878 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
879 Score score = make_score(bonus * weight * weight / 16, 0);
882 Trace::add(SPACE, Us, score);
888 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
889 // the known attacking/defending status of the players. The final value is derived
890 // by interpolation from the midgame and endgame values.
893 Value Evaluation<T>::winnable(Score score) const {
895 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
896 + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
898 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
899 && (pos.pieces(PAWN) & KingSide);
901 bool almostUnwinnable = outflanking < 0
902 && !pawnsOnBothFlanks;
904 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
905 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
907 // Compute the initiative bonus for the attacking side
908 int complexity = 9 * pe->passed_count()
909 + 12 * pos.count<PAWN>()
911 + 21 * pawnsOnBothFlanks
913 + 51 * !pos.non_pawn_material()
914 - 43 * almostUnwinnable
917 Value mg = mg_value(score);
918 Value eg = eg_value(score);
920 // Now apply the bonus: note that we find the attacking side by extracting the
921 // sign of the midgame or endgame values, and that we carefully cap the bonus
922 // so that the midgame and endgame scores do not change sign after the bonus.
923 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
924 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
929 // Compute the scale factor for the winning side
930 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
931 int sf = me->scale_factor(pos, strongSide);
933 // If scale factor is not already specific, scale up/down via general heuristics
934 if (sf == SCALE_FACTOR_NORMAL)
936 if (pos.opposite_bishops())
938 // For pure opposite colored bishops endgames use scale factor
939 // based on the number of passed pawns of the strong side.
940 if ( pos.non_pawn_material(WHITE) == BishopValueMg
941 && pos.non_pawn_material(BLACK) == BishopValueMg)
942 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
943 // For every other opposite colored bishops endgames use scale factor
944 // based on the number of all pieces of the strong side.
946 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
948 // For rook endgames with strong side not having overwhelming pawn number advantage
949 // and its pawns being on one flank and weak side protecting its pieces with a king
950 // use lower scale factor.
951 else if ( pos.non_pawn_material(WHITE) == RookValueMg
952 && pos.non_pawn_material(BLACK) == RookValueMg
953 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
954 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
955 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
957 // For queen vs no queen endgames use scale factor
958 // based on number of minors of side that doesn't have queen.
959 else if (pos.count<QUEEN>() == 1)
960 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
961 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
962 // In every other case use scale factor based on
963 // the number of pawns of the strong side reduced if pawns are on a single flank.
965 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
967 // Reduce scale factor in case of pawns being on a single flank
968 sf -= 4 * !pawnsOnBothFlanks;
971 // Interpolate between the middlegame and (scaled by 'sf') endgame score
972 v = mg * int(me->game_phase())
973 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
978 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
979 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
986 // Evaluation::value() is the main function of the class. It computes the various
987 // parts of the evaluation and returns the value of the position from the point
988 // of view of the side to move.
991 Value Evaluation<T>::value() {
993 assert(!pos.checkers());
995 // Probe the material hash table
996 me = Material::probe(pos);
998 // If we have a specialized evaluation function for the current material
999 // configuration, call it and return.
1000 if (me->specialized_eval_exists())
1001 return me->evaluate(pos);
1003 // Initialize score by reading the incrementally updated scores included in
1004 // the position object (material + piece square tables) and the material
1005 // imbalance. Score is computed internally from the white point of view.
1006 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
1008 // Probe the pawn hash table
1009 pe = Pawns::probe(pos);
1010 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
1012 // Early exit if score is high
1013 auto lazy_skip = [&](Value lazyThreshold) {
1014 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
1017 if (lazy_skip(LazyThreshold1))
1020 // Main evaluation begins here
1021 initialize<WHITE>();
1022 initialize<BLACK>();
1024 // Pieces evaluated first (also populates attackedBy, attackedBy2).
1025 // Note that the order of evaluation of the terms is left unspecified.
1026 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
1027 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
1028 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
1029 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
1031 score += mobility[WHITE] - mobility[BLACK];
1033 // More complex interactions that require fully populated attack bitboards
1034 score += king< WHITE>() - king< BLACK>()
1035 + passed< WHITE>() - passed< BLACK>();
1037 if (lazy_skip(LazyThreshold2))
1040 score += threats<WHITE>() - threats<BLACK>()
1041 + space< WHITE>() - space< BLACK>();
1044 // Derive single value from mg and eg parts of score
1045 Value v = winnable(score);
1047 // In case of tracing add all remaining individual evaluation terms
1050 Trace::add(MATERIAL, pos.psq_score());
1051 Trace::add(IMBALANCE, me->imbalance());
1052 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1053 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1059 // Side to move point of view
1060 v = (pos.side_to_move() == WHITE ? v : -v);
1066 /// Fisher Random Chess: correction for cornered bishops, to fix chess960 play with NNUE
1068 Value fix_FRC(const Position& pos) {
1070 constexpr Bitboard Corners = 1ULL << SQ_A1 | 1ULL << SQ_H1 | 1ULL << SQ_A8 | 1ULL << SQ_H8;
1072 if (!(pos.pieces(BISHOP) & Corners))
1077 if ( pos.piece_on(SQ_A1) == W_BISHOP
1078 && pos.piece_on(SQ_B2) == W_PAWN)
1079 correction += !pos.empty(SQ_B3) ? -CorneredBishop * 4
1080 : -CorneredBishop * 3;
1082 if ( pos.piece_on(SQ_H1) == W_BISHOP
1083 && pos.piece_on(SQ_G2) == W_PAWN)
1084 correction += !pos.empty(SQ_G3) ? -CorneredBishop * 4
1085 : -CorneredBishop * 3;
1087 if ( pos.piece_on(SQ_A8) == B_BISHOP
1088 && pos.piece_on(SQ_B7) == B_PAWN)
1089 correction += !pos.empty(SQ_B6) ? CorneredBishop * 4
1090 : CorneredBishop * 3;
1092 if ( pos.piece_on(SQ_H8) == B_BISHOP
1093 && pos.piece_on(SQ_G7) == B_PAWN)
1094 correction += !pos.empty(SQ_G6) ? CorneredBishop * 4
1095 : CorneredBishop * 3;
1097 return pos.side_to_move() == WHITE ? Value(correction)
1098 : -Value(correction);
1104 /// evaluate() is the evaluator for the outer world. It returns a static
1105 /// evaluation of the position from the point of view of the side to move.
1107 Value Eval::evaluate(const Position& pos) {
1112 v = Evaluation<NO_TRACE>(pos).value();
1115 // Scale and shift NNUE for compatibility with search and classical evaluation
1116 auto adjusted_NNUE = [&]()
1119 int scale = 903 + 28 * pos.count<PAWN>() + 28 * pos.non_pawn_material() / 1024;
1121 Value nnue = NNUE::evaluate(pos, true) * scale / 1024;
1123 if (pos.is_chess960())
1124 nnue += fix_FRC(pos);
1129 // If there is PSQ imbalance we use the classical eval.
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;
1134 v = largePsq ? Evaluation<NO_TRACE>(pos).value() // classical
1135 : adjusted_NNUE(); // NNUE
1139 // Damp down the evaluation linearly when shuffling
1140 v = v * (100 - pos.rule50_count()) / 100;
1142 // Guarantee evaluation does not hit the tablebase range
1143 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1148 /// trace() is like evaluate(), but instead of returning a value, it returns
1149 /// a string (suitable for outputting to stdout) that contains the detailed
1150 /// descriptions and values of each evaluation term. Useful for debugging.
1151 /// Trace scores are from white's point of view
1153 std::string Eval::trace(const Position& pos) {
1156 return "Final evaluation: none (in check)";
1158 std::stringstream ss;
1159 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1163 std::memset(scores, 0, sizeof(scores));
1165 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
1167 v = Evaluation<TRACE>(pos).value();
1169 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1170 << " Term | White | Black | Total \n"
1171 << " | MG EG | MG EG | MG EG \n"
1172 << " ------------+-------------+-------------+------------\n"
1173 << " Material | " << Term(MATERIAL)
1174 << " Imbalance | " << Term(IMBALANCE)
1175 << " Pawns | " << Term(PAWN)
1176 << " Knights | " << Term(KNIGHT)
1177 << " Bishops | " << Term(BISHOP)
1178 << " Rooks | " << Term(ROOK)
1179 << " Queens | " << Term(QUEEN)
1180 << " Mobility | " << Term(MOBILITY)
1181 << " King safety | " << Term(KING)
1182 << " Threats | " << Term(THREAT)
1183 << " Passed | " << Term(PASSED)
1184 << " Space | " << Term(SPACE)
1185 << " Winnable | " << Term(WINNABLE)
1186 << " ------------+-------------+-------------+------------\n"
1187 << " Total | " << Term(TOTAL);
1189 v = pos.side_to_move() == WHITE ? v : -v;
1191 ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n";
1195 v = NNUE::evaluate(pos);
1196 v = pos.side_to_move() == WHITE ? v : -v;
1197 ss << "\nNNUE evaluation: " << to_cp(v) << " (white side)\n";
1201 v = pos.side_to_move() == WHITE ? v : -v;
1202 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";
1207 } // namespace Stockfish