Subversion Repositories Games.Chess Giants

Rev

Rev 154 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
96 pmbaty 1
/*
2
  Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3
  Copyright (C) 2004-2008 Tord Romstad (Glaurung author)
4
  Copyright (C) 2008-2015 Marco Costalba, Joona Kiiski, Tord Romstad
169 pmbaty 5
  Copyright (C) 2015-2018 Marco Costalba, Joona Kiiski, Gary Linscott, Tord Romstad
96 pmbaty 6
 
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
9
  the Free Software Foundation, either version 3 of the License, or
10
  (at your option) any later version.
11
 
12
  Stockfish is distributed in the hope that it will be useful,
13
  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
  GNU General Public License for more details.
16
 
17
  You should have received a copy of the GNU General Public License
18
  along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
*/
20
 
21
#include <algorithm>
22
#include <cassert>
23
#include <cstring>   // For std::memset
24
#include <iomanip>
25
#include <sstream>
26
 
154 pmbaty 27
#include "bitboard.h"
96 pmbaty 28
#include "evaluate.h"
29
#include "material.h"
30
#include "pawns.h"
31
 
32
namespace {
33
 
169 pmbaty 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
  };
42
 
96 pmbaty 43
  namespace Trace {
44
 
169 pmbaty 45
    enum Tracing {NO_TRACE, TRACE};
46
 
96 pmbaty 47
    enum Term { // The first 8 entries are for PieceType
169 pmbaty 48
      MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, INITIATIVE, TOTAL, TERM_NB
96 pmbaty 49
    };
50
 
51
    double scores[TERM_NB][COLOR_NB][PHASE_NB];
52
 
53
    double to_cp(Value v) { return double(v) / PawnValueEg; }
54
 
55
    void add(int idx, Color c, Score s) {
56
      scores[idx][c][MG] = to_cp(mg_value(s));
57
      scores[idx][c][EG] = to_cp(eg_value(s));
58
    }
59
 
60
    void add(int idx, Score w, Score b = SCORE_ZERO) {
61
      add(idx, WHITE, w); add(idx, BLACK, b);
62
    }
63
 
64
    std::ostream& operator<<(std::ostream& os, Term t) {
65
 
169 pmbaty 66
      if (t == MATERIAL || t == IMBALANCE || t == Term(PAWN) || t == INITIATIVE || t == TOTAL)
96 pmbaty 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";
76
 
77
      return os;
78
    }
79
  }
80
 
81
  using namespace Trace;
82
 
169 pmbaty 83
  // Evaluation class contains various information computed and collected
96 pmbaty 84
  // by the evaluation functions.
169 pmbaty 85
  template<Tracing T = NO_TRACE>
86
  class Evaluation {
96 pmbaty 87
 
169 pmbaty 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 };
113
 
96 pmbaty 114
    // attackedBy[color][piece type] is a bitboard representing all squares
169 pmbaty 115
    // attacked by a given color and piece type. Special "piece types" which are
116
    // also calculated are QUEEN_DIAGONAL and ALL_PIECES.
96 pmbaty 117
    Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
118
 
154 pmbaty 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
 
96 pmbaty 124
    // kingRing[color] is the zone around the king which is considered
125
    // by the king safety evaluation. This consists of the squares directly
169 pmbaty 126
    // adjacent to the king, and (only for a king on its first rank) the
96 pmbaty 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.
130
    Bitboard kingRing[COLOR_NB];
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];
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];
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];
148
  };
149
 
150
  #define V(v) Value(v)
151
  #define S(mg, eg) make_score(mg, eg)
152
 
169 pmbaty 153
  // 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.
96 pmbaty 155
  const Score MobilityBonus[][32] = {
169 pmbaty 156
    { S(-75,-76), S(-57,-54), S( -9,-28), S( -2,-10), S(  6,  5), S( 14, 12), // Knights
157
      S( 22, 26), S( 29, 29), S( 36, 29) },
158
    { 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),
160
      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
162
      S(  9,112), S( 16,118), S( 30,132), S( 29,142), S( 32,155), S( 38,165),
163
      S( 46,166), S( 48,169), S( 58,171) },
164
    { S(-39,-36), S(-21,-15), S(  3,  8), S(  3, 18), S( 14, 34), S( 22, 54), // Queens
165
      S( 28, 61), S( 41, 73), S( 43, 79), S( 48, 92), S( 56, 94), S( 60,104),
166
      S( 60,113), S( 66,120), S( 67,123), S( 70,126), S( 71,133), S( 73,136),
167
      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) }
96 pmbaty 169
  };
170
 
169 pmbaty 171
  // Outpost[knight/bishop][supported by pawn] contains bonuses for minor
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.
96 pmbaty 175
  const Score Outpost[][2] = {
169 pmbaty 176
    { S(22, 6), S(36,12) }, // Knight
177
    { S( 9, 2), S(15, 5) }  // Bishop
96 pmbaty 178
  };
