ECE 4180 Spring 2016 Lab 4
Dependencies: Memory_Card_Game SDFileSystem mbed
Diff: main.cpp
- Revision:
- 0:5b9b9c78552d
- Child:
- 2:9a3154ce8b51
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Mar 14 02:16:45 2016 +0000 @@ -0,0 +1,259 @@ +#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,p30); // 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( p8, p6, p7, p5, p17); + +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); +}