Program Design:

Maze Information

A representation of the walls surrounding each cell is stored in the 2-dimensional walls array. This is an array of characters, and the lower 4 bits of each character represent the four walls around that cell:

A "0" represents a wall, and a "1" represents no wall. Thus, to "knock down" the wall on, say, side 3 of a given cell, it was only necessary to add 2^3 to that element of the walls array (and add 2^1 to the element on its left, since that wall is also side 1 of that element).

During player and monster movement, the game uses this walls array to determine whether moves are legal.

User Input

During gameplay, both players' input is checked every 1/60 sec; any input other than "0xFF" (no buttons pressed on game controller) is saved in a userInput variable. Every 1/6 sec, each player's userInput variable is checked, the player's character is moved accordingly, and their userInput is reset to "0xFF."

The player's userInput is also stored, so that if the same input is detected on two consecutive 1/6 sec checks, the player will only be moved once. Their userInput is then reset and stored as "0xFF," so that if the player continues to hold down the button, their character will be moved every other 1/6 sec. Thus, a player ma move at a rate of 1 cell every 1/3 sec by holding down a button, but will only move once when the button is tapped (as long as it is released within 1/6 sec, which is reasonable for humans).

Movement cycle

To accomplish this 1/6 sec checking scheme (and to divide work across several vertical-blanking periods in order to avoid flicker), the state machine controlling gameplay operates in a 10-period cycle:

First 5 vertical-blanking periods: Stall in play state, incrementing m
Period 6: check/update player 1
Period 7: check/update player 2 (if playing - otherwise, this serves as another stall period)
Period 8: move monster 0 (if activated - otherwise, this serves as another stall period)
Period 9: move monster 1 (if activated - otherwise, this serves as another stall period)
Period 10: move monster 2 (if activated - otherwise, this serves as another stall period)


This cycle can be interrupted by three events, each of which use 1 period before either returning to the cycle or moving to the "win, lose, or progGame state:

1. Key is Found - When a key is found, the game updates its count of keys. If the key found was the last key, the game generates an exit at a random location along the outer wall of the maze.

2. Player Escaped - If a player is the first of two players to escape, they are simply removed from the board, and the other player is left to finish the game. If a player is the last to escape, they have won, so the game goes to the win state (or back to progGame if they are in the middle of a progression game).

3. Player Eaten - If the player eaten has more lives, they re-spawn in a random corner of the maze, and the game continues. If not, the game is lost.

The cycle will also end and go to the lose state automatically if the clock reaches 1 hour.

Monster Movement

When it is a monster's turn to be moved, a random direction is chosen. This direction is then checked against the walls array. If there is no wall on this side of the monster, the monster can be moved. However, to keep the monsters from backtracking too often, the direction of their previous movement is stored. If they attempt to move back to the square from which they just came, they are stopped, unless it is the only direction in which they can move from their current position.

If the random direction of movement selected for the monster leads into a wall or is an example of unacceptable backtracking, the monster simply does not move during this cycle - it waits until the next cycle, when another random direction is chosen. This helps to make the monsters' movements unpredictable not only in direction but also in speed, since they do not necessarily move during every cycle.

State Diagram

Conditions for state transitions:
A. user presses "C" button
B. user presses "B" button & progression != 0
C. user presses "B" button & progression == 0
D. user presses "C" button
E. done == 0
F. done != 0
G. m &60; 6 or player 1 just had turn in cycle
H. player 2 just had turn in cycle
I. a player is on the exit
J. a player is on a key
K. time reached 1 hour
L. only 1 of 2 players escaped
M. last player escaped & (not a progression game or progression game over)
N. monster 0 or 1 just had turn in cycle
O. monster 2 just had turn in cycle
P. a monster is on a player
Q. eaten player has more lives
R. eaten player has no more lives
S. user presses "B" button
T. last player escaped & progression game not over
U. user presses "B" button