Listing of relevant portions of code
for complete code, click here

Definitions
Variables
Beginning of main loop
States:
Title page
Clear function
Selection page 1
Selection page 2 - single game
Progression game handling
Setup for maze generation
Creating maze
Drawing maze
Player movement
Key found
Player escaped
Monster movement
Player eaten
Lose
Win
 
//maze size definitions
#define height 10
#define width 10  
#define mleft 8
#define mright 88
#define mtop 8
#define mbot 88 
#define vcDrawStart 2
#define vrDrawStart 128
#define hrDrawStart 256
#define hcDrawStart 1

//States           
#define title1   	0
#define title2   	1
#define title3   	2
#define title4   	3
#define title5   	4
#define clear    	5
#define select1  	6
#define select2  	7
#define select3  	8
#define select4  	9
#define select5 	10
#define select6 	11
#define select7 	12
#define select8 	13
#define progGame 	14
#define setup   	15
#define check   	16
#define create1 	17
#define create2 	18
#define create3 	19
#define draw1   	20
#define draw2   	21
#define draw3   	22
#define draw4   	23
#define play    	24
#define monster 	25
#define key		26
#define escape 		27
#define munch 		28
#define win1 		29
#define win2 		30
#define win3 		31
#define win4 		32
#define win5 		33
#define lose1 		34
#define lose2 		35
#define lose3 		36
#define lose4 		37
#define lose5 		38
#define lose6 		39
#define lose7 		40

//Variables for man and monster on title screen
unsigned char man, mon;

//Variables for game setup
unsigned char numPlayers, numMonsters, numKeys;
unsigned char afterclear, progression, cursor;

//Variables for storing and controlling user input
unsigned char userInput0,userInput1,lastInput0,lastInput1;
unsigned char userInput, lastInput;
char userSwitch;

//Variables for maze-generation algorithm
unsigned char setnum, done;
unsigned char lowset, highset;
unsigned char set[10][10];
unsigned char walls[10][10];

//Variables for drawing maze
int rowOffset, scrIndex;
char colOffset;     

//Variables for storing and updating player position
unsigned char playerNum, man0k,man0j,man1k,man1j;
char mank, manj;

//Variables for controlling monster movement
unsigned char monsterMove, monsterBack, monsterNum; 
unsigned char monster0Back, monster1Back, monster2Back;
char monster0k, monster0j, monster1k, monster1j, monster2k, monster2j, monsterk, monsterj;

//Variables for tracking keys and exit
unsigned char keyk[5], keyj[5];
unsigned char keysFound, foundKey;
unsigned char escaped;
char wink,winj;

//Variables for tracking player deaths
unsigned char eaten;
unsigned char lives[2];

//Variables used for iteration and randomized selection
unsigned char s, ia, ja, k, j, n;
char m, ic, jc;
unsigned int p;

unsigned char state;			//current state
unsigned char min2,min1,sec2,sec1;     	//timer digit values
unsigned int score;			//current player's score

//Strings for copying and displaying words from flash               
char string3[3];      
char string4[4];
char string5[5];
char string6[6];
char string7[7];

eeprom unsigned int bestscore;		//best score saved in eeprom

//Words for Menu and Title Displays
flash char title01[] = "MAZE";
flash char title02[] = "RUNNER";
flash char title03[] = "MARTIN";
flash char title04[] = "AND";
flash char title05[] = "JOHNSON";
flash char title06[] = "PRODUCT";
flash char title07[] = "ION";
flash char title08[] = "PRESS";
flash char select01[] = "PROGRES";
flash char select02[] = "SION";
flash char select03[] = "SINGLE";
flash char select04[] = "GAME";
flash char single01[] = "PLAYERS";
flash char single02[] = "MONSTER";
flash char single03[] = "KEYS";
flash char win01[] = "YOU";
flash char win02[] = "ESCAPED";
flash char win03[] = "THE";
flash char win04[] = "YOUR";
flash char win05[] = "SCORE";
flash char win06[] = "CONGRAT";
flash char win07[] = "ULATION";
flash char lose01[] = "WERE";
flash char lose02[] = "EATEN";
flash char lose03[] = "YUMMY";
flash char lose04[] = "LOSE";         
flash char best01[] = "BEST";
flash char time1[] = "TIME";
flash char lvl[] = "LVL";

