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-2009 Marco Costalba
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/>.
34 #include "ucioption.h"
38 //// Local definitions
43 const int Sign[2] = { 1, -1 };
45 // Evaluation grain size, must be a power of 2
46 const int GrainSize = 8;
48 // Evaluation weights, initialized from UCI options
49 int WeightMobilityMidgame, WeightMobilityEndgame;
50 int WeightPawnStructureMidgame, WeightPawnStructureEndgame;
51 int WeightPassedPawnsMidgame, WeightPassedPawnsEndgame;
52 int WeightKingSafety[2];
55 // Internal evaluation weights. These are applied on top of the evaluation
56 // weights read from UCI parameters. The purpose is to be able to change
57 // the evaluation weights while keeping the default values of the UCI
58 // parameters at 100, which looks prettier.
60 // Values modified by Joona Kiiski
61 const int WeightMobilityMidgameInternal = 248;
62 const int WeightMobilityEndgameInternal = 271;
63 const int WeightPawnStructureMidgameInternal = 233;
64 const int WeightPawnStructureEndgameInternal = 201;
65 const int WeightPassedPawnsMidgameInternal = 252;
66 const int WeightPassedPawnsEndgameInternal = 259;
67 const int WeightKingSafetyInternal = 247;
68 const int WeightKingOppSafetyInternal = 259;
69 const int WeightSpaceInternal = 46;
71 // Mobility and outposts bonus modified by Joona Kiiski
73 // Visually better to define tables constants
77 // Knight mobility bonus in middle game and endgame, indexed by the number
78 // of attacked squares not occupied by friendly piecess.
79 const Score KnightMobilityBonus[] = {
80 S(-38,-33), S(-25,-23), S(-12,-13), S( 0,-3),
81 S( 12, 7), S( 25, 17), S( 31, 22), S(38, 27), S(38, 27)
84 // Bishop mobility bonus in middle game and endgame, indexed by the number
85 // of attacked squares not occupied by friendly pieces. X-ray attacks through
86 // queens are also included.
87 const Score BishopMobilityBonus[] = {
88 S(-25,-30), S(-11,-16), S( 3, -2), S(17, 12),
89 S( 31, 26), S( 45, 40), S(57, 52), S(65, 60),
90 S( 71, 65), S( 74, 69), S(76, 71), S(78, 73),
91 S( 79, 74), S( 80, 75), S(81, 76), S(81, 76)
94 // Rook mobility bonus in middle game and endgame, indexed by the number
95 // of attacked squares not occupied by friendly pieces. X-ray attacks through
96 // queens and rooks are also included.
97 const Score RookMobilityBonus[] = {
98 S(-20,-36), S(-14,-19), S(-8, -3), S(-2, 13),
99 S( 4, 29), S( 10, 46), S(14, 62), S(19, 79),
100 S( 23, 95), S( 26,106), S(27,111), S(28,114),
101 S( 29,116), S( 30,117), S(31,118), S(32,118)
104 // Queen mobility bonus in middle game and endgame, indexed by the number
105 // of attacked squares not occupied by friendly pieces.
106 const Score QueenMobilityBonus[] = {
107 S(-10,-18), S(-8,-13), S(-6, -7), S(-3, -2), S(-1, 3), S( 1, 8),
108 S( 3, 13), S( 5, 19), S( 8, 23), S(10, 27), S(12, 32), S(15, 34),
109 S( 16, 35), S(17, 35), S(18, 35), S(20, 35), S(20, 35), S(20, 35),
110 S( 20, 35), S(20, 35), S(20, 35), S(20, 35), S(20, 35), S(20, 35),
111 S( 20, 35), S(20, 35), S(20, 35), S(20, 35), S(20, 35), S(20, 35),
112 S( 20, 35), S(20, 35)
115 // Pointers table to access mobility tables through piece type
116 const Score* MobilityBonus[] = { 0, 0, KnightMobilityBonus, BishopMobilityBonus, RookMobilityBonus, QueenMobilityBonus };
118 // Outpost bonuses for knights and bishops, indexed by square (from white's
120 const Value KnightOutpostBonus[64] = {
122 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // 1
123 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // 2
124 V(0), V(0), V(4), V(8), V(8), V(4), V(0), V(0), // 3
125 V(0), V(4),V(17),V(26),V(26),V(17), V(4), V(0), // 4
126 V(0), V(8),V(26),V(35),V(35),V(26), V(8), V(0), // 5
127 V(0), V(4),V(17),V(17),V(17),V(17), V(4), V(0), // 6
128 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // 7
129 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) // 8
132 const Value BishopOutpostBonus[64] = {
134 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // 1
135 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // 2
136 V(0), V(0), V(5), V(5), V(5), V(5), V(0), V(0), // 3
137 V(0), V(5),V(10),V(10),V(10),V(10), V(5), V(0), // 4
138 V(0),V(10),V(21),V(21),V(21),V(21),V(10), V(0), // 5
139 V(0), V(5), V(8), V(8), V(8), V(8), V(5), V(0), // 6
140 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // 7
141 V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0) // 8
144 // Bonus for unstoppable passed pawns
145 const Value UnstoppablePawnValue = Value(0x500);
147 // Rooks and queens on the 7th rank (modified by Joona Kiiski)
148 const Score RookOn7thBonus = Score(47, 98);
149 const Score QueenOn7thBonus = Score(27, 54);
151 // Rooks on open files (modified by Joona Kiiski)
152 const Value RookOpenFileBonus = Value(43);
153 const Value RookHalfOpenFileBonus = Value(19);
155 // Penalty for rooks trapped inside a friendly king which has lost the
157 const Value TrappedRookPenalty = Value(180);
159 // Penalty for a bishop on a7/h7 (a2/h2 for black) which is trapped by
161 const Value TrappedBishopA7H7Penalty = Value(300);
163 // Bitboard masks for detecting trapped bishops on a7/h7 (a2/h2 for black)
164 const Bitboard MaskA7H7[2] = {
165 ((1ULL << SQ_A7) | (1ULL << SQ_H7)),
166 ((1ULL << SQ_A2) | (1ULL << SQ_H2))
169 // Penalty for a bishop on a1/h1 (a8/h8 for black) which is trapped by
170 // a friendly pawn on b2/g2 (b7/g7 for black). This can obviously only
171 // happen in Chess960 games.
172 const Value TrappedBishopA1H1Penalty = Value(100);
174 // Bitboard masks for detecting trapped bishops on a1/h1 (a8/h8 for black)
175 const Bitboard MaskA1H1[2] = {
176 ((1ULL << SQ_A1) | (1ULL << SQ_H1)),
177 ((1ULL << SQ_A8) | (1ULL << SQ_H8))
180 // The SpaceMask[color] contains the area of the board which is considered
181 // by the space evaluation. In the middle game, each side is given a bonus
182 // based on how many squares inside this area are safe and available for
183 // friendly minor pieces.
184 const Bitboard SpaceMask[2] = {
185 (1ULL<<SQ_C2) | (1ULL<<SQ_D2) | (1ULL<<SQ_E2) | (1ULL<<SQ_F2) |
186 (1ULL<<SQ_C3) | (1ULL<<SQ_D3) | (1ULL<<SQ_E3) | (1ULL<<SQ_F3) |
187 (1ULL<<SQ_C4) | (1ULL<<SQ_D4) | (1ULL<<SQ_E4) | (1ULL<<SQ_F4),
188 (1ULL<<SQ_C7) | (1ULL<<SQ_D7) | (1ULL<<SQ_E7) | (1ULL<<SQ_F7) |
189 (1ULL<<SQ_C6) | (1ULL<<SQ_D6) | (1ULL<<SQ_E6) | (1ULL<<SQ_F6) |
190 (1ULL<<SQ_C5) | (1ULL<<SQ_D5) | (1ULL<<SQ_E5) | (1ULL<<SQ_F5)
193 /// King safety constants and variables. The king safety scores are taken
194 /// from the array SafetyTable[]. Various little "meta-bonuses" measuring
195 /// the strength of the attack are added up into an integer, which is used
196 /// as an index to SafetyTable[].
198 // Attack weights for each piece type and table indexed on piece type
199 const int QueenAttackWeight = 5;
200 const int RookAttackWeight = 3;
201 const int BishopAttackWeight = 2;
202 const int KnightAttackWeight = 2;
204 const int AttackWeight[] = { 0, 0, KnightAttackWeight, BishopAttackWeight, RookAttackWeight, QueenAttackWeight };
206 // Bonuses for safe checks, initialized from UCI options
207 int QueenContactCheckBonus, DiscoveredCheckBonus;
208 int QueenCheckBonus, RookCheckBonus, BishopCheckBonus, KnightCheckBonus;
210 // Scan for queen contact mates?
211 const bool QueenContactMates = true;
213 // Bonus for having a mate threat, initialized from UCI options
216 // ThreatBonus[][] contains bonus according to which piece type
217 // attacks which one.
218 const Score ThreatBonus[8][8] = {
219 #define Z Score(0, 0)
220 { Z, Z, Z, Z, Z, Z, Z, Z }, // not used
221 { Z, S(18,37), Z, S(37,47), S(55,97), S(55,97), Z, Z }, // KNIGHT attacks
222 { Z, S(18,37), S(37,47), Z, S(55,97), S(55,97), Z, Z }, // BISHOP attacks
223 { Z, S( 9,27), S(27,47), S(27,47), Z, S(37,47), Z, Z }, // ROOK attacks
224 { Z, S(27,37), S(27,37), S(27,37), S(27,37), Z, Z, Z }, // QUEEN attacks
225 { Z, Z, Z, Z, Z, Z, Z, Z }, // not used
226 { Z, Z, Z, Z, Z, Z, Z, Z }, // not used
227 { Z, Z, Z, Z, Z, Z, Z, Z } // not used
231 // ThreatedByPawnPenalty[] contains a penalty according to which piece
232 // type is attacked by an enemy pawn.
233 const Value MidgameThreatedByPawnPenalty[8] = {
234 V(0), V(0), V(56), V(56), V(76), V(86), V(0), V(0)
237 const Value EndgameThreatedByPawnPenalty[8] = {
238 V(0), V(0), V(70), V(70), V(99), V(118), V(0), V(0)
241 // InitKingDanger[] contains bonuses based on the position of the defending
243 const int InitKingDanger[64] = {
244 2, 0, 2, 5, 5, 2, 0, 2,
245 2, 2, 4, 8, 8, 4, 2, 2,
246 7, 10, 12, 12, 12, 12, 10, 7,
247 15, 15, 15, 15, 15, 15, 15, 15,
248 15, 15, 15, 15, 15, 15, 15, 15,
249 15, 15, 15, 15, 15, 15, 15, 15,
250 15, 15, 15, 15, 15, 15, 15, 15,
251 15, 15, 15, 15, 15, 15, 15, 15
254 // SafetyTable[] contains the actual king safety scores. It is initialized
256 Value SafetyTable[100];
258 // Pawn and material hash tables, indexed by the current thread id
259 PawnInfoTable* PawnTable[8] = {0, 0, 0, 0, 0, 0, 0, 0};
260 MaterialInfoTable* MaterialTable[8] = {0, 0, 0, 0, 0, 0, 0, 0};
262 // Sizes of pawn and material hash tables
263 const int PawnTableSize = 16384;
264 const int MaterialTableSize = 1024;
266 // Function prototypes
267 template<bool HasPopCnt>
268 Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID);
270 template<Color Us, bool HasPopCnt>
271 void evaluate_pieces_of_color(const Position& pos, EvalInfo& ei);
273 template<Color Us, bool HasPopCnt>
274 void evaluate_king(const Position& pos, EvalInfo& ei);
277 void evaluate_threats(const Position& pos, EvalInfo& ei);
279 template<Color Us, bool HasPopCnt>
280 void evaluate_space(const Position& pos, EvalInfo& ei);
282 void evaluate_passed_pawns(const Position& pos, EvalInfo& ei);
283 void evaluate_trapped_bishop_a7h7(const Position& pos, Square s, Color us, EvalInfo& ei);
284 void evaluate_trapped_bishop_a1h1(const Position& pos, Square s, Color us, EvalInfo& ei);
285 inline Score apply_weight(Score v, int wmg, int weg);
286 Value scale_by_game_phase(const Score& v, Phase ph, const ScaleFactor sf[]);
287 int weight_option(const std::string& opt, int weight);
296 /// evaluate() is the main evaluation function. It always computes two
297 /// values, an endgame score and a middle game score, and interpolates
298 /// between them based on the remaining material.
299 Value evaluate(const Position& pos, EvalInfo& ei, int threadID) {
301 return CpuHasPOPCNT ? do_evaluate<true>(pos, ei, threadID)
302 : do_evaluate<false>(pos, ei, threadID);
307 template<bool HasPopCnt>
308 Value do_evaluate(const Position& pos, EvalInfo& ei, int threadID) {
311 assert(threadID >= 0 && threadID < THREAD_MAX);
312 assert(!pos.is_check());
314 memset(&ei, 0, sizeof(EvalInfo));
316 // Initialize by reading the incrementally updated scores included in the
317 // position object (material + piece square tables)
318 ei.value = pos.value();
320 // Probe the material hash table
321 ei.mi = MaterialTable[threadID]->get_material_info(pos);
322 ei.value += ei.mi->material_value();
324 // If we have a specialized evaluation function for the current material
325 // configuration, call it and return
326 if (ei.mi->specialized_eval_exists())
327 return ei.mi->evaluate(pos);
329 // After get_material_info() call that modifies them
330 ScaleFactor factor[2];
331 factor[WHITE] = ei.mi->scale_factor(pos, WHITE);
332 factor[BLACK] = ei.mi->scale_factor(pos, BLACK);
334 // Probe the pawn hash table
335 ei.pi = PawnTable[threadID]->get_pawn_info(pos);
336 ei.value += apply_weight(ei.pi->value(), WeightPawnStructureMidgame, WeightPawnStructureEndgame);
338 // Initialize king attack bitboards and king attack zones for both sides
339 ei.attackedBy[WHITE][KING] = pos.attacks_from<KING>(pos.king_square(WHITE));
340 ei.attackedBy[BLACK][KING] = pos.attacks_from<KING>(pos.king_square(BLACK));
341 ei.kingZone[WHITE] = ei.attackedBy[BLACK][KING] | (ei.attackedBy[BLACK][KING] >> 8);
342 ei.kingZone[BLACK] = ei.attackedBy[WHITE][KING] | (ei.attackedBy[WHITE][KING] << 8);
344 // Initialize pawn attack bitboards for both sides
345 ei.attackedBy[WHITE][PAWN] = ei.pi->pawn_attacks(WHITE);
346 ei.attackedBy[BLACK][PAWN] = ei.pi->pawn_attacks(BLACK);
347 Bitboard b1 = ei.attackedBy[WHITE][PAWN] & ei.attackedBy[BLACK][KING];
348 Bitboard b2 = ei.attackedBy[BLACK][PAWN] & ei.attackedBy[WHITE][KING];
350 ei.kingAttackersCount[WHITE] = count_1s_max_15<HasPopCnt>(b1)/2;
353 ei.kingAttackersCount[BLACK] = count_1s_max_15<HasPopCnt>(b2)/2;
356 evaluate_pieces_of_color<WHITE, HasPopCnt>(pos, ei);
357 evaluate_pieces_of_color<BLACK, HasPopCnt>(pos, ei);
359 // Kings. Kings are evaluated after all other pieces for both sides,
360 // because we need complete attack information for all pieces when computing
361 // the king safety evaluation.
362 evaluate_king<WHITE, HasPopCnt>(pos, ei);
363 evaluate_king<BLACK, HasPopCnt>(pos, ei);
365 // Evaluate tactical threats, we need full attack info
366 evaluate_threats<WHITE>(pos, ei);
367 evaluate_threats<BLACK>(pos, ei);
369 // Evaluate passed pawns. We evaluate passed pawns for both sides at once,
370 // because we need to know which side promotes first in positions where
371 // both sides have an unstoppable passed pawn. To be called after all attacks
372 // are computed, included king.
373 if (ei.pi->passed_pawns())
374 evaluate_passed_pawns(pos, ei);
376 Phase phase = pos.game_phase();
378 // Middle-game specific evaluation terms
379 if (phase > PHASE_ENDGAME)
381 // Pawn storms in positions with opposite castling.
382 if ( square_file(pos.king_square(WHITE)) >= FILE_E
383 && square_file(pos.king_square(BLACK)) <= FILE_D)
385 ei.value += Score(ei.pi->queenside_storm_value(WHITE) - ei.pi->kingside_storm_value(BLACK), 0);
387 else if ( square_file(pos.king_square(WHITE)) <= FILE_D
388 && square_file(pos.king_square(BLACK)) >= FILE_E)
390 ei.value += Score(ei.pi->kingside_storm_value(WHITE) - ei.pi->queenside_storm_value(BLACK), 0);
392 // Evaluate space for both sides
393 if (ei.mi->space_weight() > 0)
395 evaluate_space<WHITE, HasPopCnt>(pos, ei);
396 evaluate_space<BLACK, HasPopCnt>(pos, ei);
401 ei.value += apply_weight(ei.mobility, WeightMobilityMidgame, WeightMobilityEndgame);
403 // If we don't already have an unusual scale factor, check for opposite
404 // colored bishop endgames, and use a lower scale for those
405 if ( phase < PHASE_MIDGAME
406 && pos.opposite_colored_bishops()
407 && ( (factor[WHITE] == SCALE_FACTOR_NORMAL && ei.value.eg() > Value(0))
408 || (factor[BLACK] == SCALE_FACTOR_NORMAL && ei.value.eg() < Value(0))))
412 // Only the two bishops ?
413 if ( pos.non_pawn_material(WHITE) == BishopValueMidgame
414 && pos.non_pawn_material(BLACK) == BishopValueMidgame)
416 // Check for KBP vs KB with only a single pawn that is almost
417 // certainly a draw or at least two pawns.
418 bool one_pawn = (pos.piece_count(WHITE, PAWN) + pos.piece_count(BLACK, PAWN) == 1);
419 sf = one_pawn ? ScaleFactor(8) : ScaleFactor(32);
422 // Endgame with opposite-colored bishops, but also other pieces. Still
423 // a bit drawish, but not as drawish as with only the two bishops.
424 sf = ScaleFactor(50);
426 if (factor[WHITE] == SCALE_FACTOR_NORMAL)
428 if (factor[BLACK] == SCALE_FACTOR_NORMAL)
432 // Interpolate between the middle game and the endgame score
433 Color stm = pos.side_to_move();
435 Value v = Sign[stm] * scale_by_game_phase(ei.value, phase, factor);
437 return (ei.mateThreat[stm] == MOVE_NONE ? v : 8 * QueenValueMidgame - v);
442 /// quick_evaluate() does a very approximate evaluation of the current position.
443 /// It currently considers only material and piece square table scores. Perhaps
444 /// we should add scores from the pawn and material hash tables?
446 Value quick_evaluate(const Position &pos) {
451 ScaleFactor sf[2] = {SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL};
453 Phase ph = pos.game_phase();
454 Color stm = pos.side_to_move();
456 return Sign[stm] * scale_by_game_phase(pos.value(), ph, sf);
460 /// init_eval() initializes various tables used by the evaluation function
462 void init_eval(int threads) {
464 assert(threads <= THREAD_MAX);
466 for (int i = 0; i < THREAD_MAX; i++)
471 delete MaterialTable[i];
473 MaterialTable[i] = NULL;
477 PawnTable[i] = new PawnInfoTable(PawnTableSize);
478 if (!MaterialTable[i])
479 MaterialTable[i] = new MaterialInfoTable(MaterialTableSize);
484 /// quit_eval() releases heap-allocated memory at program termination
488 for (int i = 0; i < THREAD_MAX; i++)
491 delete MaterialTable[i];
493 MaterialTable[i] = NULL;
498 /// read_weights() reads evaluation weights from the corresponding UCI parameters
500 void read_weights(Color us) {
502 Color them = opposite_color(us);
504 WeightMobilityMidgame = weight_option("Mobility (Middle Game)", WeightMobilityMidgameInternal);
505 WeightMobilityEndgame = weight_option("Mobility (Endgame)", WeightMobilityEndgameInternal);
506 WeightPawnStructureMidgame = weight_option("Pawn Structure (Middle Game)", WeightPawnStructureMidgameInternal);
507 WeightPawnStructureEndgame = weight_option("Pawn Structure (Endgame)", WeightPawnStructureEndgameInternal);
508 WeightPassedPawnsMidgame = weight_option("Passed Pawns (Middle Game)", WeightPassedPawnsMidgameInternal);
509 WeightPassedPawnsEndgame = weight_option("Passed Pawns (Endgame)", WeightPassedPawnsEndgameInternal);
510 WeightSpace = weight_option("Space", WeightSpaceInternal);
511 WeightKingSafety[us] = weight_option("Cowardice", WeightKingSafetyInternal);
512 WeightKingSafety[them] = weight_option("Aggressiveness", WeightKingOppSafetyInternal);
514 // If running in analysis mode, make sure we use symmetrical king safety. We do this
515 // by replacing both WeightKingSafety[us] and WeightKingSafety[them] by their average.
516 if (get_option_value_bool("UCI_AnalyseMode"))
518 WeightKingSafety[us] = (WeightKingSafety[us] + WeightKingSafety[them]) / 2;
519 WeightKingSafety[them] = WeightKingSafety[us];
527 // evaluate_mobility() computes mobility and attacks for every piece
529 template<PieceType Piece, Color Us, bool HasPopCnt>
530 int evaluate_mobility(Bitboard b, Bitboard mob_area, EvalInfo& ei) {
532 const Color Them = (Us == WHITE ? BLACK : WHITE);
534 // Update attack info
535 ei.attackedBy[Us][Piece] |= b;
538 if (b & ei.kingZone[Us])
540 ei.kingAttackersCount[Us]++;
541 ei.kingAttackersWeight[Us] += AttackWeight[Piece];
542 Bitboard bb = (b & ei.attackedBy[Them][KING]);
544 ei.kingAdjacentZoneAttacksCount[Us] += count_1s_max_15<HasPopCnt>(bb);
548 int mob = (Piece != QUEEN ? count_1s_max_15<HasPopCnt>(b & mob_area)
549 : count_1s<HasPopCnt>(b & mob_area));
551 ei.mobility += Sign[Us] * MobilityBonus[Piece][mob];
556 // evaluate_outposts() evaluates bishop and knight outposts squares
558 template<PieceType Piece, Color Us>
559 void evaluate_outposts(const Position& pos, EvalInfo& ei, Square s) {
561 const Color Them = (Us == WHITE ? BLACK : WHITE);
563 // Initial bonus based on square
564 Value bonus = (Piece == BISHOP ? BishopOutpostBonus[relative_square(Us, s)]
565 : KnightOutpostBonus[relative_square(Us, s)]);
567 // Increase bonus if supported by pawn, especially if the opponent has
568 // no minor piece which can exchange the outpost piece
569 if (bonus && (pos.attacks_from<PAWN>(s, Them) & pos.pieces(PAWN, Us)))
571 if ( pos.pieces(KNIGHT, Them) == EmptyBoardBB
572 && (SquaresByColorBB[square_color(s)] & pos.pieces(BISHOP, Them)) == EmptyBoardBB)
573 bonus += bonus + bonus / 2;
577 ei.value += Sign[Us] * Score(bonus, bonus);
581 // evaluate_pieces<>() assigns bonuses and penalties to the pieces of a given color
583 template<PieceType Piece, Color Us, bool HasPopCnt>
584 void evaluate_pieces(const Position& pos, EvalInfo& ei) {
591 const Color Them = (Us == WHITE ? BLACK : WHITE);
592 const Square* ptr = pos.piece_list_begin(Us, Piece);
594 // Do not include in mobility squares protected by enemy pawns or occupied by our pieces
595 const Bitboard mob_area = ~(ei.attackedBy[Them][PAWN] | pos.pieces_of_color(Us));
597 while ((s = *ptr++) != SQ_NONE)
599 if (Piece == KNIGHT || Piece == QUEEN)
600 b = pos.attacks_from<Piece>(s);
601 else if (Piece == BISHOP)
602 b = bishop_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(QUEEN, Us));
603 else if (Piece == ROOK)
604 b = rook_attacks_bb(s, pos.occupied_squares() & ~pos.pieces(ROOK, QUEEN, Us));
608 // Attacks and mobility
609 mob = evaluate_mobility<Piece, Us, HasPopCnt>(b, mob_area, ei);
611 // Decrease score if we are attacked by an enemy pawn. Remaining part
612 // of threat evaluation must be done later when we have full attack info.
613 if (bit_is_set(ei.attackedBy[Them][PAWN], s))
614 ei.value -= Sign[Us] * Score(MidgameThreatedByPawnPenalty[Piece], EndgameThreatedByPawnPenalty[Piece]);
616 // Bishop and knight outposts squares
617 if ((Piece == BISHOP || Piece == KNIGHT) && pos.square_is_weak(s, Them))
618 evaluate_outposts<Piece, Us>(pos, ei, s);
620 // Special patterns: trapped bishops on a7/h7/a2/h2
621 // and trapped bishops on a1/h1/a8/h8 in Chess960.
624 if (bit_is_set(MaskA7H7[Us], s))
625 evaluate_trapped_bishop_a7h7(pos, s, Us, ei);
627 if (Chess960 && bit_is_set(MaskA1H1[Us], s))
628 evaluate_trapped_bishop_a1h1(pos, s, Us, ei);
631 if (Piece == ROOK || Piece == QUEEN)
633 // Queen or rook on 7th rank
634 if ( relative_rank(Us, s) == RANK_7
635 && relative_rank(Us, pos.king_square(Them)) == RANK_8)
637 ei.value += Sign[Us] * (Piece == ROOK ? RookOn7thBonus : QueenOn7thBonus);
641 // Special extra evaluation for rooks
644 // Open and half-open files
646 if (ei.pi->file_is_half_open(Us, f))
648 if (ei.pi->file_is_half_open(Them, f))
649 ei.value += Sign[Us] * Score(RookOpenFileBonus, RookOpenFileBonus);
651 ei.value += Sign[Us] * Score(RookHalfOpenFileBonus, RookHalfOpenFileBonus);
654 // Penalize rooks which are trapped inside a king. Penalize more if
655 // king has lost right to castle.
656 if (mob > 6 || ei.pi->file_is_half_open(Us, f))
659 ksq = pos.king_square(Us);
661 if ( square_file(ksq) >= FILE_E
662 && square_file(s) > square_file(ksq)
663 && (relative_rank(Us, ksq) == RANK_1 || square_rank(ksq) == square_rank(s)))
665 // Is there a half-open file between the king and the edge of the board?
666 if (!ei.pi->has_open_file_to_right(Us, square_file(ksq)))
667 ei.value -= Sign[Us] * Score(pos.can_castle(Us) ? (TrappedRookPenalty - mob * 16) / 2
668 : (TrappedRookPenalty - mob * 16), 0);
670 else if ( square_file(ksq) <= FILE_D
671 && square_file(s) < square_file(ksq)
672 && (relative_rank(Us, ksq) == RANK_1 || square_rank(ksq) == square_rank(s)))
674 // Is there a half-open file between the king and the edge of the board?
675 if (!ei.pi->has_open_file_to_left(Us, square_file(ksq)))
676 ei.value -= Sign[Us] * Score(pos.can_castle(Us) ? (TrappedRookPenalty - mob * 16) / 2
677 : (TrappedRookPenalty - mob * 16), 0);
684 // evaluate_threats<>() assigns bonuses according to the type of attacking piece
685 // and the type of attacked one.
688 void evaluate_threats(const Position& pos, EvalInfo& ei) {
690 const Color Them = (Us == WHITE ? BLACK : WHITE);
695 // Enemy pieces not defended by a pawn and under our attack
696 Bitboard weakEnemies = pos.pieces_of_color(Them)
697 & ~ei.attackedBy[Them][PAWN]
698 & ei.attackedBy[Us][0];
702 // Add bonus according to type of attacked enemy pieces and to the
703 // type of attacking piece, from knights to queens. Kings are not
704 // considered because are already special handled in king evaluation.
705 for (PieceType pt1 = KNIGHT; pt1 < KING; pt1++)
707 b = ei.attackedBy[Us][pt1] & weakEnemies;
709 for (PieceType pt2 = PAWN; pt2 < KING; pt2++)
710 if (b & pos.pieces(pt2))
711 bonus += ThreatBonus[pt1][pt2];
713 ei.value += Sign[Us] * bonus;
717 // evaluate_pieces_of_color<>() assigns bonuses and penalties to all the
718 // pieces of a given color.
720 template<Color Us, bool HasPopCnt>
721 void evaluate_pieces_of_color(const Position& pos, EvalInfo& ei) {
723 evaluate_pieces<KNIGHT, Us, HasPopCnt>(pos, ei);
724 evaluate_pieces<BISHOP, Us, HasPopCnt>(pos, ei);
725 evaluate_pieces<ROOK, Us, HasPopCnt>(pos, ei);
726 evaluate_pieces<QUEEN, Us, HasPopCnt>(pos, ei);
728 // Sum up all attacked squares
729 ei.attackedBy[Us][0] = ei.attackedBy[Us][PAWN] | ei.attackedBy[Us][KNIGHT]
730 | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK]
731 | ei.attackedBy[Us][QUEEN] | ei.attackedBy[Us][KING];
735 // evaluate_king<>() assigns bonuses and penalties to a king of a given color
737 template<Color Us, bool HasPopCnt>
738 void evaluate_king(const Position& pos, EvalInfo& ei) {
740 const Color Them = (Us == WHITE ? BLACK : WHITE);
741 const Square s = pos.king_square(Us);
745 if (relative_rank(Us, s) <= RANK_4)
747 shelter = ei.pi->get_king_shelter(pos, Us, s);
748 ei.value += Sign[Us] * Score(shelter, 0);
751 // King safety. This is quite complicated, and is almost certainly far
752 // from optimally tuned.
753 if ( pos.piece_count(Them, QUEEN) >= 1
754 && ei.kingAttackersCount[Them] >= 2
755 && pos.non_pawn_material(Them) >= QueenValueMidgame + RookValueMidgame
756 && ei.kingAdjacentZoneAttacksCount[Them])
758 // Is it the attackers turn to move?
759 bool sente = (Them == pos.side_to_move());
761 // Find the attacked squares around the king which has no defenders
762 // apart from the king itself
763 Bitboard undefended =
764 ei.attacked_by(Them) & ~ei.attacked_by(Us, PAWN)
765 & ~ei.attacked_by(Us, KNIGHT) & ~ei.attacked_by(Us, BISHOP)
766 & ~ei.attacked_by(Us, ROOK) & ~ei.attacked_by(Us, QUEEN)
767 & ei.attacked_by(Us, KING);
769 Bitboard occ = pos.occupied_squares(), b, b2;
771 // Initialize the 'attackUnits' variable, which is used later on as an
772 // index to the SafetyTable[] array. The initial value is based on the
773 // number and types of the attacking pieces, the number of attacked and
774 // undefended squares around the king, the square of the king, and the
775 // quality of the pawn shelter.
777 Min((ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them]) / 2, 25)
778 + (ei.kingAdjacentZoneAttacksCount[Them] + count_1s_max_15<HasPopCnt>(undefended)) * 3
779 + InitKingDanger[relative_square(Us, s)] - (shelter >> 5);
781 // Analyse safe queen contact checks
782 b = undefended & ei.attacked_by(Them, QUEEN) & ~pos.pieces_of_color(Them);
785 Bitboard attackedByOthers =
786 ei.attacked_by(Them, PAWN) | ei.attacked_by(Them, KNIGHT)
787 | ei.attacked_by(Them, BISHOP) | ei.attacked_by(Them, ROOK);
789 b &= attackedByOthers;
792 // The bitboard b now contains the squares available for safe queen
794 int count = count_1s_max_15<HasPopCnt>(b);
795 attackUnits += QueenContactCheckBonus * count * (sente ? 2 : 1);
797 // Is there a mate threat?
798 if (QueenContactMates && !pos.is_check())
800 Bitboard escapeSquares =
801 pos.attacks_from<KING>(s) & ~pos.pieces_of_color(Us) & ~attackedByOthers;
805 Square from, to = pop_1st_bit(&b);
806 if (!(escapeSquares & ~queen_attacks_bb(to, occ & ClearMaskBB[s])))
808 // We have a mate, unless the queen is pinned or there
809 // is an X-ray attack through the queen.
810 for (int i = 0; i < pos.piece_count(Them, QUEEN); i++)
812 from = pos.piece_list(Them, QUEEN, i);
813 if ( bit_is_set(pos.attacks_from<QUEEN>(from), to)
814 && !bit_is_set(pos.pinned_pieces(Them), from)
815 && !(rook_attacks_bb(to, occ & ClearMaskBB[from]) & pos.pieces(ROOK, QUEEN, Us))
816 && !(bishop_attacks_bb(to, occ & ClearMaskBB[from]) & pos.pieces(BISHOP, QUEEN, Us)))
818 ei.mateThreat[Them] = make_move(from, to);
826 // Analyse safe distance checks
827 if (QueenCheckBonus > 0 || RookCheckBonus > 0)
829 b = pos.attacks_from<ROOK>(s) & ~pos.pieces_of_color(Them) & ~ei.attacked_by(Us);
832 b2 = b & ei.attacked_by(Them, QUEEN);
834 attackUnits += QueenCheckBonus * count_1s_max_15<HasPopCnt>(b2);
837 b2 = b & ei.attacked_by(Them, ROOK);
839 attackUnits += RookCheckBonus * count_1s_max_15<HasPopCnt>(b2);
841 if (QueenCheckBonus > 0 || BishopCheckBonus > 0)
843 b = pos.attacks_from<BISHOP>(s) & ~pos.pieces_of_color(Them) & ~ei.attacked_by(Us);
846 b2 = b & ei.attacked_by(Them, QUEEN);
848 attackUnits += QueenCheckBonus * count_1s_max_15<HasPopCnt>(b2);
851 b2 = b & ei.attacked_by(Them, BISHOP);
853 attackUnits += BishopCheckBonus * count_1s_max_15<HasPopCnt>(b2);
855 if (KnightCheckBonus > 0)
857 b = pos.attacks_from<KNIGHT>(s) & ~pos.pieces_of_color(Them) & ~ei.attacked_by(Us);
860 b2 = b & ei.attacked_by(Them, KNIGHT);
862 attackUnits += KnightCheckBonus * count_1s_max_15<HasPopCnt>(b2);
865 // Analyse discovered checks (only for non-pawns right now, consider
866 // adding pawns later).
867 if (DiscoveredCheckBonus)
869 b = pos.discovered_check_candidates(Them) & ~pos.pieces(PAWN);
871 attackUnits += DiscoveredCheckBonus * count_1s_max_15<HasPopCnt>(b) * (sente ? 2 : 1);
874 // Has a mate threat been found? We don't do anything here if the
875 // side with the mating move is the side to move, because in that
876 // case the mating side will get a huge bonus at the end of the main
877 // evaluation function instead.
878 if (ei.mateThreat[Them] != MOVE_NONE)
879 attackUnits += MateThreatBonus;
881 // Ensure that attackUnits is between 0 and 99, in order to avoid array
882 // out of bounds errors:
886 if (attackUnits >= 100)
889 // Finally, extract the king safety score from the SafetyTable[] array.
890 // Add the score to the evaluation, and also to ei.futilityMargin. The
891 // reason for adding the king safety score to the futility margin is
892 // that the king safety scores can sometimes be very big, and that
893 // capturing a single attacking piece can therefore result in a score
894 // change far bigger than the value of the captured piece.
895 Score v = apply_weight(Score(SafetyTable[attackUnits], 0), WeightKingSafety[Us], 0);
897 ei.value -= Sign[Us] * v;
899 if (Us == pos.side_to_move())
900 ei.futilityMargin += v.mg();
905 // evaluate_passed_pawns() evaluates the passed pawns of the given color
908 void evaluate_passed_pawns_of_color(const Position& pos, int movesToGo[], Square pawnToGo[], EvalInfo& ei) {
910 const Color Them = (Us == WHITE ? BLACK : WHITE);
913 Square ourKingSq = pos.king_square(Us);
914 Square theirKingSq = pos.king_square(Them);
915 Bitboard b = ei.pi->passed_pawns() & pos.pieces(PAWN, Us);
919 Square s = pop_1st_bit(&b);
921 assert(pos.piece_on(s) == piece_of_color_and_type(Us, PAWN));
922 assert(pos.pawn_is_passed(Us, s));
924 int r = int(relative_rank(Us, s) - RANK_2);
925 int tr = Max(0, r * (r - 1));
927 // Base bonus based on rank
928 Value mbonus = Value(20 * tr);
929 Value ebonus = Value(10 + r * r * 10);
931 // Adjust bonus based on king proximity
934 Square blockSq = s + pawn_push(Us);
936 ebonus -= Value(square_distance(ourKingSq, blockSq) * 3 * tr);
937 ebonus -= Value(square_distance(ourKingSq, blockSq + pawn_push(Us)) * 1 * tr);
938 ebonus += Value(square_distance(theirKingSq, blockSq) * 6 * tr);
940 // If the pawn is free to advance, increase bonus
941 if (pos.square_is_empty(blockSq))
943 // There are no enemy pawns in the pawn's path
944 b2 = squares_in_front_of(Us, s);
946 assert((b2 & pos.pieces(PAWN, Them)) == EmptyBoardBB);
948 // Squares attacked by us
949 b4 = b2 & ei.attacked_by(Us);
951 // Squares attacked or occupied by enemy pieces
952 b3 = b2 & (ei.attacked_by(Them) | pos.pieces_of_color(Them));
954 // If there is an enemy rook or queen attacking the pawn from behind,
955 // add all X-ray attacks by the rook or queen.
956 if ( (squares_behind(Us, s) & pos.pieces(ROOK, QUEEN, Them))
957 && (squares_behind(Us, s) & pos.pieces(ROOK, QUEEN, Them) & pos.attacks_from<QUEEN>(s)))
960 // Are any of the squares in the pawn's path attacked or occupied by the enemy?
961 if (b3 == EmptyBoardBB)
962 // No enemy attacks or pieces, huge bonus!
963 // Even bigger if we protect the pawn's path
964 ebonus += Value(tr * (b2 == b4 ? 17 : 15));
966 // OK, there are enemy attacks or pieces (but not pawns). Are those
967 // squares which are attacked by the enemy also attacked by us ?
968 // If yes, big bonus (but smaller than when there are no enemy attacks),
969 // if no, somewhat smaller bonus.
970 ebonus += Value(tr * ((b3 & b4) == b3 ? 13 : 8));
972 // At last, add a small bonus when there are no *friendly* pieces
973 // in the pawn's path.
974 if ((b2 & pos.pieces_of_color(Us)) == EmptyBoardBB)
979 // If the pawn is supported by a friendly pawn, increase bonus
980 b2 = pos.pieces(PAWN, Us) & neighboring_files_bb(s);
982 ebonus += Value(r * 20);
983 else if (pos.attacks_from<PAWN>(s, Them) & b2)
984 ebonus += Value(r * 12);
986 // If the other side has only a king, check whether the pawn is
988 if (pos.non_pawn_material(Them) == Value(0))
993 qsq = relative_square(Us, make_square(square_file(s), RANK_8));
994 d = square_distance(s, qsq)
995 - square_distance(theirKingSq, qsq)
996 + (Us != pos.side_to_move());
1000 int mtg = RANK_8 - relative_rank(Us, s);
1001 int blockerCount = count_1s_max_15(squares_in_front_of(Us,s) & pos.occupied_squares());
1002 mtg += blockerCount;
1004 if (d < 0 && (!movesToGo[Us] || movesToGo[Us] > mtg))
1006 movesToGo[Us] = mtg;
1012 // Rook pawns are a special case: They are sometimes worse, and
1013 // sometimes better than other passed pawns. It is difficult to find
1014 // good rules for determining whether they are good or bad. For now,
1015 // we try the following: Increase the value for rook pawns if the
1016 // other side has no pieces apart from a knight, and decrease the
1017 // value if the other side has a rook or queen.
1018 if (square_file(s) == FILE_A || square_file(s) == FILE_H)
1020 if ( pos.non_pawn_material(Them) <= KnightValueMidgame
1021 && pos.piece_count(Them, KNIGHT) <= 1)
1022 ebonus += ebonus / 4;
1023 else if (pos.pieces(ROOK, QUEEN, Them))
1024 ebonus -= ebonus / 4;
1027 // Add the scores for this pawn to the middle game and endgame eval.
1028 ei.value += Sign[Us] * apply_weight(Score(mbonus, ebonus), WeightPassedPawnsMidgame, WeightPassedPawnsEndgame);
1034 // evaluate_passed_pawns() evaluates the passed pawns for both sides
1036 void evaluate_passed_pawns(const Position& pos, EvalInfo& ei) {
1038 int movesToGo[2] = {0, 0};
1039 Square pawnToGo[2] = {SQ_NONE, SQ_NONE};
1041 // Evaluate pawns for each color
1042 evaluate_passed_pawns_of_color<WHITE>(pos, movesToGo, pawnToGo, ei);
1043 evaluate_passed_pawns_of_color<BLACK>(pos, movesToGo, pawnToGo, ei);
1045 // Neither side has an unstoppable passed pawn?
1046 if (!(movesToGo[WHITE] | movesToGo[BLACK]))
1049 // Does only one side have an unstoppable passed pawn?
1050 if (!movesToGo[WHITE] || !movesToGo[BLACK])
1052 Color winnerSide = movesToGo[WHITE] ? WHITE : BLACK;
1053 ei.value += Score(0, Sign[winnerSide] * (UnstoppablePawnValue - Value(0x40 * movesToGo[winnerSide])));
1056 { // Both sides have unstoppable pawns! Try to find out who queens
1057 // first. We begin by transforming 'movesToGo' to the number of
1058 // plies until the pawn queens for both sides.
1059 movesToGo[WHITE] *= 2;
1060 movesToGo[BLACK] *= 2;
1061 movesToGo[pos.side_to_move()]--;
1063 Color winnerSide = movesToGo[WHITE] < movesToGo[BLACK] ? WHITE : BLACK;
1064 Color loserSide = opposite_color(winnerSide);
1066 // If one side queens at least three plies before the other, that side wins
1067 if (movesToGo[winnerSide] <= movesToGo[loserSide] - 3)
1068 ei.value += Score(0, Sign[winnerSide] * (UnstoppablePawnValue - Value(0x40 * (movesToGo[winnerSide]/2))));
1070 // If one side queens one ply before the other and checks the king or attacks
1071 // the undefended opponent's queening square, that side wins. To avoid cases
1072 // where the opponent's king could move somewhere before first pawn queens we
1073 // consider only free paths to queen for both pawns.
1074 else if ( !(squares_in_front_of(WHITE, pawnToGo[WHITE]) & pos.occupied_squares())
1075 && !(squares_in_front_of(BLACK, pawnToGo[BLACK]) & pos.occupied_squares()))
1077 assert(movesToGo[loserSide] - movesToGo[winnerSide] == 1);
1079 Square winnerQSq = relative_square(winnerSide, make_square(square_file(pawnToGo[winnerSide]), RANK_8));
1080 Square loserQSq = relative_square(loserSide, make_square(square_file(pawnToGo[loserSide]), RANK_8));
1082 Bitboard b = pos.occupied_squares();
1083 clear_bit(&b, pawnToGo[winnerSide]);
1084 clear_bit(&b, pawnToGo[loserSide]);
1085 b = queen_attacks_bb(winnerQSq, b);
1087 if ( (b & pos.pieces(KING, loserSide))
1088 ||(bit_is_set(b, loserQSq) && !bit_is_set(ei.attacked_by(loserSide), loserQSq)))
1089 ei.value += Score(0, Sign[winnerSide] * (UnstoppablePawnValue - Value(0x40 * (movesToGo[winnerSide]/2))));
1095 // evaluate_trapped_bishop_a7h7() determines whether a bishop on a7/h7
1096 // (a2/h2 for black) is trapped by enemy pawns, and assigns a penalty
1099 void evaluate_trapped_bishop_a7h7(const Position& pos, Square s, Color us, EvalInfo &ei) {
1101 assert(square_is_ok(s));
1102 assert(pos.piece_on(s) == piece_of_color_and_type(us, BISHOP));
1104 Square b6 = relative_square(us, (square_file(s) == FILE_A) ? SQ_B6 : SQ_G6);
1105 Square b8 = relative_square(us, (square_file(s) == FILE_A) ? SQ_B8 : SQ_G8);
1107 if ( pos.piece_on(b6) == piece_of_color_and_type(opposite_color(us), PAWN)
1108 && pos.see(s, b6) < 0
1109 && pos.see(s, b8) < 0)
1111 ei.value -= Sign[us] * Score(TrappedBishopA7H7Penalty, TrappedBishopA7H7Penalty);
1116 // evaluate_trapped_bishop_a1h1() determines whether a bishop on a1/h1
1117 // (a8/h8 for black) is trapped by a friendly pawn on b2/g2 (b7/g7 for
1118 // black), and assigns a penalty if it is. This pattern can obviously
1119 // only occur in Chess960 games.
1121 void evaluate_trapped_bishop_a1h1(const Position& pos, Square s, Color us, EvalInfo& ei) {
1123 Piece pawn = piece_of_color_and_type(us, PAWN);
1127 assert(square_is_ok(s));
1128 assert(pos.piece_on(s) == piece_of_color_and_type(us, BISHOP));
1130 if (square_file(s) == FILE_A)
1132 b2 = relative_square(us, SQ_B2);
1133 b3 = relative_square(us, SQ_B3);
1134 c3 = relative_square(us, SQ_C3);
1138 b2 = relative_square(us, SQ_G2);
1139 b3 = relative_square(us, SQ_G3);
1140 c3 = relative_square(us, SQ_F3);
1143 if (pos.piece_on(b2) == pawn)
1147 if (!pos.square_is_empty(b3))
1148 penalty = 2*TrappedBishopA1H1Penalty;
1149 else if (pos.piece_on(c3) == pawn)
1150 penalty = TrappedBishopA1H1Penalty;
1152 penalty = TrappedBishopA1H1Penalty / 2;
1154 ei.value -= Sign[us] * Score(penalty, penalty);
1159 // evaluate_space() computes the space evaluation for a given side. The
1160 // space evaluation is a simple bonus based on the number of safe squares
1161 // available for minor pieces on the central four files on ranks 2--4. Safe
1162 // squares one, two or three squares behind a friendly pawn are counted
1163 // twice. Finally, the space bonus is scaled by a weight taken from the
1164 // material hash table.
1165 template<Color Us, bool HasPopCnt>
1166 void evaluate_space(const Position& pos, EvalInfo& ei) {
1168 const Color Them = (Us == WHITE ? BLACK : WHITE);
1170 // Find the safe squares for our pieces inside the area defined by
1171 // SpaceMask[us]. A square is unsafe if it is attacked by an enemy
1172 // pawn, or if it is undefended and attacked by an enemy piece.
1174 Bitboard safeSquares = SpaceMask[Us]
1175 & ~pos.pieces(PAWN, Us)
1176 & ~ei.attacked_by(Them, PAWN)
1177 & ~(~ei.attacked_by(Us) & ei.attacked_by(Them));
1179 // Find all squares which are at most three squares behind some friendly
1181 Bitboard behindFriendlyPawns = pos.pieces(PAWN, Us);
1182 behindFriendlyPawns |= (Us == WHITE ? behindFriendlyPawns >> 8 : behindFriendlyPawns << 8);
1183 behindFriendlyPawns |= (Us == WHITE ? behindFriendlyPawns >> 16 : behindFriendlyPawns << 16);
1185 int space = count_1s_max_15<HasPopCnt>(safeSquares)
1186 + count_1s_max_15<HasPopCnt>(behindFriendlyPawns & safeSquares);
1188 ei.value += Sign[Us] * apply_weight(Score(space * ei.mi->space_weight(), 0), WeightSpace, 0);
1192 // apply_weight() applies an evaluation weight to a value
1194 inline Score apply_weight(Score v, int wmg, int weg) {
1195 return Score(v.mg() * wmg, v.eg() * weg) / 0x100;
1199 // scale_by_game_phase() interpolates between a middle game and an endgame
1200 // score, based on game phase. It also scales the return value by a
1201 // ScaleFactor array.
1203 Value scale_by_game_phase(const Score& v, Phase ph, const ScaleFactor sf[]) {
1205 assert(v.mg() > -VALUE_INFINITE && v.mg() < VALUE_INFINITE);
1206 assert(v.eg() > -VALUE_INFINITE && v.eg() < VALUE_INFINITE);
1207 assert(ph >= PHASE_ENDGAME && ph <= PHASE_MIDGAME);
1209 Value ev = apply_scale_factor(v.eg(), sf[(v.eg() > Value(0) ? WHITE : BLACK)]);
1211 Value result = Value(int((v.mg() * ph + ev * (128 - ph)) / 128));
1212 return Value(int(result) & ~(GrainSize - 1));
1216 // weight_option() computes the value of an evaluation weight, by combining
1217 // an UCI-configurable weight with an internal weight.
1219 int weight_option(const std::string& opt, int internalWeight) {
1221 int uciWeight = get_option_value_int(opt);
1222 uciWeight = (uciWeight * 0x100) / 100;
1223 return (uciWeight * internalWeight) / 0x100;
1227 // init_safety() initizes the king safety evaluation, based on UCI
1228 // parameters. It is called from read_weights().
1230 void init_safety() {
1232 QueenContactCheckBonus = get_option_value_int("Queen Contact Check Bonus");
1233 QueenCheckBonus = get_option_value_int("Queen Check Bonus");
1234 RookCheckBonus = get_option_value_int("Rook Check Bonus");
1235 BishopCheckBonus = get_option_value_int("Bishop Check Bonus");
1236 KnightCheckBonus = get_option_value_int("Knight Check Bonus");
1237 DiscoveredCheckBonus = get_option_value_int("Discovered Check Bonus");
1238 MateThreatBonus = get_option_value_int("Mate Threat Bonus");
1240 int maxSlope = get_option_value_int("King Safety Max Slope");
1241 int peak = get_option_value_int("King Safety Max Value") * 256 / 100;
1242 double a = get_option_value_int("King Safety Coefficient") / 100.0;
1243 double b = get_option_value_int("King Safety X Intercept");
1244 bool quad = (get_option_value_string("King Safety Curve") == "Quadratic");
1245 bool linear = (get_option_value_string("King Safety Curve") == "Linear");
1247 for (int i = 0; i < 100; i++)
1250 SafetyTable[i] = Value(0);
1252 SafetyTable[i] = Value((int)(a * (i - b) * (i - b)));
1254 SafetyTable[i] = Value((int)(100 * a * (i - b)));
1257 for (int i = 0; i < 100; i++)
1259 if (SafetyTable[i+1] - SafetyTable[i] > maxSlope)
1260 for (int j = i + 1; j < 100; j++)
1261 SafetyTable[j] = SafetyTable[j-1] + Value(maxSlope);
1263 if (SafetyTable[i] > Value(peak))
1264 SafetyTable[i] = Value(peak);
1269 std::ostream& operator<<(std::ostream &os, Score s) {
1271 return os << "(" << s.mg() << ", " << s.eg() << ")";