Maze Runner Game: Fog of War, Guards and 3-Star Levels
Maze Runner Arrow-Key Game · Games · Plain HTML, CSS & JS · Live preview
For supporters
Source Code
Want the source code?
Play the game for free. Become a WebDevPuneet supporter to unlock the complete HTML, CSS and JavaScript source code, the exports (HTML, React, Vue, Angular, Tailwind) and Fork.
Extend with AI
Take This Snippet Further With AI
The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.
What's included
Features
About this UI Snippet
Maze Runner: Generated Mazes, Fog of War, Guards and a Shortest-Path Star Rating

A maze game is a small playground for some of the most useful algorithms in programming: generating a random maze, finding the shortest path through it, and steering simple enemies around it. This snippet turns those into a complete game on one HTML5 <canvas> with no libraries and no image files. You guide a glowing runner to a portal in the far corner of an ever bigger maze, collect gems hidden in dead ends, dodge patrolling guards, and earn up to three stars per level for taking a short route. It plays with the arrow keys or WASD (hold to run), by swiping on the maze, or with an on-screen D-pad.
Generated mazes that are always solvable
Each level builds a new maze with a depth-first search (a "recursive backtracker"): start in one corner, repeatedly step to a random unvisited neighbour while knocking out the wall between them, and backtrack when stuck. This produces a "perfect" maze, where exactly one path joins any two cells. Because that makes for long, winding dead ends, the generator then knocks out a few extra walls (more of them on later levels), so there is usually more than one route and choosing the best one matters. Walls are stored as four bit flags on each cell, and the maze is painted once into an off-screen canvas, with a neon glow, so each frame only draws the moving parts.
Breadth-first search for hints and stars
A breadth-first search from the runner to the portal returns the shortest route. The game uses it three times: at the start of a level to count the minimum number of moves, for the Hint button (which draws that route as a glowing dashed line for a few seconds, for a small score cost), and in the star rating. Finish within 25% of the minimum number of moves for three stars, within 70% for two, and any finish earns one.
Fog of war and guards
From level 3 the maze is dark: you only see a circle of cells around you, shrinking slightly each level, and cells you have already seen stay dimly visible so you can remember where you have been. The fog is drawn per cell with a soft edge, and gems, guards and the portal are only drawn when they are inside the light. From level 4 guards patrol the corridors one cell at a time. They never turn around unless they hit a dead end, and sometimes they head toward you when you are within seven cells. Touching one costs a life and sends you back to the start with a moment of invulnerability. You have three lives, and running out ends the run.
Controls and feel
Movement is cell by cell, but the drawn runner glides between cells, leaves a fading trail and bumps the screen slightly when you hit a wall. Holding a key or a D-pad button repeats the move about ten times a second, and dragging a finger across the maze moves one cell for each stretch of swipe. Gems pop in a burst of sparkles, the portal has spinning rings, each pair of levels has its own colour theme, and sound effects are made with the Web Audio API, with a mute button. The game pauses on P, the button or a tab switch, and your furthest level, stars and best score are saved in localStorage.
Step by step
How to Use
- 1StartPress Play (or Continue to resume from the furthest level you reached). Move with the arrow keys or WASD, the D-pad, or by swiping on the maze. Hold a key or button to keep running.
- 2Find the portalReach the glowing portal in the bottom-right corner. Each level is a new random maze, bigger than the last, with several routes once the loops appear.
- 3Collect gemsGems are worth 25 points and tend to hide in dead ends, so going for them costs moves. Decide whether the points are worth the extra steps.
- 4Beat the fog and the guardsFrom level 3 you can only see nearby, and from level 4 guards patrol the corridors. Touching a guard costs a life. You have three lives for the whole run.
- 5Use a hintPress 💡 Hint (or H) to show the shortest route for a few seconds. You get three per level and each costs 25 points.
- 6Earn starsFinish within 25% of the minimum number of moves for three stars. Time and level bonuses add to your score, and your stars and best score are saved in your browser.
Real-world uses
Common Use Cases
Got questions?
Frequently Asked Questions
generateMaze() uses a depth-first search: it starts in the top-left cell and keeps moving to a random unvisited neighbour, removing the wall between the two, and backtracks when it has no unvisited neighbour. That makes a perfect maze with one route between any two cells. It then removes a random handful of extra walls (more on later levels) so that there are loops.
Each cell holds a number whose four low bits say which sides have a wall: 1 for up, 2 for right, 4 for down and 8 for left. Removing a wall clears the bit on both cells that share it. Checking whether you can move is then one bitwise AND.
A breadth-first search finds the minimum number of moves from the start to the portal. Finishing in at most 1.25 times that gives three stars, at most 1.7 times gives two, and anything else gives one. Hints do not affect stars, but each costs 25 points.
From level 3, every cell further than the light radius from the runner is covered by a dark rectangle. Cells you have been near are remembered and covered by a lighter dim, and cells at the edge of the light fade in gradually. Gems, guards and the portal are only drawn inside the light (or the portal once you have seen it).
Every 0.2 to 0.35 seconds a guard takes one step along the corridors. It avoids turning back unless it reaches a dead end. When you are within seven cells it has a 40% chance to pick the open direction that gets it closest to you, otherwise it picks randomly. They never leave the maze or cut through walls.
Yes: params(n) returns the size, the loop chance, the fog radius, the guard count and the gem count for level n. Change the size formula (7 + 2n, capped at 21), the fog from level 3, or the guards from level 4. The canvas is 420 pixels wide and the cell size is worked out from the maze size.