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