Watch a Game AI Think: Minimax and Alpha-Beta, Live
Our Tic-Tac-Toe, Connect 4, Checkers, Othello and Chess opponents all run the same idea: search the game tree, assume the opponent plays their best, and pick the move with the best guaranteed outcome. That idea is minimax, and alpha-beta pruning is what makes it fast. Below you can step through both on a real board and watch the second one skip work the first one wastes.
· Updated September 2026
Squares are positions; the top square is the AI to move (a MAX layer), the next is your reply (a MIN layer), and so on. Leaves score +1 (AI wins), −1 (you win) or 0 (draw). Step to watch each layer take the best (max) or worst-for-the-AI (min) of its children. Turn on alpha-beta and the grayed branches are the ones it proves it can skip — same move, fewer nodes.
The whole algorithm, in two functions
Minimax is the tree walk you just watched. Alpha-beta is the same walk plus two
running bounds — alpha (the best MAX can already guarantee) and
beta (the best MIN can already guarantee) — that let it stop exploring a
branch the moment it cannot change the decision.
function minimax(node, isMax):
if node is terminal:
return score(node) # +1 / -1 / 0
if isMax:
best = -inf
for child in node.moves: # AI's turn
best = max(best, minimax(child, false))
return best
else:
best = +inf
for child in node.moves: # your turn
best = min(best, minimax(child, true))
return best function ab(node, alpha, beta, isMax):
if node is terminal:
return score(node)
if isMax:
best = -inf
for child in node.moves:
best = max(best, ab(child, alpha, beta, false))
alpha = max(alpha, best)
if beta <= alpha: break # prune rest
return best
else:
best = +inf
for child in node.moves:
best = min(best, ab(child, alpha, beta, true))
beta = min(beta, best)
if beta <= alpha: break # prune rest
return best Same answer, provably — pruning never changes the value at the root, only how many nodes you touch to find it. On full-depth Tic-Tac-Toe that's a 93% cut (549,945 → 36,528 nodes, ~0.3 ms).
Why "just search deeper" gets expensive fast
A search that looks d moves ahead visits roughly bd
nodes, where b is the branching factor — how many moves you typically have.
Drag the depth and switch games to feel it. (Branching factors are approximate
published averages, for illustration.)
That growth is exactly why alpha-beta and the tricks in our real engines matter — and why a deeper search is not always a better one: a shallow tic-tac-toe search still lost 2 of 200 games.
The same idea, five different games
Every opponent on the site is this algorithm with a different board, a different way of scoring a position, and different tricks to search deeper without searching everything.
| Game | Board | Branching (approx.) | How it scores a position | Search tricks | |
|---|---|---|---|---|---|
| Tic-Tac-Toe | 3×3 | ≤ 9 (~4) | Win / lose / draw — solved exactly at full depth | Minimax + alpha-beta, full depth on 3×3 | Play → |
| Connect 4 | 7×6 | ≤ 7 (~4) | Threats, central control, connected pieces | Bitboard negamax + alpha-beta + transposition table + iterative deepening | Play → |
| Checkers | 8×8 | ~2.8 | Material, kings, position | Iterative-deepening negamax + alpha-beta + capture quiescence | Play → |
| Othello | 8×8 | ~10 | Corners, mobility, positional square weights | Iterative-deepening negamax + alpha-beta + exact endgame solve | Play → |
| Chess | 8×8 | ~35 | Material, king safety, pawn structure, open files | Negamax + alpha-beta + null-move + quiescence + check extensions + move ordering | Play → |
Read the actual code
The pseudocode above is the shape; here is a real, unminified engine that runs one of these opponents in your browser — iterative-deepening negamax with alpha-beta pruning and capture-aware quiescence, about 230 lines of vanilla JavaScript: the LK Forge checkers engine on GitHub Gist.
And you don't have to take the node counts on faith. This
self-contained script
runs plain minimax and alpha-beta over the exact Tic-Tac-Toe position above and prints the
counts — 14 nodes down to 10 with pruning — with no
dependencies: node reproduce-minimax.mjs.
Read the rest of the cluster
- Six Games, Three Classic Algorithms — the measured strength numbers and the 93% node cut from pruning.
- Benchmarking Game AI — why "it's minimax, so it's unbeatable" is only true at one depth.
- Real Game AI, Not a Chatbot — why these run on search, not a language model.
- How the Tic-Tac-Toe AI Thinks — the same ideas in prose.
Common questions
What is minimax?
A decision rule for two-player games: search the game tree, assume the opponent always plays their best reply, and pick the move with the best guaranteed outcome. LK Forge's Tic-Tac-Toe, Connect 4, Checkers, Othello and Chess opponents all use it.
What does alpha-beta pruning do?
It skips branches that provably cannot change the result, so it returns the same move and the same guaranteed value as plain minimax while visiting far fewer positions. On full-depth Tic-Tac-Toe that is a 93% cut — 549,945 nodes down to 36,528, in about 0.3 ms.
Does alpha-beta ever change the move minimax would pick?
No. It is an exact optimization — same optimal move, same value. It only proves that certain branches cannot affect the outcome and so can be ignored.
Why is full-depth search not used on every game?
Because the tree grows exponentially with the branching factor. Tic-Tac-Toe (about 4) is solvable at full depth, but Othello (about 10) and Chess (about 35) explode, so the real engines add depth caps and other search tricks on top of alpha-beta.
Is Tic-Tac-Toe with minimax beatable?
No. A minimax player never chooses a move that leads to a loss, so its worst case is a draw. That is why you cannot beat the LK Forge Tic-Tac-Toe AI at full depth — the best you can force is a tie.
Can I reproduce the node counts?
Yes. A self-contained script with no dependencies runs plain minimax and alpha-beta over the teaching position and prints the counts (14 nodes down to 10), and the full-depth 549,945 to 36,528 figures come from the same method.