How Much Search Does 2048 Need? An Expectimax Depth Benchmark
By Lucian — builder & engineer, LK Forge
A 2048 AI that searches only one or two moves ahead never reaches the 2048 tile — not rarely, never. We took the exact expectimax engine the game ships, capped its search at each fixed depth from 1 to 6, and self-played hundreds of games at each. The result is a sharp threshold, a plateau, and a compute bill that grows 83× for the last few plies — which is why the shipped engine varies its depth instead of always digging deeper.
· 7 min read · every number from a re-runnable headless benchmark
Update — September 23, 2026: the shipped solver has since been reworked — probability-threshold pruning and a transposition table replaced the depth-sampling engine measured here, following the approach of Robert Xiao’s canonical 2048 AI (nneonneo). Every figure below has been re-measured on the reworked engine (re-swept 23 September 2026): adaptive reach-2048 rose from 70% to 94%, and the machine-readable data is published as an open dataset.
How we measured it
The engine under test is the one the 2048 game actually ships — an expectimax search with a corner-snake heuristic, pulled out of the production file and driven from a script with no browser and no human. Normally its depth adapts to the board: three plies when there is lots of space, up to five when the board is nearly full. For this benchmark we added one optional switch that pins the search to a single fixed depth, then self-played the game to a game-over at each depth from 1 to 6.
Depths 1–4 and the adaptive default are 300 games each. Depths 5 and 6 are 100 and 30 games, because each move there is far slower and a full run would take hours — so their percentages carry wider error bars, and we report the exact sample size on every row rather than hide it. Tile spawns use a seeded generator so the run is re-runnable; the search itself samples empty cells with the same randomness the shipped engine uses, so reach-rate is a stable distribution, not a single fixed value. Timing is mean milliseconds per move on one laptop.
Share of games reaching each tile by fixed search depth. Reach 2048 and reach 4096. The dashed amber line is the shipped adaptive engine. Depth 1–2 sit flat on zero for 2048.
The cliff at depth 3
The most striking thing in the data is not a curve, it is a wall. At depth 1 and depth 2 the solver reached the 2048 tile in zero of 300 games each — mean scores stuck around 4,400 and 5,100, the low plateau of a player that stacks tiles without a plan. Then at depth 3 it clears 2048 in 66% of games and the mean score jumps to 29,648, a six-fold leap for one extra ply.
This is the opposite of what tic-tac-toe showed, where even a one-ply search wins most games. 2048 is stochastic and its rewards are deferred: a merge to a higher tile is several moves away, so a shallow search optimises the immediate board and never sets up the chain that a high tile requires. Three plies is the point where the search can finally see a merge forming and start playing toward it.
What each extra ply costs
The gains are not free. Expectimax branches on every empty cell and every possible spawn, so each extra ply multiplies the work. A move takes 0.044 ms at depth 3, 0.92 ms at depth 5, and 3.67 ms at depth 6 — about 83× more compute across those three plies, for a reach-rate that climbed from 66% to 97% and then stopped climbing.
Mean milliseconds per move, linear scale. The bars are invisible until depth 4 for the same reason the shipped engine can afford a shallow search early: on an open board, thinking hard is cheap and pointless.
Every number
| Depth | Games | 2048 | 4096 | Mean score | Median | ms/move |
|---|---|---|---|---|---|---|
| 1 | 300 | 0% | 0% | 4,366 | 3,636 | 0.002 |
| 2 | 300 | 0% | 0% | 5,117 | 4,544 | 0.008 |
| 3 | 300 | 66.3% | 13.3% | 29,648 | 28,680 | 0.044 |
| 4 | 300 | 66% | 15.3% | 29,990 | 31,416 | 0.203 |
| 5 | 100 | 97% | 66% | 61,019 | 67,432 | 0.919 |
| 6 | 30 | 86.7% | 60% | 51,914 | 60,280 | 3.667 |
| adaptive | 300 | 94% | 70.3% | 62,529 | 60,644 | 1.844 |
Measured 23 September 2026 on one laptop (reworked engine: pruning + transposition table). Depth 5 (100 games) and depth 6 (30 games) use smaller samples than the 300-game rows, so their percentages are approximate. The adaptive row is the engine the game ships with; its 94% reach is corroborated by a separate 250-game run at 92.8%.
Why the shipped engine varies its depth
Put the reach-rate and the cost side by side and the design falls out on its own. A constant depth-5 search reaches 2048 the most often here — 97% — but it pays 0.92 ms on every move, including the early moves on a wide-open board where deep thinking changes nothing. A constant depth-3 search is nearly free but tops out at 66%.
The shipped engine spends its compute where it matters: shallow (depth 4) while the board is open and moves are obvious, deeper as it fills, and up to depth 7 once a wrong move would end the game. That yields the strongest overall play in the sweep — the highest mean score of any setting (62,529) and the most games reaching 4096 (70%) — while spending almost nothing on the easy early moves. It searches deeper than any fixed setting in the sweep exactly when depth matters, and cheaply when it doesn’t: varying the depth is a deliberate, measured choice rather than a guess.
Reproduce it yourself
The engine is public: solver-core.js is the exact file the game loads, and it runs unmodified in Node. Save it, then self-play at any fixed depth — selfPlayGame(rng, depth) is the whole harness.
import { readFileSync } from 'node:fs';
import vm from 'node:vm';
// solver-core.js downloaded from lkforge.com/games/2048/
vm.runInThisContext(readFileSync('solver-core.js', 'utf8'));
let reached = 0;
for (let i = 0; i < 300; i++) {
const g = globalThis.LK2048.selfPlayGame(Math.random, 3); // fixed depth 3
if (g.maxTile >= 2048) reached++;
}
console.log((100 * reached / 300).toFixed(1) + '% reached 2048'); Drop the third argument and you get the shipped adaptive engine instead. The solver’s heuristic and search live in the open-source 2048-ai-solver repository.
Watch it play
The 2048 solver runs live in your browser — ask it for a move, or let it autoplay and watch the depth-5 endgame it was built for.
How to cite this page
APALK Forge. (2026). How Much Search Does 2048 Need? An Expectimax Depth Benchmark. Retrieved October 26, 2026, from https://lkforge.com/blog/2048-expectimax-depth-benchmark/
@misc{lkforge_2048_depth_benchmark,
author = {{LK Forge}},
title = {How Much Search Does 2048 Need? An Expectimax Depth Benchmark},
year = {2026},
howpublished = {\url{https://lkforge.com/blog/2048-expectimax-depth-benchmark/}},
note = {Accessed 2026-10-26}
}