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-2010 Marco Costalba, Joona Kiiski, Tord Romstad
6 Stockfish is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 Stockfish is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
33 #include "ucioption.h"
37 //// Local definitions
42 const int Sign[2] = { 1, -1 };
44 // Evaluation grain size, must be a power of 2
45 const int GrainSize = 8;
47 // Evaluation weights, initialized from UCI options
48 enum { Mobility, PawnStructure, PassedPawns, Space, KingDangerUs, KingDangerThem };
52 #define S(mg, eg) make_score(mg, eg)
54 // Internal evaluation weights. These are applied on top of the evaluation
55 // weights read from UCI parameters. The purpose is to be able to change
56 // the evaluation weights while keeping the default values of the UCI
57 // parameters at 100, which looks prettier.
59 // Values modified by Joona Kiiski
60 const Score WeightsInternal[] = {
61 S(248, 271), S(233, 201), S(252, 259), S(46, 0), S(247, 0), S(259, 0)
64 // MobilityBonus[PieceType][attacked] contains mobility bonuses for middle and
65 // end game, indexed by piece type and number of attacked squares not occupied
66 // by friendly pieces.
67 const Score MobilityBonus[][32] = {
69 { S(-38,-33), S(-25,-23), S(-12,-13), S( 0, -3), S(12, 7), S(25, 17), // Knights
70 S( 31, 22), S( 38, 27), S( 38, 27) },
71 { S(-25,-30), S(-11,-16), S( 3, -2), S(17, 12), S(31, 26), S(45, 40), // Bishops
72 S( 57, 52), S( 65, 60), S( 71, 65), S(74, 69), S(76, 71), S(78, 73),
73 S( 79, 74), S( 80, 75), S( 81, 76), S(81, 76) },
74 { S(-20,-36), S(-14,-19), S( -8, -3), S(-2, 13), S( 4, 29), S(10, 46), // Rooks
75 S( 14, 62), S( 19, 79), S( 23, 95), S(26,106), S(27,111), S(28,114),
76 S( 29,116), S( 30,117), S( 31,118), S(32,118) },
77 { S(-10,-18), S( -8,-13), S( -6, -7), S(-3, -2), S(-1, 3), S( 1, 8), // Queens
78 S( 3, 13), S( 5, 19), S( 8, 23), S(10, 27), S(12, 32), S(15, 34),
79 S( 16, 35), S( 17, 35), S( 18, 35), S(20, 35), S(20, 35), S(20, 35),
80 S( 20, 35), S( 20, 35), S( 20, 35), S(20, 35), S(20, 35), S(20, 35),
81 S( 20, 35), S( 20, 35), S( 20, 35), S(20, 35), S(20, 35), S(20, 35),
82 S( 20, 35), S( 20, 35) }
85 // OutpostBonus[PieceType][Square] contains outpost bonuses of knights and
86 // bishops, indexed by piece type and square (from white's point of view).
87 const Value OutpostBonus[][64] = {
90 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // Knights
91 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0),
92 V(0), V(0), V(4), V(8), V(8), V(4), V(0), V(0),
93 V(0), V(4),V(17),V(26),V(26),V(17), V(4), V(0),
94 V(0), V(8),V(26),V(35),V(35),V(26), V(8), V(0),
95 V(0), V(4),V(17),V(17),V(17),V(17), V(4), V(0),
96 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0),
97 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) },
99 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // Bishops
100 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0),
101 V(0), V(0), V(5), V(5), V(5), V(5), V(0), V(0),
102 V(0), V(5),V(10),V(10),V(10),V(10), V(5), V(0),
103 V(0),V(10),V(21),V(21),V(21),V(21),V(10), V(0),
104 V(0), V(5), V(8), V(8), V(8), V(8), V(5), V(0),
105 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0),
106 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) }
109 // ThreatBonus[attacking][attacked] contains threat bonuses according to
110 // which piece type attacks which one.
111 const Score ThreatBonus[][8] = {
113 { S(0, 0), S( 7, 39), S( 0, 0), S(24, 49), S(41,100), S(41,100) }, // KNIGHT
114 { S(0, 0), S( 7, 39), S(24, 49), S( 0, 0), S(41,100), S(41,100) }, // BISHOP
115 { S(0, 0), S(-1, 29), S(15, 49), S(15, 49), S( 0, 0), S(24, 49) }, // ROOK
116 { S(0, 0), S(15, 39), S(15, 39), S(15, 39), S(15, 39), S( 0, 0) } // QUEEN
119 // ThreatedByPawnPenalty[PieceType] contains a penalty according to which
120 // piece type is attacked by an enemy pawn.
121 const Score ThreatedByPawnPenalty[] = {
122 S(0, 0), S(0, 0), S(56, 70), S(56, 70), S(76, 99), S(86, 118)
127 // Rooks and queens on the 7th rank (modified by Joona Kiiski)
128 const Score RookOn7thBonus = make_score(47, 98);
129 const Score QueenOn7thBonus = make_score(27, 54);
131 // Rooks on open files (modified by Joona Kiiski)
132 const Score RookOpenFileBonus = make_score(43, 43);
133 const Score RookHalfOpenFileBonus = make_score(19, 19);
135 // Penalty for rooks trapped inside a friendly king which has lost the
137 const Value TrappedRookPenalty = Value(180);
139 // The SpaceMask[Color] contains the area of the board which is considered
140 // by the space evaluation. In the middle game, each side is given a bonus
141 // based on how many squares inside this area are safe and available for
142 // friendly minor pieces.
143 const Bitboard SpaceMask[2] = {
144 (1ULL << SQ_C2) | (1ULL << SQ_D2) | (1ULL << SQ_E2) | (1ULL << SQ_F2) |
145 (1ULL << SQ_C3) | (1ULL << SQ_D3) | (1ULL << SQ_E3) | (1ULL << SQ_F3) |
146 (1ULL << SQ_C4) | (1ULL << SQ_D4) | (1ULL << SQ_E4) | (1ULL << SQ_F4),
147 (1ULL << SQ_C7) | (1ULL << SQ_D7) | (1ULL << SQ_E7) | (1ULL << SQ_F7) |
148 (1ULL << SQ_C6) | (1ULL << SQ_D6) | (1ULL << SQ_E6) | (1ULL << SQ_F6) |
149 (1ULL << SQ_C5) | (1ULL << SQ_D5) | (1ULL << SQ_E5) | (1ULL << SQ_F5)
152 // King danger constants and variables. The king danger scores are taken
153 // from the KingDangerTable[]. Various little "meta-bonuses" measuring
154 // the strength of the enemy attack are added up into an integer, which
155 // is used as an index to KingDangerTable[].
157 // KingAttackWeights[PieceType] contains king attack weights by piece type
158 const int KingAttackWeights[] = { 0, 0, 2, 2, 3, 5 };
160 // Bonuses for enemy's safe checks
161 const int QueenContactCheckBonus = 3;
162 const int QueenCheckBonus = 2;
163 const int RookCheckBonus = 1;
164 const int BishopCheckBonus = 1;
165 const int KnightCheckBonus = 1;
167 // InitKingDanger[Square] contains penalties based on the position of the
168 // defending king, indexed by king's square (from white's point of view).
169 const int InitKingDanger[] = {
170 2, 0, 2, 5, 5, 2, 0, 2,
171 2, 2, 4, 8, 8, 4, 2, 2,
172 7, 10, 12, 12, 12, 12, 10, 7,
173 15, 15, 15, 15, 15, 15, 15, 15,
174 15, 15, 15, 15, 15, 15, 15, 15,
175 15, 15, 15, 15, 15, 15, 15, 15,
176 15, 15, 15, 15, 15, 15, 15, 15,
177 15, 15, 15, 15, 15, 15, 15, 15
180 // KingDangerTable[Color][attackUnits] contains the actual king danger
181 // weighted scores, indexed by color and by a calculated integer number.
182 Score KingDangerTable[2][128];
184 // Pawn and material hash tables, indexed by the current thread id.
185 // Note that they will be initialized at 0 being global variables.
186 MaterialInfoTable* MaterialTable[MAX_THREADS];
187 PawnInfoTable* PawnTable[MAX_THREADS];
189 // Function prototypes
190 template<bool HasPopCnt>
191 Value do_evaluate(const Position& pos, EvalInfo& ei);
193 template<Color Us, bool HasPopCnt>
194 void init_attack_tables(const Position& pos, EvalInfo& ei);
196 template<Color Us, bool HasPopCnt>
197 Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei);
199 template<Color Us, bool HasPopCnt>
200 void evaluate_king(const Position& pos, EvalInfo& ei);
203 void evaluate_threats(const Position& pos, EvalInfo& ei);
205 template<Color Us, bool HasPopCnt>
206 int evaluate_space(const Position& pos, EvalInfo& ei);
209 void evaluate_passed_pawns(const Position& pos, EvalInfo& ei);
211 inline Score apply_weight(Score v, Score weight);
212 Value scale_by_game_phase(const Score& v, Phase ph, const ScaleFactor sf[]);
213 Score weight_option(const std::string& mgOpt, const std::string& egOpt, Score internalWeight);
223 /// Prefetches in pawn hash tables
225 void prefetchPawn(Key key, int threadID) {
227 PawnTable[threadID]->prefetch(key);
230 /// evaluate() is the main evaluation function. It always computes two
231 /// values, an endgame score and a middle game score, and interpolates
232 /// between them based on the remaining material.
233 Value evaluate(const Position& pos, EvalInfo& ei) {
235 return CpuHasPOPCNT ? do_evaluate<true>(pos, ei)
236 : do_evaluate<false>(pos, ei);
241 template<bool HasPopCnt>
242 Value do_evaluate(const Position& pos, EvalInfo& ei) {
244 ScaleFactor factor[2];
248 assert(pos.thread() >= 0 && pos.thread() < MAX_THREADS);
249 assert(!pos.is_check());
251 memset(&ei, 0, sizeof(EvalInfo));
253 // Initialize by reading the incrementally updated scores included in the
254 // position object (material + piece square tables).
255 ei.value = pos.value();
257 // Probe the material hash table
258 ei.mi = MaterialTable[pos.thread()]->get_material_info(pos);
259 ei.value += ei.mi->material_value();
261 // If we have a specialized evaluation function for the current material
262 // configuration, call it and return.
263 if (ei.mi->specialized_eval_exists())
264 return ei.mi->evaluate(pos);
266 // After get_material_info() call that modifies them
267 factor[WHITE] = ei.mi->scale_factor(pos, WHITE);
268 factor[BLACK] = ei.mi->scale_factor(pos, BLACK);
270 // Probe the pawn hash table
271 ei.pi = PawnTable[pos.thread()]->get_pawn_info(pos);
272 ei.value += apply_weight(ei.pi->pawns_value(), Weights[PawnStructure]);
274 // Initialize attack bitboards with pawns evaluation
275 init_attack_tables<WHITE, HasPopCnt>(pos, ei);
276 init_attack_tables<BLACK, HasPopCnt>(pos, ei);
278 // Evaluate pieces and mobility
279 mobility = evaluate_pieces_of_color<WHITE, HasPopCnt>(pos, ei)
280 - evaluate_pieces_of_color<BLACK, HasPopCnt>(pos, ei);
281 ei.value += apply_weight(mobility, Weights[Mobility]);
283 // Kings. Kings are evaluated after all other pieces for both sides,
284 // because we need complete attack information for all pieces when computing
285 // the king safety evaluation.
286 evaluate_king<WHITE, HasPopCnt>(pos, ei);
287 evaluate_king<BLACK, HasPopCnt>(pos, ei);
289 // Evaluate tactical threats, we need full attack info including king
290 evaluate_threats<WHITE>(pos, ei);
291 evaluate_threats<BLACK>(pos, ei);
293 // Evaluate passed pawns, we need full attack info including king
294 evaluate_passed_pawns<WHITE>(pos, ei);
295 evaluate_passed_pawns<BLACK>(pos, ei);
297 Phase phase = ei.mi->game_phase();
299 // Middle-game specific evaluation terms
300 if (phase > PHASE_ENDGAME)
302 // Evaluate pawn storms in positions with opposite castling
303 if ( square_file(pos.king_square(WHITE)) >= FILE_E
304 && square_file(pos.king_square(BLACK)) <= FILE_D)
306 ei.value += make_score(ei.pi->queenside_storm_value(WHITE) - ei.pi->kingside_storm_value(BLACK), 0);
308 else if ( square_file(pos.king_square(WHITE)) <= FILE_D
309 && square_file(pos.king_square(BLACK)) >= FILE_E)
311 ei.value += make_score(ei.pi->kingside_storm_value(WHITE) - ei.pi->queenside_storm_value(BLACK), 0);
313 // Evaluate space for both sides
314 if (ei.mi->space_weight() > 0)
316 int s = evaluate_space<WHITE, HasPopCnt>(pos, ei) - evaluate_space<BLACK, HasPopCnt>(pos, ei);
317 ei.value += apply_weight(make_score(s * ei.mi->space_weight(), 0), Weights[Space]);
321 // If we don't already have an unusual scale factor, check for opposite
322 // colored bishop endgames, and use a lower scale for those
323 if ( phase < PHASE_MIDGAME
324 && pos.opposite_colored_bishops()
325 && ( (factor[WHITE] == SCALE_FACTOR_NORMAL && eg_value(ei.value) > VALUE_ZERO)
326 || (factor[BLACK] == SCALE_FACTOR_NORMAL && eg_value(ei.value) < VALUE_ZERO)))
330 // Only the two bishops ?
331 if ( pos.non_pawn_material(WHITE) == BishopValueMidgame
332 && pos.non_pawn_material(BLACK) == BishopValueMidgame)
334 // Check for KBP vs KB with only a single pawn that is almost
335 // certainly a draw or at least two pawns.
336 bool one_pawn = (pos.piece_count(WHITE, PAWN) + pos.piece_count(BLACK, PAWN) == 1);
337 sf = one_pawn ? ScaleFactor(8) : ScaleFactor(32);
340 // Endgame with opposite-colored bishops, but also other pieces. Still
341 // a bit drawish, but not as drawish as with only the two bishops.
342 sf = ScaleFactor(50);
344 if (factor[WHITE] == SCALE_FACTOR_NORMAL)
346 if (factor[BLACK] == SCALE_FACTOR_NORMAL)
350 // Interpolate between the middle game and the endgame score
351 return Sign[pos.side_to_move()] * scale_by_game_phase(ei.value, phase, factor);
356 /// init_eval() initializes various tables used by the evaluation function
358 void init_eval(int threads) {
360 assert(threads <= MAX_THREADS);
362 for (int i = 0; i < MAX_THREADS; i++)
367 delete MaterialTable[i];
369 MaterialTable[i] = NULL;
373 PawnTable[i] = new PawnInfoTable();
374 if (!MaterialTable[i])
375 MaterialTable[i] = new MaterialInfoTable();
380 /// quit_eval() releases heap-allocated memory at program termination
384 for (int i = 0; i < MAX_THREADS; i++)
387 delete MaterialTable[i];
389 MaterialTable[i] = NULL;
394 /// read_weights() reads evaluation weights from the corresponding UCI parameters
396 void read_weights(Color us) {
398 // King safety is asymmetrical. Our king danger level is weighted by
399 // "Cowardice" UCI parameter, instead the opponent one by "Aggressiveness".
400 const int kingDangerUs = (us == WHITE ? KingDangerUs : KingDangerThem);
401 const int kingDangerThem = (us == WHITE ? KingDangerThem : KingDangerUs);
403 Weights[Mobility] = weight_option("Mobility (Middle Game)", "Mobility (Endgame)", WeightsInternal[Mobility]);
404 Weights[PawnStructure] = weight_option("Pawn Structure (Middle Game)", "Pawn Structure (Endgame)", WeightsInternal[PawnStructure]);
405 Weights[PassedPawns] = weight_option("Passed Pawns (Middle Game)", "Passed Pawns (Endgame)", WeightsInternal[PassedPawns]);
406 Weights[Space] = weight_option("Space", "Space", WeightsInternal[Space]);
407 Weights[kingDangerUs] = weight_option("Cowardice", "Cowardice", WeightsInternal[KingDangerUs]);
408 Weights[kingDangerThem] = weight_option("Aggressiveness", "Aggressiveness", WeightsInternal[KingDangerThem]);
410 // If running in analysis mode, make sure we use symmetrical king safety. We do this
411 // by replacing both Weights[kingDangerUs] and Weights[kingDangerThem] by their average.
412 if (get_option_value_bool("UCI_AnalyseMode"))
413 Weights[kingDangerUs] = Weights[kingDangerThem] = (Weights[kingDangerUs] + Weights[kingDangerThem]) / 2;
421 // init_attack_tables() initializes king bitboards for both sides adding
422 // pawn attacks. To be done before other evaluations.
424 template<Color Us, bool HasPopCnt>
425 void init_attack_tables(const Position& pos, EvalInfo& ei) {
427 const Color Them = (Us == WHITE ? BLACK : WHITE);
429 Bitboard b = ei.attackedBy[Them][KING] = pos.attacks_from<KING>(pos.king_square(Them));
430 ei.kingZone[Us] = (b | (Us == WHITE ? b >> 8 : b << 8));
431 ei.attackedBy[Us][PAWN] = ei.pi->pawn_attacks(Us);
432 b &= ei.attackedBy[Us][PAWN];
434 ei.kingAttackersCount[Us] = count_1s_max_15<HasPopCnt>(b) / 2;
438 // evaluate_outposts() evaluates bishop and knight outposts squares
440 template<PieceType Piece, Color Us>
441 void evaluate_outposts(const Position& pos, EvalInfo& ei, Square s) {
443 const Color Them = (Us == WHITE ? BLACK : WHITE);
445 assert (Piece == BISHOP || Piece == KNIGHT);
447 // Initial bonus based on square
448 Value bonus = OutpostBonus[Piece == BISHOP][relative_square(Us, s)];
450 // Increase bonus if supported by pawn, especially if the opponent has
451 // no minor piece which can exchange the outpost piece
452 if (bonus && bit_is_set(ei.attackedBy[Us][PAWN], s))
454 if ( pos.pieces(KNIGHT, Them) == EmptyBoardBB
455 && (SquaresByColorBB[square_color(s)] & pos.pieces(BISHOP, Them)) == EmptyBoardBB)
456 bonus += bonus + bonus / 2;
460 ei.value += Sign[Us] * make_score(bonus, bonus);
464 // evaluate_pieces<>() assigns bonuses and penalties to the pieces of a given color
466 template<PieceType Piece, Color Us, bool HasPopCnt>
467 Score evaluate_pieces(const Position& pos, EvalInfo& ei, Bitboard no_mob_area) {
473 Score mobility = SCORE_ZERO;
475 const Color Them = (Us == WHITE ? BLACK : WHITE);
476 const Square* ptr = pos.piece_list_begin(Us, Piece);
478 while ((s = *ptr++) != SQ_NONE)
480 // Find attacked squares, including x-ray attacks for bishops and rooks
481 if (Piece == KNIGHT || Piece == QUEEN)
482 b = pos.attacks_from<Piece>(s);
483 else if (Piece == BISHOP)
484 b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(QUEEN, Us));
485 else if (Piece == ROOK)
486 b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, QUEEN, Us));
490 // Update attack info
491 ei.attackedBy[Us][Piece] |= b;
494 if (b & ei.kingZone[Us])
496 ei.kingAttackersCount[Us]++;
497 ei.kingAttackersWeight[Us] += KingAttackWeights[Piece];
498 Bitboard bb = (b & ei.attackedBy[Them][KING]);
500 ei.kingAdjacentZoneAttacksCount[Us] += count_1s_max_15<HasPopCnt>(bb);
504 mob = (Piece != QUEEN ? count_1s_max_15<HasPopCnt>(b & no_mob_area)
505 : count_1s<HasPopCnt>(b & no_mob_area));
507 mobility += MobilityBonus[Piece][mob];
509 // Decrease score if we are attacked by an enemy pawn. Remaining part
510 // of threat evaluation must be done later when we have full attack info.
511 if (bit_is_set(ei.attackedBy[Them][PAWN], s))
512 ei.value -= Sign[Us] * ThreatedByPawnPenalty[Piece];
514 // Bishop and knight outposts squares
515 if ((Piece == BISHOP || Piece == KNIGHT) && pos.square_is_weak(s, Us))
516 evaluate_outposts<Piece, Us>(pos, ei, s);
518 // Queen or rook on 7th rank
519 if ( (Piece == ROOK || Piece == QUEEN)
520 && relative_rank(Us, s) == RANK_7
521 && relative_rank(Us, pos.king_square(Them)) == RANK_8)
523 ei.value += Sign[Us] * (Piece == ROOK ? RookOn7thBonus : QueenOn7thBonus);
526 // Special extra evaluation for rooks
529 // Open and half-open files
531 if (ei.pi->file_is_half_open(Us, f))
533 if (ei.pi->file_is_half_open(Them, f))
534 ei.value += Sign[Us] * RookOpenFileBonus;
536 ei.value += Sign[Us] * RookHalfOpenFileBonus;
539 // Penalize rooks which are trapped inside a king. Penalize more if
540 // king has lost right to castle.
541 if (mob > 6 || ei.pi->file_is_half_open(Us, f))
544 ksq = pos.king_square(Us);
546 if ( square_file(ksq) >= FILE_E
547 && square_file(s) > square_file(ksq)
548 && (relative_rank(Us, ksq) == RANK_1 || square_rank(ksq) == square_rank(s)))
550 // Is there a half-open file between the king and the edge of the board?
551 if (!ei.pi->has_open_file_to_right(Us, square_file(ksq)))
552 ei.value -= Sign[Us] * make_score(pos.can_castle(Us) ? (TrappedRookPenalty - mob * 16) / 2
553 : (TrappedRookPenalty - mob * 16), 0);
555 else if ( square_file(ksq) <= FILE_D
556 && square_file(s) < square_file(ksq)
557 && (relative_rank(Us, ksq) == RANK_1 || square_rank(ksq) == square_rank(s)))
559 // Is there a half-open file between the king and the edge of the board?
560 if (!ei.pi->has_open_file_to_left(Us, square_file(ksq)))
561 ei.value -= Sign[Us] * make_score(pos.can_castle(Us) ? (TrappedRookPenalty - mob * 16) / 2
562 : (TrappedRookPenalty - mob * 16), 0);
570 // evaluate_threats<>() assigns bonuses according to the type of attacking piece
571 // and the type of attacked one.
574 void evaluate_threats(const Position& pos, EvalInfo& ei) {
576 const Color Them = (Us == WHITE ? BLACK : WHITE);
579 Score bonus = SCORE_ZERO;
581 // Enemy pieces not defended by a pawn and under our attack
582 Bitboard weakEnemies = pos.pieces_of_color(Them)
583 & ~ei.attackedBy[Them][PAWN]
584 & ei.attackedBy[Us][0];
588 // Add bonus according to type of attacked enemy pieces and to the
589 // type of attacking piece, from knights to queens. Kings are not
590 // considered because are already special handled in king evaluation.
591 for (PieceType pt1 = KNIGHT; pt1 < KING; pt1++)
593 b = ei.attackedBy[Us][pt1] & weakEnemies;
595 for (PieceType pt2 = PAWN; pt2 < KING; pt2++)
596 if (b & pos.pieces(pt2))
597 bonus += ThreatBonus[pt1][pt2];
599 ei.value += Sign[Us] * bonus;
603 // evaluate_pieces_of_color<>() assigns bonuses and penalties to all the
604 // pieces of a given color.
606 template<Color Us, bool HasPopCnt>
607 Score evaluate_pieces_of_color(const Position& pos, EvalInfo& ei) {
609 const Color Them = (Us == WHITE ? BLACK : WHITE);
611 Score mobility = SCORE_ZERO;
613 // Do not include in mobility squares protected by enemy pawns or occupied by our pieces
614 const Bitboard no_mob_area = ~(ei.attackedBy[Them][PAWN] | pos.pieces_of_color(Us));
616 mobility += evaluate_pieces<KNIGHT, Us, HasPopCnt>(pos, ei, no_mob_area);
617 mobility += evaluate_pieces<BISHOP, Us, HasPopCnt>(pos, ei, no_mob_area);
618 mobility += evaluate_pieces<ROOK, Us, HasPopCnt>(pos, ei, no_mob_area);
619 mobility += evaluate_pieces<QUEEN, Us, HasPopCnt>(pos, ei, no_mob_area);
621 // Sum up all attacked squares
622 ei.attackedBy[Us][0] = ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT]
623 | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK]
624 | ei.attackedBy[Us][QUEEN] | ei.attackedBy[Us][KING];
629 // evaluate_king<>() assigns bonuses and penalties to a king of a given color
631 template<Color Us, bool HasPopCnt>
632 void evaluate_king(const Position& pos, EvalInfo& ei) {
634 const Color Them = (Us == WHITE ? BLACK : WHITE);
636 Bitboard undefended, b, b1, b2, safe;
639 const Square ksq = pos.king_square(Us);
642 ei.value += Sign[Us] * ei.pi->king_shelter(pos, Us, ksq);
644 // King safety. This is quite complicated, and is almost certainly far
645 // from optimally tuned.
646 if ( pos.piece_count(Them, QUEEN) >= 1
647 && ei.kingAttackersCount[Them] >= 2
648 && pos.non_pawn_material(Them) >= QueenValueMidgame + RookValueMidgame
649 && ei.kingAdjacentZoneAttacksCount[Them])
651 // Is it the attackers turn to move?
652 sente = (Them == pos.side_to_move());
654 // Find the attacked squares around the king which has no defenders
655 // apart from the king itself
656 undefended = ei.attacked_by(Them) & ei.attacked_by(Us, KING);
657 undefended &= ~( ei.attacked_by(Us, PAWN) | ei.attacked_by(Us, KNIGHT)
658 | ei.attacked_by(Us, BISHOP) | ei.attacked_by(Us, ROOK)
659 | ei.attacked_by(Us, QUEEN));
661 // Initialize the 'attackUnits' variable, which is used later on as an
662 // index to the KingDangerTable[] array. The initial value is based on
663 // the number and types of the enemy's attacking pieces, the number of
664 // attacked and undefended squares around our king, the square of the
665 // king, and the quality of the pawn shelter.
666 attackUnits = Min(25, (ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them]) / 2)
667 + 3 * (ei.kingAdjacentZoneAttacksCount[Them] + count_1s_max_15<HasPopCnt>(undefended))
668 + InitKingDanger[relative_square(Us, ksq)]
669 - mg_value(ei.pi->king_shelter(pos, Us, ksq)) / 32;
671 // Analyse enemy's safe queen contact checks. First find undefended
672 // squares around the king attacked by enemy queen...
673 b = undefended & ei.attacked_by(Them, QUEEN) & ~pos.pieces_of_color(Them);
676 // ...then remove squares not supported by another enemy piece
677 b &= ( ei.attacked_by(Them, PAWN) | ei.attacked_by(Them, KNIGHT)
678 | ei.attacked_by(Them, BISHOP) | ei.attacked_by(Them, ROOK));
680 attackUnits += QueenContactCheckBonus * count_1s_max_15<HasPopCnt>(b) * (sente ? 2 : 1);
683 // Analyse enemy's safe distance checks for sliders and knights
684 safe = ~(pos.pieces_of_color(Them) | ei.attacked_by(Us));
686 b1 = pos.attacks_from<ROOK>(ksq) & safe;
687 b2 = pos.attacks_from<BISHOP>(ksq) & safe;
689 // Enemy queen safe checks
690 b = (b1 | b2) & ei.attacked_by(Them, QUEEN);
692 attackUnits += QueenCheckBonus * count_1s_max_15<HasPopCnt>(b);
694 // Enemy rooks safe checks
695 b = b1 & ei.attacked_by(Them, ROOK);
697 attackUnits += RookCheckBonus * count_1s_max_15<HasPopCnt>(b);
699 // Enemy bishops safe checks
700 b = b2 & ei.attacked_by(Them, BISHOP);
702 attackUnits += BishopCheckBonus * count_1s_max_15<HasPopCnt>(b);
704 // Enemy knights safe checks
705 b = pos.attacks_from<KNIGHT>(ksq) & ei.attacked_by(Them, KNIGHT) & safe;
707 attackUnits += KnightCheckBonus * count_1s_max_15<HasPopCnt>(b);
709 // To index KingDangerTable[] attackUnits must be in [0, 99] range
710 attackUnits = Min(99, Max(0, attackUnits));
712 // Finally, extract the king danger score from the KingDangerTable[]
713 // array and subtract the score from evaluation. Set also ei.kingDanger[]
714 // value that will be used for pruning because this value can sometimes
715 // be very big, and so capturing a single attacking piece can therefore
716 // result in a score change far bigger than the value of the captured piece.
717 ei.value -= Sign[Us] * KingDangerTable[Us][attackUnits];
718 ei.kingDanger[Us] = mg_value(KingDangerTable[Us][attackUnits]);
723 // evaluate_passed_pawns<>() evaluates the passed pawns of the given color
726 void evaluate_passed_pawns(const Position& pos, EvalInfo& ei) {
728 const Color Them = (Us == WHITE ? BLACK : WHITE);
730 Bitboard squaresToQueen, defendedSquares, unsafeSquares, supportingPawns;
731 Bitboard b = ei.pi->passed_pawns(Us);
735 Square s = pop_1st_bit(&b);
737 assert(pos.pawn_is_passed(Us, s));
739 int r = int(relative_rank(Us, s) - RANK_2);
740 int tr = r * (r - 1);
742 // Base bonus based on rank
743 Value mbonus = Value(20 * tr);
744 Value ebonus = Value(10 + r * r * 10);
748 Square blockSq = s + pawn_push(Us);
750 // Adjust bonus based on kings proximity
751 ebonus -= Value(square_distance(pos.king_square(Us), blockSq) * 3 * tr);
752 ebonus -= Value(square_distance(pos.king_square(Us), blockSq + pawn_push(Us)) * 1 * tr);
753 ebonus += Value(square_distance(pos.king_square(Them), blockSq) * 6 * tr);
755 // If the pawn is free to advance, increase bonus
756 if (pos.square_is_empty(blockSq))
758 squaresToQueen = squares_in_front_of(Us, s);
759 defendedSquares = squaresToQueen & ei.attacked_by(Us);
761 // If there is an enemy rook or queen attacking the pawn from behind,
762 // add all X-ray attacks by the rook or queen. Otherwise consider only
763 // the squares in the pawn's path attacked or occupied by the enemy.
764 if ( (squares_behind(Us, s) & pos.pieces(ROOK, QUEEN, Them))
765 && (squares_behind(Us, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from<ROOK>(s)))
766 unsafeSquares = squaresToQueen;
768 unsafeSquares = squaresToQueen & (ei.attacked_by(Them) | pos.pieces_of_color(Them));
770 // If there aren't enemy attacks or pieces along the path to queen give
771 // huge bonus. Even bigger if we protect the pawn's path.
773 ebonus += Value(tr * (squaresToQueen == defendedSquares ? 17 : 15));
775 // OK, there are enemy attacks or pieces (but not pawns). Are those
776 // squares which are attacked by the enemy also attacked by us ?
777 // If yes, big bonus (but smaller than when there are no enemy attacks),
778 // if no, somewhat smaller bonus.
779 ebonus += Value(tr * ((unsafeSquares & defendedSquares) == unsafeSquares ? 13 : 8));
781 // At last, add a small bonus when there are no *friendly* pieces
782 // in the pawn's path.
783 if (!(squaresToQueen & pos.pieces_of_color(Us)))
788 // Increase the bonus if the passed pawn is supported by a friendly pawn
789 // on the same rank and a bit smaller if it's on the previous rank.
790 supportingPawns = pos.pieces(PAWN, Us) & neighboring_files_bb(s);
791 if (supportingPawns & rank_bb(s))
792 ebonus += Value(r * 20);
793 else if (supportingPawns & rank_bb(s - pawn_push(Us)))
794 ebonus += Value(r * 12);
796 // Rook pawns are a special case: They are sometimes worse, and
797 // sometimes better than other passed pawns. It is difficult to find
798 // good rules for determining whether they are good or bad. For now,
799 // we try the following: Increase the value for rook pawns if the
800 // other side has no pieces apart from a knight, and decrease the
801 // value if the other side has a rook or queen.
802 if (square_file(s) == FILE_A || square_file(s) == FILE_H)
804 if (pos.non_pawn_material(Them) <= KnightValueMidgame)
805 ebonus += ebonus / 4;
806 else if (pos.pieces(ROOK, QUEEN, Them))
807 ebonus -= ebonus / 4;
810 // Add the scores for this pawn to the middle game and endgame eval
811 ei.value += Sign[Us] * apply_weight(make_score(mbonus, ebonus), Weights[PassedPawns]);
817 // evaluate_space() computes the space evaluation for a given side. The
818 // space evaluation is a simple bonus based on the number of safe squares
819 // available for minor pieces on the central four files on ranks 2--4. Safe
820 // squares one, two or three squares behind a friendly pawn are counted
821 // twice. Finally, the space bonus is scaled by a weight taken from the
822 // material hash table.
823 template<Color Us, bool HasPopCnt>
824 int evaluate_space(const Position& pos, EvalInfo& ei) {
826 const Color Them = (Us == WHITE ? BLACK : WHITE);
828 // Find the safe squares for our pieces inside the area defined by
829 // SpaceMask[us]. A square is unsafe if it is attacked by an enemy
830 // pawn, or if it is undefended and attacked by an enemy piece.
831 Bitboard safe = SpaceMask[Us]
832 & ~pos.pieces(PAWN, Us)
833 & ~ei.attacked_by(Them, PAWN)
834 & (ei.attacked_by(Us) | ~ei.attacked_by(Them));
836 // Find all squares which are at most three squares behind some friendly pawn
837 Bitboard behind = pos.pieces(PAWN, Us);
838 behind |= (Us == WHITE ? behind >> 8 : behind << 8);
839 behind |= (Us == WHITE ? behind >> 16 : behind << 16);
841 return count_1s_max_15<HasPopCnt>(safe) + count_1s_max_15<HasPopCnt>(behind & safe);
845 // apply_weight() applies an evaluation weight to a value trying to prevent overflow
847 inline Score apply_weight(Score v, Score w) {
848 return make_score((int(mg_value(v)) * mg_value(w)) / 0x100, (int(eg_value(v)) * eg_value(w)) / 0x100);
852 // scale_by_game_phase() interpolates between a middle game and an endgame score,
853 // based on game phase. It also scales the return value by a ScaleFactor array.
855 Value scale_by_game_phase(const Score& v, Phase ph, const ScaleFactor sf[]) {
857 assert(mg_value(v) > -VALUE_INFINITE && mg_value(v) < VALUE_INFINITE);
858 assert(eg_value(v) > -VALUE_INFINITE && eg_value(v) < VALUE_INFINITE);
859 assert(ph >= PHASE_ENDGAME && ph <= PHASE_MIDGAME);
861 Value eg = eg_value(v);
862 ScaleFactor f = sf[eg > VALUE_ZERO ? WHITE : BLACK];
863 Value ev = Value((eg * int(f)) / SCALE_FACTOR_NORMAL);
865 int result = (mg_value(v) * int(ph) + ev * int(128 - ph)) / 128;
866 return Value(result & ~(GrainSize - 1));
870 // weight_option() computes the value of an evaluation weight, by combining
871 // two UCI-configurable weights (midgame and endgame) with an internal weight.
873 Score weight_option(const std::string& mgOpt, const std::string& egOpt, Score internalWeight) {
875 // Scale option value from 100 to 256
876 int mg = get_option_value_int(mgOpt) * 256 / 100;
877 int eg = get_option_value_int(egOpt) * 256 / 100;
879 return apply_weight(make_score(mg, eg), internalWeight);
882 // init_safety() initizes the king safety evaluation, based on UCI
883 // parameters. It is called from read_weights().
887 const Value MaxSlope = Value(30);
888 const Value Peak = Value(1280);
891 // First setup the base table
892 for (int i = 0; i < 100; i++)
894 t[i] = Value(int(0.4 * i * i));
897 t[i] = Min(t[i], t[i - 1] + MaxSlope);
899 t[i] = Min(t[i], Peak);
902 // Then apply the weights and get the final KingDangerTable[] array
903 for (Color c = WHITE; c <= BLACK; c++)
904 for (int i = 0; i < 100; i++)
905 KingDangerTable[c][i] = apply_weight(make_score(t[i], 0), Weights[KingDangerUs + c]);