]> git.sesse.net Git - stockfish/blob - src/evaluate.cpp
Small trivial clean-ups, February 2021
[stockfish] / src / evaluate.cpp
1 /*
2   Stockfish, a UCI chess playing engine derived from Glaurung 2.1
3   Copyright (C) 2004-2021 The Stockfish developers (see AUTHORS file)
4
5   Stockfish is free software: you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation, either version 3 of the License, or
8   (at your option) any later version.
9
10   Stockfish is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include <algorithm>
20 #include <cassert>
21 #include <cstdlib>
22 #include <cstring>   // For std::memset
23 #include <fstream>
24 #include <iomanip>
25 #include <sstream>
26 #include <iostream>
27 #include <streambuf>
28 #include <vector>
29
30 #include "bitboard.h"
31 #include "evaluate.h"
32 #include "material.h"
33 #include "misc.h"
34 #include "pawns.h"
35 #include "thread.h"
36 #include "uci.h"
37 #include "incbin/incbin.h"
38
39
40 // Macro to embed the default efficiently updatable neural network (NNUE) file
41 // data in the engine binary (using incbin.h, by Dale Weiler).
42 // This macro invocation will declare the following three variables
43 //     const unsigned char        gEmbeddedNNUEData[];  // a pointer to the embedded data
44 //     const unsigned char *const gEmbeddedNNUEEnd;     // a marker to the end
45 //     const unsigned int         gEmbeddedNNUESize;    // the size of the embedded file
46 // Note that this does not work in Microsoft Visual Studio.
47 #if !defined(_MSC_VER) && !defined(NNUE_EMBEDDING_OFF)
48   INCBIN(EmbeddedNNUE, EvalFileDefaultName);
49 #else
50   const unsigned char        gEmbeddedNNUEData[1] = {0x0};
51   const unsigned char *const gEmbeddedNNUEEnd = &gEmbeddedNNUEData[1];
52   const unsigned int         gEmbeddedNNUESize = 1;
53 #endif
54
55
56 using namespace std;
57 using namespace Eval::NNUE;
58
59 namespace Eval {
60
61   bool useNNUE;
62   string eval_file_loaded = "None";
63
64   /// NNUE::init() tries to load a NNUE network at startup time, or when the engine
65   /// receives a UCI command "setoption name EvalFile value nn-[a-z0-9]{12}.nnue"
66   /// The name of the NNUE network is always retrieved from the EvalFile option.
67   /// We search the given network in three locations: internally (the default
68   /// network may be embedded in the binary), in the active working directory and
69   /// in the engine directory. Distro packagers may define the DEFAULT_NNUE_DIRECTORY
70   /// variable to have the engine search in a special directory in their distro.
71
72   void NNUE::init() {
73
74     useNNUE = Options["Use NNUE"];
75     if (!useNNUE)
76         return;
77
78     string eval_file = string(Options["EvalFile"]);
79
80     #if defined(DEFAULT_NNUE_DIRECTORY)
81     #define stringify2(x) #x
82     #define stringify(x) stringify2(x)
83     vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) };
84     #else
85     vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory };
86     #endif
87
88     for (string directory : dirs)
89         if (eval_file_loaded != eval_file)
90         {
91             if (directory != "<internal>")
92             {
93                 ifstream stream(directory + eval_file, ios::binary);
94                 if (load_eval(eval_file, stream))
95                     eval_file_loaded = eval_file;
96             }
97
98             if (directory == "<internal>" && eval_file == EvalFileDefaultName)
99             {
100                 // C++ way to prepare a buffer for a memory stream
101                 class MemoryBuffer : public basic_streambuf<char> {
102                     public: MemoryBuffer(char* p, size_t n) { setg(p, p, p + n); setp(p, p + n); }
103                 };
104
105                 MemoryBuffer buffer(const_cast<char*>(reinterpret_cast<const char*>(gEmbeddedNNUEData)),
106                                     size_t(gEmbeddedNNUESize));
107
108                 istream stream(&buffer);
109                 if (load_eval(eval_file, stream))
110                     eval_file_loaded = eval_file;
111             }
112         }
113   }
114
115   /// NNUE::verify() verifies that the last net used was loaded successfully
116   void NNUE::verify() {
117
118     string eval_file = string(Options["EvalFile"]);
119
120     if (useNNUE && eval_file_loaded != eval_file)
121     {
122         UCI::OptionsMap defaults;
123         UCI::init(defaults);
124
125         string msg1 = "If the UCI option \"Use NNUE\" is set to true, network evaluation parameters compatible with the engine must be available.";
126         string msg2 = "The option is set to true, but the network file " + eval_file + " was not loaded successfully.";
127         string msg3 = "The UCI option EvalFile might need to specify the full path, including the directory name, to the network file.";
128         string msg4 = "The default net can be downloaded from: https://tests.stockfishchess.org/api/nn/" + string(defaults["EvalFile"]);
129         string msg5 = "The engine will be terminated now.";
130
131         sync_cout << "info string ERROR: " << msg1 << sync_endl;
132         sync_cout << "info string ERROR: " << msg2 << sync_endl;
133         sync_cout << "info string ERROR: " << msg3 << sync_endl;
134         sync_cout << "info string ERROR: " << msg4 << sync_endl;
135         sync_cout << "info string ERROR: " << msg5 << sync_endl;
136
137         exit(EXIT_FAILURE);
138     }
139
140     if (useNNUE)
141         sync_cout << "info string NNUE evaluation using " << eval_file << " enabled" << sync_endl;
142     else
143         sync_cout << "info string classical evaluation enabled" << sync_endl;
144   }
145 }
146
147 namespace Trace {
148
149   enum Tracing { NO_TRACE, TRACE };
150
151   enum Term { // The first 8 entries are reserved for PieceType
152     MATERIAL = 8, IMBALANCE, MOBILITY, THREAT, PASSED, SPACE, WINNABLE, TOTAL, TERM_NB
153   };
154
155   Score scores[TERM_NB][COLOR_NB];
156
157   double to_cp(Value v) { return double(v) / PawnValueEg; }
158
159   void add(int idx, Color c, Score s) {
160     scores[idx][c] = s;
161   }
162
163   void add(int idx, Score w, Score b = SCORE_ZERO) {
164     scores[idx][WHITE] = w;
165     scores[idx][BLACK] = b;
166   }
167
168   std::ostream& operator<<(std::ostream& os, Score s) {
169     os << std::setw(5) << to_cp(mg_value(s)) << " "
170        << std::setw(5) << to_cp(eg_value(s));
171     return os;
172   }
173
174   std::ostream& operator<<(std::ostream& os, Term t) {
175
176     if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
177         os << " ----  ----"    << " | " << " ----  ----";
178     else
179         os << scores[t][WHITE] << " | " << scores[t][BLACK];
180
181     os << " | " << scores[t][WHITE] - scores[t][BLACK] << "\n";
182     return os;
183   }
184 }
185
186 using namespace Trace;
187
188 namespace {
189
190   // Threshold for lazy and space evaluation
191   constexpr Value LazyThreshold1 =  Value(1565);
192   constexpr Value LazyThreshold2 =  Value(1102);
193   constexpr Value SpaceThreshold = Value(11551);
194   constexpr Value NNUEThreshold1 =   Value(682);
195   constexpr Value NNUEThreshold2 =   Value(176);
196
197   // KingAttackWeights[PieceType] contains king attack weights by piece type
198   constexpr int KingAttackWeights[PIECE_TYPE_NB] = { 0, 0, 81, 52, 44, 10 };
199
200   // SafeCheck[PieceType][single/multiple] contains safe check bonus by piece type,
201   // higher if multiple safe checks are possible for that piece type.
202   constexpr int SafeCheck[][2] = {
203       {}, {}, {803, 1292}, {639, 974}, {1087, 1878}, {759, 1132}
204   };
205
206 #define S(mg, eg) make_score(mg, eg)
207
208   // MobilityBonus[PieceType-2][attacked] contains bonuses for middle and end game,
209   // indexed by piece type and number of attacked squares in the mobility area.
210   constexpr Score MobilityBonus[][32] = {
211     { S(-62,-79), S(-53,-57), S(-12,-31), S( -3,-17), S(  3,  7), S( 12, 13), // Knight
212       S( 21, 16), S( 28, 21), S( 37, 26) },
213     { S(-47,-59), S(-20,-25), S( 14, -8), S( 29, 12), S( 39, 21), S( 53, 40), // Bishop
214       S( 53, 56), S( 60, 58), S( 62, 65), S( 69, 72), S( 78, 78), S( 83, 87),
215       S( 91, 88), S( 96, 98) },
216     { S(-60,-82), S(-24,-15), S(  0, 17) ,S(  3, 43), S(  4, 72), S( 14,100), // Rook
217       S( 20,102), S( 30,122), S( 41,133), S(41 ,139), S( 41,153), S( 45,160),
218       S( 57,165), S( 58,170), S( 67,175) },
219     { S(-29,-49), S(-16,-29), S( -8, -8), S( -8, 17), S( 18, 39), S( 25, 54), // Queen
220       S( 23, 59), S( 37, 73), S( 41, 76), S( 54, 95), S( 65, 95) ,S( 68,101),
221       S( 69,124), S( 70,128), S( 70,132), S( 70,133) ,S( 71,136), S( 72,140),
222       S( 74,147), S( 76,149), S( 90,153), S(104,169), S(105,171), S(106,171),
223       S(112,178), S(114,185), S(114,187), S(119,221) }
224   };
225
226   // BishopPawns[distance from edge] contains a file-dependent penalty for pawns on
227   // squares of the same color as our bishop.
228   constexpr Score BishopPawns[int(FILE_NB) / 2] = {
229     S(3, 8), S(3, 9), S(2, 8), S(3, 8)
230   };
231
232   // KingProtector[knight/bishop] contains penalty for each distance unit to own king
233   constexpr Score KingProtector[] = { S(8, 9), S(6, 9) };
234
235   // Outpost[knight/bishop] contains bonuses for each knight or bishop occupying a
236   // pawn protected square on rank 4 to 6 which is also safe from a pawn attack.
237   constexpr Score Outpost[] = { S(57, 38), S(31, 24) };
238
239   // PassedRank[Rank] contains a bonus according to the rank of a passed pawn
240   constexpr Score PassedRank[RANK_NB] = {
241     S(0, 0), S(7, 27), S(16, 32), S(17, 40), S(64, 71), S(170, 174), S(278, 262)
242   };
243
244   constexpr Score RookOnClosedFile = S(10, 5);
245   constexpr Score RookOnOpenFile[] = { S(19, 6), S(47, 26) };
246
247   // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
248   // which piece type attacks which one. Attacks on lesser pieces which are
249   // pawn-defended are not considered.
250   constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
251     S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
252   };
253
254   constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
255     S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
256   };
257
258   // Assorted bonuses and penalties
259   constexpr Score UncontestedOutpost  = S(  1, 10);
260   constexpr Score BishopOnKingRing    = S( 24,  0);
261   constexpr Score BishopXRayPawns     = S(  4,  5);
262   constexpr Score CorneredBishop      = S( 50, 50);
263   constexpr Score FlankAttacks        = S(  8,  0);
264   constexpr Score Hanging             = S( 69, 36);
265   constexpr Score KnightOnQueen       = S( 16, 11);
266   constexpr Score LongDiagonalBishop  = S( 45,  0);
267   constexpr Score MinorBehindPawn     = S( 18,  3);
268   constexpr Score PassedFile          = S( 11,  8);
269   constexpr Score PawnlessFlank       = S( 17, 95);
270   constexpr Score ReachableOutpost    = S( 31, 22);
271   constexpr Score RestrictedPiece     = S(  7,  7);
272   constexpr Score RookOnKingRing      = S( 16,  0);
273   constexpr Score SliderOnQueen       = S( 60, 18);
274   constexpr Score ThreatByKing        = S( 24, 89);
275   constexpr Score ThreatByPawnPush    = S( 48, 39);
276   constexpr Score ThreatBySafePawn    = S(173, 94);
277   constexpr Score TrappedRook         = S( 55, 13);
278   constexpr Score WeakQueenProtection = S( 14,  0);
279   constexpr Score WeakQueen           = S( 56, 15);
280
281
282 #undef S
283
284   // Evaluation class computes and stores attacks tables and other working data
285   template<Tracing T>
286   class Evaluation {
287
288   public:
289     Evaluation() = delete;
290     explicit Evaluation(const Position& p) : pos(p) {}
291     Evaluation& operator=(const Evaluation&) = delete;
292     Value value();
293
294   private:
295     template<Color Us> void initialize();
296     template<Color Us, PieceType Pt> Score pieces();
297     template<Color Us> Score king() const;
298     template<Color Us> Score threats() const;
299     template<Color Us> Score passed() const;
300     template<Color Us> Score space() const;
301     Value winnable(Score score) const;
302
303     const Position& pos;
304     Material::Entry* me;
305     Pawns::Entry* pe;
306     Bitboard mobilityArea[COLOR_NB];
307     Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
308
309     // attackedBy[color][piece type] is a bitboard representing all squares
310     // attacked by a given color and piece type. Special "piece types" which
311     // is also calculated is ALL_PIECES.
312     Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
313
314     // attackedBy2[color] are the squares attacked by at least 2 units of a given
315     // color, including x-rays. But diagonal x-rays through pawns are not computed.
316     Bitboard attackedBy2[COLOR_NB];
317
318     // kingRing[color] are the squares adjacent to the king plus some other
319     // very near squares, depending on king position.
320     Bitboard kingRing[COLOR_NB];
321
322     // kingAttackersCount[color] is the number of pieces of the given color
323     // which attack a square in the kingRing of the enemy king.
324     int kingAttackersCount[COLOR_NB];
325
326     // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
327     // the given color which attack a square in the kingRing of the enemy king.
328     // The weights of the individual piece types are given by the elements in
329     // the KingAttackWeights array.
330     int kingAttackersWeight[COLOR_NB];
331
332     // kingAttacksCount[color] is the number of attacks by the given color to
333     // squares directly adjacent to the enemy king. Pieces which attack more
334     // than one square are counted multiple times. For instance, if there is
335     // a white knight on g5 and black's king is on g8, this white knight adds 2
336     // to kingAttacksCount[WHITE].
337     int kingAttacksCount[COLOR_NB];
338   };
339
340
341   // Evaluation::initialize() computes king and pawn attacks, and the king ring
342   // bitboard for a given color. This is done at the beginning of the evaluation.
343
344   template<Tracing T> template<Color Us>
345   void Evaluation<T>::initialize() {
346
347     constexpr Color     Them = ~Us;
348     constexpr Direction Up   = pawn_push(Us);
349     constexpr Direction Down = -Up;
350     constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
351
352     const Square ksq = pos.square<KING>(Us);
353
354     Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
355
356     // Find our pawns that are blocked or on the first two ranks
357     Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
358
359     // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
360     // or controlled by enemy pawns are excluded from the mobility area.
361     mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
362
363     // Initialize attackedBy[] for king and pawns
364     attackedBy[Us][KING] = attacks_bb<KING>(ksq);
365     attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
366     attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
367     attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
368
369     // Init our king safety tables
370     Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
371                            std::clamp(rank_of(ksq), RANK_2, RANK_7));
372     kingRing[Us] = attacks_bb<KING>(s) | s;
373
374     kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
375     kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
376
377     // Remove from kingRing[] the squares defended by two pawns
378     kingRing[Us] &= ~dblAttackByPawn;
379   }
380
381
382   // Evaluation::pieces() scores pieces of a given color and type
383
384   template<Tracing T> template<Color Us, PieceType Pt>
385   Score Evaluation<T>::pieces() {
386
387     constexpr Color     Them = ~Us;
388     constexpr Direction Down = -pawn_push(Us);
389     constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
390                                                    : Rank5BB | Rank4BB | Rank3BB);
391     Bitboard b1 = pos.pieces(Us, Pt);
392     Bitboard b, bb;
393     Score score = SCORE_ZERO;
394
395     attackedBy[Us][Pt] = 0;
396
397     while (b1) {
398         Square s = pop_lsb(&b1);
399
400         // Find attacked squares, including x-ray attacks for bishops and rooks
401         b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
402           : Pt ==   ROOK ? attacks_bb<  ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
403                          : attacks_bb<Pt>(s, pos.pieces());
404
405         if (pos.blockers_for_king(Us) & s)
406             b &= line_bb(pos.square<KING>(Us), s);
407
408         attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
409         attackedBy[Us][Pt] |= b;
410         attackedBy[Us][ALL_PIECES] |= b;
411
412         if (b & kingRing[Them])
413         {
414             kingAttackersCount[Us]++;
415             kingAttackersWeight[Us] += KingAttackWeights[Pt];
416             kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
417         }
418
419         else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
420             score += RookOnKingRing;
421
422         else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
423             score += BishopOnKingRing;
424
425         int mob = popcount(b & mobilityArea[Us]);
426         mobility[Us] += MobilityBonus[Pt - 2][mob];
427
428         if (Pt == BISHOP || Pt == KNIGHT)
429         {
430             // Bonus if the piece is on an outpost square or can reach one
431             // Bonus for knights (UncontestedOutpost) if few relevant targets
432             bb = OutpostRanks & (attackedBy[Us][PAWN] | shift<Down>(pos.pieces(PAWN)))
433                               & ~pe->pawn_attacks_span(Them);
434             Bitboard targets = pos.pieces(Them) & ~pos.pieces(PAWN);
435
436             if (   Pt == KNIGHT
437                 && bb & s & ~CenterFiles // on a side outpost
438                 && !(b & targets)        // no relevant attacks
439                 && (!more_than_one(targets & (s & QueenSide ? QueenSide : KingSide))))
440                 score += UncontestedOutpost * popcount(pos.pieces(PAWN) & (s & QueenSide ? QueenSide : KingSide));
441             else if (bb & s)
442                 score += Outpost[Pt == BISHOP];
443             else if (Pt == KNIGHT && bb & b & ~pos.pieces(Us))
444                 score += ReachableOutpost;
445
446             // Bonus for a knight or bishop shielded by pawn
447             if (shift<Down>(pos.pieces(PAWN)) & s)
448                 score += MinorBehindPawn;
449
450             // Penalty if the piece is far from the king
451             score -= KingProtector[Pt == BISHOP] * distance(pos.square<KING>(Us), s);
452
453             if constexpr (Pt == BISHOP)
454             {
455                 // Penalty according to the number of our pawns on the same color square as the
456                 // bishop, bigger when the center files are blocked with pawns and smaller
457                 // when the bishop is outside the pawn chain.
458                 Bitboard blocked = pos.pieces(Us, PAWN) & shift<Down>(pos.pieces());
459
460                 score -= BishopPawns[edge_distance(file_of(s))] * pos.pawns_on_same_color_squares(Us, s)
461                                      * (!(attackedBy[Us][PAWN] & s) + popcount(blocked & CenterFiles));
462
463                 // Penalty for all enemy pawns x-rayed
464                 score -= BishopXRayPawns * popcount(attacks_bb<BISHOP>(s) & pos.pieces(Them, PAWN));
465
466                 // Bonus for bishop on a long diagonal which can "see" both center squares
467                 if (more_than_one(attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & Center))
468                     score += LongDiagonalBishop;
469
470                 // An important Chess960 pattern: a cornered bishop blocked by a friendly
471                 // pawn diagonally in front of it is a very serious problem, especially
472                 // when that pawn is also blocked.
473                 if (   pos.is_chess960()
474                     && (s == relative_square(Us, SQ_A1) || s == relative_square(Us, SQ_H1)))
475                 {
476                     Direction d = pawn_push(Us) + (file_of(s) == FILE_A ? EAST : WEST);
477                     if (pos.piece_on(s + d) == make_piece(Us, PAWN))
478                         score -= !pos.empty(s + d + pawn_push(Us))                ? CorneredBishop * 4
479                                 : pos.piece_on(s + d + d) == make_piece(Us, PAWN) ? CorneredBishop * 2
480                                                                                   : CorneredBishop;
481                 }
482             }
483         }
484
485         if constexpr (Pt == ROOK)
486         {
487             // Bonuses for rook on a (semi-)open or closed file
488             if (pos.is_on_semiopen_file(Us, s))
489             {
490                 score += RookOnOpenFile[pos.is_on_semiopen_file(Them, s)];
491             }
492             else
493             {
494                 // If our pawn on this file is blocked, increase penalty
495                 if ( pos.pieces(Us, PAWN)
496                    & shift<Down>(pos.pieces())
497                    & file_bb(s))
498                 {
499                     score -= RookOnClosedFile;
500                 }
501
502                 // Penalty when trapped by the king, even more if the king cannot castle
503                 if (mob <= 3)
504                 {
505                     File kf = file_of(pos.square<KING>(Us));
506                     if ((kf < FILE_E) == (file_of(s) < kf))
507                         score -= TrappedRook * (1 + !pos.castling_rights(Us));
508                 }
509             }
510         }
511
512         if constexpr (Pt == QUEEN)
513         {
514             // Penalty if any relative pin or discovered attack against the queen
515             Bitboard queenPinners;
516             if (pos.slider_blockers(pos.pieces(Them, ROOK, BISHOP), s, queenPinners))
517                 score -= WeakQueen;
518         }
519     }
520     if constexpr (T)
521         Trace::add(Pt, Us, score);
522
523     return score;
524   }
525
526
527   // Evaluation::king() assigns bonuses and penalties to a king of a given color
528
529   template<Tracing T> template<Color Us>
530   Score Evaluation<T>::king() const {
531
532     constexpr Color    Them = ~Us;
533     constexpr Bitboard Camp = (Us == WHITE ? AllSquares ^ Rank6BB ^ Rank7BB ^ Rank8BB
534                                            : AllSquares ^ Rank1BB ^ Rank2BB ^ Rank3BB);
535
536     Bitboard weak, b1, b2, b3, safe, unsafeChecks = 0;
537     Bitboard rookChecks, queenChecks, bishopChecks, knightChecks;
538     int kingDanger = 0;
539     const Square ksq = pos.square<KING>(Us);
540
541     // Init the score with king shelter and enemy pawns storm
542     Score score = pe->king_safety<Us>(pos);
543
544     // Attacked squares defended at most once by our queen or king
545     weak =  attackedBy[Them][ALL_PIECES]
546           & ~attackedBy2[Us]
547           & (~attackedBy[Us][ALL_PIECES] | attackedBy[Us][KING] | attackedBy[Us][QUEEN]);
548
549     // Analyse the safe enemy's checks which are possible on next move
550     safe  = ~pos.pieces(Them);
551     safe &= ~attackedBy[Us][ALL_PIECES] | (weak & attackedBy2[Them]);
552
553     b1 = attacks_bb<ROOK  >(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
554     b2 = attacks_bb<BISHOP>(ksq, pos.pieces() ^ pos.pieces(Us, QUEEN));
555
556     // Enemy rooks checks
557     rookChecks = b1 & attackedBy[Them][ROOK] & safe;
558     if (rookChecks)
559         kingDanger += SafeCheck[ROOK][more_than_one(rookChecks)];
560     else
561         unsafeChecks |= b1 & attackedBy[Them][ROOK];
562
563     // Enemy queen safe checks: count them only if the checks are from squares from
564     // which opponent cannot give a rook check, because rook checks are more valuable.
565     queenChecks =  (b1 | b2) & attackedBy[Them][QUEEN] & safe
566                  & ~(attackedBy[Us][QUEEN] | rookChecks);
567     if (queenChecks)
568         kingDanger += SafeCheck[QUEEN][more_than_one(queenChecks)];
569
570     // Enemy bishops checks: count them only if they are from squares from which
571     // opponent cannot give a queen check, because queen checks are more valuable.
572     bishopChecks =  b2 & attackedBy[Them][BISHOP] & safe
573                   & ~queenChecks;
574     if (bishopChecks)
575         kingDanger += SafeCheck[BISHOP][more_than_one(bishopChecks)];
576
577     else
578         unsafeChecks |= b2 & attackedBy[Them][BISHOP];
579
580     // Enemy knights checks
581     knightChecks = attacks_bb<KNIGHT>(ksq) & attackedBy[Them][KNIGHT];
582     if (knightChecks & safe)
583         kingDanger += SafeCheck[KNIGHT][more_than_one(knightChecks & safe)];
584     else
585         unsafeChecks |= knightChecks;
586
587     // Find the squares that opponent attacks in our king flank, the squares
588     // which they attack twice in that flank, and the squares that we defend.
589     b1 = attackedBy[Them][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
590     b2 = b1 & attackedBy2[Them];
591     b3 = attackedBy[Us][ALL_PIECES] & KingFlank[file_of(ksq)] & Camp;
592
593     int kingFlankAttack  = popcount(b1) + popcount(b2);
594     int kingFlankDefense = popcount(b3);
595
596     kingDanger +=        kingAttackersCount[Them] * kingAttackersWeight[Them] // (~10 Elo)
597                  + 183 * popcount(kingRing[Us] & weak)                        // (~15 Elo)
598                  + 148 * popcount(unsafeChecks)                               // (~4 Elo)
599                  +  98 * popcount(pos.blockers_for_king(Us))                  // (~2 Elo)
600                  +  69 * kingAttacksCount[Them]                               // (~0.5 Elo)
601                  +   3 * kingFlankAttack * kingFlankAttack / 8                // (~0.5 Elo)
602                  +       mg_value(mobility[Them] - mobility[Us])              // (~0.5 Elo)
603                  - 873 * !pos.count<QUEEN>(Them)                              // (~24 Elo)
604                  - 100 * bool(attackedBy[Us][KNIGHT] & attackedBy[Us][KING])  // (~5 Elo)
605                  -   6 * mg_value(score) / 8                                  // (~8 Elo)
606                  -   4 * kingFlankDefense                                     // (~5 Elo)
607                  +  37;                                                       // (~0.5 Elo)
608
609     // Transform the kingDanger units into a Score, and subtract it from the evaluation
610     if (kingDanger > 100)
611         score -= make_score(kingDanger * kingDanger / 4096, kingDanger / 16);
612
613     // Penalty when our king is on a pawnless flank
614     if (!(pos.pieces(PAWN) & KingFlank[file_of(ksq)]))
615         score -= PawnlessFlank;
616
617     // Penalty if king flank is under attack, potentially moving toward the king
618     score -= FlankAttacks * kingFlankAttack;
619
620     if constexpr (T)
621         Trace::add(KING, Us, score);
622
623     return score;
624   }
625
626
627   // Evaluation::threats() assigns bonuses according to the types of the
628   // attacking and the attacked pieces.
629
630   template<Tracing T> template<Color Us>
631   Score Evaluation<T>::threats() const {
632
633     constexpr Color     Them     = ~Us;
634     constexpr Direction Up       = pawn_push(Us);
635     constexpr Bitboard  TRank3BB = (Us == WHITE ? Rank3BB : Rank6BB);
636
637     Bitboard b, weak, defended, nonPawnEnemies, stronglyProtected, safe;
638     Score score = SCORE_ZERO;
639
640     // Non-pawn enemies
641     nonPawnEnemies = pos.pieces(Them) & ~pos.pieces(PAWN);
642
643     // Squares strongly protected by the enemy, either because they defend the
644     // square with a pawn, or because they defend the square twice and we don't.
645     stronglyProtected =  attackedBy[Them][PAWN]
646                        | (attackedBy2[Them] & ~attackedBy2[Us]);
647
648     // Non-pawn enemies, strongly protected
649     defended = nonPawnEnemies & stronglyProtected;
650
651     // Enemies not strongly protected and under our attack
652     weak = pos.pieces(Them) & ~stronglyProtected & attackedBy[Us][ALL_PIECES];
653
654     // Bonus according to the kind of attacking pieces
655     if (defended | weak)
656     {
657         b = (defended | weak) & (attackedBy[Us][KNIGHT] | attackedBy[Us][BISHOP]);
658         while (b)
659             score += ThreatByMinor[type_of(pos.piece_on(pop_lsb(&b)))];
660
661         b = weak & attackedBy[Us][ROOK];
662         while (b)
663             score += ThreatByRook[type_of(pos.piece_on(pop_lsb(&b)))];
664
665         if (weak & attackedBy[Us][KING])
666             score += ThreatByKing;
667
668         b =  ~attackedBy[Them][ALL_PIECES]
669            | (nonPawnEnemies & attackedBy2[Us]);
670         score += Hanging * popcount(weak & b);
671
672         // Additional bonus if weak piece is only protected by a queen
673         score += WeakQueenProtection * popcount(weak & attackedBy[Them][QUEEN]);
674     }
675
676     // Bonus for restricting their piece moves
677     b =   attackedBy[Them][ALL_PIECES]
678        & ~stronglyProtected
679        &  attackedBy[Us][ALL_PIECES];
680     score += RestrictedPiece * popcount(b);
681
682     // Protected or unattacked squares
683     safe = ~attackedBy[Them][ALL_PIECES] | attackedBy[Us][ALL_PIECES];
684
685     // Bonus for attacking enemy pieces with our relatively safe pawns
686     b = pos.pieces(Us, PAWN) & safe;
687     b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
688     score += ThreatBySafePawn * popcount(b);
689
690     // Find squares where our pawns can push on the next move
691     b  = shift<Up>(pos.pieces(Us, PAWN)) & ~pos.pieces();
692     b |= shift<Up>(b & TRank3BB) & ~pos.pieces();
693
694     // Keep only the squares which are relatively safe
695     b &= ~attackedBy[Them][PAWN] & safe;
696
697     // Bonus for safe pawn threats on the next move
698     b = pawn_attacks_bb<Us>(b) & nonPawnEnemies;
699     score += ThreatByPawnPush * popcount(b);
700
701     // Bonus for threats on the next moves against enemy queen
702     if (pos.count<QUEEN>(Them) == 1)
703     {
704         bool queenImbalance = pos.count<QUEEN>() == 1;
705
706         Square s = pos.square<QUEEN>(Them);
707         safe =   mobilityArea[Us]
708               & ~pos.pieces(Us, PAWN)
709               & ~stronglyProtected;
710
711         b = attackedBy[Us][KNIGHT] & attacks_bb<KNIGHT>(s);
712
713         score += KnightOnQueen * popcount(b & safe) * (1 + queenImbalance);
714
715         b =  (attackedBy[Us][BISHOP] & attacks_bb<BISHOP>(s, pos.pieces()))
716            | (attackedBy[Us][ROOK  ] & attacks_bb<ROOK  >(s, pos.pieces()));
717
718         score += SliderOnQueen * popcount(b & safe & attackedBy2[Us]) * (1 + queenImbalance);
719     }
720
721     if constexpr (T)
722         Trace::add(THREAT, Us, score);
723
724     return score;
725   }
726
727   // Evaluation::passed() evaluates the passed pawns and candidate passed
728   // pawns of the given color.
729
730   template<Tracing T> template<Color Us>
731   Score Evaluation<T>::passed() const {
732
733     constexpr Color     Them = ~Us;
734     constexpr Direction Up   = pawn_push(Us);
735     constexpr Direction Down = -Up;
736
737     auto king_proximity = [&](Color c, Square s) {
738       return std::min(distance(pos.square<KING>(c), s), 5);
739     };
740
741     Bitboard b, bb, squaresToQueen, unsafeSquares, blockedPassers, helpers;
742     Score score = SCORE_ZERO;
743
744     b = pe->passed_pawns(Us);
745
746     blockedPassers = b & shift<Down>(pos.pieces(Them, PAWN));
747     if (blockedPassers)
748     {
749         helpers =  shift<Up>(pos.pieces(Us, PAWN))
750                  & ~pos.pieces(Them)
751                  & (~attackedBy2[Them] | attackedBy[Us][ALL_PIECES]);
752
753         // Remove blocked candidate passers that don't have help to pass
754         b &=  ~blockedPassers
755             | shift<WEST>(helpers)
756             | shift<EAST>(helpers);
757     }
758
759     while (b)
760     {
761         Square s = pop_lsb(&b);
762
763         assert(!(pos.pieces(Them, PAWN) & forward_file_bb(Us, s + Up)));
764
765         int r = relative_rank(Us, s);
766
767         Score bonus = PassedRank[r];
768
769         if (r > RANK_3)
770         {
771             int w = 5 * r - 13;
772             Square blockSq = s + Up;
773
774             // Adjust bonus based on the king's proximity
775             bonus += make_score(0, (  king_proximity(Them, blockSq) * 19 / 4
776                                     - king_proximity(Us,   blockSq) *  2) * w);
777
778             // If blockSq is not the queening square then consider also a second push
779             if (r != RANK_7)
780                 bonus -= make_score(0, king_proximity(Us, blockSq + Up) * w);
781
782             // If the pawn is free to advance, then increase the bonus
783             if (pos.empty(blockSq))
784             {
785                 squaresToQueen = forward_file_bb(Us, s);
786                 unsafeSquares = passed_pawn_span(Us, s);
787
788                 bb = forward_file_bb(Them, s) & pos.pieces(ROOK, QUEEN);
789
790                 if (!(pos.pieces(Them) & bb))
791                     unsafeSquares &= attackedBy[Them][ALL_PIECES] | pos.pieces(Them);
792
793                 // If there are no enemy pieces or attacks on passed pawn span, assign a big bonus.
794                 // Or if there is some, but they are all attacked by our pawns, assign a bit smaller bonus.
795                 // Otherwise assign a smaller bonus if the path to queen is not attacked
796                 // and even smaller bonus if it is attacked but block square is not.
797                 int k = !unsafeSquares                    ? 36 :
798                 !(unsafeSquares & ~attackedBy[Us][PAWN])  ? 30 :
799                         !(unsafeSquares & squaresToQueen) ? 17 :
800                         !(unsafeSquares & blockSq)        ?  7 :
801                                                              0 ;
802
803                 // Assign a larger bonus if the block square is defended
804                 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
805                     k += 5;
806
807                 bonus += make_score(k * w, k * w);
808             }
809         } // r > RANK_3
810
811         score += bonus - PassedFile * edge_distance(file_of(s));
812     }
813
814     if constexpr (T)
815         Trace::add(PASSED, Us, score);
816
817     return score;
818   }
819
820
821   // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
822   // play in the opening. It is based on the number of safe squares on the four central files
823   // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
824   // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
825
826   template<Tracing T> template<Color Us>
827   Score Evaluation<T>::space() const {
828
829     // Early exit if, for example, both queens or 6 minor pieces have been exchanged
830     if (pos.non_pawn_material() < SpaceThreshold)
831         return SCORE_ZERO;
832
833     constexpr Color Them     = ~Us;
834     constexpr Direction Down = -pawn_push(Us);
835     constexpr Bitboard SpaceMask =
836       Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
837                   : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
838
839     // Find the available squares for our pieces inside the area defined by SpaceMask
840     Bitboard safe =   SpaceMask
841                    & ~pos.pieces(Us, PAWN)
842                    & ~attackedBy[Them][PAWN];
843
844     // Find all squares which are at most three squares behind some friendly pawn
845     Bitboard behind = pos.pieces(Us, PAWN);
846     behind |= shift<Down>(behind);
847     behind |= shift<Down+Down>(behind);
848
849     // Compute space score based on the number of safe squares and number of our pieces
850     // increased with number of total blocked pawns in position.
851     int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
852     int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
853     Score score = make_score(bonus * weight * weight / 16, 0);
854
855     if constexpr (T)
856         Trace::add(SPACE, Us, score);
857
858     return score;
859   }
860
861
862   // Evaluation::winnable() adjusts the midgame and endgame score components, based on
863   // the known attacking/defending status of the players. The final value is derived
864   // by interpolation from the midgame and endgame values.
865
866   template<Tracing T>
867   Value Evaluation<T>::winnable(Score score) const {
868
869     int outflanking =  distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
870                     + int(rank_of(pos.square<KING>(WHITE)) - rank_of(pos.square<KING>(BLACK)));
871
872     bool pawnsOnBothFlanks =   (pos.pieces(PAWN) & QueenSide)
873                             && (pos.pieces(PAWN) & KingSide);
874
875     bool almostUnwinnable =   outflanking < 0
876                            && !pawnsOnBothFlanks;
877
878     bool infiltration =   rank_of(pos.square<KING>(WHITE)) > RANK_4
879                        || rank_of(pos.square<KING>(BLACK)) < RANK_5;
880
881     // Compute the initiative bonus for the attacking side
882     int complexity =   9 * pe->passed_count()
883                     + 12 * pos.count<PAWN>()
884                     +  9 * outflanking
885                     + 21 * pawnsOnBothFlanks
886                     + 24 * infiltration
887                     + 51 * !pos.non_pawn_material()
888                     - 43 * almostUnwinnable
889                     -110 ;
890
891     Value mg = mg_value(score);
892     Value eg = eg_value(score);
893
894     // Now apply the bonus: note that we find the attacking side by extracting the
895     // sign of the midgame or endgame values, and that we carefully cap the bonus
896     // so that the midgame and endgame scores do not change sign after the bonus.
897     int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
898     int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
899
900     mg += u;
901     eg += v;
902
903     // Compute the scale factor for the winning side
904     Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
905     int sf = me->scale_factor(pos, strongSide);
906
907     // If scale factor is not already specific, scale down via general heuristics
908     if (sf == SCALE_FACTOR_NORMAL)
909     {
910         if (pos.opposite_bishops())
911         {
912             // For pure opposite colored bishops endgames use scale factor
913             // based on the number of passed pawns of the strong side.
914             if (   pos.non_pawn_material(WHITE) == BishopValueMg
915                 && pos.non_pawn_material(BLACK) == BishopValueMg)
916                 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
917             // For every other opposite colored bishops endgames use scale factor
918             // based on the number of all pieces of the strong side.
919             else
920                 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
921         }
922         // For rook endgames with strong side not having overwhelming pawn number advantage
923         // and its pawns being on one flank and weak side protecting its pieces with a king
924         // use lower scale factor.
925         else if (  pos.non_pawn_material(WHITE) == RookValueMg
926                 && pos.non_pawn_material(BLACK) == RookValueMg
927                 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
928                 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
929                 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
930             sf = 36;
931         // For queen vs no queen endgames use scale factor
932         // based on number of minors of side that doesn't have queen.
933         else if (pos.count<QUEEN>() == 1)
934             sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
935                                                         : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
936         // In every other case use scale factor based on
937         // the number of pawns of the strong side reduced if pawns are on a single flank.
938         else
939             sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
940
941         // Reduce scale factor in case of pawns being on a single flank
942         sf -= 4 * !pawnsOnBothFlanks;
943     }
944
945     // Interpolate between the middlegame and (scaled by 'sf') endgame score
946     v =  mg * int(me->game_phase())
947        + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
948     v /= PHASE_MIDGAME;
949
950     if constexpr (T)
951     {
952         Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
953         Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
954     }
955
956     return Value(v);
957   }
958
959
960   // Evaluation::value() is the main function of the class. It computes the various
961   // parts of the evaluation and returns the value of the position from the point
962   // of view of the side to move.
963
964   template<Tracing T>
965   Value Evaluation<T>::value() {
966
967     assert(!pos.checkers());
968
969     // Probe the material hash table
970     me = Material::probe(pos);
971
972     // If we have a specialized evaluation function for the current material
973     // configuration, call it and return.
974     if (me->specialized_eval_exists())
975         return me->evaluate(pos);
976
977     // Initialize score by reading the incrementally updated scores included in
978     // the position object (material + piece square tables) and the material
979     // imbalance. Score is computed internally from the white point of view.
980     Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
981
982     // Probe the pawn hash table
983     pe = Pawns::probe(pos);
984     score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
985
986     // Early exit if score is high
987     auto lazy_skip = [&](Value lazyThreshold) {
988         return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
989     };
990
991     if (lazy_skip(LazyThreshold1))
992         goto make_v;
993
994     // Main evaluation begins here
995     initialize<WHITE>();
996     initialize<BLACK>();
997
998     // Pieces evaluated first (also populates attackedBy, attackedBy2).
999     // Note that the order of evaluation of the terms is left unspecified.
1000     score +=  pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
1001             + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
1002             + pieces<WHITE, ROOK  >() - pieces<BLACK, ROOK  >()
1003             + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
1004
1005     score += mobility[WHITE] - mobility[BLACK];
1006
1007     // More complex interactions that require fully populated attack bitboards
1008     score +=  king<   WHITE>() - king<   BLACK>()
1009             + passed< WHITE>() - passed< BLACK>();
1010
1011     if (lazy_skip(LazyThreshold2))
1012         goto make_v;
1013
1014     score +=  threats<WHITE>() - threats<BLACK>()
1015             + space<  WHITE>() - space<  BLACK>();
1016
1017 make_v:
1018     // Derive single value from mg and eg parts of score
1019     Value v = winnable(score);
1020
1021     // In case of tracing add all remaining individual evaluation terms
1022     if constexpr (T)
1023     {
1024         Trace::add(MATERIAL, pos.psq_score());
1025         Trace::add(IMBALANCE, me->imbalance());
1026         Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1027         Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1028     }
1029
1030     // Evaluation grain
1031     v = (v / 16) * 16;
1032
1033     // Side to move point of view
1034     v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
1035
1036     return v;
1037   }
1038
1039 } // namespace
1040
1041
1042 /// evaluate() is the evaluator for the outer world. It returns a static
1043 /// evaluation of the position from the point of view of the side to move.
1044
1045 Value Eval::evaluate(const Position& pos) {
1046
1047   Value v;
1048
1049   if (!Eval::useNNUE)
1050       v = Evaluation<NO_TRACE>(pos).value();
1051   else
1052   {
1053       // Scale and shift NNUE for compatibility with search and classical evaluation
1054       auto  adjusted_NNUE = [&](){
1055          int mat = pos.non_pawn_material() + 2 * PawnValueMg * pos.count<PAWN>();
1056          return NNUE::evaluate(pos) * (641 + mat / 32 - 4 * pos.rule50_count()) / 1024 + Tempo;
1057       };
1058
1059       // If there is PSQ imbalance use classical eval, with small probability if it is small
1060       Value psq = Value(abs(eg_value(pos.psq_score())));
1061       int   r50 = 16 + pos.rule50_count();
1062       bool  largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50;
1063       bool  classical = largePsq || (psq > PawnValueMg / 4 && !(pos.this_thread()->nodes & 0xB));
1064
1065       // Use classical evaluation for really low piece endgames.
1066       // The most critical case is a bishop + A/H file pawn vs naked king draw.
1067       bool strongClassical = pos.non_pawn_material() < 2 * RookValueMg && pos.count<PAWN>() < 2;
1068
1069       v = classical || strongClassical ? Evaluation<NO_TRACE>(pos).value() : adjusted_NNUE();
1070
1071       // If the classical eval is small and imbalance large, use NNUE nevertheless.
1072       // For the case of opposite colored bishops, switch to NNUE eval with
1073       // small probability if the classical eval is less than the threshold.
1074       if (   largePsq && !strongClassical
1075           && (   abs(v) * 16 < NNUEThreshold2 * r50
1076               || (   pos.opposite_bishops()
1077                   && abs(v) * 16 < (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50
1078                   && !(pos.this_thread()->nodes & 0xB))))
1079           v = adjusted_NNUE();
1080   }
1081
1082   // Damp down the evaluation linearly when shuffling
1083   v = v * (100 - pos.rule50_count()) / 100;
1084
1085   // Guarantee evaluation does not hit the tablebase range
1086   v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1087
1088   return v;
1089 }
1090
1091 /// trace() is like evaluate(), but instead of returning a value, it returns
1092 /// a string (suitable for outputting to stdout) that contains the detailed
1093 /// descriptions and values of each evaluation term. Useful for debugging.
1094 /// Trace scores are from white's point of view
1095
1096 std::string Eval::trace(const Position& pos) {
1097
1098   if (pos.checkers())
1099       return "Final evaluation: none (in check)";
1100
1101   std::stringstream ss;
1102   ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1103
1104   Value v;
1105
1106   std::memset(scores, 0, sizeof(scores));
1107
1108   pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
1109
1110   v = Evaluation<TRACE>(pos).value();
1111
1112   ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1113      << "     Term    |    White    |    Black    |    Total   \n"
1114      << "             |   MG    EG  |   MG    EG  |   MG    EG \n"
1115      << " ------------+-------------+-------------+------------\n"
1116      << "    Material | " << Term(MATERIAL)
1117      << "   Imbalance | " << Term(IMBALANCE)
1118      << "       Pawns | " << Term(PAWN)
1119      << "     Knights | " << Term(KNIGHT)
1120      << "     Bishops | " << Term(BISHOP)
1121      << "       Rooks | " << Term(ROOK)
1122      << "      Queens | " << Term(QUEEN)
1123      << "    Mobility | " << Term(MOBILITY)
1124      << " King safety | " << Term(KING)
1125      << "     Threats | " << Term(THREAT)
1126      << "      Passed | " << Term(PASSED)
1127      << "       Space | " << Term(SPACE)
1128      << "    Winnable | " << Term(WINNABLE)
1129      << " ------------+-------------+-------------+------------\n"
1130      << "       Total | " << Term(TOTAL);
1131
1132   v = pos.side_to_move() == WHITE ? v : -v;
1133
1134   ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n";
1135
1136   if (Eval::useNNUE)
1137   {
1138       v = NNUE::evaluate(pos);
1139       v = pos.side_to_move() == WHITE ? v : -v;
1140       ss << "\nNNUE evaluation:      " << to_cp(v) << " (white side)\n";
1141   }
1142
1143   v = evaluate(pos);
1144   v = pos.side_to_move() == WHITE ? v : -v;
1145   ss << "\nFinal evaluation:     " << to_cp(v) << " (white side)\n";
1146
1147   return ss.str();
1148 }