Subversion Repositories Games.Chess Giants

Rev

Rev 169 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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