Futility pruning applies in the main search (not qsearch) when depth is low and the position is already bad.
If
staticEval + margin(d) < α, a quiet move (non-capture, non-check) is unlikely to save the node — skip it.
Captures and checks are never futility-pruned (they can change eval drastically).Idea
Eval + Margin vs Alpha
staticEval + margin still below α → futile quiet move
Red band = best plausible gain from one quiet move at this depth. Green line = α. No overlap → prune.
Depth margins
Margin Grows With Depth
d ≤ 2~100–150 cp margin
d = 3~200 cp margin
d ≥ 4Usually disabled
if (depth <= FUTILITY_MAX && !inCheck && !isCapture(move)) {
if (staticEval + futilityMargin[depth] <= alpha)
continue; // skip quiet move
}
Guards (always apply)
- Never prune when in check — king must move
- Never prune captures, promotions, or checks
- Disable on PV nodes / first move (risky)
- Skip when static eval is mate score
- Related: reverse futility (parent side already winning)
Related: Delta Pruning · Razoring · All Blogs