mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 00:33:09 +00:00
Small trivial cleanups
closes https://github.com/official-stockfish/Stockfish/pull/2801 No functional change
This commit is contained in:
parent
3542033342
commit
5f1843c9cb
17 changed files with 96 additions and 95 deletions
53
README.md
53
README.md
|
@ -4,17 +4,17 @@
|
|||
[](https://ci.appveyor.com/project/mcostalba/stockfish/branch/master)
|
||||
|
||||
[Stockfish](https://stockfishchess.org) is a free, powerful UCI chess engine
|
||||
derived from Glaurung 2.1. It features two evaluation functions, the classical
|
||||
evaluation based on handcrafted terms, and the NNUE evaluation based on
|
||||
efficiently updateable neural networks. The classical evaluation runs efficiently
|
||||
on most 64bit CPU architectures, while the NNUE evaluation benefits strongly from the
|
||||
vector intrinsics available on modern CPUs (avx2 or similar).
|
||||
derived from Glaurung 2.1. Stockfish is not a complete chess program and requires a
|
||||
UCI-compatible graphical user interface (GUI) (e.g. XBoard with PolyGlot, Scid,
|
||||
Cute Chess, eboard, Arena, Sigma Chess, Shredder, Chess Partner or Fritz) in order
|
||||
to be used comfortably. Read the documentation for your GUI of choice for information
|
||||
about how to use Stockfish with it.
|
||||
|
||||
Stockfish is not a complete chess program and requires a
|
||||
UCI-compatible GUI (e.g. XBoard with PolyGlot, Scid, Cute Chess, eboard, Arena,
|
||||
Sigma Chess, Shredder, Chess Partner or Fritz) in order to be used comfortably.
|
||||
Read the documentation for your GUI of choice for information about how to use
|
||||
Stockfish with it.
|
||||
The Stockfish engine features two evaluation functions for chess, the classical
|
||||
evaluation based on handcrafted terms, and the NNUE evaluation based on efficiently
|
||||
updateable neural networks. The classical evaluation runs efficiently on most 64bit
|
||||
CPU architectures, while the NNUE evaluation benefits strongly from the vector
|
||||
intrinsics available on modern CPUs (avx2 or similar).
|
||||
|
||||
|
||||
## Files
|
||||
|
@ -28,10 +28,13 @@ This distribution of Stockfish consists of the following files:
|
|||
* src, a subdirectory containing the full source code, including a Makefile
|
||||
that can be used to compile Stockfish on Unix-like systems.
|
||||
|
||||
To use the NNUE evaluation an additional data file with neural network parameters
|
||||
needs to be downloaded. The filename for the default set can be found as the default
|
||||
value of the `EvalFile` UCI option, with the format
|
||||
`nn-[SHA256 first 12 digits].nnue` (e.g. nn-c157e0a5755b.nnue). This file can be downloaded from
|
||||
* a file with the .nnue extension, storing the neural network for the NNUE
|
||||
evaluation.
|
||||
|
||||
Note: to use the NNUE evaluation, the additional data file with neural network parameters
|
||||
needs to be downloaded. The filename for the default net can be found as the default
|
||||
value of the `EvalFile` UCI option, with the format `nn-[SHA256 first 12 digits].nnue`
|
||||
(for instance, `nn-c157e0a5755b.nnue`). This file can be downloaded from
|
||||
```
|
||||
https://tests.stockfishchess.org/api/nn/[filename]
|
||||
```
|
||||
|
@ -64,14 +67,6 @@ Currently, Stockfish has the following UCI options:
|
|||
The name of the file of the NNUE evaluation parameters. Depending on the GUI the
|
||||
filename should include the full path to the folder/directory that contains the file.
|
||||
|
||||
* #### Contempt
|
||||
A positive value for contempt favors middle game positions and avoids draws,
|
||||
effective for the classical evaluation only.
|
||||
|
||||
* #### Analysis Contempt
|
||||
By default, contempt is set to prefer the side to move. Set this option to "White"
|
||||
or "Black" to analyse with contempt for that side, or "Off" to disable contempt.
|
||||
|
||||
* #### UCI_AnalyseMode
|
||||
An option handled by your GUI.
|
||||
|
||||
|
@ -120,6 +115,14 @@ Currently, Stockfish has the following UCI options:
|
|||
Limit Syzygy tablebase probing to positions with at most this many pieces left
|
||||
(including kings and pawns).
|
||||
|
||||
* #### Contempt
|
||||
A positive value for contempt favors middle game positions and avoids draws,
|
||||
effective for the classical evaluation only.
|
||||
|
||||
* #### Analysis Contempt
|
||||
By default, contempt is set to prefer the side to move. Set this option to "White"
|
||||
or "Black" to analyse with contempt for that side, or "Off" to disable contempt.
|
||||
|
||||
* #### Move Overhead
|
||||
Assume a time delay of x ms due to network and GUI overheads. This is useful to
|
||||
avoid losses on time in those cases.
|
||||
|
@ -138,7 +141,7 @@ Currently, Stockfish has the following UCI options:
|
|||
* #### Debug Log File
|
||||
Write all communication to and from the engine into a text file.
|
||||
|
||||
## Classical and NNUE evaluation
|
||||
## A note on classical and NNUE evaluation
|
||||
|
||||
Both approaches assign a value to a position that is used in alpha-beta (PVS) search
|
||||
to find the best move. The classical evaluation computes this value as a function
|
||||
|
@ -226,6 +229,7 @@ targets with corresponding descriptions.
|
|||
cd src
|
||||
make help
|
||||
make build ARCH=x86-64-modern
|
||||
make net
|
||||
```
|
||||
|
||||
When not using the Makefile to compile (for instance with Microsoft MSVC) you
|
||||
|
@ -237,8 +241,7 @@ compiler you used to create your executable. These informations can
|
|||
be found by typing the following commands in a console:
|
||||
|
||||
```
|
||||
./stockfish
|
||||
compiler
|
||||
./stockfish compiler
|
||||
```
|
||||
|
||||
## Understanding the code base and participating in the project
|
||||
|
|
|
@ -39,6 +39,16 @@ namespace {
|
|||
Bitboard BishopTable[0x1480]; // To store bishop attacks
|
||||
|
||||
void init_magics(PieceType pt, Bitboard table[], Magic magics[]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// safe_destination() returns the bitboard of target square for the given step
|
||||
/// from the given square. If the step is off the board, returns empty bitboard.
|
||||
|
||||
inline Bitboard safe_destination(Square s, int step) {
|
||||
Square to = Square(s + step);
|
||||
return is_ok(to) && distance(s, to) <= 2 ? square_bb(to) : Bitboard(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -110,7 +120,7 @@ namespace {
|
|||
Direction RookDirections[4] = {NORTH, SOUTH, EAST, WEST};
|
||||
Direction BishopDirections[4] = {NORTH_EAST, SOUTH_EAST, SOUTH_WEST, NORTH_WEST};
|
||||
|
||||
for(Direction d : (pt == ROOK ? RookDirections : BishopDirections))
|
||||
for (Direction d : (pt == ROOK ? RookDirections : BishopDirections))
|
||||
{
|
||||
Square s = sq;
|
||||
while(safe_destination(s, d) && !(occupied & s))
|
||||
|
|
|
@ -279,16 +279,6 @@ inline int edge_distance(File f) { return std::min(f, File(FILE_H - f)); }
|
|||
inline int edge_distance(Rank r) { return std::min(r, Rank(RANK_8 - r)); }
|
||||
|
||||
|
||||
/// safe_destination() returns the bitboard of target square for the given step
|
||||
/// from the given square. If the step is off the board, returns empty bitboard.
|
||||
|
||||
inline Bitboard safe_destination(Square s, int step)
|
||||
{
|
||||
Square to = Square(s + step);
|
||||
return is_ok(to) && distance(s, to) <= 2 ? square_bb(to) : Bitboard(0);
|
||||
}
|
||||
|
||||
|
||||
/// attacks_bb(Square) returns the pseudo attacks of the give piece type
|
||||
/// assuming an empty board.
|
||||
|
||||
|
|
|
@ -288,8 +288,8 @@ namespace {
|
|||
attackedBy2[Us] = dblAttackByPawn | (attackedBy[Us][KING] & attackedBy[Us][PAWN]);
|
||||
|
||||
// Init our king safety tables
|
||||
Square s = make_square(Utility::clamp(file_of(ksq), FILE_B, FILE_G),
|
||||
Utility::clamp(rank_of(ksq), RANK_2, RANK_7));
|
||||
Square s = make_square(std::clamp(file_of(ksq), FILE_B, FILE_G),
|
||||
std::clamp(rank_of(ksq), RANK_2, RANK_7));
|
||||
kingRing[Us] = attacks_bb<KING>(s) | s;
|
||||
|
||||
kingAttackersCount[Them] = popcount(kingRing[Us] & pe->pawn_attacks(Them));
|
||||
|
@ -686,8 +686,8 @@ namespace {
|
|||
Square blockSq = s + Up;
|
||||
|
||||
// Adjust bonus based on the king's proximity
|
||||
bonus += make_score(0, ( (king_proximity(Them, blockSq) * 19) / 4
|
||||
- king_proximity(Us, blockSq) * 2) * w);
|
||||
bonus += make_score(0, ( king_proximity(Them, blockSq) * 19 / 4
|
||||
- king_proximity(Us, blockSq) * 2) * w);
|
||||
|
||||
// If blockSq is not the queening square then consider also a second push
|
||||
if (r != RANK_7)
|
||||
|
@ -731,7 +731,7 @@ namespace {
|
|||
|
||||
|
||||
// Evaluation::space() computes a space evaluation for a given side, aiming to improve game
|
||||
// play in the opening. It is based on the number of safe squares on the 4 central files
|
||||
// play in the opening. It is based on the number of safe squares on the four central files
|
||||
// on ranks 2 to 4. Completely safe squares behind a friendly pawn are counted twice.
|
||||
// Finally, the space bonus is multiplied by a weight which decreases according to occupancy.
|
||||
|
||||
|
@ -804,7 +804,7 @@ namespace {
|
|||
// Now apply the bonus: note that we find the attacking side by extracting the
|
||||
// sign of the midgame or endgame values, and that we carefully cap the bonus
|
||||
// so that the midgame and endgame scores do not change sign after the bonus.
|
||||
int u = ((mg > 0) - (mg < 0)) * Utility::clamp(complexity + 50, -abs(mg), 0);
|
||||
int u = ((mg > 0) - (mg < 0)) * std::clamp(complexity + 50, -abs(mg), 0);
|
||||
int v = ((eg > 0) - (eg < 0)) * std::max(complexity, -abs(eg));
|
||||
|
||||
mg += u;
|
||||
|
@ -951,8 +951,8 @@ Value Eval::evaluate(const Position& pos) {
|
|||
// Damp down the evaluation linearly when shuffling
|
||||
v = v * (100 - pos.rule50_count()) / 100;
|
||||
|
||||
// Guarantee evalution outside of TB range
|
||||
v = Utility::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1);
|
||||
// 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);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
@ -1013,6 +1013,5 @@ std::string Eval::trace(const Position& pos) {
|
|||
v = pos.side_to_move() == WHITE ? v : -v;
|
||||
ss << "\nFinal evaluation: " << to_cp(v) << " (white side)\n";
|
||||
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ Entry* probe(const Position& pos) {
|
|||
|
||||
Value npm_w = pos.non_pawn_material(WHITE);
|
||||
Value npm_b = pos.non_pawn_material(BLACK);
|
||||
Value npm = Utility::clamp(npm_w + npm_b, EndgameLimit, MidgameLimit);
|
||||
Value npm = std::clamp(npm_w + npm_b, EndgameLimit, MidgameLimit);
|
||||
|
||||
// Map total non-pawn material into [PHASE_ENDGAME, PHASE_MIDGAME]
|
||||
e->gamePhase = Phase(((npm - EndgameLimit) * PHASE_MIDGAME) / (MidgameLimit - EndgameLimit));
|
||||
|
|
17
src/misc.cpp
17
src/misc.cpp
|
@ -328,16 +328,16 @@ void prefetch(void* addr) {
|
|||
|
||||
#endif
|
||||
|
||||
/// Wrappers for systems where the c++17 implementation doesn't guarantee the availability of aligned_alloc.
|
||||
/// Memory allocated with std_aligned_alloc must be freed with std_aligned_free.
|
||||
///
|
||||
|
||||
/// std_aligned_alloc() is our wrapper for systems where the c++17 implementation
|
||||
/// does not guarantee the availability of aligned_alloc(). Memory allocated with
|
||||
/// std_aligned_alloc() must be freed with std_aligned_free().
|
||||
|
||||
void* std_aligned_alloc(size_t alignment, size_t size) {
|
||||
|
||||
#if defined(POSIXALIGNEDALLOC)
|
||||
void *pointer;
|
||||
if(posix_memalign(&pointer, alignment, size) == 0)
|
||||
return pointer;
|
||||
return nullptr;
|
||||
void *mem;
|
||||
return posix_memalign(&mem, alignment, size) ? nullptr : mem;
|
||||
#elif defined(_WIN32)
|
||||
return _mm_malloc(size, alignment);
|
||||
#else
|
||||
|
@ -346,6 +346,7 @@ void* std_aligned_alloc(size_t alignment, size_t size) {
|
|||
}
|
||||
|
||||
void std_aligned_free(void* ptr) {
|
||||
|
||||
#if defined(POSIXALIGNEDALLOC)
|
||||
free(ptr);
|
||||
#elif defined(_WIN32)
|
||||
|
@ -355,7 +356,7 @@ void std_aligned_free(void* ptr) {
|
|||
#endif
|
||||
}
|
||||
|
||||
/// aligned_ttmem_alloc() will return suitably aligned memory, and if possible use large pages.
|
||||
/// aligned_ttmem_alloc() will return suitably aligned memory, if possible using large pages.
|
||||
/// The returned pointer is the aligned one, while the mem argument is the one that needs
|
||||
/// to be passed to free. With c++17 some of this functionality could be simplified.
|
||||
|
||||
|
|
|
@ -65,14 +65,6 @@ std::ostream& operator<<(std::ostream&, SyncCout);
|
|||
#define sync_cout std::cout << IO_LOCK
|
||||
#define sync_endl std::endl << IO_UNLOCK
|
||||
|
||||
namespace Utility {
|
||||
|
||||
/// Clamp a value between lo and hi. Available in c++17.
|
||||
template<class T> constexpr const T& clamp(const T& v, const T& lo, const T& hi) {
|
||||
return v < lo ? lo : v > hi ? hi : v;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// xorshift64star Pseudo-Random Number Generator
|
||||
/// This class is based on original code written and dedicated
|
||||
|
|
|
@ -248,7 +248,7 @@ namespace {
|
|||
*moveList++ = make_move(ksq, pop_lsb(&b));
|
||||
|
||||
if ((Type != CAPTURES) && pos.can_castle(Us & ANY_CASTLING))
|
||||
for(CastlingRights cr : { Us & KING_SIDE, Us & QUEEN_SIDE } )
|
||||
for (CastlingRights cr : { Us & KING_SIDE, Us & QUEEN_SIDE } )
|
||||
if (!pos.castling_impeded(cr) && pos.can_castle(cr))
|
||||
*moveList++ = make<CASTLING>(ksq, pos.castling_rook_square(cr));
|
||||
}
|
||||
|
|
|
@ -182,7 +182,7 @@ top:
|
|||
--endMoves;
|
||||
|
||||
++stage;
|
||||
/* fallthrough */
|
||||
[[fallthrough]];
|
||||
|
||||
case REFUTATION:
|
||||
if (select<Next>([&](){ return *cur != MOVE_NONE
|
||||
|
@ -190,7 +190,7 @@ top:
|
|||
&& pos.pseudo_legal(*cur); }))
|
||||
return *(cur - 1);
|
||||
++stage;
|
||||
/* fallthrough */
|
||||
[[fallthrough]];
|
||||
|
||||
case QUIET_INIT:
|
||||
if (!skipQuiets)
|
||||
|
@ -203,7 +203,7 @@ top:
|
|||
}
|
||||
|
||||
++stage;
|
||||
/* fallthrough */
|
||||
[[fallthrough]];
|
||||
|
||||
case QUIET:
|
||||
if ( !skipQuiets
|
||||
|
@ -217,7 +217,7 @@ top:
|
|||
endMoves = endBadCaptures;
|
||||
|
||||
++stage;
|
||||
/* fallthrough */
|
||||
[[fallthrough]];
|
||||
|
||||
case BAD_CAPTURE:
|
||||
return select<Next>([](){ return true; });
|
||||
|
@ -228,7 +228,7 @@ top:
|
|||
|
||||
score<EVASIONS>();
|
||||
++stage;
|
||||
/* fallthrough */
|
||||
[[fallthrough]];
|
||||
|
||||
case EVASION:
|
||||
return select<Best>([](){ return true; });
|
||||
|
@ -246,14 +246,14 @@ top:
|
|||
return MOVE_NONE;
|
||||
|
||||
++stage;
|
||||
/* fallthrough */
|
||||
[[fallthrough]];
|
||||
|
||||
case QCHECK_INIT:
|
||||
cur = moves;
|
||||
endMoves = generate<QUIET_CHECKS>(pos, cur);
|
||||
|
||||
++stage;
|
||||
/* fallthrough */
|
||||
[[fallthrough]];
|
||||
|
||||
case QCHECK:
|
||||
return select<Next>([](){ return true; });
|
||||
|
|
|
@ -86,9 +86,9 @@ enum StatsType { NoCaptures, Captures };
|
|||
/// the move's from and to squares, see www.chessprogramming.org/Butterfly_Boards
|
||||
typedef Stats<int16_t, 10692, COLOR_NB, int(SQUARE_NB) * int(SQUARE_NB)> ButterflyHistory;
|
||||
|
||||
/// At higher depths LowPlyHistory records successful quiet moves near the root and quiet
|
||||
/// moves which are/were in the PV (ttPv)
|
||||
/// It is cleared with each new search and filled during iterative deepening
|
||||
/// At higher depths LowPlyHistory records successful quiet moves near the root
|
||||
/// and quiet moves which are/were in the PV (ttPv). It is cleared with each new
|
||||
/// search and filled during iterative deepening.
|
||||
constexpr int MAX_LPH = 4;
|
||||
typedef Stats<int16_t, 10692, MAX_LPH, int(SQUARE_NB) * int(SQUARE_NB)> LowPlyHistory;
|
||||
|
||||
|
|
|
@ -219,7 +219,7 @@ Score Entry::evaluate_shelter(const Position& pos, Square ksq) const {
|
|||
|
||||
Score bonus = make_score(5, 5);
|
||||
|
||||
File center = Utility::clamp(file_of(ksq), FILE_B, FILE_G);
|
||||
File center = std::clamp(file_of(ksq), FILE_B, FILE_G);
|
||||
for (File f = File(center - 1); f <= File(center + 1); ++f)
|
||||
{
|
||||
b = ourPawns & file_bb(f);
|
||||
|
|
|
@ -1145,8 +1145,8 @@ bool Position::see_ge(Move m, Value threshold) const {
|
|||
|
||||
// Don't allow pinned pieces to attack (except the king) as long as
|
||||
// there are pinners on their original square.
|
||||
if (st->pinners[~stm] & occupied)
|
||||
stmAttackers &= ~st->blockersForKing[stm];
|
||||
if (pinners(~stm) & occupied)
|
||||
stmAttackers &= ~blockers_for_king(stm);
|
||||
|
||||
if (!stmAttackers)
|
||||
break;
|
||||
|
|
|
@ -113,6 +113,7 @@ public:
|
|||
Bitboard checkers() const;
|
||||
Bitboard blockers_for_king(Color c) const;
|
||||
Bitboard check_squares(PieceType pt) const;
|
||||
Bitboard pinners(Color c) const;
|
||||
bool is_discovery_check_on_king(Color c, Move m) const;
|
||||
|
||||
// Attacks to/from a given square
|
||||
|
@ -309,6 +310,10 @@ inline Bitboard Position::blockers_for_king(Color c) const {
|
|||
return st->blockersForKing[c];
|
||||
}
|
||||
|
||||
inline Bitboard Position::pinners(Color c) const {
|
||||
return st->pinners[c];
|
||||
}
|
||||
|
||||
inline Bitboard Position::check_squares(PieceType pt) const {
|
||||
return st->checkSquares[pt];
|
||||
}
|
||||
|
|
|
@ -335,7 +335,7 @@ void Thread::search() {
|
|||
// for match (TC 60+0.6) results spanning a wide range of k values.
|
||||
PRNG rng(now());
|
||||
double floatLevel = Options["UCI_LimitStrength"] ?
|
||||
Utility::clamp(std::pow((Options["UCI_Elo"] - 1346.6) / 143.4, 1 / 0.806), 0.0, 20.0) :
|
||||
std::clamp(std::pow((Options["UCI_Elo"] - 1346.6) / 143.4, 1 / 0.806), 0.0, 20.0) :
|
||||
double(Options["Skill Level"]);
|
||||
int intLevel = int(floatLevel) +
|
||||
((floatLevel - int(floatLevel)) * 1024 > rng.rand<unsigned>() % 1024 ? 1 : 0);
|
||||
|
@ -508,7 +508,7 @@ void Thread::search() {
|
|||
{
|
||||
double fallingEval = (318 + 6 * (mainThread->bestPreviousScore - bestValue)
|
||||
+ 6 * (mainThread->iterValue[iterIdx] - bestValue)) / 825.0;
|
||||
fallingEval = Utility::clamp(fallingEval, 0.5, 1.5);
|
||||
fallingEval = std::clamp(fallingEval, 0.5, 1.5);
|
||||
|
||||
// If the bestMove is stable over several iterations, reduce time accordingly
|
||||
timeReduction = lastBestMoveDepth + 9 < completedDepth ? 1.92 : 0.95;
|
||||
|
@ -807,8 +807,9 @@ namespace {
|
|||
&& eval <= alpha - RazorMargin)
|
||||
return qsearch<NT>(pos, ss, alpha, beta);
|
||||
|
||||
improving = (ss-2)->staticEval == VALUE_NONE ? (ss->staticEval > (ss-4)->staticEval
|
||||
|| (ss-4)->staticEval == VALUE_NONE) : ss->staticEval > (ss-2)->staticEval;
|
||||
improving = (ss-2)->staticEval == VALUE_NONE
|
||||
? ss->staticEval > (ss-4)->staticEval || (ss-4)->staticEval == VALUE_NONE
|
||||
: ss->staticEval > (ss-2)->staticEval;
|
||||
|
||||
// Step 8. Futility pruning: child node (~50 Elo)
|
||||
if ( !PvNode
|
||||
|
@ -1238,7 +1239,7 @@ moves_loop: // When in check, search starts from here
|
|||
r++;
|
||||
}
|
||||
|
||||
Depth d = Utility::clamp(newDepth - r, 1, newDepth);
|
||||
Depth d = std::clamp(newDepth - r, 1, newDepth);
|
||||
|
||||
value = -search<NonPV>(pos, ss+1, -(alpha+1), -alpha, d, true);
|
||||
|
||||
|
|
|
@ -38,9 +38,9 @@ void TimeManagement::init(Search::LimitsType& limits, Color us, int ply) {
|
|||
TimePoint slowMover = TimePoint(Options["Slow Mover"]);
|
||||
TimePoint npmsec = TimePoint(Options["nodestime"]);
|
||||
|
||||
// opt_scale is a percentage of available time to use for the current move.
|
||||
// max_scale is a multiplier applied to optimumTime.
|
||||
double opt_scale, max_scale;
|
||||
// optScale is a percentage of available time to use for the current move.
|
||||
// maxScale is a multiplier applied to optimumTime.
|
||||
double optScale, maxScale;
|
||||
|
||||
// If we have to play in 'nodes as time' mode, then convert from time
|
||||
// to nodes, and use resulting values in time management formulas.
|
||||
|
@ -75,22 +75,22 @@ void TimeManagement::init(Search::LimitsType& limits, Color us, int ply) {
|
|||
// game time for the current move, so also cap to 20% of available game time.
|
||||
if (limits.movestogo == 0)
|
||||
{
|
||||
opt_scale = std::min(0.008 + std::pow(ply + 3.0, 0.5) / 250.0,
|
||||
optScale = std::min(0.008 + std::pow(ply + 3.0, 0.5) / 250.0,
|
||||
0.2 * limits.time[us] / double(timeLeft));
|
||||
max_scale = std::min(7.0, 4.0 + ply / 12.0);
|
||||
maxScale = std::min(7.0, 4.0 + ply / 12.0);
|
||||
}
|
||||
|
||||
// x moves in y seconds (+ z increment)
|
||||
else
|
||||
{
|
||||
opt_scale = std::min((0.8 + ply / 128.0) / mtg,
|
||||
optScale = std::min((0.8 + ply / 128.0) / mtg,
|
||||
0.8 * limits.time[us] / double(timeLeft));
|
||||
max_scale = std::min(6.3, 1.5 + 0.11 * mtg);
|
||||
maxScale = std::min(6.3, 1.5 + 0.11 * mtg);
|
||||
}
|
||||
|
||||
// Never use more than 80% of the available time for this move
|
||||
optimumTime = TimePoint(opt_scale * timeLeft);
|
||||
maximumTime = TimePoint(std::min(0.8 * limits.time[us] - moveOverhead, max_scale * optimumTime));
|
||||
optimumTime = TimePoint(optScale * timeLeft);
|
||||
maximumTime = TimePoint(std::min(0.8 * limits.time[us] - moveOverhead, maxScale * optimumTime));
|
||||
|
||||
if (Options["Ponder"])
|
||||
optimumTime += optimumTime / 4;
|
||||
|
|
|
@ -211,7 +211,7 @@ namespace {
|
|||
double b = (((bs[0] * m + bs[1]) * m + bs[2]) * m) + bs[3];
|
||||
|
||||
// Transform eval to centipawns with limited range
|
||||
double x = Utility::clamp(double(100 * v) / PawnValueEg, -1000.0, 1000.0);
|
||||
double x = std::clamp(double(100 * v) / PawnValueEg, -1000.0, 1000.0);
|
||||
|
||||
// Return win rate in per mille (rounded to nearest)
|
||||
return int(0.5 + 1000 / (1 + std::exp((a - x) / b)));
|
||||
|
|
Loading…
Add table
Reference in a new issue