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