Skip to content

Commit

Permalink
Fix reported DTZ for mate-in-1-ply positions
Browse files Browse the repository at this point in the history
This corrects a bug in Tablebases::probe_dtz() which sometimes causes
a higher DTZ value to be returned for the position one ply before mate
than for the position two plies before mate.

The problem was reported by Kolja Kühn here:
http://talkchess.com/forum/viewtopic.php?p=757497#757497

It is explained here:
http://talkchess.com/forum/viewtopic.php?p=757506#757506

I have also adjusted some comments to make clear that probe_dtz()
returns -1 for a mate position.

Closes #1546

No functional change
  • Loading branch information
syzygy1 authored and snicolet committed Apr 14, 2018
1 parent 6413d9b commit ae0bb6d
Showing 1 changed file with 10 additions and 7 deletions.
17 changes: 10 additions & 7 deletions src/syzygy/tbprobe.cpp
Expand Up @@ -1354,6 +1354,7 @@ WDLScore Tablebases::probe_wdl(Position& pos, ProbeState* result) {
// The return value is from the point of view of the side to move:
// n < -100 : loss, but draw under 50-move rule
// -100 <= n < -1 : loss in n ply (assuming 50-move counter == 0)
// -1 : loss, the side to move is mated
// 0 : draw
// 1 < n <= 100 : win in n ply (assuming 50-move counter == 0)
// 100 < n : win, but draw under 50-move rule
Expand Down Expand Up @@ -1413,10 +1414,9 @@ int Tablebases::probe_dtz(Position& pos, ProbeState* result) {
dtz = zeroing ? -dtz_before_zeroing(search(pos, result))
: -probe_dtz(pos, result);

pos.undo_move(move);

if (*result == FAIL)
return 0;
// If the move mates, force minDTZ to 1
if (dtz == 1 && pos.checkers() && MoveList<LEGAL>(pos).size() == 0)
minDTZ = 1;

// Convert result from 1-ply search. Zeroing moves are already accounted
// by dtz_before_zeroing() that returns the DTZ of the previous move.
Expand All @@ -1426,11 +1426,14 @@ int Tablebases::probe_dtz(Position& pos, ProbeState* result) {
// Skip the draws and if we are winning only pick positive dtz
if (dtz < minDTZ && sign_of(dtz) == sign_of(wdl))
minDTZ = dtz;

pos.undo_move(move);

if (*result == FAIL)
return 0;
}

// Special handle a mate position, when there are no legal moves, in this
// case return value is somewhat arbitrary, so stick to the original TB code
// that returns -1 in this case.
// When there are no legal moves, the position is mate: we return -1
return minDTZ == 0xFFFF ? -1 : minDTZ;
}

Expand Down

0 comments on commit ae0bb6d

Please sign in to comment.