Richmond Sua / Mbed 2 deprecated Lab4_Whack-A-Mole_4_final

Dependencies:   4DGL-uLCD-SE mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 //Whack-a-mole with LCD and touch keypad
00002 
00003 #include "mbed.h"
00004 #include "uLCD_4DGL.h"  /*LCD*/
00005 #include <mpr121.h>     /*touch keypad*/
00006 
00007 #include <stdio.h>      /* printf, scanf, puts, NULL */
00008 #include <stdlib.h>     /* srand, rand */
00009 #include <time.h>       /* time */
00010 #include <math.h>       /* log2 */
00011 
00012 
00013 
00014 #define REFRESH_TIME_MS 2000
00015 
00016 //Mole locations
00017 #define X1 1
00018 #define X2 43
00019 #define X3 85
00020 #define Y1 0
00021 #define Y2 30
00022 #define Y3 60
00023 #define Y4 90
00024 
00025 PwmOut vib(p21); //vibration motor
00026 Serial pc(USBTX, USBRX);
00027 uLCD_4DGL lcd(p28, p27, p30);
00028 
00029 AnalogIn random_analog(A0);
00030 
00031 // Create the interrupt receiver object on pin 26 -->> for keypad
00032 InterruptIn interrupt(p26);
00033 
00034 // Setup the i2c bus on pins 28 and 27 -->> for keypad
00035 I2C i2c(p9, p10);
00036 
00037 // Setup the Mpr121:
00038 // constructor(i2c object, i2c address of the mpr121) -->> for keypad
00039 Mpr121 mpr121(&i2c, Mpr121::ADD_VSS);
00040 
00041 //Timer
00042 Timer t; //for function use
00043 Timer gametime; //for int main() use
00044 Timer again; //for restart countdown
00045 
00046 //global variables accessable to all functions
00047 //mole locations
00048 int hole = 0;   //hole number
00049 int x = 0;      //coordinate values (not actual pixel values)
00050 int y = 0;
00051 //score
00052 int value = 0;
00053 int keynum = 0;
00054 int hit = 0;
00055 int miss = 0;
00056 int highest = 0;
00057 
00058 bool isMoleAlive = 0;
00059 
00060 
00061 // initializes screen with 12 empty mole holes
00062 void allempty() 
00063 {
00064     lcd.cls();
00065     
00066     //choose empty mole hole picture and intialize variables for while function
00067     lcd.set_sector_address(0x0000, 0x0000);
00068     int i = 0;
00069     int k = 1;
00070     int x = 0;
00071     int y = 1;
00072     
00073     //print 12 empty mole holes
00074     while(i < 12)
00075     {   
00076         lcd.locate(0,15);
00077         lcd.display_image(x, y);
00078         if ( k < 3 ) 
00079         {   x += 42;
00080             k++;        }
00081         else 
00082         {   k = 1;
00083             x = 0; 
00084             y += 30;    }   
00085         i++;
00086     }
00087     
00088     //count down to start of game
00089     int z = 3;
00090     lcd.locate(4, 15);
00091     lcd.printf("Get Ready!");
00092     wait(1);
00093     while (z > 0)
00094     {
00095         lcd.locate(4, 15);
00096         lcd.printf("     %d       ", z);
00097         wait(1);
00098         z--;
00099     }
00100     lcd.locate(5, 15);
00101     lcd.printf("   Go!     ");
00102     wait(0.5);
00103 }    
00104 
00105 //revised modulus operator created to work correctly with negative modulus
00106 int mod (int x1, int x2)
00107 {
00108     if(x1 < 0) { return (x1 % x2)+x2; }
00109     else { return x1 % x2; }
00110 }
00111 
00112 //pop / show the mole
00113 void popup()
00114 {
00115     isMoleAlive = 1;
00116     
00117     //generate random int 0 to 11
00118     hole = rand() % 12;
00119     
00120     //use random number to match x and y coordinate of touchpad
00121     if (hole < 4)       { x = 0;}
00122     else if (hole < 8)  { x = 1;}
00123     else                { x = 2;}
00124     y = mod(4-(1+mod(hole, 4)), 4);    
00125         
00126     //pop up mole corresponding to that hole number
00127     lcd.set_sector_address(0x0000, 0x0005);
00128     lcd.display_image(x*42, y*30);
00129     
00130     //testing purposes only
00131         //lcd.locate(0,15);
00132         //lcd.printf("r:%d,   x:%d,   y:%d\n", hole, x, y);
00133     
00134     highest++; //highest possible number of hits
00135     
00136     lcd.locate(0,15);
00137     //lcd.printf("H:%d Hit:%d, Miss:%d", keynum, hit, miss);
00138 }
00139 
00140 //hide a mole
00141 void hide()
00142 {
00143     isMoleAlive = 0;
00144     vib = 0;
00145     //reseting the mole hole to empty hole
00146     lcd.set_sector_address(0x0000, 0x0000);
00147     lcd.display_image(x*42, y*30);
00148 }
00149 
00150 //to convert keypad
00151 int mylog2(int arg)
00152 {
00153         //creating log 2 
00154         int squared = 1;
00155         int tmp = 0; //log 2 value
00156         for ( ; squared < arg; )  //( squared != arg )
00157         {
00158             squared = squared * 2;
00159             tmp++;
00160         }
00161         if (squared == arg)
00162         {
00163             return tmp;     //keynum = tmp;
00164         }
00165         return keynum;      //return same in case more than one pad is touched.
00166 }
00167     
00168 void keyInterrupt() {
00169     
00170     value=mpr121.read(0x00);
00171     value +=mpr121.read(0x01)<<8;
00172     // LED demo mod by J. Hamblen
00173     pc.printf("MPR value: %d \r\n", value);
00174     
00175     
00176     //Did the hammer hit the mole?
00177     if (value != 0)     //ignore the release
00178     {
00179         //Converting to keynum
00180         keynum = mylog2(value);
00181         
00182         //hit or miss
00183         if ( keynum == hole && isMoleAlive )   //If the hammer hit the mole
00184         {
00185             hit++;
00186             vib = 1;
00187             lcd.set_sector_address(0x0000, 0x000A);
00188             lcd.display_image(x*42, y*30);
00189             isMoleAlive = 0;
00190         }
00191         else
00192         {
00193             miss++;
00194         }
00195         
00196 
00197     }
00198     
00199 }
00200 
00201 
00202 
00203 //initialize lcd screen
00204 void setup()
00205 {
00206     interrupt.fall(&keyInterrupt);
00207     interrupt.mode(PullUp);
00208     
00209     srand (random_analog * 100000);
00210     
00211     lcd.baudrate(3000000);
00212     lcd.background_color(0x029142);
00213     lcd.textbackground_color(0x029142);
00214     lcd.cls();
00215     lcd.media_init();
00216     lcd.color(WHITE);
00217     lcd.set_font(FONT_7X8);
00218     lcd.text_bold(ON);
00219 }
00220 
00221 //printing score
00222 void printScore()
00223 {
00224     lcd.locate(0,15);
00225     lcd.printf("->%d ", keynum);
00226     lcd.locate(8,15);           
00227     lcd.printf("+%d  ", hit);
00228     lcd.locate(15,15);
00229     lcd.printf("-%d  ", miss);
00230 }
00231 
00232 //function to endgame and print final score
00233 void endgame()
00234 {
00235     //displaying final score
00236     lcd.cls();
00237     lcd.text_width(1.5); 
00238     lcd.text_height(1.5);
00239     lcd.color(WHITE);
00240     lcd.locate(0,1);
00241     lcd.printf("    FINAL SCORE\n");
00242     lcd.printf("------------------\n");
00243     lcd.locate(1,4);
00244     lcd.printf("%d HITS", hit);
00245     lcd.locate(1,7);
00246     lcd.printf("%d MISSES \n\n------------------", miss);
00247     
00248     //print a commentary based on player's score
00249     double grade = 100*(hit-(0.25*miss))/highest;
00250     lcd.locate(0,12);
00251     if (grade < 20) {lcd.printf("  WOW.. YOU SUCK");}
00252     else if (grade < 50) {lcd.printf("    TRY HARDER");}
00253     else if (grade < 80) {lcd.printf("   YOU DID OKAY");}
00254     else if (grade < 90) {lcd.printf("    NICE JOB!!");}
00255     else if (grade < 100) {lcd.printf("    GRRRREAT!!");}
00256     else if (grade == 100) 
00257         {
00258             lcd.locate(0, 11);
00259             lcd.printf("    /\\/\\/\\/\\/\\ \n");
00260             lcd.printf("   |          |\n");
00261             lcd.printf("   | MOLE GOD |\n");
00262             lcd.printf("   |__________|\n");
00263         }
00264 }
00265 
00266 //function to restart another game
00267 bool restart()
00268 {
00269     
00270     bool replay = false;
00271     
00272     //reset score
00273     hit = miss = highest = 0;
00274     
00275     //clear screen for restart prompt
00276     lcd.cls();
00277     lcd.locate(0,1);
00278     lcd.text_height(2);
00279     lcd.text_width(2);
00280     lcd.printf(" ANOTHER   GAME?  \nPRESS ANY   KEY   \n");
00281     
00282     again.start();
00283     int countdown;
00284     //waiting for key press
00285     while(again.read() < 10 && replay == false)
00286     {
00287         countdown = 10 - (int)again.read();
00288         //countdown: user has 10 seconds to replay 
00289         lcd.locate(0,7);
00290         lcd.printf("    %d    ", countdown);
00291                 
00292         //check for key press
00293         if(value != 0)
00294         {
00295             //user has pressed a key and wants to play again!
00296             replay = true;
00297             break;
00298         }
00299         
00300     }
00301     
00302     again.stop();
00303     again.reset();
00304     return replay;
00305 }
00306 
00307 
00308 //////////////////////////////////////////////////
00309 ////////////####main####//////////////
00310 int main()
00311 {   
00312     bool keepplaying = 1;
00313     
00314     //initializing...
00315     setup(); 
00316     
00317     while(keepplaying == true)
00318     {   //starting the game - 30 seconds for testing
00319         allempty();
00320         gametime.reset();
00321         gametime.start();
00322         float timelimit;
00323         float overalltime = 20;
00324         
00325         while (gametime.read() < overalltime) 
00326         { 
00327             popup();
00328             
00329             //reduce time limit as game progresses
00330             if (gametime.read() < overalltime/3)       { timelimit = 2; }
00331             else if (gametime.read() < overalltime/2)  { timelimit = 1.6;   }
00332             else if (gametime.read() < overalltime/1.5)  { timelimit = 1.2; }
00333             else if (gametime.read() < overalltime/1.3)  { timelimit = 1;   }
00334             else if (gametime.read() < overalltime/1.1)  { timelimit = 0.8; }
00335             else if (gametime.read() < overalltime)  { timelimit = 0.65;} 
00336                 
00337             wait(timelimit);
00338             
00339             if (isMoleAlive == 1)
00340             {
00341                 miss++;
00342             }
00343             
00344             hide();
00345             printScore();
00346             
00347         }
00348             
00349             gametime.stop();
00350             endgame();
00351             wait(3);
00352             keepplaying = restart();
00353             
00354             
00355     }
00356         
00357     lcd.cls();
00358     lcd.locate(0,2);
00359     lcd.text_height(2);
00360     lcd.text_width(2);
00361     lcd.printf(" THANKS\n");
00362     lcd.printf("   FOR\n\n");
00363     lcd.printf(" PLAYING\n");
00364     
00365 }
00366 
00367     
00368     
00369