Skip to content

Commit

Permalink
Randomize draw eval
Browse files Browse the repository at this point in the history
The patch adds a small random component (+-1) to VALUE_DRAW for the evaluation
of draw positions (mostly 3folds). This random component is not static, but
potentially different for each visit of the node (hence derived from the node
counter). The effect is that in positions with many 3fold draw lines, different
lines are followed at each iteration. This keeps the search much more dynamic,
as opposed to being locked to one particular 3fold.

An example of a position where master suffers from 3fold-blindness and this patch
solves quickly is the famous TCEC game 53:

FEN: 3r2k1/pr6/1p3q1p/5R2/3P3p/8/5RP1/3Q2K1 b - - 0 51

master doesn't see that this is a lost position (draw eval up to depth 50) as
Qf6-e6 d4-d5 (found by patch at depth 23) leads to a loss.

The 3fold-blindness is more important at longer TC, the patch was yellow STC and
LTC, but passed VLTC:

STC
LLR: -2.95 (-2.94,2.94) [0.00,5.00]
Total: 46328 W: 10048 L: 9953 D: 26327
http://tests.stockfishchess.org/tests/view/5b9c0ca20ebc592cf275f7c7

LTC
LLR: -2.95 (-2.94,2.94) [0.00,5.00]
Total: 54663 W: 8938 L: 8846 D: 36879
http://tests.stockfishchess.org/tests/view/5b9ca1610ebc592cf27601d3

VLTC
LLR: 2.95 (-2.94,2.94) [0.00,5.00]
Total: 31789 W: 4512 L: 4284 D: 22993
http://tests.stockfishchess.org/tests/view/5b9d1a670ebc592cf276076d

Credit to @crossbr for pointing to this problem repeatedly, and giving the hint
that many draw lines are typical in those situations.

Bench: 4756639
  • Loading branch information
vondele authored and snicolet committed Oct 14, 2018
1 parent cb0111d commit 97d2cc9
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions src/search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ namespace {
return d > 17 ? 0 : 29 * d * d + 138 * d - 134;
}

// Add a small random component to draw evaluations to keep search dynamic
// and to avoid 3fold-blindness.
Value value_draw(Depth depth, Thread* thisThread) {
return depth < 4 ? VALUE_DRAW
: VALUE_DRAW + Value(2 * (thisThread->nodes.load(std::memory_order_relaxed) % 2) - 1);
}

// Skill structure is used to implement strength limit
struct Skill {
explicit Skill(int l) : level(l) {}
Expand Down Expand Up @@ -535,7 +542,7 @@ namespace {
&& !rootNode
&& pos.has_game_cycle(ss->ply))
{
alpha = VALUE_DRAW;
alpha = value_draw(depth, pos.this_thread());
if (alpha >= beta)
return alpha;
}
Expand Down Expand Up @@ -584,7 +591,8 @@ namespace {
if ( Threads.stop.load(std::memory_order_relaxed)
|| pos.is_draw(ss->ply)
|| ss->ply >= MAX_PLY)
return (ss->ply >= MAX_PLY && !inCheck) ? evaluate(pos) : VALUE_DRAW;
return (ss->ply >= MAX_PLY && !inCheck) ? evaluate(pos)
: value_draw(depth, pos.this_thread());

// Step 3. Mate distance pruning. Even if we mate at the next move our score
// would be at best mate_in(ss->ply+1), but if alpha is already bigger because
Expand Down

0 comments on commit 97d2cc9

Please sign in to comment.