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);
}