179
 
180
  // RookOnFile[semiopen/open] contains bonuses for each rook when there is no
181
  // friendly pawn on the rook file.
169 pmbaty 182
  const Score RookOnFile[] = { S(20, 7), S(45, 20) };
96 pmbaty 183
 
169 pmbaty 184
  // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
185
  // which piece type attacks which one. Attacks on lesser pieces which are
186
  // pawn-defended are not considered.
187
  const Score ThreatByMinor[PIECE_TYPE_NB] = {
188
    S(0, 0), S(0, 33), S(45, 43), S(46, 47), S(72, 107), S(48, 118)
154 pmbaty 189
  };
96 pmbaty 190
 
169 pmbaty 191
  const Score ThreatByRook[PIECE_TYPE_NB] = {
192
    S(0, 0), S(0, 25), S(40, 62), S(40, 59), S(0, 34), S(35, 48)
96 pmbaty 193
  };
194
 
169 pmbaty 195
  // ThreatByKing[on one/on many] contains bonuses for king attacks on
96 pmbaty 196
  // pawns or pieces which are not pawn-defended.
169 pmbaty 197
  const Score ThreatByKing[] = { S(3, 62), S(9, 138) };
96 pmbaty 198
 
199
  // Passed[mg/eg][Rank] contains midgame and endgame bonuses for passed pawns.
200
  // We don't use a Score because we process the two components independently.
201
  const Value Passed[][RANK_NB] = {
169 pmbaty 202
    { V(0), V(5), V( 5), V(31), V(73), V(166), V(252) },
203
    { V(0), V(7), V(14), V(38), V(73), V(166), V(252) }
96 pmbaty 204
  };
205
 
206
  // PassedFile[File] contains a bonus according to the file of a passed pawn
207
  const Score PassedFile[FILE_NB] = {
208
    S(  9, 10), S( 2, 10), S( 1, -8), S(-20,-12),
169 pmbaty 209
    S(-20,-12), S( 1, -8), S( 2, 10), S(  9, 10)
96 pmbaty 210
  };
211
 
169 pmbaty 212
  // Rank factor applied on some bonus for passed pawn on rank 4 or beyond
213
  const int RankFactor[RANK_NB] = {0, 0, 0, 2, 6, 11, 16};
214
 
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
 
96 pmbaty 218
  // Assorted bonuses and penalties used by evaluation
169 pmbaty 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);
233
  const Score HinderPassedPawn      = S(  7,  0);
234
  const Score TrappedBishopA1H1     = S( 50, 50);
96 pmbaty 235
 
236
  #undef S
237
  #undef V
238
 
239
  // KingAttackWeights[PieceType] contains king attack weights by piece type
154 pmbaty 240
  const int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 78, 56, 45, 11 };
96 pmbaty 241
 
242
  // Penalties for enemy's safe checks
169 pmbaty 243
  const int QueenSafeCheck  = 780;
244
  const int RookSafeCheck   = 880;
245
  const int BishopSafeCheck = 435;
246
  const int KnightSafeCheck = 790;
96 pmbaty 247
 
169 pmbaty 248
  // Threshold for lazy and space evaluation
249
  const Value LazyThreshold  = Value(1500);
250
  const Value SpaceThreshold = Value(12222);
96 pmbaty 251
 
252
 
169 pmbaty 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.
96 pmbaty 255
 
169 pmbaty 256
  template<Tracing T> template<Color Us>
257
  void Evaluation<T>::initialize() {
96 pmbaty 258
 
169 pmbaty 259
    const Color     Them = (Us == WHITE ? BLACK : WHITE);
260
    const Direction Up   = (Us == WHITE ? NORTH : SOUTH);
261
    const Direction Down = (Us == WHITE ? SOUTH : NORTH);
262
    const Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB: Rank7BB | Rank6BB);
96 pmbaty 263
 
169 pmbaty 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
 
278
    // Init our king safety tables only if we are going to use them
279
    if (pos.non_pawn_material(Them) >= RookValueMg + KnightValueMg)
96 pmbaty 280
    {
169 pmbaty 281
        kingRing[Us] = b;
282
        if (relative_rank(Us, pos.square<KING>(Us)) == RANK_1)
283
            kingRing[Us] |= shift<Up>(b);
284
 
285
        kingAttackersCount[Them] = popcount(b & pe->pawn_attacks(Them));
286
        kingAdjacentZoneAttacksCount[Them] = kingAttackersWeight[Them] = 0;
96 pmbaty 287
    }
288
    else
169 pmbaty 289
        kingRing[Us] = kingAttackersCount[Them] = 0;
96 pmbaty 290
  }
291
 
292
 
293
  // evaluate_pieces() assigns bonuses and penalties to the pieces of a given
294
  // color and type.
295
 
