Update to Stockfish 16

This commit is contained in:
Peter Osterlund
2023-07-01 12:18:01 +02:00
parent af1d725f27
commit 1a81595361
56 changed files with 1618 additions and 990 deletions

View File

@@ -1,6 +1,6 @@
/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2022 The Stockfish developers (see AUTHORS file)
Copyright (C) 2004-2023 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -36,7 +36,7 @@
#include "timeman.h"
#include "uci.h"
#include "incbin/incbin.h"
#include "nnue/evaluate_nnue.h"
// Macro to embed the default efficiently updatable neural network (NNUE) file
// data in the engine binary (using incbin.h, by Dale Weiler).
@@ -82,20 +82,18 @@ namespace Eval {
eval_file = EvalFileDefaultName;
#if defined(DEFAULT_NNUE_DIRECTORY)
#define stringify2(x) #x
#define stringify(x) stringify2(x)
vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory , stringify(DEFAULT_NNUE_DIRECTORY) };
#else
vector<string> dirs = { "<internal>" , "" , CommandLine::binaryDirectory };
#endif
for (string directory : dirs)
for (const string& directory : dirs)
if (currentEvalFileName != eval_file)
{
if (directory != "<internal>")
{
ifstream stream(directory + eval_file, ios::binary);
if (load_eval(eval_file, stream))
if (NNUE::load_eval(eval_file, stream))
currentEvalFileName = eval_file;
}
@@ -111,12 +109,10 @@ namespace Eval {
(void) gEmbeddedNNUEEnd; // Silence warning on unused variable
istream stream(&buffer);
if (load_eval(eval_file, stream))
if (NNUE::load_eval(eval_file, stream))
currentEvalFileName = eval_file;
}
}
if (currentEvalFileName != eval_file)
currentEvalFileName = "";
}
/// NNUE::verify() verifies that the last net used was loaded successfully
@@ -161,24 +157,24 @@ namespace Trace {
Score scores[TERM_NB][COLOR_NB];
double to_cp(Value v) { return double(v) / UCI::NormalizeToPawnValue; }
static double to_cp(Value v) { return double(v) / UCI::NormalizeToPawnValue; }
void add(int idx, Color c, Score s) {
static void add(int idx, Color c, Score s) {
scores[idx][c] = s;
}
void add(int idx, Score w, Score b = SCORE_ZERO) {
static void add(int idx, Score w, Score b = SCORE_ZERO) {
scores[idx][WHITE] = w;
scores[idx][BLACK] = b;
}
std::ostream& operator<<(std::ostream& os, Score s) {
static std::ostream& operator<<(std::ostream& os, Score s) {
os << std::setw(5) << to_cp(mg_value(s)) << " "
<< std::setw(5) << to_cp(eg_value(s));
return os;
}
std::ostream& operator<<(std::ostream& os, Term t) {
static std::ostream& operator<<(std::ostream& os, Term t) {
if (t == MATERIAL || t == IMBALANCE || t == WINNABLE || t == TOTAL)
os << " ---- ----" << " | " << " ---- ----";
@@ -195,8 +191,8 @@ using namespace Trace;
namespace {
// Threshold for lazy and space evaluation
constexpr Value LazyThreshold1 = Value(3631);
constexpr Value LazyThreshold2 = Value(2084);
constexpr Value LazyThreshold1 = Value(3622);
constexpr Value LazyThreshold2 = Value(1962);
constexpr Value SpaceThreshold = Value(11551);
// KingAttackWeights[PieceType] contains king attack weights by piece type
@@ -390,10 +386,10 @@ namespace {
template<Tracing T> template<Color Us, PieceType Pt>
Score Evaluation<T>::pieces() {
constexpr Color Them = ~Us;
constexpr Direction Down = -pawn_push(Us);
constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
: Rank5BB | Rank4BB | Rank3BB);
constexpr Color Them = ~Us;
[[maybe_unused]] constexpr Direction Down = -pawn_push(Us);
[[maybe_unused]] constexpr Bitboard OutpostRanks = (Us == WHITE ? Rank4BB | Rank5BB | Rank6BB
: Rank5BB | Rank4BB | Rank3BB);
Bitboard b1 = pos.pieces(Us, Pt);
Bitboard b, bb;
Score score = SCORE_ZERO;
@@ -432,7 +428,7 @@ namespace {
int mob = popcount(b & mobilityArea[Us]);
mobility[Us] += MobilityBonus[Pt - 2][mob];
if (Pt == BISHOP || Pt == KNIGHT)
if constexpr (Pt == BISHOP || Pt == KNIGHT)
{
// Bonus if the piece is on an outpost square or can reach one
// Bonus for knights (UncontestedOutpost) if few relevant targets
@@ -1050,52 +1046,41 @@ make_v:
/// evaluate() is the evaluator for the outer world. It returns a static
/// evaluation of the position from the point of view of the side to move.
Value Eval::evaluate(const Position& pos, int* complexity) {
Value Eval::evaluate(const Position& pos) {
assert(!pos.checkers());
Value v;
Value psq = pos.psq_eg_stm();
// We use the much less accurate but faster Classical eval when the NNUE
// option is set to false. Otherwise we use the NNUE eval unless the
// PSQ advantage is decisive and several pieces remain. (~3 Elo)
bool useClassical = !useNNUE || (pos.count<ALL_PIECES>() > 7 && abs(psq) > 1760);
// PSQ advantage is decisive. (~4 Elo at STC, 1 Elo at LTC)
bool useClassical = !useNNUE || abs(psq) > 2048;
if (useClassical)
v = Evaluation<NO_TRACE>(pos).value();
else
{
int nnueComplexity;
int scale = 1064 + 106 * pos.non_pawn_material() / 5120;
int npm = pos.non_pawn_material() / 64;
Color stm = pos.side_to_move();
Value optimism = pos.this_thread()->optimism[stm];
Value nnue = NNUE::evaluate(pos, true, &nnueComplexity);
// Blend nnue complexity with (semi)classical complexity
nnueComplexity = ( 416 * nnueComplexity
+ 424 * abs(psq - nnue)
+ (optimism > 0 ? int(optimism) * int(psq - nnue) : 0)
) / 1024;
// Return hybrid NNUE complexity to caller
if (complexity)
*complexity = nnueComplexity;
optimism = optimism * (269 + nnueComplexity) / 256;
v = (nnue * scale + optimism * (scale - 754)) / 1024;
// Blend optimism with nnue complexity and (semi)classical complexity
optimism += optimism * (nnueComplexity + abs(psq - nnue)) / 512;
v = (nnue * (945 + npm) + optimism * (150 + npm)) / 1024;
}
// Damp down the evaluation linearly when shuffling
v = v * (195 - pos.rule50_count()) / 211;
v = v * (200 - pos.rule50_count()) / 214;
// Guarantee evaluation does not hit the tablebase range
v = std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
// When not using NNUE, return classical complexity to caller
if (complexity && (!useNNUE || useClassical))
*complexity = abs(v - psq);
return v;
}