Subversion Repositories Games.Chess Giants

Rev

Rev 96 | Rev 169 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 96 Rev 154
Line 22... Line 22...
22
#include <cassert>
22
#include <cassert>
23
#include <cstring>   // For std::memset
23
#include <cstring>   // For std::memset
24
#include <iomanip>
24
#include <iomanip>
25
#include <sstream>
25
#include <sstream>
26
 
26
 
27
#include "bitcount.h"
27
#include "bitboard.h"
28
#include "evaluate.h"
28
#include "evaluate.h"
29
#include "material.h"
29
#include "material.h"
30
#include "pawns.h"
30
#include "pawns.h"
31
 
31
 
32
namespace {
32
namespace {
Line 74... Line 74...
74
  struct EvalInfo {
74
  struct EvalInfo {
75
 
75
 
76
    // attackedBy[color][piece type] is a bitboard representing all squares
76
    // attackedBy[color][piece type] is a bitboard representing all squares
77
    // attacked by a given color and piece type (can be also ALL_PIECES).
77
    // attacked by a given color and piece type (can be also ALL_PIECES).
78
    Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
78
    Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
-
 
79
 
-
 
80
    // attackedBy2[color] are the squares attacked by 2 pieces of a given color,
-
 
81
    // possibly via x-ray or by one pawn and one piece. Diagonal x-ray through
-
 
82
    // pawn or squares attacked by 2 pawns are not explicitly added.
-
 
83
    Bitboard attackedBy2[COLOR_NB];
79
 
84
 
80
    // kingRing[color] is the zone around the king which is considered
85
    // kingRing[color] is the zone around the king which is considered
81
    // by the king safety evaluation. This consists of the squares directly
86
    // by the king safety evaluation. This consists of the squares directly
82
    // adjacent to the king, and the three (or two, for a king on an edge file)
87
    // adjacent to the king, and the three (or two, for a king on an edge file)
83
    // squares two ranks in front of the king. For instance, if black's king
88
    // squares two ranks in front of the king. For instance, if black's king
Line 112... Line 117...
112
 
117
 
113
  // MobilityBonus[PieceType][attacked] contains bonuses for middle and end
118
  // MobilityBonus[PieceType][attacked] contains bonuses for middle and end
114
  // game, indexed by piece type and number of attacked squares in the MobilityArea.
119
  // game, indexed by piece type and number of attacked squares in the MobilityArea.
115
  const Score MobilityBonus[][32] = {
120
  const Score MobilityBonus[][32] = {
116
    {}, {},
121
    {}, {},
117
    { S(-75,-76), S(-56,-54), S(- 9,-26), S( -2,-10), S(  6,  5), S( 15, 11), // Knights
122
    { S(-75,-76), S(-56,-54), S( -9,-26), S( -2,-10), S(  6,  5), S( 15, 11), // Knights
118
      S( 22, 26), S( 30, 28), S( 36, 29) },
123
      S( 22, 26), S( 30, 28), S( 36, 29) },
119
    { S(-48,-58), S(-21,-19), S( 16, -2), S( 26, 12), S( 37, 22), S( 51, 42), // Bishops
124
    { S(-48,-58), S(-21,-19), S( 16, -2), S( 26, 12), S( 37, 22), S( 51, 42), // Bishops
120
      S( 54, 54), S( 63, 58), S( 65, 63), S( 71, 70), S( 79, 74), S( 81, 86),
125
      S( 54, 54), S( 63, 58), S( 65, 63), S( 71, 70), S( 79, 74), S( 81, 86),
121
      S( 92, 90), S( 97, 94) },
126
      S( 92, 90), S( 97, 94) },
122
    { S(-56,-78), S(-25,-18), S(-11, 26), S( -5, 55), S( -4, 70), S( -1, 81), // Rooks
127
    { S(-56,-78), S(-25,-18), S(-11, 26), S( -5, 55), S( -4, 70), S( -1, 81), // Rooks
Line 130... Line 135...
130
  };
135
  };
131
 
136
 
132
  // Outpost[knight/bishop][supported by pawn] contains bonuses for knights and
137
  // Outpost[knight/bishop][supported by pawn] contains bonuses for knights and
133
  // bishops outposts, bigger if outpost piece is supported by a pawn.
138
  // bishops outposts, bigger if outpost piece is supported by a pawn.
134
  const Score Outpost[][2] = {
139
  const Score Outpost[][2] = {
135
    { S(42,11), S(63,17) }, // Knights
140
    { S(43,11), S(65,20) }, // Knights
136
    { S(18, 5), S(27, 8) }  // Bishops
141
    { S(20, 3), S(29, 8) }  // Bishops
137
  };
142
  };
138
 
143
 
139
  // ReachableOutpost[knight/bishop][supported by pawn] contains bonuses for
144
  // ReachableOutpost[knight/bishop][supported by pawn] contains bonuses for
140
  // knights and bishops which can reach an outpost square in one move, bigger
145
  // knights and bishops which can reach an outpost square in one move, bigger
141
  // if outpost square is supported by a pawn.
146
  // if outpost square is supported by a pawn.
142
  const Score ReachableOutpost[][2] = {
147
  const Score ReachableOutpost[][2] = {
143
    { S(21, 5), S(31, 8) }, // Knights
148
    { S(21, 5), S(35, 8) }, // Knights
144
    { S( 8, 2), S(13, 4) }  // Bishops
149
    { S( 8, 0), S(14, 4) }  // Bishops
145
  };
150
  };
146
 
151
 
147
  // RookOnFile[semiopen/open] contains bonuses for each rook when there is no
152
  // RookOnFile[semiopen/open] contains bonuses for each rook when there is no
148
  // friendly pawn on the rook file.
153
  // friendly pawn on the rook file.
149
  const Score RookOnFile[2] = { S(19, 10), S(43, 21) };
154
  const Score RookOnFile[2] = { S(20, 7), S(45, 20) };
150
 
155
 
151
  // ThreatBySafePawn[PieceType] contains bonuses according to which piece
156
  // ThreatBySafePawn[PieceType] contains bonuses according to which piece
152
  // type is attacked by a pawn which is protected or is not attacked.
157
  // type is attacked by a pawn which is protected or is not attacked.
153
  const Score ThreatBySafePawn[PIECE_TYPE_NB] = {
158
  const Score ThreatBySafePawn[PIECE_TYPE_NB] = {
154
    S(0, 0), S(0, 0), S(176, 139), S(131, 127), S(217, 218), S(203, 215) };
159
    S(0, 0), S(0, 0), S(176, 139), S(131, 127), S(217, 218), S(203, 215)
-
 
160
  };
155
 
161
 
156
  // Threat[by minor/by rook][attacked PieceType] contains
162
  // Threat[by minor/by rook][attacked PieceType] contains
157
  // bonuses according to which piece type attacks which one.
163
  // bonuses according to which piece type attacks which one.
158
  // Attacks on lesser pieces which are pawn-defended are not considered.
164
  // Attacks on lesser pieces which are pawn-defended are not considered.
159
  const Score Threat[][PIECE_TYPE_NB] = {
165
  const Score Threat[][PIECE_TYPE_NB] = {
Line 166... Line 172...
166
  const Score ThreatByKing[2] = { S(3, 62), S(9, 138) };
172
  const Score ThreatByKing[2] = { S(3, 62), S(9, 138) };
167
 
173
 
168
  // Passed[mg/eg][Rank] contains midgame and endgame bonuses for passed pawns.
174
  // Passed[mg/eg][Rank] contains midgame and endgame bonuses for passed pawns.
169
  // We don't use a Score because we process the two components independently.
175
  // We don't use a Score because we process the two components independently.
170
  const Value Passed[][RANK_NB] = {
176
  const Value Passed[][RANK_NB] = {
171
    { V(0), V( 1), V(26), V(68), V(161), V(247) },
177
    { V(5), V( 5), V(31), V(73), V(166), V(252) },
172
    { V(7), V(14), V(38), V(64), V(137), V(193) }
178
    { V(7), V(14), V(38), V(73), V(166), V(252) }
173
  };
179
  };
174
 
180
 
175
  // PassedFile[File] contains a bonus according to the file of a passed pawn
181
  // PassedFile[File] contains a bonus according to the file of a passed pawn
176
  const Score PassedFile[FILE_NB] = {
182
  const Score PassedFile[FILE_NB] = {
177
    S(  9, 10), S( 2, 10), S( 1, -8), S(-20,-12),
183
    S(  9, 10), S( 2, 10), S( 1, -8), S(-20,-12),
Line 179... Line 185...
179
  };
185
  };
180
 
186
 
181
  // Assorted bonuses and penalties used by evaluation
187
  // Assorted bonuses and penalties used by evaluation
182
  const Score MinorBehindPawn     = S(16,  0);
188
  const Score MinorBehindPawn     = S(16,  0);
183
  const Score BishopPawns         = S( 8, 12);
189
  const Score BishopPawns         = S( 8, 12);
184
  const Score RookOnPawn          = S( 7, 27);
190
  const Score RookOnPawn          = S( 8, 24);
185
  const Score TrappedRook         = S(92,  0);
191
  const Score TrappedRook         = S(92,  0);
-
 
192
  const Score CloseEnemies        = S( 7,  0);
186
  const Score Checked             = S(20, 20);
193
  const Score SafeCheck           = S(20, 20);
-
 
194
  const Score OtherCheck          = S(10, 10);
187
  const Score ThreatByHangingPawn = S(70, 63);
195
  const Score ThreatByHangingPawn = S(71, 61);
-
 
196
  const Score LooseEnemies        = S( 0, 25);
-
 
197
  const Score WeakQueen           = S(35,  0);
188
  const Score Hanging             = S(48, 28);
198
  const Score Hanging             = S(48, 27);
189
  const Score ThreatByPawnPush    = S(31, 19);
199
  const Score ThreatByPawnPush    = S(38, 22);
190
  const Score Unstoppable         = S( 0, 20);
200
  const Score Unstoppable         = S( 0, 20);
-
 
201
  const Score PawnlessFlank       = S(20, 80);
-
 
202
  const Score HinderPassedPawn    = S( 7,  0);
191
 
203
 
192
  // Penalty for a bishop on a1/h1 (a8/h8 for black) which is trapped by
204
  // Penalty for a bishop on a1/h1 (a8/h8 for black) which is trapped by
193
  // a friendly pawn on b2/g2 (b7/g7 for black). This can obviously only
205
  // a friendly pawn on b2/g2 (b7/g7 for black). This can obviously only
194
  // happen in Chess960 games.
206
  // happen in Chess960 games.
195
  const Score TrappedBishopA1H1 = S(50, 50);
207
  const Score TrappedBishopA1H1 = S(50, 50);
196
 
208
 
197
  #undef S
209
  #undef S
198
  #undef V
210
  #undef V
199
 
-
 
200
  // King danger constants and variables. The king danger scores are looked-up
-
 
201
  // in KingDanger[]. Various little "meta-bonuses" measuring the strength
-
 
202
  // of the enemy attack are added up into an integer, which is used as an
-
 
203
  // index to KingDanger[].
-
 
204
  Score KingDanger[512];
-
 
205
 
211
 
206
  // KingAttackWeights[PieceType] contains king attack weights by piece type
212
  // KingAttackWeights[PieceType] contains king attack weights by piece type
207
  const int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 7, 5, 4, 1 };
213
  const int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 78, 56, 45, 11 };
208
 
214
 
209
  // Penalties for enemy's safe checks
215
  // Penalties for enemy's safe checks
210
  const int QueenContactCheck = 89;
216
  const int QueenContactCheck = 997;
211
  const int QueenCheck        = 50;
217
  const int QueenCheck        = 695;
212
  const int RookCheck         = 45;
218
  const int RookCheck         = 638;
213
  const int BishopCheck       = 6;
219
  const int BishopCheck       = 538;
214
  const int KnightCheck       = 14;
220
  const int KnightCheck       = 874;
215
 
221
 
216
 
222
 
217
  // eval_init() initializes king and attack bitboards for a given color
223
  // eval_init() initializes king and attack bitboards for a given color
218
  // adding pawn attacks. To be done at the beginning of the evaluation.
224
  // adding pawn attacks. To be done at the beginning of the evaluation.
219
 
225
 
220
  template<Color Us>
226
  template<Color Us>
221
  void eval_init(const Position& pos, EvalInfo& ei) {
227
  void eval_init(const Position& pos, EvalInfo& ei) {
222
 
228
 
223
    const Color  Them = (Us == WHITE ? BLACK   : WHITE);
229
    const Color  Them = (Us == WHITE ? BLACK : WHITE);
224
    const Square Down = (Us == WHITE ? DELTA_S : DELTA_N);
230
    const Square Down = (Us == WHITE ? SOUTH : NORTH);
225
 
231
 
226
    ei.pinnedPieces[Us] = pos.pinned_pieces(Us);
232
    ei.pinnedPieces[Us] = pos.pinned_pieces(Us);
227
    Bitboard b = ei.attackedBy[Them][KING] = pos.attacks_from<KING>(pos.square<KING>(Them));
233
    Bitboard b = ei.attackedBy[Them][KING];
228
    ei.attackedBy[Them][ALL_PIECES] |= b;
234
    ei.attackedBy[Them][ALL_PIECES] |= b;
229
    ei.attackedBy[Us][ALL_PIECES] |= ei.attackedBy[Us][PAWN] = ei.pi->pawn_attacks(Us);
235
    ei.attackedBy[Us][ALL_PIECES] |= ei.attackedBy[Us][PAWN] = ei.pi->pawn_attacks(Us);
-
 
236
    ei.attackedBy2[Us] = ei.attackedBy[Us][PAWN] & ei.attackedBy[Us][KING];
230
 
237
 
231
    // Init king safety tables only if we are going to use them
238
    // Init king safety tables only if we are going to use them
232
    if (pos.non_pawn_material(Us) >= QueenValueMg)
239
    if (pos.non_pawn_material(Us) >= QueenValueMg)
233
    {
240
    {
234
        ei.kingRing[Them] = b | shift_bb<Down>(b);
241
        ei.kingRing[Them] = b | shift<Down>(b);
235
        b &= ei.attackedBy[Us][PAWN];
242
        b &= ei.attackedBy[Us][PAWN];
236
        ei.kingAttackersCount[Us] = b ? popcount<Max15>(b) : 0;
243
        ei.kingAttackersCount[Us] = popcount(b);
237
        ei.kingAdjacentZoneAttacksCount[Us] = ei.kingAttackersWeight[Us] = 0;
244
        ei.kingAdjacentZoneAttacksCount[Us] = ei.kingAttackersWeight[Us] = 0;
238
    }
245
    }
239
    else
246
    else
240
        ei.kingRing[Them] = ei.kingAttackersCount[Us] = 0;
247
        ei.kingRing[Them] = ei.kingAttackersCount[Us] = 0;
241
  }
248
  }
Line 267... Line 274...
267
                         : pos.attacks_from<Pt>(s);
274
                         : pos.attacks_from<Pt>(s);
268
 
275
 
269
        if (ei.pinnedPieces[Us] & s)
276
        if (ei.pinnedPieces[Us] & s)
270
            b &= LineBB[pos.square<KING>(Us)][s];
277
            b &= LineBB[pos.square<KING>(Us)][s];
271
 
278
 
-
 
279
        ei.attackedBy2[Us] |= ei.attackedBy[Us][ALL_PIECES] & b;
272
        ei.attackedBy[Us][ALL_PIECES] |= ei.attackedBy[Us][Pt] |= b;
280
        ei.attackedBy[Us][ALL_PIECES] |= ei.attackedBy[Us][Pt] |= b;
273
 
281
 
274
        if (b & ei.kingRing[Them])
282
        if (b & ei.kingRing[Them])
275
        {
283
        {
276
            ei.kingAttackersCount[Us]++;
284
            ei.kingAttackersCount[Us]++;
277
            ei.kingAttackersWeight[Us] += KingAttackWeights[Pt];
285
            ei.kingAttackersWeight[Us] += KingAttackWeights[Pt];
278
            bb = b & ei.attackedBy[Them][KING];
-
 
279
            if (bb)
-
 
280
                ei.kingAdjacentZoneAttacksCount[Us] += popcount<Max15>(bb);
286
            ei.kingAdjacentZoneAttacksCount[Us] += popcount(b & ei.attackedBy[Them][KING]);
281
        }
287
        }
282
 
288
 
283
        if (Pt == QUEEN)
289
        if (Pt == QUEEN)
284
            b &= ~(  ei.attackedBy[Them][KNIGHT]
290
            b &= ~(  ei.attackedBy[Them][KNIGHT]
285
                   | ei.attackedBy[Them][BISHOP]
291
                   | ei.attackedBy[Them][BISHOP]
286
                   | ei.attackedBy[Them][ROOK]);
292
                   | ei.attackedBy[Them][ROOK]);
287
 
293
 
288
        int mob = popcount<Pt == QUEEN ? Full : Max15>(b & mobilityArea[Us]);
294
        int mob = popcount(b & mobilityArea[Us]);
289
 
295
 
290
        mobility[Us] += MobilityBonus[Pt][mob];
296
        mobility[Us] += MobilityBonus[Pt][mob];
291
 
297
 
292
        if (Pt == BISHOP || Pt == KNIGHT)
298
        if (Pt == BISHOP || Pt == KNIGHT)
293
        {
299
        {
Line 316... Line 322...
316
            // when that pawn is also blocked.
322
            // when that pawn is also blocked.
317
            if (   Pt == BISHOP
323
            if (   Pt == BISHOP
318
                && pos.is_chess960()
324
                && pos.is_chess960()
319
                && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
325
                && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
320
            {
326
            {
321
                Square d = pawn_push(Us) + (file_of(s) == FILE_A ? DELTA_E : DELTA_W);
327
                Square d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
322
                if (pos.piece_on(s + d) == make_piece(Us, PAWN))
328
                if (pos.piece_on(s + d) == make_piece(Us, PAWN))
323
                    score -= !pos.empty(s + d + pawn_push(Us))                ? TrappedBishopA1H1 * 4
329
                    score -= !pos.empty(s + d + pawn_push(Us))                ? TrappedBishopA1H1 * 4
324
                            : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? TrappedBishopA1H1 * 2
330
                            : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? TrappedBishopA1H1 * 2
325
                                                                              : TrappedBishopA1H1;
331
                                                                              : TrappedBishopA1H1;
326
            }
332
            }
Line 328... Line 334...
328
 
334
 
329
        if (Pt == ROOK)
335
        if (Pt == ROOK)
330
        {
336
        {
331
            // Bonus for aligning with enemy pawns on the same rank/file
337
            // Bonus for aligning with enemy pawns on the same rank/file
332
            if (relative_rank(Us, s) >= RANK_5)
338
            if (relative_rank(Us, s) >= RANK_5)
333
            {
-
 
334
                Bitboard alignedPawns = pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s];
339
                score += RookOnPawn * popcount(pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s]);
335
                if (alignedPawns)
-
 
336
                    score += RookOnPawn * popcount<Max15>(alignedPawns);
-
 
337
            }
-
 
338
 
340
 
339
            // Bonus when on an open or semi-open file
341
            // Bonus when on an open or semi-open file
340
            if (ei.pi->semiopen_file(Us, file_of(s)))
342
            if (ei.pi->semiopen_file(Us, file_of(s)))
341
                score += RookOnFile[!!ei.pi->semiopen_file(Them, file_of(s))];
343
                score += RookOnFile[!!ei.pi->semiopen_file(Them, file_of(s))];
342
 
344
 
Line 348... Line 350...
348
                if (   ((file_of(ksq) < FILE_E) == (file_of(s) < file_of(ksq)))
350
                if (   ((file_of(ksq) < FILE_E) == (file_of(s) < file_of(ksq)))
349
                    && (rank_of(ksq) == rank_of(s) || relative_rank(Us, ksq) == RANK_1)
351
                    && (rank_of(ksq) == rank_of(s) || relative_rank(Us, ksq) == RANK_1)
350
                    && !ei.pi->semiopen_side(Us, file_of(ksq), file_of(s) < file_of(ksq)))
352
                    && !ei.pi->semiopen_side(Us, file_of(ksq), file_of(s) < file_of(ksq)))
351
                    score -= (TrappedRook - make_score(mob * 22, 0)) * (1 + !pos.can_castle(Us));
353
                    score -= (TrappedRook - make_score(mob * 22, 0)) * (1 + !pos.can_castle(Us));
352
            }
354
            }
-
 
355
        }
-
 
356
 
-
 
357
        if (Pt == QUEEN)
-
 
358
        {
-
 
359
            // Penalty if any relative pin or discovered attack against the queen
-
 
360
            Bitboard pinners;
-
 
361
            if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, pinners))
-
 
362
                score -= WeakQueen;
353
        }
363
        }
354
    }
364
    }
355
 
365
 
356
    if (DoTrace)
366
    if (DoTrace)
357
        Trace::add(Pt, Us, score);
367
        Trace::add(Pt, Us, score);
Line 365... Line 375...
365
  template<>
375
  template<>
366
  Score evaluate_pieces< true, WHITE, KING>(const Position&, EvalInfo&, Score*, const Bitboard*) { return SCORE_ZERO; }
376
  Score evaluate_pieces< true, WHITE, KING>(const Position&, EvalInfo&, Score*, const Bitboard*) { return SCORE_ZERO; }
367
 
377
 
368
 
378
 
369
  // evaluate_king() assigns bonuses and penalties to a king of a given color
379
  // evaluate_king() assigns bonuses and penalties to a king of a given color
-
 
380
 
-
 
381
  const Bitboard WhiteCamp = Rank1BB | Rank2BB | Rank3BB | Rank4BB | Rank5BB;
-
 
382
  const Bitboard BlackCamp = Rank8BB | Rank7BB | Rank6BB | Rank5BB | Rank4BB;
-
 
383
  const Bitboard QueenSide   = FileABB | FileBBB | FileCBB | FileDBB;
-
 
384
  const Bitboard CenterFiles = FileCBB | FileDBB | FileEBB | FileFBB;
-
 
385
  const Bitboard KingSide    = FileEBB | FileFBB | FileGBB | FileHBB;
-
 
386
 
-
 
387
  const Bitboard KingFlank[COLOR_NB][FILE_NB] = {
-
 
388
    { QueenSide   & WhiteCamp, QueenSide & WhiteCamp, QueenSide & WhiteCamp, CenterFiles & WhiteCamp,
-
 
389
      CenterFiles & WhiteCamp, KingSide  & WhiteCamp, KingSide  & WhiteCamp, KingSide    & WhiteCamp },
-
 
390
    { QueenSide   & BlackCamp, QueenSide & BlackCamp, QueenSide & BlackCamp, CenterFiles & BlackCamp,
-
 
391
      CenterFiles & BlackCamp, KingSide  & BlackCamp, KingSide  & BlackCamp, KingSide    & BlackCamp },
-
 
392
  };
370
 
393
 
371
  template<Color Us, bool DoTrace>
394
  template<Color Us, bool DoTrace>
372
  Score evaluate_king(const Position& pos, const EvalInfo& ei) {
395
  Score evaluate_king(const Position& pos, const EvalInfo& ei) {
373
 
396
 
374
    const Color Them = (Us == WHITE ? BLACK : WHITE);
397
    const Color Them = (Us == WHITE ? BLACK : WHITE);
-
 
398
    const Square  Up = (Us == WHITE ? NORTH : SOUTH);
375
 
399
 
376
    Bitboard undefended, b, b1, b2, safe;
400
    Bitboard undefended, b, b1, b2, safe, other;
377
    int attackUnits;
401
    int kingDanger;
378
    const Square ksq = pos.square<KING>(Us);
402
    const Square ksq = pos.square<KING>(Us);
379
 
403
 
380
    // King shelter and enemy pawns storm
404
    // King shelter and enemy pawns storm
381
    Score score = ei.pi->king_safety<Us>(pos, ksq);
405
    Score score = ei.pi->king_safety<Us>(pos, ksq);
382
 
406
 
383
    // Main king safety evaluation
407
    // Main king safety evaluation
384
    if (ei.kingAttackersCount[Them])
408
    if (ei.kingAttackersCount[Them])
385
    {
409
    {
386
        // Find the attacked squares around the king which have no defenders
410
        // Find the attacked squares which are defended only by the king...
387
        // apart from the king itself.
-
 
388
        undefended =  ei.attackedBy[Them][ALL_PIECES]
411
        undefended =   ei.attackedBy[Them][ALL_PIECES]
389
                    & ei.attackedBy[Us][KING]
412
                    &  ei.attackedBy[Us][KING]
390
                    & ~(  ei.attackedBy[Us][PAWN]   | ei.attackedBy[Us][KNIGHT]
-
 
391
                        | ei.attackedBy[Us][BISHOP] | ei.attackedBy[Us][ROOK]
-
 
392
                        | ei.attackedBy[Us][QUEEN]);
413
                    & ~ei.attackedBy2[Us];
393
 
414
 
-
 
415
        // ... and those which are not defended at all in the larger king ring
-
 
416
        b =  ei.attackedBy[Them][ALL_PIECES] & ~ei.attackedBy[Us][ALL_PIECES]
-
 
417
           & ei.kingRing[Us] & ~pos.pieces(Them);
-
 
418
 
394
        // Initialize the 'attackUnits' variable, which is used later on as an
419
        // Initialize the 'kingDanger' variable, which will be transformed
395
        // index into the KingDanger[] array. The initial value is based on the
420
        // later into a king danger score. The initial value is based on the
396
        // number and types of the enemy's attacking pieces, the number of
421
        // number and types of the enemy's attacking pieces, the number of
397
        // attacked and undefended squares around our king and the quality of
422
        // attacked and undefended squares around our king and the quality of
398
        // the pawn shelter (current 'score' value).
423
        // the pawn shelter (current 'score' value).
399
        attackUnits =  std::min(72, ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them])
424
        kingDanger =  std::min(807, ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them])
400
                     +  9 * ei.kingAdjacentZoneAttacksCount[Them]
425
                    + 101 * ei.kingAdjacentZoneAttacksCount[Them]
401
                     + 27 * popcount<Max15>(undefended)
426
                    + 235 * popcount(undefended)
402
                     + 11 * !!ei.pinnedPieces[Us]
427
                    + 134 * (popcount(b) + !!ei.pinnedPieces[Us])
403
                     - 64 * !pos.count<QUEEN>(Them)
428
                    - 717 * !pos.count<QUEEN>(Them)
404
                     - mg_value(score) / 8;
429
                    -   7 * mg_value(score) / 5 - 5;
405
 
430
 
406
        // Analyse the enemy's safe queen contact checks. Firstly, find the
431
        // Analyse the enemy's safe queen contact checks. Firstly, find the
407
        // undefended squares around the king reachable by the enemy queen...
432
        // undefended squares around the king reachable by the enemy queen...
408
        b = undefended & ei.attackedBy[Them][QUEEN] & ~pos.pieces(Them);
433
        b = undefended & ei.attackedBy[Them][QUEEN] & ~pos.pieces(Them);
409
        if (b)
-
 
410
        {
-
 
411
            // ...and then remove squares not supported by another enemy piece
-
 
412
            b &=  ei.attackedBy[Them][PAWN]   | ei.attackedBy[Them][KNIGHT]
-
 
413
                | ei.attackedBy[Them][BISHOP] | ei.attackedBy[Them][ROOK]
-
 
414
                | ei.attackedBy[Them][KING];
-
 
415
 
434
 
416
            if (b)
435
        // ...and keep squares supported by another enemy piece
417
                attackUnits += QueenContactCheck * popcount<Max15>(b);
436
        kingDanger += QueenContactCheck * popcount(b & ei.attackedBy2[Them]);
418
        }
-
 
419
 
437
 
420
        // Analyse the enemy's safe distance checks for sliders and knights
438
        // Analyse the safe enemy's checks which are possible on next move...
421
        safe = ~(ei.attackedBy[Us][ALL_PIECES] | pos.pieces(Them));
439
        safe  = ~(ei.attackedBy[Us][ALL_PIECES] | pos.pieces(Them));
422
 
440
 
-
 
441
        // ... and some other potential checks, only requiring the square to be
-
 
442
        // safe from pawn-attacks, and not being occupied by a blocked pawn.
-
 
443
        other = ~(   ei.attackedBy[Us][PAWN]
-
 
444
                  | (pos.pieces(Them, PAWN) & shift<Up>(pos.pieces(PAWN))));
-
 
445
 
423
        b1 = pos.attacks_from<ROOK  >(ksq) & safe;
446
        b1 = pos.attacks_from<ROOK  >(ksq);
424
        b2 = pos.attacks_from<BISHOP>(ksq) & safe;
447
        b2 = pos.attacks_from<BISHOP>(ksq);
425
 
448
 
426
        // Enemy queen safe checks
449
        // Enemy queen safe checks
427
        b = (b1 | b2) & ei.attackedBy[Them][QUEEN];
450
        if ((b1 | b2) & ei.attackedBy[Them][QUEEN] & safe)
428
        if (b)
-
 
429
        {
-
 
430
            attackUnits += QueenCheck * popcount<Max15>(b);
451
            kingDanger += QueenCheck, score -= SafeCheck;
431
            score -= Checked;
-
 
432
        }
-
 
433
 
452
 
-
 
453
        // For other pieces, also consider the square safe if attacked twice,
434
        // Enemy rooks safe checks
454
        // and only defended by a queen.
435
        b = b1 & ei.attackedBy[Them][ROOK];
455
        safe |=  ei.attackedBy2[Them]
436
        if (b)
-
 
437
        {
-
 
438
            attackUnits += RookCheck * popcount<Max15>(b);
456
               & ~(ei.attackedBy2[Us] | pos.pieces(Them))
439
            score -= Checked;
457
               & ei.attackedBy[Us][QUEEN];
440
        }
-
 
441
 
458
 
442
        // Enemy bishops safe checks
459
        // Enemy rooks safe and other checks
443
        b = b2 & ei.attackedBy[Them][BISHOP];
460
        if (b1 & ei.attackedBy[Them][ROOK] & safe)
444
        if (b)
-
 
445
        {
-
 
446
            attackUnits += BishopCheck * popcount<Max15>(b);
461
            kingDanger += RookCheck, score -= SafeCheck;
447
            score -= Checked;
-
 
448
        }
-
 
449
 
462
 
450
        // Enemy knights safe checks
-
 
451
        b = pos.attacks_from<KNIGHT>(ksq) & ei.attackedBy[Them][KNIGHT] & safe;
463
        else if (b1 & ei.attackedBy[Them][ROOK] & other)
452
        if (b)
-
 
453
        {
-
 
454
            attackUnits += KnightCheck * popcount<Max15>(b);
-
 
455
            score -= Checked;
464
            score -= OtherCheck;
456
        }
-
 
457
 
465
 
-
 
466
        // Enemy bishops safe and other checks
-
 
467
        if (b2 & ei.attackedBy[Them][BISHOP] & safe)
458
        // Finally, extract the king danger score from the KingDanger[]
468
            kingDanger += BishopCheck, score -= SafeCheck;
-
 
469
 
-
 
470
        else if (b2 & ei.attackedBy[Them][BISHOP] & other)
-
 
471
            score -= OtherCheck;
-
 
472
 
-
 
473
        // Enemy knights safe and other checks
-
 
474
        b = pos.attacks_from<KNIGHT>(ksq) & ei.attackedBy[Them][KNIGHT];
-
 
475
        if (b & safe)
-
 
476
            kingDanger += KnightCheck, score -= SafeCheck;
-
 
477
 
-
 
478
        else if (b & other)
-
 
479
            score -= OtherCheck;
-
 
480
 
459
        // array and subtract the score from the evaluation.
481
        // Compute the king danger score and subtract it from the evaluation
-
 
482
        if (kingDanger > 0)
460
        score -= KingDanger[std::max(std::min(attackUnits, 399), 0)];
483
            score -= make_score(std::min(kingDanger * kingDanger / 4096,  2 * int(BishopValueMg)), 0);
461
    }
484
    }
-
 
485
 
-
 
486
    // King tropism: firstly, find squares that opponent attacks in our king flank
-
 
487
    File kf = file_of(ksq);
-
 
488
    b = ei.attackedBy[Them][ALL_PIECES] & KingFlank[Us][kf];
-
 
489
 
-
 
490
    assert(((Us == WHITE ? b << 4 : b >> 4) & b) == 0);
-
 
491
    assert(popcount(Us == WHITE ? b << 4 : b >> 4) == popcount(b));
-
 
492
 
-
 
493
    // Secondly, add the squares which are attacked twice in that flank and
-
 
494
    // which are not defended by our pawns.
-
 
495
    b =  (Us == WHITE ? b << 4 : b >> 4)
-
 
496
       | (b & ei.attackedBy2[Them] & ~ei.attackedBy[Us][PAWN]);
-
 
497
 
-
 
498
    score -= CloseEnemies * popcount(b);
-
 
499
 
-
 
500
    // Penalty when our king is on a pawnless flank
-
 
501
    if (!(pos.pieces(PAWN) & (KingFlank[WHITE][kf] | KingFlank[BLACK][kf])))
-
 
502
        score -= PawnlessFlank;
462
 
503
 
463
    if (DoTrace)
504
    if (DoTrace)
464
        Trace::add(KING, Us, score);
505
        Trace::add(KING, Us, score);
465
 
506
 
466
    return score;
507
    return score;
467
  }
508
  }