169 pmbaty 296
  template<Tracing T>  template<Color Us, PieceType Pt>
297
  Score Evaluation<T>::evaluate_pieces() {
96 pmbaty 298
 
299
    const Color Them = (Us == WHITE ? BLACK : WHITE);
300
    const Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
301
                                               : Rank5BB | Rank4BB | Rank3BB);
302
    const Square* pl = pos.squares<Pt>(Us);
303
 
169 pmbaty 304
    Bitboard b, bb;
305
    Square s;
306
    Score score = SCORE_ZERO;
96 pmbaty 307
 
169 pmbaty 308
    attackedBy[Us][Pt] = 0;
309
 
310
    if (Pt == QUEEN)
311
        attackedBy[Us][QUEEN_DIAGONAL] = 0;
312
 
96 pmbaty 313
    while ((s = *pl++) != SQ_NONE)
314
    {
315
        // Find attacked squares, including x-ray attacks for bishops and rooks
169 pmbaty 316
        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))
96 pmbaty 318
                         : pos.attacks_from<Pt>(s);
319
 
169 pmbaty 320
        if (pos.pinned_pieces(Us) & s)
96 pmbaty 321
            b &= LineBB[pos.square<KING>(Us)][s];
322
 
169 pmbaty 323
        attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
324
        attackedBy[Us][ALL_PIECES] |= attackedBy[Us][Pt] |= b;
96 pmbaty 325
 
169 pmbaty 326
        if (Pt == QUEEN)
327
            attackedBy[Us][QUEEN_DIAGONAL] |= b & PseudoAttacks[BISHOP][s];
328
 
329
        if (b & kingRing[Them])
96 pmbaty 330
        {
169 pmbaty 331
            kingAttackersCount[Us]++;
332
            kingAttackersWeight[Us] += KingAttackWeights[Pt];
333
            kingAdjacentZoneAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
96 pmbaty 334
        }
335
 
154 pmbaty 336
        int mob = popcount(b & mobilityArea[Us]);
96 pmbaty 337
 
169 pmbaty 338
        mobility[Us] += MobilityBonus[Pt - 2][mob];
96 pmbaty 339
 
169 pmbaty 340
        // Bonus for this piece as a king protector
341
        score += KingProtector[Pt - 2] * distance(s, pos.square<KING>(Us));
342
 
96 pmbaty 343
        if (Pt == BISHOP || Pt == KNIGHT)
344
        {
345
            // Bonus for outpost squares
169 pmbaty 346
            bb = OutpostRanks & ~pe->pawn_attacks_span(Them);
96 pmbaty 347
            if (bb & s)
169 pmbaty 348
                score += Outpost[Pt == BISHOP][bool(attackedBy[Us][PAWN] & s)] * 2;
96 pmbaty 349
            else
350
            {
351
                bb &= b & ~pos.pieces(Us);
352
                if (bb)
169 pmbaty 353
                   score += Outpost[Pt == BISHOP][bool(attackedBy[Us][PAWN] & bb)];
96 pmbaty 354
            }
355
 
356
            // Bonus when behind a pawn
357
            if (    relative_rank(Us, s) < RANK_5
358
                && (pos.pieces(PAWN) & (s + pawn_push(Us))))
359
                score += MinorBehindPawn;
360
 
361
            if (Pt == BISHOP)
169 pmbaty 362
            {
363
                // Penalty for pawns on the same color square as the bishop
364
                score -= BishopPawns * pe->pawns_on_same_color_squares(Us, s);
96 pmbaty 365
 
169 pmbaty 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
            }
370
 
96 pmbaty 371
            // An important Chess960 pattern: A cornered bishop blocked by a friendly
372
            // pawn diagonally in front of it is a very serious problem, especially
373
            // when that pawn is also blocked.
374
            if (   Pt == BISHOP
375
                && pos.is_chess960()
376
                && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
377
            {
169 pmbaty 378
                Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
96 pmbaty 379
                if (pos.piece_on(s + d) == make_piece(Us, PAWN))
380
                    score -= !pos.empty(s + d + pawn_push(Us))                ? TrappedBishopA1H1 * 4
381
                            : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? TrappedBishopA1H1 * 2
382
                                                                              : TrappedBishopA1H1;
383
            }
384
        }
385
 
386
        if (Pt == ROOK)
387
        {
388
            // Bonus for aligning with enemy pawns on the same rank/file
389
            if (relative_rank(Us, s) >= RANK_5)
154 pmbaty 390
                score += RookOnPawn * popcount(pos.pieces(Them, PAWN) & PseudoAttacks[ROOK][s]);
96 pmbaty 391
 
392
            // Bonus when on an open or semi-open file
169 pmbaty 393
            if (pe->semiopen_file(Us, file_of(s)))
394
                score += RookOnFile[bool(pe->semiopen_file(Them, file_of(s)))];
96 pmbaty 395
 
169 pmbaty 396
            // Penalty when trapped by the king, even more if the king cannot castle
96 pmbaty 397
            else if (mob <= 3)
398
            {
399
                Square ksq = pos.square<KING>(Us);
400
 
401
                if (   ((file_of(ksq) < FILE_E) == (file_of(s) < file_of(ksq)))
169 pmbaty 402
                    && !pe->semiopen_side(Us, file_of(ksq), file_of(s) < file_of(ksq)))
96 pmbaty 403
                    score -= (TrappedRook - make_score(mob * 22, 0)) * (1 + !pos.can_castle(Us));
404
            }
405
        }
154 pmbaty 406
 
407
        if (Pt == QUEEN)
408
        {
409
            // Penalty if any relative pin or discovered attack against the queen
410
            Bitboard pinners;
411
            if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, pinners))
