summaryrefslogtreecommitdiff
path: root/src/dynamic.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dynamic.c')
-rwxr-xr-xsrc/dynamic.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/src/dynamic.c b/src/dynamic.c
index c6e86e3..694fe50 100755
--- a/src/dynamic.c
+++ b/src/dynamic.c
@@ -289,10 +289,21 @@ Return value:
{
ctx->mvKillerEscapes[uPly][1] = ctx->mvKillerEscapes[uPly][0];
ctx->mvKillerEscapes[uPly][0] = mv;
- if (ctx->mvKillerEscapes[uPly][1].uMove == 0)
- {
- ctx->mvKillerEscapes[uPly][1] = ctx->mvNullmoveRefutations[uPly];
- }
+ // No mvNullmoveQuietRefutations backfill here, unlike the
+ // regular killer table below: TryNullmovePruning asserts
+ // !InCheck() before probing, and a null move doesn't move
+ // any piece, so the move that refutes it is necessarily
+ // played from a position where the opponent was *not* in
+ // check either -- it can never legitimately be a check
+ // evasion. Backfilling with it here wouldn't be dead code
+ // the way the old capture-into-quiet-slot bug was (that
+ // was mathematically guaranteed to never match); since
+ // IS_SAME_MOVE ignores bvFlags, an ordinary quiet move
+ // from some unrelated non-check position could coincide
+ // with a real escaping candidate by cFrom/cTo/pMoved/
+ // pCaptured/pPromoted alone and pick up an undeserved
+ // SECOND_KILLER bonus in evasion ordering. Leave the slot
+ // empty instead of risking that.
}
ASSERT(!IS_SAME_MOVE(ctx->mvKillerEscapes[uPly][0],
ctx->mvKillerEscapes[uPly][1]));
@@ -304,9 +315,9 @@ Return value:
{
ctx->mvKiller[uPly][1] = ctx->mvKiller[uPly][0];
ctx->mvKiller[uPly][0] = mv;
- if (ctx->mvKiller[uPly][1].uMove == 0)
+ if (ctx->mvKiller[uPly][1].uMove == 0)
{
- ctx->mvKiller[uPly][1] = ctx->mvNullmoveRefutations[uPly];
+ ctx->mvKiller[uPly][1] = ctx->mvNullmoveQuietRefutations[uPly];
}
}
ASSERT(!IS_SAME_MOVE(ctx->mvKiller[uPly][0], ctx->mvKiller[uPly][1]));