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 std::string eval_file_loaded="None";
41 useNNUE = Options["Use NNUE"];
42 std::string eval_file = std::string(Options["EvalFile"]);
43 if (useNNUE && eval_file_loaded != eval_file)
44 if (Eval::NNUE::load_eval_file(eval_file))
45 eval_file_loaded = eval_file;
50 std::string eval_file = std::string(Options["EvalFile"]);
51 if (useNNUE && eval_file_loaded != eval_file)
53 std::cerr << "Use of NNUE evaluation, but the file " << eval_file << " was not loaded successfully. "
54 << "These network evaluation parameters must be available, compatible with this version of the code. "
55 << "The UCI option EvalFile might need to specify the full path, including the directory/folder name, to the file." << std::endl;
56 std::exit(EXIT_FAILURE);
60 sync_cout << "info string NNUE evaluation using " << eval_file << " enabled." << sync_endl;
62 sync_cout << "info string classical evaluation enabled." << sync_endl;
68 enum Tracing { NO_TRACE, TRACE };
70 enum Term { // The first 8 entries are reserved for PieceType
71 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
74 Score scores[TERM_NB][COLOR_NB];
76 double to_cp(Value v) { return double(v) / PawnValueEg; }
78 void add(int idx, Color c, Score s) {
82 void add(int idx, Score w, Score b = SCORE_ZERO) {
83 scores[idx][WHITE] = w;
84 scores[idx][BLACK] = b;
87 std::ostream& operator<<(std::ostream& os, Score s) {
88 os << std::setw(5) << to_cp(mg_value(s)) << " "
89 << std::setw(5) << to_cp(eg_value(s));
93 std::ostream& operator<<(std::ostream& os, Term t) {
95 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
96 os << " ---- ----" << " | " << " ---- ----";
98 os << scores[t][WHITE] << " | " << scores[t][BLACK];
100 os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
105 using namespace Trace;
109 // Threshold for lazy and space evaluation
110 constexpr Value LazyThreshold1 = Value(1400);
111 constexpr Value LazyThreshold2 = Value(1300);
112 constexpr Value SpaceThreshold = Value(12222);
113 constexpr Value NNUEThreshold = Value(500);
115 // KingAttackWeights[PieceType] contains king attack weights by piece type
116 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
118 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
119 // higher if multiple safe checks are possible for that piece type.
120 constexpr int SafeCheck[][2] = {
121 {}, {}, {792, 1283}, {645, 967}, {1084, 1897}, {772, 1119}
124 #define S(mg, eg) make_score(mg, eg)
126 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
127 // indexed by piece type and number of attacked squares in the mobility area.
128 constexpr Score MobilityBonus[][32] = {
129 { S(-62,-81), S(-53,-56), S(-12,-31), S( -4,-16), S( 3, 5), S( 13, 11), // Knight
130 S( 22, 17), S( 28, 20), S( 33, 25) },
131 { S(-48,-59), S(-20,-23), S( 16, -3), S( 26, 13), S( 38, 24), S( 51, 42), // Bishop
132 S( 55, 54), S( 63, 57), S( 63, 65), S( 68, 73), S( 81, 78), S( 81, 86),
133 S( 91, 88), S( 98, 97) },
134 { S(-60,-78), S(-20,-17), S( 2, 23), S( 3, 39), S( 3, 70), S( 11, 99), // Rook
135 S( 22,103), S( 31,121), S( 40,134), S( 40,139), S( 41,158), S( 48,164),
136 S( 57,168), S( 57,169), S( 62,172) },
137 { S(-30,-48), S(-12,-30), S( -8, -7), S( -9, 19), S( 20, 40), S( 23, 55), // Queen
138 S( 23, 59), S( 35, 75), S( 38, 78), S( 53, 96), S( 64, 96), S( 65,100),
139 S( 65,121), S( 66,127), S( 67,131), S( 67,133), S( 72,136), S( 72,141),
140 S( 77,147), S( 79,150), S( 93,151), S(108,168), S(108,168), S(108,171),
141 S(110,182), S(114,182), S(114,192), S(116,219) }
144 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
145 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
147 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
148 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
149 constexpr Score Outpost[] = { S(56, 36), S(30, 23) };
151 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
152 constexpr Score PassedRank[RANK_NB] = {
153 S(0, 0), S(10, 28), S(17, 33), S(15, 41), S(62, 72), S(168, 177), S(276, 260)
156 // RookOnFile[semiopen/open] contains bonuses for each rook when there is
157 // no (friendly) pawn on the rook file.
158 constexpr Score RookOnFile[] = { S(19, 7), S(48, 29) };
160 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
161 // which piece type attacks which one. Attacks on lesser pieces which are
162 // pawn-defended are not considered.
163 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
164 S(0, 0), S(5, 32), S(57, 41), S(77, 56), S(88, 119), S(79, 161)
167 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
168 S(0, 0), S(3, 46), S(37, 68), S(42, 60), S(0, 38), S(58, 41)
171 // Assorted bonuses and penalties
172 constexpr Score BadOutpost = S( -7, 36);
173 constexpr Score BishopOnKingRing = S( 24, 0);
174 constexpr Score BishopPawns = S( 3, 7);
175 constexpr Score BishopXRayPawns = S( 4, 5);
176 constexpr Score CorneredBishop = S( 50, 50);
177 constexpr Score FlankAttacks = S( 8, 0);
178 constexpr Score Hanging = S( 69, 36);
179 constexpr Score KnightOnQueen = S( 16, 11);
180 constexpr Score LongDiagonalBishop = S( 45, 0);
181 constexpr Score MinorBehindPawn = S( 18, 3);
182 constexpr Score PassedFile = S( 11, 8);
183 constexpr Score PawnlessFlank = S( 17, 95);
184 constexpr Score QueenInfiltration = S( -2, 14);
185 constexpr Score ReachableOutpost = S( 31, 22);
186 constexpr Score RestrictedPiece = S( 7, 7);
187 constexpr Score RookOnKingRing = S( 16, 0);
188 constexpr Score RookOnQueenFile = S( 6, 11);
189 constexpr Score SliderOnQueen = S( 60, 18);
190 constexpr Score ThreatByKing = S( 24, 89);
191 constexpr Score ThreatByPawnPush = S( 48, 39);
192 constexpr Score ThreatBySafePawn = S(173, 94);
193 constexpr Score TrappedRook = S( 55, 13);
194 constexpr Score WeakQueenProtection = S( 14, 0);
195 constexpr Score WeakQueen = S( 56, 15);
200 // Evaluation class computes and stores attacks tables and other working data
205 Evaluation() = delete;
206 explicit Evaluation(const Position& p) : pos(p) {}
207 Evaluation& operator=(const Evaluation&) = delete;
211 template<Color Us> void initialize();
212 template<Color Us, PieceType Pt> Score pieces();
213 template<Color Us> Score king() const;
214 template<Color Us> Score threats() const;
215 template<Color Us> Score passed() const;
216 template<Color Us> Score space() const;
217 Value winnable(Score score) const;
222 Bitboard mobilityArea[COLOR_NB];
223 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
225 // attackedBy[color][piece type] is a bitboard representing all squares
226 // attacked by a given color and piece type. Special "piece types" which
227 // is also calculated is ALL_PIECES.
228 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
230 // attackedBy2[color] are the squares attacked by at least 2 units of a given
231 // color, including x-rays. But diagonal x-rays through pawns are not computed.
232 Bitboard attackedBy2[COLOR_NB];
234 // kingRing[color] are the squares adjacent to the king plus some other
235 // very near squares, depending on king position.
236 Bitboard kingRing[COLOR_NB];
238 // kingAttackersCount[color] is the number of pieces of the given color
239 // which attack a square in the kingRing of the enemy king.
240 int kingAttackersCount[COLOR_NB];
242 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
243 // the given color which attack a square in the kingRing of the enemy king.
244 // The weights of the individual piece types are given by the elements in
245 // the KingAttackWeights array.
246 int kingAttackersWeight[COLOR_NB];
248 // kingAttacksCount[color] is the number of attacks by the given color to
249 // squares directly adjacent to the enemy king. Pieces which attack more
250 // than one square are counted multiple times. For instance, if there is
251 // a white knight on g5 and black's king is on g8, this white knight adds 2
252 // to kingAttacksCount[WHITE].
253 int kingAttacksCount[COLOR_NB];
257 // Evaluation::initialize() computes king and pawn attacks, and the king ring
258 // bitboard for a given color. This is done at the beginning of the evaluation.
260 template<Tracing T> template<Color Us>
261 void Evaluation<T>::initialize() {
263 constexpr Color Them = ~Us;
264 constexpr Direction Up = pawn_push(Us);
265 constexpr Direction Down = -Up;
266 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
268 const Square ksq = pos.square<KING>(Us);
270 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
272 // Find our pawns that are blocked or on the first two ranks
273 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
275 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
276 // or controlled by enemy pawns are excluded from the mobility area.
277 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
279 // Initialize attackedBy[] for king and pawns
280 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
281 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
282 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
283 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
285 // Init our king safety tables
286 Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, FILE_G),
287 Utility::clamp(rank_of(ksq), RANK_2, RANK_7));
288 kingRing[Us] = attacks_bb<KING>(s) | s;
290 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
291 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
293 // Remove from kingRing[] the squares defended by two pawns
294 kingRing[Us] &= ~dblAttackByPawn;
298 // Evaluation::pieces() scores pieces of a given color and type
300 template<Tracing T> template<Color Us, PieceType Pt>
301 Score Evaluation<T>::pieces() {
303 constexpr Color Them = ~Us;
304 constexpr Direction Down = -pawn_push(Us);
305 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
306 : Rank5BB | Rank4BB | Rank3BB);
307 const Square* pl = pos.squares<Pt>(Us);
310 Score score = SCORE_ZERO;
312 attackedBy[Us][Pt] = 0;
314 for (Square s = *pl; s != SQ_NONE; s = *++pl)
316 // Find attacked squares, including x-ray attacks for bishops and rooks
317 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
318 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
319 : attacks_bb<Pt>(s, pos.pieces());
321 if (pos.blockers_for_king(Us) & s)
322 b &= line_bb(pos.square<KING>(Us), s);
324 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
325 attackedBy[Us][Pt] |= b;
326 attackedBy[Us][ALL_PIECES] |= b;
328 if (b & kingRing[Them])
330 kingAttackersCount[Us]++;
331 kingAttackersWeight[Us] += KingAttackWeights[Pt];
332 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
335 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
336 score += RookOnKingRing;
338 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
339 score += BishopOnKingRing;
341 int mob = popcount(b & mobilityArea[Us]);
343 mobility[Us] += MobilityBonus[Pt - 2][mob];
345 if (Pt == BISHOP || Pt == KNIGHT)
347 // Bonus if the piece is on an outpost square or can reach one
348 // Reduced bonus for knights (BadOutpost) if few relevant targets
349 bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them);
350 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
353 && bb & s & ~CenterFiles // on a side outpost
354 && !(b & targets) // no relevant attacks
355 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
358 score += Outpost[Pt == BISHOP];
359 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
360 score += ReachableOutpost;
362 // Bonus for a knight or bishop shielded by pawn
363 if (shift<Down>(pos.pieces(PAWN)) & s)
364 score += MinorBehindPawn;
366 // Penalty if the piece is far from the king
367 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
371 // Penalty according to the number of our pawns on the same color square as the
372 // bishop, bigger when the center files are blocked with pawns and smaller
373 // when the bishop is outside the pawn chain.
374 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
376 score -= BishopPawns * pos.pawns_on_same_color_squares(Us, s)
377 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
379 // Penalty for all enemy pawns x-rayed
380 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
382 // Bonus for bishop on a long diagonal which can "see" both center squares
383 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
384 score += LongDiagonalBishop;
386 // An important Chess960 pattern: a cornered bishop blocked by a friendly
387 // pawn diagonally in front of it is a very serious problem, especially
388 // when that pawn is also blocked.
389 if ( pos.is_chess960()
390 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
392 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
393 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
394 score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
395 : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
403 // Bonus for rook on the same file as a queen
404 if (file_bb(s) & pos.pieces(QUEEN))
405 score += RookOnQueenFile;
407 // Bonus for rook on an open or semi-open file
408 if (pos.is_on_semiopen_file(Us, s))
409 score += RookOnFile[pos.is_on_semiopen_file(Them, s)];
411 // Penalty when trapped by the king, even more if the king cannot castle
414 File kf = file_of(pos.square<KING>(Us));
415 if ((kf < FILE_E) == (file_of(s) < kf))
416 score -= TrappedRook * (1 + !pos.castling_rights(Us));
422 // Penalty if any relative pin or discovered attack against the queen
423 Bitboard queenPinners;
424 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
427 // Bonus for queen on weak square in enemy camp
428 if (relative_rank(Us, s) > RANK_4 && (~pe->pawn_attacks_span(Them) & s))
429 score += QueenInfiltration;
433 Trace::add(Pt, Us, score);
439 // Evaluation::king() assigns bonuses and penalties to a king of a given color
441 template<Tracing T> template<Color Us>
442 Score Evaluation<T>::king() const {
444 constexpr Color Them = ~Us;
445 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
446 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
448 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
449 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
451 const Square ksq = pos.square<KING>(Us);
453 // Init the score with king shelter and enemy pawns storm
454 Score score = pe->king_safety<Us>(pos);
456 // Attacked squares defended at most once by our queen or king
457 weak = attackedBy[Them][ALL_PIECES]
459 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
461 // Analyse the safe enemy's checks which are possible on next move
462 safe = ~pos.pieces(Them);
463 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
465 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
466 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
468 // Enemy rooks checks
469 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
471 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
473 unsafeChecks |= b1 & attackedBy[Them][ROOK];
475 // Enemy queen safe checks: count them only if the checks are from squares from
476 // which opponent cannot give a rook check, because rook checks are more valuable.
477 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
478 & ~(attackedBy[Us][QUEEN] | rookChecks);
480 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
482 // Enemy bishops checks: count them only if they are from squares from which
483 // opponent cannot give a queen check, because queen checks are more valuable.
484 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
487 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
490 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
492 // Enemy knights checks
493 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
494 if (knightChecks & safe)
495 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
497 unsafeChecks |= knightChecks;
499 // Find the squares that opponent attacks in our king flank, the squares
500 // which they attack twice in that flank, and the squares that we defend.
501 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
502 b2 = b1 & attackedBy2[Them];
503 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
505 int kingFlankAttack = popcount(b1) + popcount(b2);
506 int kingFlankDefense = popcount(b3);
508 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
509 + 185 * popcount(kingRing[Us] & weak)
510 + 148 * popcount(unsafeChecks)
511 + 98 * popcount(pos.blockers_for_king(Us))
512 + 69 * kingAttacksCount[Them]
513 + 3 * kingFlankAttack * kingFlankAttack / 8
514 + mg_value(mobility[Them] - mobility[Us])
515 - 873 * !pos.count<QUEEN>(Them)
516 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
517 - 6 * mg_value(score) / 8
518 - 4 * kingFlankDefense
521 // Transform the kingDanger units into a Score, and subtract it from the evaluation
522 if (kingDanger > 100)
523 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
525 // Penalty when our king is on a pawnless flank
526 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
527 score -= PawnlessFlank;
529 // Penalty if king flank is under attack, potentially moving toward the king
530 score -= FlankAttacks * kingFlankAttack;
533 Trace::add(KING, Us, score);
539 // Evaluation::threats() assigns bonuses according to the types of the
540 // attacking and the attacked pieces.
542 template<Tracing T> template<Color Us>
543 Score Evaluation<T>::threats() const {
545 constexpr Color Them = ~Us;
546 constexpr Direction Up = pawn_push(Us);
547 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
549 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
550 Score score = SCORE_ZERO;
553 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
555 // Squares strongly protected by the enemy, either because they defend the
556 // square with a pawn, or because they defend the square twice and we don't.
557 stronglyProtected = attackedBy[Them][PAWN]
558 | (attackedBy2[Them] & ~attackedBy2[Us]);
560 // Non-pawn enemies, strongly protected
561 defended = nonPawnEnemies & stronglyProtected;
563 // Enemies not strongly protected and under our attack
564 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
566 // Bonus according to the kind of attacking pieces
569 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
571 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
573 b = weak & attackedBy[Us][ROOK];
575 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
577 if (weak & attackedBy[Us][KING])
578 score += ThreatByKing;
580 b = ~attackedBy[Them][ALL_PIECES]
581 | (nonPawnEnemies & attackedBy2[Us]);
582 score += Hanging * popcount(weak & b);
584 // Additional bonus if weak piece is only protected by a queen
585 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
588 // Bonus for restricting their piece moves
589 b = attackedBy[Them][ALL_PIECES]
591 & attackedBy[Us][ALL_PIECES];
592 score += RestrictedPiece * popcount(b);
594 // Protected or unattacked squares
595 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
597 // Bonus for attacking enemy pieces with our relatively safe pawns
598 b = pos.pieces(Us, PAWN) & safe;
599 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
600 score += ThreatBySafePawn * popcount(b);
602 // Find squares where our pawns can push on the next move
603 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
604 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
606 // Keep only the squares which are relatively safe
607 b &= ~attackedBy[Them][PAWN] & safe;
609 // Bonus for safe pawn threats on the next move
610 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
611 score += ThreatByPawnPush * popcount(b);
613 // Bonus for threats on the next moves against enemy queen
614 if (pos.count<QUEEN>(Them) == 1)
616 bool queenImbalance = pos.count<QUEEN>() == 1;
618 Square s = pos.square<QUEEN>(Them);
619 safe = mobilityArea[Us]
620 & ~pos.pieces(Us, PAWN)
621 & ~stronglyProtected;
623 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
625 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
627 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
628 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
630 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
634 Trace::add(THREAT, Us, score);
639 // Evaluation::passed() evaluates the passed pawns and candidate passed
640 // pawns of the given color.
642 template<Tracing T> template<Color Us>
643 Score Evaluation<T>::passed() const {
645 constexpr Color Them = ~Us;
646 constexpr Direction Up = pawn_push(Us);
647 constexpr Direction Down = -Up;
649 auto king_proximity = [&](Color c, Square s) {
650 return std::min(distance(pos.square<KING>(c), s), 5);
653 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
654 Score score = SCORE_ZERO;
656 b = pe->passed_pawns(Us);
658 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
661 helpers = shift<Up>(pos.pieces(Us, PAWN))
663 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
665 // Remove blocked candidate passers that don't have help to pass
667 | shift<WEST>(helpers)
668 | shift<EAST>(helpers);
673 Square s = pop_lsb(&b);
675 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
677 int r = relative_rank(Us, s);
679 Score bonus = PassedRank[r];
684 Square blockSq = s + Up;
686 // Adjust bonus based on the king's proximity
687 bonus += make_score(0, ( (king_proximity(Them, blockSq) * 19) / 4
688 - king_proximity(Us, blockSq) * 2) * w);
690 // If blockSq is not the queening square then consider also a second push
692 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
694 // If the pawn is free to advance, then increase the bonus
695 if (pos.empty(blockSq))
697 squaresToQueen = forward_file_bb(Us, s);
698 unsafeSquares = passed_pawn_span(Us, s);
700 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
702 if (!(pos.pieces(Them) & bb))
703 unsafeSquares &= attackedBy[Them][ALL_PIECES];
705 // If there are no enemy attacks on passed pawn span, assign a big bonus.
706 // Otherwise assign a smaller bonus if the path to queen is not attacked
707 // and even smaller bonus if it is attacked but block square is not.
708 int k = !unsafeSquares ? 35 :
709 !(unsafeSquares & squaresToQueen) ? 20 :
710 !(unsafeSquares & blockSq) ? 9 :
713 // Assign a larger bonus if the block square is defended
714 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
717 bonus += make_score(k * w, k * w);
721 score += bonus - PassedFile * edge_distance(file_of(s));
725 Trace::add(PASSED, Us, score);
731 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
732 // play in the opening. It is based on the number of safe squares on the 4 central files
733 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
734 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
736 template<Tracing T> template<Color Us>
737 Score Evaluation<T>::space() const {
739 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
740 if (pos.non_pawn_material() < SpaceThreshold)
743 constexpr Color Them = ~Us;
744 constexpr Direction Down = -pawn_push(Us);
745 constexpr Bitboard SpaceMask =
746 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
747 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
749 // Find the available squares for our pieces inside the area defined by SpaceMask
750 Bitboard safe = SpaceMask
751 & ~pos.pieces(Us, PAWN)
752 & ~attackedBy[Them][PAWN];
754 // Find all squares which are at most three squares behind some friendly pawn
755 Bitboard behind = pos.pieces(Us, PAWN);
756 behind |= shift<Down>(behind);
757 behind |= shift<Down+Down>(behind);
759 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
760 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
761 Score score = make_score(bonus * weight * weight / 16, 0);
764 Trace::add(SPACE, Us, score);
770 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
771 // the known attacking/defending status of the players. The final value is derived
772 // by interpolation from the midgame and endgame values.
775 Value Evaluation<T>::winnable(Score score) const {
777 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
778 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
780 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
781 && (pos.pieces(PAWN) & KingSide);
783 bool almostUnwinnable = outflanking < 0
784 && !pawnsOnBothFlanks;
786 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
787 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
789 // Compute the initiative bonus for the attacking side
790 int complexity = 9 * pe->passed_count()
791 + 12 * pos.count<PAWN>()
793 + 21 * pawnsOnBothFlanks
795 + 51 * !pos.non_pawn_material()
796 - 43 * almostUnwinnable
799 Value mg = mg_value(score);
800 Value eg = eg_value(score);
802 // Now apply the bonus: note that we find the attacking side by extracting the
803 // sign of the midgame or endgame values, and that we carefully cap the bonus
804 // so that the midgame and endgame scores do not change sign after the bonus.
805 int u = ((mg > 0) - (mg < 0)) * Utility::clamp(complexity + 50, -abs(mg), 0);
806 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
811 // Compute the scale factor for the winning side
812 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
813 int sf = me->scale_factor(pos, strongSide);
815 // If scale factor is not already specific, scale down via general heuristics
816 if (sf == SCALE_FACTOR_NORMAL)
818 if (pos.opposite_bishops())
820 if ( pos.non_pawn_material(WHITE) == BishopValueMg
821 && pos.non_pawn_material(BLACK) == BishopValueMg)
822 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
824 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
826 else if ( pos.non_pawn_material(WHITE) == RookValueMg
827 && pos.non_pawn_material(BLACK) == RookValueMg
828 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
829 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
830 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
832 else if (pos.count<QUEEN>() == 1)
833 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
834 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
836 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide));
839 // Interpolate between the middlegame and (scaled by 'sf') endgame score
840 v = mg * int(me->game_phase())
841 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
846 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
847 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
854 // Evaluation::value() is the main function of the class. It computes the various
855 // parts of the evaluation and returns the value of the position from the point
856 // of view of the side to move.
859 Value Evaluation<T>::value() {
861 assert(!pos.checkers());
863 // Probe the material hash table
864 me = Material::probe(pos);
866 // If we have a specialized evaluation function for the current material
867 // configuration, call it and return.
868 if (me->specialized_eval_exists())
869 return me->evaluate(pos);
871 // Initialize score by reading the incrementally updated scores included in
872 // the position object (material + piece square tables) and the material
873 // imbalance. Score is computed internally from the white point of view.
874 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
876 // Probe the pawn hash table
877 pe = Pawns::probe(pos);
878 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
880 // Early exit if score is high
881 auto lazy_skip = [&](Value lazyThreshold) {
882 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
885 if (lazy_skip(LazyThreshold1))
888 // Main evaluation begins here
892 // Pieces evaluated first (also populates attackedBy, attackedBy2).
893 // Note that the order of evaluation of the terms is left unspecified.
894 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
895 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
896 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
897 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
899 score += mobility[WHITE] - mobility[BLACK];
901 // More complex interactions that require fully populated attack bitboards
902 score += king< WHITE>() - king< BLACK>()
903 + passed< WHITE>() - passed< BLACK>();
905 if (lazy_skip(LazyThreshold2))
908 score += threats<WHITE>() - threats<BLACK>()
909 + space< WHITE>() - space< BLACK>();
912 // Derive single value from mg and eg parts of score
913 Value v = winnable(score);
915 // In case of tracing add all remaining individual evaluation terms
918 Trace::add(MATERIAL, pos.psq_score());
919 Trace::add(IMBALANCE, me->imbalance());
920 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
921 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
927 // Side to move point of view
928 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
930 // Damp down the evaluation linearly when shuffling
931 v = v * (100 - pos.rule50_count()) / 100;
939 /// evaluate() is the evaluator for the outer world. It returns a static
940 /// evaluation of the position from the point of view of the side to move.
942 Value Eval::evaluate(const Position& pos) {
946 Value balance = pos.non_pawn_material(WHITE) - pos.non_pawn_material(BLACK);
947 balance += 200 * (pos.count<PAWN>(WHITE) - pos.count<PAWN>(BLACK));
948 // Take NNUE eval only on balanced positions
949 if (abs(balance) < NNUEThreshold)
950 return NNUE::evaluate(pos) + Tempo;
952 return Evaluation<NO_TRACE>(pos).value();
955 /// trace() is like evaluate(), but instead of returning a value, it returns
956 /// a string (suitable for outputting to stdout) that contains the detailed
957 /// descriptions and values of each evaluation term. Useful for debugging.
958 /// Trace scores are from white's point of view
960 std::string Eval::trace(const Position& pos) {
963 return "Final evaluation: none (in check)";
965 std::stringstream ss;
966 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
972 v = NNUE::evaluate(pos);
976 std::memset(scores, 0, sizeof(scores));
978 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
980 v = Evaluation<TRACE>(pos).value();
982 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
983 << " Term | White | Black | Total \n"
984 << " | MG EG | MG EG | MG EG \n"
985 << " ------------+-------------+-------------+------------\n"
986 << " Material | " << Term(MATERIAL)
987 << " Imbalance | " << Term(IMBALANCE)
988 << " Pawns | " << Term(PAWN)
989 << " Knights | " << Term(KNIGHT)
990 << " Bishops | " << Term(BISHOP)
991 << " Rooks | " << Term(ROOK)
992 << " Queens | " << Term(QUEEN)
993 << " Mobility | " << Term(MOBILITY)
994 << " King safety | " << Term(KING)
995 << " Threats | " << Term(THREAT)
996 << " Passed | " << Term(PASSED)
997 << " Space | " << Term(SPACE)
998 << " Winnable | " << Term(WINNABLE)
999 << " ------------+-------------+-------------+------------\n"
1000 << " Total | " << Term(TOTAL);
1003 v = pos.side_to_move() == WHITE ? v : -v;
1005 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";