ECE 4180 Spring 2016 Lab 4
Dependencies: Memory_Card_Game SDFileSystem mbed
Revision 0:5b9b9c78552d, committed 2016-03-14
- Comitter:
- kravemind
- Date:
- Mon Mar 14 02:16:45 2016 +0000
- Child:
- 1:769f5ef8157f
- Commit message:
- final
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/4DGL-uLCD-SE.lib Mon Mar 14 02:16:45 2016 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/4180_1/code/4DGL-uLCD-SE/#15c1642a6f59
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Mon Mar 14 02:16:45 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/teams/mbed/code/SDFileSystem/#7b35d1709458
--- /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);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Mar 14 02:16:45 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/87f2f5183dfb \ No newline at end of file