468
 
509
 
469
 
510
 
470
  // evaluate_threats() assigns bonuses according to the types of the attacking 
511
  // evaluate_threats() assigns bonuses according to the types of the attacking
471
  // and the attacked pieces.
512
  // and the attacked pieces.
472
 
513
 
473
  template<Color Us, bool DoTrace>
514
  template<Color Us, bool DoTrace>
474
  Score evaluate_threats(const Position& pos, const EvalInfo& ei) {
515
  Score evaluate_threats(const Position& pos, const EvalInfo& ei) {
475
 
516
 
476
    const Color Them        = (Us == WHITE ? BLACK    : WHITE);
517
    const Color Them        = (Us == WHITE ? BLACK      : WHITE);
477
    const Square Up         = (Us == WHITE ? DELTA_N  : DELTA_S);
518
    const Square Up         = (Us == WHITE ? NORTH      : SOUTH);
478
    const Square Left       = (Us == WHITE ? DELTA_NW : DELTA_SE);
519
    const Square Left       = (Us == WHITE ? NORTH_WEST : SOUTH_EAST);
479
    const Square Right      = (Us == WHITE ? DELTA_NE : DELTA_SW);
520
    const Square Right      = (Us == WHITE ? NORTH_EAST : SOUTH_WEST);
480
    const Bitboard TRank2BB = (Us == WHITE ? Rank2BB  : Rank7BB);
521
    const Bitboard TRank2BB = (Us == WHITE ? Rank2BB    : Rank7BB);
481
    const Bitboard TRank7BB = (Us == WHITE ? Rank7BB  : Rank2BB);
522
    const Bitboard TRank7BB = (Us == WHITE ? Rank7BB    : Rank2BB);
482
 
523
 
483
    enum { Minor, Rook };
524
    enum { Minor, Rook };
484
 
525
 
485
    Bitboard b, weak, defended, safeThreats;
526
    Bitboard b, weak, defended, safeThreats;
486
    Score score = SCORE_ZERO;
527
    Score score = SCORE_ZERO;
-
 
528
 
-
 
529
    // Small bonus if the opponent has loose pawns or pieces
-
 
530
    if (   (pos.pieces(Them) ^ pos.pieces(Them, QUEEN, KING))
-
 
531
        & ~(ei.attackedBy[Us][ALL_PIECES] | ei.attackedBy[Them][ALL_PIECES]))
-
 
532
        score += LooseEnemies;
487
 
533
 
488
    // Non-pawn enemies attacked by a pawn
534
    // Non-pawn enemies attacked by a pawn
489
    weak = (pos.pieces(Them) ^ pos.pieces(Them, PAWN)) & ei.attackedBy[Us][PAWN];
535
    weak = (pos.pieces(Them) ^ pos.pieces(Them, PAWN)) & ei.attackedBy[Us][PAWN];
490
 
536
 
491
    if (weak)
537
    if (weak)
492
    {
538
    {
493
        b = pos.pieces(Us, PAWN) & ( ~ei.attackedBy[Them][ALL_PIECES]
539
        b = pos.pieces(Us, PAWN) & ( ~ei.attackedBy[Them][ALL_PIECES]
494
                                    | ei.attackedBy[Us][ALL_PIECES]);
540
                                    | ei.attackedBy[Us][ALL_PIECES]);
495
 
541
 
496
        safeThreats = (shift_bb<Right>(b) | shift_bb<Left>(b)) & weak;
542
        safeThreats = (shift<Right>(b) | shift<Left>(b)) & weak;
497
 
543
 
498
        if (weak ^ safeThreats)
544
        if (weak ^ safeThreats)
499
            score += ThreatByHangingPawn;
545
            score += ThreatByHangingPawn;
500
 
546
 
501
        while (safeThreats)
547
        while (safeThreats)
Line 519... Line 565...
519
 
565
 
520
        b = (pos.pieces(Them, QUEEN) | weak) & ei.attackedBy[Us][ROOK];
566
        b = (pos.pieces(Them, QUEEN) | weak) & ei.attackedBy[Us][ROOK];
521
        while (b)
567
        while (b)
522
            score += Threat[Rook ][type_of(pos.piece_on(pop_lsb(&b)))];
568
            score += Threat[Rook ][type_of(pos.piece_on(pop_lsb(&b)))];
523
 
569
 
524
        b = weak & ~ei.attackedBy[Them][ALL_PIECES];
570
        score += Hanging * popcount(weak & ~ei.attackedBy[Them][ALL_PIECES]);
525
        if (b)
-
 
526
            score += Hanging * popcount<Max15>(b);
-
 
527
 
571
 
528
        b = weak & ei.attackedBy[Us][KING];
572
        b = weak & ei.attackedBy[Us][KING];
529
        if (b)
573
        if (b)
530
            score += ThreatByKing[more_than_one(b)];
574
            score += ThreatByKing[more_than_one(b)];
531
    }
575
    }
532
 
576
 
533
    // Bonus if some pawns can safely push and attack an enemy piece
577
    // Bonus if some pawns can safely push and attack an enemy piece
534
    b = pos.pieces(Us, PAWN) & ~TRank7BB;
578
    b = pos.pieces(Us, PAWN) & ~TRank7BB;
535
    b = shift_bb<Up>(b | (shift_bb<Up>(b & TRank2BB) & ~pos.pieces()));
579
    b = shift<Up>(b | (shift<Up>(b & TRank2BB) & ~pos.pieces()));
536
 
580
 
537
    b &=  ~pos.pieces()
581
    b &=  ~pos.pieces()
538
        & ~ei.attackedBy[Them][PAWN]
582
        & ~ei.attackedBy[Them][PAWN]
539
        & (ei.attackedBy[Us][ALL_PIECES] | ~ei.attackedBy[Them][ALL_PIECES]);
583
        & (ei.attackedBy[Us][ALL_PIECES] | ~ei.attackedBy[Them][ALL_PIECES]);
540
 
584
 
541
    b =  (shift_bb<Left>(b) | shift_bb<Right>(b))
585
    b =  (shift<Left>(b) | shift<Right>(b))
542
       &  pos.pieces(Them)
586
       &  pos.pieces(Them)
543
       & ~ei.attackedBy[Us][PAWN];
587
       & ~ei.attackedBy[Us][PAWN];
544
 
588
 
545
    if (b)
-
 
546
        score += ThreatByPawnPush * popcount<Max15>(b);
589
    score += ThreatByPawnPush * popcount(b);
547
 
590
 
548
    if (DoTrace)
591
    if (DoTrace)
549
        Trace::add(THREAT, Us, score);
592
        Trace::add(THREAT, Us, score);
550
 
593
 
551
    return score;
594
    return score;
Line 557... Line 600...
557
  template<Color Us, bool DoTrace>
600
  template<Color Us, bool DoTrace>
558
  Score evaluate_passed_pawns(const Position& pos, const EvalInfo& ei) {
601
  Score evaluate_passed_pawns(const Position& pos, const EvalInfo& ei) {
559
 
602
 
560
    const Color Them = (Us == WHITE ? BLACK : WHITE);
603
    const Color Them = (Us == WHITE ? BLACK : WHITE);
561
 
604
 
562
    Bitboard b, squaresToQueen, defendedSquares, unsafeSquares;
605
    Bitboard b, bb, squaresToQueen, defendedSquares, unsafeSquares;
563
    Score score = SCORE_ZERO;
606
    Score score = SCORE_ZERO;
564
 
607
 
565
    b = ei.pi->passed_pawns(Us);
608
    b = ei.pi->passed_pawns(Us);
566
 
609
 
567
    while (b)
610
    while (b)
568
    {
611
    {
569
        Square s = pop_lsb(&b);
612
        Square s = pop_lsb(&b);
570
 
613
 
571
        assert(pos.pawn_passed(Us, s));
614
        assert(pos.pawn_passed(Us, s));
-
 
615
        assert(!(pos.pieces(PAWN) & forward_bb(Us, s)));
-
 
616
 
-
 
617
        bb = forward_bb(Us, s) & (ei.attackedBy[Them][ALL_PIECES] | pos.pieces(Them));
-
 
618
        score -= HinderPassedPawn * popcount(bb);
572
 
619
 
573
        int r = relative_rank(Us, s) - RANK_2;
620
        int r = relative_rank(Us, s) - RANK_2;
574
        int rr = r * (r - 1);
621
        int rr = r * (r - 1);
575
 
622
 
576
        Value mbonus = Passed[MG][r], ebonus = Passed[EG][r];
623
        Value mbonus = Passed[MG][r], ebonus = Passed[EG][r];
Line 593... Line 640...
593
                // If there is a rook or queen attacking/defending the pawn from behind,
640
                // If there is a rook or queen attacking/defending the pawn from behind,
594
                // consider all the squaresToQueen. Otherwise consider only the squares
641
                // consider all the squaresToQueen. Otherwise consider only the squares
595
                // in the pawn's path attacked or occupied by the enemy.
642
                // in the pawn's path attacked or occupied by the enemy.
596
                defendedSquares = unsafeSquares = squaresToQueen = forward_bb(Us, s);
643
                defendedSquares = unsafeSquares = squaresToQueen = forward_bb(Us, s);
597
 
644
 
598
                Bitboard bb = forward_bb(Them, s) & pos.pieces(ROOK, QUEEN) & pos.attacks_from<ROOK>(s);
645
                bb = forward_bb(Them, s) & pos.pieces(ROOK, QUEEN) & pos.attacks_from<ROOK>(s);
599
 
646
 
600
                if (!(pos.pieces(Us) & bb))
647
                if (!(pos.pieces(Us) & bb))
601
                    defendedSquares &= ei.attackedBy[Us][ALL_PIECES];
648
                    defendedSquares &= ei.attackedBy[Us][ALL_PIECES];
602
 
649
 
603
                if (!(pos.pieces(Them) & bb))
650
                if (!(pos.pieces(Them) & bb))
Line 613... Line 660...
613
                    k += 6;
660
                    k += 6;
614
 
661
 
615
                else if (defendedSquares & blockSq)
662
                else if (defendedSquares & blockSq)
616
                    k += 4;
663
                    k += 4;
617
 
664
 
618
                mbonus += k * rr * 3 / 4, ebonus += k * rr;
665
                mbonus += k * rr, ebonus += k * rr;
619
            }
666
            }
620
            else if (pos.pieces(Us) & blockSq)
667
            else if (pos.pieces(Us) & blockSq)
621
                mbonus += (rr * 3 + r * 2 + 3) * 3 / 4, ebonus += rr + r * 2;
668
                mbonus += rr + r * 2, ebonus += rr + r * 2;
622
        } // rr != 0
669
        } // rr != 0
623
 
-
 
624
        if (pos.count<PAWN>(Us) < pos.count<PAWN>(Them))
-
 
625
            ebonus += ebonus / 4;
-
 
626
 
670
 
627
        score += make_score(mbonus, ebonus) + PassedFile[file_of(s)];
671
        score += make_score(mbonus, ebonus) + PassedFile[file_of(s)];
628
    }
672
    }
