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