Subversion Repositories Games.Chess Giants

Rev

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

Rev 154 Rev 169
Line 4... Line 4...
4
  Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
4
  Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
5
  Copyright (C) 2015-2016 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
5
  Copyright (C) 2015-2018 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
6
 
6
 
7
  Stockfish is free software: you can redistribute it and/or modify
7
  Stockfish is free software: you can redistribute it and/or modify
8
  it under the terms of the GNU General Public License as published by
8
  it under the terms of the GNU General Public License as published by
9
  the Free Software Foundation, either version 3 of the License, or
9
  the Free Software Foundation, either version 3 of the License, or
10
  (at your option) any later version.
10
  (at your option) any later version.
Line 28... Line 28...
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 {
-
 
33
 
-
 
34
  const Bitboard Center      = (FileDBB | FileEBB) & (Rank4BB | Rank5BB);
-
 
35
  const Bitboard QueenSide   = FileABB | FileBBB | FileCBB | FileDBB;
-
 
36
  const Bitboard CenterFiles = FileCBB | FileDBB | FileEBB | FileFBB;
-
 
37
  const Bitboard KingSide    = FileEBB | FileFBB | FileGBB | FileHBB;
-
 
38
 
-
 
39
  const Bitboard KingFlank[FILE_NB] = {
-
 
40
    QueenSide, QueenSide, QueenSide, CenterFiles, CenterFiles, KingSide, KingSide, KingSide
-
 
41
  };
33
 
42
 
34
  namespace Trace {
43
  namespace Trace {
-
 
44
 
-
 
45
    enum Tracing {NO_TRACE, TRACE};
35
 
46
 
36
    enum Term { // The first 8 entries are for PieceType
47
    enum Term { // The first 8 entries are for PieceType
37
      MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, TOTAL, TERM_NB
48
      MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, INITIATIVE, TOTAL, TERM_NB
38
    };
49
    };
39
 
50
 
40
    double scores[TERM_NB][COLOR_NB][PHASE_NB];
51
    double scores[TERM_NB][COLOR_NB][PHASE_NB];
41
 
52
 
42
    double to_cp(Value v) { return double(v) / PawnValueEg; }
53
    double to_cp(Value v) { return double(v) / PawnValueEg; }
Line 50... Line 61...
50
      add(idx, WHITE, w); add(idx, BLACK, b);
61
      add(idx, WHITE, w); add(idx, BLACK, b);
51
    }
62
    }
52
 
63
 
53
    std::ostream& operator<<(std::ostream& os, Term t) {
64
    std::ostream& operator<<(std::ostream& os, Term t) {
54
 
65
 
55
      if (t == MATERIAL || t == IMBALANCE || t == Term(PAWN) || t == TOTAL)
66
      if (t == MATERIAL || t == IMBALANCE || t == Term(PAWN) || t == INITIATIVE || t == TOTAL)
56
          os << "  ---   --- |   ---   --- | ";
67
          os << "  ---   --- |   ---   --- | ";
57
      else
68
      else
58
          os << std::setw(5) << scores[t][WHITE][MG] << " "
69
          os << std::setw(5) << scores[t][WHITE][MG] << " "
59
             << std::setw(5) << scores[t][WHITE][EG] << " | "
70
             << std::setw(5) << scores[t][WHITE][EG] << " | "
60
             << std::setw(5) << scores[t][BLACK][MG] << " "
71
             << std::setw(5) << scores[t][BLACK][MG] << " "
Line 67... Line 78...
67
    }
78
    }
68
  }
79
  }
69
 
80
 
70
  using namespace Trace;
81
  using namespace Trace;
71
 
82
 
72
  // Struct EvalInfo contains various information computed and collected
83
  // Evaluation class contains various information computed and collected
73
  // by the evaluation functions.
84
  // by the evaluation functions.
-
 
85
  template<Tracing T = NO_TRACE>
74
  struct EvalInfo {
86
  class Evaluation {
-
 
87
 
-
 
88
  public:
-
 
89
    Evaluation() = delete;
-
 
90
    Evaluation(const Position& p) : pos(p) {}
-
 
91
    Evaluation& operator=(const Evaluation&) = delete;
-
 
92
 
-
 
93
    Value value();
-
 
94
 
-
 
95
  private:
-
 
96
    // Evaluation helpers (used when calling value())
-
 
97
    template<Color Us> void initialize();
-
 
98
    template<Color Us> Score evaluate_king();
-
 
99
    template<Color Us> Score evaluate_threats();
-
 
100
    int king_distance(Color c, Square s);
-
 
101
    template<Color Us> Score evaluate_passed_pawns();
-
 
102
    template<Color Us> Score evaluate_space();
-
 
103
    template<Color Us, PieceType Pt> Score evaluate_pieces();
-
 
104
    ScaleFactor evaluate_scale_factor(Value eg);
-
 
105
    Score evaluate_initiative(Value eg);
-
 
106
 
-
 
107
    // Data members
-
 
108
    const Position& pos;
-
 
109
    Material::Entry* me;
-
 
110
    Pawns::Entry* pe;
-
 
111
    Bitboard mobilityArea[COLOR_NB];
-
 
112
    Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
75
 
113
 
76
    // attackedBy[color][piece type] is a bitboard representing all squares
114
    // attackedBy[color][piece type] is a bitboard representing all squares
77
    // attacked by a given color and piece type (can be also ALL_PIECES).
115
    // attacked by a given color and piece type. Special "piece types" which are
-
 
116
    // also calculated are QUEEN_DIAGONAL and ALL_PIECES.
78
    Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
117
    Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
79
 
118
 
80
    // attackedBy2[color] are the squares attacked by 2 pieces of a given color,
119
    // 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
120
    // 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.
121
    // pawn or squares attacked by 2 pawns are not explicitly added.
83
    Bitboard attackedBy2[COLOR_NB];
122
    Bitboard attackedBy2[COLOR_NB];
84
 
123
 
85
    // kingRing[color] is the zone around the king which is considered
124
    // kingRing[color] is the zone around the king which is considered
86
    // by the king safety evaluation. This consists of the squares directly
125
    // by the king safety evaluation. This consists of the squares directly
87
    // adjacent to the king, and the three (or two, for a king on an edge file)
126
    // adjacent to the king, and (only for a king on its first rank) the
88
    // squares two ranks in front of the king. For instance, if black's king
127
    // squares two ranks in front of the king. For instance, if black's king
89
    // is on g8, kingRing[BLACK] is a bitboard containing the squares f8, h8,
128
    // is on g8, kingRing[BLACK] is a bitboard containing the squares f8, h8,
90
    // f7, g7, h7, f6, g6 and h6.
129
    // f7, g7, h7, f6, g6 and h6.
91
    Bitboard kingRing[COLOR_NB];
130
    Bitboard kingRing[COLOR_NB];
92
 
131
 
Line 104... Line 143...
104
    // color to squares directly adjacent to the enemy king. Pieces which attack
143
    // color to squares directly adjacent to the enemy king. Pieces which attack
105
    // more than one square are counted multiple times. For instance, if there is
144
    // more than one square are counted multiple times. For instance, if there is
106
    // a white knight on g5 and black's king is on g8, this white knight adds 2
145
    // a white knight on g5 and black's king is on g8, this white knight adds 2
107
    // to kingAdjacentZoneAttacksCount[WHITE].
146
    // to kingAdjacentZoneAttacksCount[WHITE].
108
    int kingAdjacentZoneAttacksCount[COLOR_NB];
147
    int kingAdjacentZoneAttacksCount[COLOR_NB];
109
 
-
 
110
    Bitboard pinnedPieces[COLOR_NB];
-
 
111
    Material::Entry* me;
-
 
112
    Pawns::Entry* pi;
-
 
113
  };
148
  };
114
 
149
 
115
  #define V(v) Value(v)
150
  #define V(v) Value(v)
116
  #define S(mg, eg) make_score(mg, eg)
151
  #define S(mg, eg) make_score(mg, eg)
117
 
152
 
118
  // MobilityBonus[PieceType][attacked] contains bonuses for middle and end
153
  // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
119
  // game, indexed by piece type and number of attacked squares in the MobilityArea.
154
  // indexed by piece type and number of attacked squares in the mobility area.
120
  const Score MobilityBonus[][32] = {
155
  const Score MobilityBonus[][32] = {
121
    {}, {},
-
 
122
    { S(-75,-76), S(-56,-54), S( -9,-26), S( -2,-10), S(  6,  5), S( 15, 11), // Knights
156
    { S(-75,-76), S(-57,-54), S( -9,-28), S( -2,-10), S(  6,  5), S( 14, 12), // Knights
123
      S( 22, 26), S( 30, 28), S( 36, 29) },
157
      S( 22, 26), S( 29, 29), S( 36, 29) },
124
    { S(-48,-58), S(-21,-19), S( 16, -2), S( 26, 12), S( 37, 22), S( 51, 42), // Bishops
158
    { S(-48,-59), S(-20,-23), S( 16, -3), S( 26, 13), S( 38, 24), S( 51, 42), // Bishops
125
      S( 54, 54), S( 63, 58), S( 65, 63), S( 71, 70), S( 79, 74), S( 81, 86),
159
      S( 55, 54), S( 63, 57), S( 63, 65), S( 68, 73), S( 81, 78), S( 81, 86),
126
      S( 92, 90), S( 97, 94) },
160
      S( 91, 88), S( 98, 97) },
127
    { S(-56,-78), S(-25,-18), S(-11, 26), S( -5, 55), S( -4, 70), S( -1, 81), // Rooks
161
    { S(-58,-76), S(-27,-18), S(-15, 28), S(-10, 55), S( -5, 69), S( -2, 82), // Rooks
128
      S(  8,109), S( 14,120), S( 21,128), S( 23,143), S( 31,154), S( 32,160),
162
      S(  9,112), S( 16,118), S( 30,132), S( 29,142), S( 32,155), S( 38,165),
129
      S( 43,165), S( 49,168), S( 59,169) },
163
      S( 46,166), S( 48,169), S( 58,171) },
130
    { S(-40,-35), S(-25,-12), S(  2,  7), S(  4, 19), S( 14, 37), S( 24, 55), // Queens
164
    { S(-39,-36), S(-21,-15), S(  3,  8), S(  3, 18), S( 14, 34), S( 22, 54), // Queens
131
      S( 25, 62), S( 40, 76), S( 43, 79), S( 47, 87), S( 54, 94), S( 56,102),
165
      S( 28, 61), S( 41, 73), S( 43, 79), S( 48, 92), S( 56, 94), S( 60,104),
132
      S( 60,111), S( 70,116), S( 72,118), S( 73,122), S( 75,128), S( 77,130),
166
      S( 60,113), S( 66,120), S( 67,123), S( 70,126), S( 71,133), S( 73,136),
133
      S( 85,133), S( 94,136), S( 99,140), S(108,157), S(112,158), S(113,161),
167
      S( 79,140), S( 88,143), S( 88,148), S( 99,166), S(102,170), S(102,175),
134
      S(118,174), S(119,177), S(123,191), S(128,199) }
168
      S(106,184), S(109,191), S(113,206), S(116,212) }
135
  };
169
  };
