]> git.sesse.net Git - stockfish/commitdiff
Fix TB score output in UCI without using TB
authorShahin M. Shahin <41402573+peregrineshahin@users.noreply.github.com>
Fri, 17 Nov 2023 15:25:50 +0000 (18:25 +0300)
committerDisservin <disservin.social@gmail.com>
Thu, 14 Dec 2023 17:35:38 +0000 (18:35 +0100)
This is a rewrite of the fix introduced for
https://github.com/official-stockfish/Stockfish/issues/4413 in
https://github.com/official-stockfish/Stockfish/pull/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 https://github.com/official-stockfish/Stockfish/issues/4413
closes https://github.com/official-stockfish/Stockfish/pull/4591
closes https://github.com/official-stockfish/Stockfish/pull/4882

Bench: 1305821

src/search.cpp
src/types.h
src/uci.cpp

index f398074065d26be50920eadd5fa4024063300f17..89879374c1a40643a9d2a73b6893fb869a336593 100644 (file)
@@ -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
@@ -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;
     }
@@ -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
index 0575f1d453cd3e371ec4305144f568c93459796f..3e00d68d19dcc8bad266ef8b03ba11872f24dd93 100644 (file)
@@ -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
index 95f6f349dd3cf4675407ac7ebb54efd32df4464b..d0341bd71683a173e8096317cfa1b5e46405bfb4 100644 (file)
@@ -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