Summary
I turned my SIT215 Wumpus World planning assignment into a live demo: a planner that solves a fresh Wumpus World in the browser every few seconds, with no input needed. Over 1,200 random worlds, A* expands a median 3.9 to 5.8 times fewer nodes than breadth-first search (BFS) while finding the same optimal plan. It costs $0 to host and lets visitors watch three search algorithms compete on the same world.
Stack
- Original assignment
- PDDL, BFWS and LAMA-First (Fast Downward)
- Demo
- Plain JavaScript and canvas
- Deployment
- GitHub and Netlify
Problem and goal
A notebook full of solver timings proves the assignment ran, but it does not show a recruiter that the planner works or why one algorithm beats another. I wanted a link that a visitor understands in under a minute, built on work I had already done.
The constraints were deliberate:
- Keep the PDDL visibleThe demo shows the real move, take and shoot actions from my domain as the agent executes them.
- No backendStatic files only, so nothing can break or cost money.
- No dependencies at runtimeThe planner is plain JavaScript.
- Self-runningA visitor sees something happening without clicking anything.
The assignment
The starting point was SIT215 Assignment 3: model Wumpus World in PDDL and compare two planners on it. The world is a 4×4 grid with an agent, an arrow, gold, a Wumpus and pits. The domain has three actions, move, take and shoot. A corrected version adds guards: a dead agent cannot act, an arrow can only be used once, and a flag records whether the Wumpus is alive.
| Problem file | Value |
|---|---|
| Agent starts | sq-1-1, with the arrow |
| Gold | sq-2-3 |
| Wumpus | sq-1-3 |
| Goal | Hold the gold and be back at sq-1-1 |
My notebook compared two solvers on it.
| Solver | Planning time (s) | Nodes generated | Nodes expanded | Plan length | Peak memory (KB) |
|---|---|---|---|---|---|
| BFWS (FF parser) | 0.000456 | 89 | 58 | 10 | not recorded |
| LAMA-First (Fast Downward) | 0.027971 | 52 | 12 | 10 | 12,500 |
LAMA-First expanded about 5 times fewer nodes (12 against 58) but took about 60 times longer. On a problem this small that likely reflects fixed startup cost rather than search effort, which is why the demo reports expanded nodes.
Approach
The demo re-implements the domain's three actions as a search problem and runs it in the browser. A state is four facts: the agent's square, whether it holds the gold, whether it still has the arrow, and whether the Wumpus is alive. That gives 128 states on a 4×4 grid and 288 on a 6×6.
- moveStep to an adjacent square that is not a pit.
- takePick up the gold when standing on it.
- shootFire the arrow at a living Wumpus on an adjacent square.
The goal matches the assignment: hold the gold and be back at the start.
One rule is my addition, behind a toggle. The PDDL domain lets the agent walk straight through the Wumpus's square, but the classic game does not. With the rule on, the Wumpus blocks its square, so shooting becomes worth using.
Three algorithms search the same state space.
| Solver | Frontier ordered by | Finds the shortest plan? |
|---|---|---|
| BFS | Steps taken | Yes |
| A* | Steps taken plus a heuristic | Yes, because the heuristic never overestimates |
| Greedy best-first | Heuristic only | No |
The heuristic is the Manhattan distance to the gold, one step to take it, then the distance back to the start. It ignores pits and the Wumpus, so it never overestimates.
Before taking the gold, h of s equals the Manhattan distance from p to the gold, plus 1, plus the distance from the gold to the start. After taking it, h of s equals the distance from p to the start.
Each episode builds a random world that is guaranteed solvable. The gold sits at least n−1 squares from the start, and the Wumpus is placed next to the gold in 60% of worlds so that shooting is sometimes the only way through. Pits number 2 or 3 on 4×4, 4 on 5×5 and 6 on 6×6, and BFS rejects any world with no plan.
Product and UI
The demo is designed to show the planner thinking, not just a final answer. It uses a dark, minimal interface with a near-black background, hairline borders and an indigo accent, matching my Snake project.