136
 
170
 
137
  // Outpost[knight/bishop][supported by pawn] contains bonuses for knights and
171
  // Outpost[knight/bishop][supported by pawn] contains bonuses for minor
138
  // bishops outposts, bigger if outpost piece is supported by a pawn.
172
  // pieces if they can reach an outpost square, bigger if that square is
-
 
173
  // supported by a pawn. If the minor piece occupies an outpost square
-
 
174
  // then score is doubled.
139
  const Score Outpost[][2] = {
175
  const Score Outpost[][2] = {
140
    { S(43,11), S(65,20) }, // Knights
-
 
141
    { S(20, 3), S(29, 8) }  // Bishops
-
 
142
  };
-
 
143
 
-
 
144
  // ReachableOutpost[knight/bishop][supported by pawn] contains bonuses for
-
 
145
  // knights and bishops which can reach an outpost square in one move, bigger
-
 
146
  // if outpost square is supported by a pawn.
-
 
147
  const Score ReachableOutpost[][2] = {
-
 
148
    { S(21, 5), S(35, 8) }, // Knights
176
    { S(22, 6), S(36,12) }, // Knight
149
    { S( 8, 0), S(14, 4) }  // Bishops
177
    { S( 9, 2), S(15, 5) }  // Bishop
150
  };
178
  };
151
 
179
 
152
  // RookOnFile[semiopen/open] contains bonuses for each rook when there is no
180
  // RookOnFile[semiopen/open] contains bonuses for each rook when there is no
153
  // friendly pawn on the rook file.
181
  // friendly pawn on the rook file.
154
  const Score RookOnFile[2] = { S(20, 7), S(45, 20) };
182
  const Score RookOnFile[] = { S(20, 7), S(45, 20) };
155
 
183
 
156
  // ThreatBySafePawn[PieceType] contains bonuses according to which piece
184
  // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
157
  // type is attacked by a pawn which is protected or is not attacked.
185
  // which piece type attacks which one. Attacks on lesser pieces which are
-
 
186
  // pawn-defended are not considered.
158
  const Score ThreatBySafePawn[PIECE_TYPE_NB] = {
187
  const Score ThreatByMinor[PIECE_TYPE_NB] = {
159
    S(0, 0), S(0, 0), S(176, 139), S(131, 127), S(217, 218), S(203, 215)
188
    S(0, 0), S(0, 33), S(45, 43), S(46, 47), S(72, 107), S(48, 118)
160
  };
189
  };
161
 
190
 
162
  // Threat[by minor/by rook][attacked PieceType] contains
-
 
163
  // bonuses according to which piece type attacks which one.
-
 
164
  // Attacks on lesser pieces which are pawn-defended are not considered.
-
 
165
  const Score Threat[][PIECE_TYPE_NB] = {
191
  const Score ThreatByRook[PIECE_TYPE_NB] = {
166
    { S(0, 0), S(0, 33), S(45, 43), S(46, 47), S(72,107), S(48,118) }, // by Minor
-
 
167
    { S(0, 0), S(0, 25), S(40, 62), S(40, 59), S( 0, 34), S(35, 48) }  // by Rook
192
    S(0, 0), S(0, 25), S(40, 62), S(40, 59), S(0, 34), S(35, 48)
168
  };
193
  };
169
 
194
 
170
  // ThreatByKing[on one/on many] contains bonuses for King attacks on
195
  // ThreatByKing[on one/on many] contains bonuses for king attacks on
171
  // pawns or pieces which are not pawn-defended.
196
  // pawns or pieces which are not pawn-defended.
172
  const Score ThreatByKing[2] = { S(3, 62), S(9, 138) };
197
  const Score ThreatByKing[] = { S(3, 62), S(9, 138) };
173
 
198
 
174
  // Passed[mg/eg][Rank] contains midgame and endgame bonuses for passed pawns.
199
  // Passed[mg/eg][Rank] contains midgame and endgame bonuses for passed pawns.
175
  // We don't use a Score because we process the two components independently.
200
  // We don't use a Score because we process the two components independently.
176
  const Value Passed[][RANK_NB] = {
201
  const Value Passed[][RANK_NB] = {
177
    { V(5), V( 5), V(31), V(73), V(166), V(252) },
202
    { V(0), V(5), V( 5), V(31), V(73), V(166), V(252) },
178
    { V(7), V(14), V(38), V(73), V(166), V(252) }
203
    { V(0), V(7), V(14), V(38), V(73), V(166), V(252) }
179
  };
204
  };
180
 
205
 
181
  // PassedFile[File] contains a bonus according to the file of a passed pawn
206
  // PassedFile[File] contains a bonus according to the file of a passed pawn
182
  const Score PassedFile[FILE_NB] = {
207
  const Score PassedFile[FILE_NB] = {
183
    S(  9, 10), S( 2, 10), S( 1, -8), S(-20,-12),
208
    S(  9, 10), S( 2, 10), S( 1, -8), S(-20,-12),
184
    S(-20,-12), S( 1, -8), S( 2, 10), S( 9, 10)
209
    S(-20,-12), S( 1, -8), S( 2, 10), S(  9, 10)
185
  };
210
  };
186
 
211
 
187
  // Assorted bonuses and penalties used by evaluation
212
  // Rank factor applied on some bonus for passed pawn on rank 4 or beyond
188
  const Score MinorBehindPawn     = S(16,  0);
-
 
189
  const Score BishopPawns         = S( 8, 12);
-
 
190
  const Score RookOnPawn          = S( 8, 24);
213
  const int RankFactor[RANK_NB] = {0, 0, 0, 2, 6, 11, 16};
191
  const Score TrappedRook         = S(92,  0);
-
 
192
  const Score CloseEnemies        = S( 7,  0);
-
 
193
  const Score SafeCheck           = S(20, 20);
-
 
194
  const Score OtherCheck          = S(10, 10);
-
 
195
  const Score ThreatByHangingPawn = S(71, 61);
-
 
196
  const Score LooseEnemies        = S( 0, 25);
-
 
197
  const Score WeakQueen           = S(35,  0);
-
 
198
  const Score Hanging             = S(48, 27);
-
 
199
  const Score ThreatByPawnPush    = S(38, 22);
-
 
200
  const Score Unstoppable         = S( 0, 20);
-
 
201
  const Score PawnlessFlank       = S(20, 80);
-
 
202
  const Score HinderPassedPawn    = S( 7,  0);
-
 
203
 
214
 
204
  // Penalty for a bishop on a1/h1 (a8/h8 for black) which is trapped by
215
  // KingProtector[PieceType-2] contains a bonus according to distance from king
-
 
216
  const Score KingProtector[] = { S(-3, -5), S(-4, -3), S(-3, 0), S(-1, 1) };
-
 
217
 
205
  // a friendly pawn on b2/g2 (b7/g7 for black). This can obviously only
218
  // Assorted bonuses and penalties used by evaluation
-
 
219
  const Score MinorBehindPawn       = S( 16,  0);
-
 
220
  const Score BishopPawns           = S(  8, 12);
-
 
221
  const Score LongRangedBishop      = S( 22,  0);
-
 
222
  const Score RookOnPawn            = S(  8, 24);
-
 
223
  const Score TrappedRook           = S( 92,  0);
-
 
224
  const Score WeakQueen             = S( 50, 10);
-
 
225
  const Score CloseEnemies          = S(  7,  0);
-
 
226
  const Score PawnlessFlank         = S( 20, 80);
-
 
227
  const Score ThreatBySafePawn      = S(192,175);
-
 
228
  const Score ThreatByRank          = S( 16,  3);
-
 
229
  const Score Hanging               = S( 48, 27);
206
  // happen in Chess960 games.
230
  const Score WeakUnopposedPawn     = S(  5, 25);
-
 
231
  const Score ThreatByPawnPush      = S( 38, 22);
-
 
232
  const Score ThreatByAttackOnQueen = S( 38, 22);
-
 
233
  const Score HinderPassedPawn      = S(  7,  0);
207
  const Score TrappedBishopA1H1 = S(50, 50);
234
  const Score TrappedBishopA1H1     = S( 50, 50);
208
 
235
 
209
  #undef S
236
  #undef S
210
  #undef V
237
  #undef V
211
 
238
 
212
  // KingAttackWeights[PieceType] contains king attack weights by piece type
239
  // KingAttackWeights[PieceType] contains king attack weights by piece type
213
  const int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 78, 56, 45, 11 };
240
  const int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 78, 56, 45, 11 };
214
 
241
 
215
  // Penalties for enemy's safe checks
242
  // Penalties for enemy's safe checks
216
  const int QueenContactCheck = 997;
243
  const int QueenSafeCheck  = 780;
217
  const int QueenCheck        = 695;
-
 
218
  const int RookCheck         = 638;
244
  const int RookSafeCheck   = 880;
219
  const int BishopCheck       = 538;
245
  const int BishopSafeCheck = 435;
220
  const int KnightCheck       = 874;
246
  const int KnightSafeCheck = 790;
221
 
247
 
-
 
248
  // Threshold for lazy and space evaluation
-
 
249
  const Value LazyThreshold  = Value(1500);
-
 
250
  const Value SpaceThreshold = Value(12222);
222
 
251
 
223
  // eval_init() initializes king and attack bitboards for a given color
-
 
224
  // adding pawn attacks. To be done at the beginning of the evaluation.
-
 
225
 
252
 
226
  template<Color Us>
253
  // initialize() computes king and pawn attacks, and the king ring bitboard
227
  void eval_init(const Position& pos, EvalInfo& ei) {
254
  // for a given color. This is done at the beginning of the evaluation.
228
 
255
 
229
    const Color  Them = (Us == WHITE ? BLACK : WHITE);
256
  template<Tracing T> template<Color Us>
230
    const Square Down = (Us == WHITE ? SOUTH : NORTH);
257
  void Evaluation<T>::initialize() {
231
 
258
 
232
    ei.pinnedPieces[Us] = pos.pinned_pieces(Us);
259
    const Color     Them = (Us == WHITE ? BLACK : WHITE);
233
    Bitboard b = ei.attackedBy[Them][KING];
260
    const Direction Up   = (Us == WHITE ? NORTH : SOUTH);
234
    ei.attackedBy[Them][ALL_PIECES] |= b;
261
    const Direction Down = (Us == WHITE ? SOUTH : NORTH);
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];
262
    const Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB: Rank7BB | Rank6BB);
