Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: 4DGL-uLCD-SE mbed
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
Generated on Sun Jul 17 2022 23:18:29 by
1.7.2