2 Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3 Copyright (C) 2004-2020 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
37 #include "incbin/incbin.h"
40 // Macro to embed the default NNUE file data in the engine binary (using incbin.h, by Dale Weiler).
41 // This macro invocation will declare the following three variables
42 // const unsigned char gEmbeddedNNUEData[]; // a pointer to the embedded data
43 // const unsigned char *const gEmbeddedNNUEEnd; // a marker to the end
44 // const unsigned int gEmbeddedNNUESize; // the size of the embedded file
45 // Note that this does not work in Microsof Visual Studio.
46 #if !defined(_MSC_VER) && !defined(NNUE_EMBEDDING_OFF)
47 INCBIN(EmbeddedNNUE, EvalFileDefaultName);
49 const unsigned char gEmbeddedNNUEData[1] = {0x0};
50 const unsigned char *const gEmbeddedNNUEEnd = &gEmbeddedNNUEData[1];
51 const unsigned int gEmbeddedNNUESize = 1;
56 using namespace Eval::NNUE;
61 string eval_file_loaded = "None";
63 /// NNUE::init() tries to load a nnue network at startup time, or when the engine
64 /// receives a UCI command "setoption name EvalFile value nn-[a-z0-9]{12}.nnue"
65 /// The name of the nnue network is always retrieved from the EvalFile option.
66 /// We search the given network in three locations: internally (the default
67 /// network may be embedded in the binary), in the active working directory and
68 /// in the engine directory. Distro packagers may define the DEFAULT_NNUE_DIRECTORY
69 /// variable to have the engine search in a special directory in their distro.
73 useNNUE = Options["Use NNUE"];
77 string eval_file = string(Options["EvalFile"]);
79 #if defined(DEFAULT_NNUE_DIRECTORY)
80 #define stringify2(x) #x
81 #define stringify(x) stringify2(x)
82 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) };
84 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory };
87 for (string directory : dirs)
88 if (eval_file_loaded != eval_file)
90 if (directory != "<internal>")
92 ifstream stream(directory + eval_file, ios::binary);
93 if (load_eval(eval_file, stream))
94 eval_file_loaded = eval_file;
97 if (directory == "<internal>" && eval_file == EvalFileDefaultName)
99 // C++ way to prepare a buffer for a memory stream
100 class MemoryBuffer : public basic_streambuf<char> {
101 public: MemoryBuffer(char* p, size_t n) { setg(p, p, p + n); setp(p, p + n); }
104 MemoryBuffer buffer(const_cast<char*>(reinterpret_cast<const char*>(gEmbeddedNNUEData)),
105 size_t(gEmbeddedNNUESize));
107 istream stream(&buffer);
108 if (load_eval(eval_file, stream))
109 eval_file_loaded = eval_file;
114 /// NNUE::verify() verifies that the last net used was loaded successfully
115 void NNUE::verify() {
117 string eval_file = string(Options["EvalFile"]);
119 if (useNNUE && eval_file_loaded != eval_file)
121 UCI::OptionsMap defaults;
124 string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
125 string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
126 string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
127 string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + string(defaults["EvalFile"]);
128 string msg5 = "The engine will be terminated now.";
130 sync_cout << "info string ERROR: " << msg1 << sync_endl;
131 sync_cout << "info string ERROR: " << msg2 << sync_endl;
132 sync_cout << "info string ERROR: " << msg3 << sync_endl;
133 sync_cout << "info string ERROR: " << msg4 << sync_endl;
134 sync_cout << "info string ERROR: " << msg5 << sync_endl;
140 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
142 sync_cout << "info string classical evaluation enabled" << sync_endl;
148 enum Tracing { NO_TRACE, TRACE };
150 enum Term { // The first 8 entries are reserved for PieceType
151 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
154 Score scores[TERM_NB][COLOR_NB];
156 double to_cp(Value v) { return double(v) / PawnValueEg; }
158 void add(int idx, Color c, Score s) {
162 void add(int idx, Score w, Score b = SCORE_ZERO) {
163 scores[idx][WHITE] = w;
164 scores[idx][BLACK] = b;
167 std::ostream& operator<<(std::ostream& os, Score s) {
168 os << std::setw(5) << to_cp(mg_value(s)) << " "
169 << std::setw(5) << to_cp(eg_value(s));
173 std::ostream& operator<<(std::ostream& os, Term t) {
175 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
176 os << " ---- ----" << " | " << " ---- ----";
178 os << scores[t][WHITE] << " | " << scores[t][BLACK];
180 os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
185 using namespace Trace;
189 // Threshold for lazy and space evaluation
190 constexpr Value LazyThreshold1 = Value(1565);
191 constexpr Value LazyThreshold2 = Value(1102);
192 constexpr Value SpaceThreshold = Value(11551);
193 constexpr Value NNUEThreshold1 = Value(682);
194 constexpr Value NNUEThreshold2 = Value(176);
196 // KingAttackWeights[PieceType] contains king attack weights by piece type
197 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
199 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
200 // higher if multiple safe checks are possible for that piece type.
201 constexpr int SafeCheck[][2] = {
202 {}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
205 #define S(mg, eg) make_score(mg, eg)
207 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
208 // indexed by piece type and number of attacked squares in the mobility area.
209 constexpr Score MobilityBonus[][32] = {
210 { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S( 3, 7), S( 12, 13), // Knight
211 S( 21, 16), S( 28, 21), S( 37, 26) },
212 { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
213 S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
214 S( 91, 88), S( 96, 98) },
215 { S(-60,-82), S(-24,-15), S( 0, 17) ,S( 3, 43), S( 4, 72), S( 14,100), // Rook
216 S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
217 S( 57,165), S( 58,170), S( 67,175) },
218 { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
219 S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
220 S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
221 S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
222 S(112,178), S(114,185), S(114,187), S(119,221) }
225 // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
226 // squares of the same color as our bishop.
227 constexpr Score BishopPawns[int(FILE_NB) / 2] = {
228 S(3, 8), S(3, 9), S(1, 8), S(3, 7)
231 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
232 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
234 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
235 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
236 constexpr Score Outpost[] = { S(56, 34), S(31, 23) };
238 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
239 constexpr Score PassedRank[RANK_NB] = {
240 S(0, 0), S(9, 28), S(15, 31), S(17, 39), S(64, 70), S(171, 177), S(277, 260)
243 // RookOnFile[semiopen/open] contains bonuses for each rook when there is
244 // no (friendly) pawn on the rook file.
245 constexpr Score RookOnFile[] = { S(19, 7), S(48, 27) };
247 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
248 // which piece type attacks which one. Attacks on lesser pieces which are
249 // pawn-defended are not considered.
250 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
251 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
254 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
255 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
258 // Assorted bonuses and penalties
259 constexpr Score BadOutpost = S( -7, 36);
260 constexpr Score BishopOnKingRing = S( 24, 0);
261 constexpr Score BishopXRayPawns = S( 4, 5);
262 constexpr Score CorneredBishop = S( 50, 50);
263 constexpr Score FlankAttacks = S( 8, 0);
264 constexpr Score Hanging = S( 69, 36);
265 constexpr Score KnightOnQueen = S( 16, 11);
266 constexpr Score LongDiagonalBishop = S( 45, 0);
267 constexpr Score MinorBehindPawn = S( 18, 3);
268 constexpr Score PassedFile = S( 11, 8);
269 constexpr Score PawnlessFlank = S( 17, 95);
270 constexpr Score ReachableOutpost = S( 31, 22);
271 constexpr Score RestrictedPiece = S( 7, 7);
272 constexpr Score RookOnKingRing = S( 16, 0);
273 constexpr Score SliderOnQueen = S( 60, 18);
274 constexpr Score ThreatByKing = S( 24, 89);
275 constexpr Score ThreatByPawnPush = S( 48, 39);
276 constexpr Score ThreatBySafePawn = S(173, 94);
277 constexpr Score TrappedRook = S( 55, 13);
278 constexpr Score WeakQueenProtection = S( 14, 0);
279 constexpr Score WeakQueen = S( 56, 15);
284 // Evaluation class computes and stores attacks tables and other working data
289 Evaluation() = delete;
290 explicit Evaluation(const Position& p) : pos(p) {}
291 Evaluation& operator=(const Evaluation&) = delete;
295 template<Color Us> void initialize();
296 template<Color Us, PieceType Pt> Score pieces();
297 template<Color Us> Score king() const;
298 template<Color Us> Score threats() const;
299 template<Color Us> Score passed() const;
300 template<Color Us> Score space() const;
301 Value winnable(Score score) const;
306 Bitboard mobilityArea[COLOR_NB];
307 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
309 // attackedBy[color][piece type] is a bitboard representing all squares
310 // attacked by a given color and piece type. Special "piece types" which
311 // is also calculated is ALL_PIECES.
312 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
314 // attackedBy2[color] are the squares attacked by at least 2 units of a given
315 // color, including x-rays. But diagonal x-rays through pawns are not computed.
316 Bitboard attackedBy2[COLOR_NB];
318 // kingRing[color] are the squares adjacent to the king plus some other
319 // very near squares, depending on king position.
320 Bitboard kingRing[COLOR_NB];
322 // kingAttackersCount[color] is the number of pieces of the given color
323 // which attack a square in the kingRing of the enemy king.
324 int kingAttackersCount[COLOR_NB];
326 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
327 // the given color which attack a square in the kingRing of the enemy king.
328 // The weights of the individual piece types are given by the elements in
329 // the KingAttackWeights array.
330 int kingAttackersWeight[COLOR_NB];
332 // kingAttacksCount[color] is the number of attacks by the given color to
333 // squares directly adjacent to the enemy king. Pieces which attack more
334 // than one square are counted multiple times. For instance, if there is
335 // a white knight on g5 and black's king is on g8, this white knight adds 2
336 // to kingAttacksCount[WHITE].
337 int kingAttacksCount[COLOR_NB];
341 // Evaluation::initialize() computes king and pawn attacks, and the king ring
342 // bitboard for a given color. This is done at the beginning of the evaluation.
344 template<Tracing T> template<Color Us>
345 void Evaluation<T>::initialize() {
347 constexpr Color Them = ~Us;
348 constexpr Direction Up = pawn_push(Us);
349 constexpr Direction Down = -Up;
350 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
352 const Square ksq = pos.square<KING>(Us);
354 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
356 // Find our pawns that are blocked or on the first two ranks
357 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
359 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
360 // or controlled by enemy pawns are excluded from the mobility area.
361 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
363 // Initialize attackedBy[] for king and pawns
364 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
365 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
366 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
367 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
369 // Init our king safety tables
370 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
371 std::clamp(rank_of(ksq), RANK_2, RANK_7));
372 kingRing[Us] = attacks_bb<KING>(s) | s;
374 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
375 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
377 // Remove from kingRing[] the squares defended by two pawns
378 kingRing[Us] &= ~dblAttackByPawn;
382 // Evaluation::pieces() scores pieces of a given color and type
384 template<Tracing T> template<Color Us, PieceType Pt>
385 Score Evaluation<T>::pieces() {
387 constexpr Color Them = ~Us;
388 constexpr Direction Down = -pawn_push(Us);
389 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
390 : Rank5BB | Rank4BB | Rank3BB);
391 const Square* pl = pos.squares<Pt>(Us);
394 Score score = SCORE_ZERO;
396 attackedBy[Us][Pt] = 0;
398 for (Square s = *pl; s != SQ_NONE; s = *++pl)
400 // Find attacked squares, including x-ray attacks for bishops and rooks
401 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
402 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
403 : attacks_bb<Pt>(s, pos.pieces());
405 if (pos.blockers_for_king(Us) & s)
406 b &= line_bb(pos.square<KING>(Us), s);
408 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
409 attackedBy[Us][Pt] |= b;
410 attackedBy[Us][ALL_PIECES] |= b;
412 if (b & kingRing[Them])
414 kingAttackersCount[Us]++;
415 kingAttackersWeight[Us] += KingAttackWeights[Pt];
416 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
419 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
420 score += RookOnKingRing;
422 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
423 score += BishopOnKingRing;
425 int mob = popcount(b & mobilityArea[Us]);
427 mobility[Us] += MobilityBonus[Pt - 2][mob];
429 if (Pt == BISHOP || Pt == KNIGHT)
431 // Bonus if the piece is on an outpost square or can reach one
432 // Reduced bonus for knights (BadOutpost) if few relevant targets
433 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
434 & ~pe->pawn_attacks_span(Them);
435 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
438 && bb & s & ~CenterFiles // on a side outpost
439 && !(b & targets) // no relevant attacks
440 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
443 score += Outpost[Pt == BISHOP];
444 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
445 score += ReachableOutpost;
447 // Bonus for a knight or bishop shielded by pawn
448 if (shift<Down>(pos.pieces(PAWN)) & s)
449 score += MinorBehindPawn;
451 // Penalty if the piece is far from the king
452 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
456 // Penalty according to the number of our pawns on the same color square as the
457 // bishop, bigger when the center files are blocked with pawns and smaller
458 // when the bishop is outside the pawn chain.
459 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
461 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
462 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
464 // Penalty for all enemy pawns x-rayed
465 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
467 // Bonus for bishop on a long diagonal which can "see" both center squares
468 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
469 score += LongDiagonalBishop;
471 // An important Chess960 pattern: a cornered bishop blocked by a friendly
472 // pawn diagonally in front of it is a very serious problem, especially
473 // when that pawn is also blocked.
474 if ( pos.is_chess960()
475 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
477 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
478 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
479 score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
480 : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
488 // Bonus for rook on an open or semi-open file
489 if (pos.is_on_semiopen_file(Us, s))
490 score += RookOnFile[pos.is_on_semiopen_file(Them, s)];
492 // Penalty when trapped by the king, even more if the king cannot castle
495 File kf = file_of(pos.square<KING>(Us));
496 if ((kf < FILE_E) == (file_of(s) < kf))
497 score -= TrappedRook * (1 + !pos.castling_rights(Us));
503 // Penalty if any relative pin or discovered attack against the queen
504 Bitboard queenPinners;
505 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
510 Trace::add(Pt, Us, score);
516 // Evaluation::king() assigns bonuses and penalties to a king of a given color
518 template<Tracing T> template<Color Us>
519 Score Evaluation<T>::king() const {
521 constexpr Color Them = ~Us;
522 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
523 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
525 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
526 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
528 const Square ksq = pos.square<KING>(Us);
530 // Init the score with king shelter and enemy pawns storm
531 Score score = pe->king_safety<Us>(pos);
533 // Attacked squares defended at most once by our queen or king
534 weak = attackedBy[Them][ALL_PIECES]
536 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
538 // Analyse the safe enemy's checks which are possible on next move
539 safe = ~pos.pieces(Them);
540 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
542 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
543 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
545 // Enemy rooks checks
546 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
548 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
550 unsafeChecks |= b1 & attackedBy[Them][ROOK];
552 // Enemy queen safe checks: count them only if the checks are from squares from
553 // which opponent cannot give a rook check, because rook checks are more valuable.
554 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
555 & ~(attackedBy[Us][QUEEN] | rookChecks);
557 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
559 // Enemy bishops checks: count them only if they are from squares from which
560 // opponent cannot give a queen check, because queen checks are more valuable.
561 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
564 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
567 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
569 // Enemy knights checks
570 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
571 if (knightChecks & safe)
572 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
574 unsafeChecks |= knightChecks;
576 // Find the squares that opponent attacks in our king flank, the squares
577 // which they attack twice in that flank, and the squares that we defend.
578 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
579 b2 = b1 & attackedBy2[Them];
580 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
582 int kingFlankAttack = popcount(b1) + popcount(b2);
583 int kingFlankDefense = popcount(b3);
585 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
586 + 185 * popcount(kingRing[Us] & weak) // (~15 Elo)
587 + 148 * popcount(unsafeChecks) // (~4 Elo)
588 + 98 * popcount(pos.blockers_for_king(Us)) // (~2 Elo)
589 + 69 * kingAttacksCount[Them] // (~0.5 Elo)
590 + 3 * kingFlankAttack * kingFlankAttack / 8 // (~0.5 Elo)
591 + mg_value(mobility[Them] - mobility[Us]) // (~0.5 Elo)
592 - 873 * !pos.count<QUEEN>(Them) // (~24 Elo)
593 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING]) // (~5 Elo)
594 - 6 * mg_value(score) / 8 // (~8 Elo)
595 - 4 * kingFlankDefense // (~5 Elo)
598 // Transform the kingDanger units into a Score, and subtract it from the evaluation
599 if (kingDanger > 100)
600 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
602 // Penalty when our king is on a pawnless flank
603 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
604 score -= PawnlessFlank;
606 // Penalty if king flank is under attack, potentially moving toward the king
607 score -= FlankAttacks * kingFlankAttack;
610 Trace::add(KING, Us, score);
616 // Evaluation::threats() assigns bonuses according to the types of the
617 // attacking and the attacked pieces.
619 template<Tracing T> template<Color Us>
620 Score Evaluation<T>::threats() const {
622 constexpr Color Them = ~Us;
623 constexpr Direction Up = pawn_push(Us);
624 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
626 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
627 Score score = SCORE_ZERO;
630 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
632 // Squares strongly protected by the enemy, either because they defend the
633 // square with a pawn, or because they defend the square twice and we don't.
634 stronglyProtected = attackedBy[Them][PAWN]
635 | (attackedBy2[Them] & ~attackedBy2[Us]);
637 // Non-pawn enemies, strongly protected
638 defended = nonPawnEnemies & stronglyProtected;
640 // Enemies not strongly protected and under our attack
641 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
643 // Bonus according to the kind of attacking pieces
646 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
648 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
650 b = weak & attackedBy[Us][ROOK];
652 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
654 if (weak & attackedBy[Us][KING])
655 score += ThreatByKing;
657 b = ~attackedBy[Them][ALL_PIECES]
658 | (nonPawnEnemies & attackedBy2[Us]);
659 score += Hanging * popcount(weak & b);
661 // Additional bonus if weak piece is only protected by a queen
662 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
665 // Bonus for restricting their piece moves
666 b = attackedBy[Them][ALL_PIECES]
668 & attackedBy[Us][ALL_PIECES];
669 score += RestrictedPiece * popcount(b);
671 // Protected or unattacked squares
672 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
674 // Bonus for attacking enemy pieces with our relatively safe pawns
675 b = pos.pieces(Us, PAWN) & safe;
676 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
677 score += ThreatBySafePawn * popcount(b);
679 // Find squares where our pawns can push on the next move
680 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
681 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
683 // Keep only the squares which are relatively safe
684 b &= ~attackedBy[Them][PAWN] & safe;
686 // Bonus for safe pawn threats on the next move
687 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
688 score += ThreatByPawnPush * popcount(b);
690 // Bonus for threats on the next moves against enemy queen
691 if (pos.count<QUEEN>(Them) == 1)
693 bool queenImbalance = pos.count<QUEEN>() == 1;
695 Square s = pos.square<QUEEN>(Them);
696 safe = mobilityArea[Us]
697 & ~pos.pieces(Us, PAWN)
698 & ~stronglyProtected;
700 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
702 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
704 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
705 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
707 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
711 Trace::add(THREAT, Us, score);
716 // Evaluation::passed() evaluates the passed pawns and candidate passed
717 // pawns of the given color.
719 template<Tracing T> template<Color Us>
720 Score Evaluation<T>::passed() const {
722 constexpr Color Them = ~Us;
723 constexpr Direction Up = pawn_push(Us);
724 constexpr Direction Down = -Up;
726 auto king_proximity = [&](Color c, Square s) {
727 return std::min(distance(pos.square<KING>(c), s), 5);
730 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
731 Score score = SCORE_ZERO;
733 b = pe->passed_pawns(Us);
735 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
738 helpers = shift<Up>(pos.pieces(Us, PAWN))
740 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
742 // Remove blocked candidate passers that don't have help to pass
744 | shift<WEST>(helpers)
745 | shift<EAST>(helpers);
750 Square s = pop_lsb(&b);
752 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
754 int r = relative_rank(Us, s);
756 Score bonus = PassedRank[r];
761 Square blockSq = s + Up;
763 // Adjust bonus based on the king's proximity
764 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
765 - king_proximity(Us, blockSq) * 2) * w);
767 // If blockSq is not the queening square then consider also a second push
769 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
771 // If the pawn is free to advance, then increase the bonus
772 if (pos.empty(blockSq))
774 squaresToQueen = forward_file_bb(Us, s);
775 unsafeSquares = passed_pawn_span(Us, s);
777 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
779 if (!(pos.pieces(Them) & bb))
780 unsafeSquares &= attackedBy[Them][ALL_PIECES];
782 // If there are no enemy attacks on passed pawn span, assign a big bonus.
783 // Otherwise assign a smaller bonus if the path to queen is not attacked
784 // and even smaller bonus if it is attacked but block square is not.
785 int k = !unsafeSquares ? 35 :
786 !(unsafeSquares & squaresToQueen) ? 20 :
787 !(unsafeSquares & blockSq) ? 9 :
790 // Assign a larger bonus if the block square is defended
791 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
794 bonus += make_score(k * w, k * w);
798 score += bonus - PassedFile * edge_distance(file_of(s));
802 Trace::add(PASSED, Us, score);
808 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
809 // play in the opening. It is based on the number of safe squares on the four central files
810 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
811 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
813 template<Tracing T> template<Color Us>
814 Score Evaluation<T>::space() const {
816 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
817 if (pos.non_pawn_material() < SpaceThreshold)
820 constexpr Color Them = ~Us;
821 constexpr Direction Down = -pawn_push(Us);
822 constexpr Bitboard SpaceMask =
823 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
824 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
826 // Find the available squares for our pieces inside the area defined by SpaceMask
827 Bitboard safe = SpaceMask
828 & ~pos.pieces(Us, PAWN)
829 & ~attackedBy[Them][PAWN];
831 // Find all squares which are at most three squares behind some friendly pawn
832 Bitboard behind = pos.pieces(Us, PAWN);
833 behind |= shift<Down>(behind);
834 behind |= shift<Down+Down>(behind);
836 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
837 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
838 Score score = make_score(bonus * weight * weight / 16, 0);
841 Trace::add(SPACE, Us, score);
847 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
848 // the known attacking/defending status of the players. The final value is derived
849 // by interpolation from the midgame and endgame values.
852 Value Evaluation<T>::winnable(Score score) const {
854 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
855 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
857 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
858 && (pos.pieces(PAWN) & KingSide);
860 bool almostUnwinnable = outflanking < 0
861 && !pawnsOnBothFlanks;
863 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
864 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
866 // Compute the initiative bonus for the attacking side
867 int complexity = 9 * pe->passed_count()
868 + 12 * pos.count<PAWN>()
870 + 21 * pawnsOnBothFlanks
872 + 51 * !pos.non_pawn_material()
873 - 43 * almostUnwinnable
876 Value mg = mg_value(score);
877 Value eg = eg_value(score);
879 // Now apply the bonus: note that we find the attacking side by extracting the
880 // sign of the midgame or endgame values, and that we carefully cap the bonus
881 // so that the midgame and endgame scores do not change sign after the bonus.
882 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
883 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
888 // Compute the scale factor for the winning side
889 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
890 int sf = me->scale_factor(pos, strongSide);
892 // If scale factor is not already specific, scale down via general heuristics
893 if (sf == SCALE_FACTOR_NORMAL)
895 if (pos.opposite_bishops())
897 if ( pos.non_pawn_material(WHITE) == BishopValueMg
898 && pos.non_pawn_material(BLACK) == BishopValueMg)
899 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
901 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
903 else if ( pos.non_pawn_material(WHITE) == RookValueMg
904 && pos.non_pawn_material(BLACK) == RookValueMg
905 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
906 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
907 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
909 else if (pos.count<QUEEN>() == 1)
910 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
911 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
913 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
915 sf -= 4 * !pawnsOnBothFlanks;
918 // Interpolate between the middlegame and (scaled by 'sf') endgame score
919 v = mg * int(me->game_phase())
920 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
925 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
926 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
933 // Evaluation::value() is the main function of the class. It computes the various
934 // parts of the evaluation and returns the value of the position from the point
935 // of view of the side to move.
938 Value Evaluation<T>::value() {
940 assert(!pos.checkers());
942 // Probe the material hash table
943 me = Material::probe(pos);
945 // If we have a specialized evaluation function for the current material
946 // configuration, call it and return.
947 if (me->specialized_eval_exists())
948 return me->evaluate(pos);
950 // Initialize score by reading the incrementally updated scores included in
951 // the position object (material + piece square tables) and the material
952 // imbalance. Score is computed internally from the white point of view.
953 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
955 // Probe the pawn hash table
956 pe = Pawns::probe(pos);
957 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
959 // Early exit if score is high
960 auto lazy_skip = [&](Value lazyThreshold) {
961 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
964 if (lazy_skip(LazyThreshold1))
967 // Main evaluation begins here
971 // Pieces evaluated first (also populates attackedBy, attackedBy2).
972 // Note that the order of evaluation of the terms is left unspecified.
973 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
974 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
975 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
976 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
978 score += mobility[WHITE] - mobility[BLACK];
980 // More complex interactions that require fully populated attack bitboards
981 score += king< WHITE>() - king< BLACK>()
982 + passed< WHITE>() - passed< BLACK>();
984 if (lazy_skip(LazyThreshold2))
987 score += threats<WHITE>() - threats<BLACK>()
988 + space< WHITE>() - space< BLACK>();
991 // Derive single value from mg and eg parts of score
992 Value v = winnable(score);
994 // In case of tracing add all remaining individual evaluation terms
997 Trace::add(MATERIAL, pos.psq_score());
998 Trace::add(IMBALANCE, me->imbalance());
999 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1000 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1006 // Side to move point of view
1007 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
1015 /// evaluate() is the evaluator for the outer world. It returns a static
1016 /// evaluation of the position from the point of view of the side to move.
1018 Value Eval::evaluate(const Position& pos) {
1023 v = Evaluation<NO_TRACE>(pos).value();
1026 // Scale and shift NNUE for compatibility with search and classical evaluation
1027 auto adjusted_NNUE = [&](){
1028 int mat = pos.non_pawn_material() + PawnValueMg * pos.count<PAWN>();
1029 return NNUE::evaluate(pos) * (720 + mat / 32) / 1024 + Tempo;
1032 // If there is PSQ imbalance use classical eval, with small probability if it is small
1033 Value psq = Value(abs(eg_value(pos.psq_score())));
1034 int r50 = 16 + pos.rule50_count();
1035 bool largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50;
1036 bool classical = largePsq || (psq > PawnValueMg / 4 && !(pos.this_thread()->nodes & 0xB));
1038 bool strongClassical = pos.non_pawn_material() < 2 * RookValueMg && pos.count<PAWN>() < 2;
1040 v = classical || strongClassical ? Evaluation<NO_TRACE>(pos).value() : adjusted_NNUE();
1042 // If the classical eval is small and imbalance large, use NNUE nevertheless.
1043 // For the case of opposite colored bishops, switch to NNUE eval with
1044 // small probability if the classical eval is less than the threshold.
1045 if ( largePsq && !strongClassical
1046 && ( abs(v) * 16 < NNUEThreshold2 * r50
1047 || ( pos.opposite_bishops()
1048 && abs(v) * 16 < (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50
1049 && !(pos.this_thread()->nodes & 0xB))))
1050 v = adjusted_NNUE();
1053 // Damp down the evaluation linearly when shuffling
1054 v = v * (100 - pos.rule50_count()) / 100;
1056 // Guarantee evaluation does not hit the tablebase range
1057 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1062 /// trace() is like evaluate(), but instead of returning a value, it returns
1063 /// a string (suitable for outputting to stdout) that contains the detailed
1064 /// descriptions and values of each evaluation term. Useful for debugging.
1065 /// Trace scores are from white's point of view
1067 std::string Eval::trace(const Position& pos) {
1070 return "Final evaluation: none (in check)";
1072 std::stringstream ss;
1073 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1077 std::memset(scores, 0, sizeof(scores));
1079 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
1081 v = Evaluation<TRACE>(pos).value();
1083 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1084 << " Term | White | Black | Total \n"
1085 << " | MG EG | MG EG | MG EG \n"
1086 << " ------------+-------------+-------------+------------\n"
1087 << " Material | " << Term(MATERIAL)
1088 << " Imbalance | " << Term(IMBALANCE)
1089 << " Pawns | " << Term(PAWN)
1090 << " Knights | " << Term(KNIGHT)
1091 << " Bishops | " << Term(BISHOP)
1092 << " Rooks | " << Term(ROOK)
1093 << " Queens | " << Term(QUEEN)
1094 << " Mobility | " << Term(MOBILITY)
1095 << " King safety | " << Term(KING)
1096 << " Threats | " << Term(THREAT)
1097 << " Passed | " << Term(PASSED)
1098 << " Space | " << Term(SPACE)
1099 << " Winnable | " << Term(WINNABLE)
1100 << " ------------+-------------+-------------+------------\n"
1101 << " Total | " << Term(TOTAL);
1103 v = pos.side_to_move() == WHITE ? v : -v;
1105 ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n";
1109 v = NNUE::evaluate(pos);
1110 v = pos.side_to_move() == WHITE ? v : -v;
1111 ss << "\nNNUE evaluation: " << to_cp(v) << " (white side)\n";
1115 v = pos.side_to_move() == WHITE ? v : -v;
1116 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";