629
 
673
 
630
    if (DoTrace)
674
    if (DoTrace)
Line 664... Line 708...
664
 
708
 
665
    // Since SpaceMask[Us] is fully on our half of the board...
709
    // Since SpaceMask[Us] is fully on our half of the board...
666
    assert(unsigned(safe >> (Us == WHITE ? 32 : 0)) == 0);
710
    assert(unsigned(safe >> (Us == WHITE ? 32 : 0)) == 0);
667
 
711
 
668
    // ...count safe + (behind & safe) with a single popcount
712
    // ...count safe + (behind & safe) with a single popcount
669
    int bonus = popcount<Full>((Us == WHITE ? safe << 32 : safe >> 32) | (behind & safe));
713
    int bonus = popcount((Us == WHITE ? safe << 32 : safe >> 32) | (behind & safe));
670
    int weight =  pos.count<KNIGHT>(Us) + pos.count<BISHOP>(Us)
714
    bonus = std::min(16, bonus);
671
                + pos.count<KNIGHT>(Them) + pos.count<BISHOP>(Them);
715
    int weight = pos.count<ALL_PIECES>(Us) - 2 * ei.pi->open_files();
672
 
716
 
673
    return make_score(bonus * weight * weight * 2 / 11, 0);
717
    return make_score(bonus * weight * weight / 18, 0);
