spectastic Walkthrough
specs/001-tic-tac-toe/plan.html
Implementation plan · 001-tic-tac-toe

Building over-engineered tic-tac-toe

A pure rules core, an engine registry, and a thin view — plus the one decision that actually mattered.

accepted spec  001-tic-tac-toe owner  games created  2026-07-20 read time  6 min
TL;DR

Three layers: pure rules, a registry of six interchangeable engines, and a thin DOM view. The engines come straight from the algorithmic interlude; the only genuine fork was whether three-player tic-tac-toe needs a bigger board. It doesn't.

§1  Principles check

Principle Gate How met
P-1OKRules live in pure functions, no DOM.
P-2OKOne HTML file, no build.
P-3OKAll six engines behind chooseMove().
P-4OKA self-play harness proves SC-001–003.
P-5OKWordle-grade board, minimal chrome.

§2  Technical context

Language
Vanilla JS (ES2019).
Framework
None.
Build
None.
Storage
None.
Testing
In-browser self-play harness.
Performance
< 500 ms per move.
Constraints
Single file, runs from file://.

§3  Grounding & evidence

Claim Source Status Finding
Engine set = Random → MCTSOver-Engineering Tic-Tac-Toe (article)verifiedSix named engines adopted verbatim as the difficulty ladder.
3×3 game tree ≤ 9! = 362,880 leavesCombinatorial boundverifiedExhaustive search is tractable in the browser.
Alpha-Beta explores far fewer nodes than MinimaxSelf-play measurementverifiedReply to a centre opening: 29,632 positions (Minimax) vs 4,979 (α-β); to a corner: 31,972 vs 3,886.
MCTS at 2,500 iterations plays soundly on 3×3SpikespikeSound within the 500 ms budget, though not provably optimal.
3×3 Minimax moving second cannot loseClassic result + self-playverifiedZero losses across 40 random-opponent games.

§4  Approach

Three layers, cleanly separated. A pure rules core holds the board, its legal moves, and win/draw detection — plain functions over plain data, with no reference to the DOM. On top sits an engine registry keyed by name: Random, Minimax, Alpha-Beta, MaxN, Paranoid, and MCTS, each reached through one chooseMove() contract, so adding an engine never touches the loop.

A thin DOM view renders the board, the controls, and the result overlay — and nothing more. A player click drives the game loop, which advances the turn and, for any CPU seat, calls chooseMove() against the current registry entry. The rules core is the single source of truth; the view only reflects it.

Rules core board · legal moves · win/draw Engine registry 6 engines · chooseMove() DOM view + result render · controls · overlay player click drives the loop

§5  Alternatives considered

Option MaxN cost Winnable Tractable < 500 ms
3×3 (reuse) LowYes (drawish)Yes
4×4, 3-in-a-rowHighYesMarginal
5×5, 4-in-a-rowVery highYesNo

Bigger boards make MaxN meaningful but blow the move-time budget. 3×3 keeps the search instant.

§6  Decisions

D-001Architecture decisionverified

Keep three-player on the 3×3 board

Context
MaxN's cost climbs steeply with board size, and a larger board breaks the 500 ms budget.
Decision
Reuse the 3×3 board for three players.
Consequences
Strong three-player play tends to draw — accepted, and surfaced as a verify finding rather than treated as a defect.
D-002Architecture decisionverified

Mode-scoped engine menu

Context
Minimax and Alpha-Beta assume exactly one opponent; MaxN and Paranoid need three or more players.
Decision
Offer Minimax/Alpha-Beta only in two-player, MaxN/Paranoid only in three-player; Random and MCTS span both.
Consequences
The menu maps honestly onto the article's taxonomy; no engine is offered where it degenerates.
D-003Architecture decisionspike

MCTS budget = 2,500 iterations

Context
MCTS trades iterations for strength.
Decision
Fix 2,500 iterations.
Consequences
Sound 3×3 play inside the perf budget; revisit if the board ever grows.

§7  Project structure

tictactoe.html
 ├─ rules/        board · legalMoves · winner · isDraw   (pure)
 ├─ engines/      random · minimax · alphabeta · maxn · paranoid · mcts
 ├─ view/         board render · controls · result overlay
 └─ verify/       self-play harness (SC-001–003)

§8  Risks & mitigations

Risk Mitigation Status
MaxN first move on the empty 3×3 explores ~362k nodesStill resolves under 500 ms; bounded by the 9-cell board.accepted
MCTS is non-deterministic (seedless)Acceptable for a demo; results are stable in aggregate.accepted

§9  Change log

1.0.0 · 2026-07-20
Accepted; grounding gate cleared, all decisions grounded.
0.1.0 · 2026-07-20
Draft plan: three-layer approach, engine registry.
This worked example
principles.html spec.html plan.html tasks.html triage-log.html proposal.html ↳ walkthrough ▶ play the game

One file. Renders anywhere. Degrades to readable static HTML.