Code for 4180 mini project

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

Fork of Pacman by Shawn Rigdon

Revision:
1:b86030cf57c4
Parent:
0:0a900ff9a788
Child:
2:610d5194c64e
--- a/main.cpp	Tue Mar 25 04:36:32 2014 +0000
+++ b/main.cpp	Tue Mar 25 18:49:05 2014 +0000
@@ -1,29 +1,35 @@
+/*
+So far, this program will run through one level of what will hopefully be a full Pacman game.
+As of now, only Pacman will run all the way through, so the thread to start the blue ghost has
+been commented out.  This program only runs through one level of the game.
+*/
+
 #include "mbed.h"
 #include "rtos.h"
 #include "uLCD_4DGL.h"
 
-#define PAC_SIZE    5
-#define STEP_SIZE   8
-#define CLEARANCE   12
+#define PAC_SIZE    5   //The radius of Pacman and the ghost
+#define STEP_SIZE   8   //The number of pixels each character moves at once
+#define CLEARANCE   12  //The number of pixels each character checks ahead before moving
 
 AnalogIn jsx(p19);  // The joysticks origin is about 1.6V in both directions
-AnalogIn jsy(p20);  // For just three states in each direction use thresholds 1.1V and 2V
+AnalogIn jsy(p20);  // For just three states in each direction, thresholds .33V and 3V were used
 uLCD_4DGL uLCD(p28, p27, p29);
 Mutex lcd_mutex;
 
-void checkMOVE(void);
+void checkMOVE(void);   //This function is defined below.  It was written here since other functions return to it that it also calls.
 
-volatile bool win=false;
-volatile bool lose=false;
-volatile int x = 64;
+//several variables are used by multiple threads
+volatile bool win=false;    //True when pacman has eaten all coins
+volatile bool lose=false;   //True when the position of the ghost and pacman are the same
+volatile int x = 64;        //x and y are pacman's position.  The starting position is defined here.
 volatile int y = 88;
-//volatile int x = 0;
-//volatile int y = 0;
-volatile int gx1 = 64;
+volatile int gx1 = 64;      //Starting position of the blue ghost
 volatile int gy1 = 40;
-volatile int pixel;
 int i;
 bool clearRIGHT,clearLEFT,clearUP,clearDOWN,bgcr,bgcl,bgcu,bgcd;
+
+//An array containing the locations of the 81 coins pacman must eat
 int coins[81][2] = {
         {40,88},{48,88},{56,88},{72,88},{80,88},{88,88},
         {40,40},{48,40},{56,40},{64,40},{72,40},{80,40},{88,40},
@@ -45,19 +51,21 @@
         {72,24},{72,32}
     };
 
+//This function is used in the ghost thread to replace coins as it passes over them
 void replaceCOINS(void)
 {
     for(int n=0; n<81; n++)
     {
-        lcd_mutex.lock();
+        lcd_mutex.lock();   //The coins array is used by both threads
         if(gx1 == coins[n][0] && gy1 == coins[n][1])
         {
-            uLCD.filled_circle(gx1,gy1,1,0xFFFF00);    
+            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   
         }
         lcd_mutex.unlock();
     }
 }
 
+//Checks if the ghost can move right (there is no boundary immediately to the right)
 void BGclearRIGHT(void)
 {
     bgcr = true;
@@ -66,12 +74,13 @@
         lcd_mutex.lock();
         if(uLCD.read_pixel(p,gy1)==uLCD.read_pixel(4,4))
         {
-            bgcr = false;
-        }
+            bgcr = false;   //compare the pixels immediately in front of the ghost to the boundary up to the spec. clearance
+        }                   //if they are the same color, determine the ghost can't move right
         lcd_mutex.unlock();
     }
 }
 
+//Checks if ghost can move left
 void BGclearLEFT(void)
 {
     bgcl = true;
@@ -86,6 +95,7 @@
     }
 }
 
+//Checks if ghost can move up
 void BGclearUP(void)
 {
     bgcu = true;
@@ -100,6 +110,7 @@
     }
 }
 
+//Checks if ghost can move down
 void BGclearDOWN(void)
 {
     bgcd = true;
@@ -114,19 +125,21 @@
     }
 }
 
+//Moves the blue ghost to the right
 void bgRIGHT(void)
 {
     Thread::wait(50);
     lcd_mutex.lock();
-    uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK);
+    uLCD.filled_rectangle(gx1-PAC_SIZE,gy1-PAC_SIZE,gx1+PAC_SIZE,gy1+PAC_SIZE,BLACK);   //erase the previous ghost drawing
     lcd_mutex.unlock();
-    replaceCOINS();
-    if(gx1>124)
+    replaceCOINS();     //replace the coin the ghost was just on if there was one
+    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
     {
         gx1 = 0;
     }
