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(1400);
191 constexpr Value LazyThreshold2 = Value(1300);
192 constexpr Value SpaceThreshold = Value(12222);
193 constexpr Value NNUEThreshold1 = Value(550);
194 constexpr Value NNUEThreshold2 = Value(150);
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(-61,-82), S(-20,-17), S( 2, 23) ,S( 3, 40), S( 4, 72), S( 11,100), // Rook
216 S( 22,104), S( 31,120), S( 39,134), S(40 ,138), S( 41,158), S( 47,163),
217 S( 59,168), S( 60,169), S( 64,173) },
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 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
226 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
228 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
229 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
230 constexpr Score Outpost[] = { S(56, 34), S(31, 23) };
232 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
233 constexpr Score PassedRank[RANK_NB] = {
234 S(0, 0), S(9, 28), S(15, 31), S(17, 39), S(64, 70), S(171, 177), S(277, 260)
237 // RookOnFile[semiopen/open] contains bonuses for each rook when there is
238 // no (friendly) pawn on the rook file.
239 constexpr Score RookOnFile[] = { S(19, 7), S(48, 27) };
241 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
242 // which piece type attacks which one. Attacks on lesser pieces which are
243 // pawn-defended are not considered.
244 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
245 S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
248 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
249 S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
252 // Assorted bonuses and penalties
253 constexpr Score BadOutpost = S( -7, 36);
254 constexpr Score BishopOnKingRing = S( 24, 0);
255 constexpr Score BishopPawns = S( 3, 7);
256 constexpr Score BishopXRayPawns = S( 4, 5);
257 constexpr Score CorneredBishop = S( 50, 50);
258 constexpr Score FlankAttacks = S( 8, 0);
259 constexpr Score Hanging = S( 69, 36);
260 constexpr Score KnightOnQueen = S( 16, 11);
261 constexpr Score LongDiagonalBishop = S( 45, 0);
262 constexpr Score MinorBehindPawn = S( 18, 3);
263 constexpr Score PassedFile = S( 11, 8);
264 constexpr Score PawnlessFlank = S( 17, 95);
265 constexpr Score ReachableOutpost = S( 31, 22);
266 constexpr Score RestrictedPiece = S( 7, 7);
267 constexpr Score RookOnKingRing = S( 16, 0);
268 constexpr Score SliderOnQueen = S( 60, 18);
269 constexpr Score ThreatByKing = S( 24, 89);
270 constexpr Score ThreatByPawnPush = S( 48, 39);
271 constexpr Score ThreatBySafePawn = S(173, 94);
272 constexpr Score TrappedRook = S( 55, 13);
273 constexpr Score WeakQueenProtection = S( 14, 0);
274 constexpr Score WeakQueen = S( 56, 15);
279 // Evaluation class computes and stores attacks tables and other working data
284 Evaluation() = delete;
285 explicit Evaluation(const Position& p) : pos(p) {}
286 Evaluation& operator=(const Evaluation&) = delete;
290 template<Color Us> void initialize();
291 template<Color Us, PieceType Pt> Score pieces();
292 template<Color Us> Score king() const;
293 template<Color Us> Score threats() const;
294 template<Color Us> Score passed() const;
295 template<Color Us> Score space() const;
296 Value winnable(Score score) const;
301 Bitboard mobilityArea[COLOR_NB];
302 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
304 // attackedBy[color][piece type] is a bitboard representing all squares
305 // attacked by a given color and piece type. Special "piece types" which
306 // is also calculated is ALL_PIECES.
307 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
309 // attackedBy2[color] are the squares attacked by at least 2 units of a given
310 // color, including x-rays. But diagonal x-rays through pawns are not computed.
311 Bitboard attackedBy2[COLOR_NB];
313 // kingRing[color] are the squares adjacent to the king plus some other
314 // very near squares, depending on king position.
315 Bitboard kingRing[COLOR_NB];
317 // kingAttackersCount[color] is the number of pieces of the given color
318 // which attack a square in the kingRing of the enemy king.
319 int kingAttackersCount[COLOR_NB];
321 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
322 // the given color which attack a square in the kingRing of the enemy king.
323 // The weights of the individual piece types are given by the elements in
324 // the KingAttackWeights array.
325 int kingAttackersWeight[COLOR_NB];
327 // kingAttacksCount[color] is the number of attacks by the given color to
328 // squares directly adjacent to the enemy king. Pieces which attack more
329 // than one square are counted multiple times. For instance, if there is
330 // a white knight on g5 and black's king is on g8, this white knight adds 2
331 // to kingAttacksCount[WHITE].
332 int kingAttacksCount[COLOR_NB];
336 // Evaluation::initialize() computes king and pawn attacks, and the king ring
337 // bitboard for a given color. This is done at the beginning of the evaluation.
339 template<Tracing T> template<Color Us>
340 void Evaluation<T>::initialize() {
342 constexpr Color Them = ~Us;
343 constexpr Direction Up = pawn_push(Us);
344 constexpr Direction Down = -Up;
345 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
347 const Square ksq = pos.square<KING>(Us);
349 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
351 // Find our pawns that are blocked or on the first two ranks
352 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
354 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
355 // or controlled by enemy pawns are excluded from the mobility area.
356 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
358 // Initialize attackedBy[] for king and pawns
359 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
360 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
361 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
362 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
364 // Init our king safety tables
365 Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
366 std::clamp(rank_of(ksq), RANK_2, RANK_7));
367 kingRing[Us] = attacks_bb<KING>(s) | s;
369 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
370 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
372 // Remove from kingRing[] the squares defended by two pawns
373 kingRing[Us] &= ~dblAttackByPawn;
377 // Evaluation::pieces() scores pieces of a given color and type
379 template<Tracing T> template<Color Us, PieceType Pt>
380 Score Evaluation<T>::pieces() {
382 constexpr Color Them = ~Us;
383 constexpr Direction Down = -pawn_push(Us);
384 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
385 : Rank5BB | Rank4BB | Rank3BB);
386 const Square* pl = pos.squares<Pt>(Us);
389 Score score = SCORE_ZERO;
391 attackedBy[Us][Pt] = 0;
393 for (Square s = *pl; s != SQ_NONE; s = *++pl)
395 // Find attacked squares, including x-ray attacks for bishops and rooks
396 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
397 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
398 : attacks_bb<Pt>(s, pos.pieces());
400 if (pos.blockers_for_king(Us) & s)
401 b &= line_bb(pos.square<KING>(Us), s);
403 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
404 attackedBy[Us][Pt] |= b;
405 attackedBy[Us][ALL_PIECES] |= b;
407 if (b & kingRing[Them])
409 kingAttackersCount[Us]++;
410 kingAttackersWeight[Us] += KingAttackWeights[Pt];
411 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
414 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
415 score += RookOnKingRing;
417 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
418 score += BishopOnKingRing;
420 int mob = popcount(b & mobilityArea[Us]);
422 mobility[Us] += MobilityBonus[Pt - 2][mob];
424 if (Pt == BISHOP || Pt == KNIGHT)
426 // Bonus if the piece is on an outpost square or can reach one
427 // Reduced bonus for knights (BadOutpost) if few relevant targets
428 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
429 & ~pe->pawn_attacks_span(Them);
430 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
433 && bb & s & ~CenterFiles // on a side outpost
434 && !(b & targets) // no relevant attacks
435 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
438 score += Outpost[Pt == BISHOP];
439 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
440 score += ReachableOutpost;
442 // Bonus for a knight or bishop shielded by pawn
443 if (shift<Down>(pos.pieces(PAWN)) & s)
444 score += MinorBehindPawn;
446 // Penalty if the piece is far from the king
447 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
451 // Penalty according to the number of our pawns on the same color square as the
452 // bishop, bigger when the center files are blocked with pawns and smaller
453 // when the bishop is outside the pawn chain.
454 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
456 score -= BishopPawns * pos.pawns_on_same_color_squares(Us, s)
457 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
459 // Penalty for all enemy pawns x-rayed
460 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
462 // Bonus for bishop on a long diagonal which can "see" both center squares
463 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
464 score += LongDiagonalBishop;
466 // An important Chess960 pattern: a cornered bishop blocked by a friendly
467 // pawn diagonally in front of it is a very serious problem, especially
468 // when that pawn is also blocked.
469 if ( pos.is_chess960()
470 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
472 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
473 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
474 score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
475 : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
483 // Bonus for rook on an open or semi-open file
484 if (pos.is_on_semiopen_file(Us, s))
485 score += RookOnFile[pos.is_on_semiopen_file(Them, s)];
487 // Penalty when trapped by the king, even more if the king cannot castle
490 File kf = file_of(pos.square<KING>(Us));
491 if ((kf < FILE_E) == (file_of(s) < kf))
492 score -= TrappedRook * (1 + !pos.castling_rights(Us));
498 // Penalty if any relative pin or discovered attack against the queen
499 Bitboard queenPinners;
500 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
505 Trace::add(Pt, Us, score);
511 // Evaluation::king() assigns bonuses and penalties to a king of a given color
513 template<Tracing T> template<Color Us>
514 Score Evaluation<T>::king() const {
516 constexpr Color Them = ~Us;
517 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
518 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
520 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
521 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
523 const Square ksq = pos.square<KING>(Us);
525 // Init the score with king shelter and enemy pawns storm
526 Score score = pe->king_safety<Us>(pos);
528 // Attacked squares defended at most once by our queen or king
529 weak = attackedBy[Them][ALL_PIECES]
531 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
533 // Analyse the safe enemy's checks which are possible on next move
534 safe = ~pos.pieces(Them);
535 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
537 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
538 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
540 // Enemy rooks checks
541 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
543 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
545 unsafeChecks |= b1 & attackedBy[Them][ROOK];
547 // Enemy queen safe checks: count them only if the checks are from squares from
548 // which opponent cannot give a rook check, because rook checks are more valuable.
549 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
550 & ~(attackedBy[Us][QUEEN] | rookChecks);
552 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
554 // Enemy bishops checks: count them only if they are from squares from which
555 // opponent cannot give a queen check, because queen checks are more valuable.
556 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
559 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
562 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
564 // Enemy knights checks
565 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
566 if (knightChecks & safe)
567 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
569 unsafeChecks |= knightChecks;
571 // Find the squares that opponent attacks in our king flank, the squares
572 // which they attack twice in that flank, and the squares that we defend.
573 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
574 b2 = b1 & attackedBy2[Them];
575 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
577 int kingFlankAttack = popcount(b1) + popcount(b2);
578 int kingFlankDefense = popcount(b3);
580 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
581 + 185 * popcount(kingRing[Us] & weak)
582 + 148 * popcount(unsafeChecks)
583 + 98 * popcount(pos.blockers_for_king(Us))
584 + 69 * kingAttacksCount[Them]
585 + 3 * kingFlankAttack * kingFlankAttack / 8
586 + mg_value(mobility[Them] - mobility[Us])
587 - 873 * !pos.count<QUEEN>(Them)
588 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
589 - 6 * mg_value(score) / 8
590 - 4 * kingFlankDefense
593 // Transform the kingDanger units into a Score, and subtract it from the evaluation
594 if (kingDanger > 100)
595 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
597 // Penalty when our king is on a pawnless flank
598 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
599 score -= PawnlessFlank;
601 // Penalty if king flank is under attack, potentially moving toward the king
602 score -= FlankAttacks * kingFlankAttack;
605 Trace::add(KING, Us, score);
611 // Evaluation::threats() assigns bonuses according to the types of the
612 // attacking and the attacked pieces.
614 template<Tracing T> template<Color Us>
615 Score Evaluation<T>::threats() const {
617 constexpr Color Them = ~Us;
618 constexpr Direction Up = pawn_push(Us);
619 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
621 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
622 Score score = SCORE_ZERO;
625 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
627 // Squares strongly protected by the enemy, either because they defend the
628 // square with a pawn, or because they defend the square twice and we don't.
629 stronglyProtected = attackedBy[Them][PAWN]
630 | (attackedBy2[Them] & ~attackedBy2[Us]);
632 // Non-pawn enemies, strongly protected
633 defended = nonPawnEnemies & stronglyProtected;
635 // Enemies not strongly protected and under our attack
636 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
638 // Bonus according to the kind of attacking pieces
641 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
643 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
645 b = weak & attackedBy[Us][ROOK];
647 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
649 if (weak & attackedBy[Us][KING])
650 score += ThreatByKing;
652 b = ~attackedBy[Them][ALL_PIECES]
653 | (nonPawnEnemies & attackedBy2[Us]);
654 score += Hanging * popcount(weak & b);
656 // Additional bonus if weak piece is only protected by a queen
657 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
660 // Bonus for restricting their piece moves
661 b = attackedBy[Them][ALL_PIECES]
663 & attackedBy[Us][ALL_PIECES];
664 score += RestrictedPiece * popcount(b);
666 // Protected or unattacked squares
667 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
669 // Bonus for attacking enemy pieces with our relatively safe pawns
670 b = pos.pieces(Us, PAWN) & safe;
671 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
672 score += ThreatBySafePawn * popcount(b);
674 // Find squares where our pawns can push on the next move
675 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
676 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
678 // Keep only the squares which are relatively safe
679 b &= ~attackedBy[Them][PAWN] & safe;
681 // Bonus for safe pawn threats on the next move
682 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
683 score += ThreatByPawnPush * popcount(b);
685 // Bonus for threats on the next moves against enemy queen
686 if (pos.count<QUEEN>(Them) == 1)
688 bool queenImbalance = pos.count<QUEEN>() == 1;
690 Square s = pos.square<QUEEN>(Them);
691 safe = mobilityArea[Us]
692 & ~pos.pieces(Us, PAWN)
693 & ~stronglyProtected;
695 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
697 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
699 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
700 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
702 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
706 Trace::add(THREAT, Us, score);
711 // Evaluation::passed() evaluates the passed pawns and candidate passed
712 // pawns of the given color.
714 template<Tracing T> template<Color Us>
715 Score Evaluation<T>::passed() const {
717 constexpr Color Them = ~Us;
718 constexpr Direction Up = pawn_push(Us);
719 constexpr Direction Down = -Up;
721 auto king_proximity = [&](Color c, Square s) {
722 return std::min(distance(pos.square<KING>(c), s), 5);
725 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
726 Score score = SCORE_ZERO;
728 b = pe->passed_pawns(Us);
730 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
733 helpers = shift<Up>(pos.pieces(Us, PAWN))
735 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
737 // Remove blocked candidate passers that don't have help to pass
739 | shift<WEST>(helpers)
740 | shift<EAST>(helpers);
745 Square s = pop_lsb(&b);
747 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
749 int r = relative_rank(Us, s);
751 Score bonus = PassedRank[r];
756 Square blockSq = s + Up;
758 // Adjust bonus based on the king's proximity
759 bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
760 - king_proximity(Us, blockSq) * 2) * w);
762 // If blockSq is not the queening square then consider also a second push
764 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
766 // If the pawn is free to advance, then increase the bonus
767 if (pos.empty(blockSq))
769 squaresToQueen = forward_file_bb(Us, s);
770 unsafeSquares = passed_pawn_span(Us, s);
772 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
774 if (!(pos.pieces(Them) & bb))
775 unsafeSquares &= attackedBy[Them][ALL_PIECES];
777 // If there are no enemy attacks on passed pawn span, assign a big bonus.
778 // Otherwise assign a smaller bonus if the path to queen is not attacked
779 // and even smaller bonus if it is attacked but block square is not.
780 int k = !unsafeSquares ? 35 :
781 !(unsafeSquares & squaresToQueen) ? 20 :
782 !(unsafeSquares & blockSq) ? 9 :
785 // Assign a larger bonus if the block square is defended
786 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
789 bonus += make_score(k * w, k * w);
793 score += bonus - PassedFile * edge_distance(file_of(s));
797 Trace::add(PASSED, Us, score);
803 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
804 // play in the opening. It is based on the number of safe squares on the four central files
805 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
806 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
808 template<Tracing T> template<Color Us>
809 Score Evaluation<T>::space() const {
811 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
812 if (pos.non_pawn_material() < SpaceThreshold)
815 constexpr Color Them = ~Us;
816 constexpr Direction Down = -pawn_push(Us);
817 constexpr Bitboard SpaceMask =
818 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
819 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
821 // Find the available squares for our pieces inside the area defined by SpaceMask
822 Bitboard safe = SpaceMask
823 & ~pos.pieces(Us, PAWN)
824 & ~attackedBy[Them][PAWN];
826 // Find all squares which are at most three squares behind some friendly pawn
827 Bitboard behind = pos.pieces(Us, PAWN);
828 behind |= shift<Down>(behind);
829 behind |= shift<Down+Down>(behind);
831 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
832 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
833 Score score = make_score(bonus * weight * weight / 16, 0);
836 Trace::add(SPACE, Us, score);
842 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
843 // the known attacking/defending status of the players. The final value is derived
844 // by interpolation from the midgame and endgame values.
847 Value Evaluation<T>::winnable(Score score) const {
849 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
850 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
852 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
853 && (pos.pieces(PAWN) & KingSide);
855 bool almostUnwinnable = outflanking < 0
856 && !pawnsOnBothFlanks;
858 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
859 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
861 // Compute the initiative bonus for the attacking side
862 int complexity = 9 * pe->passed_count()
863 + 12 * pos.count<PAWN>()
865 + 21 * pawnsOnBothFlanks
867 + 51 * !pos.non_pawn_material()
868 - 43 * almostUnwinnable
871 Value mg = mg_value(score);
872 Value eg = eg_value(score);
874 // Now apply the bonus: note that we find the attacking side by extracting the
875 // sign of the midgame or endgame values, and that we carefully cap the bonus
876 // so that the midgame and endgame scores do not change sign after the bonus.
877 int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
878 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
883 // Compute the scale factor for the winning side
884 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
885 int sf = me->scale_factor(pos, strongSide);
887 // If scale factor is not already specific, scale down via general heuristics
888 if (sf == SCALE_FACTOR_NORMAL)
890 if (pos.opposite_bishops())
892 if ( pos.non_pawn_material(WHITE) == BishopValueMg
893 && pos.non_pawn_material(BLACK) == BishopValueMg)
894 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
896 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
898 else if ( pos.non_pawn_material(WHITE) == RookValueMg
899 && pos.non_pawn_material(BLACK) == RookValueMg
900 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
901 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
902 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
904 else if (pos.count<QUEEN>() == 1)
905 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
906 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
908 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide));
911 // Interpolate between the middlegame and (scaled by 'sf') endgame score
912 v = mg * int(me->game_phase())
913 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
918 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
919 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
926 // Evaluation::value() is the main function of the class. It computes the various
927 // parts of the evaluation and returns the value of the position from the point
928 // of view of the side to move.
931 Value Evaluation<T>::value() {
933 assert(!pos.checkers());
935 // Probe the material hash table
936 me = Material::probe(pos);
938 // If we have a specialized evaluation function for the current material
939 // configuration, call it and return.
940 if (me->specialized_eval_exists())
941 return me->evaluate(pos);
943 // Initialize score by reading the incrementally updated scores included in
944 // the position object (material + piece square tables) and the material
945 // imbalance. Score is computed internally from the white point of view.
946 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
948 // Probe the pawn hash table
949 pe = Pawns::probe(pos);
950 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
952 // Early exit if score is high
953 auto lazy_skip = [&](Value lazyThreshold) {
954 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
957 if (lazy_skip(LazyThreshold1))
960 // Main evaluation begins here
964 // Pieces evaluated first (also populates attackedBy, attackedBy2).
965 // Note that the order of evaluation of the terms is left unspecified.
966 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
967 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
968 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
969 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
971 score += mobility[WHITE] - mobility[BLACK];
973 // More complex interactions that require fully populated attack bitboards
974 score += king< WHITE>() - king< BLACK>()
975 + passed< WHITE>() - passed< BLACK>();
977 if (lazy_skip(LazyThreshold2))
980 score += threats<WHITE>() - threats<BLACK>()
981 + space< WHITE>() - space< BLACK>();
984 // Derive single value from mg and eg parts of score
985 Value v = winnable(score);
987 // In case of tracing add all remaining individual evaluation terms
990 Trace::add(MATERIAL, pos.psq_score());
991 Trace::add(IMBALANCE, me->imbalance());
992 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
993 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
999 // Side to move point of view
1000 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
1008 /// evaluate() is the evaluator for the outer world. It returns a static
1009 /// evaluation of the position from the point of view of the side to move.
1011 Value Eval::evaluate(const Position& pos) {
1016 v = Evaluation<NO_TRACE>(pos).value();
1019 // Scale and shift NNUE for compatibility with search and classical evaluation
1020 auto adjusted_NNUE = [&](){
1021 int mat = pos.non_pawn_material() + PieceValue[MG][PAWN] * pos.count<PAWN>();
1022 return NNUE::evaluate(pos) * (720 + mat / 32) / 1024 + Tempo;
1025 // If there is PSQ imbalance use classical eval, with small probability if it is small
1026 Value psq = Value(abs(eg_value(pos.psq_score())));
1027 int r50 = 16 + pos.rule50_count();
1028 bool largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50;
1029 bool classical = largePsq || (psq > PawnValueMg / 4 && !(pos.this_thread()->nodes & 0xB));
1031 v = classical ? Evaluation<NO_TRACE>(pos).value() : adjusted_NNUE();
1033 // If the classical eval is small and imbalance large, use NNUE nevertheless.
1034 // For the case of opposite colored bishops, switch to NNUE eval with
1035 // small probability if the classical eval is less than the threshold.
1037 && (abs(v) * 16 < NNUEThreshold2 * r50
1038 || ( pos.opposite_bishops()
1039 && abs(v) * 16 < (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50
1040 && !(pos.this_thread()->nodes & 0xB))))
1041 v = adjusted_NNUE();
1044 // Damp down the evaluation linearly when shuffling
1045 v = v * (100 - pos.rule50_count()) / 100;
1047 // Guarantee evaluation does not hit the tablebase range
1048 v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1053 /// trace() is like evaluate(), but instead of returning a value, it returns
1054 /// a string (suitable for outputting to stdout) that contains the detailed
1055 /// descriptions and values of each evaluation term. Useful for debugging.
1056 /// Trace scores are from white's point of view
1058 std::string Eval::trace(const Position& pos) {
1061 return "Final evaluation: none (in check)";
1063 std::stringstream ss;
1064 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1068 std::memset(scores, 0, sizeof(scores));
1070 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
1072 v = Evaluation<TRACE>(pos).value();
1074 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1075 << " Term | White | Black | Total \n"
1076 << " | MG EG | MG EG | MG EG \n"
1077 << " ------------+-------------+-------------+------------\n"
1078 << " Material | " << Term(MATERIAL)
1079 << " Imbalance | " << Term(IMBALANCE)
1080 << " Pawns | " << Term(PAWN)
1081 << " Knights | " << Term(KNIGHT)
1082 << " Bishops | " << Term(BISHOP)
1083 << " Rooks | " << Term(ROOK)
1084 << " Queens | " << Term(QUEEN)
1085 << " Mobility | " << Term(MOBILITY)
1086 << " King safety | " << Term(KING)
1087 << " Threats | " << Term(THREAT)
1088 << " Passed | " << Term(PASSED)
1089 << " Space | " << Term(SPACE)
1090 << " Winnable | " << Term(WINNABLE)
1091 << " ------------+-------------+-------------+------------\n"
1092 << " Total | " << Term(TOTAL);
1094 v = pos.side_to_move() == WHITE ? v : -v;
1096 ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n";
1100 v = NNUE::evaluate(pos);
1101 v = pos.side_to_move() == WHITE ? v : -v;
1102 ss << "\nNNUE evaluation: " << to_cp(v) << " (white side)\n";
1106 v = pos.side_to_move() == WHITE ? v : -v;
1107 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";