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