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: Memory_Card_Game SDFileSystem mbed
main.cpp
00001 // Authors: Kristen Fernandez, Krish Ravindranath 00002 // Target: MBED nxp lpc1768 00003 00004 #include "mbed.h" 00005 #include "SDFileSystem.h" 00006 #include "uLCD_4DGL.h" 00007 #include "wave_player.h" 00008 //#include <time.h> 00009 //#include "Nav_Switch.h" 00010 00011 AnalogOut DACout(p18); // used to play sound on speaker 00012 wave_player waver(&DACout); //wave player plays a *.wav file to D/A and a PWM 00013 uLCD_4DGL uLCD(p28,p27,p26); // serial tx, serial rx, reset pin; 00014 SDFileSystem sd(p11, p12, p13, p14, "sd"); //SD card setup 00015 00016 // Function to play wav file 00017 void playSound(char * wav); 00018 void playSound(char * wav) 00019 { 00020 // open wav file 00021 FILE *wave_file; 00022 wave_file=fopen(wav,"r"); 00023 00024 // play wav file 00025 waver.play(wave_file); 00026 00027 // close wav file 00028 fclose(wave_file); 00029 } 00030 00031 // Navigation switch class 00032 class Nav_Switch 00033 { 00034 public: 00035 Nav_Switch(PinName up,PinName down,PinName left,PinName right,PinName fire); 00036 int read(); 00037 //boolean functions to test each switch 00038 bool up(); 00039 bool down(); 00040 bool left(); 00041 bool right(); 00042 bool fire(); 00043 //automatic read on RHS 00044 operator int (); 00045 //index to any switch array style 00046 bool operator[](int index) { 00047 return _pins[index]; 00048 }; 00049 private: 00050 BusIn _pins; 00051 00052 }; 00053 Nav_Switch::Nav_Switch (PinName up,PinName down,PinName left,PinName right,PinName fire): 00054 _pins(up, down, left, right, fire) 00055 { 00056 _pins.mode(PullUp); //needed if pullups not on board or a bare nav switch is used - delete otherwise 00057 wait(0.001); //delays just a bit for pullups to pull inputs high 00058 } 00059 inline bool Nav_Switch::up() 00060 { 00061 return !(_pins[0]); 00062 } 00063 inline bool Nav_Switch::down() 00064 { 00065 return !(_pins[1]); 00066 } 00067 inline bool Nav_Switch::left() 00068 { 00069 return !(_pins[2]); 00070 } 00071 inline bool Nav_Switch::right() 00072 { 00073 return !(_pins[3]); 00074 } 00075 inline bool Nav_Switch::fire() 00076 { 00077 return !(_pins[4]); 00078 } 00079 inline int Nav_Switch::read() 00080 { 00081 return _pins.read(); 00082 } 00083 inline Nav_Switch::operator int () 00084 { 00085 return _pins.read(); 00086 } 00087 00088 //up, down, left, right, center 00089 Nav_Switch myNav( p9, p6, p7, p5, p8); 00090 00091 Timer t; 00092 00093 // Game Variables 00094 const int BLOCK_SIDE = 29; // side of card 00095 const int BUFFER = 5; // space between cards 00096 const int NUM_ROWS = 4; // num of rows and also columns since it's a square grid 00097 int score = 0; // initialize score 00098 float time_limit = 60.0; // set time limit 00099 00100 bool start_game = 1; // Determines if it is the start of the game 00101 typedef enum { 00102 red_circle, blue_circle, green_circle, pink_circle, red_square, blue_square, green_square, pink_square 00103 } shapes; 00104 int final_shapes[4][4] = {red_circle, blue_circle, green_circle, pink_circle, red_square, blue_square, green_square, pink_square, red_circle, blue_circle, green_circle, pink_circle, red_square, blue_square, green_square, pink_square}; 00105 int temp_shape; // temp shape array 00106 int block_arr[NUM_ROWS][NUM_ROWS] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; 00107 int current_x = 0; 00108 int current_y = 0; 00109 int prev_x = 0; 00110 int prev_y = 0; 00111 int num_flips = 0; 00112 int current_shape = 0; 00113 int prev_shape = 0; 00114 int k = 0; 00115 int main() { 00116 t.start(); 00117 while(score<8 && t.read() < time_limit) { 00118 if (start_game) { 00119 //set_time(1256729737); 00120 srand(time(0)); // create random seed so rand() will generate new random numbers each time 00121 for (int i = 0; i < NUM_ROWS; i++ ) { 00122 for (int j = 0; j < NUM_ROWS; j++ ) { 00123 // randomize elements within the array using "shuffle" algorithm 00124 int rand_x = rand() % 4; 00125 int rand_y = rand() % 4; 00126 int temp = final_shapes[i][j]; 00127 final_shapes[i][j] = final_shapes[rand_x][rand_y]; 00128 final_shapes[rand_x][rand_y] = temp; 00129 00130 // draw all white blocks 00131 uLCD.filled_rectangle(BUFFER + (j * BLOCK_SIDE), BUFFER + (i * BLOCK_SIDE), BLOCK_SIDE + (j * BLOCK_SIDE), BLOCK_SIDE + (i * BLOCK_SIDE), WHITE); 00132 } 00133 } 00134 uLCD.rectangle(BUFFER, BUFFER, BLOCK_SIDE, BLOCK_SIDE, RED); // initialize player at top left block 00135 start_game = 0; 00136 } 00137 uLCD.locate(0,15); 00138 uLCD.color(0xFFCCCC); 00139 uLCD.printf("Time left: %2.0F", time_limit - t.read()); 00140 00141 /* 00142 * Handle player input for movement 00143 */ 00144 00145 if (myNav.right() && current_x < NUM_ROWS - 1) { 00146 uLCD.rectangle(BUFFER + (current_x * BLOCK_SIDE), BUFFER + (current_y * BLOCK_SIDE), BLOCK_SIDE + (current_x * BLOCK_SIDE), BLOCK_SIDE + (current_y * BLOCK_SIDE), WHITE); 00147 current_x++; 00148 uLCD.rectangle(BUFFER + (current_x * BLOCK_SIDE), BUFFER + (current_y * BLOCK_SIDE), BLOCK_SIDE + (current_x * BLOCK_SIDE), BLOCK_SIDE + (current_y * BLOCK_SIDE), RED); 00149 // playSound("/sd/wavfiles/shoot.wav"); 00150 wait(.2); 00151 } 00152 if (myNav.left() && current_x > 0) { 00153 uLCD.rectangle(BUFFER + (current_x * BLOCK_SIDE), BUFFER + (current_y * BLOCK_SIDE), BLOCK_SIDE + (current_x * BLOCK_SIDE), BLOCK_SIDE + (current_y * BLOCK_SIDE), WHITE); 00154 current_x--; 00155 uLCD.rectangle(BUFFER + (current_x * BLOCK_SIDE), BUFFER + (current_y * BLOCK_SIDE), BLOCK_SIDE + (current_x * BLOCK_SIDE), BLOCK_SIDE + (current_y * BLOCK_SIDE), RED); 00156 wait(.2); 00157 } 00158 if (myNav.down() && current_y < NUM_ROWS - 1) { 00159 uLCD.rectangle(BUFFER + (current_x * BLOCK_SIDE), BUFFER + (current_y * BLOCK_SIDE), BLOCK_SIDE + (current_x * BLOCK_SIDE), BLOCK_SIDE + (current_y * BLOCK_SIDE), WHITE); 00160 current_y++; 00161 uLCD.rectangle(BUFFER + (current_x * BLOCK_SIDE), BUFFER + (current_y * BLOCK_SIDE), BLOCK_SIDE + (current_x * BLOCK_SIDE), BLOCK_SIDE + (current_y * BLOCK_SIDE), RED); 00162 wait(.2); 00163 } 00164 if (myNav.up() && current_y > 0) { 00165 uLCD.rectangle(BUFFER + (current_x * BLOCK_SIDE), BUFFER + (current_y * BLOCK_SIDE), BLOCK_SIDE + (current_x * BLOCK_SIDE), BLOCK_SIDE + (current_y * BLOCK_SIDE), WHITE); 00166 current_y--; 00167 uLCD.rectangle(BUFFER + (current_x * BLOCK_SIDE), BUFFER + (current_y * BLOCK_SIDE), BLOCK_SIDE + (current_x * BLOCK_SIDE), BLOCK_SIDE + (current_y * BLOCK_SIDE), RED); 00168 wait(.2); 00169 } 00170 00171 /* 00172 * When user clicks, draw the according shape from the final_shapes array in that spot 00173 */ 00174 if(myNav.fire() && num_flips < 2 && final_shapes[current_x][current_y]!= -1) { 00175 // keep track of shape's position from first click 00176 if(num_flips == 0) { 00177 prev_x = current_x; 00178 prev_y = current_y; 00179 } 00180 playSound("/sd/wavfiles/buttonpress.wav"); 00181 // fill block background with black 00182 uLCD.filled_rectangle(BUFFER + (current_x * BLOCK_SIDE), BUFFER + (current_y * BLOCK_SIDE), BLOCK_SIDE + (current_x * BLOCK_SIDE), BLOCK_SIDE + (current_y * BLOCK_SIDE), BLACK); 00183 prev_shape = current_shape; 00184 switch(final_shapes[current_x][current_y]) { 00185 case red_circle: 00186 uLCD.filled_circle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), 5, RED); 00187 current_shape = red_circle; 00188 break; 00189 case blue_circle: 00190 uLCD.filled_circle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), 5, BLUE); 00191 current_shape = blue_circle; 00192 break; 00193 case green_circle: 00194 uLCD.filled_circle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), 5, GREEN); 00195 current_shape = green_circle; 00196 break; 00197 case pink_circle: 00198 uLCD.filled_circle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), 5, PINK); 00199 current_shape = pink_circle; 00200 break; 00201 case red_square: 00202 uLCD.filled_rectangle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), BLOCK_SIDE - BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BLOCK_SIDE - BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), RED); 00203 current_shape = red_square; 00204 break; 00205 case green_square: 00206 uLCD.filled_rectangle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), BLOCK_SIDE - BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BLOCK_SIDE - BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), BLUE); 00207 current_shape = green_square; 00208 break; 00209 case blue_square: 00210 uLCD.filled_rectangle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), BLOCK_SIDE - BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BLOCK_SIDE - BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), GREEN); 00211 current_shape = blue_square; 00212 break; 00213 case pink_square: 00214 uLCD.filled_rectangle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), BLOCK_SIDE - BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BLOCK_SIDE - BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), PINK); 00215 current_shape = pink_square; 00216 break; 00217 default: 00218 uLCD.filled_circle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), 5, BLACK); 00219 break; 00220 } 00221 num_flips++; 00222 //wait(.2); 00223 } 00224 00225 // Prevents double click from registering as match 00226 if(num_flips == 2 && current_x == prev_x && current_y == prev_y){ 00227 num_flips--; 00228 } 00229 /* 00230 * After user flips 2 cards, check to see if they are correct 00231 */ 00232 if(num_flips == 2) { 00233 num_flips = 0; 00234 wait(.5); // seconds before shapes disappears (time to memorize shapes) 00235 00236 //user is correct (shapes match) 00237 if (prev_shape == current_shape) { 00238 // draws black rectangles over the two blocks so they go away 00239 uLCD.filled_rectangle(BUFFER + (prev_x * BLOCK_SIDE), BUFFER + (prev_y * BLOCK_SIDE), BLOCK_SIDE + (prev_x * BLOCK_SIDE), BLOCK_SIDE + (prev_y * BLOCK_SIDE), BLACK); 00240 uLCD.filled_rectangle(BUFFER + (current_x * BLOCK_SIDE), BUFFER + (current_y * BLOCK_SIDE), BLOCK_SIDE + (current_x * BLOCK_SIDE), BLOCK_SIDE + (current_y * BLOCK_SIDE), BLACK); 00241 playSound("/sd/wavfiles/supermissile.wav"); 00242 final_shapes[current_x][current_y] = -1; 00243 final_shapes[prev_x][prev_y] = -1; 00244 score++; 00245 } 00246 // user did not match shapes 00247 else { 00248 // draws white blocks back over them (back to unflipped) 00249 uLCD.filled_rectangle(BUFFER + (prev_x * BLOCK_SIDE), BUFFER + (prev_y * BLOCK_SIDE), BLOCK_SIDE + (prev_x * BLOCK_SIDE), BLOCK_SIDE + (prev_y * BLOCK_SIDE), WHITE); 00250 uLCD.filled_rectangle(BUFFER + (current_x * BLOCK_SIDE), BUFFER + (current_y * BLOCK_SIDE), BLOCK_SIDE + (current_x * BLOCK_SIDE), BLOCK_SIDE + (current_y * BLOCK_SIDE), WHITE); 00251 } 00252 uLCD.rectangle(BUFFER + (prev_x * BLOCK_SIDE), BUFFER + (prev_y * BLOCK_SIDE), BLOCK_SIDE + (prev_x * BLOCK_SIDE), BLOCK_SIDE + (prev_y * BLOCK_SIDE), WHITE); 00253 uLCD.rectangle(BUFFER + (current_x * BLOCK_SIDE), BUFFER + (current_y * BLOCK_SIDE), BLOCK_SIDE + (current_x * BLOCK_SIDE), BLOCK_SIDE + (current_y * BLOCK_SIDE), WHITE); 00254 } 00255 } 00256 // End Screen 00257 t.stop(); 00258 uLCD.cls(); 00259 uLCD.text_string("GAME OVER", 5, 5, FONT_7X8, 0xFFCCCC); 00260 uLCD.locate(5,8); 00261 uLCD.printf("Score = %D",score); 00262 }
Generated on Fri Aug 5 2022 04:42:34 by
1.7.2