237
 
263
 
-
 
264
    // Find our pawns on the first two ranks, and those which are blocked
-
 
265
    Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
-
 
266
 
-
 
267
    // Squares occupied by those pawns, by our king, or controlled by enemy pawns
-
 
268
    // are excluded from the mobility area.
-
 
269
    mobilityArea[Us] = ~(b | pos.square<KING>(Us) | pe->pawn_attacks(Them));
-
 
270
 
-
 
271
    // Initialise the attack bitboards with the king and pawn information
-
 
272
    b = attackedBy[Us][KING] = pos.attacks_from<KING>(pos.square<KING>(Us));
-
 
273
    attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
-
 
274
 
-
 
275
    attackedBy2[Us]            = b & attackedBy[Us][PAWN];
-
 
276
    attackedBy[Us][ALL_PIECES] = b | attackedBy[Us][PAWN];
-
 
277
 
238
    // Init king safety tables only if we are going to use them
278
    // Init our king safety tables only if we are going to use them
239
    if (pos.non_pawn_material(Us) >= QueenValueMg)
279
    if (pos.non_pawn_material(Them) >= RookValueMg + KnightValueMg)
240
    {
280
    {
241
        ei.kingRing[Them] = b | shift<Down>(b);
281
        kingRing[Us] = b;
-
 
282
        if (relative_rank(Us, pos.square<KING>(Us)) == RANK_1)
242
        b &= ei.attackedBy[Us][PAWN];
283
            kingRing[Us] |= shift<Up>(b);
-
 
284
 
243
        ei.kingAttackersCount[Us] = popcount(b);
285
        kingAttackersCount[Them] = popcount(b & pe->pawn_attacks(Them));
244
        ei.kingAdjacentZoneAttacksCount[Us] = ei.kingAttackersWeight[Us] = 0;
286
        kingAdjacentZoneAttacksCount[Them] = kingAttackersWeight[Them] = 0;
245
    }
287
    }
246
    else
288
    else
247
        ei.kingRing[Them] = ei.kingAttackersCount[Us] = 0;
289
        kingRing[Us] = kingAttackersCount[Them] = 0;
248
  }
290
  }
249
 
291
 
250
 
292
 
251
  // evaluate_pieces() assigns bonuses and penalties to the pieces of a given
293
  // evaluate_pieces() assigns bonuses and penalties to the pieces of a given
252
  // color and type.
294
  // color and type.
253
 
295
 
254
  template<bool DoTrace, Color Us = WHITE, PieceType Pt = KNIGHT>
296
  template<Tracing T>  template<Color Us, PieceType Pt>
255
  Score evaluate_pieces(const Position& pos, EvalInfo& ei, Score* mobility,
297
  Score Evaluation<T>::evaluate_pieces() {
256
                        const Bitboard* mobilityArea) {
-
 
257
    Bitboard b, bb;
-
 
258
    Square s;
-
 
259
    Score score = SCORE_ZERO;
-
 
260
 
298
 
261
    const PieceType NextPt = (Us == WHITE ? Pt : PieceType(Pt + 1));
-
 
262
    const Color Them = (Us == WHITE ? BLACK : WHITE);
299
    const Color Them = (Us == WHITE ? BLACK : WHITE);
263
    const Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
300
    const Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
264
                                               : Rank5BB | Rank4BB | Rank3BB);
301
                                               : Rank5BB | Rank4BB | Rank3BB);
265
    const Square* pl = pos.squares<Pt>(Us);
302
    const Square* pl = pos.squares<Pt>(Us);
266
 
303
 
-
 
304
    Bitboard b, bb;
-
 
305
    Square s;
-
 
306
    Score score = SCORE_ZERO;
-
 
307
 
267
    ei.attackedBy[Us][Pt] = 0;
308
    attackedBy[Us][Pt] = 0;
-
 
309
 
-
 
310
    if (Pt == QUEEN)
-
 
311
        attackedBy[Us][QUEEN_DIAGONAL] = 0;
268
 
312
 
269
    while ((s = *pl++) != SQ_NONE)
313
    while ((s = *pl++) != SQ_NONE)
270
    {
314
    {
271
        // Find attacked squares, including x-ray attacks for bishops and rooks
315
        // Find attacked squares, including x-ray attacks for bishops and rooks
272
        b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(Us, QUEEN))
316
        b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
273
          : Pt ==   ROOK ? attacks_bb<  ROOK>(s, pos.pieces() ^ pos.pieces(Us, ROOK, QUEEN))
317
          : Pt ==   ROOK ? attacks_bb<  ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
274
                         : pos.attacks_from<Pt>(s);
318
                         : pos.attacks_from<Pt>(s);
275
 
319
 
276
        if (ei.pinnedPieces[Us] & s)
320
        if (pos.pinned_pieces(Us) & s)
277
            b &= LineBB[pos.square<KING>(Us)][s];
321
            b &= LineBB[pos.square<KING>(Us)][s];
278
 
322
 
279
        ei.attackedBy2[Us] |= ei.attackedBy[Us][ALL_PIECES] & b;
323
        attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
280
        ei.attackedBy[Us][ALL_PIECES] |= ei.attackedBy[Us][Pt] |= b;
324
        attackedBy[Us][ALL_PIECES] |= attackedBy[Us][Pt] |= b;
281
 
325
 
-
 
326
        if (Pt == QUEEN)
-
 
327
            attackedBy[Us][QUEEN_DIAGONAL] |= b & PseudoAttacks[BISHOP][s];
-
 
328
 
282
        if (b & ei.kingRing[Them])
329
        if (b & kingRing[Them])
283
        {
330
        {
284
            ei.kingAttackersCount[Us]++;
331
            kingAttackersCount[Us]++;
285
            ei.kingAttackersWeight[Us] += KingAttackWeights[Pt];
332
            kingAttackersWeight[Us] += KingAttackWeights[Pt];
286
            ei.kingAdjacentZoneAttacksCount[Us] += popcount(b & ei.attackedBy[Them][KING]);
333
            kingAdjacentZoneAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
287
        }
334
        }
288
 
335
 
289
        if (Pt == QUEEN)
-
 
290
            b &= ~(  ei.attackedBy[Them][KNIGHT]
-
 
291
                   | ei.attackedBy[Them][BISHOP]
-
 
292
                   | ei.attackedBy[Them][ROOK]);
336
        int mob = popcount(b & mobilityArea[Us]);
293
 
337
 
294
        int mob = popcount(b & mobilityArea[Us]);
338
        mobility[Us] += MobilityBonus[Pt - 2][mob];
295
 
339
 
296
        mobility[Us] += MobilityBonus[Pt][mob];
340
        // Bonus for this piece as a king protector
-
 
341
        score += KingProtector[Pt - 2] * distance(s, pos.square<KING>(Us));
297
 
342
 
298
        if (Pt == BISHOP || Pt == KNIGHT)
343
        if (Pt == BISHOP || Pt == KNIGHT)
299
        {
344
        {
300
            // Bonus for outpost squares
345
            // Bonus for outpost squares
301
            bb = OutpostRanks & ~ei.pi->pawn_attacks_span(Them);
346
            bb = OutpostRanks & ~pe->pawn_attacks_span(Them);
302
            if (bb & s)
347
            if (bb & s)
303
                score += Outpost[Pt == BISHOP][!!(ei.attackedBy[Us][PAWN] & s)];
348
                score += Outpost[Pt == BISHOP][bool(attackedBy[Us][PAWN] & s)] * 2;
304
            else
349
            else
305
            {
350
            {
306
                bb &= b & ~pos.pieces(Us);
351
                bb &= b & ~pos.pieces(Us);
307
                if (bb)
352
                if (bb)
308
                   score += ReachableOutpost[Pt == BISHOP][!!(ei.attackedBy[Us][PAWN] & bb)];
353
                   score += Outpost[Pt == BISHOP][bool(attackedBy[Us][PAWN] & bb)];
309
            }
354
            }
310
 
355
 
311
            // Bonus when behind a pawn
356
            // Bonus when behind a pawn
312
            if (    relative_rank(Us, s) < RANK_5
357
            if (    relative_rank(Us, s) < RANK_5
313
                && (pos.pieces(PAWN) & (s + pawn_push(Us))))
358
                && (pos.pieces(PAWN) & (s + pawn_push(Us))))
314
                score += MinorBehindPawn;
359
                score += MinorBehindPawn;
315
 
360
 
316
            // Penalty for pawns on the same color square as the bishop
-
 
317
            if (Pt == BISHOP)
361
            if (Pt == BISHOP)
-
 
362
            {
-
 
363
                // Penalty for pawns on the same color square as the bishop
318
                score -= BishopPawns * ei.pi->pawns_on_same_color_squares(Us, s);
364
                score -= BishopPawns * pe->pawns_on_same_color_squares(Us, s);
-
 
365
 
-
 
366
                // Bonus for bishop on a long diagonal which can "see" both center squares
-
 
367
                if (more_than_one(Center & (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) | s)))
-
 
368
                    score += LongRangedBishop;
-
 
369
            }
319
 
370
 
320
            // An important Chess960 pattern: A cornered bishop blocked by a friendly
371
            // An important Chess960 pattern: A cornered bishop blocked by a friendly
321
            // pawn diagonally in front of it is a very serious problem, especially
372
            // pawn diagonally in front of it is a very serious problem, especially
322
            // when that pawn is also blocked.
373
            // when that pawn is also blocked.
323
            if (   Pt == BISHOP
374
            if (   Pt == BISHOP
324
                && pos.is_chess960()
375
                && pos.is_chess960()
325
                && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
376
                && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
326
            {
377
            {
327
                Square d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
378
                Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
328
                if (pos.piece_on(s + d) == make_piece(Us, PAWN))
379
                if (pos.piece_on(s + d) == make_piece(Us, PAWN))
329
                    score -= !pos.empty(s + d + pawn_push(Us))                ? TrappedBishopA1H1 * 4
380
                    score -= !pos.empty(s + d + pawn_push(Us))                ? TrappedBishopA1H1 * 4
330
                            : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? TrappedBishopA1H1 * 2
381
                            : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? TrappedBishopA1H1 * 2
331
                                                                              : TrappedBishopA1H1;
382
                                                                              : TrappedBishopA1H1;
332
            }
383
            }
Line 337... Line 388...
337
            // Bonus for aligning with enemy pawns on the same rank/file
388
            // Bonus for aligning with enemy pawns on the same rank/file
338
            if (relative_rank(Us, s) >= RANK_5)
389
            if (relative_rank(Us, s) >= RANK_5)
339
                score += RookOnPawn * popcount(pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s]);
390
                score += RookOnPawn * popcount(pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s]);
340
 
391
 
341
            // Bonus when on an open or semi-open file
392
            // Bonus when on an open or semi-open file
342
            if (ei.pi->semiopen_file(Us, file_of(s)))
393
            if (pe->semiopen_file(Us, file_of(s)))
343
                score += RookOnFile[!!ei.pi->semiopen_file(Them, file_of(s))];
394
                score += RookOnFile[bool(pe->semiopen_file(Them, file_of(s)))];
344
 
395
 
345
            // Penalize when trapped by the king, even more if the king cannot castle
396
            // Penalty when trapped by the king, even more if the king cannot castle
346
            else if (mob <= 3)
397
            else if (mob <= 3)
347
            {
398
            {
348
                Square ksq = pos.square<KING>(Us);
399
                Square ksq = pos.square<KING>(Us);
349
 
400
 
350
                if (   ((file_of(ksq) < FILE_E) == (file_of(s) < file_of(ksq)))
401
                if (   ((file_of(ksq) < FILE_E) == (file_of(s) < file_of(ksq)))
351
                    && (rank_of(ksq) == rank_of(s) || relative_rank(Us, ksq) == RANK_1)
-
 
352
                    && !ei.pi->semiopen_side(Us, file_of(ksq), file_of(s) < file_of(ksq)))
402
                    && !pe->semiopen_side(Us, file_of(ksq), file_of(s) < file_of(ksq)))
353
                    score -= (TrappedRook - make_score(mob * 22, 0)) * (1 + !pos.can_castle(Us));
403
                    score -= (TrappedRook - make_score(mob * 22, 0)) * (1 + !pos.can_castle(Us));
354
            }
404
            }
355
        }
405
        }
