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
38 #include "incbin/incbin.h"
41 // Macro to embed the default NNUE file data in the engine binary (using incbin.h, by Dale Weiler).
42 // This macro invocation will declare the following three variables
43 // const unsigned char gEmbeddedNNUEData[]; // a pointer to the embedded data
44 // const unsigned char *const gEmbeddedNNUEEnd; // a marker to the end
45 // const unsigned int gEmbeddedNNUESize; // the size of the embedded file
46 // Note that this does not work in Microsof Visual Studio.
47 #if !defined(_MSC_VER) && !defined(NNUE_EMBEDDING_OFF)
48 INCBIN(EmbeddedNNUE, EvalFileDefaultName);
50 const unsigned char gEmbeddedNNUEData[1] = {0x0};
51 const unsigned char *const gEmbeddedNNUEEnd = &gEmbeddedNNUEData[1];
52 const unsigned int gEmbeddedNNUESize = 1;
57 using namespace Eval::NNUE;
62 string eval_file_loaded = "None";
64 /// init_NNUE() tries to load a nnue network at startup time, or when the engine
65 /// receives a UCI command "setoption name EvalFile value nn-[a-z0-9]{12}.nnue"
66 /// The name of the nnue network is always retrieved from the EvalFile option.
67 /// We search the given network in three locations: internally (the default
68 /// network may be embedded in the binary), in the active working directory and
69 /// in the engine directory. Distro packagers may define the DEFAULT_NNUE_DIRECTORY
70 /// variable to have the engine search in a special directory in their distro.
74 useNNUE = Options["Use NNUE"];
78 string eval_file = string(Options["EvalFile"]);
80 #if defined(DEFAULT_NNUE_DIRECTORY)
81 #define stringify2(x) #x
82 #define stringify(x) stringify2(x)
83 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) };
85 vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory };
88 for (string directory : dirs)
89 if (eval_file_loaded != eval_file)
91 if (directory != "<internal>")
93 ifstream stream(directory + eval_file, ios::binary);
94 if (load_eval(eval_file, stream))
95 eval_file_loaded = eval_file;
98 if (directory == "<internal>" && eval_file == EvalFileDefaultName)
100 // C++ way to prepare a buffer for a memory stream
101 class MemoryBuffer : public basic_streambuf<char> {
102 public: MemoryBuffer(char* p, size_t n) { setg(p, p, p + n); setp(p, p + n); }
105 MemoryBuffer buffer(const_cast<char*>(reinterpret_cast<const char*>(gEmbeddedNNUEData)),
106 size_t(gEmbeddedNNUESize));
108 istream stream(&buffer);
109 if (load_eval(eval_file, stream))
110 eval_file_loaded = eval_file;
115 /// verify_NNUE() verifies that the last net used was loaded successfully
118 string eval_file = string(Options["EvalFile"]);
120 if (useNNUE && eval_file_loaded != eval_file)
122 UCI::OptionsMap defaults;
125 string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
126 string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
127 string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
128 string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + string(defaults["EvalFile"]);
129 string msg5 = "The engine will be terminated now.";
131 sync_cout << "info string ERROR: " << msg1 << sync_endl;
132 sync_cout << "info string ERROR: " << msg2 << sync_endl;
133 sync_cout << "info string ERROR: " << msg3 << sync_endl;
134 sync_cout << "info string ERROR: " << msg4 << sync_endl;
135 sync_cout << "info string ERROR: " << msg5 << sync_endl;
140 if (Cluster::is_root())
143 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
145 sync_cout << "info string classical evaluation enabled" << sync_endl;
152 enum Tracing { NO_TRACE, TRACE };
154 enum Term { // The first 8 entries are reserved for PieceType
155 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
158 Score scores[TERM_NB][COLOR_NB];
160 double to_cp(Value v) { return double(v) / PawnValueEg; }
162 void add(int idx, Color c, Score s) {
166 void add(int idx, Score w, Score b = SCORE_ZERO) {
167 scores[idx][WHITE] = w;
168 scores[idx][BLACK] = b;
171 std::ostream& operator<<(std::ostream& os, Score s) {
172 os << std::setw(5) << to_cp(mg_value(s)) << " "
173 << std::setw(5) << to_cp(eg_value(s));
177 std::ostream& operator<<(std::ostream& os, Term t) {
179 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
180 os << " ---- ----" << " | " << " ---- ----";
182 os << scores[t][WHITE] << " | " << scores[t][BLACK];
184 os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
189 using namespace Trace;
193 // Threshold for lazy and space evaluation
194 constexpr Value LazyThreshold1 = Value(1400);
195 constexpr Value LazyThreshold2 = Value(1300);
196 constexpr Value SpaceThreshold = Value(12222);
197 constexpr Value NNUEThreshold1 = Value(550);
198 constexpr Value NNUEThreshold2 = Value(150);
200 // KingAttackWeights[PieceType] contains king attack weights by piece type
201 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
203 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
204 // higher if multiple safe checks are possible for that piece type.
205 constexpr int SafeCheck[][2] = {
206 {}, {}, {792, 1283}, {645, 967}, {1084, 1897}, {772, 1119}
209 #define S(mg, eg) make_score(mg, eg)
211 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
212 // indexed by piece type and number of attacked squares in the mobility area.
213 constexpr Score MobilityBonus[][32] = {
214 { S(-62,-81), S(-53,-56), S(-12,-31), S( -4,-16), S( 3, 5), S( 13, 11), // Knight
215 S( 22, 17), S( 28, 20), S( 33, 25) },
216 { S(-48,-59), S(-20,-23), S( 16, -3), S( 26, 13), S( 38, 24), S( 51, 42), // Bishop
217 S( 55, 54), S( 63, 57), S( 63, 65), S( 68, 73), S( 81, 78), S( 81, 86),
218 S( 91, 88), S( 98, 97) },
219 { S(-60,-78), S(-20,-17), S( 2, 23), S( 3, 39), S( 3, 70), S( 11, 99), // Rook
220 S( 22,103), S( 31,121), S( 40,134), S( 40,139), S( 41,158), S( 48,164),
221 S( 57,168), S( 57,169), S( 62,172) },
222 { S(-30,-48), S(-12,-30), S( -8, -7), S( -9, 19), S( 20, 40), S( 23, 55), // Queen
223 S( 23, 59), S( 35, 75), S( 38, 78), S( 53, 96), S( 64, 96), S( 65,100),
224 S( 65,121), S( 66,127), S( 67,131), S( 67,133), S( 72,136), S( 72,141),
225 S( 77,147), S( 79,150), S( 93,151), S(108,168), S(108,168), S(108,171),
226 S(110,182), S(114,182), S(114,192), S(116,219) }
229 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
230 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
232 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
233 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
234 constexpr Score Outpost[] = { S(56, 34), S(31, 23) };
236 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
237 constexpr Score PassedRank[RANK_NB] = {
238 S(0, 0), S(9, 28), S(15, 31), S(17, 39), S(64, 70), S(171, 177), S(277, 260)
241 // RookOnFile[semiopen/open] contains bonuses for each rook when there is
242 // no (friendly) pawn on the rook file.
243 constexpr Score RookOnFile[] = { S(19, 7), S(48, 27) };
245 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
246 // which piece type attacks which one. Attacks on lesser pieces which are
247 // pawn-defended are not considered.
248 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
249 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
252 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
253 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
256 // Assorted bonuses and penalties
257 constexpr Score BadOutpost = S( -7, 36);
258 constexpr Score BishopOnKingRing = S( 24, 0);
259 constexpr Score BishopPawns = S( 3, 7);
260 constexpr Score BishopXRayPawns = S( 4, 5);
261 constexpr Score CorneredBishop = S( 50, 50);
262 constexpr Score FlankAttacks = S( 8, 0);
263 constexpr Score Hanging = S( 69, 36);
264 constexpr Score KnightOnQueen = S( 16, 11);
265 constexpr Score LongDiagonalBishop = S( 45, 0);
266 constexpr Score MinorBehindPawn = S( 18, 3);
267 constexpr Score PassedFile = S( 11, 8);
268 constexpr Score PawnlessFlank = S( 17, 95);
269 constexpr Score ReachableOutpost = S( 31, 22);
270 constexpr Score RestrictedPiece = S( 7, 7);
271 constexpr Score RookOnKingRing = S( 16, 0);
272 constexpr Score RookOnQueenFile = S( 6, 11);
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 * 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 the same file as a queen
489 if (file_bb(s) & pos.pieces(QUEEN))
490 score += RookOnQueenFile;
492 // Bonus for rook on an open or semi-open file
493 if (pos.is_on_semiopen_file(Us, s))
494 score += RookOnFile[pos.is_on_semiopen_file(Them, s)];
496 // Penalty when trapped by the king, even more if the king cannot castle
499 File kf = file_of(pos.square<KING>(Us));
500 if ((kf < FILE_E) == (file_of(s) < kf))
501 score -= TrappedRook * (1 + !pos.castling_rights(Us));
507 // Penalty if any relative pin or discovered attack against the queen
508 Bitboard queenPinners;
509 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
514 Trace::add(Pt, Us, score);
520 // Evaluation::king() assigns bonuses and penalties to a king of a given color
522 template<Tracing T> template<Color Us>
523 Score Evaluation<T>::king() const {
525 constexpr Color Them = ~Us;
526 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
527 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
529 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
530 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
532 const Square ksq = pos.square<KING>(Us);
534 // Init the score with king shelter and enemy pawns storm
535 Score score = pe->king_safety<Us>(pos);
537 // Attacked squares defended at most once by our queen or king
538 weak = attackedBy[Them][ALL_PIECES]
540 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
542 // Analyse the safe enemy's checks which are possible on next move
543 safe = ~pos.pieces(Them);
544 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
546 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
547 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
549 // Enemy rooks checks
550 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
552 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
554 unsafeChecks |= b1 & attackedBy[Them][ROOK];
556 // Enemy queen safe checks: count them only if the checks are from squares from
557 // which opponent cannot give a rook check, because rook checks are more valuable.
558 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
559 & ~(attackedBy[Us][QUEEN] | rookChecks);
561 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
563 // Enemy bishops checks: count them only if they are from squares from which
564 // opponent cannot give a queen check, because queen checks are more valuable.
565 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
568 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
571 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
573 // Enemy knights checks
574 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
575 if (knightChecks & safe)
576 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
578 unsafeChecks |= knightChecks;
580 // Find the squares that opponent attacks in our king flank, the squares
581 // which they attack twice in that flank, and the squares that we defend.
582 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
583 b2 = b1 & attackedBy2[Them];
584 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
586 int kingFlankAttack = popcount(b1) + popcount(b2);
587 int kingFlankDefense = popcount(b3);
589 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
590 + 185 * popcount(kingRing[Us] & weak)
591 + 148 * popcount(unsafeChecks)
592 + 98 * popcount(pos.blockers_for_king(Us))
593 + 69 * kingAttacksCount[Them]
594 + 3 * kingFlankAttack * kingFlankAttack / 8
595 + mg_value(mobility[Them] - mobility[Us])
596 - 873 * !pos.count<QUEEN>(Them)
597 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
598 - 6 * mg_value(score) / 8
599 - 4 * kingFlankDefense
602 // Transform the kingDanger units into a Score, and subtract it from the evaluation
603 if (kingDanger > 100)
604 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
606 // Penalty when our king is on a pawnless flank
607 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
608 score -= PawnlessFlank;
610 // Penalty if king flank is under attack, potentially moving toward the king
611 score -= FlankAttacks * kingFlankAttack;
614 Trace::add(KING, Us, score);
620 // Evaluation::threats() assigns bonuses according to the types of the
621 // attacking and the attacked pieces.
623 template<Tracing T> template<Color Us>
624 Score Evaluation<T>::threats() const {
626 constexpr Color Them = ~Us;
627 constexpr Direction Up = pawn_push(Us);
628 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
630 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
631 Score score = SCORE_ZERO;
634 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
636 // Squares strongly protected by the enemy, either because they defend the
637 // square with a pawn, or because they defend the square twice and we don't.
638 stronglyProtected = attackedBy[Them][PAWN]
639 | (attackedBy2[Them] & ~attackedBy2[Us]);
641 // Non-pawn enemies, strongly protected
642 defended = nonPawnEnemies & stronglyProtected;
644 // Enemies not strongly protected and under our attack
645 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
647 // Bonus according to the kind of attacking pieces
650 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
652 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
654 b = weak & attackedBy[Us][ROOK];
656 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
658 if (weak & attackedBy[Us][KING])
659 score += ThreatByKing;
661 b = ~attackedBy[Them][ALL_PIECES]
662 | (nonPawnEnemies & attackedBy2[Us]);
663 score += Hanging * popcount(weak & b);
665 // Additional bonus if weak piece is only protected by a queen
666 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
669 // Bonus for restricting their piece moves
670 b = attackedBy[Them][ALL_PIECES]
672 & attackedBy[Us][ALL_PIECES];
673 score += RestrictedPiece * popcount(b);
675 // Protected or unattacked squares
676 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
678 // Bonus for attacking enemy pieces with our relatively safe pawns
679 b = pos.pieces(Us, PAWN) & safe;
680 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
681 score += ThreatBySafePawn * popcount(b);
683 // Find squares where our pawns can push on the next move
684 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
685 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
687 // Keep only the squares which are relatively safe
688 b &= ~attackedBy[Them][PAWN] & safe;
690 // Bonus for safe pawn threats on the next move
691 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
692 score += ThreatByPawnPush * popcount(b);
694 // Bonus for threats on the next moves against enemy queen
695 if (pos.count<QUEEN>(Them) == 1)
697 bool queenImbalance = pos.count<QUEEN>() == 1;
699 Square s = pos.square<QUEEN>(Them);
700 safe = mobilityArea[Us]
701 & ~pos.pieces(Us, PAWN)
702 & ~stronglyProtected;
704 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
706 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
708 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
709 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
711 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
715 Trace::add(THREAT, Us, score);
720 // Evaluation::passed() evaluates the passed pawns and candidate passed
721 // pawns of the given color.
723 template<Tracing T> template<Color Us>
724 Score Evaluation<T>::passed() const {
726 constexpr Color Them = ~Us;
727 constexpr Direction Up = pawn_push(Us);
728 constexpr Direction Down = -Up;
730 auto king_proximity = [&](Color c, Square s) {
731 return std::min(distance(pos.square<KING>(c), s), 5);
734 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
735 Score score = SCORE_ZERO;
737 b = pe->passed_pawns(Us);
739 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
742 helpers = shift<Up>(pos.pieces(Us, PAWN))
744 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
746 // Remove blocked candidate passers that don't have help to pass
748 | shift<WEST>(helpers)
749 | shift<EAST>(helpers);
754 Square s = pop_lsb(&b);
756 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
758 int r = relative_rank(Us, s);
760 Score bonus = PassedRank[r];
765 Square blockSq = s + Up;
767 // Adjust bonus based on the king's proximity
768 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
769 - king_proximity(Us, blockSq) * 2) * w);
771 // If blockSq is not the queening square then consider also a second push
773 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
775 // If the pawn is free to advance, then increase the bonus
776 if (pos.empty(blockSq))
778 squaresToQueen = forward_file_bb(Us, s);
779 unsafeSquares = passed_pawn_span(Us, s);
781 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
783 if (!(pos.pieces(Them) & bb))
784 unsafeSquares &= attackedBy[Them][ALL_PIECES];
786 // If there are no enemy attacks on passed pawn span, assign a big bonus.
787 // Otherwise assign a smaller bonus if the path to queen is not attacked
788 // and even smaller bonus if it is attacked but block square is not.
789 int k = !unsafeSquares ? 35 :
790 !(unsafeSquares & squaresToQueen) ? 20 :
791 !(unsafeSquares & blockSq) ? 9 :
794 // Assign a larger bonus if the block square is defended
795 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
798 bonus += make_score(k * w, k * w);
802 score += bonus - PassedFile * edge_distance(file_of(s));
806 Trace::add(PASSED, Us, score);
812 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
813 // play in the opening. It is based on the number of safe squares on the four central files
814 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
815 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
817 template<Tracing T> template<Color Us>
818 Score Evaluation<T>::space() const {
820 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
821 if (pos.non_pawn_material() < SpaceThreshold)
824 constexpr Color Them = ~Us;
825 constexpr Direction Down = -pawn_push(Us);
826 constexpr Bitboard SpaceMask =
827 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
828 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
830 // Find the available squares for our pieces inside the area defined by SpaceMask
831 Bitboard safe = SpaceMask
832 & ~pos.pieces(Us, PAWN)
833 & ~attackedBy[Them][PAWN];
835 // Find all squares which are at most three squares behind some friendly pawn
836 Bitboard behind = pos.pieces(Us, PAWN);
837 behind |= shift<Down>(behind);
838 behind |= shift<Down+Down>(behind);
840 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
841 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
842 Score score = make_score(bonus * weight * weight / 16, 0);
845 Trace::add(SPACE, Us, score);
851 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
852 // the known attacking/defending status of the players. The final value is derived
853 // by interpolation from the midgame and endgame values.
856 Value Evaluation<T>::winnable(Score score) const {
858 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
859 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
861 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
862 && (pos.pieces(PAWN) & KingSide);
864 bool almostUnwinnable = outflanking < 0
865 && !pawnsOnBothFlanks;
867 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
868 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
870 // Compute the initiative bonus for the attacking side
871 int complexity = 9 * pe->passed_count()
872 + 12 * pos.count<PAWN>()
874 + 21 * pawnsOnBothFlanks
876 + 51 * !pos.non_pawn_material()
877 - 43 * almostUnwinnable
880 Value mg = mg_value(score);
881 Value eg = eg_value(score);
883 // Now apply the bonus: note that we find the attacking side by extracting the
884 // sign of the midgame or endgame values, and that we carefully cap the bonus
885 // so that the midgame and endgame scores do not change sign after the bonus.
886 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
887 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
892 // Compute the scale factor for the winning side
893 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
894 int sf = me->scale_factor(pos, strongSide);
896 // If scale factor is not already specific, scale down via general heuristics
897 if (sf == SCALE_FACTOR_NORMAL)
899 if (pos.opposite_bishops())
901 if ( pos.non_pawn_material(WHITE) == BishopValueMg
902 && pos.non_pawn_material(BLACK) == BishopValueMg)
903 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
905 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
907 else if ( pos.non_pawn_material(WHITE) == RookValueMg
908 && pos.non_pawn_material(BLACK) == RookValueMg
909 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
910 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
911 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
913 else if (pos.count<QUEEN>() == 1)
914 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
915 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
917 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide));
920 // Interpolate between the middlegame and (scaled by 'sf') endgame score
921 v = mg * int(me->game_phase())
922 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
927 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
928 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
935 // Evaluation::value() is the main function of the class. It computes the various
936 // parts of the evaluation and returns the value of the position from the point
937 // of view of the side to move.
940 Value Evaluation<T>::value() {
942 assert(!pos.checkers());
944 // Probe the material hash table
945 me = Material::probe(pos);
947 // If we have a specialized evaluation function for the current material
948 // configuration, call it and return.
949 if (me->specialized_eval_exists())
950 return me->evaluate(pos);
952 // Initialize score by reading the incrementally updated scores included in
953 // the position object (material + piece square tables) and the material
954 // imbalance. Score is computed internally from the white point of view.
955 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
957 // Probe the pawn hash table
958 pe = Pawns::probe(pos);
959 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
961 // Early exit if score is high
962 auto lazy_skip = [&](Value lazyThreshold) {
963 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
966 if (lazy_skip(LazyThreshold1))
969 // Main evaluation begins here
973 // Pieces evaluated first (also populates attackedBy, attackedBy2).
974 // Note that the order of evaluation of the terms is left unspecified.
975 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
976 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
977 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
978 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
980 score += mobility[WHITE] - mobility[BLACK];
982 // More complex interactions that require fully populated attack bitboards
983 score += king< WHITE>() - king< BLACK>()
984 + passed< WHITE>() - passed< BLACK>();
986 if (lazy_skip(LazyThreshold2))
989 score += threats<WHITE>() - threats<BLACK>()
990 + space< WHITE>() - space< BLACK>();
993 // Derive single value from mg and eg parts of score
994 Value v = winnable(score);
996 // In case of tracing add all remaining individual evaluation terms
999 Trace::add(MATERIAL, pos.psq_score());
1000 Trace::add(IMBALANCE, me->imbalance());
1001 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1002 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1008 // Side to move point of view
1009 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
1017 /// evaluate() is the evaluator for the outer world. It returns a static
1018 /// evaluation of the position from the point of view of the side to move.
1020 Value Eval::evaluate(const Position& pos) {
1022 // Use classical eval if there is a large imbalance
1023 // If there is a moderate imbalance, use classical eval with probability (1/8),
1024 // as derived from the node counter.
1025 bool useClassical = abs(eg_value(pos.psq_score())) * 16 > NNUEThreshold1 * (16 + pos.rule50_count());
1026 bool classical = !Eval::useNNUE
1028 || (abs(eg_value(pos.psq_score())) > PawnValueMg / 4 && !(pos.this_thread()->nodes & 0xB));
1029 Value v = classical ? Evaluation<NO_TRACE>(pos).value()
1030 : NNUE::evaluate(pos) * 5 / 4 + Tempo;
1034 && abs(v) * 16 < NNUEThreshold2 * (16 + pos.rule50_count()))
1035 v = NNUE::evaluate(pos) * 5 / 4 + Tempo;
1037 // Damp down the evaluation linearly when shuffling
1038 v = v * (100 - pos.rule50_count()) / 100;
1040 // Guarantee evaluation does not hit the tablebase range
1041 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1046 /// trace() is like evaluate(), but instead of returning a value, it returns
1047 /// a string (suitable for outputting to stdout) that contains the detailed
1048 /// descriptions and values of each evaluation term. Useful for debugging.
1049 /// Trace scores are from white's point of view
1051 std::string Eval::trace(const Position& pos) {
1054 return "Final evaluation: none (in check)";
1056 std::stringstream ss;
1057 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1061 std::memset(scores, 0, sizeof(scores));
1063 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
1065 v = Evaluation<TRACE>(pos).value();
1067 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1068 << " Term | White | Black | Total \n"
1069 << " | MG EG | MG EG | MG EG \n"
1070 << " ------------+-------------+-------------+------------\n"
1071 << " Material | " << Term(MATERIAL)
1072 << " Imbalance | " << Term(IMBALANCE)
1073 << " Pawns | " << Term(PAWN)
1074 << " Knights | " << Term(KNIGHT)
1075 << " Bishops | " << Term(BISHOP)
1076 << " Rooks | " << Term(ROOK)
1077 << " Queens | " << Term(QUEEN)
1078 << " Mobility | " << Term(MOBILITY)
1079 << " King safety | " << Term(KING)
1080 << " Threats | " << Term(THREAT)
1081 << " Passed | " << Term(PASSED)
1082 << " Space | " << Term(SPACE)
1083 << " Winnable | " << Term(WINNABLE)
1084 << " ------------+-------------+-------------+------------\n"
1085 << " Total | " << Term(TOTAL);
1087 v = pos.side_to_move() == WHITE ? v : -v;
1089 ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n";
1093 v = NNUE::evaluate(pos);
1094 v = pos.side_to_move() == WHITE ? v : -v;
1095 ss << "\nNNUE evaluation: " << to_cp(v) << " (white side)\n";
1099 v = pos.side_to_move() == WHITE ? v : -v;
1100 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";