team krichilichanga / Mbed 2 deprecated Memory_Card_Game

Dependencies:   Memory_Card_Game SDFileSystem mbed

Dependents:   Memory_Card_Game

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

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 }