Code for 4180 mini project

Dependencies:   4DGL-uLCD-SE SDFileSystem mbed-rtos mbed wave_player

Fork of Pacman by Shawn Rigdon

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "rtos.h"
00003 #include "uLCD_4DGL.h"
00004 #include "SDFileSystem.h"
00005 #include "wave_player.h"
00006 
00007 #define PAC_SIZE    5   // The radius of Pacman and the ghost
00008 #define STEP_SIZE   8   // The number of pixels each character moves at once
00009 #define CLEARANCE   12  // The number of pixels each character checks ahead before moving
00010 
00011 DigitalIn left_pb(p21);  // push button
00012 DigitalIn right_pb(p22); // push button
00013 DigitalIn up_pb(p23);    // push button
00014 DigitalIn down_pb(p24);  // push button
00015 SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
00016 AnalogOut DACout(p18);
00017 wave_player waver(&DACout); // wave player
00018 uLCD_4DGL uLCD(p28, p27, p29);
00019 Mutex lcd_mutex;
00020 
00021 void checkMOVE(void);   // This function is defined below.  It was written here since other functions return to it that it also calls.
00022 
00023 // several variables are used by multiple threads
00024 volatile bool win=false;    // True when pacman has eaten all coins
00025 volatile bool lose=false;   // True when the position of the ghost and pacman are the same
00026 volatile int x = 64;        // x and y are pacman's position.  The starting position is defined here.
00027 volatile int y = 88;
00028 volatile int gx1 = 64;      // Starting position of the blue ghost
00029 volatile int gy1 = 40;
00030 int i;
00031 bool clearRIGHT,clearLEFT,clearUP,clearDOWN,bgcr,bgcl,bgcu,bgcd;
00032 
00033 // An array containing the locations of the 81 coins pacman must eat
00034 int coins[81][2] = {
00035         {40,88},{48,88},{56,88},{72,88},{80,88},{88,88},
00036         {40,40},{48,40},{56,40},{64,40},{72,40},{80,40},{88,40},
00037         {40,48},{40,56},{40,64},{40,72},{40,80},
00038         {88,48},{88,56},{88,64},{88,72},{88,80},
00039         {56,96},{56,104},{56,112},
00040         {48,112},{40,112},{32,112},{24,112},{16,112},
00041         {16,104},{16,96},{16,88},{16,80},{16,72},
00042         {24,64},{32,64},
00043         {16,64},{16,56},{16,48},{16,40},{16,32},{16,24},{16,16},
00044         {24,16},{32,16},{40,16},{48,16},{56,16},
00045         {56,24},{56,32},
00046         {72,96},{72,104},{72,112},
00047         {80,112},{88,112},{96,112},{104,112},{112,112},
00048         {112,104},{112,96},{112,88},{112,80},{112,72},
00049         {104,64},{96,64},
00050         {112,64},{112,56},{112,48},{112,40},{112,32},{112,24},{112,16},
00051         {104,16},{96,16},{88,16},{80,16},{72,16},
00052         {72,24},{72,32}
00053     };
00054 
00055 // This function is used in the ghost thread to replace coins as it passes over them
00056 void replaceCOINS(void)
00057 {
00058     for(int n=0; n<81; n++)
00059     {
00060         lcd_mutex.lock();   //The coins array is used by both threads
00061         if(gx1 == coins[n][0] && gy1 == coins[n][1])
00062         {
00063             uLCD.filled_circle(gx1,gy1,1,0xFFFF00);     //compare the set of coins to the ghost's previous position and if there is a match redraw coin   
00064         }
00065         lcd_mutex.unlock();
00066     }
00067 }
00068 
00069 // Checks if the ghost can move right (there is no boundary immediately to the right)
00070 void BGclearRIGHT(void)
00071 {
00072     bgcr = true;
00073     for(int p=gx1; p <= gx1+CLEARANCE; p++)
00074     {
00075         lcd_mutex.lock();
00076         if(uLCD.read_pixel(p,gy1)==uLCD.read_pixel(4,4))
00077         {
00078             bgcr = false;   // compare the pixels immediately in front of the ghost to the boundary up to the spec. clearance
00079         }                   // if they are the same color, determine the ghost can't move right
00080         lcd_mutex.unlock();
00081     }
00082 }
00083 
00084 //Checks if ghost can move left
00085 void BGclearLEFT(void)
00086 {
00087     bgcl = true;
00088     for(int p=gx1; p >= gx1-CLEARANCE; p--)
00089     {
00090         lcd_mutex.lock();
00091         if(uLCD.read_pixel(p,gy1)==uLCD.read_pixel(4,4))
00092         {
00093             bgcl = false;
00094         }
00095         lcd_mutex.unlock();
00096     }
00097 }
00098 
00099 //Checks if ghost can move up
00100 void BGclearUP(void)
00101 {
00102     bgcu = true;
00103     for(int p=gy1; p >= gy1-CLEARANCE; p--)
00104     {
00105         lcd_mutex.lock();
00106         if(uLCD.read_pixel(gx1,p)==uLCD.read_pixel(4,4))
00107         {
00108             bgcu = false;
00109         }
00110         lcd_mutex.unlock();
00111     }
00112 }
00113 
00114 //Checks if ghost can move down
00115 void BGclearDOWN(void)
00116 {
00117     bgcd = true;
00118     for(int p=gy1; p <= gy1+CLEARANCE; p++)
00119     {
00120         lcd_mutex.lock();
00121         if(uLCD.read_pixel(gx1,p)==uLCD.read_pixel(4,4))
00122         {
00123             bgcd = false;
00124         }
00125         lcd_mutex.unlock();
00126     }
00127 }
00128 
00129 //Moves the blue ghost to the right
00130 void bgRIGHT(void)
00131 {
00132     Thread::wait(50);
00133     lcd_mutex.lock();
00134     uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK);   //erase the previous ghost drawing
00135     lcd_mutex.unlock();
00136     replaceCOINS();     //replace the coin the ghost was just on if there was one
00137     if(gx1>124)         //This will cause the ghost to wrap around to the left side of the screen if there were no boundary on the far right
00138     {
00139         gx1 = 0;
00140     }
00141     gx1 = gx1+STEP_SIZE;    //Move one step size in the x direction
00142     lcd_mutex.lock();
00143     //redraw the ghost at the new position
00144     uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE);
00145     uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE);
00146     uLCD.filled_circle(gx1+2,gy1-2,1,BLACK);
00147     uLCD.filled_circle(gx1-2,gy1-2,1,BLACK);
00148     lcd_mutex.unlock();
00149 }
00150 
00151 //Moves the blue ghost left
00152 void bgLEFT(void)
00153 {
00154     Thread::wait(50);
00155     lcd_mutex.lock();
00156     uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK);
00157     lcd_mutex.unlock();
00158     replaceCOINS();
00159     if(gx1<4)
00160     {
00161         gx1 = 124;
00162     }
00163     gx1 = gx1-STEP_SIZE;
00164     lcd_mutex.lock();
00165     uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE);
00166     uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE);
00167     uLCD.filled_circle(gx1+2,gy1-2,1,BLACK);
00168     uLCD.filled_circle(gx1-2,gy1-2,1,BLACK);
00169     lcd_mutex.unlock();
00170 }
00171 
00172 //Moves the blue ghost up
00173 void bgUP(void)
00174 {
00175     Thread::wait(50);
00176     lcd_mutex.lock();
00177     uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK);
00178     lcd_mutex.unlock();
00179     replaceCOINS();
00180     if(gy1<4)
00181     {
00182         gy1 = 124;
00183     }
00184     gy1 = gy1-STEP_SIZE;
00185     lcd_mutex.lock();
00186     uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE);
00187     uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE);
00188     uLCD.filled_circle(gx1+2,gy1-2,1,BLACK);
00189     uLCD.filled_circle(gx1-2,gy1-2,1,BLACK);
00190     lcd_mutex.unlock();
00191 }
00192 
00193 //Moves the blue ghost down
00194 void bgDOWN(void)
00195 {
00196     Thread::wait(50);
00197     lcd_mutex.lock();
00198     uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK);
00199     lcd_mutex.unlock();
00200     replaceCOINS();
00201     if(gy1>124)
00202     {
00203         gy1 = 0;
00204     }
00205     gy1 = gy1+STEP_SIZE;
00206     lcd_mutex.lock();
00207     uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE);
00208     uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE);
00209     uLCD.filled_circle(gx1+2,gy1-2,1,BLACK);
00210     uLCD.filled_circle(gx1-2,gy1-2,1,BLACK);
00211     lcd_mutex.unlock();
00212 }
00213 
00214 //Force ghost to chase Pacman
00215 void follow(void)
00216 {
00217     if((gx1==x) && (y == gy1) )    //if the ghost and Pacman are at the same position trigger losing condition
00218     {
00219         win = true;         //This is set to true just to exit the check for a win loop and terminate other loops without writing additional conditions
00220         lose = true;
00221         if(lose)            //Print game over message if lose (determined in the follow function)
00222         {
00223             uLCD.cls();
00224             uLCD.printf("Sorry\nGame Over");
00225             // if loss, ring the buzzer
00226             FILE *wave_file;
00227             wave_file=fopen("/sd/test.wav","r");
00228             waver.play(wave_file);
00229             fclose(wave_file);
00230             Thread::wait(1000);
00231             return void();
00232         }
00233 
00234     }
00235     while(x==gx1 && gy1<y && !win)  //If the ghost is directly above Pacman check to see if moving down is possible, then move down
00236     {
00237         BGclearDOWN();  
00238         bgDOWN();
00239     }
00240     while(x==gx1 && gy1>y && !win)
00241     {
00242         BGclearUP();
00243         bgUP();
00244     }
00245     while(y==gy1 && gx1<x && !win)
00246     {
00247         BGclearRIGHT();
00248         bgRIGHT();
00249     }
00250     while(y==gy1 && gx1>x && !win)
00251     {
00252         BGclearLEFT();
00253         bgLEFT();
00254     }
00255 }
00256 
00257 //Ghost selects a direction to move
00258 void pickMOVE(void)
00259 {   
00260     
00261     while((gx1==x || gy1==y) && abs(x-gx1)+abs(y-gy1)<=16 && !win)  //If Pacman is close by give chase
00262     {
00263         follow();
00264     }
00265     int dec = rand()%4; //randomly generate a number from the set 0,1,2,3, which serves as the direction decision
00266     if(dec == 0)
00267     {
00268         BGclearRIGHT();
00269         while(bgcr && !win)     //If decision 0 was reached, check to the the move right until a boundary is reached
00270         {
00271             bgRIGHT();
00272             BGclearRIGHT();
00273         }
00274     }
00275     else if(dec == 1)
00276     {
00277         BGclearLEFT();
00278         while(bgcl && !win)
00279         {
00280             bgLEFT();
00281             BGclearLEFT();
00282         }
00283     }
00284     else if(dec == 2)
00285     {
00286         BGclearUP();
00287         while(bgcu && !win)
00288         {
00289             bgUP();
00290             BGclearUP();
00291         }
00292     }
00293     else
00294     {
00295         BGclearDOWN();
00296         while(bgcd && !win)
00297         {
00298             bgDOWN();
00299             BGclearDOWN();
00300         }
00301     }
00302 }        
00303 
00304 //Check if Pacman can move one step size to the right (Essentially the same as checking for the ghost)
00305 void CHECKclearRIGHT(void)
00306 {
00307     clearRIGHT = true;
00308     for(i=x; i <= x+CLEARANCE; i++)
00309     {
00310         lcd_mutex.lock();
00311         if(uLCD.read_pixel(i,y)==uLCD.read_pixel(4,4))
00312         {
00313             clearRIGHT = false;
00314         }
00315         lcd_mutex.unlock();
00316     }
00317 }
00318 
00319 //Check if Pacman can move left
00320 void CHECKclearLEFT(void)
00321 {
00322     clearLEFT = true;
00323     for(i=x; i >= x-CLEARANCE; i--)
00324     {
00325         lcd_mutex.lock();
00326         if(uLCD.read_pixel(i,y)==uLCD.read_pixel(4,4))
00327         {
00328             clearLEFT = false;
00329         }
00330         lcd_mutex.unlock();
00331     }
00332 }
00333 
00334 //Check if Pacman can move up
00335 void CHECKclearUP(void)
00336 {
00337     clearUP = true;
00338     for(i=y; i >= y-CLEARANCE; i--)
00339     {
00340         lcd_mutex.lock();
00341         if(uLCD.read_pixel(x,i)==uLCD.read_pixel(4,4))
00342         {
00343             clearUP = false;
00344         }
00345         lcd_mutex.unlock();
00346     }
00347 }
00348 
00349 //Check if Pacman can move down
00350 void CHECKclearDOWN(void)
00351 {
00352     clearDOWN = true;
00353     for(i=y; i <= y+CLEARANCE; i++)
00354     {
00355         lcd_mutex.lock();
00356         if(uLCD.read_pixel(x,i)==uLCD.read_pixel(4,4))
00357         {
00358             clearDOWN = false;
00359         }
00360         lcd_mutex.unlock();
00361     }
00362 }
00363 
00364 //This function tracks the coin Pacman eats as he passes over it
00365 void changeCOINS(void)
00366 {
00367     for(int m=0; m<81; m++)
00368     {
00369         lcd_mutex.lock();
00370         if(x == coins[m][0] && y == coins[m][1])    //Compare Pacman's position to the set of coins
00371         {
00372             coins[m][0]=64;                         //If there is a match, change that coins location to the center of the board where Pacman
00373             coins[m][1]=64;                         //cannot go, but do not draw the coin
00374         }
00375         lcd_mutex.unlock();
00376     }
00377 }
00378 
00379 //Move Pacman one step size to the right
00380 void PACmoveRIGHT(void)
00381 {
00382     while(clearRIGHT && !win)   //Not win indicates the game has not ended
00383     {
00384         lcd_mutex.lock();
00385         uLCD.filled_circle(x,y,PAC_SIZE,BLACK);     //Erase Pacman at his last location
00386         lcd_mutex.unlock();
00387         if(x>124)       //wrap around if moving off the board
00388         {
00389             x = 0;
00390         }
00391         x = x+STEP_SIZE;    //move Pacman one step size to the right
00392         changeCOINS();  //Track the coin that was eaten at the last location
00393         
00394         if(x%(2*STEP_SIZE) == 0)    //There are two drawings provided for Pacman.  The if statement causes Pacman to open his mouth every other move.
00395         {
00396             lcd_mutex.lock();
00397             uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
00398             uLCD.filled_rectangle(x+2,y-2,x+PAC_SIZE,y+2,BLACK);
00399             lcd_mutex.unlock();
00400         }
00401         else
00402         {
00403             lcd_mutex.lock();
00404             uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
00405             uLCD.filled_rectangle(x+2,y,x+PAC_SIZE,y+1,BLACK);
00406             lcd_mutex.unlock();
00407         }
00408         
00409         CHECKclearRIGHT();  //If the user remains in the loop, check for a boundary to the right
00410         Thread::wait(10);
00411         break;
00412     }
00413 }
00414 
00415 //Move Pacman left
00416 void PACmoveLEFT(void)
00417 {
00418     while(clearLEFT && !win)
00419     {
00420         lcd_mutex.lock();
00421         uLCD.filled_circle(x,y,PAC_SIZE,BLACK);
00422         lcd_mutex.unlock();
00423         if(x<4)
00424         {
00425             x = 128;
00426         }
00427         x = x-STEP_SIZE;
00428         
00429         changeCOINS();
00430         if(x%(2*STEP_SIZE) == 0)
00431         {
00432             lcd_mutex.lock();
00433             uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
00434             uLCD.filled_rectangle(x-2,y-2,x-PAC_SIZE,y+2,BLACK);
00435             lcd_mutex.unlock();
00436         }
00437         else
00438         {
00439             lcd_mutex.lock();
00440             uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
00441             uLCD.filled_rectangle(x-2,y,x-PAC_SIZE,y+1,BLACK);
00442             lcd_mutex.unlock();
00443         }
00444         
00445         CHECKclearLEFT();
00446         Thread::wait(10);
00447         break;
00448     }
00449 }
00450 
00451 //Move Pacman up
00452 void PACmoveUP(void)
00453 {
00454     while(clearUP && !win)
00455     {
00456         lcd_mutex.lock();
00457         uLCD.filled_circle(x,y,PAC_SIZE,BLACK);
00458         lcd_mutex.unlock();
00459         if(y<4)
00460         {
00461             y = 128;
00462         }
00463         y = y-STEP_SIZE;
00464         changeCOINS();
00465         if(y%(2*STEP_SIZE) == 0)
00466         {
00467             lcd_mutex.lock();
00468             uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
00469             uLCD.filled_rectangle(x-2,y-2,x+2,y-PAC_SIZE,BLACK);
00470             lcd_mutex.unlock();
00471         }
00472         else
00473         {
00474             lcd_mutex.lock();
00475             uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
00476             uLCD.filled_rectangle(x,y-2,x+1,y-PAC_SIZE,BLACK);
00477             lcd_mutex.unlock();
00478         }
00479         
00480         CHECKclearUP();
00481         Thread::wait(10);
00482         break;
00483     }
00484 }
00485 
00486 //Move Pacman down
00487 void PACmoveDOWN(void)
00488 {
00489     while(clearDOWN && !win)
00490     {
00491         lcd_mutex.lock();
00492         uLCD.filled_circle(x,y,PAC_SIZE,BLACK);
00493         lcd_mutex.unlock();
00494         if(y>124)
00495         {
00496             y = 0;
00497         }
00498         y = y+STEP_SIZE;
00499         changeCOINS();
00500         if(y%(2*STEP_SIZE) == 0)
00501         {
00502             lcd_mutex.lock();
00503             uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
00504             uLCD.filled_rectangle(x-2,y+2,x+2,y+PAC_SIZE,BLACK);
00505             lcd_mutex.unlock();
00506         }
00507         else
00508         {
00509             lcd_mutex.lock();
00510             uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
00511             uLCD.filled_rectangle(x,y+2,x+1,y+PAC_SIZE,BLACK);
00512             lcd_mutex.unlock();
00513         }
00514         
00515         CHECKclearDOWN();
00516         Thread::wait(10);
00517         break;
00518     }
00519 }
00520 
00521 //Read the input from pushbuttons
00522 void checkMOVE(void)
00523 {
00524     if(!right_pb) {
00525         CHECKclearRIGHT();
00526         PACmoveRIGHT();
00527     } else if(!left_pb) {
00528         CHECKclearLEFT();
00529         PACmoveLEFT();
00530     } else if(!up_pb){
00531         CHECKclearUP();
00532         PACmoveUP();
00533     } else if(!down_pb){
00534         CHECKclearDOWN();
00535         PACmoveDOWN();
00536     }
00537 }
00538 
00539 //Draw the boudaries for the game using the uLCD graphics commands
00540 void drawBORDERS(void)
00541 {
00542     //Outer Border
00543     uLCD.rectangle(4,4,124,124,RED);
00544     uLCD.line(8,8,8,120,RED);
00545     uLCD.line(8,8,62,8,RED);
00546     uLCD.line(62,8,62,32,RED);
00547     uLCD.line(62,32,66,32,RED);
00548     uLCD.line(66,32,66,8,RED);
00549     uLCD.line(66,8,120,8,RED);
00550     uLCD.line(120,8,120,120,RED);
00551     uLCD.line(120,120,66,120,RED);
00552     uLCD.line(66,120,66,96,RED);
00553     uLCD.line(66,96,62,96,RED);
00554     uLCD.line(62,96,62,120,RED);
00555     uLCD.line(62,120,8,120,RED);
00556     //Inner Rectangle
00557     uLCD.rectangle(52,52,76,76,RED);
00558     uLCD.rectangle(48,48,80,80,RED);
00559     //Upper Left Corner
00560     uLCD.line(48,24,24,24,RED);
00561     uLCD.line(24,24,24,56,RED);
00562     uLCD.line(24,56,32,56,RED);
00563     uLCD.line(32,56,32,32,RED);
00564     uLCD.line(32,32,48,32,RED);
00565     uLCD.line(48,32,48,24,RED);
00566     //Upper Right Corner
00567     uLCD.line(80,24,104,24,RED);
00568     uLCD.line(104,24,104,56,RED);
00569     uLCD.line(104,56,96,56,RED);
00570     uLCD.line(96,56,96,32,RED);
00571     uLCD.line(96,32,80,32,RED);
00572     uLCD.line(80,32,80,24,RED);
00573     //Lower Left Corner
00574     uLCD.line(48,104,24,104,RED);
00575     uLCD.line(24,104,24,72,RED);
00576     uLCD.line(24,72,32,72,RED);
00577     uLCD.line(32,72,32,96,RED);
00578     uLCD.line(32,96,48,96,RED);
00579     uLCD.line(48,96,48,104,RED);
00580     //Lower Right Corner
00581     uLCD.line(80,104,104,104,RED);
00582     uLCD.line(104,104,104,72,RED);
00583     uLCD.line(104,72,96,72,RED);
00584     uLCD.line(96,72,96,96,RED);
00585     uLCD.line(96,96,80,96,RED);
00586     uLCD.line(80,96,80,104,RED);
00587 }
00588 
00589 void placeCOINS(void)
00590 {
00591     for(int j=0; j<81; j++)
00592     {
00593         uLCD.filled_circle(coins[j][0],coins[j][1],1,0xFFFF00);     //Draw the coins in their initial locations
00594     }
00595 }
00596 
00597 //Draw all the initial states of the game
00598 void initialize(void)
00599 {
00600     drawBORDERS();
00601     placeCOINS();
00602     uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
00603     uLCD.filled_rectangle(x-2,y-2,x-PAC_SIZE,y+2,BLACK);
00604 }
00605 
00606 //Check to see if all the coins have been eaten
00607 void checkWIN(void)
00608 {
00609     win = true;
00610     for(int k=0; k<81; k++)
00611     {
00612         lcd_mutex.lock();
00613         if(coins[k][0]!=64 || coins[k][1]!=64)  //Check the locations of all coins and if 1 has coordinates other than (64,64) the user has not won
00614         {
00615             win = false;
00616         }
00617         lcd_mutex.unlock();
00618     }
00619 }
00620 
00621 //Thread supervising the joystick inputs and moving Pacman accordingly
00622 void pacMOVE(void const *args)
00623 {
00624     while(!win)
00625     {
00626         checkMOVE();
00627         Thread::wait(1);
00628     }
00629 }
00630 
00631 //Thread controlling the movement of the blue ghost
00632 void blueGHOST(void const *args)
00633 {
00634     while(!win)
00635     {
00636         pickMOVE();
00637     }
00638 }
00639 
00640 int main()
00641 {
00642     left_pb.mode(PullUp);  // The variable left_pb will be zero when the pushbutton for moving the player left is pressed    
00643     right_pb.mode(PullUp); // The variable rightt_pb will be zero when the pushbutton for moving the player right is pressed        
00644     up_pb.mode(PullUp);    // the variable fire_pb will be zero when the pushbutton for firing a missile is pressed
00645     down_pb.mode(PullUp);  // the variable fire_pb will be zero when the pushbutton for firing a missile is pressed
00646     uLCD.cls();
00647     uLCD.baudrate(BAUD_3000000);
00648     initialize();                   // Draw the level setup
00649     Thread pm(pacMOVE);             // Start the thread for moving Pacman
00650     Thread bg(blueGHOST);           // Start the thread for moving the blue ghost
00651     
00652     Thread::wait(3000000000);       // Wait some time before checking the win conditions since it will take around 30 secs to eat all 81 coins
00653     while(!win)                     // Check to see if there was a win once every  tenth of a second
00654     {
00655         checkWIN();
00656         Thread::wait(1);
00657     }
00658     
00659     Thread::wait(500);              // Wait .5 second before displaying end message
00660     
00661     if(lose)                        // Print game over message if lose (determined in the follow function)
00662     {
00663         uLCD.cls();
00664         uLCD.printf("Sorry\nGame Over");
00665     }
00666     else
00667     {
00668         uLCD.cls();
00669         uLCD.printf("Congratulations!\nYou Won!");
00670     }
00671     
00672     
00673     while(1){Thread::wait(1);}
00674 }