356
 
406
 
357
        if (Pt == QUEEN)
407
        if (Pt == QUEEN)
Line 361... Line 411...
361
            if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, pinners))
411
            if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, pinners))
362
                score -= WeakQueen;
412
                score -= WeakQueen;
363
        }
413
        }
364
    }
414
    }
365
 
415
 
366
    if (DoTrace)
416
    if (T)
367
        Trace::add(Pt, Us, score);
417
        Trace::add(Pt, Us, score);
368
 
418
 
369
    // Recursively call evaluate_pieces() of next piece type until KING is excluded
-
 
370
    return score - evaluate_pieces<DoTrace, Them, NextPt>(pos, ei, mobility, mobilityArea);
419
    return score;
371
  }
420
  }
372
 
-
 
373
  template<>
-
 
374
  Score evaluate_pieces<false, WHITE, KING>(const Position&, EvalInfo&, Score*, const Bitboard*) { return SCORE_ZERO; }
-
 
375
  template<>
-
 
376
  Score evaluate_pieces< true, WHITE, KING>(const Position&, EvalInfo&, Score*, const Bitboard*) { return SCORE_ZERO; }
-
 
377
 
421
 
378
 
422
 
379
  // evaluate_king() assigns bonuses and penalties to a king of a given color
423
  // evaluate_king() assigns bonuses and penalties to a king of a given color
380
 
424
 
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;
425
  template<Tracing T>  template<Color Us>
384
  const Bitboard CenterFiles = FileCBB | FileDBB | FileEBB | FileFBB;
426
  Score Evaluation<T>::evaluate_king() {
385
  const Bitboard KingSide    = FileEBB | FileFBB | FileGBB | FileHBB;
-
 
386
 
427
 
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
  };
-
 
393
 
-
 
394
  template<Color Us, bool DoTrace>
-
 
395
  Score evaluate_king(const Position& pos, const EvalInfo& ei) {
-
 
396
 
-
 
397
    const Color Them = (Us == WHITE ? BLACK : WHITE);
428
    const Color     Them = (Us == WHITE ? BLACK : WHITE);
398
    const Square  Up = (Us == WHITE ? NORTH : SOUTH);
429
    const Bitboard  Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
-
 
430
                                        : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
399
 
431
 
400
    Bitboard undefended, b, b1, b2, safe, other;
-
 
401
    int kingDanger;
-
 
402
    const Square ksq = pos.square<KING>(Us);
432
    const Square ksq = pos.square<KING>(Us);
-
 
433
    Bitboard weak, b, b1, b2, safe, unsafeChecks;
403
 
434
 
404
    // King shelter and enemy pawns storm
435
    // King shelter and enemy pawns storm
405
    Score score = ei.pi->king_safety<Us>(pos, ksq);
436
    Score score = pe->king_safety<Us>(pos, ksq);
406
 
437
 
407
    // Main king safety evaluation
438
    // Main king safety evaluation
408
    if (ei.kingAttackersCount[Them])
439
    if (kingAttackersCount[Them] > (1 - pos.count<QUEEN>(Them)))
409
    {
440
    {
410
        // Find the attacked squares which are defended only by the king...
441
        // Attacked squares defended at most once by our queen or king
411
        undefended =   ei.attackedBy[Them][ALL_PIECES]
442
        weak =  attackedBy[Them][ALL_PIECES]
412
                    &  ei.attackedBy[Us][KING]
-
 
413
                    & ~ei.attackedBy2[Us];
443
              & ~attackedBy2[Us]
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]
444
              & (attackedBy[Us][KING] | attackedBy[Us][QUEEN] | ~attackedBy[Us][ALL_PIECES]);
417
           & ei.kingRing[Us] & ~pos.pieces(Them);
-
 
418
 
445
 
419
        // Initialize the 'kingDanger' variable, which will be transformed
-
 
420
        // later into a king danger score. The initial value is based on the
-
 
421
        // number and types of the enemy's attacking pieces, the number of
-
 
422
        // attacked and undefended squares around our king and the quality of
446
        unsafeChecks = 0; // Pierre-Marie Baty -- fixed variable initialization
423
        // the pawn shelter (current 'score' value).
-
 
424
        kingDanger =  std::min(807, ei.kingAttackersCount[Them] * ei.kingAttackersWeight[Them])
-
 
425
                    + 101 * ei.kingAdjacentZoneAttacksCount[Them]
-
 
426
                    + 235 * popcount(undefended)
-
 
427
                    + 134 * (popcount(b) + !!ei.pinnedPieces[Us])
-
 
428
                    - 717 * !pos.count<QUEEN>(Them)
-
 
429
                    -   7 * mg_value(score) / 5 - 5;
447
        int kingDanger = 0;
430
 
-
 
431
        // Analyse the enemy's safe queen contact checks. Firstly, find the
-
 
432
        // undefended squares around the king reachable by the enemy queen...
-
 
433
        b = undefended & ei.attackedBy[Them][QUEEN] & ~pos.pieces(Them);
-
 
434
 
-
 
435
        // ...and keep squares supported by another enemy piece
-
 
436
        kingDanger += QueenContactCheck * popcount(b & ei.attackedBy2[Them]);
-
 
437
 
-
 
438
        // Analyse the safe enemy's checks which are possible on next move...
-
 
439
        safe  = ~(ei.attackedBy[Us][ALL_PIECES] | pos.pieces(Them));
-
 
440
 
448
 
441
        // ... and some other potential checks, only requiring the square to be
449
        // Analyse the safe enemy's checks which are possible on next move
442
        // safe from pawn-attacks, and not being occupied by a blocked pawn.
-
 
443
        other = ~(   ei.attackedBy[Us][PAWN]
450
        safe  = ~pos.pieces(Them);
444
                  | (pos.pieces(Them, PAWN) & shift<Up>(pos.pieces(PAWN))));
451
        safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
445
 
452
 
446
        b1 = pos.attacks_from<ROOK  >(ksq);
453
        b1 = attacks_bb<ROOK  >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
447
        b2 = pos.attacks_from<BISHOP>(ksq);
454
        b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
448
 
455
 
449
        // Enemy queen safe checks
456
        // Enemy queen safe checks
450
        if ((b1 | b2) & ei.attackedBy[Them][QUEEN] & safe)
457
        if ((b1 | b2) & attackedBy[Them][QUEEN] & safe & ~attackedBy[Us][QUEEN])
451
            kingDanger += QueenCheck, score -= SafeCheck;
458
            kingDanger += QueenSafeCheck;
452
 
459
 
453
        // For other pieces, also consider the square safe if attacked twice,
-
 
454
        // and only defended by a queen.
-
 
455
        safe |=  ei.attackedBy2[Them]
460
        b1 &= attackedBy[Them][ROOK];
456
               & ~(ei.attackedBy2[Us] | pos.pieces(Them))
-
 
457
               & ei.attackedBy[Us][QUEEN];
461
        b2 &= attackedBy[Them][BISHOP];
458
 
462
 
459
        // Enemy rooks safe and other checks
463
        // Enemy rooks checks
460
        if (b1 & ei.attackedBy[Them][ROOK] & safe)
464
        if (b1 & safe)
461
            kingDanger += RookCheck, score -= SafeCheck;
465
            kingDanger += RookSafeCheck;
-
 
466
        else
-
 
467
            unsafeChecks |= b1;
462
 
468
 
-
 
469
        // Enemy bishops checks
-
 
470
        if (b2 & safe)
463
        else if (b1 & ei.attackedBy[Them][ROOK] & other)
471
            kingDanger += BishopSafeCheck;
-
 
472
        else
464
            score -= OtherCheck;
473
            unsafeChecks |= b2;
465
 
474
 
466
        // Enemy bishops safe and other checks
-
 
467
        if (b2 & ei.attackedBy[Them][BISHOP] & safe)
-
 
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
475
        // Enemy knights checks
474
        b = pos.attacks_from<KNIGHT>(ksq) & ei.attackedBy[Them][KNIGHT];
476
        b = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
475
        if (b & safe)
477
        if (b & safe)
476
            kingDanger += KnightCheck, score -= SafeCheck;
478
            kingDanger += KnightSafeCheck;
-
 
479
        else
-
 
480
            unsafeChecks |= b;
477
 
481
 
-
 
482
        // Unsafe or occupied checking squares will also be considered, as long as
478
        else if (b & other)
483
        // the square is in the attacker's mobility area.
479
            score -= OtherCheck;
484
        unsafeChecks &= mobilityArea[Them];
480
 
485
 
-
 
486
        kingDanger +=        kingAttackersCount[Them] * kingAttackersWeight[Them]
-
 
487
                     + 102 * kingAdjacentZoneAttacksCount[Them]
-
 
488
                     + 191 * popcount(kingRing[Us] & weak)
-
 
489
                     + 143 * popcount(pos.pinned_pieces(Us) | unsafeChecks)
-
 
490
                     - 848 * !pos.count<QUEEN>(Them)
-
 
491
                     -   9 * mg_value(score) / 8
-
 
492
                     +  40;
-
 
493
 
481
        // Compute the king danger score and subtract it from the evaluation
494
        // Transform the kingDanger units into a Score, and subtract it from the evaluation
482
        if (kingDanger > 0)
495
        if (kingDanger > 0)
-
 
496
        {
-
 
497
            int mobilityDanger = mg_value(mobility[Them] - mobility[Us]);
-
 
498
            kingDanger = std::max(0, kingDanger + mobilityDanger);
483
            score -= make_score(std::min(kingDanger * kingDanger / 4096,  2 * int(BishopValueMg)), 0);
499
            score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
-
 
500
        }
484
    }
501
    }
