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);
114 // KingAttackWeights[PieceType] contains king attack weights by piece type
115 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
117 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
118 // higher if multiple safe checks are possible for that piece type.
119 constexpr int SafeCheck[][2] = {
120 {}, {}, {792, 1283}, {645, 967}, {1084, 1897}, {772, 1119}
123 #define S(mg, eg) make_score(mg, eg)
125 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
126 // indexed by piece type and number of attacked squares in the mobility area.
127 constexpr Score MobilityBonus[][32] = {
128 { S(-62,-81), S(-53,-56), S(-12,-31), S( -4,-16), S( 3, 5), S( 13, 11), // Knight
129 S( 22, 17), S( 28, 20), S( 33, 25) },
130 { S(-48,-59), S(-20,-23), S( 16, -3), S( 26, 13), S( 38, 24), S( 51, 42), // Bishop
131 S( 55, 54), S( 63, 57), S( 63, 65), S( 68, 73), S( 81, 78), S( 81, 86),
132 S( 91, 88), S( 98, 97) },
133 { S(-60,-78), S(-20,-17), S( 2, 23), S( 3, 39), S( 3, 70), S( 11, 99), // Rook
134 S( 22,103), S( 31,121), S( 40,134), S( 40,139), S( 41,158), S( 48,164),
135 S( 57,168), S( 57,169), S( 62,172) },
136 { S(-30,-48), S(-12,-30), S( -8, -7), S( -9, 19), S( 20, 40), S( 23, 55), // Queen
137 S( 23, 59), S( 35, 75), S( 38, 78), S( 53, 96), S( 64, 96), S( 65,100),
138 S( 65,121), S( 66,127), S( 67,131), S( 67,133), S( 72,136), S( 72,141),
139 S( 77,147), S( 79,150), S( 93,151), S(108,168), S(108,168), S(108,171),
140 S(110,182), S(114,182), S(114,192), S(116,219) }
143 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
144 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
146 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
147 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
148 constexpr Score Outpost[] = { S(56, 36), S(30, 23) };
150 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
151 constexpr Score PassedRank[RANK_NB] = {
152 S(0, 0), S(10, 28), S(17, 33), S(15, 41), S(62, 72), S(168, 177), S(276, 260)
155 // RookOnFile[semiopen/open] contains bonuses for each rook when there is
156 // no (friendly) pawn on the rook file.
157 constexpr Score RookOnFile[] = { S(19, 7), S(48, 29) };
159 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
160 // which piece type attacks which one. Attacks on lesser pieces which are
161 // pawn-defended are not considered.
162 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
163 S(0, 0), S(5, 32), S(57, 41), S(77, 56), S(88, 119), S(79, 161)
166 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
167 S(0, 0), S(3, 46), S(37, 68), S(42, 60), S(0, 38), S(58, 41)
170 // Assorted bonuses and penalties
171 constexpr Score BadOutpost = S( -7, 36);
172 constexpr Score BishopOnKingRing = S( 24, 0);
173 constexpr Score BishopPawns = S( 3, 7);
174 constexpr Score BishopXRayPawns = S( 4, 5);
175 constexpr Score CorneredBishop = S( 50, 50);
176 constexpr Score FlankAttacks = S( 8, 0);
177 constexpr Score Hanging = S( 69, 36);
178 constexpr Score KnightOnQueen = S( 16, 11);
179 constexpr Score LongDiagonalBishop = S( 45, 0);
180 constexpr Score MinorBehindPawn = S( 18, 3);
181 constexpr Score PassedFile = S( 11, 8);
182 constexpr Score PawnlessFlank = S( 17, 95);
183 constexpr Score QueenInfiltration = S( -2, 14);
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))
426 // Bonus for queen on weak square in enemy camp
427 if (relative_rank(Us, s) > RANK_4 && (~pe->pawn_attacks_span(Them) & s))
428 score += QueenInfiltration;
432 Trace::add(Pt, Us, score);
438 // Evaluation::king() assigns bonuses and penalties to a king of a given color
440 template<Tracing T> template<Color Us>
441 Score Evaluation<T>::king() const {
443 constexpr Color Them = ~Us;
444 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
445 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
447 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
448 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
450 const Square ksq = pos.square<KING>(Us);
452 // Init the score with king shelter and enemy pawns storm
453 Score score = pe->king_safety<Us>(pos);
455 // Attacked squares defended at most once by our queen or king
456 weak = attackedBy[Them][ALL_PIECES]
458 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
460 // Analyse the safe enemy's checks which are possible on next move
461 safe = ~pos.pieces(Them);
462 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
464 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
465 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
467 // Enemy rooks checks
468 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
470 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
472 unsafeChecks |= b1 & attackedBy[Them][ROOK];
474 // Enemy queen safe checks: count them only if the checks are from squares from
475 // which opponent cannot give a rook check, because rook checks are more valuable.
476 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
477 & ~(attackedBy[Us][QUEEN] | rookChecks);
479 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
481 // Enemy bishops checks: count them only if they are from squares from which
482 // opponent cannot give a queen check, because queen checks are more valuable.
483 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
486 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
489 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
491 // Enemy knights checks
492 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
493 if (knightChecks & safe)
494 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
496 unsafeChecks |= knightChecks;
498 // Find the squares that opponent attacks in our king flank, the squares
499 // which they attack twice in that flank, and the squares that we defend.
500 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
501 b2 = b1 & attackedBy2[Them];
502 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
504 int kingFlankAttack = popcount(b1) + popcount(b2);
505 int kingFlankDefense = popcount(b3);
507 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
508 + 185 * popcount(kingRing[Us] & weak)
509 + 148 * popcount(unsafeChecks)
510 + 98 * popcount(pos.blockers_for_king(Us))
511 + 69 * kingAttacksCount[Them]
512 + 3 * kingFlankAttack * kingFlankAttack / 8
513 + mg_value(mobility[Them] - mobility[Us])
514 - 873 * !pos.count<QUEEN>(Them)
515 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
516 - 6 * mg_value(score) / 8
517 - 4 * kingFlankDefense
520 // Transform the kingDanger units into a Score, and subtract it from the evaluation
521 if (kingDanger > 100)
522 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
524 // Penalty when our king is on a pawnless flank
525 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
526 score -= PawnlessFlank;
528 // Penalty if king flank is under attack, potentially moving toward the king
529 score -= FlankAttacks * kingFlankAttack;
532 Trace::add(KING, Us, score);
538 // Evaluation::threats() assigns bonuses according to the types of the
539 // attacking and the attacked pieces.
541 template<Tracing T> template<Color Us>
542 Score Evaluation<T>::threats() const {
544 constexpr Color Them = ~Us;
545 constexpr Direction Up = pawn_push(Us);
546 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
548 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
549 Score score = SCORE_ZERO;
552 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
554 // Squares strongly protected by the enemy, either because they defend the
555 // square with a pawn, or because they defend the square twice and we don't.
556 stronglyProtected = attackedBy[Them][PAWN]
557 | (attackedBy2[Them] & ~attackedBy2[Us]);
559 // Non-pawn enemies, strongly protected
560 defended = nonPawnEnemies & stronglyProtected;
562 // Enemies not strongly protected and under our attack
563 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
565 // Bonus according to the kind of attacking pieces
568 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
570 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
572 b = weak & attackedBy[Us][ROOK];
574 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
576 if (weak & attackedBy[Us][KING])
577 score += ThreatByKing;
579 b = ~attackedBy[Them][ALL_PIECES]
580 | (nonPawnEnemies & attackedBy2[Us]);
581 score += Hanging * popcount(weak & b);
583 // Additional bonus if weak piece is only protected by a queen
584 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
587 // Bonus for restricting their piece moves
588 b = attackedBy[Them][ALL_PIECES]
590 & attackedBy[Us][ALL_PIECES];
591 score += RestrictedPiece * popcount(b);
593 // Protected or unattacked squares
594 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
596 // Bonus for attacking enemy pieces with our relatively safe pawns
597 b = pos.pieces(Us, PAWN) & safe;
598 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
599 score += ThreatBySafePawn * popcount(b);
601 // Find squares where our pawns can push on the next move
602 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
603 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
605 // Keep only the squares which are relatively safe
606 b &= ~attackedBy[Them][PAWN] & safe;
608 // Bonus for safe pawn threats on the next move
609 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
610 score += ThreatByPawnPush * popcount(b);
612 // Bonus for threats on the next moves against enemy queen
613 if (pos.count<QUEEN>(Them) == 1)
615 bool queenImbalance = pos.count<QUEEN>() == 1;
617 Square s = pos.square<QUEEN>(Them);
618 safe = mobilityArea[Us]
619 & ~pos.pieces(Us, PAWN)
620 & ~stronglyProtected;
622 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
624 score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
626 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
627 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
629 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
633 Trace::add(THREAT, Us, score);
638 // Evaluation::passed() evaluates the passed pawns and candidate passed
639 // pawns of the given color.
641 template<Tracing T> template<Color Us>
642 Score Evaluation<T>::passed() const {
644 constexpr Color Them = ~Us;
645 constexpr Direction Up = pawn_push(Us);
646 constexpr Direction Down = -Up;
648 auto king_proximity = [&](Color c, Square s) {
649 return std::min(distance(pos.square<KING>(c), s), 5);
652 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
653 Score score = SCORE_ZERO;
655 b = pe->passed_pawns(Us);
657 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
660 helpers = shift<Up>(pos.pieces(Us, PAWN))
662 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
664 // Remove blocked candidate passers that don't have help to pass
666 | shift<WEST>(helpers)
667 | shift<EAST>(helpers);
672 Square s = pop_lsb(&b);
674 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
676 int r = relative_rank(Us, s);
678 Score bonus = PassedRank[r];
683 Square blockSq = s + Up;
685 // Adjust bonus based on the king's proximity
686 bonus += make_score(0, ( (king_proximity(Them, blockSq) * 19) / 4
687 - king_proximity(Us, blockSq) * 2) * w);
689 // If blockSq is not the queening square then consider also a second push
691 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
693 // If the pawn is free to advance, then increase the bonus
694 if (pos.empty(blockSq))
696 squaresToQueen = forward_file_bb(Us, s);
697 unsafeSquares = passed_pawn_span(Us, s);
699 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
701 if (!(pos.pieces(Them) & bb))
702 unsafeSquares &= attackedBy[Them][ALL_PIECES];
704 // If there are no enemy attacks on passed pawn span, assign a big bonus.
705 // Otherwise assign a smaller bonus if the path to queen is not attacked
706 // and even smaller bonus if it is attacked but block square is not.
707 int k = !unsafeSquares ? 35 :
708 !(unsafeSquares & squaresToQueen) ? 20 :
709 !(unsafeSquares & blockSq) ? 9 :
712 // Assign a larger bonus if the block square is defended
713 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
716 bonus += make_score(k * w, k * w);
720 score += bonus - PassedFile * edge_distance(file_of(s));
724 Trace::add(PASSED, Us, score);
730 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
731 // play in the opening. It is based on the number of safe squares on the 4 central files
732 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
733 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
735 template<Tracing T> template<Color Us>
736 Score Evaluation<T>::space() const {
738 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
739 if (pos.non_pawn_material() < SpaceThreshold)
742 constexpr Color Them = ~Us;
743 constexpr Direction Down = -pawn_push(Us);
744 constexpr Bitboard SpaceMask =
745 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
746 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
748 // Find the available squares for our pieces inside the area defined by SpaceMask
749 Bitboard safe = SpaceMask
750 & ~pos.pieces(Us, PAWN)
751 & ~attackedBy[Them][PAWN];
753 // Find all squares which are at most three squares behind some friendly pawn
754 Bitboard behind = pos.pieces(Us, PAWN);
755 behind |= shift<Down>(behind);
756 behind |= shift<Down+Down>(behind);
758 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
759 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
760 Score score = make_score(bonus * weight * weight / 16, 0);
763 Trace::add(SPACE, Us, score);
769 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
770 // the known attacking/defending status of the players. The final value is derived
771 // by interpolation from the midgame and endgame values.
774 Value Evaluation<T>::winnable(Score score) const {
776 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
777 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
779 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
780 && (pos.pieces(PAWN) & KingSide);
782 bool almostUnwinnable = outflanking < 0
783 && !pawnsOnBothFlanks;
785 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
786 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
788 // Compute the initiative bonus for the attacking side
789 int complexity = 9 * pe->passed_count()
790 + 12 * pos.count<PAWN>()
792 + 21 * pawnsOnBothFlanks
794 + 51 * !pos.non_pawn_material()
795 - 43 * almostUnwinnable
798 Value mg = mg_value(score);
799 Value eg = eg_value(score);
801 // Now apply the bonus: note that we find the attacking side by extracting the
802 // sign of the midgame or endgame values, and that we carefully cap the bonus
803 // so that the midgame and endgame scores do not change sign after the bonus.
804 int u = ((mg > 0) - (mg < 0)) * Utility::clamp(complexity + 50, -abs(mg), 0);
805 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
810 // Compute the scale factor for the winning side
811 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
812 int sf = me->scale_factor(pos, strongSide);
814 // If scale factor is not already specific, scale down via general heuristics
815 if (sf == SCALE_FACTOR_NORMAL)
817 if (pos.opposite_bishops())
819 if ( pos.non_pawn_material(WHITE) == BishopValueMg
820 && pos.non_pawn_material(BLACK) == BishopValueMg)
821 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
823 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
825 else if ( pos.non_pawn_material(WHITE) == RookValueMg
826 && pos.non_pawn_material(BLACK) == RookValueMg
827 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
828 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
829 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
831 else if (pos.count<QUEEN>() == 1)
832 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
833 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
835 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide));
838 // Interpolate between the middlegame and (scaled by 'sf') endgame score
839 v = mg * int(me->game_phase())
840 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
845 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
846 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
853 // Evaluation::value() is the main function of the class. It computes the various
854 // parts of the evaluation and returns the value of the position from the point
855 // of view of the side to move.
858 Value Evaluation<T>::value() {
860 assert(!pos.checkers());
862 // Probe the material hash table
863 me = Material::probe(pos);
865 // If we have a specialized evaluation function for the current material
866 // configuration, call it and return.
867 if (me->specialized_eval_exists())
868 return me->evaluate(pos);
870 // Initialize score by reading the incrementally updated scores included in
871 // the position object (material + piece square tables) and the material
872 // imbalance. Score is computed internally from the white point of view.
873 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
875 // Probe the pawn hash table
876 pe = Pawns::probe(pos);
877 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
879 // Early exit if score is high
880 auto lazy_skip = [&](Value lazyThreshold) {
881 return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
884 if (lazy_skip(LazyThreshold1))
887 // Main evaluation begins here
891 // Pieces evaluated first (also populates attackedBy, attackedBy2).
892 // Note that the order of evaluation of the terms is left unspecified.
893 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
894 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
895 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
896 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
898 score += mobility[WHITE] - mobility[BLACK];
900 // More complex interactions that require fully populated attack bitboards
901 score += king< WHITE>() - king< BLACK>()
902 + passed< WHITE>() - passed< BLACK>();
904 if (lazy_skip(LazyThreshold2))
907 score += threats<WHITE>() - threats<BLACK>()
908 + space< WHITE>() - space< BLACK>();
911 // Derive single value from mg and eg parts of score
912 Value v = winnable(score);
914 // In case of tracing add all remaining individual evaluation terms
917 Trace::add(MATERIAL, pos.psq_score());
918 Trace::add(IMBALANCE, me->imbalance());
919 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
920 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
926 // Side to move point of view
927 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
929 // Damp down the evaluation linearly when shuffling
930 v = v * (100 - pos.rule50_count()) / 100;
938 /// evaluate() is the evaluator for the outer world. It returns a static
939 /// evaluation of the position from the point of view of the side to move.
941 Value Eval::evaluate(const Position& pos) {
944 return NNUE::evaluate(pos);
946 return Evaluation<NO_TRACE>(pos).value();
949 /// trace() is like evaluate(), but instead of returning a value, it returns
950 /// a string (suitable for outputting to stdout) that contains the detailed
951 /// descriptions and values of each evaluation term. Useful for debugging.
952 /// Trace scores are from white's point of view
954 std::string Eval::trace(const Position& pos) {
957 return "Final evaluation: none (in check)";
959 std::stringstream ss;
960 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
966 v = NNUE::evaluate(pos);
970 std::memset(scores, 0, sizeof(scores));
972 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
974 v = Evaluation<TRACE>(pos).value();
976 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
977 << " Term | White | Black | Total \n"
978 << " | MG EG | MG EG | MG EG \n"
979 << " ------------+-------------+-------------+------------\n"
980 << " Material | " << Term(MATERIAL)
981 << " Imbalance | " << Term(IMBALANCE)
982 << " Pawns | " << Term(PAWN)
983 << " Knights | " << Term(KNIGHT)
984 << " Bishops | " << Term(BISHOP)
985 << " Rooks | " << Term(ROOK)
986 << " Queens | " << Term(QUEEN)
987 << " Mobility | " << Term(MOBILITY)
988 << " King safety | " << Term(KING)
989 << " Threats | " << Term(THREAT)
990 << " Passed | " << Term(PASSED)
991 << " Space | " << Term(SPACE)
992 << " Winnable | " << Term(WINNABLE)
993 << " ------------+-------------+-------------+------------\n"
994 << " Total | " << Term(TOTAL);
997 v = pos.side_to_move() == WHITE ? v : -v;
999 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";