-    gx1 = gx1+STEP_SIZE;
+    gx1 = gx1+STEP_SIZE;    //Move one step size in the x direction
     lcd_mutex.lock();
+    //redraw the ghost at the new position
     uLCD.filled_circle(gx1,gy1,PAC_SIZE,BLUE);
     uLCD.filled_rectangle(gx1-PAC_SIZE,gy1,gx1+PAC_SIZE,gy1+PAC_SIZE,BLUE);
     uLCD.filled_circle(gx1+2,gy1-2,1,BLACK);
@@ -134,6 +147,7 @@
     lcd_mutex.unlock();
 }
 
+//Moves the blue ghost left
 void bgLEFT(void)
 {
     Thread::wait(50);
@@ -154,6 +168,7 @@
     lcd_mutex.unlock();
 }
 
+//Moves the blue ghost up
 void bgUP(void)
 {
     Thread::wait(50);
@@ -174,6 +189,7 @@
     lcd_mutex.unlock();
 }
 
+//Moves the blue ghost down
 void bgDOWN(void)
 {
     Thread::wait(50);
@@ -194,16 +210,17 @@
     lcd_mutex.unlock();
 }
 
+//Force ghost to chase Pacman
 void follow(void)
 {
-    if(x==gx1 && y==gy1)
+    if(x==gx1 && y==gy1)    //if the ghost and Pacman are at the same position trigger losing condition
     {
-        win = true;
+        win = true;         //This is set to true just to exit the check for a win loop and terminate other loops without writing additional conditions
         lose = true;
     }
-    while(x==gx1 && gy1<y && !win)
+    while(x==gx1 && gy1<y && !win)  //If the ghost is directly above Pacman check to see if moving down is possible, then move down
     {
-        BGclearDOWN();
+        BGclearDOWN();  
         bgDOWN();
     }
     while(x==gx1 && gy1>y && !win)
@@ -223,19 +240,18 @@
     }
 }
 
+//Ghost selects a direction to move
 void pickMOVE(void)
 {
-    while((gx1==x || gy1==y) && abs(x-gx1)+abs(y-gy1)<=16 && !win)
+    while((gx1==x || gy1==y) && abs(x-gx1)+abs(y-gy1)<=16 && !win)  //If Pacman is close by give chase
     {
         follow();
-        //Thread::wait(100);
     }
-    int dec = rand()%4;
-    //int dec = 0;
+    int dec = rand()%4; //randomly generate a number from the set 0,1,2,3, which serves as the direction decision
     if(dec == 0)
     {
         BGclearRIGHT();
-        while(bgcr && !win)
+        while(bgcr && !win)     //If decision 0 was reached, check to the the move right until a boundary is reached
         {
             bgRIGHT();
             BGclearRIGHT();
@@ -270,6 +286,7 @@
     }
 }        
 
+//Check if Pacman can move one step size to the right (Essentially the same as checking for the ghost)
 void CHECKclearRIGHT(void)
 {
     clearRIGHT = true;
@@ -284,6 +301,7 @@
     }
 }
 
+//Check if Pacman can move left
 void CHECKclearLEFT(void)
 {
     clearLEFT = true;
@@ -298,6 +316,7 @@
     }
 }
 
+//Check if Pacman can move up
 void CHECKclearUP(void)
 {
     clearUP = true;
@@ -312,6 +331,7 @@
     }
 }
 
+//Check if Pacman can move down
 void CHECKclearDOWN(void)
 {
     clearDOWN = true;
@@ -326,35 +346,37 @@
     }
 }
 
+//This function tracks the coin Pacman eats as he passes over it
 void changeCOINS(void)
 {
     for(int m=0; m<81; m++)
     {
         lcd_mutex.lock();
-        if(x == coins[m][0] && y == coins[m][1])
+        if(x == coins[m][0] && y == coins[m][1])    //Compare Pacman's position to the set of coins
         {
-            coins[m][0]=64;
-            coins[m][1]=64;
+            coins[m][0]=64;                         //If there is a match, change that coins location to the center of the board where Pacman
+            coins[m][1]=64;                         //cannot go, but do not draw the coin
         }
         lcd_mutex.unlock();
     }
 }
 
