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 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] & ~pe->pawn_attacks_span(Them);
349 Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
352 && bb & s & ~CenterFiles // on a side outpost
353 && !(b & targets) // no relevant attacks
354 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
357 score += Outpost[Pt == BISHOP];
358 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
359 score += ReachableOutpost;
361 // Bonus for a knight or bishop shielded by pawn
362 if (shift<Down>(pos.pieces(PAWN)) & s)
363 score += MinorBehindPawn;
365 // Penalty if the piece is far from the king
366 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
370 // Penalty according to the number of our pawns on the same color square as the
371 // bishop, bigger when the center files are blocked with pawns and smaller
372 // when the bishop is outside the pawn chain.
373 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
375 score -= BishopPawns * pos.pawns_on_same_color_squares(Us, s)
376 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
378 // Penalty for all enemy pawns x-rayed
379 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
381 // Bonus for bishop on a long diagonal which can "see" both center squares
382 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
383 score += LongDiagonalBishop;
385 // An important Chess960 pattern: a cornered bishop blocked by a friendly
386 // pawn diagonally in front of it is a very serious problem, especially
387 // when that pawn is also blocked.
388 if ( pos.is_chess960()
389 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
391 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
392 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
393 score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
394 : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
402 // Bonus for rook on the same file as a queen
403 if (file_bb(s) & pos.pieces(QUEEN))
404 score += RookOnQueenFile;
406 // Bonus for rook on an open or semi-open file
407 if (pos.is_on_semiopen_file(Us, s))
408 score += RookOnFile[pos.is_on_semiopen_file(Them, s)];
410 // Penalty when trapped by the king, even more if the king cannot castle
413 File kf = file_of(pos.square<KING>(Us));
414 if ((kf < FILE_E) == (file_of(s) < kf))
415 score -= TrappedRook * (1 + !pos.castling_rights(Us));
421 // Penalty if any relative pin or discovered attack against the queen
422 Bitboard queenPinners;
423 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
428 Trace::add(Pt, Us, score);
434 // Evaluation::king() assigns bonuses and penalties to a king of a given color
436 template<Tracing T> template<Color Us>
437 Score Evaluation<T>::king() const {
439 constexpr Color Them = ~Us;
440 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
441 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
443 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
444 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
446 const Square ksq = pos.square<KING>(Us);
448 // Init the score with king shelter and enemy pawns storm
449 Score score = pe->king_safety<Us>(pos);
451 // Attacked squares defended at most once by our queen or king
452 weak = attackedBy[Them][ALL_PIECES]
454 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
456 // Analyse the safe enemy's checks which are possible on next move
457 safe = ~pos.pieces(Them);
458 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
460 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
461 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
463 // Enemy rooks checks
464 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
466 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
468 unsafeChecks |= b1 & attackedBy[Them][ROOK];
470 // Enemy queen safe checks: count them only if the checks are from squares from
471 // which opponent cannot give a rook check, because rook checks are more valuable.
472 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
473 & ~(attackedBy[Us][QUEEN] | rookChecks);
475 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
477 // Enemy bishops checks: count them only if they are from squares from which
478 // opponent cannot give a queen check, because queen checks are more valuable.
479 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
482 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
485 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
487 // Enemy knights checks
488 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
489 if (knightChecks & safe)
490 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
492 unsafeChecks |= knightChecks;
494 // Find the squares that opponent attacks in our king flank, the squares
495 // which they attack twice in that flank, and the squares that we defend.
496 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
497 b2 = b1 & attackedBy2[Them];
498 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
500 int kingFlankAttack = popcount(b1) + popcount(b2);
501 int kingFlankDefense = popcount(b3);
503 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
504 + 185 * popcount(kingRing[Us] & weak)
505 + 148 * popcount(unsafeChecks)
506 + 98 * popcount(pos.blockers_for_king(Us))
507 + 69 * kingAttacksCount[Them]
508 + 3 * kingFlankAttack * kingFlankAttack / 8
509 + mg_value(mobility[Them] - mobility[Us])
510 - 873 * !pos.count<QUEEN>(Them)
511 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
512 - 6 * mg_value(score) / 8
513 - 4 * kingFlankDefense
516 // Transform the kingDanger units into a Score, and subtract it from the evaluation
517 if (kingDanger > 100)
518 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
520 // Penalty when our king is on a pawnless flank
521 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
522 score -= PawnlessFlank;
524 // Penalty if king flank is under attack, potentially moving toward the king
525 score -= FlankAttacks * kingFlankAttack;
528 Trace::add(KING, Us, score);
534 // Evaluation::threats() assigns bonuses according to the types of the
535 // attacking and the attacked pieces.
537 template<Tracing T> template<Color Us>
538 Score Evaluation<T>::threats() const {
540 constexpr Color Them = ~Us;
541 constexpr Direction Up = pawn_push(Us);
542 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
544 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
545 Score score = SCORE_ZERO;
548 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
550 // Squares strongly protected by the enemy, either because they defend the
551 // square with a pawn, or because they defend the square twice and we don't.
552 stronglyProtected = attackedBy[Them][PAWN]
553 | (attackedBy2[Them] & ~attackedBy2[Us]);
555 // Non-pawn enemies, strongly protected
556 defended = nonPawnEnemies & stronglyProtected;
558 // Enemies not strongly protected and under our attack
559 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
561 // Bonus according to the kind of attacking pieces
564 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
566 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
568 b = weak & attackedBy[Us][ROOK];
570 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
572 if (weak & attackedBy[Us][KING])
573 score += ThreatByKing;
575 b = ~attackedBy[Them][ALL_PIECES]
576 | (nonPawnEnemies & attackedBy2[Us]);
577 score += Hanging * popcount(weak & b);
579 // Additional bonus if weak piece is only protected by a queen
580 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
583 // Bonus for restricting their piece moves
584 b = attackedBy[Them][ALL_PIECES]
586 & attackedBy[Us][ALL_PIECES];
587 score += RestrictedPiece * popcount(b);
589 // Protected or unattacked squares
590 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
592 // Bonus for attacking enemy pieces with our relatively safe pawns
593 b = pos.pieces(Us, PAWN) & safe;
594 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
595 score += ThreatBySafePawn * popcount(b);
597 // Find squares where our pawns can push on the next move
598 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
599 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
601 // Keep only the squares which are relatively safe
602 b &= ~attackedBy[Them][PAWN] & safe;
604 // Bonus for safe pawn threats on the next move
605 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
606 score += ThreatByPawnPush * popcount(b);
608 // Bonus for threats on the next moves against enemy queen
609 if (pos.count<QUEEN>(Them) == 1)
611 bool queenImbalance = pos.count<QUEEN>() == 1;
613 Square s = pos.square<QUEEN>(Them);
614 safe = mobilityArea[Us]
615 & ~pos.pieces(Us, PAWN)
616 & ~stronglyProtected;
618 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
620 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
622 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
623 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
625 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
629 Trace::add(THREAT, Us, score);
634 // Evaluation::passed() evaluates the passed pawns and candidate passed
635 // pawns of the given color.
637 template<Tracing T> template<Color Us>
638 Score Evaluation<T>::passed() const {
640 constexpr Color Them = ~Us;
641 constexpr Direction Up = pawn_push(Us);
642 constexpr Direction Down = -Up;
644 auto king_proximity = [&](Color c, Square s) {
645 return std::min(distance(pos.square<KING>(c), s), 5);
648 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
649 Score score = SCORE_ZERO;
651 b = pe->passed_pawns(Us);
653 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
656 helpers = shift<Up>(pos.pieces(Us, PAWN))
658 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
660 // Remove blocked candidate passers that don't have help to pass
662 | shift<WEST>(helpers)
663 | shift<EAST>(helpers);
668 Square s = pop_lsb(&b);
670 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
672 int r = relative_rank(Us, s);
674 Score bonus = PassedRank[r];
679 Square blockSq = s + Up;
681 // Adjust bonus based on the king's proximity
682 bonus += make_score(0, ( (king_proximity(Them, blockSq) * 19) / 4
683 - king_proximity(Us, blockSq) * 2) * w);
685 // If blockSq is not the queening square then consider also a second push
687 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
689 // If the pawn is free to advance, then increase the bonus
690 if (pos.empty(blockSq))
692 squaresToQueen = forward_file_bb(Us, s);
693 unsafeSquares = passed_pawn_span(Us, s);
695 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
697 if (!(pos.pieces(Them) & bb))
698 unsafeSquares &= attackedBy[Them][ALL_PIECES];
700 // If there are no enemy attacks on passed pawn span, assign a big bonus.
701 // Otherwise assign a smaller bonus if the path to queen is not attacked
702 // and even smaller bonus if it is attacked but block square is not.
703 int k = !unsafeSquares ? 35 :
704 !(unsafeSquares & squaresToQueen) ? 20 :
705 !(unsafeSquares & blockSq) ? 9 :
708 // Assign a larger bonus if the block square is defended
709 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
712 bonus += make_score(k * w, k * w);
716 score += bonus - PassedFile * edge_distance(file_of(s));
720 Trace::add(PASSED, Us, score);
726 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
727 // play in the opening. It is based on the number of safe squares on the 4 central files
728 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
729 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
731 template<Tracing T> template<Color Us>
732 Score Evaluation<T>::space() const {
734 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
735 if (pos.non_pawn_material() < SpaceThreshold)
738 constexpr Color Them = ~Us;
739 constexpr Direction Down = -pawn_push(Us);
740 constexpr Bitboard SpaceMask =
741 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
742 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
744 // Find the available squares for our pieces inside the area defined by SpaceMask
745 Bitboard safe = SpaceMask
746 & ~pos.pieces(Us, PAWN)
747 & ~attackedBy[Them][PAWN];
749 // Find all squares which are at most three squares behind some friendly pawn
750 Bitboard behind = pos.pieces(Us, PAWN);
751 behind |= shift<Down>(behind);
752 behind |= shift<Down+Down>(behind);
754 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
755 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
756 Score score = make_score(bonus * weight * weight / 16, 0);
759 Trace::add(SPACE, Us, score);
765 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
766 // the known attacking/defending status of the players. The final value is derived
767 // by interpolation from the midgame and endgame values.
770 Value Evaluation<T>::winnable(Score score) const {
772 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
773 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
775 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
776 && (pos.pieces(PAWN) & KingSide);
778 bool almostUnwinnable = outflanking < 0
779 && !pawnsOnBothFlanks;
781 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
782 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
784 // Compute the initiative bonus for the attacking side
785 int complexity = 9 * pe->passed_count()
786 + 12 * pos.count<PAWN>()
788 + 21 * pawnsOnBothFlanks
790 + 51 * !pos.non_pawn_material()
791 - 43 * almostUnwinnable
794 Value mg = mg_value(score);
795 Value eg = eg_value(score);
797 // Now apply the bonus: note that we find the attacking side by extracting the
798 // sign of the midgame or endgame values, and that we carefully cap the bonus
799 // so that the midgame and endgame scores do not change sign after the bonus.
800 int u = ((mg > 0) - (mg < 0)) * Utility::clamp(complexity + 50, -abs(mg), 0);
801 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
806 // Compute the scale factor for the winning side
807 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
808 int sf = me->scale_factor(pos, strongSide);
810 // If scale factor is not already specific, scale down via general heuristics
811 if (sf == SCALE_FACTOR_NORMAL)
813 if (pos.opposite_bishops())
815 if ( pos.non_pawn_material(WHITE) == BishopValueMg
816 && pos.non_pawn_material(BLACK) == BishopValueMg)
817 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
819 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
821 else if ( pos.non_pawn_material(WHITE) == RookValueMg
822 && pos.non_pawn_material(BLACK) == RookValueMg
823 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
824 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
825 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
827 else if (pos.count<QUEEN>() == 1)
828 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
829 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
831 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide));
834 // Interpolate between the middlegame and (scaled by 'sf') endgame score
835 v = mg * int(me->game_phase())
836 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
841 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
842 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
849 // Evaluation::value() is the main function of the class. It computes the various
850 // parts of the evaluation and returns the value of the position from the point
851 // of view of the side to move.
854 Value Evaluation<T>::value() {
856 assert(!pos.checkers());
858 // Probe the material hash table
859 me = Material::probe(pos);
861 // If we have a specialized evaluation function for the current material
862 // configuration, call it and return.
863 if (me->specialized_eval_exists())
864 return me->evaluate(pos);
866 // Initialize score by reading the incrementally updated scores included in
867 // the position object (material + piece square tables) and the material
868 // imbalance. Score is computed internally from the white point of view.
869 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
871 // Probe the pawn hash table
872 pe = Pawns::probe(pos);
873 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
875 // Early exit if score is high
876 auto lazy_skip = [&](Value lazyThreshold) {
877 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
880 if (lazy_skip(LazyThreshold1))
883 // Main evaluation begins here
887 // Pieces evaluated first (also populates attackedBy, attackedBy2).
888 // Note that the order of evaluation of the terms is left unspecified.
889 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
890 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
891 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
892 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
894 score += mobility[WHITE] - mobility[BLACK];
896 // More complex interactions that require fully populated attack bitboards
897 score += king< WHITE>() - king< BLACK>()
898 + passed< WHITE>() - passed< BLACK>();
900 if (lazy_skip(LazyThreshold2))
903 score += threats<WHITE>() - threats<BLACK>()
904 + space< WHITE>() - space< BLACK>();
907 // Derive single value from mg and eg parts of score
908 Value v = winnable(score);
910 // In case of tracing add all remaining individual evaluation terms
913 Trace::add(MATERIAL, pos.psq_score());
914 Trace::add(IMBALANCE, me->imbalance());
915 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
916 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
922 // Side to move point of view
923 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
925 // Damp down the evaluation linearly when shuffling
926 v = v * (100 - pos.rule50_count()) / 100;
934 /// evaluate() is the evaluator for the outer world. It returns a static
935 /// evaluation of the position from the point of view of the side to move.
937 Value Eval::evaluate(const Position& pos) {
941 Value balance = pos.non_pawn_material(WHITE) - pos.non_pawn_material(BLACK);
942 balance += 200 * (pos.count<PAWN>(WHITE) - pos.count<PAWN>(BLACK));
943 // Take NNUE eval only on balanced positions
944 if (abs(balance) < 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";