412
                score -= WeakQueen;
413
        }
96 pmbaty 414
    }
415
 
169 pmbaty 416
    if (T)
96 pmbaty 417
        Trace::add(Pt, Us, score);
418
 
169 pmbaty 419
    return score;
96 pmbaty 420
  }
421
 
422
 
423
  // evaluate_king() assigns bonuses and penalties to a king of a given color
424
 
169 pmbaty 425
  template<Tracing T>  template<Color Us>
426
  Score Evaluation<T>::evaluate_king() {
154 pmbaty 427
 
169 pmbaty 428
    const Color     Them = (Us == WHITE ? BLACK : WHITE);
429
    const Bitboard  Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
430
                                        : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
154 pmbaty 431
 
96 pmbaty 432
    const Square ksq = pos.square<KING>(Us);
169 pmbaty 433
    Bitboard weak, b, b1, b2, safe, unsafeChecks;
96 pmbaty 434
 
435
    // King shelter and enemy pawns storm
169 pmbaty 436
    Score score = pe->king_safety<Us>(pos, ksq);
96 pmbaty 437
 
438
    // Main king safety evaluation
169 pmbaty 439
    if (kingAttackersCount[Them] > (1 - pos.count<QUEEN>(Them)))
96 pmbaty 440
    {
169 pmbaty 441
        // Attacked squares defended at most once by our queen or king
442
        weak =  attackedBy[Them][ALL_PIECES]
443
              & ~attackedBy2[Us]
444
              & (attackedBy[Us][KING] | attackedBy[Us][QUEEN] | ~attackedBy[Us][ALL_PIECES]);
445
 
446
        unsafeChecks = 0; // Pierre-Marie Baty -- fixed variable initialization
447
        int kingDanger = 0;
96 pmbaty 448
 
169 pmbaty 449
        // Analyse the safe enemy's checks which are possible on next move
450
        safe  = ~pos.pieces(Them);
451
        safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
154 pmbaty 452
 
169 pmbaty 453
        b1 = attacks_bb<ROOK  >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
454
        b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
96 pmbaty 455
 
456
        // Enemy queen safe checks
169 pmbaty 457
        if ((b1 | b2) & attackedBy[Them][QUEEN] & safe & ~attackedBy[Us][QUEEN])
458
            kingDanger += QueenSafeCheck;
96 pmbaty 459
 
169 pmbaty 460
        b1 &= attackedBy[Them][ROOK];
461
        b2 &= attackedBy[Them][BISHOP];
96 pmbaty 462
 
169 pmbaty 463
        // Enemy rooks checks
464
        if (b1 & safe)
465
            kingDanger += RookSafeCheck;
466
        else
467
            unsafeChecks |= b1;
96 pmbaty 468
 
169 pmbaty 469
        // Enemy bishops checks
470
        if (b2 & safe)
471
            kingDanger += BishopSafeCheck;
472
        else
473
            unsafeChecks |= b2;
96 pmbaty 474
 
169 pmbaty 475
        // Enemy knights checks
476
        b = pos.attacks_from<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
477
        if (b & safe)
478
            kingDanger += KnightSafeCheck;
479
        else
480
            unsafeChecks |= b;
154 pmbaty 481
 
169 pmbaty 482
        // Unsafe or occupied checking squares will also be considered, as long as
483
        // the square is in the attacker's mobility area.
484
        unsafeChecks &= mobilityArea[Them];
154 pmbaty 485
 
169 pmbaty 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;
154 pmbaty 493
 
169 pmbaty 494
        // Transform the kingDanger units into a Score, and subtract it from the evaluation
154 pmbaty 495
        if (kingDanger > 0)
169 pmbaty 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);
500
        }
96 pmbaty 501
    }
502
 
154 pmbaty 503
    // King tropism: firstly, find squares that opponent attacks in our king flank
504
    File kf = file_of(ksq);
169 pmbaty 505
    b = attackedBy[Them][ALL_PIECES] & KingFlank[kf] & Camp;
