For qn4N1/6R1/3K4/8/B2k4/8/8/8 w - - 0 1, white loses with DTZ 1034.
See https://syzygy-tables.info/?fen=qn4N1/6R1/3K4/8/B2k4/8/8/8_w_-_-_0_1
Prior to this fix, due to a too small hard-coded value, Stockfish interpreted this as winning.
The new value picked (1<<18) is large enough to deal with the largest DTZ values that can be stored in the current syzygy format.
closes https://github.com/official-stockfish/Stockfish/pull/4187
No functional change.
Reuven Peleg
Richard Lloyd
Rodrigo Exterckötter Tjäder
Reuven Peleg
Richard Lloyd
Rodrigo Exterckötter Tjäder
Ron Britvich (Britvich)
Ronald de Man (syzygy1, syzygy)
rqs
Ron Britvich (Britvich)
Ronald de Man (syzygy1, syzygy)
rqs
namespace {
constexpr int TBPIECES = 7; // Max number of supported pieces
namespace {
constexpr int TBPIECES = 7; // Max number of supported pieces
+constexpr int MAX_DTZ = 1 << 18; // Max DTZ supported, large enough to deal with the syzygy TB limit.
enum { BigEndian, LittleEndian };
enum TBType { WDL, DTZ }; // Used as template parameter
enum { BigEndian, LittleEndian };
enum TBType { WDL, DTZ }; // Used as template parameter
// Check whether a position was repeated since the last zeroing move.
bool rep = pos.has_repeated();
// Check whether a position was repeated since the last zeroing move.
bool rep = pos.has_repeated();
- int dtz, bound = Options["Syzygy50MoveRule"] ? 900 : 1;
+ int dtz, bound = Options["Syzygy50MoveRule"] ? (MAX_DTZ - 100) : 1;
// Probe and rank each move
for (auto& m : rootMoves)
// Probe and rank each move
for (auto& m : rootMoves)
// Better moves are ranked higher. Certain wins are ranked equally.
// Losing moves are ranked equally unless a 50-move draw is in sight.
// Better moves are ranked higher. Certain wins are ranked equally.
// Losing moves are ranked equally unless a 50-move draw is in sight.
- int r = dtz > 0 ? (dtz + cnt50 <= 99 && !rep ? 1000 : 1000 - (dtz + cnt50))
- : dtz < 0 ? (-dtz * 2 + cnt50 < 100 ? -1000 : -1000 + (-dtz + cnt50))
+ int r = dtz > 0 ? (dtz + cnt50 <= 99 && !rep ? MAX_DTZ : MAX_DTZ - (dtz + cnt50))
+ : dtz < 0 ? (-dtz * 2 + cnt50 < 100 ? -MAX_DTZ : -MAX_DTZ + (-dtz + cnt50))
// 1 cp to cursed wins and let it grow to 49 cp as the positions gets
// closer to a real win.
m.tbScore = r >= bound ? VALUE_MATE - MAX_PLY - 1
// 1 cp to cursed wins and let it grow to 49 cp as the positions gets
// closer to a real win.
m.tbScore = r >= bound ? VALUE_MATE - MAX_PLY - 1
- : r > 0 ? Value((std::max( 3, r - 800) * int(PawnValueEg)) / 200)
+ : r > 0 ? Value((std::max( 3, r - (MAX_DTZ - 200)) * int(PawnValueEg)) / 200)
- : r > -bound ? Value((std::min(-3, r + 800) * int(PawnValueEg)) / 200)
+ : r > -bound ? Value((std::min(-3, r + (MAX_DTZ - 200)) * int(PawnValueEg)) / 200)
: -VALUE_MATE + MAX_PLY + 1;
}
: -VALUE_MATE + MAX_PLY + 1;
}
// A return value false indicates that not all probes were successful.
bool Tablebases::root_probe_wdl(Position& pos, Search::RootMoves& rootMoves) {
// A return value false indicates that not all probes were successful.
bool Tablebases::root_probe_wdl(Position& pos, Search::RootMoves& rootMoves) {
- static const int WDL_to_rank[] = { -1000, -899, 0, 899, 1000 };
+ static const int WDL_to_rank[] = { -MAX_DTZ, -MAX_DTZ + 101, 0, MAX_DTZ - 101, MAX_DTZ };
ProbeState result;
StateInfo st;
ProbeState result;
StateInfo st;
WDLDraw = 0, // Draw
WDLCursedWin = 1, // Win, but draw under 50-move rule
WDLWin = 2, // Win
WDLDraw = 0, // Draw
WDLCursedWin = 1, // Win, but draw under 50-move rule
WDLWin = 2, // Win
};
// Possible states after a probing operation
};
// Possible states after a probing operation