mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 08:43:09 +00:00
Null capture pruning
Null move can fail low because of a capture artifact due to the side to move change. Try to detect this condition and fail high instead. This pruning is very powerful, around 7% of nodes, but is still experimental so is disabled by default. Set UseNullCapturePruning to true to enable. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
dc2302b701
commit
b4fcfed55b
1 changed files with 37 additions and 0 deletions
|
@ -133,6 +133,9 @@ namespace {
|
||||||
// evaluation of the position is more than NullMoveMargin below beta.
|
// evaluation of the position is more than NullMoveMargin below beta.
|
||||||
const Value NullMoveMargin = Value(0x300);
|
const Value NullMoveMargin = Value(0x300);
|
||||||
|
|
||||||
|
// Use null capture pruning?
|
||||||
|
const bool UseNullCapturePruning = false;
|
||||||
|
|
||||||
// Pruning criterions. See the code and comments in ok_to_prune() to
|
// Pruning criterions. See the code and comments in ok_to_prune() to
|
||||||
// understand their precise meaning.
|
// understand their precise meaning.
|
||||||
const bool PruneEscapeMoves = false;
|
const bool PruneEscapeMoves = false;
|
||||||
|
@ -1130,6 +1133,7 @@ namespace {
|
||||||
|
|
||||||
Value approximateEval = quick_evaluate(pos);
|
Value approximateEval = quick_evaluate(pos);
|
||||||
bool mateThreat = false;
|
bool mateThreat = false;
|
||||||
|
bool nullCapturePruning = false;
|
||||||
bool isCheck = pos.is_check();
|
bool isCheck = pos.is_check();
|
||||||
|
|
||||||
// Null move search
|
// Null move search
|
||||||
|
@ -1143,7 +1147,20 @@ namespace {
|
||||||
UndoInfo u;
|
UndoInfo u;
|
||||||
pos.do_null_move(u);
|
pos.do_null_move(u);
|
||||||
int R = (depth > 7 ? 4 : 3);
|
int R = (depth > 7 ? 4 : 3);
|
||||||
|
|
||||||
Value nullValue = -search(pos, ss, -(beta-1), depth-R*OnePly, ply+1, false, threadID);
|
Value nullValue = -search(pos, ss, -(beta-1), depth-R*OnePly, ply+1, false, threadID);
|
||||||
|
|
||||||
|
// Check for a null capture artifact, if the value without the null capture
|
||||||
|
// is above beta then mark the node as a suspicious failed low. We will verify
|
||||||
|
// later if we are really under threat.
|
||||||
|
if ( UseNullCapturePruning
|
||||||
|
&& nullValue < beta
|
||||||
|
&& depth < 5 * OnePly
|
||||||
|
&& ss[ply + 1].currentMove != MOVE_NONE
|
||||||
|
&& pos.move_is_capture(ss[ply + 1].currentMove)
|
||||||
|
&& pos.see(ss[ply + 1].currentMove) * PawnValueMidgame + nullValue > beta)
|
||||||
|
nullCapturePruning = true;
|
||||||
|
|
||||||
pos.undo_null_move(u);
|
pos.undo_null_move(u);
|
||||||
|
|
||||||
if (nullValue >= beta)
|
if (nullValue >= beta)
|
||||||
|
@ -1170,6 +1187,26 @@ namespace {
|
||||||
&& ss[ply - 1].reduction
|
&& ss[ply - 1].reduction
|
||||||
&& connected_moves(pos, ss[ply - 1].currentMove, ss[ply].threatMove))
|
&& connected_moves(pos, ss[ply - 1].currentMove, ss[ply].threatMove))
|
||||||
return beta - 1;
|
return beta - 1;
|
||||||
|
|
||||||
|
if (nullCapturePruning && !mateThreat)
|
||||||
|
{
|
||||||
|
// The null move failed low due to a suspicious capture. Verify if
|
||||||
|
// position is really dangerous or we are facing a null capture
|
||||||
|
// artifact due to the side to move change. So search this
|
||||||
|
// position with a reduced depth and see if we still fail low.
|
||||||
|
Move tm = ss[ply].threatMove;
|
||||||
|
|
||||||
|
assert(tm != MOVE_NONE);
|
||||||
|
|
||||||
|
Value v = search(pos, ss, beta, depth-3*OnePly, ply, false, threadID);
|
||||||
|
if (v >= beta)
|
||||||
|
return beta;
|
||||||
|
|
||||||
|
// Restore stack and update ttMove if was empty
|
||||||
|
ss[ply].threatMove = tm;
|
||||||
|
if (ttMove == MOVE_NONE)
|
||||||
|
ttMove = ss[ply].pv[ply];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Null move search not allowed, try razoring
|
// Null move search not allowed, try razoring
|
||||||
|
|
Loading…
Add table
Reference in a new issue