154 pmbaty 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)
169 pmbaty 513
       | (b & attackedBy2[Them] & ~attackedBy[Us][PAWN]);
154 pmbaty 514
 
515
    score -= CloseEnemies * popcount(b);
516
 
517
    // Penalty when our king is on a pawnless flank
169 pmbaty 518
    if (!(pos.pieces(PAWN) & KingFlank[kf]))
154 pmbaty 519
        score -= PawnlessFlank;
520
 
169 pmbaty 521
    if (T)
96 pmbaty 522
        Trace::add(KING, Us, score);
523
 
524
    return score;
525
  }
526
 
527
 
154 pmbaty 528
  // evaluate_threats() assigns bonuses according to the types of the attacking
96 pmbaty 529
  // and the attacked pieces.
530
 
169 pmbaty 531
  template<Tracing T>  template<Color Us>
532
  Score Evaluation<T>::evaluate_threats() {
96 pmbaty 533
 
169 pmbaty 534
    const Color     Them     = (Us == WHITE ? BLACK      : WHITE);
535
    const 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);
96 pmbaty 539
 
169 pmbaty 540
    Bitboard b, weak, defended, stronglyProtected, safeThreats;
96 pmbaty 541
    Score score = SCORE_ZERO;
542
 
543
    // Non-pawn enemies attacked by a pawn
169 pmbaty 544
    weak = (pos.pieces(Them) ^ pos.pieces(Them, PAWN)) & attackedBy[Us][PAWN];
96 pmbaty 545
 
546
    if (weak)
547
    {
169 pmbaty 548
        b = pos.pieces(Us, PAWN) & ( ~attackedBy[Them][ALL_PIECES]
549
                                    | attackedBy[Us][ALL_PIECES]);
96 pmbaty 550
 
154 pmbaty 551
        safeThreats = (shift<Right>(b) | shift<Left>(b)) & weak;
96 pmbaty 552
 
169 pmbaty 553
        score += ThreatBySafePawn * popcount(safeThreats);
96 pmbaty 554
    }
555
 
169 pmbaty 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]);
96 pmbaty 560
 
169 pmbaty 561
    // Non-pawn enemies, strongly protected
562
    defended =  (pos.pieces(Them) ^ pos.pieces(Them, PAWN))
563
              & stronglyProtected;
564
 
565
    // Enemies not strongly protected and under our attack
96 pmbaty 566
    weak =   pos.pieces(Them)
169 pmbaty 567
          & ~stronglyProtected
568
          &  attackedBy[Us][ALL_PIECES];
96 pmbaty 569
 
570
    // Add a bonus according to the kind of attacking pieces
571
    if (defended | weak)
572
    {
169 pmbaty 573
        b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
96 pmbaty 574
        while (b)
169 pmbaty 575
        {
576
            Square s = 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
        }
96 pmbaty 581
 
169 pmbaty 582
        b = (pos.pieces(Them, QUEEN) | weak) & attackedBy[Us][ROOK];
96 pmbaty 583
        while (b)
169 pmbaty 584
        {
585
            Square s = 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
        }
96 pmbaty 590
 
169 pmbaty 591
        score += Hanging * popcount(weak & ~attackedBy[Them][ALL_PIECES]);
96 pmbaty 592
 
169 pmbaty 593
        b = weak & attackedBy[Us][KING];
96 pmbaty 594
        if (b)
595
            score += ThreatByKing[more_than_one(b)];
596
    }
597
 
169 pmbaty 598
    // Bonus for opponent unopposed weak pawns
599
    if (pos.pieces(Us, ROOK, QUEEN))
600
        score += WeakUnopposedPawn * pe->weak_unopposed(Them);
96 pmbaty 601
 
169 pmbaty 602
    // Find squares where our pawns can push on the next move
603
    b  = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
604
    b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
96 pmbaty 605
 
169 pmbaty 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
154 pmbaty 611
    b =  (shift<Left>(b) | shift<Right>(b))
96 pmbaty 612
       &  pos.pieces(Them)
169 pmbaty 613
       & ~attackedBy[Us][PAWN];
96 pmbaty 614
 
154 pmbaty 615
    score += ThreatByPawnPush * popcount(b);
96 pmbaty 616
 
169 pmbaty 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
 
624
    if (T)
96 pmbaty 625
        Trace::add(THREAT, Us, score);
626
 
627
    return score;
628
  }
629
 
169 pmbaty 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
  }
96 pmbaty 635
 
169 pmbaty 636
  // evaluate_passed_pawns() evaluates the passed pawns and candidate passed
637
  // pawns of the given color.
96 pmbaty 638
 
169 pmbaty 639
  template<Tracing T>  template<Color Us>
