A side-by-side pathfinding race on weighted terrain, built as a single offline HTML file, designed as a teaching tool.
Four algorithms run simultaneously in lockstep on one shared maze, so a learner sees the behavioural differences at a glance:
| Panel | Algorithm | One-line teaching point |
|---|---|---|
| 1 | BFS | Uninformed, ignores weights → fewest steps but can be costly |
| 2 | Dijkstra | Uniform-cost → genuinely cheapest path, but explores widely |
| 3 | Greedy Best-First | Pure heuristic → fast, beelines, but not optimal |
| 4 | A* | Cost-so-far + heuristic → optimal and directed (fewer cells than Dijkstra) |
Each algorithm differs from a neighbour by one idea: add a cost function (BFS→Dijkstra), swap to a heuristic (Dijkstra→Greedy), combine both (Greedy/Dijkstra→A*). The weighted terrain is what makes Dijkstra and A* meaningfully different from BFS and Greedy — without weights, Dijkstra and BFS would be visually identical.
| Alternative | Why rejected |
|---|---|
| Single-grid demo (faithful PathFinding.js clone) | Weakest for teaching — can't see contrast; learner must remember prior runs |
| Single grid + accumulating scoreboard | Quantitative but not visual; the simultaneous spatial contrast is the payload |
| Unweighted grid (3 algorithms) | Dijkstra collapses into BFS — looks like a duplicate/bug; loses the cost story |
| Diagonal movement | Forces Manhattan/Euclidean/Chebyshev digression; muddies the heuristic lesson |
| Jump Point Search / IDA* / bi-directional | Advanced; dilute the core four-way contrast — deferred to a later iteration |
| Importing PathFinding.js | Violates single-file/offline goal; reimplementing is clearer for teaching anyway |
In scope (iteration 1):
Out of scope (deferred):
Fully offline, single-file, client-side artifact:
textContent only — never
innerHTML — so there is no injection path even in
principle. No eval, no dynamic script. This is the one
boundary worth stating; everything else is moot offline.