]> git.sesse.net Git - stockfish/blob - src/evaluate.cpp
89b074eb2f16a63b1594e97da5b107f27f616e9a
[stockfish] / src / evaluate.cpp
1 /*
2   Glaurung, a UCI chess playing engine.
3   Copyright (C) 2004-2008 Tord Romstad
4
5   Glaurung is free software: you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation, either version 3 of the License, or
8   (at your option) any later version.
9
10   Glaurung is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19
20 ////
21 //// Includes
22 ////
23
24 #include <cassert>
25 #include <cstring>
26
27 #include "evaluate.h"
28 #include "material.h"
29 #include "pawns.h"
30 #include "scale.h"
31 #include "thread.h"
32 #include "ucioption.h"
33
34
35 ////
36 //// Local definitions
37 ////
38
39 namespace {
40
41   const int Sign[2] = {1, -1};
42
43   // Evaluation grain size, must be a power of 2.
44   const int GrainSize = 4;
45
46   // Evaluation weights
47   int WeightMobilityMidgame      = 0x100;
48   int WeightMobilityEndgame      = 0x100;
49   int WeightPawnStructureMidgame = 0x100;
50   int WeightPawnStructureEndgame = 0x100;
51   int WeightPassedPawnsMidgame   = 0x100;
52   int WeightPassedPawnsEndgame   = 0x100;
53   int WeightKingSafety[2] = { 0x100, 0x100 };
54
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.
59   const int WeightMobilityMidgameInternal      = 0x100;
60   const int WeightMobilityEndgameInternal      = 0x100;
61   const int WeightPawnStructureMidgameInternal = 0x100;
62   const int WeightPawnStructureEndgameInternal = 0x100;
63   const int WeightPassedPawnsMidgameInternal   = 0x100;
64   const int WeightPassedPawnsEndgameInternal   = 0x100;
65   const int WeightKingSafetyInternal           = 0x100;
66   const int WeightKingOppSafetyInternal        = 0x100;
67
68   // Visually better to define tables constants
69   typedef Value V;
70
71   // Knight mobility bonus in middle game and endgame, indexed by the number
72   // of attacked squares not occupied by friendly piecess.
73   const Value MidgameKnightMobilityBonus[] = {
74   //    0       1      2     3      4      5      6      7      8
75     V(-30), V(-20),V(-10), V(0), V(10), V(20), V(25), V(30), V(30)
76   };
77
78   const Value EndgameKnightMobilityBonus[] = {
79   //    0       1      2     3      4      5      6      7      8
80     V(-30), V(-20),V(-10), V(0), V(10), V(20), V(25), V(30), V(30)
81   };
82
83   // Bishop mobility bonus in middle game and endgame, indexed by the number
84   // of attacked squares not occupied by friendly pieces.  X-ray attacks through
85   // queens are also included.
86   const Value MidgameBishopMobilityBonus[] = {
87   //    0       1      2      3      4      5      6      7
88     V(-30), V(-15),  V(0), V(15), V(30), V(45), V(58), V(66),
89   //    8       9     10     11     12     13     14     15
90     V( 72), V( 76), V(78), V(80), V(81), V(82), V(83), V(83)
91   };
92
93   const Value EndgameBishopMobilityBonus[] = {
94   //    0       1      2      3      4      5      6      7
95     V(-30), V(-15),  V(0), V(15), V(30), V(45), V(58), V(66),
96   //    8       9     10     11     12     13     14     15
97     V( 72), V( 76), V(78), V(80), V(81), V(82), V(83), V(83)
98   };
99
100   // Rook mobility bonus in middle game and endgame, indexed by the number
101   // of attacked squares not occupied by friendly pieces.  X-ray attacks through
102   // queens and rooks are also included.
103   const Value MidgameRookMobilityBonus[] = {
104   //    0       1      2      3      4      5      6      7
105     V(-18), V(-12), V(-6),  V(0),  V(6), V(12), V(16), V(21),
106   //    8       9     10     11     12     13     14     15
107     V( 24), V( 27), V(28), V(29), V(30), V(31), V(32), V(33)
108   };
109
110   const Value EndgameRookMobilityBonus[] = {
111   //    0       1      2      3      4      5      6      7
112     V(-30), V(-18), V(-6),  V(6), V(18), V(30), V(42), V(54),
113   //    8       9     10     11     12     13     14     15
114     V( 66), V( 74), V(78), V(80), V(81), V(82), V(83), V(83)
115   };
116
117   // Queen mobility bonus in middle game and endgame, indexed by the number
118   // of attacked squares not occupied by friendly pieces.
119   const Value MidgameQueenMobilityBonus[] = {
120   //    0      1      2      3      4      5      6      7
121     V(-10), V(-8), V(-6), V(-4), V(-2), V( 0), V( 2), V( 4),
122   //    8      9     10     11     12     13     14     15
123     V(  6), V( 8), V(10), V(12), V(13), V(14), V(15), V(16),
124   //   16     17     18     19     20     21     22     23
125     V( 16), V(16), V(16), V(16), V(16), V(16), V(16), V(16),
126   //   24     25     26     27     28     29     30     31
127     V( 16), V(16), V(16), V(16), V(16), V(16), V(16), V(16)
128   };
129
130   const Value EndgameQueenMobilityBonus[] = {
131   //    0      1      2      3      4      5      6      7
132     V(-20),V(-15),V(-10), V(-5), V( 0), V( 5), V(10), V(15),
133   //    8      9     10     11     12     13     14     15
134     V( 19), V(23), V(27), V(29), V(30), V(30), V(30), V(30),
135   //   16     17     18     19     20     21     22     23
136     V( 30), V(30), V(30), V(30), V(30), V(30), V(30), V(30),
137   //   24     25     26     27     28     29     30     31
138     V( 30), V(30), V(30), V(30), V(30), V(30), V(30), V(30)
139   };
140
141   // Outpost bonuses for knights and bishops, indexed by square (from white's
142   // point of view).
143   const Value KnightOutpostBonus[64] = {
144   //  A     B     C     D     E     F     G     H
145     V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // 1
146     V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // 2
147     V(0), V(0), V(5),V(10),V(10), V(5), V(0), V(0), // 3
148     V(0), V(5),V(20),V(30),V(30),V(20), V(5), V(0), // 4
149     V(0),V(10),V(30),V(40),V(40),V(30),V(10), V(0), // 5
150     V(0), V(5),V(20),V(20),V(20),V(20), V(5), V(0), // 6
151     V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // 7
152     V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0)  // 8
153   };
154
155   const Value BishopOutpostBonus[64] = {
156   //  A     B     C     D     E     F     G     H
157     V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // 1
158     V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // 2
159     V(0), V(0), V(5), V(5), V(5), V(5), V(0), V(0), // 3
160     V(0), V(5),V(10),V(10),V(10),V(10), V(5), V(0), // 4
161     V(0),V(10),V(20),V(20),V(20),V(20),V(10), V(0), // 5
162     V(0), V(5), V(8), V(8), V(8), V(8), V(5), V(0), // 6
163     V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0), // 7
164     V(0), V(0), V(0), V(0), V(0), V(0), V(0), V(0)  // 8
165   };
166
167   // Bonus for unstoppable passed pawns:
168   const Value UnstoppablePawnValue = Value(0x500);
169
170   // Rooks and queens on the 7th rank:
171   const Value MidgameRookOn7thBonus  = Value(50);
172   const Value EndgameRookOn7thBonus  = Value(100);
173   const Value MidgameQueenOn7thBonus = Value(25);
174   const Value EndgameQueenOn7thBonus = Value(50);
175
176   // Rooks on open files:
177   const Value RookOpenFileBonus     = Value(40);
178   const Value RookHalfOpenFileBonus = Value(20);
179
180   // Penalty for rooks trapped inside a friendly king which has lost the
181   // right to castle:
182   const Value TrappedRookPenalty = Value(180);
183
184   // Penalty for a bishop on a7/h7 (a2/h2 for black) which is trapped by
185   // enemy pawns:
186   const Value TrappedBishopA7H7Penalty = Value(300);
187
188   // Bitboard masks for detecting trapped bishops on a7/h7 (a2/h2 for black):
189   const Bitboard MaskA7H7[2] = {
190     ((1ULL << SQ_A7) | (1ULL << SQ_H7)),
191     ((1ULL << SQ_A2) | (1ULL << SQ_H2))
192   };
193
194   // Penalty for a bishop on a1/h1 (a8/h8 for black) which is trapped by
195   // a friendly pawn on b2/g2 (b7/g7 for black).  This can obviously only
196   // happen in Chess960 games.
197   const Value TrappedBishopA1H1Penalty = Value(100);
198
199   // Bitboard masks for detecting trapped bishops on a1/h1 (a8/h8 for black):
200   const Bitboard MaskA1H1[2] = {
201     ((1ULL << SQ_A1) | (1ULL << SQ_H1)),
202     ((1ULL << SQ_A8) | (1ULL << SQ_H8))
203   };
204
205   /// King safety constants and variables.  The king safety scores are taken
206   /// from the array SafetyTable[].  Various little "meta-bonuses" measuring
207   /// the strength of the attack are added up into an integer, which is used
208   /// as an index to SafetyTable[].
209
210   // Attack weights for each piece type.
211   const int QueenAttackWeight  = 5;
212   const int RookAttackWeight   = 3;
213   const int BishopAttackWeight = 2;
214   const int KnightAttackWeight = 2;
215
216   // Bonuses for safe checks for each piece type.
217   int QueenContactCheckBonus = 4;
218   int RookContactCheckBonus  = 2;
219   int QueenCheckBonus        = 2;
220   int RookCheckBonus         = 1;
221   int BishopCheckBonus       = 1;
222   int KnightCheckBonus       = 1;
223   int DiscoveredCheckBonus   = 3;
224
225   // Scan for queen contact mates?
226   const bool QueenContactMates = true;
227
228   // Bonus for having a mate threat.
229   int MateThreatBonus = 3;
230
231   // InitKingDanger[] contains bonuses based on the position of the defending
232   // king.
233   const int InitKingDanger[64] = {
234      2,  0,  2,  5,  5,  2,  0,  2,
235      2,  2,  4,  8,  8,  4,  2,  2,
236      7, 10, 12, 12, 12, 12, 10,  7,
237     15, 15, 15, 15, 15, 15, 15, 15,
238     15, 15, 15, 15, 15, 15, 15, 15,
239     15, 15, 15, 15, 15, 15, 15, 15,
240     15, 15, 15, 15, 15, 15, 15, 15,
241     15, 15, 15, 15, 15, 15, 15, 15
242   };
243
244   // SafetyTable[] contains the actual king safety scores.  It is initialized
245   // in init_safety().
246   Value SafetyTable[100];
247
248   // Pawn and material hash tables, indexed by the current thread id:
249   PawnInfoTable *PawnTable[8] = {0, 0, 0, 0, 0, 0, 0, 0};
250   MaterialInfoTable *MaterialTable[8] = {0, 0, 0, 0, 0, 0, 0, 0};
251
252   // Sizes of pawn and material hash tables:
253   const int PawnTableSize = 16384;
254   const int MaterialTableSize = 1024;
255
256   // Array which gives the number of nonzero bits in an 8-bit integer:
257   uint8_t BitCount8Bit[256];
258
259   // Function prototypes:
260   void evaluate_knight(const Position &p, Square s, Color us, EvalInfo &ei);
261   void evaluate_bishop(const Position &p, Square s, Color us, EvalInfo &ei);
262   void evaluate_rook(const Position &p, Square s, Color us, EvalInfo &ei);
263   void evaluate_queen(const Position &p, Square s, Color us, EvalInfo &ei);
264   void evaluate_king(const Position &p, Square s, Color us, EvalInfo &ei);
265
266   void evaluate_passed_pawns(const Position &pos, EvalInfo &ei);
267   void evaluate_trapped_bishop_a7h7(const Position &pos, Square s, Color us,
268                                     EvalInfo &ei);
269   void evaluate_trapped_bishop_a1h1(const Position &pos, Square s, Color us,
270                                     EvalInfo &ei);
271
272   inline Value apply_weight(Value v, int w);
273   Value scale_by_game_phase(Value mv, Value ev, Phase ph, const ScaleFactor sf[]);
274
275   int count_1s_8bit(Bitboard b);
276
277   int compute_weight(int uciWeight, int internalWeight);
278   int weight_option(const std::string& opt, int weight);
279   void init_safety();
280
281 }
282
283
284 ////
285 //// Functions
286 ////
287
288 /// evaluate() is the main evaluation function.  It always computes two
289 /// values, an endgame score and a middle game score, and interpolates
290 /// between them based on the remaining material.
291
292 Value evaluate(const Position &pos, EvalInfo &ei, int threadID) {
293
294   assert(pos.is_ok());
295   assert(threadID >= 0 && threadID < THREAD_MAX);
296
297   memset(&ei, 0, sizeof(EvalInfo));
298
299   // Initialize by reading the incrementally updated scores included in the
300   // position object (material + piece square tables)
301   ei.mgValue = pos.mg_value();
302   ei.egValue = pos.eg_value();
303
304   // Probe the material hash table
305   ei.mi = MaterialTable[threadID]->get_material_info(pos);
306   ei.mgValue += ei.mi->mg_value();
307   ei.egValue += ei.mi->eg_value();
308
309   // If we have a specialized evaluation function for the current material
310   // configuration, call it and return
311   if (ei.mi->specialized_eval_exists())
312       return ei.mi->evaluate(pos);
313
314   // After get_material_info() call that modifies them
315   ScaleFactor factor[2];
316   factor[WHITE] = ei.mi->scale_factor(pos, WHITE);
317   factor[BLACK] = ei.mi->scale_factor(pos, BLACK);
318
319   // Probe the pawn hash table
320   ei.pi = PawnTable[threadID]->get_pawn_info(pos);
321   ei.mgValue += apply_weight(ei.pi->mg_value(), WeightPawnStructureMidgame);
322   ei.egValue += apply_weight(ei.pi->eg_value(), WeightPawnStructureEndgame);
323
324   // Initialize king attack bitboards and king attack zones for both sides
325   ei.attackedBy[WHITE][KING] = pos.king_attacks(pos.king_square(WHITE));
326   ei.attackedBy[BLACK][KING] = pos.king_attacks(pos.king_square(BLACK));
327   ei.kingZone[WHITE] = ei.attackedBy[BLACK][KING] | (ei.attackedBy[BLACK][KING] >> 8);
328   ei.kingZone[BLACK] = ei.attackedBy[WHITE][KING] | (ei.attackedBy[WHITE][KING] << 8);
329
330   // Initialize pawn attack bitboards for both sides
331   ei.attackedBy[WHITE][PAWN] = ((pos.pawns(WHITE) << 9) & ~FileABB) | ((pos.pawns(WHITE) << 7) & ~FileHBB);
332   ei.attackedBy[BLACK][PAWN] = ((pos.pawns(BLACK) >> 7) & ~FileABB) | ((pos.pawns(BLACK) >> 9) & ~FileHBB);
333   ei.kingAttackersCount[WHITE] = count_1s_max_15(ei.attackedBy[WHITE][PAWN] & ei.attackedBy[BLACK][KING])/2;
334   ei.kingAttackersCount[BLACK] = count_1s_max_15(ei.attackedBy[BLACK][PAWN] & ei.attackedBy[WHITE][KING])/2;
335
336   // Evaluate pieces
337   for (Color c = WHITE; c <= BLACK; c++)
338   {
339     // Knights
340     for (int i = 0; i < pos.knight_count(c); i++)
341         evaluate_knight(pos, pos.knight_list(c, i), c, ei);
342
343     // Bishops
344     for (int i = 0; i < pos.bishop_count(c); i++)
345         evaluate_bishop(pos, pos.bishop_list(c, i), c, ei);
346
347     // Rooks
348     for (int i = 0; i < pos.rook_count(c); i++)
349         evaluate_rook(pos, pos.rook_list(c, i), c, ei);
350
351     // Queens
352     for(int i = 0; i < pos.queen_count(c); i++)
353         evaluate_queen(pos, pos.queen_list(c, i), c, ei);
354
355     // Special pattern: trapped bishops on a7/h7/a2/h2
356     Bitboard b = pos.bishops(c) & MaskA7H7[c];
357     while (b)
358     {
359         Square s = pop_1st_bit(&b);
360         evaluate_trapped_bishop_a7h7(pos, s, c, ei);
361     }
362
363     // Special pattern: trapped bishops on a1/h1/a8/h8 in Chess960:
364     if (Chess960)
365     {
366         b = pos.bishops(c) & MaskA1H1[c];
367         while (b)
368         {
369             Square s = pop_1st_bit(&b);
370             evaluate_trapped_bishop_a1h1(pos, s, c, ei);
371         }
372     }
373
374     // Sum up all attacked squares
375     ei.attackedBy[c][0] =   ei.attackedBy[c][PAWN]   | ei.attackedBy[c][KNIGHT]
376                           | ei.attackedBy[c][BISHOP] | ei.attackedBy[c][ROOK]
377                           | ei.attackedBy[c][QUEEN]  | ei.attackedBy[c][KING];
378   }
379
380   // Kings.  Kings are evaluated after all other pieces for both sides,
381   // because we need complete attack information for all pieces when computing
382   // the king safety evaluation.
383   for (Color c = WHITE; c <= BLACK; c++)
384       evaluate_king(pos, pos.king_square(c), c, ei);
385
386   // Evaluate passed pawns.  We evaluate passed pawns for both sides at once,
387   // because we need to know which side promotes first in positions where
388   // both sides have an unstoppable passed pawn.
389   if (ei.pi->passed_pawns())
390       evaluate_passed_pawns(pos, ei);
391
392   Phase phase = pos.game_phase();
393
394   // Middle-game specific evaluation terms
395   if (phase > PHASE_ENDGAME)
396   {
397     // Pawn storms in positions with opposite castling.
398     if (   square_file(pos.king_square(WHITE)) >= FILE_E
399         && square_file(pos.king_square(BLACK)) <= FILE_D)
400
401         ei.mgValue += ei.pi->queenside_storm_value(WHITE)
402                     - ei.pi->kingside_storm_value(BLACK);
403
404     else if (   square_file(pos.king_square(WHITE)) <= FILE_D
405              && square_file(pos.king_square(BLACK)) >= FILE_E)
406
407         ei.mgValue += ei.pi->kingside_storm_value(WHITE)
408                     - ei.pi->queenside_storm_value(BLACK);
409   }
410
411   // Mobility
412   ei.mgValue += apply_weight(ei.mgMobility, WeightMobilityMidgame);
413   ei.egValue += apply_weight(ei.egMobility, WeightMobilityEndgame);
414
415   // If we don't already have an unusual scale factor, check for opposite
416   // colored bishop endgames, and use a lower scale for those:
417   if (   phase < PHASE_MIDGAME
418       && pos.opposite_colored_bishops()
419       && (   (factor[WHITE] == SCALE_FACTOR_NORMAL && ei.egValue > Value(0))
420           || (factor[BLACK] == SCALE_FACTOR_NORMAL && ei.egValue < Value(0))))
421   {
422       ScaleFactor sf;
423
424       // Only the two bishops ?
425       if (   pos.non_pawn_material(WHITE) == BishopValueMidgame
426           && pos.non_pawn_material(BLACK) == BishopValueMidgame)
427       {
428           // Check for KBP vs KB with only a single pawn that is almost
429           // certainly a draw or at least two pawns.
430           bool one_pawn = (pos.pawn_count(WHITE) + pos.pawn_count(BLACK) == 1);
431           sf = one_pawn ? ScaleFactor(8) : ScaleFactor(32);
432       }
433       else
434           // Endgame with opposite-colored bishops, but also other pieces. Still
435           // a bit drawish, but not as drawish as with only the two bishops.
436            sf = ScaleFactor(50);
437
438       if (factor[WHITE] == SCALE_FACTOR_NORMAL)
439           factor[WHITE] = sf;
440       if (factor[BLACK] == SCALE_FACTOR_NORMAL)
441           factor[BLACK] = sf;
442   }
443
444   // Interpolate between the middle game and the endgame score, and
445   // return
446   Color stm = pos.side_to_move();
447
448   Value v = Sign[stm] * scale_by_game_phase(ei.mgValue, ei.egValue, phase, factor);
449
450   return (ei.mateThreat[stm] == MOVE_NONE ? v : 8 * QueenValueMidgame - v);
451 }
452
453
454 /// quick_evaluate() does a very approximate evaluation of the current position.
455 /// It currently considers only material and piece square table scores.  Perhaps
456 /// we should add scores from the pawn and material hash tables?
457
458 Value quick_evaluate(const Position &pos) {
459
460   assert(pos.is_ok());
461
462   static const
463   ScaleFactor sf[2] = {SCALE_FACTOR_NORMAL, SCALE_FACTOR_NORMAL};  
464
465   Value mgv = pos.mg_value();
466   Value egv = pos.eg_value();
467   Phase ph = pos.game_phase();
468   Color stm = pos.side_to_move();
469
470   return Sign[stm] * scale_by_game_phase(mgv, egv, ph, sf);
471 }
472
473
474 /// init_eval() initializes various tables used by the evaluation function.
475
476 void init_eval(int threads) {
477
478   assert(threads <= THREAD_MAX);
479
480   for (int i = 0; i < THREAD_MAX; i++)
481   {
482     if (i >= threads)
483     {
484         delete PawnTable[i];
485         delete MaterialTable[i];
486         PawnTable[i] = NULL;
487         MaterialTable[i] = NULL;
488         continue;
489     }
490     if (!PawnTable[i])
491         PawnTable[i] = new PawnInfoTable(PawnTableSize);
492     if (!MaterialTable[i])
493         MaterialTable[i] = new MaterialInfoTable(MaterialTableSize);
494   }
495
496   for (Bitboard b = 0ULL; b < 256ULL; b++)
497       BitCount8Bit[b] = count_1s(b);
498 }
499
500
501 /// quit_eval() releases heap-allocated memory at program termination.
502
503 void quit_eval() {
504   for(int i = 0; i < THREAD_MAX; i++) {
505     delete PawnTable[i];
506     delete MaterialTable[i];
507   }
508 }
509
510
511 /// read_weights() reads evaluation weights from the corresponding UCI
512 /// parameters.
513
514 void read_weights(Color us) {
515
516   WeightMobilityMidgame      = weight_option("Mobility (Middle Game)", WeightMobilityMidgameInternal);
517   WeightMobilityEndgame      = weight_option("Mobility (Endgame)", WeightMobilityEndgameInternal);
518   WeightPawnStructureMidgame = weight_option("Pawn Structure (Middle Game)", WeightPawnStructureMidgameInternal);
519   WeightPawnStructureEndgame = weight_option("Pawn Structure (Endgame)", WeightPawnStructureEndgameInternal);
520   WeightPassedPawnsMidgame   = weight_option("Passed Pawns (Middle Game)", WeightPassedPawnsMidgameInternal);
521   WeightPassedPawnsEndgame   = weight_option("Passed Pawns (Endgame)", WeightPassedPawnsEndgameInternal);
522
523   Color them = opposite_color(us);
524
525   WeightKingSafety[us]   = weight_option("Cowardice", WeightKingSafetyInternal);
526   WeightKingSafety[them] = weight_option("Aggressiveness", WeightKingOppSafetyInternal);
527
528   init_safety();
529 }
530
531
532 namespace {
533
534   // evaluate_common() computes terms common to all pieces attack
535
536   int evaluate_common(const Position&p, const Bitboard& b, Color us, EvalInfo& ei,
537                        int AttackWeight, const Value* mgBonus, const Value* egBonus,
538                        Square s = SQ_NONE, const Value* OutpostBonus = NULL) {
539
540     Color them = opposite_color(us);
541
542     // King attack
543     if (b & ei.kingZone[us])
544     {
545       ei.kingAttackersCount[us]++;
546       ei.kingAttackersWeight[us] += AttackWeight;
547       Bitboard bb = (b & ei.attackedBy[them][KING]);
548       if (bb)
549           ei.kingZoneAttacksCount[us] += count_1s_max_15(bb);
550     }
551
552     // Mobility
553     int mob = count_1s_max_15(b & ~p.pieces_of_color(us));
554     ei.mgMobility += Sign[us] * mgBonus[mob];
555     ei.egMobility += Sign[us] * egBonus[mob];
556
557     // Bishop and Knight outposts
558     if (!OutpostBonus || !p.square_is_weak(s, them))
559         return mob;
560
561     // Initial bonus based on square
562     Value v, bonus;
563     v = bonus = OutpostBonus[relative_square(us, s)];
564
565     // Increase bonus if supported by pawn, especially if the opponent has
566     // no minor piece which can exchange the outpost piece
567     if (v && (p.pawn_attacks(them, s) & p.pawns(us)))
568     {
569         bonus += v / 2;
570         if (   p.knight_count(them) == 0
571             && (SquaresByColorBB[square_color(s)] & p.bishops(them)) == EmptyBoardBB)
572             bonus += v;
573     }
574     ei.mgValue += Sign[us] * bonus;
575     ei.egValue += Sign[us] * bonus;
576     return mob;
577   }
578
579
580   // evaluate_knight() assigns bonuses and penalties to a knight of a given
581   // color on a given square.
582
583   void evaluate_knight(const Position &p, Square s, Color us, EvalInfo &ei) {
584
585     Bitboard b = p.knight_attacks(s);
586     ei.attackedBy[us][KNIGHT] |= b;
587
588     // King attack, mobility and outposts
589     evaluate_common(p, b, us, ei, KnightAttackWeight, MidgameKnightMobilityBonus,
590                     EndgameKnightMobilityBonus, s, KnightOutpostBonus);
591   }
592
593
594   // evaluate_bishop() assigns bonuses and penalties to a bishop of a given
595   // color on a given square.
596
597   void evaluate_bishop(const Position &p, Square s, Color us, EvalInfo &ei) {
598
599     Bitboard b = bishop_attacks_bb(s, p.occupied_squares() & ~p.queens(us));
600     ei.attackedBy[us][BISHOP] |= b;
601
602     // King attack, mobility and outposts
603     evaluate_common(p, b, us, ei, BishopAttackWeight, MidgameBishopMobilityBonus,
604                     EndgameBishopMobilityBonus, s, BishopOutpostBonus);
605   }
606
607
608   // evaluate_rook() assigns bonuses and penalties to a rook of a given
609   // color on a given square.
610
611   void evaluate_rook(const Position &p, Square s, Color us, EvalInfo &ei) {
612
613     //Bitboard b = p.rook_attacks(s);
614     Bitboard b = rook_attacks_bb(s, p.occupied_squares() & ~p.rooks_and_queens(us));
615     ei.attackedBy[us][ROOK] |= b;
616
617     // King attack and mobility
618     int mob = evaluate_common(p, b, us, ei, RookAttackWeight, MidgameRookMobilityBonus,
619                               EndgameRookMobilityBonus);
620
621     // Rook on 7th rank
622     Color them = opposite_color(us);
623
624     if (   relative_rank(us, s) == RANK_7
625         && relative_rank(us, p.king_square(them)) == RANK_8)
626     {
627         ei.mgValue += Sign[us] * MidgameRookOn7thBonus;
628         ei.egValue += Sign[us] * EndgameRookOn7thBonus;
629     }
630
631     // Open and half-open files
632     File f = square_file(s);
633     if (ei.pi->file_is_half_open(us, f))
634     {
635         if (ei.pi->file_is_half_open(them, f))
636         {
637             ei.mgValue += Sign[us] * RookOpenFileBonus;
638             ei.egValue += Sign[us] * RookOpenFileBonus;
639         }
640         else
641         {
642             ei.mgValue += Sign[us] * RookHalfOpenFileBonus;
643             ei.egValue += Sign[us] * RookHalfOpenFileBonus;
644         }
645     }
646
647     // Penalize rooks which are trapped inside a king. Penalize more if
648     // king has lost right to castle
649     if (mob > 6 || ei.pi->file_is_half_open(us, f))
650         return;
651
652     Square ksq = p.king_square(us);
653
654     if (    square_file(ksq) >= FILE_E
655         &&  square_file(s) > square_file(ksq)
656         && (relative_rank(us, ksq) == RANK_1 || square_rank(ksq) == square_rank(s)))
657     {
658         // Is there a half-open file between the king and the edge of the board?
659         if (!ei.pi->has_open_file_to_right(us, square_file(ksq)))
660             ei.mgValue -= p.can_castle(us)? Sign[us] * ((TrappedRookPenalty - mob * 16) / 2)
661                                           : Sign[us] *  (TrappedRookPenalty - mob * 16);
662     }
663     else if (    square_file(ksq) <= FILE_D
664              &&  square_file(s) < square_file(ksq)
665              && (relative_rank(us, ksq) == RANK_1 || square_rank(ksq) == square_rank(s)))
666     {
667         // Is there a half-open file between the king and the edge of the board?
668         if (!ei.pi->has_open_file_to_left(us, square_file(ksq)))
669             ei.mgValue -= p.can_castle(us)? Sign[us] * ((TrappedRookPenalty - mob * 16) / 2)
670                                           : Sign[us] * (TrappedRookPenalty - mob * 16);
671     }
672   }
673
674
675   // evaluate_queen() assigns bonuses and penalties to a queen of a given
676   // color on a given square.
677
678   void evaluate_queen(const Position &p, Square s, Color us, EvalInfo &ei) {
679
680     Bitboard b = p.queen_attacks(s);
681     ei.attackedBy[us][QUEEN] |= b;
682
683     // King attack and mobility
684     evaluate_common(p, b, us, ei, QueenAttackWeight, MidgameQueenMobilityBonus,
685                     EndgameQueenMobilityBonus);
686
687     // Queen on 7th rank
688     Color them = opposite_color(us);
689
690     if (   relative_rank(us, s) == RANK_7
691         && relative_rank(us, p.king_square(them)) == RANK_8)
692     {
693         ei.mgValue += Sign[us] * MidgameQueenOn7thBonus;
694         ei.egValue += Sign[us] * EndgameQueenOn7thBonus;
695     }
696   }
697
698
699   // evaluate_king() assigns bonuses and penalties to a king of a given
700   // color on a given square.
701
702   void evaluate_king(const Position &p, Square s, Color us, EvalInfo &ei) {
703
704     int shelter = 0, sign = Sign[us];
705
706     // King shelter.
707     if(relative_rank(us, s) <= RANK_4) {
708       Bitboard pawns = p.pawns(us) & this_and_neighboring_files_bb(s);
709       Rank r = square_rank(s);
710       for(int i = 0; i < 3; i++)
711         shelter += count_1s_8bit(pawns >> ((r+(i+1)*sign) * 8)) * (64>>i);
712       ei.mgValue += sign * Value(shelter);
713     }
714
715     // King safety.  This is quite complicated, and is almost certainly far
716     // from optimally tuned.
717     Color them = opposite_color(us);
718     if(p.queen_count(them) >= 1 && ei.kingAttackersCount[them] >= 2
719        && p.non_pawn_material(them) >= QueenValueMidgame + RookValueMidgame
720        && ei.kingZoneAttacksCount[them]) {
721
722       // Is it the attackers turn to move?
723       bool sente = (them == p.side_to_move());
724
725       // Find the attacked squares around the king which has no defenders
726       // apart from the king itself:
727       Bitboard undefended =
728         ei.attacked_by(them) & ~ei.attacked_by(us, PAWN)
729         & ~ei.attacked_by(us, KNIGHT) & ~ei.attacked_by(us, BISHOP)
730         & ~ei.attacked_by(us, ROOK) & ~ei.attacked_by(us, QUEEN)
731         & ei.attacked_by(us, KING);
732       Bitboard occ = p.occupied_squares(), b, b2;
733
734       // Initialize the 'attackUnits' variable, which is used later on as an
735       // index to the SafetyTable[] array.  The initial is based on the number
736       // and types of the attacking pieces, the number of attacked and
737       // undefended squares around the king, the square of the king, and the
738       // quality of the pawn shelter.
739       int attackUnits =
740         Min((ei.kingAttackersCount[them] * ei.kingAttackersWeight[them]) / 2, 25)
741         + (ei.kingZoneAttacksCount[them] + count_1s_max_15(undefended)) * 3
742         + InitKingDanger[relative_square(us, s)] - shelter / 32;
743
744       // Analyse safe queen contact checks:
745       b = undefended & ei.attacked_by(them, QUEEN) & ~p.pieces_of_color(them);
746       if(b) {
747         Bitboard attackedByOthers =
748           ei.attacked_by(them, PAWN) | ei.attacked_by(them, KNIGHT)
749           | ei.attacked_by(them, BISHOP) | ei.attacked_by(them, ROOK);
750         b &= attackedByOthers;
751         if(b) {
752           // The bitboard b now contains the squares available for safe queen
753           // contact checks.
754           int count = count_1s_max_15(b);
755           attackUnits += QueenContactCheckBonus * count * (sente? 2 : 1);
756
757           // Is there a mate threat?
758           if(QueenContactMates && !p.is_check()) {
759             Bitboard escapeSquares =
760               p.king_attacks(s) & ~p.pieces_of_color(us) & ~attackedByOthers;
761             while(b) {
762               Square from, to = pop_1st_bit(&b);
763               if(!(escapeSquares
764                    & ~queen_attacks_bb(to, occ & clear_mask_bb(s)))) {
765                 // We have a mate, unless the queen is pinned or there
766                 // is an X-ray attack through the queen.
767                 for(int i = 0; i < p.queen_count(them); i++) {
768                   from = p.queen_list(them, i);
769                   if(bit_is_set(p.queen_attacks(from), to)
770                      && !bit_is_set(p.pinned_pieces(them), from)
771                      && !(rook_attacks_bb(to, occ & clear_mask_bb(from))
772                           & p.rooks_and_queens(us))
773                      && !(rook_attacks_bb(to, occ & clear_mask_bb(from))
774                           & p.rooks_and_queens(us)))
775                     ei.mateThreat[them] = make_move(from, to);
776                 }
777               }
778             }
779           }
780         }
781       }
782
783       // Analyse safe rook contact checks:
784       if(RookContactCheckBonus) {
785         b = undefended & ei.attacked_by(them, ROOK) & ~p.pieces_of_color(them);
786         if(b) {
787           Bitboard attackedByOthers =
788             ei.attacked_by(them, PAWN) | ei.attacked_by(them, KNIGHT)
789             | ei.attacked_by(them, BISHOP) | ei.attacked_by(them, QUEEN);
790           b &= attackedByOthers;
791           if(b) {
792             int count = count_1s_max_15(b);
793             attackUnits += (RookContactCheckBonus * count * (sente? 2 : 1));
794           }
795         }
796       }
797
798       // Analyse safe distance checks:
799       if(QueenCheckBonus > 0 || RookCheckBonus > 0) {
800         b = p.rook_attacks(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us);
801
802         // Queen checks
803         b2 = b & ei.attacked_by(them, QUEEN);
804         if(b2) attackUnits += QueenCheckBonus * count_1s_max_15(b2);
805
806         // Rook checks
807         b2 = b & ei.attacked_by(them, ROOK);
808         if(b2) attackUnits += RookCheckBonus * count_1s_max_15(b2);
809       }
810       if(QueenCheckBonus > 0 || BishopCheckBonus > 0) {
811         b = p.bishop_attacks(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us);
812         // Queen checks
813         b2 = b & ei.attacked_by(them, QUEEN);
814         if(b2) attackUnits += QueenCheckBonus * count_1s_max_15(b2);
815
816         // Bishop checks
817         b2 = b & ei.attacked_by(them, BISHOP);
818         if(b2) attackUnits += BishopCheckBonus * count_1s_max_15(b2);
819       }
820       if(KnightCheckBonus > 0) {
821         b = p.knight_attacks(s) & ~p.pieces_of_color(them) & ~ei.attacked_by(us);
822         // Knight checks
823         b2 = b & ei.attacked_by(them, KNIGHT);
824         if(b2) attackUnits += KnightCheckBonus * count_1s_max_15(b2);
825       }
826
827       // Analyse discovered checks (only for non-pawns right now, consider
828       // adding pawns later).
829       if(DiscoveredCheckBonus) {
830         b = p.discovered_check_candidates(them) & ~p.pawns();
831         if(b)
832           attackUnits +=
833             DiscoveredCheckBonus * count_1s_max_15(b) * (sente? 2 : 1);
834       }
835
836       // Has a mate threat been found?  We don't do anything here if the
837       // side with the mating move is the side to move, because in that
838       // case the mating side will get a huge bonus at the end of the main
839       // evaluation function instead.
840       if(ei.mateThreat[them] != MOVE_NONE)
841         attackUnits += MateThreatBonus;
842
843       // Ensure that attackUnits is between 0 and 99, in order to avoid array
844       // out of bounds errors:
845       if(attackUnits < 0) attackUnits = 0;
846       if(attackUnits >= 100) attackUnits = 99;
847
848       // Finally, extract the king safety score from the SafetyTable[] array.
849       // Add the score to the evaluation, and also to ei.futilityMargin.  The
850       // reason for adding the king safety score to the futility margin is
851       // that the king safety scores can sometimes be very big, and that
852       // capturing a single attacking piece can therefore result in a score
853       // change far bigger than the value of the captured piece.
854       Value v = apply_weight(SafetyTable[attackUnits], WeightKingSafety[us]);
855       ei.mgValue -= sign * v;
856       if(us == p.side_to_move())
857         ei.futilityMargin += v;
858     }
859   }
860
861
862   // evaluate_passed_pawns() evaluates the passed pawns for both sides.
863
864   void evaluate_passed_pawns(const Position &pos, EvalInfo &ei) {
865     bool hasUnstoppable[2] = {false, false};
866     int movesToGo[2] = {100, 100};
867
868     for(Color us = WHITE; us <= BLACK; us++) {
869       Color them = opposite_color(us);
870       Square ourKingSq = pos.king_square(us);
871       Square theirKingSq = pos.king_square(them);
872       Bitboard b = ei.pi->passed_pawns() & pos.pawns(us), b2, b3, b4;
873
874       while(b) {
875         Square s = pop_1st_bit(&b);
876         assert(pos.piece_on(s) == pawn_of_color(us));
877         assert(pos.pawn_is_passed(us, s));
878
879         int r = int(relative_rank(us, s) - RANK_2);
880         int tr = Max(0, r * (r-1));
881         Square blockSq = s + pawn_push(us);
882
883         // Base bonus based on rank:
884         Value mbonus = Value(20 * tr);
885         Value ebonus = Value(10 + r * r * 10);
886
887         // Adjust bonus based on king proximity:
888         ebonus -= Value(square_distance(ourKingSq, blockSq) * 3 * tr);
889         ebonus -=
890           Value(square_distance(ourKingSq, blockSq + pawn_push(us)) * 1 * tr);
891         ebonus += Value(square_distance(theirKingSq, blockSq) * 6 * tr);
892
893         // If the pawn is free to advance, increase bonus:
894         if(pos.square_is_empty(blockSq)) {
895
896           b2 = squares_in_front_of(us, s);
897           b3 = b2 & ei.attacked_by(them);
898           b4 = b2 & ei.attacked_by(us);
899           if((b2 & pos.pieces_of_color(them)) == EmptyBoardBB) {
900             // There are no enemy pieces in the pawn's path!  Are any of the
901             // squares in the pawn's path attacked by the enemy?
902             if(b3 == EmptyBoardBB)
903               // No enemy attacks, huge bonus!
904               ebonus += Value(tr * ((b2 == b4)? 17 : 15));
905             else
906               // OK, there are enemy attacks.  Are those squares which are
907               // attacked by the enemy also attacked by us?  If yes, big bonus
908               // (but smaller than when there are no enemy attacks), if no,
909               // somewhat smaller bonus.
910               ebonus += Value(tr * (((b3 & b4) == b3)? 13 : 8));
911           }
912           else {
913             // There are some enemy pieces in the pawn's path.  While this is
914             // sad, we still assign a moderate bonus if all squares in the path
915             // which are either occupied by or attacked by enemy pieces are
916             // also attacked by us.
917             if(((b3 | (b2 & pos.pieces_of_color(them))) & ~b4) == EmptyBoardBB)
918               ebonus += Value(tr * 6);
919           }
920           // At last, add a small bonus when there are no *friendly* pieces
921           // in the pawn's path:
922           if((b2 & pos.pieces_of_color(us)) == EmptyBoardBB)
923             ebonus += Value(tr);
924         }
925
926         // If the pawn is supported by a friendly pawn, increase bonus.
927         b2 = pos.pawns(us) & neighboring_files_bb(s);
928         if(b2 & rank_bb(s))
929           ebonus += Value(r * 20);
930         else if(pos.pawn_attacks(them, s) & b2)
931           ebonus += Value(r * 12);
932
933         // If the other side has only a king, check whether the pawn is
934         // unstoppable:
935         if(pos.non_pawn_material(them) == Value(0)) {
936           Square qsq;
937           int d;
938
939           qsq = relative_square(us, make_square(square_file(s), RANK_8));
940           d = square_distance(s, qsq) - square_distance(theirKingSq, qsq)
941             + ((us == pos.side_to_move())? 0 : 1);
942
943           if(d < 0) {
944             int mtg = RANK_8 - relative_rank(us, s);
945             int blockerCount =
946               count_1s_max_15(squares_in_front_of(us,s)&pos.occupied_squares());
947             mtg += blockerCount;
948             d += blockerCount;
949             if(d < 0) {
950               hasUnstoppable[us] = true;
951               movesToGo[us] = Min(movesToGo[us], mtg);
952             }
953           }
954         }
955         // Rook pawns are a special case:  They are sometimes worse, and
956         // sometimes better than other passed pawns.  It is difficult to find
957         // good rules for determining whether they are good or bad.  For now,
958         // we try the following:  Increase the value for rook pawns if the
959         // other side has no pieces apart from a knight, and decrease the
960         // value if the other side has a rook or queen.
961         if(square_file(s) == FILE_A || square_file(s) == FILE_H) {
962           if(pos.non_pawn_material(them) == KnightValueMidgame
963              && pos.knight_count(them) == 1)
964             ebonus += ebonus / 4;
965           else if(pos.rooks_and_queens(them))
966             ebonus -= ebonus / 4;
967         }
968
969         // Add the scores for this pawn to the middle game and endgame eval.
970         ei.mgValue += apply_weight(Sign[us] * mbonus, WeightPassedPawnsMidgame);
971         ei.egValue += apply_weight(Sign[us] * ebonus, WeightPassedPawnsEndgame);
972       }
973     }
974
975     // Does either side have an unstoppable passed pawn?
976     if(hasUnstoppable[WHITE] && !hasUnstoppable[BLACK])
977       ei.egValue += UnstoppablePawnValue - Value(0x40 * movesToGo[WHITE]);
978     else if(hasUnstoppable[BLACK] && !hasUnstoppable[WHITE])
979       ei.egValue -= UnstoppablePawnValue - Value(0x40 * movesToGo[BLACK]);
980     else if(hasUnstoppable[BLACK] && hasUnstoppable[WHITE]) {
981       // Both sides have unstoppable pawns!  Try to find out who queens
982       // first.  We begin by transforming 'movesToGo' to the number of
983       // plies until the pawn queens for both sides:
984       movesToGo[WHITE] *= 2;
985       movesToGo[BLACK] *= 2;
986       movesToGo[pos.side_to_move()]--;
987
988       // If one side queens at least three plies before the other, that
989       // side wins:
990       if(movesToGo[WHITE] <= movesToGo[BLACK] - 3)
991         ei.egValue += UnstoppablePawnValue - Value(0x40 * (movesToGo[WHITE]/2));
992       else if(movesToGo[BLACK] <= movesToGo[WHITE] - 3)
993         ei.egValue -= UnstoppablePawnValue - Value(0x40 * (movesToGo[BLACK]/2));
994
995       // We could also add some rules about the situation when one side
996       // queens exactly one ply before the other:  Does the first queen
997       // check the opponent's king, or attack the opponent's queening square?
998       // This is slightly tricky to get right, because it is possible that
999       // the opponent's king has moved somewhere before the first pawn queens.
1000     }
1001   }
1002
1003
1004   // evaluate_trapped_bishop_a7h7() determines whether a bishop on a7/h7
1005   // (a2/h2 for black) is trapped by enemy pawns, and assigns a penalty
1006   // if it is.
1007
1008   void evaluate_trapped_bishop_a7h7(const Position &pos, Square s, Color us,
1009                                     EvalInfo &ei) {
1010
1011     assert(square_is_ok(s));
1012     assert(pos.piece_on(s) == bishop_of_color(us));
1013
1014     Square b6 = relative_square(us, (square_file(s) == FILE_A) ? SQ_B6 : SQ_G6);
1015     Square b8 = relative_square(us, (square_file(s) == FILE_A) ? SQ_B8 : SQ_G8);
1016
1017     if (   pos.piece_on(b6) == pawn_of_color(opposite_color(us))
1018         && pos.see(s, b6) < 0
1019         && pos.see(s, b8) < 0)
1020     {
1021         ei.mgValue -= Sign[us] * TrappedBishopA7H7Penalty;
1022         ei.egValue -= Sign[us] * TrappedBishopA7H7Penalty;
1023     }
1024   }
1025
1026
1027   // evaluate_trapped_bishop_a1h1() determines whether a bishop on a1/h1
1028   // (a8/h8 for black) is trapped by a friendly pawn on b2/g2 (b7/g7 for
1029   // black), and assigns a penalty if it is.  This pattern can obviously
1030   // only occur in Chess960 games.
1031
1032   void evaluate_trapped_bishop_a1h1(const Position &pos, Square s, Color us,
1033                                     EvalInfo &ei) {
1034     Piece pawn = pawn_of_color(us);
1035     Square b2, b3, c3;
1036
1037     assert(Chess960);
1038     assert(square_is_ok(s));
1039     assert(pos.piece_on(s) == bishop_of_color(us));
1040
1041     if(square_file(s) == FILE_A) {
1042       b2 = relative_square(us, SQ_B2);
1043       b3 = relative_square(us, SQ_B3);
1044       c3 = relative_square(us, SQ_C3);
1045     }
1046     else {
1047       b2 = relative_square(us, SQ_G2);
1048       b3 = relative_square(us, SQ_G3);
1049       c3 = relative_square(us, SQ_F3);
1050     }
1051
1052     if(pos.piece_on(b2) == pawn) {
1053       Value penalty;
1054
1055       if(!pos.square_is_empty(b3))
1056         penalty = 2*TrappedBishopA1H1Penalty;
1057       else if(pos.piece_on(c3) == pawn)
1058         penalty = TrappedBishopA1H1Penalty;
1059       else
1060         penalty = TrappedBishopA1H1Penalty / 2;
1061
1062       ei.mgValue -= Sign[us] * penalty;
1063       ei.egValue -= Sign[us] * penalty;
1064     }
1065
1066   }
1067
1068
1069   // apply_weight applies an evaluation weight to a value.
1070
1071   inline Value apply_weight(Value v, int w) {
1072     return (v*w) / 0x100;
1073   }
1074
1075
1076   // scale_by_game_phase interpolates between a middle game and an endgame
1077   // score, based on game phase.  It also scales the return value by a
1078   // ScaleFactor array.
1079
1080   Value scale_by_game_phase(Value mv, Value ev, Phase ph, const ScaleFactor sf[]) {
1081
1082     assert(mv > -VALUE_INFINITE && mv < VALUE_INFINITE);
1083     assert(ev > -VALUE_INFINITE && ev < VALUE_INFINITE);
1084     assert(ph >= PHASE_ENDGAME && ph <= PHASE_MIDGAME);
1085
1086     ev = apply_scale_factor(ev, sf[(ev > Value(0) ? WHITE : BLACK)]);
1087
1088     // Linearized sigmoid interpolator
1089     int sph = int(ph);
1090     sph -= (64 - sph) / 4;
1091     sph = Min(PHASE_MIDGAME, Max(PHASE_ENDGAME, sph));
1092
1093     Value result = Value(int((mv * sph + ev * (128 - sph)) / 128));
1094
1095     return Value(int(result) & ~(GrainSize - 1));
1096   }
1097
1098
1099   // count_1s_8bit() counts the number of nonzero bits in the 8 least
1100   // significant bits of a Bitboard. This function is used by the king
1101   // shield evaluation.
1102
1103   int count_1s_8bit(Bitboard b) {
1104     return int(BitCount8Bit[b & 0xFF]);
1105   }
1106
1107
1108   // compute_weight() computes the value of an evaluation weight, by combining
1109   // an UCI-configurable weight with an internal weight.
1110
1111   int compute_weight(int uciWeight, int internalWeight) {
1112     uciWeight = (uciWeight * 0x100) / 100;
1113     return (uciWeight * internalWeight) / 0x100;
1114   }
1115
1116
1117   // helper used in read_weights()
1118   int weight_option(const std::string& opt, int weight) {
1119
1120     return compute_weight(get_option_value_int(opt), weight);
1121   }
1122
1123
1124   // init_safety() initizes the king safety evaluation, based on UCI
1125   // parameters.  It is called from read_weights().
1126
1127   void init_safety() {
1128
1129     QueenContactCheckBonus = get_option_value_int("Queen Contact Check Bonus");
1130     RookContactCheckBonus  = get_option_value_int("Rook Contact Check Bonus");
1131     QueenCheckBonus        = get_option_value_int("Queen Check Bonus");
1132     RookCheckBonus         = get_option_value_int("Rook Check Bonus");
1133     BishopCheckBonus       = get_option_value_int("Bishop Check Bonus");
1134     KnightCheckBonus       = get_option_value_int("Knight Check Bonus");
1135     DiscoveredCheckBonus   = get_option_value_int("Discovered Check Bonus");
1136     MateThreatBonus        = get_option_value_int("Mate Threat Bonus");
1137
1138     int maxSlope = get_option_value_int("King Safety Max Slope");
1139     int peak     = get_option_value_int("King Safety Max Value") * 256 / 100;
1140     double a     = get_option_value_int("King Safety Coefficient") / 100.0;
1141     double b     = get_option_value_int("King Safety X Intercept");
1142     bool quad    = (get_option_value_string("King Safety Curve") == "Quadratic");
1143     bool linear  = (get_option_value_string("King Safety Curve") == "Linear");
1144
1145     for (int i = 0; i < 100; i++)
1146     {
1147         if (i < b)
1148             SafetyTable[i] = Value(0);
1149         else if(quad)
1150             SafetyTable[i] = Value((int)(a * (i - b) * (i - b)));
1151         else if(linear)
1152             SafetyTable[i] = Value((int)(100 * a * (i - b)));
1153     }
1154
1155     for (int i = 0; i < 100; i++)
1156     {
1157         if (SafetyTable[i+1] - SafetyTable[i] > maxSlope)
1158             for (int j = i + 1; j < 100; j++)
1159                 SafetyTable[j] = SafetyTable[j-1] + Value(maxSlope);
1160
1161         if (SafetyTable[i]  > Value(peak))
1162             SafetyTable[i] = Value(peak);
1163     }
1164   }
1165
1166 }