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