485
 
502
 
486
    // King tropism: firstly, find squares that opponent attacks in our king flank
503
    // King tropism: firstly, find squares that opponent attacks in our king flank
487
    File kf = file_of(ksq);
504
    File kf = file_of(ksq);
488
    b = ei.attackedBy[Them][ALL_PIECES] & KingFlank[Us][kf];
505
    b = attackedBy[Them][ALL_PIECES] & KingFlank[kf] & Camp;
489
 
506
 
490
    assert(((Us == WHITE ? b << 4 : b >> 4) & b) == 0);
507
    assert(((Us == WHITE ? b << 4 : b >> 4) & b) == 0);
491
    assert(popcount(Us == WHITE ? b << 4 : b >> 4) == popcount(b));
508
    assert(popcount(Us == WHITE ? b << 4 : b >> 4) == popcount(b));
492
 
509
 
493
    // Secondly, add the squares which are attacked twice in that flank and
510
    // Secondly, add the squares which are attacked twice in that flank and
494
    // which are not defended by our pawns.
511
    // which are not defended by our pawns.
495
    b =  (Us == WHITE ? b << 4 : b >> 4)
512
    b =  (Us == WHITE ? b << 4 : b >> 4)
496
       | (b & ei.attackedBy2[Them] & ~ei.attackedBy[Us][PAWN]);
513
       | (b & attackedBy2[Them] & ~attackedBy[Us][PAWN]);
497
 
514
 
498
    score -= CloseEnemies * popcount(b);
515
    score -= CloseEnemies * popcount(b);
499
 
516
 
500
    // Penalty when our king is on a pawnless flank
517
    // Penalty when our king is on a pawnless flank
501
    if (!(pos.pieces(PAWN) & (KingFlank[WHITE][kf] | KingFlank[BLACK][kf])))
518
    if (!(pos.pieces(PAWN) & KingFlank[kf]))
502
        score -= PawnlessFlank;
519
        score -= PawnlessFlank;
503
 
520
 
504
    if (DoTrace)
521
    if (T)
505
        Trace::add(KING, Us, score);
522
        Trace::add(KING, Us, score);
506
 
523
 
507
    return score;
524
    return score;
508
  }
525
  }
509
 
526
 
510
 
527
 
511
  // evaluate_threats() assigns bonuses according to the types of the attacking
528
  // evaluate_threats() assigns bonuses according to the types of the attacking
512
  // and the attacked pieces.
529
  // and the attacked pieces.
513
 
530
 
514
  template<Color Us, bool DoTrace>
531
  template<Tracing T>  template<Color Us>
515
  Score evaluate_threats(const Position& pos, const EvalInfo& ei) {
532
  Score Evaluation<T>::evaluate_threats() {
516
 
533
 
517
    const Color Them        = (Us == WHITE ? BLACK      : WHITE);
534
    const Color     Them     = (Us == WHITE ? BLACK      : WHITE);
518
    const Square Up         = (Us == WHITE ? NORTH      : SOUTH);
535
    const Direction Up       = (Us == WHITE ? NORTH      : SOUTH);
519
    const Square Left       = (Us == WHITE ? NORTH_WEST : SOUTH_EAST);
536
    const Direction Left     = (Us == WHITE ? NORTH_WEST : SOUTH_EAST);
520
    const Square Right      = (Us == WHITE ? NORTH_EAST : SOUTH_WEST);
537
    const Direction Right    = (Us == WHITE ? NORTH_EAST : SOUTH_WEST);
521
    const Bitboard TRank2BB = (Us == WHITE ? Rank2BB    : Rank7BB);
-
 
522
    const Bitboard TRank7BB = (Us == WHITE ? Rank7BB    : Rank2BB);
538
    const Bitboard  TRank3BB = (Us == WHITE ? Rank3BB    : Rank6BB);
523
 
539
 
524
    enum { Minor, Rook };
-
 
525
 
-
 
526
    Bitboard b, weak, defended, safeThreats;
540
    Bitboard b, weak, defended, stronglyProtected, safeThreats;
527
    Score score = SCORE_ZERO;
541
    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;
-
 
533
 
542
 
534
    // Non-pawn enemies attacked by a pawn
543
    // Non-pawn enemies attacked by a pawn
535
    weak = (pos.pieces(Them) ^ pos.pieces(Them, PAWN)) & ei.attackedBy[Us][PAWN];
544
    weak = (pos.pieces(Them) ^ pos.pieces(Them, PAWN)) & attackedBy[Us][PAWN];
536
 
545
 
537
    if (weak)
546
    if (weak)
538
    {
547
    {
539
        b = pos.pieces(Us, PAWN) & ( ~ei.attackedBy[Them][ALL_PIECES]
548
        b = pos.pieces(Us, PAWN) & ( ~attackedBy[Them][ALL_PIECES]
540
                                    | ei.attackedBy[Us][ALL_PIECES]);
549
                                    | attackedBy[Us][ALL_PIECES]);
541
 
550
 
542
        safeThreats = (shift<Right>(b) | shift<Left>(b)) & weak;
551
        safeThreats = (shift<Right>(b) | shift<Left>(b)) & weak;
543
 
552
 
544
        if (weak ^ safeThreats)
-
 
545
            score += ThreatByHangingPawn;
-
 
546
 
-
 
547
        while (safeThreats)
-
 
548
            score += ThreatBySafePawn[type_of(pos.piece_on(pop_lsb(&safeThreats)))];
553
        score += ThreatBySafePawn * popcount(safeThreats);
549
    }
554
    }
550
 
555
 
-
 
556
    // Squares strongly protected by the opponent, either because they attack the
-
 
557
    // square with a pawn, or because they attack the square twice and we don't.
-
 
558
    stronglyProtected =  attackedBy[Them][PAWN]
-
 
559
                       | (attackedBy2[Them] & ~attackedBy2[Us]);
-
 
560
 
551
    // Non-pawn enemies defended by a pawn
561
    // Non-pawn enemies, strongly protected
552
    defended = (pos.pieces(Them) ^ pos.pieces(Them, PAWN)) & ei.attackedBy[Them][PAWN];
562
    defended =  (pos.pieces(Them) ^ pos.pieces(Them, PAWN))
-
 
563
              & stronglyProtected;
553
 
564
 
554
    // Enemies not defended by a pawn and under our attack
565
    // Enemies not strongly protected and under our attack
555
    weak =   pos.pieces(Them)
566
    weak =   pos.pieces(Them)
556
          & ~ei.attackedBy[Them][PAWN]
567
          & ~stronglyProtected
557
          &  ei.attackedBy[Us][ALL_PIECES];
568
          &  attackedBy[Us][ALL_PIECES];
558
 
569
 
559
    // Add a bonus according to the kind of attacking pieces
570
    // Add a bonus according to the kind of attacking pieces
560
    if (defended | weak)
571
    if (defended | weak)
561
    {
572
    {
562
        b = (defended | weak) & (ei.attackedBy[Us][KNIGHT] | ei.attackedBy[Us][BISHOP]);
573
        b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
563
        while (b)
574
        while (b)
-
 
575
        {
-
 
576
            Square s = pop_lsb(&b);
564
            score += Threat[Minor][type_of(pos.piece_on(pop_lsb(&b)))];
577
            score += ThreatByMinor[type_of(pos.piece_on(s))];
-
 
578
            if (type_of(pos.piece_on(s)) != PAWN)
-
 
579
                score += ThreatByRank * (int)relative_rank(Them, s);
-
 
580
        }
565
 
581
 
566
        b = (pos.pieces(Them, QUEEN) | weak) & ei.attackedBy[Us][ROOK];
582
        b = (pos.pieces(Them, QUEEN) | weak) & attackedBy[Us][ROOK];
567
        while (b)
583
        while (b)
-
 
584
        {
-
 
585
            Square s = pop_lsb(&b);
568
            score += Threat[Rook ][type_of(pos.piece_on(pop_lsb(&b)))];
586
            score += ThreatByRook[type_of(pos.piece_on(s))];
-
 
587
            if (type_of(pos.piece_on(s)) != PAWN)
-
 
588
                score += ThreatByRank * (int)relative_rank(Them, s);
-
 
589
        }
569
 
590
 
570
        score += Hanging * popcount(weak & ~ei.attackedBy[Them][ALL_PIECES]);
591
        score += Hanging * popcount(weak & ~attackedBy[Them][ALL_PIECES]);
571
 
592
 
572
        b = weak & ei.attackedBy[Us][KING];
593
        b = weak & attackedBy[Us][KING];
573
        if (b)
594
        if (b)
574
            score += ThreatByKing[more_than_one(b)];
595
            score += ThreatByKing[more_than_one(b)];
575
    }
596
    }
576
 
597
 
577
    // Bonus if some pawns can safely push and attack an enemy piece
598
    // Bonus for opponent unopposed weak pawns
578
    b = pos.pieces(Us, PAWN) & ~TRank7BB;
599
    if (pos.pieces(Us, ROOK, QUEEN))
579
    b = shift<Up>(b | (shift<Up>(b & TRank2BB) & ~pos.pieces()));
600
        score += WeakUnopposedPawn * pe->weak_unopposed(Them);
580
 
601
 
581
    b &=  ~pos.pieces()
602
    // Find squares where our pawns can push on the next move
582
        & ~ei.attackedBy[Them][PAWN]
603
    b  = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
583
        & (ei.attackedBy[Us][ALL_PIECES] | ~ei.attackedBy[Them][ALL_PIECES]);
604
    b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
584
 
605
 
-
 
606
    // Keep only the squares which are not completely unsafe
-
 
607
    b &= ~attackedBy[Them][PAWN]
-
 
608
        & (attackedBy[Us][ALL_PIECES] | ~attackedBy[Them][ALL_PIECES]);
-
 
609
 
-
 
610
    // Add a bonus for each new pawn threats from those squares
585
    b =  (shift<Left>(b) | shift<Right>(b))
611
    b =  (shift<Left>(b) | shift<Right>(b))
586
       &  pos.pieces(Them)
612
       &  pos.pieces(Them)
587
       & ~ei.attackedBy[Us][PAWN];
613
       & ~attackedBy[Us][PAWN];
588
 
614
 
589
    score += ThreatByPawnPush * popcount(b);
615
    score += ThreatByPawnPush * popcount(b);
590
 
616
 
-
 
617
    // Add a bonus for safe slider attack threats on opponent queen
-
 
618
    safeThreats = ~pos.pieces(Us) & ~attackedBy2[Them] & attackedBy2[Us];
-
 
619
    b =  (attackedBy[Us][BISHOP] & attackedBy[Them][QUEEN_DIAGONAL])
-
 
620
       | (attackedBy[Us][ROOK  ] & attackedBy[Them][QUEEN] & ~attackedBy[Them][QUEEN_DIAGONAL]);
-
 
621
 
-
 
622
    score += ThreatByAttackOnQueen * popcount(b & safeThreats);
-
 
623
 
591
    if (DoTrace)
624
    if (T)
592
        Trace::add(THREAT, Us, score);
625
        Trace::add(THREAT, Us, score);
593
 
626
 
594
    return score;
627
    return score;
595
  }
628
  }
