Skip to content

Commit

Permalink
Fix TB score output in UCI without using TB
Browse files Browse the repository at this point in the history
This is a rewrite of the fix introduced for
#4413 in
#4591 by @windfishballad it
targets only the relevant part of this issue that returns TB scores (CP 20000)
without using TB due to the downgrading of potentially false mates from the TT
to an optimal TB score.

the difference is that it is a much clearer code that introduces a separate
TB_VALUE constant to account for a correct distance from the TB_VALUE with
MAX_PLY.

the originally posted position in the issue does not trigger the problem
anymore, so here is a new position to test:
```
position fen 3k4/8/8/8/8/8/3BN3/3K4 w - - 0 1
go infinite
```

Passed non-regression STC:
https://tests.stockfishchess.org/tests/view/65578994136acbc57353b258
LLR: 2.96 (-2.94,2.94) <-1.75,0.25>
Total: 119264 W: 29993 L: 29863 D: 59408
Ptnml(0-2): 372, 13692, 31379, 13812, 377

Passed non-regression LTC:
https://tests.stockfishchess.org/tests/view/6558323f136acbc57353c1ca
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 237834 W: 58791 L: 58792 D: 120251
Ptnml(0-2): 193, 26200, 66111, 26241, 172

fixes #4413
closes #4591
closes #4882

Bench: 1305821
  • Loading branch information
peregrineshahin authored and Disservin committed Dec 14, 2023
1 parent 36db936 commit 282e15b
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 19 deletions.
39 changes: 27 additions & 12 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -678,9 +678,11 @@ Value search(Position& pos, Stack* ss, Value alpha, Value beta, Depth depth, boo

int drawScore = TB::UseRule50 ? 1 : 0;

// use the range VALUE_MATE_IN_MAX_PLY to VALUE_TB_WIN_IN_MAX_PLY to score
value = wdl < -drawScore ? VALUE_MATED_IN_MAX_PLY + ss->ply + 1
: wdl > drawScore ? VALUE_MATE_IN_MAX_PLY - ss->ply - 1
Value tbValue = VALUE_TB - ss->ply;

// use the range VALUE_TB to VALUE_TB_WIN_IN_MAX_PLY to score
value = wdl < -drawScore ? -tbValue
: wdl > drawScore ? tbValue
: VALUE_DRAW + 2 * wdl * drawScore;

Bound b = wdl < -drawScore ? BOUND_UPPER
Expand Down Expand Up @@ -1631,25 +1633,38 @@ Value value_to_tt(Value v, int ply) {
// Inverse of value_to_tt(): it adjusts a mate or TB score
// from the transposition table (which refers to the plies to mate/be mated from
// current position) to "plies to mate/be mated (TB win/loss) from the root".
// However, to avoid potentially false mate scores related to the 50 moves rule
// and the graph history interaction problem, we return an optimal TB score instead.
// However, to avoid potentially false mate or TB scores related to the 50 moves rule
// and the graph history interaction, we return highest non-TB score instead.

Value value_from_tt(Value v, int ply, int r50c) {

if (v == VALUE_NONE)
return VALUE_NONE;

if (v >= VALUE_TB_WIN_IN_MAX_PLY) // TB win or better
// handle TB win or better
if (v >= VALUE_TB_WIN_IN_MAX_PLY)
{
if (v >= VALUE_MATE_IN_MAX_PLY && VALUE_MATE - v > 99 - r50c)
return VALUE_MATE_IN_MAX_PLY - 1; // do not return a potentially false mate score
// Downgrade a potentially false mate score
if (v >= VALUE_MATE_IN_MAX_PLY && VALUE_MATE - v > 100 - r50c)
return VALUE_TB_WIN_IN_MAX_PLY - 1;

// Downgrade a potentially false TB score.
if (VALUE_TB - v > 100 - r50c)
return VALUE_TB_WIN_IN_MAX_PLY - 1;

return v - ply;
}

if (v <= VALUE_TB_LOSS_IN_MAX_PLY) // TB loss or worse
// handle TB loss or worse
if (v <= VALUE_TB_LOSS_IN_MAX_PLY)
{
if (v <= VALUE_MATED_IN_MAX_PLY && VALUE_MATE + v > 99 - r50c)
return VALUE_MATED_IN_MAX_PLY + 1; // do not return a potentially false mate score
// Downgrade a potentially false mate score.
if (v <= VALUE_MATED_IN_MAX_PLY && VALUE_MATE + v > 100 - r50c)
return VALUE_TB_LOSS_IN_MAX_PLY + 1;

// Downgrade a potentially false TB score.
if (VALUE_TB + v > 100 - r50c)
return VALUE_TB_LOSS_IN_MAX_PLY + 1;

return v + ply;
}
Expand Down Expand Up @@ -1866,7 +1881,7 @@ string UCI::pv(const Position& pos, Depth depth) {
if (v == -VALUE_INFINITE)
v = VALUE_ZERO;

bool tb = TB::RootInTB && abs(v) < VALUE_MATE_IN_MAX_PLY;
bool tb = TB::RootInTB && abs(v) <= VALUE_TB;
v = tb ? rootMoves[i].tbScore : v;

if (ss.rdbuf()->in_avail()) // Not at first line
Expand Down
12 changes: 7 additions & 5 deletions src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,14 +164,16 @@ enum Bound {
enum Value : int {
VALUE_ZERO = 0,
VALUE_DRAW = 0,
VALUE_MATE = 32000,
VALUE_INFINITE = 32001,
VALUE_NONE = 32002,
VALUE_INFINITE = 32001,

VALUE_MATE = 32000,
VALUE_MATE_IN_MAX_PLY = VALUE_MATE - MAX_PLY,
VALUE_MATED_IN_MAX_PLY = -VALUE_MATE_IN_MAX_PLY,

VALUE_TB_WIN_IN_MAX_PLY = VALUE_MATE - 2 * MAX_PLY,
VALUE_TB = VALUE_MATE_IN_MAX_PLY - 1,
VALUE_TB_WIN_IN_MAX_PLY = VALUE_TB - MAX_PLY,
VALUE_TB_LOSS_IN_MAX_PLY = -VALUE_TB_WIN_IN_MAX_PLY,
VALUE_MATE_IN_MAX_PLY = VALUE_MATE - MAX_PLY,
VALUE_MATED_IN_MAX_PLY = -VALUE_MATE_IN_MAX_PLY,

// In the code, we make the assumption that these values
// are such that non_pawn_material() can be used to uniquely
Expand Down
4 changes: 2 additions & 2 deletions src/uci.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -356,9 +356,9 @@ std::string UCI::value(Value v) {

if (abs(v) < VALUE_TB_WIN_IN_MAX_PLY)
ss << "cp " << UCI::to_cp(v);
else if (abs(v) < VALUE_MATE_IN_MAX_PLY)
else if (abs(v) <= VALUE_TB)
{
const int ply = VALUE_MATE_IN_MAX_PLY - 1 - std::abs(v); // recompute ss->ply
const int ply = VALUE_TB - std::abs(v); // recompute ss->ply
ss << "cp " << (v > 0 ? 20000 - ply : -20000 + ply);
}
else
Expand Down

0 comments on commit 282e15b

Please sign in to comment.