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(520);
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 ReachableOutpost = S( 31, 22);
185 constexpr Score RestrictedPiece = S( 7, 7);
186 constexpr Score RookOnKingRing = S( 16, 0);
187 constexpr Score RookOnQueenFile = S( 6, 11);
188 constexpr Score SliderOnQueen = S( 60, 18);
189 constexpr Score ThreatByKing = S( 24, 89);
190 constexpr Score ThreatByPawnPush = S( 48, 39);
191 constexpr Score ThreatBySafePawn = S(173, 94);
192 constexpr Score TrappedRook = S( 55, 13);
193 constexpr Score WeakQueenProtection = S( 14, 0);
194 constexpr Score WeakQueen = S( 56, 15);
199 // Evaluation class computes and stores attacks tables and other working data
204 Evaluation() = delete;
205 explicit Evaluation(const Position& p) : pos(p) {}
206 Evaluation& operator=(const Evaluation&) = delete;
210 template<Color Us> void initialize();
211 template<Color Us, PieceType Pt> Score pieces();
212 template<Color Us> Score king() const;
213 template<Color Us> Score threats() const;
214 template<Color Us> Score passed() const;
215 template<Color Us> Score space() const;
216 Value winnable(Score score) const;
221 Bitboard mobilityArea[COLOR_NB];
222 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
224 // attackedBy[color][piece type] is a bitboard representing all squares
225 // attacked by a given color and piece type. Special "piece types" which
226 // is also calculated is ALL_PIECES.
227 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
229 // attackedBy2[color] are the squares attacked by at least 2 units of a given
230 // color, including x-rays. But diagonal x-rays through pawns are not computed.
231 Bitboard attackedBy2[COLOR_NB];
233 // kingRing[color] are the squares adjacent to the king plus some other
234 // very near squares, depending on king position.
235 Bitboard kingRing[COLOR_NB];
237 // kingAttackersCount[color] is the number of pieces of the given color
238 // which attack a square in the kingRing of the enemy king.
239 int kingAttackersCount[COLOR_NB];
241 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
242 // the given color which attack a square in the kingRing of the enemy king.
243 // The weights of the individual piece types are given by the elements in
244 // the KingAttackWeights array.
245 int kingAttackersWeight[COLOR_NB];
247 // kingAttacksCount[color] is the number of attacks by the given color to
248 // squares directly adjacent to the enemy king. Pieces which attack more
249 // than one square are counted multiple times. For instance, if there is
250 // a white knight on g5 and black's king is on g8, this white knight adds 2
251 // to kingAttacksCount[WHITE].
252 int kingAttacksCount[COLOR_NB];
256 // Evaluation::initialize() computes king and pawn attacks, and the king ring
257 // bitboard for a given color. This is done at the beginning of the evaluation.
259 template<Tracing T> template<Color Us>
260 void Evaluation<T>::initialize() {
262 constexpr Color Them = ~Us;
263 constexpr Direction Up = pawn_push(Us);
264 constexpr Direction Down = -Up;
265 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
267 const Square ksq = pos.square<KING>(Us);
269 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
271 // Find our pawns that are blocked or on the first two ranks
272 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
274 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
275 // or controlled by enemy pawns are excluded from the mobility area.
276 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
278 // Initialize attackedBy[] for king and pawns
279 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
280 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
281 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
282 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
284 // Init our king safety tables
285 Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, FILE_G),
286 Utility::clamp(rank_of(ksq), RANK_2, RANK_7));
287 kingRing[Us] = attacks_bb<KING>(s) | s;
289 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
290 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
292 // Remove from kingRing[] the squares defended by two pawns
293 kingRing[Us] &= ~dblAttackByPawn;
297 // Evaluation::pieces() scores pieces of a given color and type
299 template<Tracing T> template<Color Us, PieceType Pt>
300 Score Evaluation<T>::pieces() {
302 constexpr Color Them = ~Us;
303 constexpr Direction Down = -pawn_push(Us);
304 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
305 : Rank5BB | Rank4BB | Rank3BB);
306 const Square* pl = pos.squares<Pt>(Us);
309 Score score = SCORE_ZERO;
311 attackedBy[Us][Pt] = 0;
313 for (Square s = *pl; s != SQ_NONE; s = *++pl)
315 // Find attacked squares, including x-ray attacks for bishops and rooks
316 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
317 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
318 : attacks_bb<Pt>(s, pos.pieces());
320 if (pos.blockers_for_king(Us) & s)
321 b &= line_bb(pos.square<KING>(Us), s);
323 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
324 attackedBy[Us][Pt] |= b;
325 attackedBy[Us][ALL_PIECES] |= b;
327 if (b & kingRing[Them])
329 kingAttackersCount[Us]++;
330 kingAttackersWeight[Us] += KingAttackWeights[Pt];
331 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
334 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
335 score += RookOnKingRing;
337 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
338 score += BishopOnKingRing;
340 int mob = popcount(b & mobilityArea[Us]);
342 mobility[Us] += MobilityBonus[Pt - 2][mob];
344 if (Pt == BISHOP || Pt == KNIGHT)
346 // Bonus if the piece is on an outpost square or can reach one
347 // Reduced bonus for knights (BadOutpost) if few relevant targets
348 bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
349 & ~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))
429 Trace::add(Pt, Us, score);
435 // Evaluation::king() assigns bonuses and penalties to a king of a given color
437 template<Tracing T> template<Color Us>
438 Score Evaluation<T>::king() const {
440 constexpr Color Them = ~Us;
441 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
442 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
444 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
445 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
447 const Square ksq = pos.square<KING>(Us);
449 // Init the score with king shelter and enemy pawns storm
450 Score score = pe->king_safety<Us>(pos);
452 // Attacked squares defended at most once by our queen or king
453 weak = attackedBy[Them][ALL_PIECES]
455 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
457 // Analyse the safe enemy's checks which are possible on next move
458 safe = ~pos.pieces(Them);
459 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
461 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
462 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
464 // Enemy rooks checks
465 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
467 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
469 unsafeChecks |= b1 & attackedBy[Them][ROOK];
471 // Enemy queen safe checks: count them only if the checks are from squares from
472 // which opponent cannot give a rook check, because rook checks are more valuable.
473 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
474 & ~(attackedBy[Us][QUEEN] | rookChecks);
476 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
478 // Enemy bishops checks: count them only if they are from squares from which
479 // opponent cannot give a queen check, because queen checks are more valuable.
480 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
483 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
486 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
488 // Enemy knights checks
489 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
490 if (knightChecks & safe)
491 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
493 unsafeChecks |= knightChecks;
495 // Find the squares that opponent attacks in our king flank, the squares
496 // which they attack twice in that flank, and the squares that we defend.
497 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
498 b2 = b1 & attackedBy2[Them];
499 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
501 int kingFlankAttack = popcount(b1) + popcount(b2);
502 int kingFlankDefense = popcount(b3);
504 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
505 + 185 * popcount(kingRing[Us] & weak)
506 + 148 * popcount(unsafeChecks)
507 + 98 * popcount(pos.blockers_for_king(Us))
508 + 69 * kingAttacksCount[Them]
509 + 3 * kingFlankAttack * kingFlankAttack / 8
510 + mg_value(mobility[Them] - mobility[Us])
511 - 873 * !pos.count<QUEEN>(Them)
512 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
513 - 6 * mg_value(score) / 8
514 - 4 * kingFlankDefense
517 // Transform the kingDanger units into a Score, and subtract it from the evaluation
518 if (kingDanger > 100)
519 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
521 // Penalty when our king is on a pawnless flank
522 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
523 score -= PawnlessFlank;
525 // Penalty if king flank is under attack, potentially moving toward the king
526 score -= FlankAttacks * kingFlankAttack;
529 Trace::add(KING, Us, score);
535 // Evaluation::threats() assigns bonuses according to the types of the
536 // attacking and the attacked pieces.
538 template<Tracing T> template<Color Us>
539 Score Evaluation<T>::threats() const {
541 constexpr Color Them = ~Us;
542 constexpr Direction Up = pawn_push(Us);
543 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
545 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
546 Score score = SCORE_ZERO;
549 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
551 // Squares strongly protected by the enemy, either because they defend the
552 // square with a pawn, or because they defend the square twice and we don't.
553 stronglyProtected = attackedBy[Them][PAWN]
554 | (attackedBy2[Them] & ~attackedBy2[Us]);
556 // Non-pawn enemies, strongly protected
557 defended = nonPawnEnemies & stronglyProtected;
559 // Enemies not strongly protected and under our attack
560 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
562 // Bonus according to the kind of attacking pieces
565 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
567 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
569 b = weak & attackedBy[Us][ROOK];
571 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
573 if (weak & attackedBy[Us][KING])
574 score += ThreatByKing;
576 b = ~attackedBy[Them][ALL_PIECES]
577 | (nonPawnEnemies & attackedBy2[Us]);
578 score += Hanging * popcount(weak & b);
580 // Additional bonus if weak piece is only protected by a queen
581 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
584 // Bonus for restricting their piece moves
585 b = attackedBy[Them][ALL_PIECES]
587 & attackedBy[Us][ALL_PIECES];
588 score += RestrictedPiece * popcount(b);
590 // Protected or unattacked squares
591 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
593 // Bonus for attacking enemy pieces with our relatively safe pawns
594 b = pos.pieces(Us, PAWN) & safe;
595 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
596 score += ThreatBySafePawn * popcount(b);
598 // Find squares where our pawns can push on the next move
599 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
600 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
602 // Keep only the squares which are relatively safe
603 b &= ~attackedBy[Them][PAWN] & safe;
605 // Bonus for safe pawn threats on the next move
606 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
607 score += ThreatByPawnPush * popcount(b);
609 // Bonus for threats on the next moves against enemy queen
610 if (pos.count<QUEEN>(Them) == 1)
612 bool queenImbalance = pos.count<QUEEN>() == 1;
614 Square s = pos.square<QUEEN>(Them);
615 safe = mobilityArea[Us]
616 & ~pos.pieces(Us, PAWN)
617 & ~stronglyProtected;
619 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
621 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
623 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
624 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
626 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
630 Trace::add(THREAT, Us, score);
635 // Evaluation::passed() evaluates the passed pawns and candidate passed
636 // pawns of the given color.
638 template<Tracing T> template<Color Us>
639 Score Evaluation<T>::passed() const {
641 constexpr Color Them = ~Us;
642 constexpr Direction Up = pawn_push(Us);
643 constexpr Direction Down = -Up;
645 auto king_proximity = [&](Color c, Square s) {
646 return std::min(distance(pos.square<KING>(c), s), 5);
649 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
650 Score score = SCORE_ZERO;
652 b = pe->passed_pawns(Us);
654 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
657 helpers = shift<Up>(pos.pieces(Us, PAWN))
659 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
661 // Remove blocked candidate passers that don't have help to pass
663 | shift<WEST>(helpers)
664 | shift<EAST>(helpers);
669 Square s = pop_lsb(&b);
671 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
673 int r = relative_rank(Us, s);
675 Score bonus = PassedRank[r];
680 Square blockSq = s + Up;
682 // Adjust bonus based on the king's proximity
683 bonus += make_score(0, ( (king_proximity(Them, blockSq) * 19) / 4
684 - king_proximity(Us, blockSq) * 2) * w);
686 // If blockSq is not the queening square then consider also a second push
688 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
690 // If the pawn is free to advance, then increase the bonus
691 if (pos.empty(blockSq))
693 squaresToQueen = forward_file_bb(Us, s);
694 unsafeSquares = passed_pawn_span(Us, s);
696 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
698 if (!(pos.pieces(Them) & bb))
699 unsafeSquares &= attackedBy[Them][ALL_PIECES];
701 // If there are no enemy attacks on passed pawn span, assign a big bonus.
702 // Otherwise assign a smaller bonus if the path to queen is not attacked
703 // and even smaller bonus if it is attacked but block square is not.
704 int k = !unsafeSquares ? 35 :
705 !(unsafeSquares & squaresToQueen) ? 20 :
706 !(unsafeSquares & blockSq) ? 9 :
709 // Assign a larger bonus if the block square is defended
710 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
713 bonus += make_score(k * w, k * w);
717 score += bonus - PassedFile * edge_distance(file_of(s));
721 Trace::add(PASSED, Us, score);
727 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
728 // play in the opening. It is based on the number of safe squares on the 4 central files
729 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
730 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
732 template<Tracing T> template<Color Us>
733 Score Evaluation<T>::space() const {
735 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
736 if (pos.non_pawn_material() < SpaceThreshold)
739 constexpr Color Them = ~Us;
740 constexpr Direction Down = -pawn_push(Us);
741 constexpr Bitboard SpaceMask =
742 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
743 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
745 // Find the available squares for our pieces inside the area defined by SpaceMask
746 Bitboard safe = SpaceMask
747 & ~pos.pieces(Us, PAWN)
748 & ~attackedBy[Them][PAWN];
750 // Find all squares which are at most three squares behind some friendly pawn
751 Bitboard behind = pos.pieces(Us, PAWN);
752 behind |= shift<Down>(behind);
753 behind |= shift<Down+Down>(behind);
755 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
756 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
757 Score score = make_score(bonus * weight * weight / 16, 0);
760 Trace::add(SPACE, Us, score);
766 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
767 // the known attacking/defending status of the players. The final value is derived
768 // by interpolation from the midgame and endgame values.
771 Value Evaluation<T>::winnable(Score score) const {
773 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
774 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
776 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
777 && (pos.pieces(PAWN) & KingSide);
779 bool almostUnwinnable = outflanking < 0
780 && !pawnsOnBothFlanks;
782 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
783 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
785 // Compute the initiative bonus for the attacking side
786 int complexity = 9 * pe->passed_count()
787 + 12 * pos.count<PAWN>()
789 + 21 * pawnsOnBothFlanks
791 + 51 * !pos.non_pawn_material()
792 - 43 * almostUnwinnable
795 Value mg = mg_value(score);
796 Value eg = eg_value(score);
798 // Now apply the bonus: note that we find the attacking side by extracting the
799 // sign of the midgame or endgame values, and that we carefully cap the bonus
800 // so that the midgame and endgame scores do not change sign after the bonus.
801 int u = ((mg > 0) - (mg < 0)) * Utility::clamp(complexity + 50, -abs(mg), 0);
802 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
807 // Compute the scale factor for the winning side
808 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
809 int sf = me->scale_factor(pos, strongSide);
811 // If scale factor is not already specific, scale down via general heuristics
812 if (sf == SCALE_FACTOR_NORMAL)
814 if (pos.opposite_bishops())
816 if ( pos.non_pawn_material(WHITE) == BishopValueMg
817 && pos.non_pawn_material(BLACK) == BishopValueMg)
818 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
820 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
822 else if ( pos.non_pawn_material(WHITE) == RookValueMg
823 && pos.non_pawn_material(BLACK) == RookValueMg
824 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
825 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
826 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
828 else if (pos.count<QUEEN>() == 1)
829 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
830 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
832 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide));
835 // Interpolate between the middlegame and (scaled by 'sf') endgame score
836 v = mg * int(me->game_phase())
837 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
842 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
843 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
850 // Evaluation::value() is the main function of the class. It computes the various
851 // parts of the evaluation and returns the value of the position from the point
852 // of view of the side to move.
855 Value Evaluation<T>::value() {
857 assert(!pos.checkers());
859 // Probe the material hash table
860 me = Material::probe(pos);
862 // If we have a specialized evaluation function for the current material
863 // configuration, call it and return.
864 if (me->specialized_eval_exists())
865 return me->evaluate(pos);
867 // Initialize score by reading the incrementally updated scores included in
868 // the position object (material + piece square tables) and the material
869 // imbalance. Score is computed internally from the white point of view.
870 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
872 // Probe the pawn hash table
873 pe = Pawns::probe(pos);
874 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
876 // Early exit if score is high
877 auto lazy_skip = [&](Value lazyThreshold) {
878 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
881 if (lazy_skip(LazyThreshold1))
884 // Main evaluation begins here
888 // Pieces evaluated first (also populates attackedBy, attackedBy2).
889 // Note that the order of evaluation of the terms is left unspecified.
890 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
891 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
892 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
893 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
895 score += mobility[WHITE] - mobility[BLACK];
897 // More complex interactions that require fully populated attack bitboards
898 score += king< WHITE>() - king< BLACK>()
899 + passed< WHITE>() - passed< BLACK>();
901 if (lazy_skip(LazyThreshold2))
904 score += threats<WHITE>() - threats<BLACK>()
905 + space< WHITE>() - space< BLACK>();
908 // Derive single value from mg and eg parts of score
909 Value v = winnable(score);
911 // In case of tracing add all remaining individual evaluation terms
914 Trace::add(MATERIAL, pos.psq_score());
915 Trace::add(IMBALANCE, me->imbalance());
916 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
917 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
923 // Side to move point of view
924 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
926 // Damp down the evaluation linearly when shuffling
927 v = v * (100 - pos.rule50_count()) / 100;
935 /// evaluate() is the evaluator for the outer world. It returns a static
936 /// evaluation of the position from the point of view of the side to move.
938 Value Eval::evaluate(const Position& pos) {
942 Value v = eg_value(pos.psq_score());
943 // Take NNUE eval only on balanced positions
944 if (abs(v) < NNUEThreshold)
945 return NNUE::evaluate(pos) + Tempo;
947 return Evaluation<NO_TRACE>(pos).value();
950 /// trace() is like evaluate(), but instead of returning a value, it returns
951 /// a string (suitable for outputting to stdout) that contains the detailed
952 /// descriptions and values of each evaluation term. Useful for debugging.
953 /// Trace scores are from white's point of view
955 std::string Eval::trace(const Position& pos) {
958 return "Final evaluation: none (in check)";
960 std::stringstream ss;
961 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
967 v = NNUE::evaluate(pos);
971 std::memset(scores, 0, sizeof(scores));
973 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
975 v = Evaluation<TRACE>(pos).value();
977 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
978 << " Term | White | Black | Total \n"
979 << " | MG EG | MG EG | MG EG \n"
980 << " ------------+-------------+-------------+------------\n"
981 << " Material | " << Term(MATERIAL)
982 << " Imbalance | " << Term(IMBALANCE)
983 << " Pawns | " << Term(PAWN)
984 << " Knights | " << Term(KNIGHT)
985 << " Bishops | " << Term(BISHOP)
986 << " Rooks | " << Term(ROOK)
987 << " Queens | " << Term(QUEEN)
988 << " Mobility | " << Term(MOBILITY)
989 << " King safety | " << Term(KING)
990 << " Threats | " << Term(THREAT)
991 << " Passed | " << Term(PASSED)
992 << " Space | " << Term(SPACE)
993 << " Winnable | " << Term(WINNABLE)
994 << " ------------+-------------+-------------+------------\n"
995 << " Total | " << Term(TOTAL);
998 v = pos.side_to_move() == WHITE ? v : -v;
1000 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";