596
 
629
 
-
 
630
  // helper used by evaluate_passed_pawns to cap the distance
-
 
631
  template<Tracing T>
-
 
632
  int Evaluation<T>::king_distance(Color c, Square s) {
-
 
633
    return std::min(distance(pos.square<KING>(c), s), 5);
-
 
634
  }
597
 
635
 
598
  // evaluate_passed_pawns() evaluates the passed pawns of the given color
636
  // evaluate_passed_pawns() evaluates the passed pawns and candidate passed
-
 
637
  // pawns of the given color.
599
 
638
 
600
  template<Color Us, bool DoTrace>
639
  template<Tracing T>  template<Color Us>
601
  Score evaluate_passed_pawns(const Position& pos, const EvalInfo& ei) {
640
  Score Evaluation<T>::evaluate_passed_pawns() {
602
 
641
 
603
    const Color Them = (Us == WHITE ? BLACK : WHITE);
642
    const Color     Them = (Us == WHITE ? BLACK : WHITE);
-
 
643
    const Direction Up   = (Us == WHITE ? NORTH : SOUTH);
604
 
644
 
605
    Bitboard b, bb, squaresToQueen, defendedSquares, unsafeSquares;
645
    Bitboard b, bb, squaresToQueen, defendedSquares, unsafeSquares;
606
    Score score = SCORE_ZERO;
646
    Score score = SCORE_ZERO;
607
 
647
 
608
    b = ei.pi->passed_pawns(Us);
648
    b = pe->passed_pawns(Us);
609
 
649
 
610
    while (b)
650
    while (b)
611
    {
651
    {
612
        Square s = pop_lsb(&b);
652
        Square s = pop_lsb(&b);
613
 
653
 
614
        assert(pos.pawn_passed(Us, s));
-
 
615
        assert(!(pos.pieces(PAWN) & forward_bb(Us, s)));
654
        assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
616
 
655
 
617
        bb = forward_bb(Us, s) & (ei.attackedBy[Them][ALL_PIECES] | pos.pieces(Them));
656
        bb = forward_file_bb(Us, s) & (attackedBy[Them][ALL_PIECES] | pos.pieces(Them));
618
        score -= HinderPassedPawn * popcount(bb);
657
        score -= HinderPassedPawn * popcount(bb);
619
 
658
 
620
        int r = relative_rank(Us, s) - RANK_2;
659
        int r = relative_rank(Us, s);
621
        int rr = r * (r - 1);
660
        int rr = RankFactor[r];
622
 
661
 
623
        Value mbonus = Passed[MG][r], ebonus = Passed[EG][r];
662
        Value mbonus = Passed[MG][r], ebonus = Passed[EG][r];
624
 
663
 
625
        if (rr)
664
        if (rr)
626
        {
665
        {
627
            Square blockSq = s + pawn_push(Us);
666
            Square blockSq = s + Up;
628
 
667
 
629
            // Adjust bonus based on the king's proximity
668
            // Adjust bonus based on the king's proximity
630
            ebonus +=  distance(pos.square<KING>(Them), blockSq) * 5 * rr
669
            ebonus += (king_distance(Them, blockSq) * 5 - king_distance(Us, blockSq) * 2) * rr;
631
                     - distance(pos.square<KING>(Us  ), blockSq) * 2 * rr;
-
 
632
 
670
 
633
            // If blockSq is not the queening square then consider also a second push
671
            // If blockSq is not the queening square then consider also a second push
634
            if (relative_rank(Us, blockSq) != RANK_8)
672
            if (r != RANK_7)
635
                ebonus -= distance(pos.square<KING>(Us), blockSq + pawn_push(Us)) * rr;
673
                ebonus -= king_distance(Us, blockSq + Up) * rr;
636
 
674
 
637
            // If the pawn is free to advance, then increase the bonus
675
            // If the pawn is free to advance, then increase the bonus
638
            if (pos.empty(blockSq))
676
            if (pos.empty(blockSq))
639
            {
677
            {
640
                // If there is a rook or queen attacking/defending the pawn from behind,
678
                // If there is a rook or queen attacking/defending the pawn from behind,
641
                // consider all the squaresToQueen. Otherwise consider only the squares
679
                // consider all the squaresToQueen. Otherwise consider only the squares
642
                // in the pawn's path attacked or occupied by the enemy.
680
                // in the pawn's path attacked or occupied by the enemy.
643
                defendedSquares = unsafeSquares = squaresToQueen = forward_bb(Us, s);
681
                defendedSquares = unsafeSquares = squaresToQueen = forward_file_bb(Us, s);
644
 
682
 
645
                bb = forward_bb(Them, s) & pos.pieces(ROOK, QUEEN) & pos.attacks_from<ROOK>(s);
683
                bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN) & pos.attacks_from<ROOK>(s);
646
 
684
 
647
                if (!(pos.pieces(Us) & bb))
685
                if (!(pos.pieces(Us) & bb))
648
                    defendedSquares &= ei.attackedBy[Us][ALL_PIECES];
686
                    defendedSquares &= attackedBy[Us][ALL_PIECES];
649
 
687
 
650
                if (!(pos.pieces(Them) & bb))
688
                if (!(pos.pieces(Them) & bb))
651
                    unsafeSquares &= ei.attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
689
                    unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
652
 
690
 
653
                // If there aren't any enemy attacks, assign a big bonus. Otherwise
691
                // If there aren't any enemy attacks, assign a big bonus. Otherwise
654
                // assign a smaller bonus if the block square isn't attacked.
692
                // assign a smaller bonus if the block square isn't attacked.
655
                int k = !unsafeSquares ? 18 : !(unsafeSquares & blockSq) ? 8 : 0;
693
                int k = !unsafeSquares ? 18 : !(unsafeSquares & blockSq) ? 8 : 0;
656
 
694
 
Line 665... Line 703...
665
                mbonus += k * rr, ebonus += k * rr;
703
                mbonus += k * rr, ebonus += k * rr;
666
            }
704
            }
667
            else if (pos.pieces(Us) & blockSq)
705
            else if (pos.pieces(Us) & blockSq)
668
                mbonus += rr + r * 2, ebonus += rr + r * 2;
706
                mbonus += rr + r * 2, ebonus += rr + r * 2;
669
        } // rr != 0
707
        } // rr != 0
-
 
708
 
-
 
709
        // Scale down bonus for candidate passers which need more than one
-
 
710
        // pawn push to become passed or have a pawn in front of them.
-
 
711
        if (!pos.pawn_passed(Us, s + Up) || (pos.pieces(PAWN) & forward_file_bb(Us, s)))
-
 
712
            mbonus /= 2, ebonus /= 2;
670
 
713
 
671
        score += make_score(mbonus, ebonus) + PassedFile[file_of(s)];
714
        score += make_score(mbonus, ebonus) + PassedFile[file_of(s)];
672
    }
715
    }
673
 
716
 
674
    if (DoTrace)
717
    if (T)
675
        Trace::add(PASSED, Us, score);
718
        Trace::add(PASSED, Us, score);
676
 
719
 
677
    // Add the scores to the middlegame and endgame eval
-
 
678
    return score;
720
    return score;
679
  }
721
  }
680
 
722
 
681
 
723
 
682
  // evaluate_space() computes the space evaluation for a given side. The
724
  // evaluate_space() computes the space evaluation for a given side. The
683
  // space evaluation is a simple bonus based on the number of safe squares
725
  // space evaluation is a simple bonus based on the number of safe squares
684
  // available for minor pieces on the central four files on ranks 2--4. Safe
726
  // available for minor pieces on the central four files on ranks 2--4. Safe
685
  // squares one, two or three squares behind a friendly pawn are counted
727
  // squares one, two or three squares behind a friendly pawn are counted
686
  // twice. Finally, the space bonus is multiplied by a weight. The aim is to
728
  // twice. Finally, the space bonus is multiplied by a weight. The aim is to
687
  // improve play on game opening.
729
  // improve play on game opening.
-
 
730
 
688
  template<Color Us>
731
  template<Tracing T>  template<Color Us>
