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 // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
84 // higher if multiple safe checks are possible for that piece type.
85 constexpr int SafeCheck[][2] = {
86 {}, {}, {792, 1283}, {645, 967}, {1084, 1897}, {772, 1119}
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 // KingProtector[knight/bishop] contains penalty for each distance unit to own king
110 constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
112 // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
113 // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
114 constexpr Score Outpost[] = { S(56, 36), S(30, 23) };
116 // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
117 constexpr Score PassedRank[RANK_NB] = {
118 S(0, 0), S(10, 28), S(17, 33), S(15, 41), S(62, 72), S(168, 177), S(276, 260)
121 // RookOnFile[semiopen/open] contains bonuses for each rook when there is
122 // no (friendly) pawn on the rook file.
123 constexpr Score RookOnFile[] = { S(19, 7), S(48, 29) };
125 // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
126 // which piece type attacks which one. Attacks on lesser pieces which are
127 // pawn-defended are not considered.
128 constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
129 S(0, 0), S(5, 32), S(57, 41), S(77, 56), S(88, 119), S(79, 161)
132 constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
133 S(0, 0), S(3, 46), S(37, 68), S(42, 60), S(0, 38), S(58, 41)
136 // Assorted bonuses and penalties
137 constexpr Score BadOutpost = S( -7, 36);
138 constexpr Score BishopOnKingRing = S( 24, 0);
139 constexpr Score BishopPawns = S( 3, 7);
140 constexpr Score BishopXRayPawns = S( 4, 5);
141 constexpr Score CorneredBishop = S( 50, 50);
142 constexpr Score FlankAttacks = S( 8, 0);
143 constexpr Score Hanging = S( 69, 36);
144 constexpr Score KnightOnQueen = S( 16, 11);
145 constexpr Score LongDiagonalBishop = S( 45, 0);
146 constexpr Score MinorBehindPawn = S( 18, 3);
147 constexpr Score PassedFile = S( 11, 8);
148 constexpr Score PawnlessFlank = S( 17, 95);
149 constexpr Score QueenInfiltration = S( -2, 14);
150 constexpr Score ReachableOutpost = S( 31, 22);
151 constexpr Score RestrictedPiece = S( 7, 7);
152 constexpr Score RookOnKingRing = S( 16, 0);
153 constexpr Score RookOnQueenFile = S( 6, 11);
154 constexpr Score SliderOnQueen = S( 60, 18);
155 constexpr Score ThreatByKing = S( 24, 89);
156 constexpr Score ThreatByPawnPush = S( 48, 39);
157 constexpr Score ThreatBySafePawn = S(173, 94);
158 constexpr Score TrappedRook = S( 55, 13);
159 constexpr Score WeakQueenProtection = S( 14, 0);
160 constexpr Score WeakQueen = S( 56, 15);
165 // Evaluation class computes and stores attacks tables and other working data
170 Evaluation() = delete;
171 explicit Evaluation(const Position& p) : pos(p) {}
172 Evaluation& operator=(const Evaluation&) = delete;
176 template<Color Us> void initialize();
177 template<Color Us, PieceType Pt> Score pieces();
178 template<Color Us> Score king() const;
179 template<Color Us> Score threats() const;
180 template<Color Us> Score passed() const;
181 template<Color Us> Score space() const;
182 Value winnable(Score score) const;
187 Bitboard mobilityArea[COLOR_NB];
188 Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
190 // attackedBy[color][piece type] is a bitboard representing all squares
191 // attacked by a given color and piece type. Special "piece types" which
192 // is also calculated is ALL_PIECES.
193 Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
195 // attackedBy2[color] are the squares attacked by at least 2 units of a given
196 // color, including x-rays. But diagonal x-rays through pawns are not computed.
197 Bitboard attackedBy2[COLOR_NB];
199 // kingRing[color] are the squares adjacent to the king plus some other
200 // very near squares, depending on king position.
201 Bitboard kingRing[COLOR_NB];
203 // kingAttackersCount[color] is the number of pieces of the given color
204 // which attack a square in the kingRing of the enemy king.
205 int kingAttackersCount[COLOR_NB];
207 // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
208 // the given color which attack a square in the kingRing of the enemy king.
209 // The weights of the individual piece types are given by the elements in
210 // the KingAttackWeights array.
211 int kingAttackersWeight[COLOR_NB];
213 // kingAttacksCount[color] is the number of attacks by the given color to
214 // squares directly adjacent to the enemy king. Pieces which attack more
215 // than one square are counted multiple times. For instance, if there is
216 // a white knight on g5 and black's king is on g8, this white knight adds 2
217 // to kingAttacksCount[WHITE].
218 int kingAttacksCount[COLOR_NB];
222 // Evaluation::initialize() computes king and pawn attacks, and the king ring
223 // bitboard for a given color. This is done at the beginning of the evaluation.
225 template<Tracing T> template<Color Us>
226 void Evaluation<T>::initialize() {
228 constexpr Color Them = ~Us;
229 constexpr Direction Up = pawn_push(Us);
230 constexpr Direction Down = -Up;
231 constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
233 const Square ksq = pos.square<KING>(Us);
235 Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
237 // Find our pawns that are blocked or on the first two ranks
238 Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
240 // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
241 // or controlled by enemy pawns are excluded from the mobility area.
242 mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
244 // Initialize attackedBy[] for king and pawns
245 attackedBy[Us][KING] = attacks_bb<KING>(ksq);
246 attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
247 attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
248 attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
250 // Init our king safety tables
251 Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, FILE_G),
252 Utility::clamp(rank_of(ksq), RANK_2, RANK_7));
253 kingRing[Us] = attacks_bb<KING>(s) | s;
255 kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
256 kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
258 // Remove from kingRing[] the squares defended by two pawns
259 kingRing[Us] &= ~dblAttackByPawn;
263 // Evaluation::pieces() scores pieces of a given color and type
265 template<Tracing T> template<Color Us, PieceType Pt>
266 Score Evaluation<T>::pieces() {
268 constexpr Color Them = ~Us;
269 constexpr Direction Down = -pawn_push(Us);
270 constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
271 : Rank5BB | Rank4BB | Rank3BB);
272 const Square* pl = pos.squares<Pt>(Us);
275 Score score = SCORE_ZERO;
277 attackedBy[Us][Pt] = 0;
279 for (Square s = *pl; s != SQ_NONE; s = *++pl)
281 // Find attacked squares, including x-ray attacks for bishops and rooks
282 b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
283 : Pt == ROOK ? attacks_bb< ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
284 : attacks_bb<Pt>(s, pos.pieces());
286 if (pos.blockers_for_king(Us) & s)
287 b &= line_bb(pos.square<KING>(Us), s);
289 attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
290 attackedBy[Us][Pt] |= b;
291 attackedBy[Us][ALL_PIECES] |= b;
293 if (b & kingRing[Them])
295 kingAttackersCount[Us]++;
296 kingAttackersWeight[Us] += KingAttackWeights[Pt];
297 kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
300 else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
301 score += RookOnKingRing;
303 else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
304 score += BishopOnKingRing;
306 int mob = popcount(b & mobilityArea[Us]);
308 mobility[Us] += MobilityBonus[Pt - 2][mob];
310 if (Pt == BISHOP || Pt == KNIGHT)
312 // Bonus if piece is on an outpost square or can reach one
313 bb = OutpostRanks & attackedBy[Us][PAWN] & ~pe->pawn_attacks_span(Them);
315 && bb & s & ~CenterFiles
316 && !(b & pos.pieces(Them) & ~pos.pieces(PAWN))
317 && !conditional_more_than_two(
318 pos.pieces(Them) & ~pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide)))
321 score += Outpost[Pt == BISHOP];
322 else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
323 score += ReachableOutpost;
325 // Bonus for a knight or bishop shielded by pawn
326 if (shift<Down>(pos.pieces(PAWN)) & s)
327 score += MinorBehindPawn;
329 // Penalty if the piece is far from the king
330 score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
334 // Penalty according to the number of our pawns on the same color square as the
335 // bishop, bigger when the center files are blocked with pawns and smaller
336 // when the bishop is outside the pawn chain.
337 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
339 score -= BishopPawns * pos.pawns_on_same_color_squares(Us, s)
340 * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
342 // Penalty for all enemy pawns x-rayed
343 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
345 // Bonus for bishop on a long diagonal which can "see" both center squares
346 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
347 score += LongDiagonalBishop;
349 // An important Chess960 pattern: a cornered bishop blocked by a friendly
350 // pawn diagonally in front of it is a very serious problem, especially
351 // when that pawn is also blocked.
352 if ( pos.is_chess960()
353 && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
355 Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
356 if (pos.piece_on(s + d) == make_piece(Us, PAWN))
357 score -= !pos.empty(s + d + pawn_push(Us)) ? CorneredBishop * 4
358 : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
366 // Bonus for rook on the same file as a queen
367 if (file_bb(s) & pos.pieces(QUEEN))
368 score += RookOnQueenFile;
370 // Bonus for rook on an open or semi-open file
371 if (pos.is_on_semiopen_file(Us, s))
372 score += RookOnFile[pos.is_on_semiopen_file(Them, s)];
374 // Penalty when trapped by the king, even more if the king cannot castle
377 File kf = file_of(pos.square<KING>(Us));
378 if ((kf < FILE_E) == (file_of(s) < kf))
379 score -= TrappedRook * (1 + !pos.castling_rights(Us));
385 // Penalty if any relative pin or discovered attack against the queen
386 Bitboard queenPinners;
387 if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
390 // Bonus for queen on weak square in enemy camp
391 if (relative_rank(Us, s) > RANK_4 && (~pe->pawn_attacks_span(Them) & s))
392 score += QueenInfiltration;
396 Trace::add(Pt, Us, score);
402 // Evaluation::king() assigns bonuses and penalties to a king of a given color
404 template<Tracing T> template<Color Us>
405 Score Evaluation<T>::king() const {
407 constexpr Color Them = ~Us;
408 constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
409 : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
411 Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
412 Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
414 const Square ksq = pos.square<KING>(Us);
416 // Init the score with king shelter and enemy pawns storm
417 Score score = pe->king_safety<Us>(pos);
419 // Attacked squares defended at most once by our queen or king
420 weak = attackedBy[Them][ALL_PIECES]
422 & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
424 // Analyse the safe enemy's checks which are possible on next move
425 safe = ~pos.pieces(Them);
426 safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
428 b1 = attacks_bb<ROOK >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
429 b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
431 // Enemy rooks checks
432 rookChecks = b1 & attackedBy[Them][ROOK] & safe;
434 kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
436 unsafeChecks |= b1 & attackedBy[Them][ROOK];
438 // Enemy queen safe checks: count them only if the checks are from squares from
439 // which opponent cannot give a rook check, because rook checks are more valuable.
440 queenChecks = (b1 | b2) & attackedBy[Them][QUEEN] & safe
441 & ~(attackedBy[Us][QUEEN] | rookChecks);
443 kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
445 // Enemy bishops checks: count them only if they are from squares from which
446 // opponent cannot give a queen check, because queen checks are more valuable.
447 bishopChecks = b2 & attackedBy[Them][BISHOP] & safe
450 kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
453 unsafeChecks |= b2 & attackedBy[Them][BISHOP];
455 // Enemy knights checks
456 knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
457 if (knightChecks & safe)
458 kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
460 unsafeChecks |= knightChecks;
462 // Find the squares that opponent attacks in our king flank, the squares
463 // which they attack twice in that flank, and the squares that we defend.
464 b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
465 b2 = b1 & attackedBy2[Them];
466 b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
468 int kingFlankAttack = popcount(b1) + popcount(b2);
469 int kingFlankDefense = popcount(b3);
471 kingDanger += kingAttackersCount[Them] * kingAttackersWeight[Them]
472 + 185 * popcount(kingRing[Us] & weak)
473 + 148 * popcount(unsafeChecks)
474 + 98 * popcount(pos.blockers_for_king(Us))
475 + 69 * kingAttacksCount[Them]
476 + 3 * kingFlankAttack * kingFlankAttack / 8
477 + mg_value(mobility[Them] - mobility[Us])
478 - 873 * !pos.count<QUEEN>(Them)
479 - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])
480 - 6 * mg_value(score) / 8
481 - 4 * kingFlankDefense
484 // Transform the kingDanger units into a Score, and subtract it from the evaluation
485 if (kingDanger > 100)
486 score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
488 // Penalty when our king is on a pawnless flank
489 if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
490 score -= PawnlessFlank;
492 // Penalty if king flank is under attack, potentially moving toward the king
493 score -= FlankAttacks * kingFlankAttack;
496 Trace::add(KING, Us, score);
502 // Evaluation::threats() assigns bonuses according to the types of the
503 // attacking and the attacked pieces.
505 template<Tracing T> template<Color Us>
506 Score Evaluation<T>::threats() const {
508 constexpr Color Them = ~Us;
509 constexpr Direction Up = pawn_push(Us);
510 constexpr Bitboard TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
512 Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
513 Score score = SCORE_ZERO;
516 nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
518 // Squares strongly protected by the enemy, either because they defend the
519 // square with a pawn, or because they defend the square twice and we don't.
520 stronglyProtected = attackedBy[Them][PAWN]
521 | (attackedBy2[Them] & ~attackedBy2[Us]);
523 // Non-pawn enemies, strongly protected
524 defended = nonPawnEnemies & stronglyProtected;
526 // Enemies not strongly protected and under our attack
527 weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
529 // Bonus according to the kind of attacking pieces
532 b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
534 score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
536 b = weak & attackedBy[Us][ROOK];
538 score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
540 if (weak & attackedBy[Us][KING])
541 score += ThreatByKing;
543 b = ~attackedBy[Them][ALL_PIECES]
544 | (nonPawnEnemies & attackedBy2[Us]);
545 score += Hanging * popcount(weak & b);
547 // Additional bonus if weak piece is only protected by a queen
548 score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
551 // Bonus for restricting their piece moves
552 b = attackedBy[Them][ALL_PIECES]
554 & attackedBy[Us][ALL_PIECES];
555 score += RestrictedPiece * popcount(b);
557 // Protected or unattacked squares
558 safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
560 // Bonus for attacking enemy pieces with our relatively safe pawns
561 b = pos.pieces(Us, PAWN) & safe;
562 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
563 score += ThreatBySafePawn * popcount(b);
565 // Find squares where our pawns can push on the next move
566 b = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
567 b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
569 // Keep only the squares which are relatively safe
570 b &= ~attackedBy[Them][PAWN] & safe;
572 // Bonus for safe pawn threats on the next move
573 b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
574 score += ThreatByPawnPush * popcount(b);
576 // Bonus for threats on the next moves against enemy queen
577 if (pos.count<QUEEN>(Them) == 1)
579 Square s = pos.square<QUEEN>(Them);
580 safe = mobilityArea[Us] & ~stronglyProtected;
582 b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
584 score += KnightOnQueen * popcount(b & safe);
586 b = (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
587 | (attackedBy[Us][ROOK ] & attacks_bb<ROOK >(s, pos.pieces()));
589 score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]);
593 Trace::add(THREAT, Us, score);
598 // Evaluation::passed() evaluates the passed pawns and candidate passed
599 // pawns of the given color.
601 template<Tracing T> template<Color Us>
602 Score Evaluation<T>::passed() const {
604 constexpr Color Them = ~Us;
605 constexpr Direction Up = pawn_push(Us);
606 constexpr Direction Down = -Up;
608 auto king_proximity = [&](Color c, Square s) {
609 return std::min(distance(pos.square<KING>(c), s), 5);
612 Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
613 Score score = SCORE_ZERO;
615 b = pe->passed_pawns(Us);
617 blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
620 helpers = shift<Up>(pos.pieces(Us, PAWN))
622 & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
624 // Remove blocked candidate passers that don't have help to pass
626 | shift<WEST>(helpers)
627 | shift<EAST>(helpers);
632 Square s = pop_lsb(&b);
634 assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
636 int r = relative_rank(Us, s);
638 Score bonus = PassedRank[r];
643 Square blockSq = s + Up;
645 // Adjust bonus based on the king's proximity
646 bonus += make_score(0, ( (king_proximity(Them, blockSq) * 19) / 4
647 - king_proximity(Us, blockSq) * 2) * w);
649 // If blockSq is not the queening square then consider also a second push
651 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
653 // If the pawn is free to advance, then increase the bonus
654 if (pos.empty(blockSq))
656 squaresToQueen = forward_file_bb(Us, s);
657 unsafeSquares = passed_pawn_span(Us, s);
659 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
661 if (!(pos.pieces(Them) & bb))
662 unsafeSquares &= attackedBy[Them][ALL_PIECES];
664 // If there are no enemy attacks on passed pawn span, assign a big bonus.
665 // Otherwise assign a smaller bonus if the path to queen is not attacked
666 // and even smaller bonus if it is attacked but block square is not.
667 int k = !unsafeSquares ? 35 :
668 !(unsafeSquares & squaresToQueen) ? 20 :
669 !(unsafeSquares & blockSq) ? 9 :
672 // Assign a larger bonus if the block square is defended
673 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
676 bonus += make_score(k * w, k * w);
680 score += bonus - PassedFile * edge_distance(file_of(s));
684 Trace::add(PASSED, Us, score);
690 // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
691 // play in the opening. It is based on the number of safe squares on the 4 central files
692 // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
693 // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
695 template<Tracing T> template<Color Us>
696 Score Evaluation<T>::space() const {
698 // Early exit if, for example, both queens or 6 minor pieces have been exchanged
699 if (pos.non_pawn_material() < SpaceThreshold)
702 constexpr Color Them = ~Us;
703 constexpr Direction Down = -pawn_push(Us);
704 constexpr Bitboard SpaceMask =
705 Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
706 : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
708 // Find the available squares for our pieces inside the area defined by SpaceMask
709 Bitboard safe = SpaceMask
710 & ~pos.pieces(Us, PAWN)
711 & ~attackedBy[Them][PAWN];
713 // Find all squares which are at most three squares behind some friendly pawn
714 Bitboard behind = pos.pieces(Us, PAWN);
715 behind |= shift<Down>(behind);
716 behind |= shift<Down+Down>(behind);
718 int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
719 int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
720 Score score = make_score(bonus * weight * weight / 16, 0);
723 Trace::add(SPACE, Us, score);
729 // Evaluation::winnable() adjusts the midgame and endgame score components, based on
730 // the known attacking/defending status of the players. The final value is derived
731 // by interpolation from the midgame and endgame values.
734 Value Evaluation<T>::winnable(Score score) const {
736 int outflanking = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
737 - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
739 bool pawnsOnBothFlanks = (pos.pieces(PAWN) & QueenSide)
740 && (pos.pieces(PAWN) & KingSide);
742 bool almostUnwinnable = outflanking < 0
743 && !pawnsOnBothFlanks;
745 bool infiltration = rank_of(pos.square<KING>(WHITE)) > RANK_4
746 || rank_of(pos.square<KING>(BLACK)) < RANK_5;
748 // Compute the initiative bonus for the attacking side
749 int complexity = 9 * pe->passed_count()
750 + 12 * pos.count<PAWN>()
752 + 21 * pawnsOnBothFlanks
754 + 51 * !pos.non_pawn_material()
755 - 43 * almostUnwinnable
758 Value mg = mg_value(score);
759 Value eg = eg_value(score);
761 // Now apply the bonus: note that we find the attacking side by extracting the
762 // sign of the midgame or endgame values, and that we carefully cap the bonus
763 // so that the midgame and endgame scores do not change sign after the bonus.
764 int u = ((mg > 0) - (mg < 0)) * Utility::clamp(complexity + 50, -abs(mg), 0);
765 int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
770 // Compute the scale factor for the winning side
771 Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
772 int sf = me->scale_factor(pos, strongSide);
774 // If scale factor is not already specific, scale down via general heuristics
775 if (sf == SCALE_FACTOR_NORMAL)
777 if (pos.opposite_bishops())
779 if ( pos.non_pawn_material(WHITE) == BishopValueMg
780 && pos.non_pawn_material(BLACK) == BishopValueMg)
781 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
783 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
785 else if ( pos.non_pawn_material(WHITE) == RookValueMg
786 && pos.non_pawn_material(BLACK) == RookValueMg
787 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
788 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
789 && (attackedBy[~strongSide][KING] & pos.pieces(~strongSide, PAWN)))
791 else if (pos.count<QUEEN>() == 1)
792 sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
793 : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
795 sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide));
798 // Interpolate between the middlegame and (scaled by 'sf') endgame score
799 v = mg * int(me->game_phase())
800 + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
805 Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
806 Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
813 // Evaluation::value() is the main function of the class. It computes the various
814 // parts of the evaluation and returns the value of the position from the point
815 // of view of the side to move.
818 Value Evaluation<T>::value() {
820 assert(!pos.checkers());
822 // Probe the material hash table
823 me = Material::probe(pos);
825 // If we have a specialized evaluation function for the current material
826 // configuration, call it and return.
827 if (me->specialized_eval_exists())
828 return me->evaluate(pos);
830 // Initialize score by reading the incrementally updated scores included in
831 // the position object (material + piece square tables) and the material
832 // imbalance. Score is computed internally from the white point of view.
833 Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
835 // Probe the pawn hash table
836 pe = Pawns::probe(pos);
837 score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
839 // Early exit if score is high
840 Value v = (mg_value(score) + eg_value(score)) / 2;
841 if (abs(v) > LazyThreshold + pos.non_pawn_material() / 64)
842 return pos.side_to_move() == WHITE ? v : -v;
844 // Main evaluation begins here
848 // Pieces evaluated first (also populates attackedBy, attackedBy2).
849 // Note that the order of evaluation of the terms is left unspecified.
850 score += pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
851 + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
852 + pieces<WHITE, ROOK >() - pieces<BLACK, ROOK >()
853 + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
855 score += mobility[WHITE] - mobility[BLACK];
857 // More complex interactions that require fully populated attack bitboards
858 score += king< WHITE>() - king< BLACK>()
859 + threats<WHITE>() - threats<BLACK>()
860 + passed< WHITE>() - passed< BLACK>()
861 + space< WHITE>() - space< BLACK>();
863 // Derive single value from mg and eg parts of score
866 // In case of tracing add all remaining individual evaluation terms
869 Trace::add(MATERIAL, pos.psq_score());
870 Trace::add(IMBALANCE, me->imbalance());
871 Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
872 Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
878 // Side to move point of view
879 v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
881 // Damp down the evaluation linearly when shuffling
882 v = v * (100 - pos.rule50_count()) / 100;
890 /// evaluate() is the evaluator for the outer world. It returns a static
891 /// evaluation of the position from the point of view of the side to move.
893 Value Eval::evaluate(const Position& pos) {
894 return Evaluation<NO_TRACE>(pos).value();
898 /// trace() is like evaluate(), but instead of returning a value, it returns
899 /// a string (suitable for outputting to stdout) that contains the detailed
900 /// descriptions and values of each evaluation term. Useful for debugging.
902 std::string Eval::trace(const Position& pos) {
905 return "Total evaluation: none (in check)";
907 std::memset(scores, 0, sizeof(scores));
909 pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
911 Value v = Evaluation<TRACE>(pos).value();
913 v = pos.side_to_move() == WHITE ? v : -v; // Trace scores are from white's point of view
915 std::stringstream ss;
916 ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
917 << " Term | White | Black | Total \n"
918 << " | MG EG | MG EG | MG EG \n"
919 << " ------------+-------------+-------------+------------\n"
920 << " Material | " << Term(MATERIAL)
921 << " Imbalance | " << Term(IMBALANCE)
922 << " Pawns | " << Term(PAWN)
923 << " Knights | " << Term(KNIGHT)
924 << " Bishops | " << Term(BISHOP)
925 << " Rooks | " << Term(ROOK)
926 << " Queens | " << Term(QUEEN)
927 << " Mobility | " << Term(MOBILITY)
928 << " King safety | " << Term(KING)
929 << " Threats | " << Term(THREAT)
930 << " Passed | " << Term(PASSED)
931 << " Space | " << Term(SPACE)
932 << " Winnable | " << Term(WINNABLE)
933 << " ------------+-------------+-------------+------------\n"
934 << " Total | " << Term(TOTAL);
936 ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";