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