689
  Score evaluate_space(const Position& pos, const EvalInfo& ei) {
732
  Score Evaluation<T>::evaluate_space() {
690
 
733
 
691
    const Color Them = (Us == WHITE ? BLACK : WHITE);
734
    const Color Them = (Us == WHITE ? BLACK : WHITE);
692
    const Bitboard SpaceMask =
735
    const Bitboard SpaceMask =
693
      Us == WHITE ? (FileCBB | FileDBB | FileEBB | FileFBB) & (Rank2BB | Rank3BB | Rank4BB)
736
      Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
694
                  : (FileCBB | FileDBB | FileEBB | FileFBB) & (Rank7BB | Rank6BB | Rank5BB);
737
                  : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
695
 
738
 
696
    // Find the safe squares for our pieces inside the area defined by
739
    // Find the safe squares for our pieces inside the area defined by
697
    // SpaceMask. A square is unsafe if it is attacked by an enemy
740
    // SpaceMask. A square is unsafe if it is attacked by an enemy
698
    // pawn, or if it is undefended and attacked by an enemy piece.
741
    // pawn, or if it is undefended and attacked by an enemy piece.
699
    Bitboard safe =   SpaceMask
742
    Bitboard safe =   SpaceMask
700
                   & ~pos.pieces(Us, PAWN)
743
                   & ~pos.pieces(Us, PAWN)
701
                   & ~ei.attackedBy[Them][PAWN]
744
                   & ~attackedBy[Them][PAWN]
702
                   & (ei.attackedBy[Us][ALL_PIECES] | ~ei.attackedBy[Them][ALL_PIECES]);
745
                   & (attackedBy[Us][ALL_PIECES] | ~attackedBy[Them][ALL_PIECES]);
703
 
746
 
704
    // Find all squares which are at most three squares behind some friendly pawn
747
    // Find all squares which are at most three squares behind some friendly pawn
705
    Bitboard behind = pos.pieces(Us, PAWN);
748
    Bitboard behind = pos.pieces(Us, PAWN);
706
    behind |= (Us == WHITE ? behind >>  8 : behind <<  8);
749
    behind |= (Us == WHITE ? behind >>  8 : behind <<  8);
707
    behind |= (Us == WHITE ? behind >> 16 : behind << 16);
750
    behind |= (Us == WHITE ? behind >> 16 : behind << 16);
708
 
751
 
709
    // Since SpaceMask[Us] is fully on our half of the board...
752
    // Since SpaceMask[Us] is fully on our half of the board...
710
    assert(unsigned(safe >> (Us == WHITE ? 32 : 0)) == 0);
753
    assert(unsigned(safe >> (Us == WHITE ? 32 : 0)) == 0);
711
 
754
 
712
    // ...count safe + (behind & safe) with a single popcount
755
    // ...count safe + (behind & safe) with a single popcount.
713
    int bonus = popcount((Us == WHITE ? safe << 32 : safe >> 32) | (behind & safe));
756
    int bonus = popcount((Us == WHITE ? safe << 32 : safe >> 32) | (behind & safe));
714
    bonus = std::min(16, bonus);
-
 
715
    int weight = pos.count<ALL_PIECES>(Us) - 2 * ei.pi->open_files();
757
    int weight = pos.count<ALL_PIECES>(Us) - 2 * pe->open_files();
716
 
758
 
717
    return make_score(bonus * weight * weight / 18, 0);
759
    return make_score(bonus * weight * weight / 16, 0);
718
  }
760
  }
719
 
761
 
720
 
762
 
721
  // evaluate_initiative() computes the initiative correction value for the
763
  // evaluate_initiative() computes the initiative correction value for the
722
  // position, i.e., second order bonus/malus based on the known attacking/defending
764
  // position, i.e., second order bonus/malus based on the known attacking/defending
723
  // status of the players.
765
  // status of the players.
-
 
766
 
-
 
767
  template<Tracing T>
724
  Score evaluate_initiative(const Position& pos, int asymmetry, Value eg) {
768
  Score Evaluation<T>::evaluate_initiative(Value eg) {
725
 
769
 
726
    int kingDistance =  distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
770
    int kingDistance =  distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
727
                      - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
771
                      - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
728
    int pawns = pos.count<PAWN>(WHITE) + pos.count<PAWN>(BLACK);
772
    bool bothFlanks = (pos.pieces(PAWN) & QueenSide) && (pos.pieces(PAWN) & KingSide);
729
 
773
 
730
    // Compute the initiative bonus for the attacking side
774
    // Compute the initiative bonus for the attacking side
731
    int initiative = 8 * (asymmetry + kingDistance - 15) + 12 * pawns;
775
    int initiative = 8 * (pe->pawn_asymmetry() + kingDistance - 17) + 12 * pos.count<PAWN>() + 16 * bothFlanks;
732
 
776
 
733
    // Now apply the bonus: note that we find the attacking side by extracting
777
    // Now apply the bonus: note that we find the attacking side by extracting
734
    // the sign of the endgame value, and that we carefully cap the bonus so
778
    // the sign of the endgame value, and that we carefully cap the bonus so
735
    // that the endgame score will never be divided by more than two.
779
    // that the endgame score will never change sign after the bonus.
736
    int value = ((eg > 0) - (eg < 0)) * std::max(initiative, -abs(eg / 2));
780
    int v = ((eg > 0) - (eg < 0)) * std::max(initiative, -abs(eg));
-
 
781
 
-
 
782
    if (T)
-
 
783
        Trace::add(INITIATIVE, make_score(0, v));
737
 
784
 
738
    return make_score(0, value);
785
    return make_score(0, v);
739
  }
786
  }
740
 
787
 
741
 
788
 
742
  // evaluate_scale_factor() computes the scale factor for the winning side
789
  // evaluate_scale_factor() computes the scale factor for the winning side
-
 
790
 
-
 
791
  template<Tracing T>
743
  ScaleFactor evaluate_scale_factor(const Position& pos, const EvalInfo& ei, Value eg) {
792
  ScaleFactor Evaluation<T>::evaluate_scale_factor(Value eg) {
744
 
793
 
745
    Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
794
    Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
746
    ScaleFactor sf = ei.me->scale_factor(pos, strongSide);
795
    ScaleFactor sf = me->scale_factor(pos, strongSide);
747
 
796
 
748
    // If we don't already have an unusual scale factor, check for certain
797
    // If we don't already have an unusual scale factor, check for certain
749
    // types of endgames, and use a lower scale for those.
798
    // types of endgames, and use a lower scale for those.
750
    if (    ei.me->game_phase() < PHASE_MIDGAME
-
 
751
        && (sf == SCALE_FACTOR_NORMAL || sf == SCALE_FACTOR_ONEPAWN))
799
    if (sf == SCALE_FACTOR_NORMAL || sf == SCALE_FACTOR_ONEPAWN)
752
    {
800
    {
753
        if (pos.opposite_bishops())
801
        if (pos.opposite_bishops())
754
        {
802
        {
755
            // Endgame with opposite-colored bishops and no other pieces (ignoring pawns)
803
            // Endgame with opposite-colored bishops and no other pieces (ignoring pawns)
756
            // is almost a draw, in case of KBP vs KB, it is even more a draw.
804
            // is almost a draw, in case of KBP vs KB, it is even more a draw.
757
            if (   pos.non_pawn_material(WHITE) == BishopValueMg
805
            if (   pos.non_pawn_material(WHITE) == BishopValueMg
758
                && pos.non_pawn_material(BLACK) == BishopValueMg)
806
                && pos.non_pawn_material(BLACK) == BishopValueMg)
759
                sf = more_than_one(pos.pieces(PAWN)) ? ScaleFactor(31) : ScaleFactor(9);
807
                return more_than_one(pos.pieces(PAWN)) ? ScaleFactor(31) : ScaleFactor(9);
760
 
808
 
761
            // Endgame with opposite-colored bishops, but also other pieces. Still
809
            // Endgame with opposite-colored bishops, but also other pieces. Still
762
            // a bit drawish, but not as drawish as with only the two bishops.
810
            // a bit drawish, but not as drawish as with only the two bishops.
763
            else
-
 
764
                sf = ScaleFactor(46);
811
            return ScaleFactor(46);
765
        }
812
        }
766
        // Endings where weaker side can place his king in front of the opponent's
813
        // Endings where weaker side can place his king in front of the opponent's
767
        // pawns are drawish.
814
        // pawns are drawish.
768
        else if (    abs(eg) <= BishopValueEg
815
        else if (    abs(eg) <= BishopValueEg
769
                 &&  pos.count<PAWN>(strongSide) <= 2
816
                 &&  pos.count<PAWN>(strongSide) <= 2
770
                 && !pos.pawn_passed(~strongSide, pos.square<KING>(~strongSide)))
817
                 && !pos.pawn_passed(~strongSide, pos.square<KING>(~strongSide)))
771
            sf = ScaleFactor(37 + 7 * pos.count<PAWN>(strongSide));
818
            return ScaleFactor(37 + 7 * pos.count<PAWN>(strongSide));
772
    }
819
    }
773
 
820
 
774
    return sf;
821
    return sf;
775
  }
822
  }
776
 
823
 
777
} // namespace
-
 
778
 
824
 
-
 
825
  // value() is the main function of the class. It computes the various parts of
-
 
826
  // the evaluation and returns the value of the position from the point of view
-
 
827
  // of the side to move.
779
 
828
 
780
/// evaluate() is the main evaluation function. It returns a static evaluation
829
  template<Tracing T>
781
/// of the position from the point of view of the side to move.
830
  Value Evaluation<T>::value() {
782
 
831
 
783
template<bool DoTrace>
832
    assert(!pos.checkers());
784
Value Eval::evaluate(const Position& pos) {
-
 
785
 
833
 
-
 
834
    // Probe the material hash table
786
  assert(!pos.checkers());
835
    me = Material::probe(pos);
787
 
836
 
-
 
837
    // If we have a specialized evaluation function for the current material
788
  Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
838
    // configuration, call it and return.
-
 
839
    if (me->specialized_eval_exists())
789
  EvalInfo ei;
840
        return me->evaluate(pos);
790
 
841
 
-
 
842
    // Initialize score by reading the incrementally updated scores included in
791
  // Probe the material hash table
843
    // the position object (material + piece square tables) and the material
-
 
844
    // imbalance. Score is computed internally from the white point of view.
792
  ei.me = Material::probe(pos);
845
    Score score = pos.psq_score() + me->imbalance() + Eval::Contempt;
793
 
846
 
794
  // If we have a specialized evaluation function for the current material
-
 
795
  // configuration, call it and return.
847
    // Probe the pawn hash table
796
  if (ei.me->specialized_eval_exists())
848
    pe = Pawns::probe(pos);
797
      return ei.me->evaluate(pos);
849
    score += pe->pawns_score();
798
 
850
 
799
  // Initialize score by reading the incrementally updated scores included in
851
    // Early exit if score is high
800
  // the position object (material + piece square tables) and the material
852
    Value v = (mg_value(score) + eg_value(score)) / 2;
801
  // imbalance. Score is computed internally from the white point of view.
853
    if (abs(v) > LazyThreshold)
802
  Score score = pos.psq_score() + ei.me->imbalance();
854
       return pos.side_to_move() == WHITE ? v : -v;
803
 
855
 
804
  // Probe the pawn hash table
856
    // Main evaluation begins here
805
  ei.pi = Pawns::probe(pos);
-
 
806
  score += ei.pi->pawns_score();
-
 
807
 
857
 
808
  // Initialize attack and king safety bitboards
-
 
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));
-
 