640
  Score Evaluation<T>::evaluate_passed_pawns() {
96 pmbaty 641
 
169 pmbaty 642
    const Color     Them = (Us == WHITE ? BLACK : WHITE);
643
    const Direction Up   = (Us == WHITE ? NORTH : SOUTH);
96 pmbaty 644
 
154 pmbaty 645
    Bitboard b, bb, squaresToQueen, defendedSquares, unsafeSquares;
96 pmbaty 646
    Score score = SCORE_ZERO;
647
 
169 pmbaty 648
    b = pe->passed_pawns(Us);
96 pmbaty 649
 
650
    while (b)
651
    {
652
        Square s = pop_lsb(&b);
653
 
169 pmbaty 654
        assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
96 pmbaty 655
 
169 pmbaty 656
        bb = forward_file_bb(Us, s) & (attackedBy[Them][ALL_PIECES] | pos.pieces(Them));
154 pmbaty 657
        score -= HinderPassedPawn * popcount(bb);
658
 
169 pmbaty 659
        int r = relative_rank(Us, s);
660
        int rr = RankFactor[r];
96 pmbaty 661
 
662
        Value mbonus = Passed[MG][r], ebonus = Passed[EG][r];
663
 
664
        if (rr)
665
        {
169 pmbaty 666
            Square blockSq = s + Up;
96 pmbaty 667
 
668
            // Adjust bonus based on the king's proximity
169 pmbaty 669
            ebonus += (king_distance(Them, blockSq) * 5 - king_distance(Us, blockSq) * 2) * rr;
96 pmbaty 670
 
671
            // If blockSq is not the queening square then consider also a second push
169 pmbaty 672
            if (r != RANK_7)
673
                ebonus -= king_distance(Us, blockSq + Up) * rr;
96 pmbaty 674
 
675
            // If the pawn is free to advance, then increase the bonus
676
            if (pos.empty(blockSq))
677
            {
678
                // If there is a rook or queen attacking/defending the pawn from behind,
679
                // consider all the squaresToQueen. Otherwise consider only the squares
680
                // in the pawn's path attacked or occupied by the enemy.
169 pmbaty 681
                defendedSquares = unsafeSquares = squaresToQueen = forward_file_bb(Us, s);
96 pmbaty 682
 
169 pmbaty 683
                bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN) & pos.attacks_from<ROOK>(s);
96 pmbaty 684
 
685
                if (!(pos.pieces(Us) & bb))
169 pmbaty 686
                    defendedSquares &= attackedBy[Us][ALL_PIECES];
96 pmbaty 687
 
688
                if (!(pos.pieces(Them) & bb))
169 pmbaty 689
                    unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
96 pmbaty 690
 
691
                // If there aren't any enemy attacks, assign a big bonus. Otherwise
692
                // assign a smaller bonus if the block square isn't attacked.
693
                int k = !unsafeSquares ? 18 : !(unsafeSquares & blockSq) ? 8 : 0;
694
 
695
                // 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.
697
                if (defendedSquares == squaresToQueen)
698
                    k += 6;
699
 
700
                else if (defendedSquares & blockSq)
701
                    k += 4;
702
 
154 pmbaty 703
                mbonus += k * rr, ebonus += k * rr;
96 pmbaty 704
            }
705
            else if (pos.pieces(Us) & blockSq)
154 pmbaty 706
                mbonus += rr + r * 2, ebonus += rr + r * 2;
96 pmbaty 707
        } // rr != 0
708
 
169 pmbaty 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;
713
 
96 pmbaty 714
        score += make_score(mbonus, ebonus) + PassedFile[file_of(s)];
715
    }
716
 
169 pmbaty 717
    if (T)
96 pmbaty 718
        Trace::add(PASSED, Us, score);
719
 
720
    return score;
721
  }
722
 
723
 
724
  // evaluate_space() computes the space evaluation for a given side. The
725
  // 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
727
  // 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
729
  // improve play on game opening.
730
 
169 pmbaty 731
  template<Tracing T>  template<Color Us>
732
  Score Evaluation<T>::evaluate_space() {
733
 
96 pmbaty 734
    const Color Them = (Us == WHITE ? BLACK : WHITE);
735
    const Bitboard SpaceMask =
169 pmbaty 736
      Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
737
                  : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
96 pmbaty 738
 
739
    // Find the safe squares for our pieces inside the area defined by
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
743
                   & ~pos.pieces(Us, PAWN)
169 pmbaty 744
                   & ~attackedBy[Them][PAWN]
745
                   & (attackedBy[Us][ALL_PIECES] | ~attackedBy[Them][ALL_PIECES]);
96 pmbaty 746
 
747
    // Find all squares which are at most three squares behind some friendly pawn
748
    Bitboard behind = pos.pieces(Us, PAWN);
749
    behind |= (Us == WHITE ? behind >>  8 : behind <<  8);
750
    behind |= (Us == WHITE ? behind >> 16 : behind << 16);
751
 
752
    // Since SpaceMask[Us] is fully on our half of the board...
753
    assert(unsigned(safe >> (Us == WHITE ? 32 : 0)) == 0);
754
 
169 pmbaty 755
    // ...count safe + (behind & safe) with a single popcount.
154 pmbaty 756
    int bonus = popcount((Us == WHITE ? safe << 32 : safe >> 32) | (behind & safe));
169 pmbaty 757
    int weight = pos.count<ALL_PIECES>(Us) - 2 * pe->open_files();
96 pmbaty 758
 
169 pmbaty 759
    return make_score(bonus * weight * weight / 16, 0);
96 pmbaty 760
  }
