# RCWeb Maze Control

![Maze Control icon](pwa-512x512.png "Maze Control icon")

`maze-c` is the smartphone controller and live map for the RCWeb [`maze`](../maze/appinfo) display. Open it by scanning the QR code on the maze display, or visit `/maze-c/?r=<room>` with the same room.

## What it does

- Draws a 2D top-down map that fills in as the player explores. Only squares that have been walked are revealed, along with their walls, so corridors and side openings appear one square at a time. The starting square, the player arrow with its vision cone, and the pulsing exit are always drawn; everything not yet visited stays dark.
- Sends hold-to-act movement: `Forward`, `Back`, `Turn left`, `Turn right`.
- Shows the current level, level time, step count, and network status.
- `New maze` asks the display to abandon the current labyrinth and generate a fresh level 1.

## Controls

- Hold `Forward` to keep walking down the corridor. The player stops centred on the next square when the button is released.
- Hold a turn button to keep rotating in 90 degree steps.
- Turning while walking is allowed, so corners can be taken without stopping.
- A desktop keyboard can drive the same actions with `W`/`S` and `A`/`D`, which is useful for testing.
- Every button press releases cleanly if the phone is locked, backgrounded, or refreshed, so the player never keeps walking after the controller disappears.

## Control ownership

The maze is a single-player walk, so only one phone drives at a time.

- The first phone in the room takes the controls and shows `In control`.
- Extra phones show `Watching` and still receive the map and live position, so a group can follow the run together.
- If the owning phone leaves the room or stops checking in for seven seconds, the longest-waiting watcher takes over.
- The controller stores an identity in browser storage, so refreshing the page reclaims the controls with the same identity even though RCWeb assigns a new client ID.

## How the map stays in sync

The display sends the maze once per level with `mazeControl.receiveMap`. The grid arrives as one hex character per square, each a bitmask of the four walls, plus the start square, exit square, level number, and theme name. The controller keeps that grid but only draws the squares the player has walked, painting them onto an off-screen canvas that is repainted when the trail grows. The exit marker and player arrow are drawn on top every frame.

Live updates arrive with `mazeControl.receiveState` about twelve times a second and carry the fractional position, heading in degrees, level, time, steps, which phone owns the controls, and the squares walked since the last update. A full trail snapshot follows every few seconds so a phone that joins late still draws the complete route. Short messages such as `Wall ahead`, `Exit found`, or `You have control` arrive as `mazeControl.showPulse` and appear in the banner at the bottom of the controller.

## Screenshots

![Maze map after the first movement](screenshot01.png)

![Map revealing the walked route](screenshot02.png)

![Fresh maze map ready for exploration](screenshot03.png)
