ECE 4180 Spring 2016 Lab 4
Dependencies: Memory_Card_Game SDFileSystem mbed
main.cpp
- Committer:
- kravemind
- Date:
- 2016-03-14
- Revision:
- 6:88e284f2063c
- Parent:
- 5:6853dc5bd06d
File content as of revision 6:88e284f2063c:
// Authors: Kristen Fernandez, Krish Ravindranath // Target: MBED nxp lpc1768 #include "mbed.h" #include "SDFileSystem.h" #include "uLCD_4DGL.h" #include "wave_player.h" //#include <time.h> //#include "Nav_Switch.h" AnalogOut DACout(p18); // used to play sound on speaker wave_player waver(&DACout); //wave player plays a *.wav file to D/A and a PWM uLCD_4DGL uLCD(p28,p27,p26); // serial tx, serial rx, reset pin; SDFileSystem sd(p11, p12, p13, p14, "sd"); //SD card setup // Function to play wav file void playSound(char * wav); void playSound(char * wav) { // open wav file FILE *wave_file; wave_file=fopen(wav,"r"); // play wav file waver.play(wave_file); // close wav file fclose(wave_file); } // Navigation switch class class Nav_Switch { public: Nav_Switch(PinName up,PinName down,PinName left,PinName right,PinName fire); int read(); //boolean functions to test each switch bool up(); bool down(); bool left(); bool right(); bool fire(); //automatic read on RHS operator int (); //index to any switch array style bool operator[](int index) { return _pins[index]; }; private: BusIn _pins; }; Nav_Switch::Nav_Switch (PinName up,PinName down,PinName left,PinName right,PinName fire): _pins(up, down, left, right, fire) { _pins.mode(PullUp); //needed if pullups not on board or a bare nav switch is used - delete otherwise wait(0.001); //delays just a bit for pullups to pull inputs high } inline bool Nav_Switch::up() { return !(_pins[0]); } inline bool Nav_Switch::down() { return !(_pins[1]); } inline bool Nav_Switch::left() { return !(_pins[2]); } inline bool Nav_Switch::right() { return !(_pins[3]); } inline bool Nav_Switch::fire() { return !(_pins[4]); } inline int Nav_Switch::read() { return _pins.read(); } inline Nav_Switch::operator int () { return _pins.read(); } //up, down, left, right, center Nav_Switch myNav( p9, p6, p7, p5, p8); Timer t; // Game Variables const int BLOCK_SIDE = 29; // side of card const int BUFFER = 5; // space between cards const int NUM_ROWS = 4; // num of rows and also columns since it's a square grid int score = 0; // initialize score float time_limit = 60.0; // set time limit bool start_game = 1; // Determines if it is the start of the game typedef enum { red_circle, blue_circle, green_circle, pink_circle, red_square, blue_square, green_square, pink_square } shapes; 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}; int temp_shape; // temp shape array int block_arr[NUM_ROWS][NUM_ROWS] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; int current_x = 0; int current_y = 0; int prev_x = 0; int prev_y = 0; int num_flips = 0; int current_shape = 0; int prev_shape = 0; int k = 0; int main() { t.start(); while(score<8 && t.read() < time_limit) { if (start_game) { //set_time(1256729737); srand(time(0)); // create random seed so rand() will generate new random numbers each time for (int i = 0; i < NUM_ROWS; i++ ) { for (int j = 0; j < NUM_ROWS; j++ ) { // randomize elements within the array using "shuffle" algorithm int rand_x = rand() % 4; int rand_y = rand() % 4; int temp = final_shapes[i][j]; final_shapes[i][j] = final_shapes[rand_x][rand_y]; final_shapes[rand_x][rand_y] = temp; // draw all white blocks uLCD.filled_rectangle(BUFFER + (j * BLOCK_SIDE), BUFFER + (i * BLOCK_SIDE), BLOCK_SIDE + (j * BLOCK_SIDE), BLOCK_SIDE + (i * BLOCK_SIDE), WHITE); } } uLCD.rectangle(BUFFER, BUFFER, BLOCK_SIDE, BLOCK_SIDE, RED); // initialize player at top left block start_game = 0; } uLCD.locate(0,15); uLCD.color(0xFFCCCC); uLCD.printf("Time left: %2.0F", time_limit - t.read()); /* * Handle player input for movement */ if (myNav.right() && current_x < NUM_ROWS - 1) { 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); current_x++; 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); // playSound("/sd/wavfiles/shoot.wav"); wait(.2); } if (myNav.left() && current_x > 0) { 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); current_x--; 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); wait(.2); } if (myNav.down() && current_y < NUM_ROWS - 1) { 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); current_y++; 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); wait(.2); } if (myNav.up() && current_y > 0) { 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); current_y--; 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); wait(.2); } /* * When user clicks, draw the according shape from the final_shapes array in that spot */ if(myNav.fire() && num_flips < 2 && final_shapes[current_x][current_y]!= -1) { // keep track of shape's position from first click if(num_flips == 0) { prev_x = current_x; prev_y = current_y; } playSound("/sd/wavfiles/buttonpress.wav"); // fill block background with black 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); prev_shape = current_shape; switch(final_shapes[current_x][current_y]) { case red_circle: uLCD.filled_circle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), 5, RED); current_shape = red_circle; break; case blue_circle: uLCD.filled_circle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), 5, BLUE); current_shape = blue_circle; break; case green_circle: uLCD.filled_circle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), 5, GREEN); current_shape = green_circle; break; case pink_circle: uLCD.filled_circle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), 5, PINK); current_shape = pink_circle; break; case red_square: 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); current_shape = red_square; break; case green_square: 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); current_shape = green_square; break; case blue_square: 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); current_shape = blue_square; break; case pink_square: 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); current_shape = pink_square; break; default: uLCD.filled_circle(BUFFER + BLOCK_SIDE / 2 + (current_x * BLOCK_SIDE), BUFFER + BLOCK_SIDE / 2 + (current_y * BLOCK_SIDE), 5, BLACK); break; } num_flips++; //wait(.2); } // Prevents double click from registering as match if(num_flips == 2 && current_x == prev_x && current_y == prev_y){ num_flips--; } /* * After user flips 2 cards, check to see if they are correct */ if(num_flips == 2) { num_flips = 0; wait(.5); // seconds before shapes disappears (time to memorize shapes) //user is correct (shapes match) if (prev_shape == current_shape) { // draws black rectangles over the two blocks so they go away 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); 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); playSound("/sd/wavfiles/supermissile.wav"); final_shapes[current_x][current_y] = -1; final_shapes[prev_x][prev_y] = -1; score++; } // user did not match shapes else { // draws white blocks back over them (back to unflipped) 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); 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); } 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); 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); } } // End Screen t.stop(); uLCD.cls(); uLCD.text_string("GAME OVER", 5, 5, FONT_7X8, 0xFFCCCC); uLCD.locate(5,8); uLCD.printf("Score = %D",score); }