]> git.sesse.net Git - stockfish/blob - src/evaluate.cpp
fd51ad5347ae40161176b8ad6b684eb52c878a03
[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   constexpr Score RookOnClosedFile = S(10, 5);
244   constexpr Score RookOnOpenFile[] = { S(19, 7), S(48, 27) };
245
246   // ThreatByMinor/ByRook[attacked PieceType] contains bonuses according to
247   // which piece type attacks which one. Attacks on lesser pieces which are
248   // pawn-defended are not considered.
249   constexpr Score ThreatByMinor[PIECE_TYPE_NB] = {
250     S(0, 0), S(5, 32), S(55, 41), S(77, 56), S(89, 119), S(79, 162)
251   };
252
253   constexpr Score ThreatByRook[PIECE_TYPE_NB] = {
254     S(0, 0), S(3, 44), S(37, 68), S(42, 60), S(0, 39), S(58, 43)
255   };
256
257   // Assorted bonuses and penalties
258   constexpr Score BadOutpost          = S( -7, 36);
259   constexpr Score BishopOnKingRing    = S( 24,  0);
260   constexpr Score BishopXRayPawns     = S(  4,  5);
261   constexpr Score CorneredBishop      = S( 50, 50);
262   constexpr Score FlankAttacks        = S(  8,  0);
263   constexpr Score Hanging             = S( 69, 36);
264   constexpr Score KnightOnQueen       = S( 16, 11);
265   constexpr Score LongDiagonalBishop  = S( 45,  0);
266   constexpr Score MinorBehindPawn     = S( 18,  3);
267   constexpr Score PassedFile          = S( 11,  8);
268   constexpr Score PawnlessFlank       = S( 17, 95);
269   constexpr Score ReachableOutpost    = S( 31, 22);
270   constexpr Score RestrictedPiece     = S(  7,  7);
271   constexpr Score RookOnKingRing      = S( 16,  0);
272   constexpr Score SliderOnQueen       = S( 60, 18);
273   constexpr Score ThreatByKing        = S( 24, 89);
274   constexpr Score ThreatByPawnPush    = S( 48, 39);
275   constexpr Score ThreatBySafePawn    = S(173, 94);
276   constexpr Score TrappedRook         = S( 55, 13);
277   constexpr Score WeakQueenProtection = S( 14,  0);
278   constexpr Score WeakQueen           = S( 56, 15);
279
280
281 #undef S
282
283   // Evaluation class computes and stores attacks tables and other working data
284   template<Tracing T>
285   class Evaluation {
286
287   public:
288     Evaluation() = delete;
289     explicit Evaluation(const Position& p) : pos(p) {}
290     Evaluation& operator=(const Evaluation&) = delete;
291     Value value();
292
293   private:
294     template<Color Us> void initialize();
295     template<Color Us, PieceType Pt> Score pieces();
296     template<Color Us> Score king() const;
297     template<Color Us> Score threats() const;
298     template<Color Us> Score passed() const;
299     template<Color Us> Score space() const;
300     Value winnable(Score score) const;
301
302     const Position& pos;
303     Material::Entry* me;
304     Pawns::Entry* pe;
305     Bitboard mobilityArea[COLOR_NB];
306     Score mobility[COLOR_NB] = { SCORE_ZERO, SCORE_ZERO };
307
308     // attackedBy[color][piece type] is a bitboard representing all squares
309     // attacked by a given color and piece type. Special "piece types" which
310     // is also calculated is ALL_PIECES.
311     Bitboard attackedBy[COLOR_NB][PIECE_TYPE_NB];
312
313     // attackedBy2[color] are the squares attacked by at least 2 units of a given
314     // color, including x-rays. But diagonal x-rays through pawns are not computed.
315     Bitboard attackedBy2[COLOR_NB];
316
317     // kingRing[color] are the squares adjacent to the king plus some other
318     // very near squares, depending on king position.
319     Bitboard kingRing[COLOR_NB];
320
321     // kingAttackersCount[color] is the number of pieces of the given color
322     // which attack a square in the kingRing of the enemy king.
323     int kingAttackersCount[COLOR_NB];
324
325     // kingAttackersWeight[color] is the sum of the "weights" of the pieces of
326     // the given color which attack a square in the kingRing of the enemy king.
327     // The weights of the individual piece types are given by the elements in
328     // the KingAttackWeights array.
329     int kingAttackersWeight[COLOR_NB];
330
331     // kingAttacksCount[color] is the number of attacks by the given color to
332     // squares directly adjacent to the enemy king. Pieces which attack more
333     // than one square are counted multiple times. For instance, if there is
334     // a white knight on g5 and black's king is on g8, this white knight adds 2
335     // to kingAttacksCount[WHITE].
336     int kingAttacksCount[COLOR_NB];
337   };
338
339
340   // Evaluation::initialize() computes king and pawn attacks, and the king ring
341   // bitboard for a given color. This is done at the beginning of the evaluation.
342
343   template<Tracing T> template<Color Us>
344   void Evaluation<T>::initialize() {
345
346     constexpr Color     Them = ~Us;
347     constexpr Direction Up   = pawn_push(Us);
348     constexpr Direction Down = -Up;
349     constexpr Bitboard LowRanks = (Us == WHITE ? Rank2BB | Rank3BB : Rank7BB | Rank6BB);
350
351     const Square ksq = pos.square<KING>(Us);
352
353     Bitboard dblAttackByPawn = pawn_double_attacks_bb<Us>(pos.pieces(Us, PAWN));
354
355     // Find our pawns that are blocked or on the first two ranks
356     Bitboard b = pos.pieces(Us, PAWN) & (shift<Down>(pos.pieces()) | LowRanks);
357
358     // Squares occupied by those pawns, by our king or queen, by blockers to attacks on our king
359     // or controlled by enemy pawns are excluded from the mobility area.
360     mobilityArea[Us] = ~(b | pos.pieces(Us, KING, QUEEN) | pos.blockers_for_king(Us) | pe->pawn_attacks(Them));
361
362     // Initialize attackedBy[] for king and pawns
363     attackedBy[Us][KING] = attacks_bb<KING>(ksq);
364     attackedBy[Us][PAWN] = pe->pawn_attacks(Us);
365     attackedBy[Us][ALL_PIECES] = attackedBy[Us][KING] | attackedBy[Us][PAWN];
366     attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
367
368     // Init our king safety tables
369     Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
370                            std::clamp(rank_of(ksq), RANK_2, RANK_7));
371     kingRing[Us] = attacks_bb<KING>(s) | s;
372
373     kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
374     kingAttacksCount[Them] = kingAttackersWeight[Them] = 0;
375
376     // Remove from kingRing[] the squares defended by two pawns
377     kingRing[Us] &= ~dblAttackByPawn;
378   }
379
380
381   // Evaluation::pieces() scores pieces of a given color and type
382
383   template<Tracing T> template<Color Us, PieceType Pt>
384   Score Evaluation<T>::pieces() {
385
386     constexpr Color     Them = ~Us;
387     constexpr Direction Down = -pawn_push(Us);
388     constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
389                                                    : Rank5BB | Rank4BB | Rank3BB);
390     const Square* pl = pos.squares<Pt>(Us);
391
392     Bitboard b, bb;
393     Score score = SCORE_ZERO;
394
395     attackedBy[Us][Pt] = 0;
396
397     for (Square s = *pl; s != SQ_NONE; s = *++pl)
398     {
399         // Find attacked squares, including x-ray attacks for bishops and rooks
400         b = Pt == BISHOP ? attacks_bb<BISHOP>(s, pos.pieces() ^ pos.pieces(QUEEN))
401           : Pt ==   ROOK ? attacks_bb<  ROOK>(s, pos.pieces() ^ pos.pieces(QUEEN) ^ pos.pieces(Us, ROOK))
402                          : attacks_bb<Pt>(s, pos.pieces());
403
404         if (pos.blockers_for_king(Us) & s)
405             b &= line_bb(pos.square<KING>(Us), s);
406
407         attackedBy2[Us] |= attackedBy[Us][ALL_PIECES] & b;
408         attackedBy[Us][Pt] |= b;
409         attackedBy[Us][ALL_PIECES] |= b;
410
411         if (b & kingRing[Them])
412         {
413             kingAttackersCount[Us]++;
414             kingAttackersWeight[Us] += KingAttackWeights[Pt];
415             kingAttacksCount[Us] += popcount(b & attackedBy[Them][KING]);
416         }
417
418         else if (Pt == ROOK && (file_bb(s) & kingRing[Them]))
419             score += RookOnKingRing;
420
421         else if (Pt == BISHOP && (attacks_bb<BISHOP>(s, pos.pieces(PAWN)) & kingRing[Them]))
422             score += BishopOnKingRing;
423
424         int mob = popcount(b & mobilityArea[Us]);
425
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             // Reduced bonus for knights (BadOutpost) 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 += BadOutpost;
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 (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 (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 (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 (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                  + 185 * 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 (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 (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];
792
793                 // If there are no enemy attacks on passed pawn span, assign a big bonus.
794                 // Otherwise assign a smaller bonus if the path to queen is not attacked
795                 // and even smaller bonus if it is attacked but block square is not.
796                 int k = !unsafeSquares                    ? 35 :
797                         !(unsafeSquares & squaresToQueen) ? 20 :
798                         !(unsafeSquares & blockSq)        ?  9 :
799                                                              0 ;
800
801                 // Assign a larger bonus if the block square is defended
802                 if ((pos.pieces(Us) & bb) || (attackedBy[Us][ALL_PIECES] & blockSq))
803                     k += 5;
804
805                 bonus += make_score(k * w, k * w);
806             }
807         } // r > RANK_3
808
809         score += bonus - PassedFile * edge_distance(file_of(s));
810     }
811
812     if (T)
813         Trace::add(PASSED, Us, score);
814
815     return score;
816   }
817
818
819   // Evaluation::space() computes a space evaluation for a given side, aiming to improve game
820   // play in the opening. It is based on the number of safe squares on the four central files
821   // on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
822   // Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
823
824   template<Tracing T> template<Color Us>
825   Score Evaluation<T>::space() const {
826
827     // Early exit if, for example, both queens or 6 minor pieces have been exchanged
828     if (pos.non_pawn_material() < SpaceThreshold)
829         return SCORE_ZERO;
830
831     constexpr Color Them     = ~Us;
832     constexpr Direction Down = -pawn_push(Us);
833     constexpr Bitboard SpaceMask =
834       Us == WHITE ? CenterFiles & (Rank2BB | Rank3BB | Rank4BB)
835                   : CenterFiles & (Rank7BB | Rank6BB | Rank5BB);
836
837     // Find the available squares for our pieces inside the area defined by SpaceMask
838     Bitboard safe =   SpaceMask
839                    & ~pos.pieces(Us, PAWN)
840                    & ~attackedBy[Them][PAWN];
841
842     // Find all squares which are at most three squares behind some friendly pawn
843     Bitboard behind = pos.pieces(Us, PAWN);
844     behind |= shift<Down>(behind);
845     behind |= shift<Down+Down>(behind);
846
847     int bonus = popcount(safe) + popcount(behind & safe & ~attackedBy[Them][ALL_PIECES]);
848     int weight = pos.count<ALL_PIECES>(Us) - 3 + std::min(pe->blocked_count(), 9);
849     Score score = make_score(bonus * weight * weight / 16, 0);
850
851     if (T)
852         Trace::add(SPACE, Us, score);
853
854     return score;
855   }
856
857
858   // Evaluation::winnable() adjusts the midgame and endgame score components, based on
859   // the known attacking/defending status of the players. The final value is derived
860   // by interpolation from the midgame and endgame values.
861
862   template<Tracing T>
863   Value Evaluation<T>::winnable(Score score) const {
864
865     int outflanking =  distance<File>(pos.square<KING>(WHITE), pos.square<KING>(BLACK))
866                      - distance<Rank>(pos.square<KING>(WHITE), pos.square<KING>(BLACK));
867
868     bool pawnsOnBothFlanks =   (pos.pieces(PAWN) & QueenSide)
869                             && (pos.pieces(PAWN) & KingSide);
870
871     bool almostUnwinnable =   outflanking < 0
872                            && !pawnsOnBothFlanks;
873
874     bool infiltration =   rank_of(pos.square<KING>(WHITE)) > RANK_4
875                        || rank_of(pos.square<KING>(BLACK)) < RANK_5;
876
877     // Compute the initiative bonus for the attacking side
878     int complexity =   9 * pe->passed_count()
879                     + 12 * pos.count<PAWN>()
880                     +  9 * outflanking
881                     + 21 * pawnsOnBothFlanks
882                     + 24 * infiltration
883                     + 51 * !pos.non_pawn_material()
884                     - 43 * almostUnwinnable
885                     -110 ;
886
887     Value mg = mg_value(score);
888     Value eg = eg_value(score);
889
890     // Now apply the bonus: note that we find the attacking side by extracting the
891     // sign of the midgame or endgame values, and that we carefully cap the bonus
892     // so that the midgame and endgame scores do not change sign after the bonus.
893     int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
894     int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
895
896     mg += u;
897     eg += v;
898
899     // Compute the scale factor for the winning side
900     Color strongSide = eg > VALUE_DRAW ? WHITE : BLACK;
901     int sf = me->scale_factor(pos, strongSide);
902
903     // If scale factor is not already specific, scale down via general heuristics
904     if (sf == SCALE_FACTOR_NORMAL)
905     {
906         if (pos.opposite_bishops())
907         {
908             if (   pos.non_pawn_material(WHITE) == BishopValueMg
909                 && pos.non_pawn_material(BLACK) == BishopValueMg)
910                 sf = 18 + 4 * popcount(pe->passed_pawns(strongSide));
911             else
912                 sf = 22 + 3 * pos.count<ALL_PIECES>(strongSide);
913         }
914         else if (  pos.non_pawn_material(WHITE) == RookValueMg
915                 && pos.non_pawn_material(BLACK) == RookValueMg
916                 && pos.count<PAWN>(strongSide) - pos.count<PAWN>(~strongSide) <= 1
917                 && bool(KingSide & pos.pieces(strongSide, PAWN)) != bool(QueenSide & pos.pieces(strongSide, PAWN))
918                 && (attacks_bb<KING>(pos.square<KING>(~strongSide)) & pos.pieces(~strongSide, PAWN)))
919             sf = 36;
920         else if (pos.count<QUEEN>() == 1)
921             sf = 37 + 3 * (pos.count<QUEEN>(WHITE) == 1 ? pos.count<BISHOP>(BLACK) + pos.count<KNIGHT>(BLACK)
922                                                         : pos.count<BISHOP>(WHITE) + pos.count<KNIGHT>(WHITE));
923         else
924             sf = std::min(sf, 36 + 7 * pos.count<PAWN>(strongSide)) - 4 * !pawnsOnBothFlanks;
925
926         sf -= 4 * !pawnsOnBothFlanks;
927     }
928
929     // Interpolate between the middlegame and (scaled by 'sf') endgame score
930     v =  mg * int(me->game_phase())
931        + eg * int(PHASE_MIDGAME - me->game_phase()) * ScaleFactor(sf) / SCALE_FACTOR_NORMAL;
932     v /= PHASE_MIDGAME;
933
934     if (T)
935     {
936         Trace::add(WINNABLE, make_score(u, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL - eg_value(score)));
937         Trace::add(TOTAL, make_score(mg, eg * ScaleFactor(sf) / SCALE_FACTOR_NORMAL));
938     }
939
940     return Value(v);
941   }
942
943
944   // Evaluation::value() is the main function of the class. It computes the various
945   // parts of the evaluation and returns the value of the position from the point
946   // of view of the side to move.
947
948   template<Tracing T>
949   Value Evaluation<T>::value() {
950
951     assert(!pos.checkers());
952
953     // Probe the material hash table
954     me = Material::probe(pos);
955
956     // If we have a specialized evaluation function for the current material
957     // configuration, call it and return.
958     if (me->specialized_eval_exists())
959         return me->evaluate(pos);
960
961     // Initialize score by reading the incrementally updated scores included in
962     // the position object (material + piece square tables) and the material
963     // imbalance. Score is computed internally from the white point of view.
964     Score score = pos.psq_score() + me->imbalance() + pos.this_thread()->contempt;
965
966     // Probe the pawn hash table
967     pe = Pawns::probe(pos);
968     score += pe->pawn_score(WHITE) - pe->pawn_score(BLACK);
969
970     // Early exit if score is high
971     auto lazy_skip = [&](Value lazyThreshold) {
972         return abs(mg_value(score) + eg_value(score)) / 2 > lazyThreshold + pos.non_pawn_material() / 64;
973     };
974
975     if (lazy_skip(LazyThreshold1))
976         goto make_v;
977
978     // Main evaluation begins here
979     initialize<WHITE>();
980     initialize<BLACK>();
981
982     // Pieces evaluated first (also populates attackedBy, attackedBy2).
983     // Note that the order of evaluation of the terms is left unspecified.
984     score +=  pieces<WHITE, KNIGHT>() - pieces<BLACK, KNIGHT>()
985             + pieces<WHITE, BISHOP>() - pieces<BLACK, BISHOP>()
986             + pieces<WHITE, ROOK  >() - pieces<BLACK, ROOK  >()
987             + pieces<WHITE, QUEEN >() - pieces<BLACK, QUEEN >();
988
989     score += mobility[WHITE] - mobility[BLACK];
990
991     // More complex interactions that require fully populated attack bitboards
992     score +=  king<   WHITE>() - king<   BLACK>()
993             + passed< WHITE>() - passed< BLACK>();
994
995     if (lazy_skip(LazyThreshold2))
996         goto make_v;
997
998     score +=  threats<WHITE>() - threats<BLACK>()
999             + space<  WHITE>() - space<  BLACK>();
1000
1001 make_v:
1002     // Derive single value from mg and eg parts of score
1003     Value v = winnable(score);
1004
1005     // In case of tracing add all remaining individual evaluation terms
1006     if (T)
1007     {
1008         Trace::add(MATERIAL, pos.psq_score());
1009         Trace::add(IMBALANCE, me->imbalance());
1010         Trace::add(PAWN, pe->pawn_score(WHITE), pe->pawn_score(BLACK));
1011         Trace::add(MOBILITY, mobility[WHITE], mobility[BLACK]);
1012     }
1013
1014     // Evaluation grain
1015     v = (v / 16) * 16;
1016
1017     // Side to move point of view
1018     v = (pos.side_to_move() == WHITE ? v : -v) + Tempo;
1019
1020     return v;
1021   }
1022
1023 } // namespace
1024
1025
1026 /// evaluate() is the evaluator for the outer world. It returns a static
1027 /// evaluation of the position from the point of view of the side to move.
1028
1029 Value Eval::evaluate(const Position& pos) {
1030
1031   Value v;
1032
1033   if (!Eval::useNNUE)
1034       v = Evaluation<NO_TRACE>(pos).value();
1035   else
1036   {
1037       // Scale and shift NNUE for compatibility with search and classical evaluation
1038       auto  adjusted_NNUE = [&](){
1039          int mat = pos.non_pawn_material() + PawnValueMg * pos.count<PAWN>();
1040          return NNUE::evaluate(pos) * (720 + mat / 32) / 1024 + Tempo;
1041       };
1042
1043       // If there is PSQ imbalance use classical eval, with small probability if it is small
1044       Value psq = Value(abs(eg_value(pos.psq_score())));
1045       int   r50 = 16 + pos.rule50_count();
1046       bool  largePsq = psq * 16 > (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50;
1047       bool  classical = largePsq || (psq > PawnValueMg / 4 && !(pos.this_thread()->nodes & 0xB));
1048
1049       bool strongClassical = pos.non_pawn_material() < 2 * RookValueMg && pos.count<PAWN>() < 2;
1050
1051       v = classical || strongClassical ? Evaluation<NO_TRACE>(pos).value() : adjusted_NNUE();
1052
1053       // If the classical eval is small and imbalance large, use NNUE nevertheless.
1054       // For the case of opposite colored bishops, switch to NNUE eval with
1055       // small probability if the classical eval is less than the threshold.
1056       if (   largePsq && !strongClassical
1057           && (   abs(v) * 16 < NNUEThreshold2 * r50
1058               || (   pos.opposite_bishops()
1059                   && abs(v) * 16 < (NNUEThreshold1 + pos.non_pawn_material() / 64) * r50
1060                   && !(pos.this_thread()->nodes & 0xB))))
1061           v = adjusted_NNUE();
1062   }
1063
1064   // Damp down the evaluation linearly when shuffling
1065   v = v * (100 - pos.rule50_count()) / 100;
1066
1067   // Guarantee evaluation does not hit the tablebase range
1068   v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
1069
1070   return v;
1071 }
1072
1073 /// trace() is like evaluate(), but instead of returning a value, it returns
1074 /// a string (suitable for outputting to stdout) that contains the detailed
1075 /// descriptions and values of each evaluation term. Useful for debugging.
1076 /// Trace scores are from white's point of view
1077
1078 std::string Eval::trace(const Position& pos) {
1079
1080   if (pos.checkers())
1081       return "Final evaluation: none (in check)";
1082
1083   std::stringstream ss;
1084   ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2);
1085
1086   Value v;
1087
1088   std::memset(scores, 0, sizeof(scores));
1089
1090   pos.this_thread()->contempt = SCORE_ZERO; // Reset any dynamic contempt
1091
1092   v = Evaluation<TRACE>(pos).value();
1093
1094   ss << std::showpoint << std::noshowpos << std::fixed << std::setprecision(2)
1095      << "     Term    |    White    |    Black    |    Total   \n"
1096      << "             |   MG    EG  |   MG    EG  |   MG    EG \n"
1097      << " ------------+-------------+-------------+------------\n"
1098      << "    Material | " << Term(MATERIAL)
1099      << "   Imbalance | " << Term(IMBALANCE)
1100      << "       Pawns | " << Term(PAWN)
1101      << "     Knights | " << Term(KNIGHT)
1102      << "     Bishops | " << Term(BISHOP)
1103      << "       Rooks | " << Term(ROOK)
1104      << "      Queens | " << Term(QUEEN)
1105      << "    Mobility | " << Term(MOBILITY)
1106      << " King safety | " << Term(KING)
1107      << "     Threats | " << Term(THREAT)
1108      << "      Passed | " << Term(PASSED)
1109      << "       Space | " << Term(SPACE)
1110      << "    Winnable | " << Term(WINNABLE)
1111      << " ------------+-------------+-------------+------------\n"
1112      << "       Total | " << Term(TOTAL);
1113
1114   v = pos.side_to_move() == WHITE ? v : -v;
1115
1116   ss << "\nClassical evaluation: " << to_cp(v) << " (white side)\n";
1117
1118   if (Eval::useNNUE)
1119   {
1120       v = NNUE::evaluate(pos);
1121       v = pos.side_to_move() == WHITE ? v : -v;
1122       ss << "\nNNUE evaluation:      " << to_cp(v) << " (white side)\n";
1123   }
1124
1125   v = evaluate(pos);
1126   v = pos.side_to_move() == WHITE ? v : -v;
1127   ss << "\nFinal evaluation:     " << to_cp(v) << " (white side)\n";
1128
1129   return ss.str();
1130 }