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
39 #include "incbin/incbin.h"
42 // Macro to embed the default efficiently updatable neural network (NNUE) file
43 // data in the engine binary (using incbin.h, by Dale Weiler).
44 // This macro invocation will declare the following three variables
45 // const unsigned char gEmbeddedNNUEData[]; // a pointer to the embedded data
46 // const unsigned char *const gEmbeddedNNUEEnd; // a marker to the end
47 // const unsigned int gEmbeddedNNUESize; // the size of the embedded file
48 // Note that this does not work in Microsoft Visual Studio.
49 #if !defined(_MSC_VER) && !defined(NNUE_EMBEDDING_OFF)
50 INCBIN(EmbeddedNNUE, EvalFileDefaultName);
52 const unsigned char gEmbeddedNNUEData[1] = {0x0};
53 const unsigned char *const gEmbeddedNNUEEnd = &gEmbeddedNNUEData[1];
54 const unsigned int gEmbeddedNNUESize = 1;
65 string currentEvalFileName = "None";
67 /// NNUE::init() tries to load a NNUE network at startup time, or when the engine
68 /// receives a UCI command "setoption name EvalFile value nn-[a-z0-9]{12}.nnue"
69 /// The name of the NNUE network is always retrieved from the EvalFile option.
70 /// We search the given network in three locations: internally (the default
71 /// network may be embedded in the binary), in the active working directory and
72 /// in the engine directory. Distro packagers may define the DEFAULT_NNUE_DIRECTORY
73 /// variable to have the engine search in a special directory in their distro.
77 useNNUE = Options["Use NNUE"];
81 string eval_file = string(Options["EvalFile"]);
82 if (eval_file.empty())
83 eval_file = EvalFileDefaultName;
85 #if defined(DEFAULT_NNUE_DIRECTORY)
86 #define stringify2(x) #x
87 #define stringify(x) stringify2(x)
88 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) };
90 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory };
93 for (string directory : dirs)
94 if (currentEvalFileName != eval_file)
96 if (directory != "<internal>")
98 ifstream stream(directory + eval_file, ios::binary);
99 if (load_eval(eval_file, stream))
100 currentEvalFileName = eval_file;
103 if (directory == "<internal>" && eval_file == EvalFileDefaultName)
105 // C++ way to prepare a buffer for a memory stream
106 class MemoryBuffer : public basic_streambuf<char> {
107 public: MemoryBuffer(char* p, size_t n) { setg(p, p, p + n); setp(p, p + n); }
110 MemoryBuffer buffer(const_cast<char*>(reinterpret_cast<const char*>(gEmbeddedNNUEData)),
111 size_t(gEmbeddedNNUESize));
113 istream stream(&buffer);
114 if (load_eval(eval_file, stream))
115 currentEvalFileName = eval_file;
120 /// NNUE::verify() verifies that the last net used was loaded successfully
121 void NNUE::verify() {
123 string eval_file = string(Options["EvalFile"]);
124 if (eval_file.empty())
125 eval_file = EvalFileDefaultName;
127 if (useNNUE && currentEvalFileName != eval_file)
130 string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
131 string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
132 string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
133 string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + std::string(EvalFileDefaultName);
134 string msg5 = "The engine will be terminated now.";
136 sync_cout << "info string ERROR: " << msg1 << sync_endl;
137 sync_cout << "info string ERROR: " << msg2 << sync_endl;
138 sync_cout << "info string ERROR: " << msg3 << sync_endl;
139 sync_cout << "info string ERROR: " << msg4 << sync_endl;
140 sync_cout << "info string ERROR: " << msg5 << sync_endl;
145 if (Cluster::is_root())
148 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
150 sync_cout << "info string classical evaluation enabled" << sync_endl;
157 enum Tracing { NO_TRACE, TRACE };
159 enum Term { // The first 8 entries are reserved for PieceType
160 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
163 Score scores[TERM_NB][COLOR_NB];
165 double to_cp(Value v) { return double(v) / PawnValueEg; }
167 void add(int idx, Color c, Score s) {
171 void add(int idx, Score w, Score b = SCORE_ZERO) {
172 scores[idx][WHITE] = w;
173 scores[idx][BLACK] = b;
176 std::ostream& operator<<(std::ostream& os, Score s) {
177 os << std::setw(5) << to_cp(mg_value(s)) << " "
178 << std::setw(5) << to_cp(eg_value(s));
182 std::ostream& operator<<(std::ostream& os, Term t) {
184 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
185 os << " ---- ----" << " | " << " ---- ----";
187 os << scores[t][WHITE] << " | " << scores[t][BLACK];
189 os << " | " << scores[t][WHITE] - scores[t][BLACK] << " |\n";
194 using namespace Trace;
198 // Threshold for lazy and space evaluation
199 constexpr Value LazyThreshold1 = Value(3130);
200 constexpr Value LazyThreshold2 = Value(2204);
201 constexpr Value SpaceThreshold = Value(11551);
203 // KingAttackWeights[PieceType] contains king attack weights by piece type
204 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
206 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
207 // higher if multiple safe checks are possible for that piece type.
208 constexpr int SafeCheck[][2] = {
209 {}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
212 #define S(mg, eg) make_score(mg, eg)
214 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
215 // indexed by piece type and number of attacked squares in the mobility area.
216 constexpr Score MobilityBonus[][32] = {
217 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
218 S( 21, 16), S( 28, 21), S( 37, 26) },
219 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
220 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
221 S( 91, 88), S( 96, 98) },
222 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
223 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
224 S( 57,165), S( 58,170), S( 67,175) },
225 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
226 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
227 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
228 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
229 S(112,178), S(114,185), S(114,187), S(119,221) }
232 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
233 // squares of the same color as our bishop.
234 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
235 S(3, 8), S(3, 9), S(2, 8), S(3, 8)
238 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
239 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
241 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
242 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
243 constexpr Score Outpost[] = { S(57, 38), S(31, 24) };
245 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
246 constexpr Score PassedRank[RANK_NB] = {
247 S(0, 0), S(7, 27), S(16, 32), S(17, 40), S(64, 71), S(170, 174), S(278, 262)
250 constexpr Score RookOnClosedFile = S(10, 5);
251 constexpr Score RookOnOpenFile[] = { S(19, 6), S(47, 26) };
253 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
254 // which piece type attacks which one. Attacks on lesser pieces which are
255 // pawn-defended are not considered.
256 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
257 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
260 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
261 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
264 constexpr Value CorneredBishop = Value(50);
266 // Assorted bonuses and penalties
267 constexpr Score UncontestedOutpost = S( 1, 10);
268 constexpr Score BishopOnKingRing = S( 24, 0);
269 constexpr Score BishopXRayPawns = S( 4, 5);
270 constexpr Score FlankAttacks = S( 8, 0);
271 constexpr Score Hanging = S( 69, 36);
272 constexpr Score KnightOnQueen = S( 16, 11);
273 constexpr Score LongDiagonalBishop = S( 45, 0);
274 constexpr Score MinorBehindPawn = S( 18, 3);
275 constexpr Score PassedFile = S( 11, 8);
276 constexpr Score PawnlessFlank = S( 17, 95);
277 constexpr Score ReachableOutpost = S( 31, 22);
278 constexpr Score RestrictedPiece = S( 7, 7);
279 constexpr Score RookOnKingRing = S( 16, 0);
280 constexpr Score SliderOnQueen = S( 60, 18);
281 constexpr Score ThreatByKing = S( 24, 89);
282 constexpr Score ThreatByPawnPush = S( 48, 39);
283 constexpr Score ThreatBySafePawn = S(173, 94);
284 constexpr Score TrappedRook = S( 55, 13);
285 constexpr Score WeakQueenProtection = S( 14, 0);
286 constexpr Score WeakQueen = S( 56, 15);
291 // Evaluation class computes and stores attacks tables and other working data
296 Evaluation() = delete;
297 explicit Evaluation(const Position& p) : pos(p) {}
298 Evaluation& operator=(const Evaluation&) = delete;
302 template<Color Us> void initialize();
303 template<Color Us, PieceType Pt> Score pieces();
304 template<Color Us> Score king() const;
305 template<Color Us> Score threats() const;
306 template<Color Us> Score passed() const;
307 template<Color Us> Score space() const;
308 Value winnable(Score score) const;
313 Bitboard mobilityArea[COLOR_NB];
314 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
316 // attackedBy[color][piece type] is a bitboard representing all squares
317 // attacked by a given color and piece type. Special "piece types" which
318 // is also calculated is ALL_PIECES.
319 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
321 // attackedBy2[color] are the squares attacked by at least 2 units of a given
322 // color, including x-rays. But diagonal x-rays through pawns are not computed.
323 Bitboard attackedBy2[COLOR_NB];
325 // kingRing[color] are the squares adjacent to the king plus some other
326 // very near squares, depending on king position.
327 Bitboard kingRing[COLOR_NB];
329 // kingAttackersCount[color] is the number of pieces of the given color
330 // which attack a square in the kingRing of the enemy king.
331 int kingAttackersCount[COLOR_NB];
333 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
334 // the given color which attack a square in the kingRing of the enemy king.
335 // The weights of the individual piece types are given by the elements in
336 // the KingAttackWeights array.
337 int kingAttackersWeight[COLOR_NB];
339 // kingAttacksCount[color] is the number of attacks by the given color to
340 // squares directly adjacent to the enemy king. Pieces which attack more
341 // than one square are counted multiple times. For instance, if there is
342 // a white knight on g5 and black's king is on g8, this white knight adds 2
343 // to kingAttacksCount[WHITE].
344 int kingAttacksCount[COLOR_NB];
348 // Evaluation::initialize() computes king and pawn attacks, and the king ring
349 // bitboard for a given color. This is done at the beginning of the evaluation.
351 template<Tracing T> template<Color Us>
352 void Evaluation<T>::initialize() {
354 constexpr Color Them = ~Us;
355 constexpr Direction Up = pawn_push(Us);
356 constexpr Direction Down = -Up;
357 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
359 const Square ksq = pos.square<KING>(Us);
361 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
363 // Find our pawns that are blocked or on the first two ranks
364 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
366 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
367 // or controlled by enemy pawns are excluded from the mobility area.
368 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
370 // Initialize attackedBy[] for king and pawns
371 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
372 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
373 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
374 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
376 // Init our king safety tables
377 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
378 std::clamp(rank_of(ksq), RANK_2, RANK_7));
379 kingRing[Us] = attacks_bb<KING>(s) | s;
381 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
382 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
384 // Remove from kingRing[] the squares defended by two pawns
385 kingRing[Us] &= ~dblAttackByPawn;
389 // Evaluation::pieces() scores pieces of a given color and type
391 template<Tracing T> template<Color Us, PieceType Pt>
392 Score Evaluation<T>::pieces() {
394 constexpr Color Them = ~Us;
395 constexpr Direction Down = -pawn_push(Us);
396 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
397 : Rank5BB | Rank4BB | Rank3BB);
398 Bitboard b1 = pos.pieces(Us, Pt);
400 Score score = SCORE_ZERO;
402 attackedBy[Us][Pt] = 0;
406 Square s = pop_lsb(b1);
408 // Find attacked squares, including x-ray attacks for bishops and rooks
409 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
410 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
411 : attacks_bb<Pt>(s, pos.pieces());
413 if (pos.blockers_for_king(Us) & s)
414 b &= line_bb(pos.square<KING>(Us), s);
416 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
417 attackedBy[Us][Pt] |= b;
418 attackedBy[Us][ALL_PIECES] |= b;
420 if (b & kingRing[Them])
422 kingAttackersCount[Us]++;
423 kingAttackersWeight[Us] += KingAttackWeights[Pt];
424 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
427 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
428 score += RookOnKingRing;
430 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
431 score += BishopOnKingRing;
433 int mob = popcount(b & mobilityArea[Us]);
434 mobility[Us] += MobilityBonus[Pt - 2][mob];
436 if (Pt == BISHOP || Pt == KNIGHT)
438 // Bonus if the piece is on an outpost square or can reach one
439 // Bonus for knights (UncontestedOutpost) if few relevant targets
440 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
441 & ~pe->pawn_attacks_span(Them);
442 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
445 && bb & s & ~CenterFiles // on a side outpost
446 && !(b & targets) // no relevant attacks
447 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
448 score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
450 score += Outpost[Pt == BISHOP];
451 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
452 score += ReachableOutpost;
454 // Bonus for a knight or bishop shielded by pawn
455 if (shift<Down>(pos.pieces(PAWN)) & s)
456 score += MinorBehindPawn;
458 // Penalty if the piece is far from the king
459 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
461 if constexpr (Pt == BISHOP)
463 // Penalty according to the number of our pawns on the same color square as the
464 // bishop, bigger when the center files are blocked with pawns and smaller
465 // when the bishop is outside the pawn chain.
466 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
468 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
469 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
471 // Penalty for all enemy pawns x-rayed
472 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
474 // Bonus for bishop on a long diagonal which can "see" both center squares
475 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
476 score += LongDiagonalBishop;
478 // An important Chess960 pattern: a cornered bishop blocked by a friendly
479 // pawn diagonally in front of it is a very serious problem, especially
480 // when that pawn is also blocked.
481 if ( pos.is_chess960()
482 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
484 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
485 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
486 score -= !pos.empty(s + d + pawn_push(Us)) ? 4 * make_score(CorneredBishop, CorneredBishop)
487 : 3 * make_score(CorneredBishop, CorneredBishop);
492 if constexpr (Pt == ROOK)
494 // Bonuses for rook on a (semi-)open or closed file
495 if (pos.is_on_semiopen_file(Us, s))
497 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
501 // If our pawn on this file is blocked, increase penalty
502 if ( pos.pieces(Us, PAWN)
503 & shift<Down>(pos.pieces())
506 score -= RookOnClosedFile;
509 // Penalty when trapped by the king, even more if the king cannot castle
512 File kf = file_of(pos.square<KING>(Us));
513 if ((kf < FILE_E) == (file_of(s) < kf))
514 score -= TrappedRook * (1 + !pos.castling_rights(Us));
519 if constexpr (Pt == QUEEN)
521 // Penalty if any relative pin or discovered attack against the queen
522 Bitboard queenPinners;
523 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
528 Trace::add(Pt, Us, score);
534 // Evaluation::king() assigns bonuses and penalties to a king of a given color
536 template<Tracing T> template<Color Us>
537 Score Evaluation<T>::king() const {
539 constexpr Color Them = ~Us;
540 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
541 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
543 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
544 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
546 const Square ksq = pos.square<KING>(Us);
548 // Init the score with king shelter and enemy pawns storm
549 Score score = pe->king_safety<Us>(pos);
551 // Attacked squares defended at most once by our queen or king
552 weak = attackedBy[Them][ALL_PIECES]
554 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
556 // Analyse the safe enemy's checks which are possible on next move
557 safe = ~pos.pieces(Them);
558 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
560 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
561 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
563 // Enemy rooks checks
564 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
566 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
568 unsafeChecks |= b1 & attackedBy[Them][ROOK];
570 // Enemy queen safe checks: count them only if the checks are from squares from
571 // which opponent cannot give a rook check, because rook checks are more valuable.
572 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
573 & ~(attackedBy[Us][QUEEN] | rookChecks);
575 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
577 // Enemy bishops checks: count them only if they are from squares from which
578 // opponent cannot give a queen check, because queen checks are more valuable.
579 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
582 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
585 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
587 // Enemy knights checks
588 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
589 if (knightChecks & safe)
590 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
592 unsafeChecks |= knightChecks;
594 // Find the squares that opponent attacks in our king flank, the squares
595 // which they attack twice in that flank, and the squares that we defend.
596 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
597 b2 = b1 & attackedBy2[Them];
598 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
600 int kingFlankAttack = popcount(b1) + popcount(b2);
601 int kingFlankDefense = popcount(b3);
603 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
604 + 183 * popcount(kingRing[Us] & weak) // (~15 Elo)
605 + 148 * popcount(unsafeChecks) // (~4 Elo)
606 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
607 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
608 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
609 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
610 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
611 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
612 - 6 * mg_value(score) / 8 // (~8 Elo)
613 - 4 * kingFlankDefense // (~5 Elo)
616 // Transform the kingDanger units into a Score, and subtract it from the evaluation
617 if (kingDanger > 100)
618 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
620 // Penalty when our king is on a pawnless flank
621 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
622 score -= PawnlessFlank;
624 // Penalty if king flank is under attack, potentially moving toward the king
625 score -= FlankAttacks * kingFlankAttack;
628 Trace::add(KING, Us, score);
634 // Evaluation::threats() assigns bonuses according to the types of the
635 // attacking and the attacked pieces.
637 template<Tracing T> template<Color Us>
638 Score Evaluation<T>::threats() const {
640 constexpr Color Them = ~Us;
641 constexpr Direction Up = pawn_push(Us);
642 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
644 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
645 Score score = SCORE_ZERO;
648 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
650 // Squares strongly protected by the enemy, either because they defend the
651 // square with a pawn, or because they defend the square twice and we don't.
652 stronglyProtected = attackedBy[Them][PAWN]
653 | (attackedBy2[Them] & ~attackedBy2[Us]);
655 // Non-pawn enemies, strongly protected
656 defended = nonPawnEnemies & stronglyProtected;
658 // Enemies not strongly protected and under our attack
659 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
661 // Bonus according to the kind of attacking pieces
664 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
666 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(b)))];
668 b = weak & attackedBy[Us][ROOK];
670 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(b)))];
672 if (weak & attackedBy[Us][KING])
673 score += ThreatByKing;
675 b = ~attackedBy[Them][ALL_PIECES]
676 | (nonPawnEnemies & attackedBy2[Us]);
677 score += Hanging * popcount(weak & b);
679 // Additional bonus if weak piece is only protected by a queen
680 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
683 // Bonus for restricting their piece moves
684 b = attackedBy[Them][ALL_PIECES]
686 & attackedBy[Us][ALL_PIECES];
687 score += RestrictedPiece * popcount(b);
689 // Protected or unattacked squares
690 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
692 // Bonus for attacking enemy pieces with our relatively safe pawns
693 b = pos.pieces(Us, PAWN) & safe;
694 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
695 score += ThreatBySafePawn * popcount(b);
697 // Find squares where our pawns can push on the next move
698 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
699 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
701 // Keep only the squares which are relatively safe
702 b &= ~attackedBy[Them][PAWN] & safe;
704 // Bonus for safe pawn threats on the next move
705 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
706 score += ThreatByPawnPush * popcount(b);
708 // Bonus for threats on the next moves against enemy queen
709 if (pos.count<QUEEN>(Them) == 1)
711 bool queenImbalance = pos.count<QUEEN>() == 1;
713 Square s = pos.square<QUEEN>(Them);
714 safe = mobilityArea[Us]
715 & ~pos.pieces(Us, PAWN)
716 & ~stronglyProtected;
718 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
720 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
722 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
723 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
725 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
729 Trace::add(THREAT, Us, score);
734 // Evaluation::passed() evaluates the passed pawns and candidate passed
735 // pawns of the given color.
737 template<Tracing T> template<Color Us>
738 Score Evaluation<T>::passed() const {
740 constexpr Color Them = ~Us;
741 constexpr Direction Up = pawn_push(Us);
742 constexpr Direction Down = -Up;
744 auto king_proximity = [&](Color c, Square s) {
745 return std::min(distance(pos.square<KING>(c), s), 5);
748 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
749 Score score = SCORE_ZERO;
751 b = pe->passed_pawns(Us);
753 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
756 helpers = shift<Up>(pos.pieces(Us, PAWN))
758 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
760 // Remove blocked candidate passers that don't have help to pass
762 | shift<WEST>(helpers)
763 | shift<EAST>(helpers);
768 Square s = pop_lsb(b);
770 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
772 int r = relative_rank(Us, s);
774 Score bonus = PassedRank[r];
779 Square blockSq = s + Up;
781 // Adjust bonus based on the king's proximity
782 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
783 - king_proximity(Us, blockSq) * 2) * w);
785 // If blockSq is not the queening square then consider also a second push
787 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
789 // If the pawn is free to advance, then increase the bonus
790 if (pos.empty(blockSq))
792 squaresToQueen = forward_file_bb(Us, s);
793 unsafeSquares = passed_pawn_span(Us, s);
795 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
797 if (!(pos.pieces(Them) & bb))
798 unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
800 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
801 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
802 // Otherwise assign a smaller bonus if the path to queen is not attacked
803 // and even smaller bonus if it is attacked but block square is not.
804 int k = !unsafeSquares ? 36 :
805 !(unsafeSquares & ~attackedBy[Us][PAWN]) ? 30 :
806 !(unsafeSquares & squaresToQueen) ? 17 :
807 !(unsafeSquares & blockSq) ? 7 :
810 // Assign a larger bonus if the block square is defended
811 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
814 bonus += make_score(k * w, k * w);
818 score += bonus - PassedFile * edge_distance(file_of(s));
822 Trace::add(PASSED, Us, score);
828 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
829 // play in the opening. It is based on the number of safe squares on the four central files
830 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
831 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
833 template<Tracing T> template<Color Us>
834 Score Evaluation<T>::space() const {
836 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
837 if (pos.non_pawn_material() < SpaceThreshold)
840 constexpr Color Them = ~Us;
841 constexpr Direction Down = -pawn_push(Us);
842 constexpr Bitboard SpaceMask =
843 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
844 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
846 // Find the available squares for our pieces inside the area defined by SpaceMask
847 Bitboard safe = SpaceMask
848 & ~pos.pieces(Us, PAWN)
849 & ~attackedBy[Them][PAWN];
851 // Find all squares which are at most three squares behind some friendly pawn
852 Bitboard behind = pos.pieces(Us, PAWN);
853 behind |= shift<Down>(behind);
854 behind |= shift<Down+Down>(behind);
856 // Compute space score based on the number of safe squares and number of our pieces
857 // increased with number of total blocked pawns in position.
858 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
859 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
860 Score score = make_score(bonus * weight * weight / 16, 0);
863 Trace::add(SPACE, Us, score);
869 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
870 // the known attacking/defending status of the players. The final value is derived
871 // by interpolation from the midgame and endgame values.
874 Value Evaluation<T>::winnable(Score score) const {
876 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
877 + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
879 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
880 && (pos.pieces(PAWN) & KingSide);
882 bool almostUnwinnable = outflanking < 0
883 && !pawnsOnBothFlanks;
885 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
886 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
888 // Compute the initiative bonus for the attacking side
889 int complexity = 9 * pe->passed_count()
890 + 12 * pos.count<PAWN>()
892 + 21 * pawnsOnBothFlanks
894 + 51 * !pos.non_pawn_material()
895 - 43 * almostUnwinnable
898 Value mg = mg_value(score);
899 Value eg = eg_value(score);
901 // Now apply the bonus: note that we find the attacking side by extracting the
902 // sign of the midgame or endgame values, and that we carefully cap the bonus
903 // so that the midgame and endgame scores do not change sign after the bonus.
904 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
905 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
910 // Compute the scale factor for the winning side
911 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
912 int sf = me->scale_factor(pos, strongSide);
914 // If scale factor is not already specific, scale up/down via general heuristics
915 if (sf == SCALE_FACTOR_NORMAL)
917 if (pos.opposite_bishops())
919 // For pure opposite colored bishops endgames use scale factor
920 // based on the number of passed pawns of the strong side.
921 if ( pos.non_pawn_material(WHITE) == BishopValueMg
922 && pos.non_pawn_material(BLACK) == BishopValueMg)
923 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
924 // For every other opposite colored bishops endgames use scale factor
925 // based on the number of all pieces of the strong side.
927 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
929 // For rook endgames with strong side not having overwhelming pawn number advantage
930 // and its pawns being on one flank and weak side protecting its pieces with a king
931 // use lower scale factor.
932 else if ( pos.non_pawn_material(WHITE) == RookValueMg
933 && pos.non_pawn_material(BLACK) == RookValueMg
934 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
935 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
936 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
938 // For queen vs no queen endgames use scale factor
939 // based on number of minors of side that doesn't have queen.
940 else if (pos.count<QUEEN>() == 1)
941 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
942 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
943 // In every other case use scale factor based on
944 // the number of pawns of the strong side reduced if pawns are on a single flank.
946 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
948 // Reduce scale factor in case of pawns being on a single flank
949 sf -= 4 * !pawnsOnBothFlanks;
952 // Interpolate between the middlegame and (scaled by 'sf') endgame score
953 v = mg * int(me->game_phase())
954 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
959 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
960 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
967 // Evaluation::value() is the main function of the class. It computes the various
968 // parts of the evaluation and returns the value of the position from the point
969 // of view of the side to move.
972 Value Evaluation<T>::value() {
974 assert(!pos.checkers());
976 // Probe the material hash table
977 me = Material::probe(pos);
979 // If we have a specialized evaluation function for the current material
980 // configuration, call it and return.
981 if (me->specialized_eval_exists())
982 return me->evaluate(pos);
984 // Initialize score by reading the incrementally updated scores included in
985 // the position object (material + piece square tables) and the material
986 // imbalance. Score is computed internally from the white point of view.
987 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->trend;
989 // Probe the pawn hash table
990 pe = Pawns::probe(pos);
991 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
993 // Early exit if score is high
994 auto lazy_skip = [&](Value lazyThreshold) {
995 return abs(mg_value(score) + eg_value(score)) > lazyThreshold + pos.non_pawn_material() / 32;
998 if (lazy_skip(LazyThreshold1))
1001 // Main evaluation begins here
1002 initialize<WHITE>();
1003 initialize<BLACK>();
1005 // Pieces evaluated first (also populates attackedBy, attackedBy2).
1006 // Note that the order of evaluation of the terms is left unspecified.
1007 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
1008 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
1009 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
1010 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
1012 score += mobility[WHITE] - mobility[BLACK];
1014 // More complex interactions that require fully populated attack bitboards
1015 score += king< WHITE>() - king< BLACK>()
1016 + passed< WHITE>() - passed< BLACK>();
1018 if (lazy_skip(LazyThreshold2))
1021 score += threats<WHITE>() - threats<BLACK>()
1022 + space< WHITE>() - space< BLACK>();
1025 // Derive single value from mg and eg parts of score
1026 Value v = winnable(score);
1028 // In case of tracing add all remaining individual evaluation terms
1031 Trace::add(MATERIAL, pos.psq_score());
1032 Trace::add(IMBALANCE, me->imbalance());
1033 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1034 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1040 // Side to move point of view
1041 v = (pos.side_to_move() == WHITE ? v : -v);
1047 /// Fisher Random Chess: correction for cornered bishops, to fix chess960 play with NNUE
1049 Value fix_FRC(const Position& pos) {
1051 constexpr Bitboard Corners = 1ULL << SQ_A1 | 1ULL << SQ_H1 | 1ULL << SQ_A8 | 1ULL << SQ_H8;
1053 if (!(pos.pieces(BISHOP) & Corners))
1058 if ( pos.piece_on(SQ_A1) == W_BISHOP
1059 && pos.piece_on(SQ_B2) == W_PAWN)
1060 correction -= CorneredBishop;
1062 if ( pos.piece_on(SQ_H1) == W_BISHOP
1063 && pos.piece_on(SQ_G2) == W_PAWN)
1064 correction -= CorneredBishop;
1066 if ( pos.piece_on(SQ_A8) == B_BISHOP
1067 && pos.piece_on(SQ_B7) == B_PAWN)
1068 correction += CorneredBishop;
1070 if ( pos.piece_on(SQ_H8) == B_BISHOP
1071 && pos.piece_on(SQ_G7) == B_PAWN)
1072 correction += CorneredBishop;
1074 return pos.side_to_move() == WHITE ? Value(5 * correction)
1075 : -Value(5 * correction);
1081 /// evaluate() is the evaluator for the outer world. It returns a static
1082 /// evaluation of the position from the point of view of the side to move.
1084 Value Eval::evaluate(const Position& pos) {
1088 // Deciding between classical and NNUE eval: for high PSQ imbalance we use classical,
1089 // but we switch to NNUE during long shuffling or with high material on the board.
1092 || abs(eg_value(pos.psq_score())) * 5 > (850 + pos.non_pawn_material() / 64) * (5 + pos.rule50_count()))
1093 v = Evaluation<NO_TRACE>(pos).value(); // classical
1097 + 32 * pos.count<PAWN>()
1098 + 32 * pos.non_pawn_material() / 1024;
1100 v = NNUE::evaluate(pos, true) * scale / 1024; // NNUE
1102 if (pos.is_chess960())
1106 // Damp down the evaluation linearly when shuffling
1107 v = v * (100 - pos.rule50_count()) / 100;
1109 // Guarantee evaluation does not hit the tablebase range
1110 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1115 /// trace() is like evaluate(), but instead of returning a value, it returns
1116 /// a string (suitable for outputting to stdout) that contains the detailed
1117 /// descriptions and values of each evaluation term. Useful for debugging.
1118 /// Trace scores are from white's point of view
1120 std::string Eval::trace(Position& pos) {
1123 return "Final evaluation: none (in check)";
1125 std::stringstream ss;
1126 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1130 std::memset(scores, 0, sizeof(scores));
1132 pos.this_thread()->trend = SCORE_ZERO; // Reset any dynamic contempt
1134 v = Evaluation<TRACE>(pos).value();
1136 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1137 << " Contributing terms for the classical eval:\n"
1138 << "+------------+-------------+-------------+-------------+\n"
1139 << "| Term | White | Black | Total |\n"
1140 << "| | MG EG | MG EG | MG EG |\n"
1141 << "+------------+-------------+-------------+-------------+\n"
1142 << "| Material | " << Term(MATERIAL)
1143 << "| Imbalance | " << Term(IMBALANCE)
1144 << "| Pawns | " << Term(PAWN)
1145 << "| Knights | " << Term(KNIGHT)
1146 << "| Bishops | " << Term(BISHOP)
1147 << "| Rooks | " << Term(ROOK)
1148 << "| Queens | " << Term(QUEEN)
1149 << "| Mobility | " << Term(MOBILITY)
1150 << "|King safety | " << Term(KING)
1151 << "| Threats | " << Term(THREAT)
1152 << "| Passed | " << Term(PASSED)
1153 << "| Space | " << Term(SPACE)
1154 << "| Winnable | " << Term(WINNABLE)
1155 << "+------------+-------------+-------------+-------------+\n"
1156 << "| Total | " << Term(TOTAL)
1157 << "+------------+-------------+-------------+-------------+\n";
1160 ss << '\n' << NNUE::trace(pos) << '\n';
1162 ss << std::showpoint << std::showpos << std::fixed << std::setprecision(2) << std::setw(15);
1164 v = pos.side_to_move() == WHITE ? v : -v;
1165 ss << "\nClassical evaluation " << to_cp(v) << " (white side)\n";
1168 v = NNUE::evaluate(pos, false);
1169 v = pos.side_to_move() == WHITE ? v : -v;
1170 ss << "NNUE evaluation " << to_cp(v) << " (white side)\n";
1174 v = pos.side_to_move() == WHITE ? v : -v;
1175 ss << "Final evaluation " << to_cp(v) << " (white side)";
1177 ss << " [with scaled NNUE, hybrid, ...]";
1183 } // namespace Stockfish