Fix syzygy DTZ bug
authorMarco Costalba <mcostalba@gmail.com>
Sun, 29 May 2016 08:10:39 +0000 (10:10 +0200)
committerMarco Costalba <mcostalba@gmail.com>
Tue, 7 Jun 2016 13:06:26 +0000 (15:06 +0200)
In this position: 3K4/8/3k4/8/4p3/4B3/5P2/8 w - - 0 5

Current DTZ probe returns 1 instead of 15

What happens is that the double push f4 is erroneously detected as a win move.

After the push we have:

[D]3K4/8/3k4/8/4pP2/4B3/8/8 b - f3 0 5

And here the code misses the possible ep capture exf3.

The bug is in probe_dtz_no_ep() where is used probe_ab() that is
blind to ep captures so it returns v == 2 (win) for position

3K4/8/3k4/8/4pP2/4B3/8/8 b - f3 0 5

Note that at the caller site the original position did not have any
possible ep capture, so probe_dtz() returns immediately after calling
probe_dtz_no_ep().

The fix is to call the ep-aware probe_wdl() instead of probe_ab()

I have verified that DTZ is correct now and also there are no more
mistmatches compared to the new 'syzygy' branch. Tested on a set of
more than 600 endgame positions, included some tricky ones.

For people interested to redo the test or doing additional tests
please pull branch tb_dbg from https://github.com/mcostalba/Stockfish repo.

bench: 8450534 (bench unaffected because syzygy is not exercized during bench)

src/syzygy/tbprobe.cpp

index e07cd1b..1b05db9 100644 (file)
@@ -495,7 +495,7 @@ static int probe_dtz_no_ep(Position& pos, int *success)
                 || !pos.legal(move, ci.pinned))
         continue;
       pos.do_move(move, st, pos.gives_check(move, ci));
-      int v = -probe_ab(pos, -2, -wdl + 1, success);
+      int v = -Tablebases::probe_wdl(pos, success);
       pos.undo_move(move);
       if (*success == 0) return 0;
       if (v == wdl)