761
 
762
 
763
  // evaluate_initiative() computes the initiative correction value for the
764
  // position, i.e., second order bonus/malus based on the known attacking/defending
765
  // status of the players.
766
 
169 pmbaty 767
  template<Tracing T>
768
  Score Evaluation<T>::evaluate_initiative(Value eg) {
769
 
154 pmbaty 770
    int kingDistance =  distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
771
                      - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
169 pmbaty 772
    bool bothFlanks = (pos.pieces(PAWN) & QueenSide) && (pos.pieces(PAWN) & KingSide);
96 pmbaty 773
 
774
    // Compute the initiative bonus for the attacking side
169 pmbaty 775
    int initiative = 8 * (pe->pawn_asymmetry() + kingDistance - 17) + 12 * pos.count<PAWN>() + 16 * bothFlanks;
96 pmbaty 776
 
777
    // 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
169 pmbaty 779
    // that the endgame score will never change sign after the bonus.
780
    int v = ((eg > 0) - (eg < 0)) * std::max(initiative, -abs(eg));
96 pmbaty 781
 
169 pmbaty 782
    if (T)
783
        Trace::add(INITIATIVE, make_score(0, v));
784
 
785
    return make_score(0, v);
96 pmbaty 786
  }
787
 
788
 
789
  // evaluate_scale_factor() computes the scale factor for the winning side
790
 
169 pmbaty 791
  template<Tracing T>
792
  ScaleFactor Evaluation<T>::evaluate_scale_factor(Value eg) {
793
 
154 pmbaty 794
    Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
169 pmbaty 795
    ScaleFactor sf = me->scale_factor(pos, strongSide);
96 pmbaty 796
 
797
    // If we don't already have an unusual scale factor, check for certain
798
    // types of endgames, and use a lower scale for those.
169 pmbaty 799
    if (sf == SCALE_FACTOR_NORMAL || sf == SCALE_FACTOR_ONEPAWN)
96 pmbaty 800
    {
801
        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.
805
            if (   pos.non_pawn_material(WHITE) == BishopValueMg
806
                && pos.non_pawn_material(BLACK) == BishopValueMg)
169 pmbaty 807
                return more_than_one(pos.pieces(PAWN)) ? ScaleFactor(31) : ScaleFactor(9);
96 pmbaty 808
 
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.
169 pmbaty 811
            return ScaleFactor(46);
96 pmbaty 812
        }
813
        // Endings where weaker side can place his king in front of the opponent's
814
        // pawns are drawish.
154 pmbaty 815
        else if (    abs(eg) <= BishopValueEg
816
                 &&  pos.count<PAWN>(strongSide) <= 2
96 pmbaty 817
                 && !pos.pawn_passed(~strongSide, pos.square<KING>(~strongSide)))
169 pmbaty 818
            return ScaleFactor(37 + 7 * pos.count<PAWN>(strongSide));
96 pmbaty 819
    }
820
 
821
    return sf;
822
  }
823
 
824
 
169 pmbaty 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.
96 pmbaty 828
 
169 pmbaty 829
  template<Tracing T>
