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