674
  }
718
  }
675
 
719
 
676
 
720
 
677
  // evaluate_initiative() computes the initiative correction value for the
721
  // evaluate_initiative() computes the initiative correction value for the
678
  // position, i.e., second order bonus/malus based on the known attacking/defending
722
  // position, i.e., second order bonus/malus based on the known attacking/defending
679
  // status of the players.
723
  // status of the players.
680
  Score evaluate_initiative(const Position& pos, int asymmetry, Value eg) {
724
  Score evaluate_initiative(const Position& pos, int asymmetry, Value eg) {
681
 
725
 
682
    int kingDistance = distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
726
    int kingDistance =  distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
-
 
727
                      - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
683
    int pawns = pos.count<PAWN>(WHITE) + pos.count<PAWN>(BLACK);
728
    int pawns = pos.count<PAWN>(WHITE) + pos.count<PAWN>(BLACK);
684
 
729
 
685
    // Compute the initiative bonus for the attacking side
730
    // Compute the initiative bonus for the attacking side
686
    int initiative = 8 * (pawns + asymmetry + kingDistance - 15);
731
    int initiative = 8 * (asymmetry + kingDistance - 15) + 12 * pawns;
687
 
732
 
688
    // Now apply the bonus: note that we find the attacking side by extracting
733
    // Now apply the bonus: note that we find the attacking side by extracting
689
    // the sign of the endgame value, and that we carefully cap the bonus so
734
    // the sign of the endgame value, and that we carefully cap the bonus so
690
    // that the endgame score will never be divided by more than two.
735
    // that the endgame score will never be divided by more than two.
691
    int value = ((eg > 0) - (eg < 0)) * std::max(initiative, -abs(eg / 2));
736
    int value = ((eg > 0) - (eg < 0)) * std::max(initiative, -abs(eg / 2));
Line 693... Line 738...
693
    return make_score(0, value);
738
    return make_score(0, value);
694
  }
739
  }
