ECE 4180 Spring 2016 Lab 4

Dependencies:   Memory_Card_Game SDFileSystem mbed

Dependents:   Memory_Card_Game

Files at this revision

API Documentation at this revision

Comitter:
kravemind
Date:
Mon Mar 14 02:16:45 2016 +0000
Child:
1:769f5ef8157f
Commit message:
final

Changed in this revision

4DGL-uLCD-SE.lib Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /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