2 Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3 Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
4 Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
5 Copyright (C) 2015-2020 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
7 Stockfish is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 Stockfish is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include <cstring> // For std::memset
35 enum Tracing { NO_TRACE, TRACE };
37 enum Term { // The first 8 entries are reserved for PieceType
38 MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
41 Score scores[TERM_NB][COLOR_NB];
43 double to_cp(Value v) { return double(v) / PawnValueEg; }
45 void add(int idx, Color c, Score s) {
49 void add(int idx, Score w, Score b = SCORE_ZERO) {
50 scores[idx][WHITE] = w;
51 scores[idx][BLACK] = b;
54 std::ostream& operator<<(std::ostream& os, Score s) {
55 os << std::setw(5) << to_cp(mg_value(s)) << " "
56 << std::setw(5) << to_cp(eg_value(s));
60 std::ostream& operator<<(std::ostream& os, Term t) {
62 if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
63 os << " ---- ----" << " | " << " ---- ----";
65 os << scores[t][WHITE] << " | " << scores[t][BLACK];
67 os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
72 using namespace Trace;
76 // Threshold for lazy and space evaluation
77 constexpr Value LazyThreshold = Value(1400);
78 constexpr Value SpaceThreshold = Value(12222);
80 // KingAttackWeights[PieceType] contains king attack weights by piece type
81 constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
83 // Penalties for enemy's safe checks
84 constexpr int QueenSafeCheck = 772;
85 constexpr int RookSafeCheck = 1084;
86 constexpr int BishopSafeCheck = 645;
87 constexpr int KnightSafeCheck = 792;
89 #define S(mg, eg) make_score(mg, eg)
91 // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
92 // indexed by piece type and number of attacked squares in the mobility area.
93 constexpr Score MobilityBonus[][32] = {
94 { S(-62,-81), S(-53,-56), S(-12,-31), S( -4,-16), S( 3, 5), S( 13, 11), // Knight
95 S( 22, 17), S( 28, 20), S( 33, 25) },
96 { S(-48,-59), S(-20,-23), S( 16, -3), S( 26, 13), S( 38, 24), S( 51, 42), // Bishop
97 S( 55, 54), S( 63, 57), S( 63, 65), S( 68, 73), S( 81, 78), S( 81, 86),
98 S( 91, 88), S( 98, 97) },
99 { S(-60,-78), S(-20,-17), S( 2, 23), S( 3, 39), S( 3, 70), S( 11, 99), // Rook
100 S( 22,103), S( 31,121), S( 40,134), S( 40,139), S( 41,158), S( 48,164),
101 S( 57,168), S( 57,169), S( 62,172) },
102 { S(-30,-48), S(-12,-30), S( -8, -7), S( -9, 19), S( 20, 40), S( 23, 55), // Queen
103 S( 23, 59), S( 35, 75), S( 38, 78), S( 53, 96), S( 64, 96), S( 65,100),
104 S( 65,121), S( 66,127), S( 67,131), S( 67,133), S( 72,136), S( 72,141),
105 S( 77,147), S( 79,150), S( 93,151), S(108,168), S(108,168), S(108,171),
106 S(110,182), S(114,182), S(114,192), S(116,219) }
109 // RookOnFile[semiopen/open] contains bonuses for each rook when there is
110 // no (friendly) pawn on the rook file.
111 constexpr Score RookOnFile[] = { S(19, 7), S(48, 29) };
113 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
114 // which piece type attacks which one. Attacks on lesser pieces which are
115 // pawn-defended are not considered.
116 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
117 S(0, 0), S(5, 32), S(57, 41), S(77, 56), S(88, 119), S(79, 161)
120 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
121 S(0, 0), S(3, 46), S(37, 68), S(42, 60), S(0, 38), S(58, 41)
124 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
125 constexpr Score PassedRank[RANK_NB] = {
126 S(0, 0), S(10, 28), S(17, 33), S(15, 41), S(62, 72), S(168, 177), S(276, 260)
129 // Assorted bonuses and penalties
130 constexpr Score BishopKingProtector = S( 6, 9);
131 constexpr Score BishopOnKingRing = S( 24, 0);
132 constexpr Score BishopOutpost = S( 30, 23);
133 constexpr Score BishopPawns = S( 3, 7);
134 constexpr Score BishopXRayPawns = S( 4, 5);
135 constexpr Score CorneredBishop = S( 50, 50);
136 constexpr Score FlankAttacks = S( 8, 0);
137 constexpr Score Hanging = S( 69, 36);
138 constexpr Score KnightKingProtector = S( 8, 9);
139 constexpr Score KnightOnQueen = S( 16, 11);
140 constexpr Score KnightOutpost = S( 56, 36);
141 constexpr Score LongDiagonalBishop = S( 45, 0);
142 constexpr Score MinorBehindPawn = S( 18, 3);
143 constexpr Score PassedFile = S( 11, 8);
144 constexpr Score PawnlessFlank = S( 17, 95);
145 constexpr Score QueenInfiltration = S( -2, 14);
146 constexpr Score ReachableOutpost = S( 31, 22);
147 constexpr Score RestrictedPiece = S( 7, 7);
148 constexpr Score RookOnKingRing = S( 16, 0);
149 constexpr Score RookOnQueenFile = S( 6, 11);
150 constexpr Score SliderOnQueen = S( 60, 18);
151 constexpr Score ThreatByKing = S( 24, 89);
152 constexpr Score ThreatByPawnPush = S( 48, 39);
153 constexpr Score ThreatBySafePawn = S(173, 94);
154 constexpr Score TrappedRook = S( 55, 13);
155 constexpr Score WeakQueenProtection = S( 14, 0);
156 constexpr Score WeakQueen = S( 56, 15);
161 // Evaluation class computes and stores attacks tables and other working data
166 Evaluation() = delete;
167 explicit Evaluation(const Position& p) : pos(p) {}
168 Evaluation& operator=(const Evaluation&) = delete;
172 template<Color Us> void initialize();
173 template<Color Us, PieceType Pt> Score pieces();
174 template<Color Us> Score king() const;
175 template<Color Us> Score threats() const;
176 template<Color Us> Score passed() const;
177 template<Color Us> Score space() const;
178 Value winnable(Score score) const;
183 Bitboard mobilityArea[COLOR_NB];
184 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
186 // attackedBy[color][piece type] is a bitboard representing all squares
187 // attacked by a given color and piece type. Special "piece types" which
188 // is also calculated is ALL_PIECES.
189 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
191 // attackedBy2[color] are the squares attacked by at least 2 units of a given
192 // color, including x-rays. But diagonal x-rays through pawns are not computed.
193 Bitboard attackedBy2[COLOR_NB];
195 // kingRing[color] are the squares adjacent to the king plus some other
196 // very near squares, depending on king position.
197 Bitboard kingRing[COLOR_NB];
199 // kingAttackersCount[color] is the number of pieces of the given color
200 // which attack a square in the kingRing of the enemy king.
201 int kingAttackersCount[COLOR_NB];
203 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
204 // the given color which attack a square in the kingRing of the enemy king.
205 // The weights of the individual piece types are given by the elements in
206 // the KingAttackWeights array.
207 int kingAttackersWeight[COLOR_NB];
209 // kingAttacksCount[color] is the number of attacks by the given color to
210 // squares directly adjacent to the enemy king. Pieces which attack more
211 // than one square are counted multiple times. For instance, if there is
212 // a white knight on g5 and black's king is on g8, this white knight adds 2
213 // to kingAttacksCount[WHITE].
214 int kingAttacksCount[COLOR_NB];
218 // Evaluation::initialize() computes king and pawn attacks, and the king ring
219 // bitboard for a given color. This is done at the beginning of the evaluation.
221 template<Tracing T> template<Color Us>
222 void Evaluation<T>::initialize() {
224 constexpr Color Them = ~Us;
225 constexpr Direction Up = pawn_push(Us);
226 constexpr Direction Down = -Up;
227 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
229 const Square ksq = pos.square<KING>(Us);
231 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
233 // Find our pawns that are blocked or on the first two ranks
234 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
236 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
237 // or controlled by enemy pawns are excluded from the mobility area.
238 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
240 // Initialize attackedBy[] for king and pawns
241 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
242 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
243 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
244 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
246 // Init our king safety tables
247 Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, FILE_G),
248 Utility::clamp(rank_of(ksq), RANK_2, RANK_7));
249 kingRing[Us] = attacks_bb<KING>(s) | s;
251 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
252 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
254 // Remove from kingRing[] the squares defended by two pawns
255 kingRing[Us] &= ~dblAttackByPawn;
259 // Evaluation::pieces() scores pieces of a given color and type
261 template<Tracing T> template<Color Us, PieceType Pt>
262 Score Evaluation<T>::pieces() {
264 constexpr Color Them = ~Us;
265 constexpr Direction Down = -pawn_push(Us);
266 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
267 : Rank5BB | Rank4BB | Rank3BB);
268 const Square* pl = pos.squares<Pt>(Us);
271 Score score = SCORE_ZERO;
273 attackedBy[Us][Pt] = 0;
275 for (Square s = *pl; s != SQ_NONE; s = *++pl)
277 // Find attacked squares, including x-ray attacks for bishops and rooks
278 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
279 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
280 : attacks_bb<Pt>(s, pos.pieces());
282 if (pos.blockers_for_king(Us) & s)
283 b &= line_bb(pos.square<KING>(Us), s);
285 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
286 attackedBy[Us][Pt] |= b;
287 attackedBy[Us][ALL_PIECES] |= b;
289 if (b & kingRing[Them])
291 kingAttackersCount[Us]++;
292 kingAttackersWeight[Us] += KingAttackWeights[Pt];
293 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
296 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
297 score += RookOnKingRing;
299 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
300 score += BishopOnKingRing;
302 int mob = popcount(b & mobilityArea[Us]);
304 mobility[Us] += MobilityBonus[Pt - 2][mob];
306 if (Pt == BISHOP || Pt == KNIGHT)
308 // Bonus if piece is on an outpost square or can reach one
309 bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them);
311 score += (Pt == KNIGHT) ? KnightOutpost : BishopOutpost;
312 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
313 score += ReachableOutpost;
315 // Bonus for a knight or bishop shielded by pawn
316 if (shift<Down>(pos.pieces(PAWN)) & s)
317 score += MinorBehindPawn;
319 // Penalty if the piece is far from the king
320 score -= (Pt == KNIGHT ? KnightKingProtector
321 : BishopKingProtector) * distance(pos.square<KING>(Us), s);
325 // Penalty according to the number of our pawns on the same color square as the
326 // bishop, bigger when the center files are blocked with pawns and smaller
327 // when the bishop is outside the pawn chain.
328 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
330 score -= BishopPawns * pos.pawns_on_same_color_squares(Us, s)
331 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
333 // Penalty for all enemy pawns x-rayed
334 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
336 // Bonus for bishop on a long diagonal which can "see" both center squares
337 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
338 score += LongDiagonalBishop;
340 // An important Chess960 pattern: a cornered bishop blocked by a friendly
341 // pawn diagonally in front of it is a very serious problem, especially
342 // when that pawn is also blocked.
343 if ( pos.is_chess960()
344 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
346 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
347 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
348 score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
349 : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
357 // Bonus for rook on the same file as a queen
358 if (file_bb(s) & pos.pieces(QUEEN))
359 score += RookOnQueenFile;
361 // Bonus for rook on an open or semi-open file
362 if (pos.is_on_semiopen_file(Us, s))
363 score += RookOnFile[pos.is_on_semiopen_file(Them, s)];
365 // Penalty when trapped by the king, even more if the king cannot castle
368 File kf = file_of(pos.square<KING>(Us));
369 if ((kf < FILE_E) == (file_of(s) < kf))
370 score -= TrappedRook * (1 + !pos.castling_rights(Us));
376 // Penalty if any relative pin or discovered attack against the queen
377 Bitboard queenPinners;
378 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
381 // Bonus for queen on weak square in enemy camp
382 if (relative_rank(Us, s) > RANK_4 && (~pe->pawn_attacks_span(Them) & s))
383 score += QueenInfiltration;
387 Trace::add(Pt, Us, score);
393 // Evaluation::king() assigns bonuses and penalties to a king of a given color
395 template<Tracing T> template<Color Us>
396 Score Evaluation<T>::king() const {
398 constexpr Color Them = ~Us;
399 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
400 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
402 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
403 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
405 const Square ksq = pos.square<KING>(Us);
407 // Init the score with king shelter and enemy pawns storm
408 Score score = pe->king_safety<Us>(pos);
410 // Attacked squares defended at most once by our queen or king
411 weak = attackedBy[Them][ALL_PIECES]
413 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
415 // Analyse the safe enemy's checks which are possible on next move
416 safe = ~pos.pieces(Them);
417 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
419 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
420 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
422 // Enemy rooks checks
423 rookChecks = b1 & safe & attackedBy[Them][ROOK];
425 kingDanger += more_than_one(rookChecks) ? RookSafeCheck * 175/100
428 unsafeChecks |= b1 & attackedBy[Them][ROOK];
430 // Enemy queen safe checks: we count them only if they are from squares from
431 // which we can't give a rook check, because rook checks are more valuable.
432 queenChecks = (b1 | b2)
433 & attackedBy[Them][QUEEN]
435 & ~attackedBy[Us][QUEEN]
438 kingDanger += more_than_one(queenChecks) ? QueenSafeCheck * 145/100
441 // Enemy bishops checks: we count them only if they are from squares from
442 // which we can't give a queen check, because queen checks are more valuable.
444 & attackedBy[Them][BISHOP]
448 kingDanger += more_than_one(bishopChecks) ? BishopSafeCheck * 3/2
451 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
453 // Enemy knights checks
454 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
455 if (knightChecks & safe)
456 kingDanger += more_than_one(knightChecks & safe) ? KnightSafeCheck * 162/100
459 unsafeChecks |= knightChecks;
461 // Find the squares that opponent attacks in our king flank, the squares
462 // which they attack twice in that flank, and the squares that we defend.
463 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
464 b2 = b1 & attackedBy2[Them];
465 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
467 int kingFlankAttack = popcount(b1) + popcount(b2);
468 int kingFlankDefense = popcount(b3);
470 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
471 + 185 * popcount(kingRing[Us] & weak)
472 + 148 * popcount(unsafeChecks)
473 + 98 * popcount(pos.blockers_for_king(Us))
474 + 69 * kingAttacksCount[Them]
475 + 3 * kingFlankAttack * kingFlankAttack / 8
476 + mg_value(mobility[Them] - mobility[Us])
477 - 873 * !pos.count<QUEEN>(Them)
478 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
479 - 6 * mg_value(score) / 8
480 - 4 * kingFlankDefense
483 // Transform the kingDanger units into a Score, and subtract it from the evaluation
484 if (kingDanger > 100)
485 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
487 // Penalty when our king is on a pawnless flank
488 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
489 score -= PawnlessFlank;
491 // Penalty if king flank is under attack, potentially moving toward the king
492 score -= FlankAttacks * kingFlankAttack;
495 Trace::add(KING, Us, score);
501 // Evaluation::threats() assigns bonuses according to the types of the
502 // attacking and the attacked pieces.
504 template<Tracing T> template<Color Us>
505 Score Evaluation<T>::threats() const {
507 constexpr Color Them = ~Us;
508 constexpr Direction Up = pawn_push(Us);
509 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
511 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
512 Score score = SCORE_ZERO;
515 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
517 // Squares strongly protected by the enemy, either because they defend the
518 // square with a pawn, or because they defend the square twice and we don't.
519 stronglyProtected = attackedBy[Them][PAWN]
520 | (attackedBy2[Them] & ~attackedBy2[Us]);
522 // Non-pawn enemies, strongly protected
523 defended = nonPawnEnemies & stronglyProtected;
525 // Enemies not strongly protected and under our attack
526 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
528 // Bonus according to the kind of attacking pieces
531 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
533 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
535 b = weak & attackedBy[Us][ROOK];
537 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
539 if (weak & attackedBy[Us][KING])
540 score += ThreatByKing;
542 b = ~attackedBy[Them][ALL_PIECES]
543 | (nonPawnEnemies & attackedBy2[Us]);
544 score += Hanging * popcount(weak & b);
546 // Additional bonus if weak piece is only protected by a queen
547 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
550 // Bonus for restricting their piece moves
551 b = attackedBy[Them][ALL_PIECES]
553 & attackedBy[Us][ALL_PIECES];
554 score += RestrictedPiece * popcount(b);
556 // Protected or unattacked squares
557 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
559 // Bonus for attacking enemy pieces with our relatively safe pawns
560 b = pos.pieces(Us, PAWN) & safe;
561 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
562 score += ThreatBySafePawn * popcount(b);
564 // Find squares where our pawns can push on the next move
565 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
566 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
568 // Keep only the squares which are relatively safe
569 b &= ~attackedBy[Them][PAWN] & safe;
571 // Bonus for safe pawn threats on the next move
572 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
573 score += ThreatByPawnPush * popcount(b);
575 // Bonus for threats on the next moves against enemy queen
576 if (pos.count<QUEEN>(Them) == 1)
578 Square s = pos.square<QUEEN>(Them);
579 safe = mobilityArea[Us] & ~stronglyProtected;
581 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
583 score += KnightOnQueen * popcount(b & safe);
585 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
586 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
588 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]);
592 Trace::add(THREAT, Us, score);
597 // Evaluation::passed() evaluates the passed pawns and candidate passed
598 // pawns of the given color.
600 template<Tracing T> template<Color Us>
601 Score Evaluation<T>::passed() const {
603 constexpr Color Them = ~Us;
604 constexpr Direction Up = pawn_push(Us);
605 constexpr Direction Down = -Up;
607 auto king_proximity = [&](Color c, Square s) {
608 return std::min(distance(pos.square<KING>(c), s), 5);
611 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
612 Score score = SCORE_ZERO;
614 b = pe->passed_pawns(Us);
616 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
619 helpers = shift<Up>(pos.pieces(Us, PAWN))
621 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
623 // Remove blocked candidate passers that don't have help to pass
625 | shift<WEST>(helpers)
626 | shift<EAST>(helpers);
631 Square s = pop_lsb(&b);
633 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
635 int r = relative_rank(Us, s);
637 Score bonus = PassedRank[r];
642 Square blockSq = s + Up;
644 // Adjust bonus based on the king's proximity
645 bonus += make_score(0, ( (king_proximity(Them, blockSq) * 19) / 4
646 - king_proximity(Us, blockSq) * 2) * w);
648 // If blockSq is not the queening square then consider also a second push
650 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
652 // If the pawn is free to advance, then increase the bonus
653 if (pos.empty(blockSq))
655 squaresToQueen = forward_file_bb(Us, s);
656 unsafeSquares = passed_pawn_span(Us, s);
658 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
660 if (!(pos.pieces(Them) & bb))
661 unsafeSquares &= attackedBy[Them][ALL_PIECES];
663 // If there are no enemy attacks on passed pawn span, assign a big bonus.
664 // Otherwise assign a smaller bonus if the path to queen is not attacked
665 // and even smaller bonus if it is attacked but block square is not.
666 int k = !unsafeSquares ? 35 :
667 !(unsafeSquares & squaresToQueen) ? 20 :
668 !(unsafeSquares & blockSq) ? 9 :
671 // Assign a larger bonus if the block square is defended
672 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
675 bonus += make_score(k * w, k * w);
679 score += bonus - PassedFile * edge_distance(file_of(s));
683 Trace::add(PASSED, Us, score);
689 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
690 // play in the opening. It is based on the number of safe squares on the 4 central files
691 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
692 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
694 template<Tracing T> template<Color Us>
695 Score Evaluation<T>::space() const {
697 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
698 if (pos.non_pawn_material() < SpaceThreshold)
701 constexpr Color Them = ~Us;
702 constexpr Direction Down = -pawn_push(Us);
703 constexpr Bitboard SpaceMask =
704 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
705 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
707 // Find the available squares for our pieces inside the area defined by SpaceMask
708 Bitboard safe = SpaceMask
709 & ~pos.pieces(Us, PAWN)
710 & ~attackedBy[Them][PAWN];
712 // Find all squares which are at most three squares behind some friendly pawn
713 Bitboard behind = pos.pieces(Us, PAWN);
714 behind |= shift<Down>(behind);
715 behind |= shift<Down+Down>(behind);
717 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
718 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
719 Score score = make_score(bonus * weight * weight / 16, 0);
722 Trace::add(SPACE, Us, score);
728 // Evaluation::winnable() adjusts the mg and eg score components based on the
729 // known attacking/defending status of the players. A single value is derived
730 // by interpolation from the mg and eg values and returned.
733 Value Evaluation<T>::winnable(Score score) const {
735 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
736 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
738 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
739 && (pos.pieces(PAWN) & KingSide);
741 bool almostUnwinnable = outflanking < 0
742 && !pawnsOnBothFlanks;
744 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
745 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
747 // Compute the initiative bonus for the attacking side
748 int complexity = 9 * pe->passed_count()
749 + 12 * pos.count<PAWN>()
751 + 21 * pawnsOnBothFlanks
753 + 51 * !pos.non_pawn_material()
754 - 43 * almostUnwinnable
757 Value mg = mg_value(score);
758 Value eg = eg_value(score);
760 // Now apply the bonus: note that we find the attacking side by extracting the
761 // sign of the midgame or endgame values, and that we carefully cap the bonus
762 // so that the midgame and endgame scores do not change sign after the bonus.
763 int u = ((mg > 0) - (mg < 0)) * Utility::clamp(complexity + 50, -abs(mg), 0);
764 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
769 // Compute the scale factor for the winning side
770 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
771 int sf = me->scale_factor(pos, strongSide);
773 // If scale is not already specific, scale down the endgame via general heuristics
774 if (sf == SCALE_FACTOR_NORMAL)
776 if (pos.opposite_bishops())
778 if ( pos.non_pawn_material(WHITE) == BishopValueMg
779 && pos.non_pawn_material(BLACK) == BishopValueMg)
780 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
782 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
784 else if ( pos.non_pawn_material(WHITE) == RookValueMg
785 && pos.non_pawn_material(BLACK) == RookValueMg
786 && !pe->passed_pawns(strongSide)
787 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
788 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
789 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
791 else if (pos.count<QUEEN>() == 1)
794 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide));
797 // Interpolate between the middlegame and (scaled by 'sf') endgame score
798 v = mg * int(me->game_phase())
799 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
804 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
805 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
812 // Evaluation::value() is the main function of the class. It computes the various
813 // parts of the evaluation and returns the value of the position from the point
814 // of view of the side to move.
817 Value Evaluation<T>::value() {
819 assert(!pos.checkers());
821 // Probe the material hash table
822 me = Material::probe(pos);
824 // If we have a specialized evaluation function for the current material
825 // configuration, call it and return.
826 if (me->specialized_eval_exists())
827 return me->evaluate(pos);
829 // Initialize score by reading the incrementally updated scores included in
830 // the position object (material + piece square tables) and the material
831 // imbalance. Score is computed internally from the white point of view.
832 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
834 // Probe the pawn hash table
835 pe = Pawns::probe(pos);
836 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
838 // Early exit if score is high
839 Value v = (mg_value(score) + eg_value(score)) / 2;
840 if (abs(v) > LazyThreshold + pos.non_pawn_material() / 64)
841 return pos.side_to_move() == WHITE ? v : -v;
843 // Main evaluation begins here
847 // Pieces evaluated first (also populates attackedBy, attackedBy2).
848 // Note that the order of evaluation of the terms is left unspecified.
849 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
850 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
851 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
852 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
854 score += mobility[WHITE] - mobility[BLACK];
856 // More complex interactions that require fully populated attack bitboards
857 score += king< WHITE>() - king< BLACK>()
858 + threats<WHITE>() - threats<BLACK>()
859 + passed< WHITE>() - passed< BLACK>()
860 + space< WHITE>() - space< BLACK>();
862 // Derive single value from mg and eg parts of score
865 // In case of tracing add all remaining individual evaluation terms
868 Trace::add(MATERIAL, pos.psq_score());
869 Trace::add(IMBALANCE, me->imbalance());
870 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
871 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
877 // Side to move point of view
878 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
880 // Damp down the evaluation linearly when shuffling
881 v = v * (100 - pos.rule50_count()) / 100;
889 /// evaluate() is the evaluator for the outer world. It returns a static
890 /// evaluation of the position from the point of view of the side to move.
892 Value Eval::evaluate(const Position& pos) {
893 return Evaluation<NO_TRACE>(pos).value();
897 /// trace() is like evaluate(), but instead of returning a value, it returns
898 /// a string (suitable for outputting to stdout) that contains the detailed
899 /// descriptions and values of each evaluation term. Useful for debugging.
901 std::string Eval::trace(const Position& pos) {
904 return "Total evaluation: none (in check)";
906 std::memset(scores, 0, sizeof(scores));
908 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
910 Value v = Evaluation<TRACE>(pos).value();
912 v = pos.side_to_move() == WHITE ? v : -v; // Trace scores are from white's point of view
914 std::stringstream ss;
915 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
916 << " Term | White | Black | Total \n"
917 << " | MG EG | MG EG | MG EG \n"
918 << " ------------+-------------+-------------+------------\n"
919 << " Material | " << Term(MATERIAL)
920 << " Imbalance | " << Term(IMBALANCE)
921 << " Pawns | " << Term(PAWN)
922 << " Knights | " << Term(KNIGHT)
923 << " Bishops | " << Term(BISHOP)
924 << " Rooks | " << Term(ROOK)
925 << " Queens | " << Term(QUEEN)
926 << " Mobility | " << Term(MOBILITY)
927 << " King safety | " << Term(KING)
928 << " Threats | " << Term(THREAT)
929 << " Passed | " << Term(PASSED)
930 << " Space | " << Term(SPACE)
931 << " Winnable | " << Term(WINNABLE)
932 << " ------------+-------------+-------------+------------\n"
933 << " Total | " << Term(TOTAL);
935 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";