# Maze Game A text maze where a mouse navigates a 4x4 grid of rooms to reach the cheese. The program scatters internal walls at random, prints the current room, and reads one move per turn. The game ends when the mouse reaches the cheese room. Source files: `maze/maze.hpp`, `maze/maze.cpp`, `maze/game.cpp`. ## Coordinates Each room has a row letter and a column number. The row is `y_`, a `char` from `a` to `d`. The column is `x_`, an `int` from 1 to 4. `Room::print()` writes the letter then the number, so rooms read as `a1`, `b3`, `d4`, and so on. - Start room: `a1` (set by `makeStartRoom`). - Cheese room: `d4` (set by `makeCheeseRoom`, which uses `x_ = mazeSize_` and `y_ = 'a' + mazeSize_ - 1`). `mazeSize_` is 4, so the board is 4x4. The maze holds 8 internal walls (`numWalls_`). ## Three classes - `Room` holds one room's coordinates and knows how to pick a random room, pick a random adjacent room, ask the user for a move, and report whether a direction stays inside the board. - `RoomPair` holds two rooms. It models one internal wall, and it also models a candidate move (current room paired with target room). - `Maze` owns the array of 8 wall `RoomPair`s plus the current mouse room. It builds the walls, prints them, and decides whether a move is blocked. ## How the maze is built The generator places walls. It does not knock them out. `Maze::build()` loops until it has collected 8 distinct walls: 1. Make an empty `RoomPair`. 2. `RoomPair::pick()` picks a random room, then picks a random room adjacent to it. 3. `Maze::checkMaze()` scans the walls already placed. If this pair matches one (in either order), it is a duplicate. 4. If it is new, store it and increment the count. If it is a duplicate, throw it away and try again. `matchPair()` treats `r1|r2` and `r2|r1` as the same wall, so a wall is never added twice in reversed order. ```mermaid flowchart TD A([build maze]) --> B{placed 8 walls?} B -- yes --> Z([done]) B -- no --> C[pick random room] C --> D[pick a random adjacent room] D --> E[form RoomPair candidate wall] E --> F{already in maze?} F -- yes --> B F -- no --> G[store wall, count + 1] G --> B ``` A note on the picking: `pickAdjacent()` rolls a random direction and accepts it only if that direction stays inside the board. A room on an edge has fewer legal neighbors, so off-board directions get rerolled until one lands inside. ## The game loop `game.cpp` sets the start and cheese rooms, builds the walls, then offers to print the wall list (answer `y` to see it, useful for testing). After that it loops until the mouse sits on the cheese: 1. Print the current room. 2. Ask for a move. `Room::nextMove()` accepts `u`, `d`, `l`, `r`, or `q`. 3. Validate the direction. If the move would leave the board, print `There is a wall` and ask again. 4. Hand the target room to `Maze::move()`. If a wall sits between the current room and the target, the move is refused and `There is a wall` prints. Otherwise the mouse moves. 5. Check whether the current room matches the cheese room. If so, print `Game Over!` and stop. ```mermaid stateDiagram-v2 [*] --> Render Render --> ReadInput: print current room ReadInput --> CheckWin: q pressed (quit) ReadInput --> ValidateDirection: u / d / l / r ValidateDirection --> ReadInput: off the board (wall) ValidateDirection --> CheckWall: inside the board CheckWall --> Render: wall between rooms (move refused) CheckWall --> CheckWin: no wall (mouse moves) CheckWin --> Render: not on cheese yet CheckWin --> [*]: on cheese, Game Over ``` ## Controls | Key | Effect | |-----|--------| | `u` | move up, toward row `a` (decreases the row letter) | | `d` | move down, toward row `d` (increases the row letter) | | `l` | move left, toward column 1 | | `r` | move right, toward column 4 | | `q` | quit the current move prompt | ## What blocks a move Two checks can stop a move: - The edge of the board. `goodDirection()` rejects a direction that would leave the 4x4 grid. - An internal wall. `Maze::move()` builds a `RoomPair` from the current room and the target, then compares it against all 8 walls with `matchPair()`. A match means a wall sits between the two rooms, so the mouse stays put. ## Build and run ```bash g++ -std=c++11 maze/*.cpp -o maze ./maze ``` ## Known rough edges The maze never checks that a path from `a1` to `d4` actually exists, so a random layout can wall the cheese off. Several functions return a value on every branch the program uses but still fall off the end on paths the compiler cannot rule out, which g++ warns about. The Roadmap page lists these.