Alpha-beta pruning
Fail-hard
Fail-soft
Game theory
Search algorithms

Alpha-beta pruning Fail-hard VS. Fail-soft

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Fail-hard and fail-soft are two ways of reporting bounds during alpha-beta search. Both prune the same kinds of branches, but they differ in what value gets returned when the search proves the position is outside the current alpha-beta window.

Start With Alpha-Beta Basics

Alpha-beta search keeps two bounds:

  • 'alpha, the best lower bound known for the maximizing side'
  • 'beta, the best upper bound known for the minimizing side'

When the search finds that a branch cannot possibly improve the outcome beyond those bounds, it prunes the branch instead of exploring it fully.

The difference between fail-hard and fail-soft is not the pruning rule itself. It is the value you return after a cutoff.

Fail-Hard Returns the Window Boundary

In fail-hard alpha-beta, if a node fails high or fails low, the function returns the bound that caused the cutoff rather than a more informative outside-the-window score.

A simplified fail-hard maximizer looks like this:

python
1def alphabeta_fail_hard(node, depth, alpha, beta, maximizing):
2    if depth == 0 or node.is_terminal():
3        return node.evaluate()
4
5    if maximizing:
6        value = float("-inf")
7        for child in node.children():
8            value = max(value, alphabeta_fail_hard(child, depth - 1, alpha, beta, False))
9            alpha = max(alpha, value)
10            if alpha >= beta:
11                return beta
12        return value
13    else:
14        value = float("inf")
15        for child in node.children():
16            value = min(value, alphabeta_fail_hard(child, depth - 1, alpha, beta, True))
17            beta = min(beta, value)
18            if alpha >= beta:
19                return alpha
20        return value

The return on cutoff is clamped to the search window boundary.

Fail-Soft Returns the Best Score Found So Far

Fail-soft still performs the same cutoff, but it returns the actual score that exceeded the window instead of forcing the result back to the boundary.

python
1def alphabeta_fail_soft(node, depth, alpha, beta, maximizing):
2    if depth == 0 or node.is_terminal():
3        return node.evaluate()
4
5    if maximizing:
6        value = float("-inf")
7        for child in node.children():
8            score = alphabeta_fail_soft(child, depth - 1, alpha, beta, False)
9            value = max(value, score)
10            alpha = max(alpha, value)
11            if alpha >= beta:
12                return value
13        return value
14    else:
15        value = float("inf")
16        for child in node.children():
17            score = alphabeta_fail_soft(child, depth - 1, alpha, beta, True)
18            value = min(value, score)
19            beta = min(beta, value)
20            if alpha >= beta:
21                return value
22        return value

If a node proves to be better than beta or worse than alpha, the returned score can carry more information than the raw bound alone.

Why Fail-Soft Is Often Preferred

Fail-soft is popular in engine code because the extra score information can help with:

  • move ordering
  • aspiration windows
  • transposition table entries
  • debugging search behavior

A fail-soft cutoff says more than "this was at least beta". It may tell you how far beyond beta the position looked under the explored line.

Why Fail-Hard Still Exists

Fail-hard is simpler conceptually because the returned value always stays within the search contract. That can make some reasoning and textbook explanations more straightforward.

It is also easier to explain to beginners:

  • exact score if fully searched
  • boundary score if cut off

For theoretical discussions, that simplicity is attractive even though many practical engines prefer fail-soft style.

Do Not Confuse Returned Score With Exact Score

This is the most important implementation point. In fail-soft search, a returned value outside the window is still a bound, not automatically an exact evaluation of the node.

If a fail-soft maximizing node returns a score above beta, that means:

  • the position is at least that good along the explored line
  • the search cut off before proving an exact minimax value for the whole node

So the extra number is useful, but it still must be interpreted correctly.

Same Pruning, Different Reporting

Both fail-hard and fail-soft prune when the window closes. They do not differ by exploring radically different subtrees. Their main difference is what information gets returned upward when the cutoff happens.

That is why the choice matters most in search infrastructure and engine tuning rather than in the high-level correctness of alpha-beta itself.

Common Pitfalls

The biggest mistake is assuming fail-soft returns an exact value after a cutoff. It often returns a more informative bound, not a guaranteed exact minimax score.

Another common issue is mixing fail-hard assumptions with fail-soft transposition-table logic. If the engine stores or interprets the returned value incorrectly, later pruning decisions can become unsound.

People also overstate the difference. The two approaches do not invent different pruning rules; they mainly differ in cutoff return behavior.

Finally, do not treat fail-soft as automatically better in every educational or implementation context. It is usually more informative, but it also demands more careful interpretation.

Summary

  • Fail-hard and fail-soft alpha-beta prune the same kinds of branches.
  • Fail-hard returns the alpha or beta boundary on cutoff.
  • Fail-soft returns the best score found so far, even if it lies outside the window.
  • Fail-soft is often more informative for engine heuristics and transposition tables.
  • A fail-soft cutoff value is still usually a bound, not automatically an exact score.

Course illustration
Course illustration

All Rights Reserved.