695
 
740
 
696
 
741
 
697
  // evaluate_scale_factor() computes the scale factor for the winning side
742
  // evaluate_scale_factor() computes the scale factor for the winning side
698
  ScaleFactor evaluate_scale_factor(const Position& pos, const EvalInfo& ei, Score score) {
743
  ScaleFactor evaluate_scale_factor(const Position& pos, const EvalInfo& ei, Value eg) {
699
 
744
 
700
    Color strongSide = eg_value(score) > VALUE_DRAW ? WHITE : BLACK;
745
    Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
701
    ScaleFactor sf = ei.me->scale_factor(pos, strongSide);
746
    ScaleFactor sf = ei.me->scale_factor(pos, strongSide);
702
 
747
 
703
    // If we don't already have an unusual scale factor, check for certain
748
    // If we don't already have an unusual scale factor, check for certain
704
    // types of endgames, and use a lower scale for those.
749
    // types of endgames, and use a lower scale for those.
705
    if (    ei.me->game_phase() < PHASE_MIDGAME
750
    if (    ei.me->game_phase() < PHASE_MIDGAME
Line 714... Line 759...
714
                sf = more_than_one(pos.pieces(PAWN)) ? ScaleFactor(31) : ScaleFactor(9);
759
                sf = more_than_one(pos.pieces(PAWN)) ? ScaleFactor(31) : ScaleFactor(9);
715
 
760
 
716
            // Endgame with opposite-colored bishops, but also other pieces. Still
761
            // Endgame with opposite-colored bishops, but also other pieces. Still
717
            // a bit drawish, but not as drawish as with only the two bishops.
762
            // a bit drawish, but not as drawish as with only the two bishops.
718
            else
763
            else
719
                sf = ScaleFactor(46 * sf / SCALE_FACTOR_NORMAL);
764
                sf = ScaleFactor(46);
720
        }
765
        }
721
        // Endings where weaker side can place his king in front of the opponent's
766
        // Endings where weaker side can place his king in front of the opponent's
722
        // pawns are drawish.
767
        // pawns are drawish.
723
        else if (    abs(eg_value(score)) <= BishopValueEg
768
        else if (    abs(eg) <= BishopValueEg
724
                 &&  ei.pi->pawn_span(strongSide) <= 1
769
                 &&  pos.count<PAWN>(strongSide) <= 2
725
                 && !pos.pawn_passed(~strongSide, pos.square<KING>(~strongSide)))
770
                 && !pos.pawn_passed(~strongSide, pos.square<KING>(~strongSide)))
726
            sf = ei.pi->pawn_span(strongSide) ? ScaleFactor(51) : ScaleFactor(37);
771
            sf = ScaleFactor(37 + 7 * pos.count<PAWN>(strongSide));
727
    }
772
    }
