mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 00:33:09 +00:00
Null move driven internal iterative deepening
When a null move fails low due to a capture, try to detect if without the capture we are above beta, in this case there is a good possibility this is a cut-node and the capture is just a null move artifact due to side to move change. So if we still don't have a TT move it's a good time to start an IID. Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
b7c36d078b
commit
c172af1b61
1 changed files with 28 additions and 32 deletions
|
@ -106,6 +106,9 @@ namespace {
|
||||||
const bool UseIIDAtPVNodes = true;
|
const bool UseIIDAtPVNodes = true;
|
||||||
const bool UseIIDAtNonPVNodes = false;
|
const bool UseIIDAtNonPVNodes = false;
|
||||||
|
|
||||||
|
// Use null move driven internal iterative deepening?
|
||||||
|
bool UseNullDrivenIID = true;
|
||||||
|
|
||||||
// Internal iterative deepening margin. At Non-PV moves, when
|
// Internal iterative deepening margin. At Non-PV moves, when
|
||||||
// UseIIDAtNonPVNodes is true, we do an internal iterative deepening search
|
// UseIIDAtNonPVNodes is true, we do an internal iterative deepening search
|
||||||
// when the static evaluation is at most IIDMargin below beta.
|
// when the static evaluation is at most IIDMargin below beta.
|
||||||
|
@ -133,9 +136,6 @@ 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;
|
||||||
|
@ -1127,13 +1127,13 @@ namespace {
|
||||||
|
|
||||||
if (tte && ok_to_use_TT(tte, depth, beta, ply))
|
if (tte && ok_to_use_TT(tte, depth, beta, ply))
|
||||||
{
|
{
|
||||||
ss[ply].currentMove = ttMove; // can be MOVE_NONE ?
|
ss[ply].currentMove = ttMove; // can be MOVE_NONE
|
||||||
return value_from_tt(tte->value(), ply);
|
return value_from_tt(tte->value(), ply);
|
||||||
}
|
}
|
||||||
|
|
||||||
Value approximateEval = quick_evaluate(pos);
|
Value approximateEval = quick_evaluate(pos);
|
||||||
bool mateThreat = false;
|
bool mateThreat = false;
|
||||||
bool nullCapturePruning = false;
|
bool nullDrivenIID = false;
|
||||||
bool isCheck = pos.is_check();
|
bool isCheck = pos.is_check();
|
||||||
|
|
||||||
// Null move search
|
// Null move search
|
||||||
|
@ -1151,15 +1151,16 @@ namespace {
|
||||||
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
|
// 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
|
// is above beta then there is a good possibility that this is a cut-node.
|
||||||
// later if we are really under threat.
|
// We will do an IID later to find a ttMove.
|
||||||
if ( UseNullCapturePruning
|
if ( UseNullDrivenIID
|
||||||
&& nullValue < beta
|
&& nullValue < beta
|
||||||
&& depth < 5 * OnePly
|
&& depth > 6 * OnePly
|
||||||
|
&& ttMove == MOVE_NONE
|
||||||
&& ss[ply + 1].currentMove != MOVE_NONE
|
&& ss[ply + 1].currentMove != MOVE_NONE
|
||||||
&& pos.move_is_capture(ss[ply + 1].currentMove)
|
&& pos.move_is_capture(ss[ply + 1].currentMove)
|
||||||
&& pos.see(ss[ply + 1].currentMove) * PawnValueMidgame + nullValue > beta)
|
&& pos.see(ss[ply + 1].currentMove) * PawnValueMidgame + nullValue > beta - IIDMargin)
|
||||||
nullCapturePruning = true;
|
nullDrivenIID = true;
|
||||||
|
|
||||||
pos.undo_null_move(u);
|
pos.undo_null_move(u);
|
||||||
|
|
||||||
|
@ -1180,33 +1181,15 @@ namespace {
|
||||||
// low score (which will cause the reduced move to fail high in the
|
// low score (which will cause the reduced move to fail high in the
|
||||||
// parent node, which will trigger a re-search with full depth).
|
// parent node, which will trigger a re-search with full depth).
|
||||||
if (nullValue == value_mated_in(ply + 2))
|
if (nullValue == value_mated_in(ply + 2))
|
||||||
|
{
|
||||||
mateThreat = true;
|
mateThreat = true;
|
||||||
|
nullDrivenIID = false;
|
||||||
|
}
|
||||||
ss[ply].threatMove = ss[ply + 1].currentMove;
|
ss[ply].threatMove = ss[ply + 1].currentMove;
|
||||||
if ( depth < ThreatDepth
|
if ( depth < ThreatDepth
|
||||||
&& 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
|
||||||
|
@ -1225,6 +1208,19 @@ namespace {
|
||||||
search(pos, ss, beta, Min(depth/2, depth-2*OnePly), ply, false, threadID);
|
search(pos, ss, beta, Min(depth/2, depth-2*OnePly), ply, false, threadID);
|
||||||
ttMove = ss[ply].pv[ply];
|
ttMove = ss[ply].pv[ply];
|
||||||
}
|
}
|
||||||
|
else if (nullDrivenIID)
|
||||||
|
{
|
||||||
|
// The null move failed low due to a suspicious capture. Perhaps we
|
||||||
|
// are facing a null capture artifact due to the side to move change
|
||||||
|
// and this is a cut-node. So it's a good time to search for a ttMove.
|
||||||
|
Move tm = ss[ply].threatMove;
|
||||||
|
|
||||||
|
assert(tm != MOVE_NONE);
|
||||||
|
|
||||||
|
search(pos, ss, beta, Min(depth/2, depth-3*OnePly), ply, false, threadID);
|
||||||
|
ttMove = ss[ply].pv[ply];
|
||||||
|
ss[ply].threatMove = tm;
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize a MovePicker object for the current position, and prepare
|
// Initialize a MovePicker object for the current position, and prepare
|
||||||
// to search all moves:
|
// to search all moves:
|
||||||
|
|
Loading…
Add table
Reference in a new issue