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