728
 
773
 
729
    return sf;
774
    return sf;
730
  }
775
  }
731
 
776
 
Line 738... Line 783...
738
template<bool DoTrace>
783
template<bool DoTrace>
739
Value Eval::evaluate(const Position& pos) {
784
Value Eval::evaluate(const Position& pos) {
740
 
785
 
741
  assert(!pos.checkers());
786
  assert(!pos.checkers());
742
 
787
 
-
 
788
  Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
743
  EvalInfo ei;
789
  EvalInfo ei;
744
  Score score, mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
-
 
745
 
-
 
746
  // Initialize score by reading the incrementally updated scores included in
-
 
747
  // the position object (material + piece square tables). Score is computed
-
 
748
  // internally from the white point of view.
-
 
749
  score = pos.psq_score();
-
 
750
 
790
 
751
  // Probe the material hash table
791
  // Probe the material hash table
752
  ei.me = Material::probe(pos);
792
  ei.me = Material::probe(pos);
753
  score += ei.me->imbalance();
-
 
754
 
793
 
755
  // If we have a specialized evaluation function for the current material
794
  // If we have a specialized evaluation function for the current material
756
  // configuration, call it and return.
795
  // configuration, call it and return.
757
  if (ei.me->specialized_eval_exists())
796
  if (ei.me->specialized_eval_exists())
758
      return ei.me->evaluate(pos);
797
      return ei.me->evaluate(pos);
-
 
798
 
-
 
799
  // Initialize score by reading the incrementally updated scores included in
-
 
800
  // the position object (material + piece square tables) and the material
-
 
801
  // imbalance. Score is computed internally from the white point of view.
-
 
802
  Score score = pos.psq_score() + ei.me->imbalance();
759
 
803
 
760
  // Probe the pawn hash table
804
  // Probe the pawn hash table
761
  ei.pi = Pawns::probe(pos);
805
  ei.pi = Pawns::probe(pos);
762
  score += ei.pi->pawns_score();
806
  score += ei.pi->pawns_score();
763
 
807
 
764
  // Initialize attack and king safety bitboards
808
  // Initialize attack and king safety bitboards
765
  ei.attackedBy[WHITE][ALL_PIECES] = ei.attackedBy[BLACK][ALL_PIECES] = 0;
809
  ei.attackedBy[WHITE][ALL_PIECES] = ei.attackedBy[BLACK][ALL_PIECES] = 0;
-
 
810
  ei.attackedBy[WHITE][KING] = pos.attacks_from<KING>(pos.square<KING>(WHITE));
-
 
811
  ei.attackedBy[BLACK][KING] = pos.attacks_from<KING>(pos.square<KING>(BLACK));
766
  eval_init<WHITE>(pos, ei);
812
  eval_init<WHITE>(pos, ei);
767
  eval_init<BLACK>(pos, ei);
813
  eval_init<BLACK>(pos, ei);
768
 
814
 
769
  // Pawns blocked or on ranks 2 and 3 will be excluded from the mobility area
815
  // Pawns blocked or on ranks 2 and 3 will be excluded from the mobility area
770
  Bitboard blockedPawns[] = {
816
  Bitboard blockedPawns[] = {
771
    pos.pieces(WHITE, PAWN) & (shift_bb<DELTA_S>(pos.pieces()) | Rank2BB | Rank3BB),
817
    pos.pieces(WHITE, PAWN) & (shift<SOUTH>(pos.pieces()) | Rank2BB | Rank3BB),
772
    pos.pieces(BLACK, PAWN) & (shift_bb<DELTA_N>(pos.pieces()) | Rank7BB | Rank6BB)
818
    pos.pieces(BLACK, PAWN) & (shift<NORTH>(pos.pieces()) | Rank7BB | Rank6BB)
773
  };
819
  };
774
 
820
 
775
  // Do not include in mobility area squares protected by enemy pawns, or occupied
821
  // Do not include in mobility area squares protected by enemy pawns, or occupied
776
  // by our blocked pawns or king.
822
  // by our blocked pawns or king.
777
  Bitboard mobilityArea[] = {
823
  Bitboard mobilityArea[] = {
Line 814... Line 860...
814
 
860
 
815
  // Evaluate position potential for the winning side
861
  // Evaluate position potential for the winning side
816
  score += evaluate_initiative(pos, ei.pi->pawn_asymmetry(), eg_value(score));
862
  score += evaluate_initiative(pos, ei.pi->pawn_asymmetry(), eg_value(score));
817
 
863
 
818
  // Evaluate scale factor for the winning side
864
  // Evaluate scale factor for the winning side
819
  ScaleFactor sf = evaluate_scale_factor(pos, ei, score);
865
  ScaleFactor sf = evaluate_scale_factor(pos, ei, eg_value(score));
820
 
866
 
821
  // Interpolate between a middlegame and a (scaled by 'sf') endgame score
867
  // Interpolate between a middlegame and a (scaled by 'sf') endgame score
822
  Value v =  mg_value(score) * int(ei.me->game_phase())
868
  Value v =  mg_value(score) * int(ei.me->game_phase())
823
           + eg_value(score) * int(PHASE_MIDGAME - ei.me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
869
           + eg_value(score) * int(PHASE_MIDGAME - ei.me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
824
 
870
 
Line 876... Line 922...
876
     << "          Total | " << Term(TOTAL);
922
     << "          Total | " << Term(TOTAL);
877
 
923
 
878
  ss << "\nTotal Evaluation: " << to_cp(v) << " (white side)\n";
924
  ss << "\nTotal Evaluation: " << to_cp(v) << " (white side)\n";
879
 
925
 
880
  return ss.str();
926
  return ss.str();
881
}
-
 
882
 
-
 
883
 
-
 
884
/// init() computes evaluation weights, usually at startup
-
 
885
 
-
 
886
void Eval::init() {
-
 
887
 
-
 
888
  const int MaxSlope = 322;
-
 
889
  const int Peak = 47410;
-
 
890
  int t = 0;
-
 
891
 
-
 
892
  for (int i = 0; i < 400; ++i)
-
 
893
  {
-
 
894
      t = std::min(Peak, std::min(i * i - 16, t + MaxSlope));
-
 
895
      KingDanger[i] = make_score(t * 268 / 7700, 0);
-
 
896
  }
-
 
897
}
927
}