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