//define some character bitmaps
//5x7 characters
flash char bitmap[40][7]={ 

//new characters only:

	//Running Man
	0b00000000,
	0b00100000,
	0b11111000,
	0b00100000,
	0b01010000,
	0b10010000,
	0b00000000,
	//The Smiling Face of Death
	0b00000000,
	0b10001000,
	0b01010000,
	0b00000000,
	0b11111000,
	0b10001000,
	0b01110000,
	//blank
	0b00000000,
	0b00000000,
	0b00000000,
	0b00000000,
	0b00000000,
	0b00000000,
	0b00000000,	
	//key
	0b00000000,
	0b00111000,
	0b00101000,
	0b00111000,
	0b00100000,
	0b01000000,
	0b10100000	
};


Inside main loop:

//initialize game setup
numPlayers=1;
numMonsters=0;
numKeys=1;
  
  //The following loop executes once/video line during lines
  //1-230, then does all of the frame-end processing
  while(1)
  begin
  
    //stall here until next line starts
    //sleep enable; mode=idle  
    //use sleep to make entry into sync ISR uniform time  
     
    #asm ("sleep"); 
    
    //The following code executes during the vertical blanking
    //Code here can be as long as  
    //a total of 60 lines x 63.5 uSec/line x 8 cycles/uSec 


    if (LineCount==231)
    begin 
           