+//Move Pacman one step size to the right
 void PACmoveRIGHT(void)
 {
-    while(clearRIGHT && !win)
+    while(clearRIGHT && !win)   //Not win indicates the game has not ended
     {
         lcd_mutex.lock();
-        uLCD.filled_circle(x,y,PAC_SIZE,BLACK);
+        uLCD.filled_circle(x,y,PAC_SIZE,BLACK);     //Erase Pacman at his last location
         lcd_mutex.unlock();
-        if(x>124)
+        if(x>124)       //wrap around if moving off the board
         {
             x = 0;
         }
-        x = x+STEP_SIZE;
-        changeCOINS();
+        x = x+STEP_SIZE;    //move Pacman one step size to the right
+        changeCOINS();  //Track the coin that was eaten at the last location
         
-        if(x%(2*STEP_SIZE) == 0)
+        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.
         {
             lcd_mutex.lock();
             uLCD.filled_circle(x,y,PAC_SIZE,0xFFFF00);
@@ -368,15 +390,16 @@
             uLCD.filled_rectangle(x+2,y,x+PAC_SIZE,y+1,BLACK);
             lcd_mutex.unlock();
         }
-        if(jsx <= .75)
+        if(jsx <= .9)       //If the user is still holding the joystick to the right, remain in this loop
         {
             checkMOVE();
         }
-        CHECKclearRIGHT();
+        CHECKclearRIGHT();  //If the user remains in the loop, check for a boundary to the right
         Thread::wait(10);
     }
 }
 
+//Move Pacman left
 void PACmoveLEFT(void)
 {
     while(clearLEFT && !win)
@@ -413,6 +436,7 @@
     }
 }
 
+//Move Pacman up
 void PACmoveUP(void)
 {
     while(clearUP && !win)
@@ -449,6 +473,7 @@
     }
 }
 
+//Move Pacman down
 void PACmoveDOWN(void)
 {
     while(clearDOWN && !win)
@@ -485,6 +510,8 @@
     }
 }
 
+//Read the input from the joystick and select a direction to move
+//The thresholds are set near the end of their ranges to eliminate unintentional moves as much as possible
 void checkMOVE(void)
 {
     if(jsx > .9)
@@ -509,6 +536,7 @@
     }
 }
 
+//Draw the boudaries for the game using the uLCD graphics commands
 void drawBORDERS(void)
 {
     //Outer Border
@@ -562,10 +590,11 @@
 {
     for(int j=0; j<81; j++)
     {
-        uLCD.filled_circle(coins[j][0],coins[j][1],1,0xFFFF00);
+        uLCD.filled_circle(coins[j][0],coins[j][1],1,0xFFFF00);     //Draw the coins in their initial locations
     }
 }
 
+//Draw all the initial states of the game
 void initialize(void)
 {
     drawBORDERS();
@@ -574,13 +603,14 @@
     uLCD.filled_rectangle(x-2,y-2,x-PAC_SIZE,y+2,BLACK);
 }
 
+//Check to see if all the coins have been eaten
 void checkWIN(void)
 {
     win = true;
     for(int k=0; k<81; k++)
     {
         lcd_mutex.lock();
-        if(coins[k][0]!=64 || coins[k][1]!=64)
+        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
         {
             win = false;
         }
@@ -588,6 +618,7 @@
     }
 }
 
+//Thread supervising the joystick inputs and moving Pacman accordingly
 void pacMOVE(void const *args)
 {
     while(!win)
@@ -597,6 +628,7 @@
     }
 }
 
+//Thread controlling the movement of the blue ghost
 void blueGHOST(void const *args)
 {
     while(!win)
@@ -608,29 +640,21 @@
 int main()
 {
     uLCD.cls();
-    //uLCD.background_color(DGREY);
     uLCD.baudrate(BAUD_3000000);
-    //int x=64,y=64,
-    //int xy[2]={64,64};
-    //Thread t1(thread1,&x1,&y1);
-    initialize();
-    Thread pm(pacMOVE);
-    Thread bg(blueGHOST);
-    //Thread clr(clear);
-    //pixel = uLCD.read_pixel(128,128);
-    //for(int k=0; k<10; k++){
-    //i = rand();
-    //uLCD.printf("rand = %d\n",rand());
-    Thread::wait(5000);
+    initialize();                   //Draw the level setup
+    Thread pm(pacMOVE);             //Start the thread for moving Pacman
+    //Thread bg(blueGHOST);         //Start the thread for moving the blue ghost
     
-    while(!win)
+    Thread::wait(5000);             //Wait some time before checking the win conditions since it will take around 30 secs to eat all 81 coins
+    while(!win)                     //Check to see if there was a win once every  tenth of a second
     {
         checkWIN();
-        Thread::wait(1000);
+        Thread::wait(100);
     }
-    //uLCD.printf("WIN");
-    Thread::wait(1000);
-    if(lose)
+    
+    Thread::wait(1000);             //Wait one second before displaying end message
+    
+    if(lose)                        //Print game over message if lose (determined in the follow function)
     {
         uLCD.cls();
         uLCD.printf("Sorry\nGame Over");
@@ -638,8 +662,6 @@
     else
     {
         uLCD.cls();
-        //uLCD.locate(60,60);
-        //uLCD.set_font_size(10,10);
         uLCD.printf("Congratulations!\nYou Won!");
     }