830
  Value Evaluation<T>::value() {
96 pmbaty 831
 
169 pmbaty 832
    assert(!pos.checkers());
96 pmbaty 833
 
169 pmbaty 834
    // Probe the material hash table
835
    me = Material::probe(pos);
96 pmbaty 836
 
169 pmbaty 837
    // If we have a specialized evaluation function for the current material
838
    // configuration, call it and return.
839
    if (me->specialized_eval_exists())
840
        return me->evaluate(pos);
96 pmbaty 841
 
169 pmbaty 842
    // Initialize score by reading the incrementally updated scores included in
843
    // the position object (material + piece square tables) and the material
844
    // imbalance. Score is computed internally from the white point of view.
845
    Score score = pos.psq_score() + me->imbalance() + Eval::Contempt;
96 pmbaty 846
 
169 pmbaty 847
    // Probe the pawn hash table
848
    pe = Pawns::probe(pos);
849
    score += pe->pawns_score();
96 pmbaty 850
 
169 pmbaty 851
    // Early exit if score is high
852
    Value v = (mg_value(score) + eg_value(score)) / 2;
853
    if (abs(v) > LazyThreshold)
854
       return pos.side_to_move() == WHITE ? v : -v;
154 pmbaty 855
 
169 pmbaty 856
    // Main evaluation begins here
96 pmbaty 857
 
169 pmbaty 858
    initialize<WHITE>();
859
    initialize<BLACK>();
96 pmbaty 860
 
169 pmbaty 861
    score += evaluate_pieces<WHITE, KNIGHT>() - evaluate_pieces<BLACK, KNIGHT>();
862
    score += evaluate_pieces<WHITE, BISHOP>() - evaluate_pieces<BLACK, BISHOP>();
863
    score += evaluate_pieces<WHITE, ROOK  >() - evaluate_pieces<BLACK, ROOK  >();
864
    score += evaluate_pieces<WHITE, QUEEN >() - evaluate_pieces<BLACK, QUEEN >();
96 pmbaty 865
 
169 pmbaty 866
    score += mobility[WHITE] - mobility[BLACK];
96 pmbaty 867
 
169 pmbaty 868
    score +=  evaluate_king<WHITE>()
869
            - evaluate_king<BLACK>();
96 pmbaty 870
 
169 pmbaty 871
    score +=  evaluate_threats<WHITE>()
872
            - evaluate_threats<BLACK>();
96 pmbaty 873
 
169 pmbaty 874
    score +=  evaluate_passed_pawns<WHITE>()
875
            - evaluate_passed_pawns<BLACK>();
96 pmbaty 876
 
169 pmbaty 877
    if (pos.non_pawn_material() >= SpaceThreshold)
878
        score +=  evaluate_space<WHITE>()
879
                - evaluate_space<BLACK>();
96 pmbaty 880
 
169 pmbaty 881
    score += evaluate_initiative(eg_value(score));
96 pmbaty 882
 
169 pmbaty 883
    // Interpolate between a middlegame and a (scaled by 'sf') endgame score
884
    ScaleFactor sf = evaluate_scale_factor(eg_value(score));
885
    v =  mg_value(score) * int(me->game_phase())
886
       + eg_value(score) * int(PHASE_MIDGAME - me->game_phase()) * sf / SCALE_FACTOR_NORMAL;
96 pmbaty 887
 
169 pmbaty 888
    v /= int(PHASE_MIDGAME);
96 pmbaty 889
 
169 pmbaty 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());
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
    }
96 pmbaty 902
 
169 pmbaty 903
    return pos.side_to_move() == WHITE ? v : -v; // Side to move point of view
904
  }
96 pmbaty 905
 
169 pmbaty 906
} // namespace
96 pmbaty 907
 
169 pmbaty 908
Score Eval::Contempt = SCORE_ZERO;
96 pmbaty 909
 
169 pmbaty 910
/// evaluate() is the evaluator for the outer world. It returns a static evaluation
911
/// of the position from the point of view of the side to move.
96 pmbaty 912
 
169 pmbaty 913
Value Eval::evaluate(const Position& pos)
914
{
915
   return Evaluation<>(pos).value() + Eval::Tempo;
96 pmbaty 916
}
917
 
918
/// trace() is like evaluate(), but instead of returning a value, it returns
919
/// a string (suitable for outputting to stdout) that contains the detailed
920
/// descriptions and values of each evaluation term. Useful for debugging.
921
 
922
std::string Eval::trace(const Position& pos) {
923
 
924
  std::memset(scores, 0, sizeof(scores));
925
 
169 pmbaty 926
  Value v = Evaluation<TRACE>(pos).value() + Eval::Tempo;
96 pmbaty 927
  v = pos.side_to_move() == WHITE ? v : -v; // White's point of view
928
 
929
  std::stringstream ss;
930
  ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
931
     << "      Eval term |    White    |    Black    |    Total    \n"
932
     << "                |   MG    EG  |   MG    EG  |   MG    EG  \n"
933
     << "----------------+-------------+-------------+-------------\n"
934
     << "       Material | " << Term(MATERIAL)
935
     << "      Imbalance | " << Term(IMBALANCE)
936
     << "          Pawns | " << Term(PAWN)
937
     << "        Knights | " << Term(KNIGHT)
169 pmbaty 938
     << "        Bishops | " << Term(BISHOP)
96 pmbaty 939
     << "          Rooks | " << Term(ROOK)
940
     << "         Queens | " << Term(QUEEN)
941
     << "       Mobility | " << Term(MOBILITY)
942
     << "    King safety | " << Term(KING)
943
     << "        Threats | " << Term(THREAT)
944
     << "   Passed pawns | " << Term(PASSED)
945
     << "          Space | " << Term(SPACE)
169 pmbaty 946
     << "     Initiative | " << Term(INITIATIVE)
96 pmbaty 947
     << "----------------+-------------+-------------+-------------\n"
948
     << "          Total | " << Term(TOTAL);
949
 
950
  ss << "\nTotal Evaluation: " << to_cp(v) << " (white side)\n";
951
 
952
  return ss.str();
953
}