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