812
  eval_init<WHITE>(pos, ei);
858
    initialize<WHITE>();
813
  eval_init<BLACK>(pos, ei);
859
    initialize<BLACK>();
814
 
860
 
815
  // Pawns blocked or on ranks 2 and 3 will be excluded from the mobility area
861
    score += evaluate_pieces<WHITE, KNIGHT>() - evaluate_pieces<BLACK, KNIGHT>();
816
  Bitboard blockedPawns[] = {
862
    score += evaluate_pieces<WHITE, BISHOP>() - evaluate_pieces<BLACK, BISHOP>();
817
    pos.pieces(WHITE, PAWN) & (shift<SOUTH>(pos.pieces()) | Rank2BB | Rank3BB),
863
    score += evaluate_pieces<WHITE, ROOK  >() - evaluate_pieces<BLACK, ROOK  >();
818
    pos.pieces(BLACK, PAWN) & (shift<NORTH>(pos.pieces()) | Rank7BB | Rank6BB)
864
    score += evaluate_pieces<WHITE, QUEEN >() - evaluate_pieces<BLACK, QUEEN >();
819
  };
-
 
820
 
865
 
821
  // Do not include in mobility area squares protected by enemy pawns, or occupied
-
 
822
  // by our blocked pawns or king.
-
 
823
  Bitboard mobilityArea[] = {
866
    score += mobility[WHITE] - mobility[BLACK];
824
    ~(ei.attackedBy[BLACK][PAWN] | blockedPawns[WHITE] | pos.square<KING>(WHITE)),
-
 
825
    ~(ei.attackedBy[WHITE][PAWN] | blockedPawns[BLACK] | pos.square<KING>(BLACK))
-
 
826
  };
-
 
827
 
867
 
828
  // Evaluate all pieces but king and pawns
868
    score +=  evaluate_king<WHITE>()
829
  score += evaluate_pieces<DoTrace>(pos, ei, mobility, mobilityArea);
-
 
830
  score += mobility[WHITE] - mobility[BLACK];
869
            - evaluate_king<BLACK>();
831
 
870
 
832
  // Evaluate kings after all other pieces because we need full attack
-
 
833
  // information when computing the king safety evaluation.
-
 
834
  score +=  evaluate_king<WHITE, DoTrace>(pos, ei)
871
    score +=  evaluate_threats<WHITE>()
835
          - evaluate_king<BLACK, DoTrace>(pos, ei);
872
            - evaluate_threats<BLACK>();
836
 
873
 
837
  // Evaluate tactical threats, we need full attack information including king
-
 
838
  score +=  evaluate_threats<WHITE, DoTrace>(pos, ei)
874
    score +=  evaluate_passed_pawns<WHITE>()
839
          - evaluate_threats<BLACK, DoTrace>(pos, ei);
875
            - evaluate_passed_pawns<BLACK>();
840
 
876
 
841
  // Evaluate passed pawns, we need full attack information including king
877
    if (pos.non_pawn_material() >= SpaceThreshold)
842
  score +=  evaluate_passed_pawns<WHITE, DoTrace>(pos, ei)
878
        score +=  evaluate_space<WHITE>()
843
          - evaluate_passed_pawns<BLACK, DoTrace>(pos, ei);
879
                - evaluate_space<BLACK>();
844
 
880
 
845
  // If both sides have only pawns, score for potential unstoppable pawns
-
 
846
  if (!pos.non_pawn_material(WHITE) && !pos.non_pawn_material(BLACK))
-
 
847
  {
-
 
848
      Bitboard b;
-
 
849
      if ((b = ei.pi->passed_pawns(WHITE)) != 0)
881
    score += evaluate_initiative(eg_value(score));
850
          score += Unstoppable * int(relative_rank(WHITE, frontmost_sq(WHITE, b)));
-
 
851
 
882
 
-
 
883
    // Interpolate between a middlegame and a (scaled by 'sf') endgame score
-
 
884
    ScaleFactor sf = evaluate_scale_factor(eg_value(score));
852
      if ((b = ei.pi->passed_pawns(BLACK)) != 0)
885
    v =  mg_value(score) * int(me->game_phase())
853
          score -= Unstoppable * int(relative_rank(BLACK, frontmost_sq(BLACK, b)));
886
       + eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
854
  }
-
 
855
 
887
 
856
  // Evaluate space for both sides, only during opening
-
 
857
  if (pos.non_pawn_material(WHITE) + pos.non_pawn_material(BLACK) >= 12222)
-
 
858
      score +=  evaluate_space<WHITE>(pos, ei)
888
    v /= int(PHASE_MIDGAME);
859
              - evaluate_space<BLACK>(pos, ei);
-
 
860
 
889
 
861
  // Evaluate position potential for the winning side
890
    // In case of tracing add all remaining individual evaluation terms
-
 
891
    if (T)
-
 
892
    {
-
 
893
        Trace::add(MATERIAL, pos.psq_score());
-
 
894
        Trace::add(IMBALANCE, me->imbalance());
862
  score += evaluate_initiative(pos, ei.pi->pawn_asymmetry(), eg_value(score));
895
        Trace::add(PAWN, pe->pawns_score());
-
 
896
        Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
-
 
897
        if (pos.non_pawn_material() >= SpaceThreshold)
-
 
898
            Trace::add(SPACE, evaluate_space<WHITE>()
-
 
899
                            , evaluate_space<BLACK>());
-
 
900
        Trace::add(TOTAL, score);
-
 
901
    }
863
 
902
 
864
  // Evaluate scale factor for the winning side
-
 
865
  ScaleFactor sf = evaluate_scale_factor(pos, ei, eg_value(score));
903
    return pos.side_to_move() == WHITE ? v : -v; // Side to move point of view
-
 
904
  }
866
 
905
 
867
  // Interpolate between a middlegame and a (scaled by 'sf') endgame score
-
 
868
  Value v =  mg_value(score) * int(ei.me->game_phase())
906
} // namespace
869
           + eg_value(score) * int(PHASE_MIDGAME - ei.me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
-
 
870
 
907
 
871
  v /= int(PHASE_MIDGAME);
908
Score Eval::Contempt = SCORE_ZERO;
872
 
909
 
873
  // In case of tracing add all remaining individual evaluation terms
910
/// evaluate() is the evaluator for the outer world. It returns a static evaluation
874
  if (DoTrace)
-
 
875
  {
-
 
876
      Trace::add(MATERIAL, pos.psq_score());
-
 
877
      Trace::add(IMBALANCE, ei.me->imbalance());
-
 
878
      Trace::add(PAWN, ei.pi->pawns_score());
-
 
879
      Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
-
 
880
      Trace::add(SPACE, evaluate_space<WHITE>(pos, ei)
-
 
881
                      , evaluate_space<BLACK>(pos, ei));
911
/// of the position from the point of view of the side to move.
882
      Trace::add(TOTAL, score);
-
 
883
  }
-
 
884
 
912
 
-
 
913
Value Eval::evaluate(const Position& pos)
-
 
914
{
885
  return (pos.side_to_move() == WHITE ? v : -v) + Eval::Tempo; // Side to move point of view
915
   return Evaluation<>(pos).value() + Eval::Tempo;
886
}
916
}
887
 
-
 
888
// Explicit template instantiations
-
 
889
template Value Eval::evaluate<true >(const Position&);
-
 
890
template Value Eval::evaluate<false>(const Position&);
-
 
891
 
-
 
892
 
917
 
893
/// trace() is like evaluate(), but instead of returning a value, it returns
918
/// trace() is like evaluate(), but instead of returning a value, it returns
894
/// a string (suitable for outputting to stdout) that contains the detailed
919
/// a string (suitable for outputting to stdout) that contains the detailed
895
/// descriptions and values of each evaluation term. Useful for debugging.
920
/// descriptions and values of each evaluation term. Useful for debugging.
896
 
921
 
897
std::string Eval::trace(const Position& pos) {
922
std::string Eval::trace(const Position& pos) {
898
 
923
 
899
  std::memset(scores, 0, sizeof(scores));
924
  std::memset(scores, 0, sizeof(scores));
900
 
925
 
901
  Value v = evaluate<true>(pos);
926
  Value v = Evaluation<TRACE>(pos).value() + Eval::Tempo;
902
  v = pos.side_to_move() == WHITE ? v : -v; // White's point of view
927
  v = pos.side_to_move() == WHITE ? v : -v; // White's point of view
903
 
928
 
904
  std::stringstream ss;
929
  std::stringstream ss;
905
  ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
930
  ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
906
     << "      Eval term |    White    |    Black    |    Total    \n"
931
     << "      Eval term |    White    |    Black    |    Total    \n"
Line 908... Line 933...
908
     << "----------------+-------------+-------------+-------------\n"
933
     << "----------------+-------------+-------------+-------------\n"
909
     << "       Material | " << Term(MATERIAL)
934
     << "       Material | " << Term(MATERIAL)
910
     << "      Imbalance | " << Term(IMBALANCE)
935
     << "      Imbalance | " << Term(IMBALANCE)
911
     << "          Pawns | " << Term(PAWN)
936
     << "          Pawns | " << Term(PAWN)
912
     << "        Knights | " << Term(KNIGHT)
937
     << "        Knights | " << Term(KNIGHT)
913
     << "         Bishop | " << Term(BISHOP)
938
     << "        Bishops | " << Term(BISHOP)
914
     << "          Rooks | " << Term(ROOK)
939
     << "          Rooks | " << Term(ROOK)
915
     << "         Queens | " << Term(QUEEN)
940
     << "         Queens | " << Term(QUEEN)
916
     << "       Mobility | " << Term(MOBILITY)
941
     << "       Mobility | " << Term(MOBILITY)
917
     << "    King safety | " << Term(KING)
942
     << "    King safety | " << Term(KING)
918
     << "        Threats | " << Term(THREAT)
943
     << "        Threats | " << Term(THREAT)
919
     << "   Passed pawns | " << Term(PASSED)
944
     << "   Passed pawns | " << Term(PASSED)
920
     << "          Space | " << Term(SPACE)
945
     << "          Space | " << Term(SPACE)
-
 
946
     << "     Initiative | " << Term(INITIATIVE)
921
     << "----------------+-------------+-------------+-------------\n"
947
     << "----------------+-------------+-------------+-------------\n"
922
     << "          Total | " << Term(TOTAL);
948
     << "          Total | " << Term(TOTAL);
923
 
949
 
924
  ss << "\nTotal Evaluation: " << to_cp(v) << " (white side)\n";
950
  ss << "\nTotal Evaluation: " << to_cp(v) << " (white side)\n";
925
 
951