-
Notifications
You must be signed in to change notification settings - Fork 0
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.
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 bymakeStartRoom). - Cheese room:
d4(set bymakeCheeseRoom, which usesx_ = mazeSize_andy_ = 'a' + mazeSize_ - 1).
mazeSize_ is 4, so the board is 4x4. The maze holds 8 internal walls (numWalls_).
-
Roomholds 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. -
RoomPairholds two rooms. It models one internal wall, and it also models a candidate move (current room paired with target room). -
Mazeowns the array of 8 wallRoomPairs plus the current mouse room. It builds the walls, prints them, and decides whether a move is blocked.
The generator places walls. It does not knock them out. Maze::build() loops until it has collected 8 distinct walls:
- Make an empty
RoomPair. -
RoomPair::pick()picks a random room, then picks a random room adjacent to it. -
Maze::checkMaze()scans the walls already placed. If this pair matches one (in either order), it is a duplicate. - 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.
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.
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:
- Print the current room.
- Ask for a move.
Room::nextMove()acceptsu,d,l,r, orq. - Validate the direction. If the move would leave the board, print
There is a walland ask again. - Hand the target room to
Maze::move(). If a wall sits between the current room and the target, the move is refused andThere is a wallprints. Otherwise the mouse moves. - Check whether the current room matches the cheese room. If so, print
Game Over!and stop.
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
| 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 |
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 aRoomPairfrom the current room and the target, then compares it against all 8 walls withmatchPair(). A match means a wall sits between the two rooms, so the mouse stays put.
g++ -std=c++11 maze/*.cpp -o maze
./mazeThe 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.