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