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, INITIATIVE, 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 == INITIATIVE || 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 BishopPawns = S( 3, 7);
131 constexpr Score BishopXRayPawns = S( 4, 5);
132 constexpr Score CorneredBishop = S( 50, 50);
133 constexpr Score FlankAttacks = S( 8, 0);
134 constexpr Score Hanging = S( 69, 36);
135 constexpr Score BishopKingProtector = S( 6, 9);
136 constexpr Score KnightKingProtector = S( 8, 9);
137 constexpr Score KnightOnQueen = S( 16, 11);
138 constexpr Score LongDiagonalBishop = S( 45, 0);
139 constexpr Score MinorBehindPawn = S( 18, 3);
140 constexpr Score KnightOutpost = S( 56, 36);
141 constexpr Score BishopOutpost = S( 30, 23);
142 constexpr Score ReachableOutpost = S( 31, 22);
143 constexpr Score PassedFile = S( 11, 8);
144 constexpr Score PawnlessFlank = S( 17, 95);
145 constexpr Score RestrictedPiece = S( 7, 7);
146 constexpr Score RookOnKingRing = S( 16, 0);
147 constexpr Score RookOnQueenFile = S( 5, 9);
148 constexpr Score SliderOnQueen = S( 59, 18);
149 constexpr Score ThreatByKing = S( 24, 89);
150 constexpr Score ThreatByPawnPush = S( 48, 39);
151 constexpr Score ThreatBySafePawn = S(173, 94);
152 constexpr Score TrappedRook = S( 55, 13);
153 constexpr Score WeakQueen = S( 51, 14);
154 constexpr Score WeakQueenProtection = S( 15, 0);
158 // Evaluation class computes and stores attacks tables and other working data
163 Evaluation() = delete;
164 explicit Evaluation(const Position& p) : pos(p) {}
165 Evaluation& operator=(const Evaluation&) = delete;
169 template<Color Us> void initialize();
170 template<Color Us, PieceType Pt> Score pieces();
171 template<Color Us> Score king() const;
172 template<Color Us> Score threats() const;
173 template<Color Us> Score passed() const;
174 template<Color Us> Score space() const;
175 ScaleFactor scale_factor(Value eg) const;
176 Score initiative(Score score) const;
181 Bitboard mobilityArea[COLOR_NB];
182 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
184 // attackedBy[color][piece type] is a bitboard representing all squares
185 // attacked by a given color and piece type. Special "piece types" which
186 // is also calculated is ALL_PIECES.
187 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
189 // attackedBy2[color] are the squares attacked by at least 2 units of a given
190 // color, including x-rays. But diagonal x-rays through pawns are not computed.
191 Bitboard attackedBy2[COLOR_NB];
193 // kingRing[color] are the squares adjacent to the king plus some other
194 // very near squares, depending on king position.
195 Bitboard kingRing[COLOR_NB];
197 // kingAttackersCount[color] is the number of pieces of the given color
198 // which attack a square in the kingRing of the enemy king.
199 int kingAttackersCount[COLOR_NB];
201 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
202 // the given color which attack a square in the kingRing of the enemy king.
203 // The weights of the individual piece types are given by the elements in
204 // the KingAttackWeights array.
205 int kingAttackersWeight[COLOR_NB];
207 // kingAttacksCount[color] is the number of attacks by the given color to
208 // squares directly adjacent to the enemy king. Pieces which attack more
209 // than one square are counted multiple times. For instance, if there is
210 // a white knight on g5 and black's king is on g8, this white knight adds 2
211 // to kingAttacksCount[WHITE].
212 int kingAttacksCount[COLOR_NB];
216 // Evaluation::initialize() computes king and pawn attacks, and the king ring
217 // bitboard for a given color. This is done at the beginning of the evaluation.
218 template<Tracing T> template<Color Us>
219 void Evaluation<T>::initialize() {
221 constexpr Color Them = ~Us;
222 constexpr Direction Up = pawn_push(Us);
223 constexpr Direction Down = -Up;
224 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
226 const Square ksq = pos.square<KING>(Us);
228 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
230 // Find our pawns that are blocked or on the first two ranks
231 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
233 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
234 // or controlled by enemy pawns are excluded from the mobility area.
235 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
237 // Initialize attackedBy[] for king and pawns
238 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
239 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
240 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
241 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
243 // Init our king safety tables
244 Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, FILE_G),
245 Utility::clamp(rank_of(ksq), RANK_2, RANK_7));
246 kingRing[Us] = attacks_bb<KING>(s) | s;
248 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
249 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
251 // Remove from kingRing[] the squares defended by two pawns
252 kingRing[Us] &= ~dblAttackByPawn;
256 // Evaluation::pieces() scores pieces of a given color and type
257 template<Tracing T> template<Color Us, PieceType Pt>
258 Score Evaluation<T>::pieces() {
260 constexpr Color Them = ~Us;
261 constexpr Direction Down = -pawn_push(Us);
262 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
263 : Rank5BB | Rank4BB | Rank3BB);
264 const Square* pl = pos.squares<Pt>(Us);
267 Score score = SCORE_ZERO;
269 attackedBy[Us][Pt] = 0;
271 for (Square s = *pl; s != SQ_NONE; s = *++pl)
273 // Find attacked squares, including x-ray attacks for bishops and rooks
274 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
275 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
276 : attacks_bb<Pt>(s, pos.pieces());
278 if (pos.blockers_for_king(Us) & s)
279 b &= LineBB[pos.square<KING>(Us)][s];
281 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
282 attackedBy[Us][Pt] |= b;
283 attackedBy[Us][ALL_PIECES] |= b;
285 if (b & kingRing[Them])
287 kingAttackersCount[Us]++;
288 kingAttackersWeight[Us] += KingAttackWeights[Pt];
289 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
291 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
292 score += RookOnKingRing;
294 int mob = popcount(b & mobilityArea[Us]);
296 mobility[Us] += MobilityBonus[Pt - 2][mob];
298 if (Pt == BISHOP || Pt == KNIGHT)
300 // Bonus if piece is on an outpost square or can reach one
301 bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them);
303 score += (Pt == KNIGHT) ? KnightOutpost : BishopOutpost;
304 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
305 score += ReachableOutpost;
307 // Bonus for a knight or bishop shielded by pawn
308 if (shift<Down>(pos.pieces(PAWN)) & s)
309 score += MinorBehindPawn;
311 // Penalty if the piece is far from the king
312 score -= (Pt == KNIGHT ? KnightKingProtector
313 : BishopKingProtector) * distance(pos.square<KING>(Us), s);
317 // Penalty according to the number of our pawns on the same color square as the
318 // bishop, bigger when the center files are blocked with pawns and smaller
319 // when the bishop is outside the pawn chain.
320 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
322 score -= BishopPawns * pos.pawns_on_same_color_squares(Us, s)
323 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
325 // Penalty for all enemy pawns x-rayed
326 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
328 // Bonus for bishop on a long diagonal which can "see" both center squares
329 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
330 score += LongDiagonalBishop;
332 // An important Chess960 pattern: a cornered bishop blocked by a friendly
333 // pawn diagonally in front of it is a very serious problem, especially
334 // when that pawn is also blocked.
335 if ( pos.is_chess960()
336 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
338 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
339 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
340 score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
341 : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
349 // Bonus for rook on the same file as a queen
350 if (file_bb(s) & pos.pieces(QUEEN))
351 score += RookOnQueenFile;
353 // Bonus for rook on an open or semi-open file
354 if (pos.is_on_semiopen_file(Us, s))
355 score += RookOnFile[pos.is_on_semiopen_file(Them, s)];
357 // Penalty when trapped by the king, even more if the king cannot castle
360 File kf = file_of(pos.square<KING>(Us));
361 if ((kf < FILE_E) == (file_of(s) < kf))
362 score -= TrappedRook * (1 + !pos.castling_rights(Us));
368 // Penalty if any relative pin or discovered attack against the queen
369 Bitboard queenPinners;
370 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
375 Trace::add(Pt, Us, score);
381 // Evaluation::king() assigns bonuses and penalties to a king of a given color
382 template<Tracing T> template<Color Us>
383 Score Evaluation<T>::king() const {
385 constexpr Color Them = ~Us;
386 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
387 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
389 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
390 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
392 const Square ksq = pos.square<KING>(Us);
394 // Init the score with king shelter and enemy pawns storm
395 Score score = pe->king_safety<Us>(pos);
397 // Attacked squares defended at most once by our queen or king
398 weak = attackedBy[Them][ALL_PIECES]
400 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
402 // Analyse the safe enemy's checks which are possible on next move
403 safe = ~pos.pieces(Them);
404 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
406 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
407 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
409 // Enemy rooks checks
410 rookChecks = b1 & safe & attackedBy[Them][ROOK];
412 kingDanger += more_than_one(rookChecks) ? RookSafeCheck * 175/100
415 unsafeChecks |= b1 & attackedBy[Them][ROOK];
417 // Enemy queen safe checks: we count them only if they are from squares from
418 // which we can't give a rook check, because rook checks are more valuable.
419 queenChecks = (b1 | b2)
420 & attackedBy[Them][QUEEN]
422 & ~attackedBy[Us][QUEEN]
425 kingDanger += more_than_one(queenChecks) ? QueenSafeCheck * 145/100
428 // Enemy bishops checks: we count them only if they are from squares from
429 // which we can't give a queen check, because queen checks are more valuable.
431 & attackedBy[Them][BISHOP]
435 kingDanger += more_than_one(bishopChecks) ? BishopSafeCheck * 3/2
438 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
440 // Enemy knights checks
441 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
442 if (knightChecks & safe)
443 kingDanger += more_than_one(knightChecks & safe) ? KnightSafeCheck * 162/100
446 unsafeChecks |= knightChecks;
448 // Find the squares that opponent attacks in our king flank, the squares
449 // which they attack twice in that flank, and the squares that we defend.
450 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
451 b2 = b1 & attackedBy2[Them];
452 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
454 int kingFlankAttack = popcount(b1) + popcount(b2);
455 int kingFlankDefense = popcount(b3);
457 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
458 + 185 * popcount(kingRing[Us] & weak)
459 + 148 * popcount(unsafeChecks)
460 + 98 * popcount(pos.blockers_for_king(Us))
461 + 69 * kingAttacksCount[Them]
462 + 3 * kingFlankAttack * kingFlankAttack / 8
463 + mg_value(mobility[Them] - mobility[Us])
464 - 873 * !pos.count<QUEEN>(Them)
465 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
466 - 6 * mg_value(score) / 8
467 - 4 * kingFlankDefense
470 // Transform the kingDanger units into a Score, and subtract it from the evaluation
471 if (kingDanger > 100)
472 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
474 // Penalty when our king is on a pawnless flank
475 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
476 score -= PawnlessFlank;
478 // Penalty if king flank is under attack, potentially moving toward the king
479 score -= FlankAttacks * kingFlankAttack;
482 Trace::add(KING, Us, score);
488 // Evaluation::threats() assigns bonuses according to the types of the
489 // attacking and the attacked pieces.
490 template<Tracing T> template<Color Us>
491 Score Evaluation<T>::threats() const {
493 constexpr Color Them = ~Us;
494 constexpr Direction Up = pawn_push(Us);
495 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
497 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
498 Score score = SCORE_ZERO;
501 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
503 // Squares strongly protected by the enemy, either because they defend the
504 // square with a pawn, or because they defend the square twice and we don't.
505 stronglyProtected = attackedBy[Them][PAWN]
506 | (attackedBy2[Them] & ~attackedBy2[Us]);
508 // Non-pawn enemies, strongly protected
509 defended = nonPawnEnemies & stronglyProtected;
511 // Enemies not strongly protected and under our attack
512 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
514 // Bonus according to the kind of attacking pieces
517 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
519 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
521 b = weak & attackedBy[Us][ROOK];
523 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
525 if (weak & attackedBy[Us][KING])
526 score += ThreatByKing;
528 b = ~attackedBy[Them][ALL_PIECES]
529 | (nonPawnEnemies & attackedBy2[Us]);
530 score += Hanging * popcount(weak & b);
532 // Additional bonus if weak piece is only protected by a queen
533 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
536 // Bonus for restricting their piece moves
537 b = attackedBy[Them][ALL_PIECES]
539 & attackedBy[Us][ALL_PIECES];
540 score += RestrictedPiece * popcount(b);
542 // Protected or unattacked squares
543 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
545 // Bonus for attacking enemy pieces with our relatively safe pawns
546 b = pos.pieces(Us, PAWN) & safe;
547 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
548 score += ThreatBySafePawn * popcount(b);
550 // Find squares where our pawns can push on the next move
551 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
552 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
554 // Keep only the squares which are relatively safe
555 b &= ~attackedBy[Them][PAWN] & safe;
557 // Bonus for safe pawn threats on the next move
558 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
559 score += ThreatByPawnPush * popcount(b);
561 // Bonus for threats on the next moves against enemy queen
562 if (pos.count<QUEEN>(Them) == 1)
564 Square s = pos.square<QUEEN>(Them);
565 safe = mobilityArea[Us] & ~stronglyProtected;
567 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
569 score += KnightOnQueen * popcount(b & safe);
571 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
572 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
574 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]);
578 Trace::add(THREAT, Us, score);
583 // Evaluation::passed() evaluates the passed pawns and candidate passed
584 // pawns of the given color.
586 template<Tracing T> template<Color Us>
587 Score Evaluation<T>::passed() const {
589 constexpr Color Them = ~Us;
590 constexpr Direction Up = pawn_push(Us);
591 constexpr Direction Down = -Up;
593 auto king_proximity = [&](Color c, Square s) {
594 return std::min(distance(pos.square<KING>(c), s), 5);
597 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
598 Score score = SCORE_ZERO;
600 b = pe->passed_pawns(Us);
602 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
605 helpers = shift<Up>(pos.pieces(Us, PAWN))
607 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
609 // Remove blocked candidate passers that don't have help to pass
611 | shift<WEST>(helpers)
612 | shift<EAST>(helpers);
617 Square s = pop_lsb(&b);
619 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
621 int r = relative_rank(Us, s);
623 Score bonus = PassedRank[r];
628 Square blockSq = s + Up;
630 // Adjust bonus based on the king's proximity
631 bonus += make_score(0, ( (king_proximity(Them, blockSq) * 19) / 4
632 - king_proximity(Us, blockSq) * 2) * w);
634 // If blockSq is not the queening square then consider also a second push
636 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
638 // If the pawn is free to advance, then increase the bonus
639 if (pos.empty(blockSq))
641 squaresToQueen = forward_file_bb(Us, s);
642 unsafeSquares = passed_pawn_span(Us, s);
644 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
646 if (!(pos.pieces(Them) & bb))
647 unsafeSquares &= attackedBy[Them][ALL_PIECES];
649 // If there are no enemy attacks on passed pawn span, assign a big bonus.
650 // Otherwise assign a smaller bonus if the path to queen is not attacked
651 // and even smaller bonus if it is attacked but block square is not.
652 int k = !unsafeSquares ? 35 :
653 !(unsafeSquares & squaresToQueen) ? 20 :
654 !(unsafeSquares & blockSq) ? 9 :
657 // Assign a larger bonus if the block square is defended
658 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
661 bonus += make_score(k * w, k * w);
665 score += bonus - PassedFile * edge_distance(file_of(s));
669 Trace::add(PASSED, Us, score);
675 // Evaluation::space() computes the space evaluation for a given side. The
676 // space evaluation is a simple bonus based on the number of safe squares
677 // available for minor pieces on the central four files on ranks 2--4. Safe
678 // squares one, two or three squares behind a friendly pawn are counted
679 // twice. Finally, the space bonus is multiplied by a weight. The aim is to
680 // improve play on game opening.
682 template<Tracing T> template<Color Us>
683 Score Evaluation<T>::space() const {
685 if (pos.non_pawn_material() < SpaceThreshold)
688 constexpr Color Them = ~Us;
689 constexpr Direction Down = -pawn_push(Us);
690 constexpr Bitboard SpaceMask =
691 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
692 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
694 // Find the available squares for our pieces inside the area defined by SpaceMask
695 Bitboard safe = SpaceMask
696 & ~pos.pieces(Us, PAWN)
697 & ~attackedBy[Them][PAWN];
699 // Find all squares which are at most three squares behind some friendly pawn
700 Bitboard behind = pos.pieces(Us, PAWN);
701 behind |= shift<Down>(behind);
702 behind |= shift<Down+Down>(behind);
704 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
705 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
706 Score score = make_score(bonus * weight * weight / 16, 0);
709 Trace::add(SPACE, Us, score);
715 // Evaluation::initiative() computes the initiative correction value
716 // for the position. It is a second order bonus/malus based on the
717 // known attacking/defending status of the players.
720 Score Evaluation<T>::initiative(Score score) const {
722 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
723 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
725 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
726 && (pos.pieces(PAWN) & KingSide);
728 bool almostUnwinnable = outflanking < 0
729 && !pawnsOnBothFlanks;
731 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
732 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
734 // Compute the initiative bonus for the attacking side
735 int complexity = 9 * pe->passed_count()
736 + 12 * pos.count<PAWN>()
738 + 21 * pawnsOnBothFlanks
740 + 51 * !pos.non_pawn_material()
741 - 43 * almostUnwinnable
742 - 2 * pos.rule50_count()
745 Value mg = mg_value(score);
746 Value eg = eg_value(score);
748 // Now apply the bonus: note that we find the attacking side by extracting the
749 // sign of the midgame or endgame values, and that we carefully cap the bonus
750 // so that the midgame and endgame scores do not change sign after the bonus.
751 int u = ((mg > 0) - (mg < 0)) * Utility::clamp(complexity + 50, -abs(mg), 0);
752 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
755 Trace::add(INITIATIVE, make_score(u, v));
757 return make_score(u, v);
761 // Evaluation::scale_factor() computes the scale factor for the winning side
764 ScaleFactor Evaluation<T>::scale_factor(Value eg) const {
766 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
767 int sf = me->scale_factor(pos, strongSide);
769 // If scale is not already specific, scale down the endgame via general heuristics
770 if (sf == SCALE_FACTOR_NORMAL)
772 if (pos.opposite_bishops())
774 if ( pos.non_pawn_material(WHITE) == BishopValueMg
775 && pos.non_pawn_material(BLACK) == BishopValueMg)
776 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
778 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
781 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide));
784 return ScaleFactor(sf);
788 // Evaluation::value() is the main function of the class. It computes the various
789 // parts of the evaluation and returns the value of the position from the point
790 // of view of the side to move.
793 Value Evaluation<T>::value() {
795 assert(!pos.checkers());
797 // Probe the material hash table
798 me = Material::probe(pos);
800 // If we have a specialized evaluation function for the current material
801 // configuration, call it and return.
802 if (me->specialized_eval_exists())
803 return me->evaluate(pos);
805 // Initialize score by reading the incrementally updated scores included in
806 // the position object (material + piece square tables) and the material
807 // imbalance. Score is computed internally from the white point of view.
808 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
810 // Probe the pawn hash table
811 pe = Pawns::probe(pos);
812 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
814 // Early exit if score is high
815 Value v = (mg_value(score) + eg_value(score)) / 2;
816 if (abs(v) > LazyThreshold + pos.non_pawn_material() / 64)
817 return pos.side_to_move() == WHITE ? v : -v;
819 // Main evaluation begins here
824 // Pieces evaluated first (also populates attackedBy, attackedBy2).
825 // Note that the order of evaluation of the terms is left unspecified
826 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
827 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
828 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
829 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
831 score += mobility[WHITE] - mobility[BLACK];
833 // More complex interactions that require fully populated attack bitboards
834 score += king< WHITE>() - king< BLACK>()
835 + threats<WHITE>() - threats<BLACK>()
836 + passed< WHITE>() - passed< BLACK>()
837 + space< WHITE>() - space< BLACK>();
839 score += initiative(score);
841 // Interpolate between a middlegame and a (scaled by 'sf') endgame score
842 ScaleFactor sf = scale_factor(eg_value(score));
843 v = mg_value(score) * int(me->game_phase())
844 + eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
848 // In case of tracing add all remaining individual evaluation terms
851 Trace::add(MATERIAL, pos.psq_score());
852 Trace::add(IMBALANCE, me->imbalance());
853 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
854 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
855 Trace::add(TOTAL, score);
858 // Side to move point of view
859 return (pos.side_to_move() == WHITE ? v : -v) + Tempo;
865 /// evaluate() is the evaluator for the outer world. It returns a static
866 /// evaluation of the position from the point of view of the side to move.
868 Value Eval::evaluate(const Position& pos) {
869 return Evaluation<NO_TRACE>(pos).value();
873 /// trace() is like evaluate(), but instead of returning a value, it returns
874 /// a string (suitable for outputting to stdout) that contains the detailed
875 /// descriptions and values of each evaluation term. Useful for debugging.
877 std::string Eval::trace(const Position& pos) {
880 return "Total evaluation: none (in check)";
882 std::memset(scores, 0, sizeof(scores));
884 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
886 Value v = Evaluation<TRACE>(pos).value();
888 v = pos.side_to_move() == WHITE ? v : -v; // Trace scores are from white's point of view
890 std::stringstream ss;
891 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
892 << " Term | White | Black | Total \n"
893 << " | MG EG | MG EG | MG EG \n"
894 << " ------------+-------------+-------------+------------\n"
895 << " Material | " << Term(MATERIAL)
896 << " Imbalance | " << Term(IMBALANCE)
897 << " Pawns | " << Term(PAWN)
898 << " Knights | " << Term(KNIGHT)
899 << " Bishops | " << Term(BISHOP)
900 << " Rooks | " << Term(ROOK)
901 << " Queens | " << Term(QUEEN)
902 << " Mobility | " << Term(MOBILITY)
903 << " King safety | " << Term(KING)
904 << " Threats | " << Term(THREAT)
905 << " Passed | " << Term(PASSED)
906 << " Space | " << Term(SPACE)
907 << " Initiative | " << Term(INITIATIVE)
908 << " ------------+-------------+-------------+------------\n"
909 << " Total | " << Term(TOTAL);
911 ss << "\nTotal evaluation: " << to_cp(v) << " (white side)\n";