switch(state){    
case title1:
*strcpyf(string4, title01);
video_puts(34, 2, string4);
*strcpyf(string6, title02);
video_puts(58, 10, string6);
state = title2;
break;

case title2:
video_putchar(40, 26, 10);
*strcpyf(string6, title03);
video_puts(52, 26, string6);
*strcpyf(string3, title04);
video_puts(31, 38, string3);
state = title3;            
break;           

case title3:              
*strcpyf(string7, title05);
video_puts(55, 38, string7);
*strcpyf(string7, title06);
video_puts(34, 50, string7);
state = title4;
break;

case title4:              
*strcpyf(string3, title07);
video_puts(76, 50, string3);
*strcpyf(string5, title08);
video_puts(43, 92, string5);
video_putchar(79, 92, 12);
state = title5;
break;

case title5:
if (m == 4){
	if (man == 0) 
		{video_putchar(man, 70, 36);
		man = man + 3;}
	else 
		{video_putchar(man-3, 70, 38);
		if (man == 126) 
			{man = 0;}
		else 
		{video_putchar(man, 70, 36);
		man = man + 3;}
	}
	if (man < 15 && mon > 15) {m = 0;}
}
if (m == 7) {
	if (man > 15 | mon > 15) {
	if (mon == 0) 
		{video_putchar(mon, 70, 37);
		mon = mon + 3;}
	else 
		{video_putchar(mon-3, 70, 38);
		if (mon == 126) 
			{mon = 0;}
		else 
		{video_putchar(mon, 70, 37);
		mon = mon + 3;}
	}
	}
     m = 0;
}
m++;
if ((PINB | 0x0f) == 0xef) 
{state = clear;
afterclear = select1;
m = 0;}               

//increment random seed until user exits intro screen
p++;

break;
              
case clear:
for (scrIndex = 0; scrIndex < 1600; scrIndex++)
	screen[scrIndex] = 0;
scrIndex = 0;
state = afterclear;
break;

case select1:
*strcpyf(string7, select01);
*strcpyf(string4, select02);
video_puts(32, 10, string7);
video_puts(74, 10, string4);
state = select2;
break;

case select2:
*strcpyf(string6, select03);
video_puts(32, 30, string6);
*strcpyf(string4, select04);
video_puts(74, 30, string4);
state = select3;
break;

case select3:
*strcpyf(string4, best01);
video_puts(35, 58, string4);
*strcpyf(string5, win05);
video_puts(65, 58, string5); 
state = select4;
break;

case select4:
//Display best score
video_putchar(54, 68, ((bestscore/1000)%10));
video_putchar(60, 68, ((bestscore/100)%10));
video_putchar(66, 68, ((bestscore/10)%10));
video_putchar(72, 68, (bestscore%10));

state = select5;
cursor = 10;
progression = 1;
score = 0;
break;

case select5:
video_putchar(20, cursor, 36);
*strcpyf(string5, title08);
video_puts(41, 92, string5);
video_putchar(77, 92, 11);      
if ((PINB | 0xf0) == 0xf7 && progression != 1) 
{video_putchar(20, 30, 38);
cursor = 10;
progression = 1;}
else if ((PINB | 0xf0) == 0xfd && progression == 1)
{video_putchar(20, 10, 38);
cursor = 30;
progression = 0;}
if ((PINB | 0x0f) == 0xdf)
{state = clear;
if (progression == 1){afterclear = progGame;}
else {afterclear = select6;}
}                      
break;
      
case select6:               
*strcpyf(string7, single01);
video_puts(26, 10, string7);
*strcpyf(string7, single02);
video_puts(26, 30, string7);
state = select7;
break;          

case select7:
video_putchar(68, 30, 28);
*strcpyf(string4, single03);
video_puts(26, 50, string4);
*strcpyf(string5, title08);
video_puts(36, 92, string5);
video_putchar(72, 92, 12);  
state = select8;
cursor = 10;
numPlayers = 1;
numKeys = 1;
numMonsters = 0;

//reset time and lives for single game
n=0;
sec1=0;
sec2=0;
min1=0;
min2=0;
lives[0]=3;

lastInput = 0xff;
break;          

case select8:
video_putchar(14, cursor, 36);      
video_putchar(86, 10, numPlayers);
video_putchar(86, 30, numMonsters);
video_putchar(86, 50, numKeys);

//get user 1 input
	if((PINB)!=0xff){
		userInput0=PINB;
	} 

if (m == 10){

//protect against double-move
if(userInput0==lastInput){userInput0=0xff;}  

	if ((userInput0 | 0xf0) == 0xf7 && cursor != 10) {
		video_putchar(14, 30, 38);
		video_putchar(14, 50, 38);
		video_putchar(14, 70, 38);
		cursor = cursor - 20;
		}
	else if ((userInput0 | 0xf0) == 0xfd && cursor != 50){
		video_putchar(14, 10, 38);
		video_putchar(14, 30, 38);
		video_putchar(14,50, 38); 
		cursor = cursor + 20;
	}
	if ((userInput0 | 0xf0) == 0xfb && cursor == 10 && numPlayers != 2) {
		numPlayers = 2;
	}
	if ((userInput0 | 0xf0) == 0xfe && cursor == 10 && numPlayers != 1) {
		numPlayers = 1;
	}
	if ((userInput0 | 0xf0) == 0xfb && cursor == 30 && numMonsters != 3) {
		numMonsters = numMonsters + 1;
	}
	if ((userInput0 | 0xf0) == 0xfe && cursor == 30 && numMonsters != 0) {
		numMonsters = numMonsters - 1;
	}
	if ((userInput0 | 0xf0) == 0xfb && cursor == 50 && numKeys != 4) {
		numKeys = numKeys + 1;
	}
	if ((userInput0 | 0xf0) == 0xfe && cursor == 50 && numKeys != 1) {
	     numKeys = numKeys - 1;
	}	
if (numPlayers == 1) {
lives[1]=0;
}
else lives[1] = 3;	
m = 0;
lastInput = userInput0;
userInput0 = 0xff;
}
m++;
//when user presses button, clear screen and start building maze      
if ((PINB | 0x0f) == 0xef)
{state = clear;
afterclear = setup;
}
break;

case progGame:
numPlayers=1;
if(progression==1){
	lives[0]=3;
	min2=0;
	min1=0;
	sec2=0;
	sec1=0;
	n=0;
	numKeys=1;
	numMonsters=0;
}
else if(progression==2){
	numKeys=1;
	numMonsters=1;
}
else if(progression==3){
	numKeys=2;
	numMonsters=1;
}
else if(progression==4){
	numKeys=2;
	numMonsters=2;
}
else if(progression==5){
	numKeys=3;
	numMonsters=1;
}
else if(progression==6){
	numKeys=3;
	numMonsters=2;
}
else if(progression==7){
	numKeys=3;
	numMonsters=3;
}
else if(progression==8){
	numKeys=4;
	numMonsters=1;
}
else if(progression==9){
	numKeys=4;
	numMonsters=2;
}
else if(progression==10){
	numKeys=4;
	numMonsters=3;
}
else{
	state=win1;
}

//go on to setup
if(progression < 11){state=setup;}

break;

case setup:
//put each cell of maze in its own set, and put up all walls
setnum=0;
for(k=0;k < height;k++){
	for(j=0;j < width;j++){
		set[k][j]=setnum++;      
		walls[k][j]=0;
	}
}
//initialize monster and player positions
monster0k=4;
monster0j=4;
monster1k=6;
monster1j=2;
monster2k=2;
monster2j=6;
man0k=0;
man0j=0;
man1k=9;
man1j=9;
keysFound=0;
userSwitch=0;
//initialize monsters for movement
monsterBack=0;
monsterNum=1;
//initialize event variables
eaten=0;
foundKey=0;
escaped=0;
//initialize exit (outside maze - unreachable until all keys are found)
wink=height;
winj=width;
//initialize keys (outside maze - only moved inside if being used)
for(m=0;m < 5;m++){keyk[m]=10;keyj[m]=10;}
m=0;
//draw maze border            
video_line(mleft,mtop,mright,mtop,1);
video_line(mleft,mtop,mleft,mbot,1);
video_line(mleft,mbot,mright,mbot,1);
video_line(mright,mtop,mright,mbot,1);
//go on to create maze
state=create1;

break;

case check:
done=1;
//iterate through maze, check if all cells are in set 0
for(k=0; k < height; k++){
	for(j=0; j < width; j++){
		if(set[k][j] != 0){
			done=0; //if a cell is not in set 0, maze is not done
		}
	}
}
if(done==1){
	//when maze is done, go on to draw it
	state=draw1;
}
else{
	state=create1;
}
//draw bar to show user that maze generation is in progress 
video_line(1,93,m++,93,1);
if(m > 99){
	m=0;
	//clear "maze generation" bar when it reaches 100 pixels
	video_line(1,93,100,93,0);
}
break;

case create1: 
//Pick random cell and random side of cell for wall to knock down
srand(p); p++;
ic=(char)(rand()%height); 
jc=(char)(rand()%width); 
s=(char)(rand() & 0x03); 

//Check to see if s is along edge of maze - if so, change accordingly
if((ic==0 && s==0) || (jc==width-1 && s==1)) s=s+2;
else if((ic==height-1 && s==2) || (jc==0 && s==3)) s=s-2;

//find adjacent element
if(s==0){ia=ic-1; ja=jc;}
else if(s==1){ia=ic; ja=jc+1;}
else if(s==2){ia=ic+1; ja=jc;}
else{ia=ic; ja=jc-1;}

//Check if selected elements are already connected (ie. are in same set)
if(set[ia][ja] != set[ic][jc]){

//Combine sets
lowset=min(set[ia][ja], set[ic][jc]);
highset=max(set[ia][ja], set[ic][jc]);
for(k=0; k < height; k++){
	for(j=0; j < width; j++){
		if(set[k][j] == highset){set [k][j]=lowset;}
	}
}

//knock down wall
if(s==0){walls[ic][jc]=walls[ic][jc]+1; walls[ia][ja]=walls[ia][ja]+4;}
else if(s==1){walls[ic][jc]=walls[ic][jc]+2; walls[ia][ja]=walls[ia][ja]+8;}
else if(s==2){walls[ic][jc]=walls[ic][jc]+4; walls[ia][ja]=walls[ia][ja]+1;}
else{walls[ic][jc]=walls[ic][jc]+8; walls[ia][ja]=walls[ia][ja]+2;}

}
state=check;
break;

case draw1:
//clear "maze generation" bar
video_line(0,93,100,93,0);

//draw vertical walls
colOffset=vcDrawStart;			//starting at upper left of second cell...
rowOffset=vrDrawStart;
for(j=1;j < width;j++){
	scrIndex=rowOffset+colOffset;  //start at top of maze, on upper left of given cell
	for(k=0;k < height;k++){
		screen[scrIndex]=screen[scrIndex] | 0x80; //draw corner pixel
		scrIndex=scrIndex+16;
		//if this vertical wall has not been knocked down...
		if((walls[k][j] & 0x08)==0){
			for(m=1;m<8;m++){
				screen[scrIndex]=0x80;	
				scrIndex=scrIndex+16;
			}
		}
		else{
			scrIndex=scrIndex+112;
		}
	}
	colOffset++;
}

//draw horizontal walls
rowOffset=hrDrawStart;
colOffset=hcDrawStart;
for(k=1;k < height;k++){
	scrIndex=rowOffset+colOffset;
	for(j=0;j < width;j++){
		if((walls[k][j] & 0x01)==0){
			screen[scrIndex]=0xff;
		}
	scrIndex++;
	}
	rowOffset=rowOffset+128;
}

//reset user input
userInput=0xff;

//move on to next draw state
state=draw2;

break;

case draw2:
//display lives
//Player 1
video_putchar(100,12,25);
video_putchar(106,12,1);
video_pt(112,14,1);
video_pt(112,17,1);
for(m=0;m < lives[0];m++){
	video_putchar(103+(m << 3),20,36);
}
if(numPlayers==2){
	//Player 2
	video_putchar(100,32,25);
	video_putchar(106,32,2);
	video_pt(112,34,1);
	video_pt(112,37,1);
	for(m=0;m < lives[1];m++){
		video_putchar(103+(m << 3),40,36);
	}
}
else if(progression != 0){
	//display progression level
	*strcpyf(string3,lvl);
	video_puts(100,32,string3);
	video_putchar(120,32,progression);
}

state=draw3;
break;

case draw3:
//display time
*strcpyf(string4,time1);
video_puts(100,70,string4);
video_pt(124,72,1);
video_pt(124,75,1);
video_putchar(100,80,min2);
video_putchar(106,80,min1);
video_pt(112,82,1);
video_pt(112,85,1);
video_putchar(114,80,sec2);
video_putchar(120,80,sec1);

//Place keys in random positions throughout maze
for(m=0;m < numKeys;m++){
	srand(p); p++;
	keyk[m]=rand()%10;
	keyj[m]=rand()%10;

	//draw key in maze
	video_putchar(mleft+(keyj[m] << 3)+2,mtop+(keyk[m] << 3)+1,39);
}      
m=0;      
state=play;
break;

case play:
//Timer
if(n==43){
  n=0;
  if(sec1==9){
    sec1=0;
    if(sec2==5){
      sec2=0;
      if(min1==9){
        min1=0;
        if(min2==5){
          //if a maze is not completed in 1 hour, you lose
          state=lose1;
        }else{min2++;}
      }else{min1++;}
    }else{sec2++;}
  }else{sec1++;}
  //display current time
  video_putchar(100,80,min2);
  video_putchar(106,80,min1);
  video_putchar(114,80,sec2);
  video_putchar(120,80,sec1);
}else{n++;}

//get user 1 input
if((PINB | 0xf0)!=0xff){userInput0=PINB;}
//get user 2 input
if((PINC | 0xf0)!=0xff){userInput1=PINC;}
//if player 2 is last person in maze, he becomes "user 1"
if(userSwitch==1){userInput0=userInput1;}


if(m!=6){m++;}
else{
    //move player if it is being used
    if(playerNum < numPlayers){

	//load variables for current player
	if(playerNum==0){
		mank=man0k;
		manj=man0j;
		lastInput=lastInput0;
		userInput=userInput0;
	}
	else{
		mank=man1k;
		manj=man1j;
		lastInput=lastInput1;
		userInput=userInput1;
	}

	//protect against accidental double-move
	if(userInput==lastInput){userInput=0xff;}

	//move running man
	if((userInput & 0x08)==0 && (walls[mank][manj] & 0x01)==0x01){
		video_putchar(mleft+(manj << 3)+2,mtop+(mank << 3)+1,38);   //erase old position
		mank--;							//move up
	}
	else if((userInput & 0x04)==0 && (walls[mank][manj] & 0x02)==0x02){
		video_putchar(mleft+(manj << 3)+2,mtop+(mank << 3)+1,38);   //erase old position
		manj++;							//move right
	} 
	else if((userInput & 0x02)==0 && (walls[mank][manj] & 0x04)==0x04){
		video_putchar(mleft+(manj << 3)+2,mtop+(mank << 3)+1,38);   //erase old position
		mank++;							//move down
	}
	else if((userInput & 0x01)==0 && (walls[mank][manj] & 0x08)==0x08){
		video_putchar(mleft+(manj << 3)+2,mtop+(mank << 3)+1,38);   //erase old position
		manj--;							//move left
	}
	video_putchar(mleft+(manj << 3)+2,mtop+(mank << 3)+1,36);   //draw character in current position
	lastInput=userInput;					//save input (for protecting against double-move for one press)
	userInput=0xff;						//reset input to nothing (more double-move protection)                     

	//detect key found
	for(ic=0;ic < 4;ic++){
		if(mank==keyk[ic] && manj==keyj[ic]){foundKey=1+ic;}
	}

	//detect escape
	if(mank==wink && manj==winj){escaped=1+playerNum;}

	//store variables for current player
	if(playerNum==0){
		man0k=mank;
		man0j=manj;
		lastInput0=lastInput;
		userInput0=userInput;
		if(userSwitch==1){
			userInput1=userInput;
		}
	}
	else{
		man1k=mank;
		man1j=manj;
		lastInput1=lastInput;
		userInput1=userInput;
	}
    }
    //move on to next player or to monsters
    if(playerNum==0){playerNum=1;}
    else{playerNum=0; m=0; state=monster;}
} 

//move to special state when key found
//when last key is found, this state will draw the exit
if(foundKey!=0){state=key;}                            

//move to special state when a player escapes
//when last player escapes, stage is won
else if(escaped!=0){
	state=escape;
}

break;

case key:
//move found key off of board
keyk[foundKey-1]=10;
keyj[foundKey-1]=10;
//"reshuffle" keys into lowest-number positions
if(foundKey < numKeys){
	for(ic=foundKey-1;ic < numKeys;ic++){
		keyk[ic]=keyk[ic+1];
		keyj[ic]=keyj[ic+1];
	}
}
numKeys--;	//decrement number of keys
keysFound++; //increment number of keys player has found

//When last key is found, draw exit in random location
if(numKeys==0){
	//select random exit location
	srand(p); p++;
	ic=rand() % 10;
	s=rand() & 0x03;
	//Make the exit
	if(s==0){
		wink=0; 
		winj=ic;
		screen[(mtop << 4)+1+ic]=0x80;			//break outer wall
		video_putchar(mleft+(ic << 3)+2,mtop-8,14);	//mark exit with an "E"
	}
	else if(s==1){
		wink=ic; 
		winj=9;
		video_line(mright,mtop+(ic << 3),mright,mtop+(ic << 3)+7,0);  //break outer wall
		video_putchar(mright+1,mtop+(ic << 3)+1,14);		  //mark exit with an "E"
	}
	else if(s==2){
		wink=9; 
		winj=ic;
		screen[(mbot << 4)+1+ic]=0x80;			//break outer wall
		video_putchar(mleft+(ic << 3)+2,mbot+1,14);	//mark exit with an "E"
	}
	else{
		wink=ic; 
		winj=0;
		video_line(mleft,mtop+(ic << 3),mleft,mtop+(ic << 3)+7,0);	//break outer wall
		video_putchar(mleft-6,mtop+(ic << 3)+1,14);		//mark exit with an "E"
	}      
}

foundKey=0;  	//reset found key variable             
state=monster;  //go on to monsters
break;

case escape:
if(numPlayers==1){
	//if last player just escaped, stage is won
	state = clear; 
	if(progression > 0){
		progression++; 			//move to next stage in progression
		afterclear=progGame;    //keep going with progression
	}
	else{afterclear = win1;}
}
//if first of two players has just escaped...
if(numPlayers==2){
  //if player 1 escaped...
  if(escaped==1){
    //erase player 1's character
    video_putchar(mleft+(man0j << 3)+2,mtop+(man0k << 3)+1,38);
    //player 2 becomes player 1
    man0k=man1k;
    man0j=man1j;
	lives[0]=lives[1];
    lastInput0=lastInput1;
    userSwitch=1;	//switch so controller 2 still controls remaining player
  }
  else{
    //if player 2 escaped, just erase him
    video_putchar(mleft+(man1j << 3)+2,mtop+(man1k << 3)+1,38);
  }
  numPlayers=1;	//only one player left
  state=monster;   //move on to monsters
}
         
//reset escaped variable
escaped=0;

break;

case monster:
//get user 1 input
if((PINB | 0xf0)!=0xff){userInput0=PINB;}
//get user 2 input
if((PINC | 0xf0)!=0xff){userInput1=PINC;}
//if player 2 is last person in maze, he becomes "user 1"
if(userSwitch==1){userInput0=userInput1;}

//move monster if it is being used
if(monsterNum < numMonsters){

	//load variables for current monster
	if(monsterNum==0){
		monsterk=monster0k;
		monsterj=monster0j;
		monsterBack=monster0Back;
	}
	else if(monsterNum==1){
		monsterk=monster1k;
		monsterj=monster1j;
		monsterBack=monster1Back;
	}
	else{
		monsterk=monster2k;
		monsterj=monster2j;
		monsterBack=monster2Back;
	}

	//if monster is on man before moving, man is eaten
	if(man0k==monsterk && man0j==monsterj){eaten=1;}
	else if(numPlayers>1 && man1k==monsterk && man1j==monsterj){eaten=2;}

	//Move Monster
	//pick random direction
	srand(p); p++;
	s=(char)(rand() & 0x03);
	//decode direction
	if(s > 2){monsterMove=0x08;}
	else if(s > 1){monsterMove=0x04;}
	else if(s > 0){monsterMove=0x02;}
	else{monsterMove=0x01;}
	
	//don't move backward unless it's the only option
	if((monsterMove==monsterBack) && (walls[monsterk][monsterj] != monsterMove)){monsterMove=0;}
	//don't walk into a wall
	if((walls[monsterk][monsterj] & monsterMove) != monsterMove){monsterMove=0;}
	else{
		//find "backward" direction so monster can try to avoid doubling back
		if(monsterMove > 2){monsterBack=monsterMove >> 2;}
		else if(monsterMove > 0){monsterBack=monsterMove << 2;}
	}
	
	//update monster position and erase old
	if(monsterMove==0x01){
		video_putchar(mleft+(monsterj << 3)+2,mtop+(monsterk << 3)+1,38);	//erase old position
		monsterk--;							//move up
	}
	else if(monsterMove==0x02){
		video_putchar(mleft+(monsterj << 3)+2,mtop+(monsterk << 3)+1,38);	//erase old position
		monsterj++;							//move right
	}
	else if(monsterMove==0x04){
		video_putchar(mleft+(monsterj << 3)+2,mtop+(monsterk << 3)+1,38);	//erase old position
		monsterk++;							//move down
	}
	else if(monsterMove==0x08){
		video_putchar(mleft+(monsterj << 3)+2,mtop+(monsterk << 3)+1,38);	//erase old position
		monsterj--;							//move left
	}
	
	//draw monster in new position
	video_putchar(mleft+(monsterj << 3)+2,mtop+(monsterk << 3)+1,37);
	
	
	//if monster is on man after moving, man is eaten
	if(man0k==monsterk && man0j==monsterj){eaten=1;}
	else if(numPlayers>1 && man1k==monsterk && man1j==monsterj){eaten=2;}
	
	//save variables for current monster
	if(monsterNum==0){
		monster0k=monsterk;
		monster0j=monsterj;
		monster0Back=monsterBack;
	}
	else if(monsterNum==1){
		monster1k=monsterk;
		monster1j=monsterj;
		monster1Back=monsterBack;
	}
	else{
		monster2k=monsterk;
		monster2j=monsterj;
		monster2Back=monsterBack;
	}
	
	//redraw keys in case monster erased one
	for(ic=0;ic < numKeys;ic++){
		//only redraw key if no monster is on top of it
		if((monster0j!=keyj[ic] || monster0k!=keyk[ic]) && (monster1j!=keyj[ic] || monster1k!=keyk[ic]) 
		    && (monster2j!=keyj[ic] || monster2k!=keyk[ic])){
			video_putchar(mleft+(keyj[ic] << 3)+2,mtop+(keyk[ic] << 3)+1,39);
		}
	}
	
}
	
//check if man is eaten; if so, go to "munch" state
if(eaten!=0){state=munch;}
else{
	//move on to next monster or back to player
	if(monsterNum < 2){monsterNum++;}
	else{monsterNum=0; state=play;}
}
break;

case munch:
lives[eaten-1]--;
if(lives[eaten-1] < 1){state=clear; afterclear=lose1;}
else{ 
	if(eaten==1){
		srand(p); p++;
		man0j=(rand() & 0x01)*9;
		man0k=(rand() & 0x01)*9;
		video_putchar(mleft+(man0j << 3)+2,mtop+(man0k << 3)+1,36);
		if(userSwitch==1){
			video_putchar(103+(lives[eaten-1] << 3),40,38);
		}
		else{video_putchar(103+(lives[eaten-1] << 3),20,38);}
	}
	else{
		srand(p); p++;
		man1j=(rand() & 0x01)*9;
		man1k=(rand() & 0x01)*9;
		video_putchar(mleft+(man1j << 3)+2,mtop+(man1k << 3)+1,36);
		video_putchar(103+(lives[eaten-1] << 3),40,38);
	}    
	state=play;
}
eaten=0;
break;

//Lose Cases: display losing message on screen

case lose1:
*strcpyf(string3, win01);
video_puts(10, 10, string3);
*strcpyf(string4, lose01);
video_puts(34, 10, string4);
state = lose2;
break;

case lose2:
*strcpyf(string5, lose02);
video_puts(64, 10, string5);
*strcpyf(string3, win03);
video_puts(10, 20, string3);
state = lose3;
break;

case lose3:
*strcpyf(string4, title01);
video_puts(34, 20, string4);
*strcpyf(string7, single02);
video_puts(64, 20, string7);
video_putchar(106, 20, 28);
state = lose4;
break;

case lose4:
video_putchar(100, 10, 11);
video_putchar(106, 10, 34);
*strcpyf(string3, win01);
video_puts(18, 38, string3);
*strcpyf(string4, lose01);
video_puts(42, 38, string4); 
state = lose5;
break;

case lose5:
*strcpyf(string5, lose03);
video_puts(72, 38, string5);
*strcpyf(string3, win01);
video_puts(36, 58,string3);
state = lose6;
break;

case lose6:
*strcpyf(string4, lose04);
video_puts(60, 58,string4);
*strcpyf(string4, win04);
video_puts(10, 75, string4);
*strcpyf(string5, win05);
video_puts(40, 75, string5);
state = lose7;
break;

case lose7:
score = progression;
score = score << 1;
score = score + lives[0] + lives[1];
if (progression == 0) {
	score = score + keysFound + numMonsters;
}
score = score << 8;
if(progression!=0 && (score > bestscore)){
	bestscore=score;
}
video_putchar(84, 75, ((score/1000)%10));
video_putchar(90, 75, ((score/100)%10));
video_putchar(96, 75, ((score/10)%10));
video_putchar(102, 75, (score%10));
*strcpyf(string5, title08);
video_puts(41, 92, string5);
video_putchar(77, 92, 11);  
//wait for player to press button 
if ((PINB | 0x0f) == 0xdf){
	state = clear;
	afterclear = title1;
}

break;

//Win Cases: display winning message

case win1:
*strcpyf(string3, win01);
video_puts(30, 26, string3);
*strcpyf(string7, win02);
video_puts(54, 26, string7);
state = win2;
break;

case win2:
*strcpyf(string3, win03);
video_puts(39, 36, string3);
*strcpyf(string4, title01);
video_puts(63, 36, string4);
state = win3;
break;

case win3:
*strcpyf(string7, win06);
video_puts(18, 5, string7);
*strcpyf(string7, win07);
video_puts(60, 5, string7);
state = win4;
break;

case win4:
video_putchar(102, 5, 28);
*strcpyf(string4, win04);
video_puts(32, 56, string4);
*strcpyf(string5, win05);
video_puts(62, 56, string5);
state = win5;
break;

case win5:
score = progression;
score = score << 1;
score = score + lives[0] + lives[1];
if (progression == 0) {
	score = score + keysFound + numMonsters;
}
score = score << 4;
if (progression == 0){
	if (min2 == 0 && min1 < 2) {
		score = score + 25 - (min1 << 4) - sec2;
	}                     
}
if (progression != 0){
	if (min2 == 0 && min1 < 6)
		score = score + 102 - (min1 << 4) - sec2;
}
score = score << 4;

if(progression!=0 && (score > bestscore)){
	bestscore=score;
}

video_putchar(50, 68, ((score/1000)%10));
video_putchar(56, 68, ((score/100)%10));
video_putchar(62, 68, ((score/10)%10));
video_putchar(68, 68, (score%10));
*strcpyf(string5, title08);
video_puts(40, 92, string5);
video_putchar(76, 92, 11);  
if ((PINB | 0x0f) == 0xdf)
{state = clear;
afterclear=title1;
}
break;

}//end switch(state)
                      
     end  //line 231
  end  //while
end  //main