- Live world: the agent, gold, Wumpus and pits, with breeze and stench markers. An indigo glow shows where the search spent its effort, then the agent walks the plan.
- Plan steps: the plan as a row of chips, with the current step highlighted.
- Solver table: all three solvers run on every world, showing nodes generated, nodes expanded, plan length and time. The best value in each column turns green.
- PDDL panel: the move, take or shoot action being executed lights up in the domain text, beside the grounded step, for example
(move agent sq-1-1 sq-2-1). - Chart: nodes expanded per world for the three solvers, with hover tooltips.
- Controls: solver switch, 4×4, 5×5 or 6×6 grid, speed from 0.5× to 4×, the Wumpus-blocking toggle, pause on the space bar and next world on the right arrow. The layout works on a phone.
A world takes a few seconds at normal speed, then a new one loads. The first world uses the layout from my wumpus.pddl file.
Results
A* beats BFS by a margin that grows with the grid, while finding the same shortest plan.
A* expands about 5× fewer nodes than BFS on a 6×6 grid
Average nodes expanded per world, 400 random worlds per grid size
- BFS
- A*
- Greedy
Mean of 400 random worlds per grid size (seeds 1 to 400), Wumpus blocks its square, run with the demo's planner.js.
The chart shows the ratio of mean nodes (3.4, 4.1, 5.1×) while the text below uses the median per-world ratio (3.9, 4.6, 5.8×). Both are correct; they are different statistics.
A* and BFS always return plans of equal length, because both find the shortest one. Greedy search expands 6 to 10% fewer nodes than A* but returns a longer plan in 25 of 400 worlds on 4×4, 55 on 5×5 and 76 on 6×6. The median BFS-to-A* ratio of expanded nodes is 3.9 on 4×4, 4.6 on 5×5 and 5.8 on 6×6. Shooting the Wumpus was part of the shortest plan in 82, 74 and 57 of the 400 worlds respectively.
| Grid | Median BFS ÷ A* | Greedy plan longer | Shot in shortest plan |
|---|---|---|---|
| 4×4 | 3.9× | 25 of 400 | 82 of 400 |
| 5×5 | 4.6× | 55 of 400 | 74 of 400 |
| 6×6 | 5.8× | 76 of 400 | 57 of 400 |
On the first world, which uses the layout from wumpus.pddl, BFS expands 44 nodes and A* and greedy expand 8, all finding a 7-step plan.
Limitations
Shipping at $0
Everything runs in the browser, so the site is a folder of static files: index.html and planner.js in the repo's web folder. Netlify deploys from the main branch with the publish directory set to web and no build command.
| Item | Cost |
|---|---|
| Compute | $0 (the visitor's browser) |
| Hosting | $0 (free static hosting) |
| Domain | $0 (default netlify.app subdomain) |
| Backend and database | None needed |
What I learned and what's next
What I learned
- Heuristic quality sets the cost of search: A* expands a median 3.9 to 5.8 times fewer nodes than BFS, and the gap grows with the grid.
- Greedy search's small saving costs plan quality. It expands 6 to 10% fewer nodes than A* but returns a longer plan in 6% of 4×4 worlds and 19% of 6×6 worlds.
- Implementing a domain exposes rules it leaves out. My PDDL never stops the agent walking into the Wumpus, which I only noticed when writing the search.
- Showing the search as a heat map explains more than a table of counts.
What's next
- Run the PDDL files through Fast Downward on the same worlds to verify the browser plans.
- Add fog of war, where the agent senses breeze and stench and replans, as in the classic game.
- Let visitors click to place pits and the Wumpus.
- Commit the benchmark script so the results can be reproduced.
Watch three search algorithms compete
Watch a fresh world solve in the live demo, or read the planner and PDDL files on GitHub.


