Multi-game multiplayer arcade gaming system meant for the red X when playing Super Tic-Tac-Toe.
Dependencies: uLCD_4DGL_SE PinDetect SDFileSystem mbed wave_player
Revision 2:d35fde2d82cd, committed 2015-12-04
- Comitter:
- soapy12312
- Date:
- Fri Dec 04 23:03:08 2015 +0000
- Parent:
- 1:2a7e2f5aeda4
- Commit message:
- Multi-game multiplayer arcade gaming system meant for the red X when playing Super Tic-Tac-Toe.
Changed in this revision
--- a/4DGL-uLCD-SE.lib Sat Nov 28 21:57:03 2015 +0000 +++ b/4DGL-uLCD-SE.lib Fri Dec 04 23:03:08 2015 +0000 @@ -1,1 +1,1 @@ -http://developer.mbed.org/users/4180_1/code/4DGL-uLCD-SE/#caa5d62f11f6 +https://developer.mbed.org/users/soapy12312/code/uLCD_4DGL_SE/#caa5d62f11f6
--- a/Ghost.h Sat Nov 28 21:57:03 2015 +0000 +++ b/Ghost.h Fri Dec 04 23:03:08 2015 +0000 @@ -1,11 +1,6 @@ /****************************************************** - * Author: Yuanzhe Xu - * Institution: Georgia Institute of Technology - * Date: October 18, 2015 - * - * This header file declares all the functions and - * variables needed for the Ghost object. Specific - * ghost functionalities can be found in main.cpp. + * This header program declares all the functions and + * variables used by Ghost players in Pac-Man. ******************************************************/
--- a/MCP23S17.lib Sat Nov 28 21:57:03 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1 +0,0 @@ -http://mbed.org/users/romilly/code/MCP23S17/#068b1e8909bb
--- a/Pacman.h Sat Nov 28 21:57:03 2015 +0000 +++ b/Pacman.h Fri Dec 04 23:03:08 2015 +0000 @@ -1,20 +1,19 @@ /****************************************************** - * Author: Yuanzhe Xu - * Institution: Georgia Institute of Technology - * Date: October 18, 2015 - * - * This header file declares all the functions and - * variables needed for the Pacman object. Specific - * Pac-Man functionalities can be found in main.cpp. + * This header program declares all the functions and + * variables used by the Pac-Man player in Pac-Man. ******************************************************/ +#define DIE "/sd/Die.wav" +#define THEME "/sd/Theme.wav" + + // Pacman class class Pacman { public: // Pac-Man constructor - Pacman(PinDetect &PacmanRight, PinDetect &PacmanDown, PinDetect &PacmanLeft, PinDetect &PacmanUp, Stage &stage, uLCD_4DGL &uLCD) : - PacmanRight(PacmanRight), PacmanDown(PacmanDown), PacmanLeft(PacmanLeft), PacmanUp(PacmanUp), stage(stage), uLCD(uLCD) { + Pacman(PinDetect &PacmanRight, PinDetect &PacmanDown, PinDetect &PacmanLeft, PinDetect &PacmanUp, Stage &stage, uLCD_4DGL &uLCD, wave_player &waver) : + PacmanRight(PacmanRight), PacmanDown(PacmanDown), PacmanLeft(PacmanLeft), PacmanUp(PacmanUp), stage(stage), uLCD(uLCD), waver(waver) { // Use internal pullups PacmanRight.mode(PullUp); PacmanDown.mode(PullUp); @@ -35,6 +34,19 @@ wait(1); } + // Play a sound file + void playSound(char *wav) { + // Open sound file + FILE *wave_file; + wave_file = fopen(wav, "r"); + + // Play wav file + waver.play(wave_file); + + // Close wav file + fclose(wave_file); + } + // Initialize Pac-Man at the start of the game void initialize() { x = 64; @@ -179,6 +191,7 @@ PinDetect &PacmanUp; Stage &stage; uLCD_4DGL &uLCD; + wave_player &waver; int x; int y; int direction; @@ -712,6 +725,8 @@ direction = FACEUP; // Displays Pac-Man's dying animation dyingAnimation(); + // Play dying sound + playSound(DIE); // If the number of lives is 0 if (lives == 0) {
--- a/RGBLED.h Sat Nov 28 21:57:03 2015 +0000 +++ b/RGBLED.h Fri Dec 04 23:03:08 2015 +0000 @@ -1,3 +1,9 @@ +/****************************************************** + * This header program declares all the functions and + * variables used by RGB LED component. + ******************************************************/ + + // Class to control an RGB LED using three PWM pins class RGBLED { public:
--- a/RPSLK.h Sat Nov 28 21:57:03 2015 +0000 +++ b/RPSLK.h Fri Dec 04 23:03:08 2015 +0000 @@ -1,3 +1,10 @@ +/****************************************************** + * This header program declares all the functions and + * variables used by one of the players in Rock, Paper, + * Scissors, Lizard, Spock. + ******************************************************/ + + #define ROCK 0 #define PAPER 1 #define SCISSORS 2 @@ -10,12 +17,6 @@ #define SWITCHRIGHT 4 #define MEH "/sd/Meh.wav" -// DELETE LATER -#define MAXBAUDRATE 3000000 -#define SELECT "/sd/select.wav" -#define WIN "/sd/win.wav" -#define BOMB "/sd/wavfiles/bomb.wav" - // Rock, Paper, Scissors, Lizard, Spock player one class class RPSLK { @@ -143,7 +144,9 @@ void displayInstructions() { uLCD.cls(); uLCD.printf("Hello, and welcometo a game of Rock,Paper, Scissors,\nLizard, Spock.\n\n"); - uLCD.printf("Click to continue."); + uLCD.printf("Click the tactile "); + uLCD.printf("switch to "); + uLCD.printf("continue."); while (choice != SWITCHCLICK) { wait(0.01);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/RedX.h Fri Dec 04 23:03:08 2015 +0000 @@ -0,0 +1,717 @@ +/******************************************************* + * This header program declares all of the functions and + * variables used by the red X player in Super + * Tic-Tac-Toe. + *******************************************************/ + + +#define FORWARDSLASH 0 +#define BACKWARDSLASH 1 +#define VERTICAL 2 +#define HORIZONTAL 3 +#define BOMB "/sd/wavfiles/bomb.wav" +#define WIN "/sd/win.wav" +#define MEH "/sd/Meh.wav" + + +// Smaller Super Tic_Tac_Toe grid structure +struct smallGrid { + char individualGrid[3][3]; + char done; +}; + +// Entire Super Tic_Tac_Toe grid structure +struct largeGrid { + smallGrid smallGrid[3][3]; + char done; +}; + + +class RedX { + public: + // Player X constructor + RedX(DigitalOut &reset, InterruptIn &input, Mpr121 &MPR121, RGBLED &RGB, SDFileSystem &sd, Serial &XBee, uLCD_4DGL &uLCD, wave_player &waver) : + reset(reset), input(input), MPR121(MPR121), RGB(RGB), sd(sd), XBee(XBee), uLCD(uLCD), waver(waver) { + uLCD.baudrate(MAXBAUDRATE); + key = -1; + + // Set up XBee + reset = 0; + wait(0.001); + reset = 1; + wait(0.001); + } + + void playSuperTicTacToe() { + initializeInterrupt(); + displayInstructions(); + initializeGrid(); + + XBee.putc(true); + bool readyToPlay = false; + bool print = true; + + while (readyToPlay == false) { + if (XBee.readable() == true) { + readyToPlay = XBee.getc(); + print = false; + } + + if (print == true) { + uLCD.cls(); + uLCD.printf("Waiting for other player..."); + print = false; + } + } + + uLCD.cls(); + drawStage(); + + // False: player one's turn; true: player two's turn + bool turn = true; + + // Loop through the game + while (grid.done == (char)(-1)) { + turn = !turn; + takeTurn(turn); + gameWin(turn); + } + + uLCD.cls(); + + if (grid.done == 0) { + uLCD.printf("You win!"); + playSound(WIN); + } else if (grid.done == 1) { + uLCD.printf("The other player\nwins."); + playSound(BOMB); + } else if (grid.done == 128) { + uLCD.printf("It's a draw!"); + playSound(MEH); + } + + wait(3); + uLCD.cls(); + } + + + private: + DigitalOut &reset; + InterruptIn &input; + Mpr121 &MPR121; + RGBLED &RGB; + SDFileSystem &sd; + Serial &XBee; + uLCD_4DGL &uLCD; + wave_player &waver; + bool keyAllowed; + volatile int key; + largeGrid grid; + + // Initialize the interrupt + void initializeInterrupt() { + input.fall(this, &RedX::keyInterrupt); + wait(0.01); + input.mode(PullUp); + wait(0.01); + } + + // Determine value of the key pressed + void keyInterrupt() { + if (keyAllowed == true) { + int value = MPR121.read(0x00); + value += MPR121.read(0x01) << 8; + + for (int i = 0; i < 12; i++) { + if (((value >> i) & 0x01) == 1) { + key = i; + } + } + + // Ununsed keys + if ((key == 3) || (key == 7) || (key == 11)) { + key = -1; + } + } else { + key = -1; + } + } + + // Initialize the grid + void initializeGrid() { + grid.done = (char)(-1); + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + grid.smallGrid[i][j].done = (char)(-1); + + for (int k = 0; k < 3; k++) { + for (int l = 0; l < 3; l++) { + grid.smallGrid[i][j].individualGrid[k][l] = (char)(-1); + } + } + } + } + } + + // Display instructions + void displayInstructions() { + uLCD.printf("Hello, and welcome"); + uLCD.printf("to a game of Super"); + uLCD.printf("Tic-Tac-Toe. Use "); + uLCD.printf("the bottom three "); + uLCD.printf("rows of the touch "); + uLCD.printf("keypad to select "); + uLCD.printf("the large grid "); + uLCD.printf("followed by the "); + uLCD.printf("small grid. You "); + uLCD.printf("are the red X.\n\n"); + uLCD.printf("Press any key to "); + uLCD.printf("begin playing."); + wait(0.1); + + key = -1; + keyAllowed = true; + + while (key == -1) { + wait(0.01); + } + + key = -1; + uLCD.cls(); + } + + // Play a sound file + void playSound(char *wav) { + // Open sound file + FILE *wave_file; + wave_file = fopen(wav, "r"); + + // Play wav file + waver.play(wave_file); + + // Close wav file + fclose(wave_file); + } + + // Draw the stage + void drawStage() { + for (int i = 15; i < 120; i += 14) { + uLCD.line(i, 2, i, 127, YELLOW); + uLCD.line(2, i, 127, i, YELLOW); + } + + for (int i = 43; i < 120; i += 42) { + uLCD.line(i, 2, i, 127, WHITE); + uLCD.line(2, i, 127, i, WHITE); + } + } + + // Draw small X + void drawSmallX(int largeX, int largeY, int smallX, int smallY) { + int xCoordinate = 1 + (largeX * 42) + (smallX * 14) + 7; + int yCoordinate = 1 + (largeY * 42) + (smallY * 14) + 7; + + int x1 = xCoordinate - 6; + int x2 = xCoordinate + 6; + int y1 = yCoordinate - 6; + int y2 = yCoordinate + 6; + + uLCD.line(x1 + 1, y1 + 1, x2, y2, RED); + uLCD.line(x1 + 1, y2 - 1, x2, y1, RED); + } + + // Draw small O + void drawSmallO(int largeX, int largeY, int smallX, int smallY) { + int xCoordinate = 1 + (largeX * 42) + (smallX * 14) + 7; + int yCoordinate = 1 + (largeY * 42) + (smallY * 14) + 7; + + uLCD.circle(xCoordinate, yCoordinate, 5, BLUE); + } + + // Draw large X + void drawLargeX(int largeX, int largeY) { + int xCoordinate = 1 + (largeX * 42) + 21; + int yCoordinate = 1 + (largeY * 42) + 21; + + int x1 = xCoordinate - 20; + int x2 = xCoordinate + 20; + int y1 = yCoordinate - 20; + int y2 = yCoordinate + 20; + + uLCD.filled_rectangle(x1, y1, x2, y2, BLACK); + + uLCD.line(x1 + 1, y1 + 1, x2, y2, RED); + uLCD.line(x1 + 1, y2 - 1, x2, y1, RED); + } + + // Draw large O + void drawLargeO(int largeX, int largeY) { + int xCoordinate = 1 + (largeX * 42) + 21; + int yCoordinate = 1 + (largeY * 42) + 21; + + int x1 = xCoordinate - 20; + int x2 = xCoordinate + 20; + int y1 = yCoordinate - 20; + int y2 = yCoordinate + 20; + + uLCD.filled_rectangle(x1, y1, x2, y2, BLACK); + + uLCD.circle(xCoordinate, yCoordinate, 19, BLUE); + } + + // Find x-coordinate based on key input + int xGrid() { + int x; + + if ((key == 0) || (key == 1) || (key == 2)) { + x = 0; + } else if ((key == 4) || (key == 5) || (key == 6)) { + x = 1; + } else if ((key == 8) || (key == 9) || (key == 10)) { + x = 2; + } else { + x = -1; + } + + return x; + } + + // Find y-coordinate based on key input + int yGrid() { + int y; + + if ((key == 2) || (key == 6) || (key == 10)) { + y = 0; + } else if ((key == 1) || (key == 5) || (key == 9)) { + y = 1; + } else if ((key == 0) || (key == 4) || (key == 8)) { + y = 2; + } else { + y = -1; + } + + return y; + } + + // Display a certain small grid in a set color + void drawSmallGrid(int x, int y, int color) { + int x1 = 1 + (x * 42) + 1; + int x2 = x1 + 40; + int y1 = 1 + (y * 42) + 1; + int y2 = y1 + 40; + + for (int i = x1; i < x2; i += 14) { + for (int j = y1; j < y2; j += 14) { + uLCD.filled_rectangle(i, j, i + 12, j + 12, color); + } + } + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (grid.smallGrid[x][y].individualGrid[i][j] == 0) { + drawSmallX(x, y, i, j); + } else if (grid.smallGrid[x][y].individualGrid[i][j] == 1) { + drawSmallO(x, y, i, j); + } + } + } + } + + // Draw a line if a player takes a small grid + void drawSmallWinLine(int x1, int y1, int orientation) { + int x2 = x1; + int y2 = y1; + + if (orientation == FORWARDSLASH) { + x2 = x1 - 41; + y2 = y1 + 41; + } else if (orientation == BACKWARDSLASH) { + x2 = x1 + 41; + y2 = y1 + 41; + } else if (orientation == VERTICAL) { + y2 = y1 + 41; + } else if (orientation == HORIZONTAL) { + x2 = x1 + 41; + } + + uLCD.line(x1, y1, x2, y2, GREEN); + wait(1); + } + + // Check whether a player has taken a small grid + bool smallGridWin(int largeX, int largeY, int smallX, int smallY) { + bool taken = false; + char individual[3][3]; + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + individual[i][j] = grid.smallGrid[largeX][largeY].individualGrid[i][j]; + } + } + + int x1 = 1 + (largeX * 42) + 1; + int y1 = 1 + (largeY * 42) + 1; + int orientation = -1; + + if ((individual[0][0] == individual[1][1]) && (individual[1][1] == individual[2][2]) && + (individual[0][0] != (char)(-1))) { + orientation = BACKWARDSLASH; + taken = true; + } else if ((individual[2][0] == individual[1][1]) && (individual[1][1] == individual[0][2]) && + (individual[2][0] != (char)(-1))) { + orientation = FORWARDSLASH; + x1 += 40; + taken = true; + } else if ((individual[0][0] == individual[1][0]) && (individual[1][0] == individual[2][0]) && + (individual[0][0] != (char)(-1))) { + orientation = HORIZONTAL; + y1 += 6; + taken = true; + } else if ((individual[0][1] == individual[1][1]) && (individual[1][1] == individual[2][1]) && + (individual[0][1] != (char)(-1))) { + orientation = HORIZONTAL; + y1 += 20; + taken = true; + } else if ((individual[0][2] == individual[1][2]) && (individual[1][2] == individual[2][2]) && + (individual[0][2] != (char)(-1))) { + orientation = HORIZONTAL; + y1 += 34; + taken = true; + } else if ((individual[0][0] == individual[0][1]) && (individual[0][1] == individual[0][2]) && + (individual[0][0] != (char)(-1))) { + orientation = VERTICAL; + x1 += 6; + taken = true; + } else if ((individual[1][0] == individual[1][1]) && (individual[1][1] == individual[1][2]) && + (individual[1][0] != (char)(-1))) { + orientation = VERTICAL; + x1 += 20; + taken = true; + } else if ((individual[2][0] == individual[2][1]) && (individual[2][1] == individual[2][2]) && + (individual[2][0] != (char)(-1))) { + orientation = VERTICAL; + x1 += 34; + taken = true; + } else { + orientation = -1; + taken = false; + } + + // Check to see if there is a draw + if (taken == false) { + bool draw = true; + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (individual[i][j] != (char)(-1)) { + draw = false; + } + } + } + + if (draw == true) { + grid.smallGrid[largeX][largeY].done = 128; + } + } + + drawSmallWinLine(x1, y1, orientation); + + return taken; + } + + // Take a turn + void takeTurn(bool turn) { + // Player selects small grid, then individual grid + int keyInputs[2] = {-1, -1}; + + // If it is player one's turn + if (turn == false) { + RGB = RED; + + // Allow user input + keyAllowed = true; + + int largeX = 0; + int largeY = 0; + + key = -1; + + // Check if the other player is ready to proceed + bool ready = false; + + while (ready == false) { + if (XBee.readable() == true) { + ready = XBee.getc(); + } + } + + // Wait for player to select small grid + while ((keyInputs[0] == -1) || (grid.smallGrid[largeX][largeY].done != (char)(-1))) { + wait(0.01); + keyInputs[0] = key; + largeX = xGrid(); + largeY = yGrid(); + } + + // Send out the small grid value through the XBee + XBee.putc(keyInputs[0]); + + // Highlight selected grid + drawSmallGrid(largeX, largeY, PINK); + + playSound("/sd/select.wav"); + + // Allow user input + keyAllowed = true; + key = -1; + + // Check if the other player is ready to proceed + ready = false; + + while (ready == false) { + if (XBee.readable() == true) { + ready = XBee.getc(); + } + } + + wait(0.5); + + // Wait for player to select individual grid + while (keyInputs[1] == -1) { + wait(0.01); + + if (grid.smallGrid[largeX][largeY].individualGrid[xGrid()][yGrid()] == (char)(-1)) { + keyInputs[1] = key; + } + } + + // Send out the individual grid value through the XBee + XBee.putc(keyInputs[1]); + + int smallX = xGrid(); + int smallY = yGrid(); + + grid.smallGrid[largeX][largeY].individualGrid[smallX][smallY] = 0; + drawSmallGrid(largeX, largeY, BLACK); + drawSmallX(largeX, largeY, smallX, smallY); + + key = -1; + playSound("/sd/select.wav"); + + // Check if player one has taken a small grid + if (smallGridWin(largeX, largeY, smallX, smallY) == true) { + grid.smallGrid[largeX][largeY].done = 0; + drawLargeX(largeX, largeY); + } else { + bool draw = true; + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (grid.smallGrid[largeX][largeY].individualGrid[i][j] == (char)(-1)) { + draw = false; + } + } + } + + if (draw == true) { + grid.smallGrid[largeX][largeY].done = 128; + } + } + + // Check if the other player is ready to proceed + ready = false; + + while (ready == false) { + if (XBee.readable() == true) { + ready = XBee.getc(); + } + } + // If it is player two's turn + } else { + RGB = BLUE; + + // Allow user input + keyAllowed = true; + + int largeX = 0; + int largeY = 0; + + key = -1; + + // Ready to proceed + XBee.putc(true); + + // Wait for player to select small grid + while ((keyInputs[0] == -1) || (grid.smallGrid[largeX][largeY].done != (char)(-1))) { + // Read in the value through the XBee + if (XBee.readable() == true) { + key = XBee.getc(); + keyInputs[0] = key; + largeX = xGrid(); + largeY = yGrid(); + } + } + + // Highlight selected grid + drawSmallGrid(largeX, largeY, CYAN); + + playSound("/sd/select.wav"); + + // Allow user input + keyAllowed = true; + key = -1; + + // Ready to proceed + XBee.putc(true); + + // Wait for player to select individual grid + while (keyInputs[1] == -1) { + wait(0.01); + + // Read in the value through the XBee + if (XBee.readable() == true) { + key = XBee.getc(); + keyInputs[1] = key; + } + } + + int smallX = xGrid(); + int smallY = yGrid(); + + grid.smallGrid[largeX][largeY].individualGrid[smallX][smallY] = 1; + drawSmallGrid(largeX, largeY, BLACK); + drawSmallO(largeX, largeY, smallX, smallY); + + key = -1; + playSound("/sd/select.wav"); + + // Check if player two has taken a small grid + if (smallGridWin(largeX, largeY, smallX, smallY) == true) { + grid.smallGrid[largeX][largeY].done = 1; + drawLargeO(largeX, largeY); + } else { + bool draw = true; + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (grid.smallGrid[largeX][largeY].individualGrid[i][j] == (char)(-1)) { + draw = false; + } + } + } + + if (draw == true) { + grid.smallGrid[largeX][largeY].done = 128; + } + } + + // Ready to proceed + XBee.putc(true); + } + } + + // Draw final line when a player wins + void drawLargeWinLine(int x1, int y1, int orientation) { + int x2 = 127; + int y2 = 127; + + if (orientation == FORWARDSLASH) { + x2 = 0; + } else if (orientation == HORIZONTAL) { + y2 = y1; + } else if (orientation == VERTICAL) { + x2 = x1; + } + + wait(1); + uLCD.line(x1, y1, x2, y2, GREEN); + wait(3); + } + + // Check whether a player has won + void gameWin(bool turn) { + bool won = false; + char small[3][3]; + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + small[i][j] = grid.smallGrid[i][j].done; + } + } + + int x1 = 2; + int y1 = 2; + int orientation = -1; + + if ((small[0][0] == small[1][1]) && (small[1][1] == small[2][2]) && + (small[0][0] != (char)(-1)) && (small[0][0] != 128)) { + orientation = BACKWARDSLASH; + won = true; + } else if ((small[2][0] == small[1][1]) && (small[1][1] == small[0][2]) && + (small[2][0] != (char)(-1)) && (small[2][0] != 128)) { + orientation = FORWARDSLASH; + x1 = 126; + won = true; + } else if ((small[0][0] == small[1][0]) && (small[1][0] == small[2][0]) && + (small[0][0] != (char)(-1)) && (small[0][0] != 128)) { + orientation = HORIZONTAL; + y1 += 21; + won = true; + } else if ((small[0][1] == small[1][1]) && (small[1][1] == small[2][1]) && + (small[0][1] != (char)(-1)) && (small[0][1] != 128)) { + orientation = HORIZONTAL; + y1 += 63; + won = true; + } else if ((small[0][2] == small[1][2]) && (small[1][2] == small[2][2]) && + (small[0][2] != (char)(-1)) && (small[0][2] != 128)) { + orientation = HORIZONTAL; + y1 += 105; + won = true; + } else if ((small[0][0] == small[0][1]) && (small[0][1] == small[0][2]) && + (small[0][0] != (char)(-1)) && (small[0][0] != 128)) { + orientation = VERTICAL; + x1 += 21; + won = true; + } else if ((small[1][0] == small[1][1]) && (small[1][1] == small[1][2]) && + (small[1][0] != (char)(-1)) && (small[1][0] != 128)) { + orientation = VERTICAL; + x1 += 63; + won = true; + } else if ((small[2][0] == small[2][1]) && (small[2][1] == small[2][2]) && + (small[2][0] != (char)(-1)) && (small[2][0] != 128)) { + orientation = VERTICAL; + x1 += 105; + won = true; + } else { + orientation = -1; + won = false; + } + + // Check to see if there is a draw + if (won == false) { + bool draw = true; + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 3; j++) { + if (small[i][j] == (char)(-1)) { + draw = false; + } + } + } + + if (draw == true) { + grid.done = 128; + wait(3); + } + } else { + if (turn == false) { + grid.done = 0; + } else { + grid.done = 1; + } + + drawLargeWinLine(x1, y1, orientation); + } + } +}; \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Simon.h Fri Dec 04 23:03:08 2015 +0000 @@ -0,0 +1,994 @@ +/****************************************************** + * This header program declares all the functions and + * variables used by one of the players in Simon. + ******************************************************/ + + +#define E3 "/sd/wavfiles/trumpet_E3.wav" +#define A3 "/sd/wavfiles/trumpet_A3.wav" +#define C4 "/sd/wavfiles/trumpet_Cs.wav" +#define E4 "/sd/wavfiles/trumpet_E4.wav" +#define BUZZER "/sd/wavfiles/BUZZER.wav" +#define DING "/sd/wavfiles/DING.wav" +#define BOMB "/sd/wavfiles/bomb.wav" +#define WIN "/sd/win.wav" +#define EASY 1 +#define NORMAL 2 +#define HEROIC 3 +#define LEGENDARY 4 +#define MAXLENGTH 7 + + +// Simon Says class +class Simon { + public: + // Simon Says constructor + Simon(AnalogIn &noise, DigitalOut &reset, PinDetect &button1, PinDetect &button2, PinDetect &button3, PinDetect &button4, SDFileSystem &sd, Serial &XBee, uLCD_4DGL &uLCD, + wave_player &waver) : noise(noise), reset(reset), button1(button1), button2(button2), button3(button3), button4(button4), sd(sd), XBee(XBee), uLCD(uLCD), waver(waver) { + // Maximize the uLCD baud rate + uLCD.baudrate(MAXBAUDRATE); + + // Set up interrupts + button1.mode(PullUp); + button2.mode(PullUp); + button3.mode(PullUp); + button4.mode(PullUp); + wait(0.1); + button1.attach_deasserted(this, &Simon::button1Hit); + button2.attach_deasserted(this, &Simon::button2Hit); + button3.attach_deasserted(this, &Simon::button3Hit); + button4.attach_deasserted(this, &Simon::button4Hit); + wait(0.1); + button1.setSampleFrequency(); + button2.setSampleFrequency(); + button3.setSampleFrequency(); + button4.setSampleFrequency(); + wait(0.1); + + // Set up XBee + reset = 0; + wait(0.001); + reset = 1; + wait(0.001); + + oneHit = false; + twoHit = false; + threeHit = false; + fourHit = false; + + resetSequence(sequence, MAXLENGTH); + resetSequence(playerSequence, MAXLENGTH); + + otherPlayerWin = false; + } + + // Simulate the entire game + void playSimon() { + displayInstructions(); + selectDifficulty(); + countdown(); + playGame(); + gameOver(); + } + + + private: + AnalogIn &noise; + DigitalOut &reset; + PinDetect &button1; + PinDetect &button2; + PinDetect &button3; + PinDetect &button4; + SDFileSystem &sd; + Serial &XBee; + uLCD_4DGL &uLCD; + wave_player &waver; + volatile bool oneHit; + volatile bool twoHit; + volatile bool threeHit; + volatile bool fourHit; + int difficulty; + int sequence[MAXLENGTH]; + int playerSequence[MAXLENGTH]; + bool otherPlayerWin; + + // Color the background of one of the four corner + void drawBack(int position, int color) { + int x11, x12, x21, x22, y11, y12, y21, y22; + + switch (position) { + case 3: + x11 = 64; + x12 = 127; + x21 = 85; + x22 = 127; + y11 = 85; + y12 = 127; + y21 = 64; + y22 = 84; + break; + case 2: + x11 = 0; + x12 = 63; + x21 = 0; + x22 = 42; + y11 = 85; + y12 = 127; + y21 = 64; + y22 = 84; + break; + case 1: + x11 = 0; + x12 = 63; + x21 = 0; + x22 = 42; + y11 = 0; + y12 = 42; + y21 = 43; + y22 = 63; + break; + default: + x11 = 64; + x12 = 127; + x21 = 85; + x22 = 127; + y11 = 0; + y12 = 42; + y21 = 43; + y22 = 63; + } + + uLCD.filled_rectangle(x11, y11, x12, y12, color); + uLCD.filled_rectangle(x21, y21, x22, y22, color); + } + + // Color the foreground of one of the four corners + void drawFore(int position, int color) { + int x11, x12, x21, x22, y11, y12, y21, y22; + + switch (position) { + case 3: + x11 = 68; + x12 = 123; + x21 = 89; + x22 = 123; + y11 = 89; + y12 = 123; + y21 = 68; + y22 = 89; + break; + case 2: + x11 = 4; + x12 = 59; + x21 = 4; + x22 = 38; + y11 = 89; + y12 = 123; + y21 = 68; + y22 = 89; + break; + case 1: + x11 = 4; + x12 = 59; + x21 = 4; + x22 = 38; + y11 = 4; + y12 = 38; + y21 = 39; + y22 = 59; + break; + default: + x11 = 68; + x12 = 123; + x21 = 89; + x22 = 123; + y11 = 4; + y12 = 38; + y21 = 39; + y22 = 59; + } + + uLCD.filled_rectangle(x11, y11, x12, y12, color); + uLCD.filled_rectangle(x21, y21, x22, y22, color); + } + + // Print a number in the middle of the screen + void drawNum(int i) { + uLCD.text_width(3); + uLCD.text_height(3); + uLCD.color(BLACK); + uLCD.locate(2, 2); + uLCD.printf("%2D", i); + } + + // Create a random sequence + void createSequence(int *seq, int length) { + // Seed using noise from analog pin + srand((int)(noise * 50000 / 43)); + + for (int i = 0; i < length; i++) { + seq[i] = rand() % 4; + } + + for (int i = length; i < MAXLENGTH; i++) { + seq[i] = -1; + } + } + + // Reset the hits to false + void resetHits() { + oneHit = false; + twoHit = false; + threeHit = false; + fourHit = false; + } + + // Determine if all hits are false + bool noHits() { + return ((oneHit == false) && (twoHit == false) && (threeHit == false) && (fourHit == false)); + } + + // Wait for player input to go to next page + void nextPage() { + resetHits(); + + while (noHits() == true) { + } + + uLCD.cls(); + resetHits(); + } + + // Push button 1 interrupt routine + void button1Hit() { + oneHit = true; + } + + // Push button 2 interrupt routine + void button2Hit() { + twoHit = true; + } + + // Push button 3 interrupt routine + void button3Hit() { + threeHit = true; + } + + // Push button 4 interrupt routine + void button4Hit() { + fourHit = true; + } + + // Determine whether the player wants to view instructions + bool viewInstructions() { + bool viewInstructions = false; + + resetHits(); + + // Wait for pb1 or pb2 to be pressed + while ((oneHit == false) && (twoHit == false)) { + wait(1); + + // View instructions + if (oneHit == true) { + uLCD.cls(); + viewInstructions = true; + // Skip instructions + } else if (twoHit == true) { + uLCD.cls(); + viewInstructions = false; + } else { + resetHits(); + } + } + + return viewInstructions; + } + + // Play the sequence according to the difficulty + void playSequence(int *sequence) { + // Interval between sequence elements + float interval; + + // Set interval based on difficulty + if (difficulty == EASY) { + interval = 1.5f; + } else { + interval = 1.0f; + } + + // On Easy or Normal difficulty + if (difficulty == EASY || difficulty == NORMAL) { + int i = 0; + + // Loop through the sequence + while (i < MAXLENGTH && sequence[i] != -1) { + // Display position, color, and play sound at corresponding intervals + if (sequence[i] == 0) { + drawFore(0, RED); + playSound(A3); + wait(interval - 0.25); + drawBack(0, WHITE); + wait(0.25); + } else if (sequence[i] == 1) { + drawFore(1, GREEN); + playSound(E3); + wait(interval - 0.25); + drawBack(1, WHITE); + wait(0.25); + } else if (sequence[i] == 2) { + drawFore(2, YELLOW); + playSound(C4); + wait(interval - 0.25); + drawBack(2, WHITE); + wait(0.25); + } else { + drawFore(3, BLUE); + playSound(E4); + wait(interval - 0.25); + drawBack(3, WHITE); + wait(0.25); + } + + i++; + } + // On Heroic difficulty + } else if (difficulty == HEROIC) { + int i = 0; + + // Loop through the sequence + while (i < MAXLENGTH && sequence[i] != -1) { + // Display color with random position and sound at 1.0-second intervals + if (sequence[i] == 0) { + int position = rand() % 4; + int sound = rand() % 4; + drawFore(position, RED); + + if (sound == 0) { + playSound(E3); + } else if (sound == 1) { + playSound(A3); + } else if (sound == 2) { + playSound(C4); + } else { + playSound(E4); + } + + wait(interval - 0.25); + drawBack(position, WHITE); + wait(0.25); + } else if (sequence[i] == 1) { + int position = rand() % 4; + int sound = rand() % 4; + drawFore(position, GREEN); + + if (sound == 0) { + playSound(E3); + } else if (sound == 1) { + playSound(A3); + } else if (sound == 2) { + playSound(C4); + } else { + playSound(E4); + } + + wait(interval - 0.25); + drawBack(position, WHITE); + wait(0.25); + } else if (sequence[i] == 2) { + int position = rand() % 4; + int sound = rand() % 4; + drawFore(position, YELLOW); + + if (sound == 0) { + playSound(E3); + } else if (sound == 1) { + playSound(A3); + } else if (sound == 2) { + playSound(C4); + } else { + playSound(E4); + } + + wait(interval - 0.25); + drawBack(position, WHITE); + wait(0.25); + } else { + int position = rand() % 4; + int sound = rand() % 4; + drawFore(position, BLUE); + + if (sound == 0) { + playSound(E3); + } else if (sound == 1) { + playSound(A3); + } else if (sound == 2) { + playSound(C4); + } else { + playSound(E4); + } + + wait(interval - 0.25); + drawBack(position, WHITE); + wait(0.25); + } + + i++; + } + // On Legendary difficulty + } else { + int i = 0; + + // Loop through the sequence + while (i < MAXLENGTH && sequence[i] != -1) { + // Play sound with random color and position at 1.0-second intervals + if (sequence[i] == 0) { + int position = rand() % 4; + int color = rand() % 4; + + if (color == 0) { + drawFore(position, RED); + } else if (color == 1) { + drawFore(position, GREEN); + } else if (color == 2) { + drawFore(position, YELLOW); + } else { + drawFore(position, BLUE); + } + + playSound(A3); + wait(interval - 0.25); + drawBack(position, WHITE); + wait(0.25); + } else if (sequence[i] == 1) { + int position = rand() % 4; + int color = rand() % 4; + + if (color == 0) { + drawFore(position, RED); + } else if (color == 1) { + drawFore(position, GREEN); + } else if (color == 2) { + drawFore(position, YELLOW); + } else { + drawFore(position, BLUE); + } + + playSound(E3); + wait(interval - 0.25); + drawBack(position, WHITE); + wait(0.25); + } else if (sequence[i] == 2) { + int position = rand() % 4; + int color = rand() % 4; + + if (color == 0) { + drawFore(position, RED); + } else if (color == 1) { + drawFore(position, GREEN); + } else if (color == 2) { + drawFore(position, YELLOW); + } else { + drawFore(position, BLUE); + } + + playSound(C4); + wait(interval - 0.25); + drawBack(position, WHITE); + wait(0.25); + } else { + int position = rand() % 4; + int color = rand() % 4; + + if (color == 0) { + drawFore(position, RED); + } else if (color == 1) { + drawFore(position, GREEN); + } else if (color == 2) { + drawFore(position, YELLOW); + } else { + drawFore(position, BLUE); + } + + playSound(E4); + wait(interval - 0.25); + drawBack(position, WHITE); + wait(0.25); + } + + i++; + } + } + } + + // Play a sound file + void playSound(char *wav) { + // Open sound file + FILE *wave_file; + wave_file = fopen(wav, "r"); + + // Play wav file + waver.play(wave_file); + + // Close wav file + fclose(wave_file); + } + + // Reset the values in the sequence + void resetSequence(int *sequence, int length) { + for (int i = 0; i < length; i++) { + sequence[i] = -1; + } + } + + // Display instructions + void displayInstructions() { + uLCD.printf("Hello, and welcometo a game of\nmultiplayer Simon."); + uLCD.printf("First player to "); + uLCD.printf("reach %d points ", MAXLENGTH); + uLCD.printf("wins!\n\n"); + uLCD.printf("Press pb1 to view instructions or\npb2 to skip to\ndifficulty select-ion."); + + // If player chooses to view instructions + if (viewInstructions() == true) { + // Gameplay instructions + uLCD.printf("Sequences will be-gin with only one element. The numb-er of elements\n"); + uLCD.printf("increases by one\nupon earning a po-int, and vise ver-sa. "); + uLCD.printf("Remember, you must correctly getALL the values in a "); + uLCD.printf("sequence to earna point.\n\n"); + uLCD.printf("Press any button\nto continue."); + + nextPage(); + + uLCD.printf("Each push button\nhas its own uniqueposition, color,\nand sound.\n\n"); + uLCD.printf("Press any button\nto continue."); + + nextPage(); + + // Push button 1 + uLCD.printf("pb1: top right,\nred, note A3\n\n"); + uLCD.printf("Press pb1 for a\ndemonstration."); + + while (oneHit == false) { + } + + uLCD.background_color(WHITE); + uLCD.cls(); + wait(0.5); + + for (int i = 0; i < 5; i++) { + drawFore(0, RED); + playSound(A3); + wait(1); + drawBack(0, WHITE); + wait(0.5); + } + + uLCD.background_color(BLACK); + uLCD.cls(); + uLCD.printf("pb1: top right,\nred, note A3\n\n"); + uLCD.printf("Press any button\nto continue."); + + nextPage(); + + // Push button 2 + uLCD.printf("pb2: top left, gr-een, note E3\n\n"); + uLCD.printf("Press pb2 for a\ndemonstration."); + + while (twoHit == false) { + } + + uLCD.background_color(WHITE); + uLCD.cls(); + wait(0.5); + + for (int i = 0; i < 5; i++) { + drawFore(1, GREEN); + playSound(E3); + wait(1); + drawBack(1, WHITE); + wait(0.5); + } + + uLCD.background_color(BLACK); + uLCD.cls(); + uLCD.printf("pb2: top left, gr-een, note E3\n\n"); + uLCD.printf("Press any button\nto continue."); + + nextPage(); + + // Push button 3 + uLCD.printf("pb3: bottom left,\nyellow, note C4\n\n"); + uLCD.printf("Press pb3 for a\ndemonstration."); + + while (threeHit == false) { + } + + uLCD.background_color(WHITE); + uLCD.cls(); + wait(0.5); + + for (int i = 0; i < 5; i++) { + drawFore(2, YELLOW); + playSound(C4); + wait(1); + drawBack(2, WHITE); + wait(0.5); + } + + uLCD.background_color(BLACK); + uLCD.cls(); + uLCD.printf("pb3: bottom left,\nyellow, note C4\n\n"); + uLCD.printf("Press any button\nto continue."); + + nextPage(); + + // Push button 4 + uLCD.printf("pb4: bottom right,blue, note E4\n\n"); + uLCD.printf("Press pb4 for a\ndemonstration."); + + while (fourHit == false) { + } + + uLCD.background_color(WHITE); + uLCD.cls(); + wait(0.5); + + for (int i = 0; i < 5; i++) { + drawFore(3, BLUE); + playSound(E4); + wait(1); + drawBack(3, WHITE); + wait(0.5); + } + + uLCD.background_color(BLACK); + uLCD.cls(); + uLCD.printf("pb4: bottom right,blue, note E4\n\n"); + uLCD.printf("Press any button\nto continue."); + + nextPage(); + + uLCD.printf("There are 4 diffi-culties to choose from:\n\n"); + uLCD.printf("Easy, Normal,\nHeroic, and\nLegendary.\n\n"); + uLCD.printf("Press any button\nto continue."); + + nextPage(); + + // Different difficulties + uLCD.printf("Easy difficulty:\n\nThe timing betweenthe values of a\n"); + uLCD.printf("sequence is kept\nat constant 1.5-\nsecond intervals.\n\n"); + uLCD.printf("Press any button\nto continue."); + + nextPage(); + + uLCD.printf("Normal difficulty:\nThe timing betweenthe values of a\n"); + uLCD.printf("sequence is kept\nat constant 1.0-\nsecond intervals.\n\n"); + uLCD.printf("Press any button\nto continue."); + + nextPage(); + + uLCD.printf("Heroic difficulty:\nYou must match thepush button to the"); + uLCD.printf("right COLOR that\nis displayed at a random position\nwith a "); + uLCD.printf("random sou-nd. Timing betweenvalues is 1.0 sec-onds.\n\n"); + uLCD.printf("Press any button\nto continue."); + + nextPage(); + + uLCD.printf("Legendary\ndifficulty:\n\nYou must match thepush button to the"); + uLCD.printf("right SOUND that\nis displayed at a random position\nwith a "); + uLCD.printf("random col-or. Timing betweenvalues is 1.0 sec-onds.\n\n"); + uLCD.printf("Press any button\nto continue."); + + nextPage(); + } + } + + // Select difficulty + void selectDifficulty() { + difficultySelection: + uLCD.cls(); + + uLCD.printf("Select difficulty:\npb1: Easy\npb2: Normal\npb3: Heroic\npb4: Legendary"); + + resetHits(); + + while (noHits() == true) { + wait(1); + + if (oneHit == true) { + difficulty = EASY; + } else if (twoHit == true) { + difficulty = NORMAL; + } else if (threeHit == true) { + difficulty = HEROIC; + } else if (fourHit == true) { + difficulty = LEGENDARY; + } else { + resetHits(); + } + } + + XBee.putc(difficulty); + + char otherDifficulty = (char)(-1); + bool print = true; + + while (otherDifficulty == (char)(-1)) { + if (XBee.readable() == true) { + otherDifficulty = XBee.getc(); + print = false; + } + + if (print == true) { + uLCD.cls(); + uLCD.printf("Waiting for other player..."); + print = false; + } + } + + uLCD.cls(); + + if (otherDifficulty != difficulty) { + uLCD.cls(); + uLCD.printf("The other player "); + uLCD.printf("selected another "); + uLCD.printf("difficulty. Please"); + uLCD.printf("select again. "); + wait(3); + uLCD.cls(); + goto difficultySelection; + } + + uLCD.cls(); + + if (difficulty == EASY) { + uLCD.printf("You are playing onEasy difficulty.\n\n"); + } else if (difficulty == NORMAL) { + uLCD.printf("You are playing onNormal difficulty.\n"); + } else if (difficulty == HEROIC) { + uLCD.printf("You are playing onHeroic difficulty.\n"); + } else { + uLCD.printf("You are playing onLegendary\ndifficulty.\n\n"); + } + + uLCD.printf("Starting the\ngame..."); + wait(1.5); + } + + // Countdown to start the game + void countdown() { + uLCD.filled_rectangle(0, 0, 127, 127, WHITE); + uLCD.textbackground_color(WHITE); + uLCD.background_color(WHITE); + uLCD.cls(); + + for (int i = 3; i > 0; i--) { + drawNum(i); + wait(1); + } + } + + // Play the game + void playGame() { + // Initialize the score to be 0 + int score = 0; + + // Loop through the game + do { + // Display score + drawNum(score); + // Create a sequence + createSequence(sequence, score + 1); + // Play sequence + playSequence(sequence); + + resetHits(); + + // Loop through the player sequence + for (int i = 0; i < score + 1; i++) { + while (noHits() == true) { + } + + // Track player inputs + if (oneHit == true) { + playerSequence[i] = 0; + + // On Easy difficulty + if (difficulty == EASY) { + // Display position, color, and play sound + drawFore(0, RED); + playSound(A3); + drawBack(0, WHITE); + // On Normal difficulty + } else if (difficulty == NORMAL) { + // Display position, color, and play sound + drawFore(0, RED); + playSound(A3); + drawBack(0, WHITE); + // On Heroic difficulty + } else if (difficulty == HEROIC) { + // Display color + drawFore(0, RED); + drawFore(1, RED); + drawFore(2, RED); + drawFore(3, RED); + wait(0.5); + drawBack(0, WHITE); + drawBack(1, WHITE); + drawBack(2, WHITE); + drawBack(3, WHITE); + // On Legendary difficulty + } else { + // Play sound + playSound(A3); + } + } else if (twoHit == true) { + playerSequence[i] = 1; + + // On Easy difficulty + if (difficulty == EASY) { + // Display position, color, and play sound + drawFore(1, GREEN); + playSound(E3); + drawBack(1, WHITE); + // On Normal difficulty + } else if (difficulty == NORMAL) { + // Display position, color, and play sound + drawFore(1, GREEN); + playSound(E3); + drawBack(1, WHITE); + // On Heroic difficulty + } else if (difficulty == HEROIC) { + // Display color + drawFore(0, GREEN); + drawFore(1, GREEN); + drawFore(2, GREEN); + drawFore(3, GREEN); + wait(0.5); + drawBack(0, WHITE); + drawBack(1, WHITE); + drawBack(2, WHITE); + drawBack(3, WHITE); + // On Legendary difficulty + } else { + // Play sound + playSound(E3); + } + } else if (threeHit == true) { + playerSequence[i] = 2; + + // On Easy difficulty + if (difficulty == EASY) { + // Display position, color, and play sound + drawFore(2, YELLOW); + playSound(C4); + drawBack(2, WHITE); + // On Normal difficulty + } else if (difficulty == NORMAL) { + // Display position, color, and play sound + drawFore(2, YELLOW); + playSound(C4); + drawBack(2, WHITE); + // On Heroic difficulty + } else if (difficulty == HEROIC) { + drawFore(0, YELLOW); + drawFore(1, YELLOW); + drawFore(2, YELLOW); + drawFore(3, YELLOW); + wait(0.5); + drawBack(0, WHITE); + drawBack(1, WHITE); + drawBack(2, WHITE); + drawBack(3, WHITE); + // On Legendary difficulty + } else { + // Play sound + playSound(C4); + //wait(1); + } + } else if (fourHit == true) { + playerSequence[i] = 3; + + // On Easy difficulty + if (difficulty == EASY) { + // Display position, color, and play sound + drawFore(3, BLUE); + playSound(E4); + drawBack(3, WHITE); + // On Normal difficulty + } else if (difficulty == NORMAL) { + // Display position, color, and play sound + drawFore(3, BLUE); + playSound(E4); + drawBack(3, WHITE); + // On Heroic difficulty + } else if (difficulty == HEROIC) { + // Display color + drawFore(0, BLUE); + drawFore(1, BLUE); + drawFore(2, BLUE); + drawFore(3, BLUE); + wait(0.5); + drawBack(0, WHITE); + drawBack(1, WHITE); + drawBack(2, WHITE); + drawBack(3, WHITE); + // On Legendary difficulty + } else { + // Play sound + playSound(E4); + } + } + + resetHits(); + } + + // Determine whether the sequences match + bool correct = true; + + for (int i = 0; i < score + 1; i++) { + if (sequence[i] != playerSequence[i]) { + correct = false; + } + } + + // Play sound + if (correct == true) { + playSound(DING); + } else { + + playSound(BUZZER); + } + + // Check if the other player has won + if (XBee.readable() == true) { + otherPlayerWin = XBee.getc(); + } + + // If the other player has won, end the game + if (otherPlayerWin == true) { + goto endGame; + } + + // Update the score + if (correct == true) { + score++; + } else { + if (score > 0) { + score--; + } + } + + // Reset sequences + resetSequence(sequence, MAXLENGTH); + resetSequence(playerSequence, MAXLENGTH); + } while (score < MAXLENGTH); + + endGame: + uLCD.pixel(68, 68, WHITE); + } + + // Game over + void gameOver() { + XBee.putc(true); + + uLCD.cls(); + uLCD.text_width(1); + uLCD.text_height(1); + uLCD.textbackground_color(BLACK); + uLCD.filled_rectangle(0, 0, 127, 127, BLACK); + uLCD.background_color(BLACK); + uLCD.color(GREEN); + uLCD.locate(0, 0); + + if (otherPlayerWin == false) { + uLCD.printf("You win!"); + playSound(WIN); + } else { + uLCD.printf("The other player\n"); + uLCD.printf("wins."); + playSound(BOMB); + } + } +}; \ No newline at end of file
--- a/SimonSays.h Sat Nov 28 21:57:03 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,929 +0,0 @@ -#define E3 "/sd/wavfiles/trumpet_E3.wav" -#define A3 "/sd/wavfiles/trumpet_A3.wav" -#define C4 "/sd/wavfiles/trumpet_Cs.wav" -#define E4 "/sd/wavfiles/trumpet_E4.wav" -#define BUZZER "/sd/wavfiles/BUZZER.wav" -#define DING "/sd/wavfiles/DING.wav" -#define BOMB "/sd/wavfiles/bomb.wav" -#define WIN "/sd/win.wav" -#define EASY 1 -#define NORMAL 2 -#define HEROIC 3 -#define LEGENDARY 4 -#define MAXLENGTH 9 - - -// Simon Says class -class SimonSays { - public: - // Simon Says constructor - SimonSays(AnalogIn &noise, PinDetect &button1, PinDetect &button2, PinDetect &button3, PinDetect &button4, SDFileSystem &sd, uLCD_4DGL &uLCD, wave_player &waver) : - noise(noise), button1(button1), button2(button2), button3(button3), button4(button4), sd(sd), uLCD(uLCD), waver(waver) { - // Maximize the uLCD baud rate - uLCD.baudrate(MAXBAUDRATE); - - // Set up interrupts - button1.mode(PullUp); - button2.mode(PullUp); - button3.mode(PullUp); - button4.mode(PullUp); - wait(0.1); - button1.attach_deasserted(this, &SimonSays::button1Hit); - button2.attach_deasserted(this, &SimonSays::button2Hit); - button3.attach_deasserted(this, &SimonSays::button3Hit); - button4.attach_deasserted(this, &SimonSays::button4Hit); - wait(0.1); - button1.setSampleFrequency(); - button2.setSampleFrequency(); - button3.setSampleFrequency(); - button4.setSampleFrequency(); - wait(0.1); - - oneHit = false; - twoHit = false; - threeHit = false; - fourHit = false; - - resetSequence(sequence, MAXLENGTH); - resetSequence(playerSequence, MAXLENGTH); - } - - // Simulate the entire game - void playSimonSays() { - displayInstructions(); - selectDifficulty(); - countdown(); - int score = playGame(); - gameOver(score); - } - - - private: - AnalogIn &noise; - PinDetect &button1; - PinDetect &button2; - PinDetect &button3; - PinDetect &button4; - SDFileSystem &sd; - uLCD_4DGL &uLCD; - wave_player &waver; - volatile bool oneHit; - volatile bool twoHit; - volatile bool threeHit; - volatile bool fourHit; - int difficulty; - int sequence[MAXLENGTH]; - int playerSequence[MAXLENGTH]; - - // Color the background of one of the four corner - void drawBack(int position, int color) { - int x11, x12, x21, x22, y11, y12, y21, y22; - - switch (position) { - case 3: - x11 = 64; - x12 = 127; - x21 = 85; - x22 = 127; - y11 = 85; - y12 = 127; - y21 = 64; - y22 = 84; - break; - case 2: - x11 = 0; - x12 = 63; - x21 = 0; - x22 = 42; - y11 = 85; - y12 = 127; - y21 = 64; - y22 = 84; - break; - case 1: - x11 = 0; - x12 = 63; - x21 = 0; - x22 = 42; - y11 = 0; - y12 = 42; - y21 = 43; - y22 = 63; - break; - default: - x11 = 64; - x12 = 127; - x21 = 85; - x22 = 127; - y11 = 0; - y12 = 42; - y21 = 43; - y22 = 63; - } - - uLCD.filled_rectangle(x11, y11, x12, y12, color); - uLCD.filled_rectangle(x21, y21, x22, y22, color); - } - - // Color the foreground of one of the four corners - void drawFore(int position, int color) { - int x11, x12, x21, x22, y11, y12, y21, y22; - - switch (position) { - case 3: - x11 = 68; - x12 = 123; - x21 = 89; - x22 = 123; - y11 = 89; - y12 = 123; - y21 = 68; - y22 = 89; - break; - case 2: - x11 = 4; - x12 = 59; - x21 = 4; - x22 = 38; - y11 = 89; - y12 = 123; - y21 = 68; - y22 = 89; - break; - case 1: - x11 = 4; - x12 = 59; - x21 = 4; - x22 = 38; - y11 = 4; - y12 = 38; - y21 = 39; - y22 = 59; - break; - default: - x11 = 68; - x12 = 123; - x21 = 89; - x22 = 123; - y11 = 4; - y12 = 38; - y21 = 39; - y22 = 59; - } - - uLCD.filled_rectangle(x11, y11, x12, y12, color); - uLCD.filled_rectangle(x21, y21, x22, y22, color); - } - - // Print a number in the middle of the screen - void drawNum(int i) { - uLCD.text_width(3); - uLCD.text_height(3); - uLCD.color(BLACK); - uLCD.locate(2, 2); - uLCD.printf("%2D", i); - } - - // Create a random sequence - void createSequence(int *seq, int length) { - // Seed using noise from analog pin - srand((int)(noise * 50000 / 43)); - - for (int i = 0; i < length; i++) { - seq[i] = rand() % 4; - } - - for (int i = length; i < MAXLENGTH; i++) { - seq[i] = -1; - } - } - - // Reset the hits to false - void resetHits() { - oneHit = false; - twoHit = false; - threeHit = false; - fourHit = false; - } - - // Determine if all hits are false - bool noHits() { - return ((oneHit == false) && (twoHit == false) && (threeHit == false) && (fourHit == false)); - } - - // Wait for player input to go to next page - void nextPage() { - resetHits(); - - while (noHits() == true) { - } - - uLCD.cls(); - resetHits(); - } - - // Push button 1 interrupt routine - void button1Hit() { - oneHit = true; - } - - // Push button 2 interrupt routine - void button2Hit() { - twoHit = true; - } - - // Push button 3 interrupt routine - void button3Hit() { - threeHit = true; - } - - // Push button 4 interrupt routine - void button4Hit() { - fourHit = true; - } - - // Determine whether the player wants to view instructions - bool viewInstructions() { - bool viewInstructions = false; - - resetHits(); - - // Wait for pb1 or pb2 to be pressed - while ((oneHit == false) && (twoHit == false)) { - wait(1); - - // View instructions - if (oneHit == true) { - uLCD.cls(); - viewInstructions = true; - // Skip instructions - } else if (twoHit == true) { - uLCD.cls(); - viewInstructions = false; - } else { - resetHits(); - } - } - - return viewInstructions; - } - - // Play the sequence according to the difficulty - void playSequence(int *sequence) { - // Interval between sequence elements - float interval; - - // Set interval based on difficulty - if (difficulty == EASY) { - interval = 1.5f; - } else { - interval = 1.0f; - } - - // On Easy or Normal difficulty - if (difficulty == EASY || difficulty == NORMAL) { - int i = 0; - - // Loop through the sequence - while (i < MAXLENGTH && sequence[i] != -1) { - // Display position, color, and play sound at corresponding intervals - if (sequence[i] == 0) { - drawFore(0, RED); - playSound(A3); - wait(interval - 0.25); - drawBack(0, WHITE); - wait(0.25); - } else if (sequence[i] == 1) { - drawFore(1, GREEN); - playSound(E3); - wait(interval - 0.25); - drawBack(1, WHITE); - wait(0.25); - } else if (sequence[i] == 2) { - drawFore(2, YELLOW); - playSound(C4); - wait(interval - 0.25); - drawBack(2, WHITE); - wait(0.25); - } else { - drawFore(3, BLUE); - playSound(E4); - wait(interval - 0.25); - drawBack(3, WHITE); - wait(0.25); - } - - i++; - } - // On Heroic difficulty - } else if (difficulty == HEROIC) { - int i = 0; - - // Loop through the sequence - while (i < MAXLENGTH && sequence[i] != -1) { - // Display color with random position and sound at 1.0-second intervals - if (sequence[i] == 0) { - int position = rand() % 4; - int sound = rand() % 4; - drawFore(position, RED); - - if (sound == 0) { - playSound(E3); - } else if (sound == 1) { - playSound(A3); - } else if (sound == 2) { - playSound(C4); - } else { - playSound(E4); - } - - wait(interval - 0.25); - drawBack(position, WHITE); - wait(0.25); - } else if (sequence[i] == 1) { - int position = rand() % 4; - int sound = rand() % 4; - drawFore(position, GREEN); - - if (sound == 0) { - playSound(E3); - } else if (sound == 1) { - playSound(A3); - } else if (sound == 2) { - playSound(C4); - } else { - playSound(E4); - } - - wait(interval - 0.25); - drawBack(position, WHITE); - wait(0.25); - } else if (sequence[i] == 2) { - int position = rand() % 4; - int sound = rand() % 4; - drawFore(position, YELLOW); - - if (sound == 0) { - playSound(E3); - } else if (sound == 1) { - playSound(A3); - } else if (sound == 2) { - playSound(C4); - } else { - playSound(E4); - } - - wait(interval - 0.25); - drawBack(position, WHITE); - wait(0.25); - } else { - int position = rand() % 4; - int sound = rand() % 4; - drawFore(position, BLUE); - - if (sound == 0) { - playSound(E3); - } else if (sound == 1) { - playSound(A3); - } else if (sound == 2) { - playSound(C4); - } else { - playSound(E4); - } - - wait(interval - 0.25); - drawBack(position, WHITE); - wait(0.25); - } - - i++; - } - // On Legendary difficulty - } else { - int i = 0; - - // Loop through the sequence - while (i < MAXLENGTH && sequence[i] != -1) { - // Play sound with random color and position at 1.0-second intervals - if (sequence[i] == 0) { - int position = rand() % 4; - int color = rand() % 4; - - if (color == 0) { - drawFore(position, RED); - } else if (color == 1) { - drawFore(position, GREEN); - } else if (color == 2) { - drawFore(position, YELLOW); - } else { - drawFore(position, BLUE); - } - - playSound(A3); - wait(interval - 0.25); - drawBack(position, WHITE); - wait(0.25); - } else if (sequence[i] == 1) { - int position = rand() % 4; - int color = rand() % 4; - - if (color == 0) { - drawFore(position, RED); - } else if (color == 1) { - drawFore(position, GREEN); - } else if (color == 2) { - drawFore(position, YELLOW); - } else { - drawFore(position, BLUE); - } - - playSound(E3); - wait(interval - 0.25); - drawBack(position, WHITE); - wait(0.25); - } else if (sequence[i] == 2) { - int position = rand() % 4; - int color = rand() % 4; - - if (color == 0) { - drawFore(position, RED); - } else if (color == 1) { - drawFore(position, GREEN); - } else if (color == 2) { - drawFore(position, YELLOW); - } else { - drawFore(position, BLUE); - } - - playSound(C4); - wait(interval - 0.25); - drawBack(position, WHITE); - wait(0.25); - } else { - int position = rand() % 4; - int color = rand() % 4; - - if (color == 0) { - drawFore(position, RED); - } else if (color == 1) { - drawFore(position, GREEN); - } else if (color == 2) { - drawFore(position, YELLOW); - } else { - drawFore(position, BLUE); - } - - playSound(E4); - wait(interval - 0.25); - drawBack(position, WHITE); - wait(0.25); - } - - i++; - } - } - } - - // Play a sound file - void playSound(char *wav) { - // Open sound file - FILE *wave_file; - wave_file = fopen(wav, "r"); - - // Play wav file - waver.play(wave_file); - - // Close wav file - fclose(wave_file); - } - - // Reset the values in the sequence - void resetSequence(int *sequence, int length) { - for (int i = 0; i < length; i++) { - sequence[i] = -1; - } - } - - // Display instructions - void displayInstructions() { - uLCD.printf("Hello, and welcometo a game of SimonSays.\n\n"); - uLCD.printf("Press pb1 to view instructions or\npb2 to skip to\ndifficulty select-ion."); - - // If player chooses to view instructions - if (viewInstructions() == true) { - // Gameplay - uLCD.printf("Earn 9 points to\nwin. Each correct\nsequence earns youa point, and each\n"); - uLCD.printf("incorrect sequencecosts you a point.If your score goesback to 0, you\nlose."); - uLCD.printf("\n\nPress any button\nto continue."); - - nextPage(); - - uLCD.printf("Sequences will be-gin with only one element. The numb-er of elements\n"); - uLCD.printf("increases by one\nupon earning a po-int, and vise ver-sa. "); - uLCD.printf("Remember, you must correctly getALL the values in a "); - uLCD.printf("sequence to earna point.\n\n"); - uLCD.printf("Press any button\nto continue."); - - nextPage(); - - uLCD.printf("Each push button\nhas its own uniqueposition, color,\nand sound.\n\n"); - uLCD.printf("Press any button\nto continue."); - - nextPage(); - - // Push button 1 - uLCD.printf("pb1: top right,\nred, note A3\n\n"); - uLCD.printf("Press pb1 for a\ndemonstration."); - - while (oneHit == false) { - } - - uLCD.background_color(WHITE); - uLCD.cls(); - wait(0.5); - - for (int i = 0; i < 5; i++) { - drawFore(0, RED); - playSound(A3); - wait(1); - drawBack(0, WHITE); - wait(0.5); - } - - uLCD.background_color(BLACK); - uLCD.cls(); - uLCD.printf("pb1: top right,\nred, note A3\n\n"); - uLCD.printf("Press any button\nto continue."); - - nextPage(); - - // Push button 2 - uLCD.printf("pb2: top left, gr-een, note E3\n\n"); - uLCD.printf("Press pb2 for a\ndemonstration."); - - while (twoHit == false) { - } - - uLCD.background_color(WHITE); - uLCD.cls(); - wait(0.5); - - for (int i = 0; i < 5; i++) { - drawFore(1, GREEN); - playSound(E3); - wait(1); - drawBack(1, WHITE); - wait(0.5); - } - - uLCD.background_color(BLACK); - uLCD.cls(); - uLCD.printf("pb2: top left, gr-een, note E3\n\n"); - uLCD.printf("Press any button\nto continue."); - - nextPage(); - - // Push button 3 - uLCD.printf("pb3: bottom left,\nyellow, note C4\n\n"); - uLCD.printf("Press pb3 for a\ndemonstration."); - - while (threeHit == false) { - } - - uLCD.background_color(WHITE); - uLCD.cls(); - wait(0.5); - - for (int i = 0; i < 5; i++) { - drawFore(2, YELLOW); - playSound(C4); - wait(1); - drawBack(2, WHITE); - wait(0.5); - } - - uLCD.background_color(BLACK); - uLCD.cls(); - uLCD.printf("pb3: bottom left,\nyellow, note C4\n\n"); - uLCD.printf("Press any button\nto continue."); - - nextPage(); - - // Push button 4 - uLCD.printf("pb4: bottom right,blue, note E4\n\n"); - uLCD.printf("Press pb4 for a\ndemonstration."); - - while (fourHit == false) { - } - - uLCD.background_color(WHITE); - uLCD.cls(); - wait(0.5); - - for (int i = 0; i < 5; i++) { - drawFore(3, BLUE); - playSound(E4); - wait(1); - drawBack(3, WHITE); - wait(0.5); - } - - uLCD.background_color(BLACK); - uLCD.cls(); - uLCD.printf("pb4: bottom right,blue, note E4\n\n"); - uLCD.printf("Press any button\nto continue."); - - nextPage(); - - uLCD.printf("There are 4 diffi-culties to choose from:\n\n"); - uLCD.printf("Easy, Normal,\nHeroic, and\nLegendary.\n\n"); - uLCD.printf("Press any button\nto continue."); - - nextPage(); - - // Different difficulties - uLCD.printf("Easy difficulty:\n\nThe timing betweenthe values of a\n"); - uLCD.printf("sequence is kept\nat constant 1.5-\nsecond intervals.\n\n"); - uLCD.printf("Press any button\nto continue."); - - nextPage(); - - uLCD.printf("Normal difficulty:\nThe timing betweenthe values of a\n"); - uLCD.printf("sequence is kept\nat constant 1.0-\nsecond intervals.\n\n"); - uLCD.printf("Press any button\nto continue."); - - nextPage(); - - uLCD.printf("Heroic difficulty:\nYou must match thepush button to the"); - uLCD.printf("right COLOR that\nis displayed at a random position\nwith a "); - uLCD.printf("random sou-nd. Timing betweenvalues is 1.0 sec-onds.\n\n"); - uLCD.printf("Press any button\nto continue."); - - nextPage(); - - uLCD.printf("Legendary\ndifficulty:\n\nYou must match thepush button to the"); - uLCD.printf("right SOUND that\nis displayed at a random position\nwith a "); - uLCD.printf("random col-or. Timing betweenvalues is 1.0 sec-onds.\n\n"); - uLCD.printf("Press any button\nto continue."); - - nextPage(); - } - } - - // Select difficulty - void selectDifficulty() { - uLCD.cls(); - - uLCD.printf("Select difficulty:\npb1: Easy\npb2: Normal\npb3: Heroic\npb4: Legendary"); - - resetHits(); - - while (noHits() == true) { - wait(1); - - if (oneHit == true) { - difficulty = EASY; - } else if (twoHit == true) { - difficulty = NORMAL; - } else if (threeHit == true) { - difficulty = HEROIC; - } else if (fourHit == true) { - difficulty = LEGENDARY; - } else { - resetHits(); - } - } - - uLCD.cls(); - - if (difficulty == EASY) { - uLCD.printf("You have selected Easy difficulty.\n\n"); - uLCD.printf("Press any button\nto start the game."); - } else if (difficulty == NORMAL) { - uLCD.printf("You have selected Normal difficulty.\n"); - uLCD.printf("Press any button\nto start the game."); - } else if (difficulty == HEROIC) { - uLCD.printf("You have selected Heroic difficulty.\n"); - uLCD.printf("Press any button\nto start the game."); - } else { - uLCD.printf("You have selected Legendary\ndifficulty.\n\n"); - uLCD.printf("Press any button\nto start the game."); - } - - nextPage(); - } - - // Countdown to start the game - void countdown() { - uLCD.filled_rectangle(0, 0, 127, 127, WHITE); - uLCD.textbackground_color(WHITE); - uLCD.background_color(WHITE); - uLCD.cls(); - - for (int i = 3; i > 0; i--) { - drawNum(i); - wait(1); - } - } - - // Play the game - int playGame() { - // Initialize the score to be 0 - int score = 0; - - // Loop through the game - do { - // Display score - drawNum(score); - // Create a sequence - createSequence(sequence, score + 1); - // Play sequence - playSequence(sequence); - - resetHits(); - - // Loop through the player sequence - for (int i = 0; i < score + 1; i++) { - while (noHits() == true) { - } - - // Track player inputs - if (oneHit == true) { - playerSequence[i] = 0; - - // On Easy difficulty - if (difficulty == EASY) { - // Display position, color, and play sound - drawFore(0, RED); - playSound(A3); - drawBack(0, WHITE); - // On Normal difficulty - } else if (difficulty == NORMAL) { - // Display position, color, and play sound - drawFore(0, RED); - playSound(A3); - drawBack(0, WHITE); - // On Heroic difficulty - } else if (difficulty == HEROIC) { - // Display color - drawFore(0, RED); - drawFore(1, RED); - drawFore(2, RED); - drawFore(3, RED); - wait(0.5); - drawBack(0, WHITE); - drawBack(1, WHITE); - drawBack(2, WHITE); - drawBack(3, WHITE); - // On Legendary difficulty - } else { - // Play sound - playSound(A3); - } - } else if (twoHit == true) { - playerSequence[i] = 1; - - // On Easy difficulty - if (difficulty == EASY) { - // Display position, color, and play sound - drawFore(1, GREEN); - playSound(E3); - drawBack(1, WHITE); - // On Normal difficulty - } else if (difficulty == NORMAL) { - // Display position, color, and play sound - drawFore(1, GREEN); - playSound(E3); - drawBack(1, WHITE); - // On Heroic difficulty - } else if (difficulty == HEROIC) { - // Display color - drawFore(0, GREEN); - drawFore(1, GREEN); - drawFore(2, GREEN); - drawFore(3, GREEN); - wait(0.5); - drawBack(0, WHITE); - drawBack(1, WHITE); - drawBack(2, WHITE); - drawBack(3, WHITE); - // On Legendary difficulty - } else { - // Play sound - playSound(E3); - } - } else if (threeHit == true) { - playerSequence[i] = 2; - - // On Easy difficulty - if (difficulty == EASY) { - // Display position, color, and play sound - drawFore(2, YELLOW); - playSound(C4); - drawBack(2, WHITE); - // On Normal difficulty - } else if (difficulty == NORMAL) { - // Display position, color, and play sound - drawFore(2, YELLOW); - playSound(C4); - drawBack(2, WHITE); - // On Heroic difficulty - } else if (difficulty == HEROIC) { - drawFore(0, YELLOW); - drawFore(1, YELLOW); - drawFore(2, YELLOW); - drawFore(3, YELLOW); - wait(0.5); - drawBack(0, WHITE); - drawBack(1, WHITE); - drawBack(2, WHITE); - drawBack(3, WHITE); - // On Legendary difficulty - } else { - // Play sound - playSound(C4); - //wait(1); - } - } else if (fourHit == true) { - playerSequence[i] = 3; - - // On Easy difficulty - if (difficulty == EASY) { - // Display position, color, and play sound - drawFore(3, BLUE); - playSound(E4); - drawBack(3, WHITE); - // On Normal difficulty - } else if (difficulty == NORMAL) { - // Display position, color, and play sound - drawFore(3, BLUE); - playSound(E4); - drawBack(3, WHITE); - // On Heroic difficulty - } else if (difficulty == HEROIC) { - // Display color - drawFore(0, BLUE); - drawFore(1, BLUE); - drawFore(2, BLUE); - drawFore(3, BLUE); - wait(0.5); - drawBack(0, WHITE); - drawBack(1, WHITE); - drawBack(2, WHITE); - drawBack(3, WHITE); - // On Legendary difficulty - } else { - // Play sound - playSound(E4); - } - } - - resetHits(); - } - - // Determine whether the sequences match - bool correct = true; - - for (int i = 0; i < score + 1; i++) { - if (sequence[i] != playerSequence[i]) { - correct = false; - } - } - - // Play sound and update the score - if (correct == true) { - score++; - playSound(DING); - } else { - score--; - playSound(BUZZER); - } - - // Reset sequences - resetSequence(sequence, MAXLENGTH); - resetSequence(playerSequence, MAXLENGTH); - } while ((score > 0) && (score < 9)); - - return score; - } - - // Game over - void gameOver(int score) { - uLCD.cls(); - uLCD.text_width(1); - uLCD.text_height(1); - uLCD.textbackground_color(BLACK); - uLCD.filled_rectangle(0, 0, 127, 127, BLACK); - uLCD.background_color(BLACK); - uLCD.color(GREEN); - uLCD.locate(0, 0); - - if (score == 9) { - uLCD.printf("You win!"); - playSound(WIN); - } else { - uLCD.printf("You lose."); - playSound(BOMB); - } - } -}; \ No newline at end of file
--- a/Stage.h Sat Nov 28 21:57:03 2015 +0000 +++ b/Stage.h Fri Dec 04 23:03:08 2015 +0000 @@ -1,10 +1,6 @@ /****************************************************** - * Author: Yuanzhe Xu - * Institution: Georgia Institute of Technology - * Date: October 18, 2015 - * * This header file declares all the functions and - * variables needed for the Stage object. + * variables used by the virtual stage in Pac-Man. ******************************************************/
--- a/SuperTicTacToe.h Sat Nov 28 21:57:03 2015 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,599 +0,0 @@ -#define FORWARDSLASH 0 -#define BACKWARDSLASH 1 -#define VERTICAL 2 -#define HORIZONTAL 3 - - -// Smaller Super Tic_Tac_Toe grid structure -struct smallGrid { - char individualGrid[3][3]; - char done; -}; - -// Entire Super Tic_Tac_Toe grid structure -struct largeGrid { - smallGrid smallGrid[3][3]; - char done; -}; - - -// Super Tic-Tac-Toe class -class SuperTicTacToe { - public: - // Super Tic-Tac-Toe constructor - SuperTicTacToe(InterruptIn &input, Mpr121 &MPR121, RGBLED &RGB, SDFileSystem &sd, uLCD_4DGL &uLCD, wave_player &waver) : - input(input), MPR121(MPR121), RGB(RGB), sd(sd), uLCD(uLCD), waver(waver) { - uLCD.baudrate(MAXBAUDRATE); - initializeInterrupt(); - initializeGrid(); - drawStage(); - } - - // Simulate the entire game - void playSuperTicTacToe() { - // False: player one's turn; true: player two's turn - bool turn = true; - - // Loop through the game - while (grid.done == (char)(-1)) { - turn = !turn; - takeTurn(turn); - gameWin(turn); - } - - uLCD.cls(); - - if (grid.done == 0) { - uLCD.printf("Player One wins!"); - } else if (grid.done == 1) { - uLCD.printf("Player Two wins!"); - } else if (grid.done == 128) { - uLCD.printf("It's a draw!"); - } else { - uLCD.printf("What else is there?"); - } - } - - - private: - InterruptIn &input; - Mpr121 &MPR121; - RGBLED &RGB; - SDFileSystem &sd; - uLCD_4DGL &uLCD; - wave_player &waver; - bool keyAllowed; - volatile int key; - largeGrid grid; - - // Initialize the interrupt - void initializeInterrupt() { - input.fall(this, &SuperTicTacToe::keyInterrupt); - wait(0.01); - input.mode(PullUp); - wait(0.01); - } - - // Initialize the grid - void initializeGrid() { - grid.done = (char)(-1); - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - grid.smallGrid[i][j].done = (char)(-1); - - for (int k = 0; k < 3; k++) { - for (int l = 0; l < 3; l++) { - grid.smallGrid[i][j].individualGrid[k][l] = (char)(-1); - } - } - } - } - } - - // Play a sound file - void playSound(char *wav) { - // Open sound file - FILE *wave_file; - wave_file = fopen(wav, "r"); - - // Play wav file - waver.play(wave_file); - - // Close wav file - fclose(wave_file); - } - - // Draw the stage - void drawStage() { - for (int i = 15; i < 120; i += 14) { - uLCD.line(i, 2, i, 127, YELLOW); - uLCD.line(2, i, 127, i, YELLOW); - } - - for (int i = 43; i < 120; i += 42) { - uLCD.line(i, 2, i, 127, WHITE); - uLCD.line(2, i, 127, i, WHITE); - } - } - - // Draw small X - void drawSmallX(int largeX, int largeY, int smallX, int smallY) { - int xCoordinate = 1 + (largeX * 42) + (smallX * 14) + 7; - int yCoordinate = 1 + (largeY * 42) + (smallY * 14) + 7; - - int x1 = xCoordinate - 6; - int x2 = xCoordinate + 6; - int y1 = yCoordinate - 6; - int y2 = yCoordinate + 6; - - uLCD.line(x1 + 1, y1 + 1, x2, y2, RED); - uLCD.line(x1 + 1, y2 - 1, x2, y1, RED); - } - - // Draw small O - void drawSmallO(int largeX, int largeY, int smallX, int smallY) { - int xCoordinate = 1 + (largeX * 42) + (smallX * 14) + 7; - int yCoordinate = 1 + (largeY * 42) + (smallY * 14) + 7; - - uLCD.circle(xCoordinate, yCoordinate, 5, BLUE); - } - - // Draw large X - void drawLargeX(int largeX, int largeY) { - int xCoordinate = 1 + (largeX * 42) + 21; - int yCoordinate = 1 + (largeY * 42) + 21; - - int x1 = xCoordinate - 20; - int x2 = xCoordinate + 20; - int y1 = yCoordinate - 20; - int y2 = yCoordinate + 20; - - uLCD.filled_rectangle(x1, y1, x2, y2, BLACK); - - uLCD.line(x1 + 1, y1 + 1, x2, y2, RED); - uLCD.line(x1 + 1, y2 - 1, x2, y1, RED); - } - - // Draw large O - void drawLargeO(int largeX, int largeY) { - int xCoordinate = 1 + (largeX * 42) + 21; - int yCoordinate = 1 + (largeY * 42) + 21; - - int x1 = xCoordinate - 20; - int x2 = xCoordinate + 20; - int y1 = yCoordinate - 20; - int y2 = yCoordinate + 20; - - uLCD.filled_rectangle(x1, y1, x2, y2, BLACK); - - uLCD.circle(xCoordinate, yCoordinate, 19, BLUE); - } - - // Determine value of the key pressed - void keyInterrupt() { - if (keyAllowed == true) { - int value = MPR121.read(0x00); - value += MPR121.read(0x01) << 8; - - for (int i = 0; i < 12; i++) { - if (((value >> i) & 0x01) == 1) { - key = i; - } - } - - // Ununsed keys - if ((key == 3) || (key == 7) || (key == 11)) { - key = -1; - } - } else { - key = -1; - } - } - - // Find x-coordinate based on key input - int xGrid() { - int x; - - if ((key == 0) || (key == 1) || (key == 2)) { - x = 0; - } else if ((key == 4) || (key == 5) || (key == 6)) { - x = 1; - } else if ((key == 8) || (key == 9) || (key == 10)) { - x = 2; - } else { - x = -1; - } - - return x; - } - - // Find y-coordinate based on key input - int yGrid() { - int y; - - if ((key == 2) || (key == 6) || (key == 10)) { - y = 0; - } else if ((key == 1) || (key == 5) || (key == 9)) { - y = 1; - } else if ((key == 0) || (key == 4) || (key == 8)) { - y = 2; - } else { - y = -1; - } - - return y; - } - - // Display a certain small grid in a set color - void drawSmallGrid(int x, int y, int color) { - int x1 = 1 + (x * 42) + 1; - int x2 = x1 + 40; - int y1 = 1 + (y * 42) + 1; - int y2 = y1 + 40; - - for (int i = x1; i < x2; i += 14) { - for (int j = y1; j < y2; j += 14) { - uLCD.filled_rectangle(i, j, i + 12, j + 12, color); - } - } - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (grid.smallGrid[x][y].individualGrid[i][j] == 0) { - drawSmallX(x, y, i, j); - } else if (grid.smallGrid[x][y].individualGrid[i][j] == 1) { - drawSmallO(x, y, i, j); - } - } - } - } - - // Draw a line if a player takes a small grid - void drawSmallWinLine(int x1, int y1, int orientation) { - int x2 = x1; - int y2 = y1; - - if (orientation == FORWARDSLASH) { - x2 = x1 - 41; - y2 = y1 + 41; - } else if (orientation == BACKWARDSLASH) { - x2 = x1 + 41; - y2 = y1 + 41; - } else if (orientation == VERTICAL) { - y2 = y1 + 41; - } else if (orientation == HORIZONTAL) { - x2 = x1 + 41; - } - - uLCD.line(x1, y1, x2, y2, GREEN); - wait(1); - } - - // Check whether a player has taken a small grid - bool smallGridWin(int largeX, int largeY, int smallX, int smallY) { - bool taken = false; - char individual[3][3]; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - individual[i][j] = grid.smallGrid[largeX][largeY].individualGrid[i][j]; - } - } - - int x1 = 1 + (largeX * 42) + 1; - int y1 = 1 + (largeY * 42) + 1; - int orientation = -1; - - if ((individual[0][0] == individual[1][1]) && (individual[1][1] == individual[2][2]) && - (individual[0][0] != (char)(-1))) { - orientation = BACKWARDSLASH; - taken = true; - } else if ((individual[2][0] == individual[1][1]) && (individual[1][1] == individual[0][2]) && - (individual[2][0] != (char)(-1))) { - orientation = FORWARDSLASH; - x1 += 40; - taken = true; - } else if ((individual[0][0] == individual[1][0]) && (individual[1][0] == individual[2][0]) && - (individual[0][0] != (char)(-1))) { - orientation = HORIZONTAL; - y1 += 6; - taken = true; - } else if ((individual[0][1] == individual[1][1]) && (individual[1][1] == individual[2][1]) && - (individual[0][1] != (char)(-1))) { - orientation = HORIZONTAL; - y1 += 20; - taken = true; - } else if ((individual[0][2] == individual[1][2]) && (individual[1][2] == individual[2][2]) && - (individual[0][2] != (char)(-1))) { - orientation = HORIZONTAL; - y1 += 34; - taken = true; - } else if ((individual[0][0] == individual[0][1]) && (individual[0][1] == individual[0][2]) && - (individual[0][0] != (char)(-1))) { - orientation = VERTICAL; - x1 += 6; - taken = true; - } else if ((individual[1][0] == individual[1][1]) && (individual[1][1] == individual[1][2]) && - (individual[1][0] != (char)(-1))) { - orientation = VERTICAL; - x1 += 20; - taken = true; - } else if ((individual[2][0] == individual[2][1]) && (individual[2][1] == individual[2][2]) && - (individual[2][0] != (char)(-1))) { - orientation = VERTICAL; - x1 += 34; - taken = true; - } else { - orientation = -1; - taken = false; - } - - // Check to see if there is a draw - if (taken == false) { - bool draw = true; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (individual[i][j] != (char)(-1)) { - draw = false; - } - } - } - - if (draw == true) { - grid.smallGrid[largeX][largeY].done = 128; - } - } - - drawSmallWinLine(x1, y1, orientation); - - return taken; - } - - // Take a turn - void takeTurn(bool turn) { - // Player selects small grid, then individual grid - int keyInputs[2] = {-1, -1}; - - // If it is player one's turn - if (turn == false) { - RGB = RED; - - // Allow user input - keyAllowed = true; - - int largeX = 0; - int largeY = 0; - - key = -1; - - // Wait for player to select small grid - while ((keyInputs[0] == -1) || (grid.smallGrid[largeX][largeY].done != (char)(-1))) { - wait(0.01); - keyInputs[0] = key; - largeX = xGrid(); - largeY = yGrid(); - } - - // Highlight selected grid - drawSmallGrid(largeX, largeY, PINK); - - playSound("/sd/select.wav"); - - // Allow user input - keyAllowed = true; - key = -1; - - // Wait for player to select individual grid - while (keyInputs[1] == -1) { - wait(0.01); - - if (grid.smallGrid[largeX][largeY].individualGrid[xGrid()][yGrid()] == (char)(-1)) { - keyInputs[1] = key; - } - } - - int smallX = xGrid(); - int smallY = yGrid(); - - grid.smallGrid[largeX][largeY].individualGrid[smallX][smallY] = 0; - drawSmallGrid(largeX, largeY, BLACK); - drawSmallX(largeX, largeY, smallX, smallY); - - key = -1; - playSound("/sd/select.wav"); - - // Check if player one has taken a small grid - if (smallGridWin(largeX, largeY, smallX, smallY) == true) { - grid.smallGrid[largeX][largeY].done = 0; - drawLargeX(largeX, largeY); - } else { - bool draw = true; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (grid.smallGrid[largeX][largeY].individualGrid[i][j] == (char)(-1)) { - draw = false; - } - } - } - - if (draw == true) { - grid.smallGrid[largeX][largeY].done = 128; - } - } - // If it is player two's turn - } else { - RGB = BLUE; - - // Allow user input - keyAllowed = true; - - int largeX = 0; - int largeY = 0; - - key = -1; - - // Wait for player to select small grid - while ((keyInputs[0] == -1) || (grid.smallGrid[largeX][largeY].done != (char)(-1))) { - wait(0.01); - keyInputs[0] = key; - largeX = xGrid(); - largeY = yGrid(); - } - - // Highlight selected grid - drawSmallGrid(largeX, largeY, CYAN); - - playSound("/sd/select.wav"); - - // Allow user input - keyAllowed = true; - key = -1; - - // Wait for player to select individual grid - while (keyInputs[1] == -1) { - wait(0.01); - - if (grid.smallGrid[largeX][largeY].individualGrid[xGrid()][yGrid()] == (char)(-1)) { - keyInputs[1] = key; - } - } - - int smallX = xGrid(); - int smallY = yGrid(); - - grid.smallGrid[largeX][largeY].individualGrid[smallX][smallY] = 1; - drawSmallGrid(largeX, largeY, BLACK); - drawSmallO(largeX, largeY, smallX, smallY); - - key = -1; - playSound("/sd/select.wav"); - - // Check if player two has taken a small grid - if (smallGridWin(largeX, largeY, smallX, smallY) == true) { - grid.smallGrid[largeX][largeY].done = 1; - drawLargeO(largeX, largeY); - } else { - bool draw = true; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (grid.smallGrid[largeX][largeY].individualGrid[i][j] == (char)(-1)) { - draw = false; - } - } - } - - if (draw == true) { - grid.smallGrid[largeX][largeY].done = 128; - } - } - } - } - - // Draw final line when a player wins - void drawLargeWinLine(int x1, int y1, int orientation) { - int x2 = 127; - int y2 = 127; - - if (orientation == FORWARDSLASH) { - x2 = 0; - } else if (orientation == HORIZONTAL) { - y2 = y1; - } else if (orientation == VERTICAL) { - x2 = x1; - } - - wait(1); - uLCD.line(x1, y1, x2, y2, GREEN); - wait(3); - } - - // Check whether a player has won - void gameWin(bool turn) { - bool won = false; - char small[3][3]; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - small[i][j] = grid.smallGrid[i][j].done; - } - } - - int x1 = 2; - int y1 = 2; - int orientation = -1; - - if ((small[0][0] == small[1][1]) && (small[1][1] == small[2][2]) && - (small[0][0] != (char)(-1)) && (small[0][0] != 128)) { - orientation = BACKWARDSLASH; - won = true; - } else if ((small[2][0] == small[1][1]) && (small[1][1] == small[0][2]) && - (small[2][0] != (char)(-1)) && (small[2][0] != 128)) { - orientation = FORWARDSLASH; - x1 = 126; - won = true; - } else if ((small[0][0] == small[1][0]) && (small[1][0] == small[2][0]) && - (small[0][0] != (char)(-1)) && (small[0][0] != 128)) { - orientation = HORIZONTAL; - y1 += 21; - won = true; - } else if ((small[0][1] == small[1][1]) && (small[1][1] == small[2][1]) && - (small[0][1] != (char)(-1)) && (small[0][1] != 128)) { - orientation = HORIZONTAL; - y1 += 63; - won = true; - } else if ((small[0][2] == small[1][2]) && (small[1][2] == small[2][2]) && - (small[0][2] != (char)(-1)) && (small[0][2] != 128)) { - orientation = HORIZONTAL; - y1 += 105; - won = true; - } else if ((small[0][0] == small[0][1]) && (small[0][1] == small[0][2]) && - (small[0][0] != (char)(-1)) && (small[0][0] != 128)) { - orientation = VERTICAL; - x1 += 21; - won = true; - } else if ((small[1][0] == small[1][1]) && (small[1][1] == small[1][2]) && - (small[1][0] != (char)(-1)) && (small[1][0] != 128)) { - orientation = VERTICAL; - x1 += 63; - won = true; - } else if ((small[2][0] == small[2][1]) && (small[2][1] == small[2][2]) && - (small[2][0] != (char)(-1)) && (small[2][0] != 128)) { - orientation = VERTICAL; - x1 += 105; - won = true; - } else { - orientation = -1; - won = false; - } - - // Check to see if there is a draw - if (won == false) { - bool draw = true; - - for (int i = 0; i < 3; i++) { - for (int j = 0; j < 3; j++) { - if (small[i][j] == (char)(-1)) { - draw = false; - } - } - } - - if (draw == true) { - grid.done = 128; - } - } else { - if (turn == false) { - grid.done = 0; - } else { - grid.done = 1; - } - - drawLargeWinLine(x1, y1, orientation); - wait(2); - } - } -}; \ No newline at end of file
--- a/main.cpp Sat Nov 28 21:57:03 2015 +0000 +++ b/main.cpp Fri Dec 04 23:03:08 2015 +0000 @@ -1,3 +1,21 @@ +/******************************************************* + * This main program simulates a multi-game multiplayer + * arcade gaming system. The program allows the player + * to choose from four different games: + * + * 1) Simon + * 2) Super Tic-Tac-Toe (first player, the red X) + * 3) Pac-Man + * 4) Rock, Paper, Scissors, Lizard, Spock + * + * All games except Pac-Man communicate with another + * gaming system via an XBee module to simulate + * multiplayer. Pac-Man is multiplayer as well, but the + * characters in the game are controlled using the three + * tactile switches on one board. + *******************************************************/ + + #include "mbed.h" #include "PinDetect.h" #include "SDFileSystem.h" @@ -5,18 +23,14 @@ #include "wave_player.h" #include <mpr121.h> #include "RGBLED.h" -#include "SimonSays.h" -#include "SuperTicTacToe.h" +#include "RedX.h" +#include "Simon.h" #include "Stage.h" #include "Pacman.h" #include "Ghost.h" #include "RPSLK.h" -/* -------------------------------------------------------------------------------------------- - --------------------Global components used in all games with no overlap--------------------- - --------------------------------------------------------------------------------------------*/ - // Speaker AnalogOut DACout(p18); wave_player waver(&DACout); @@ -32,29 +46,15 @@ uLCD_4DGL uLCD(p28, p27, p30); -/* -------------------------------------------------------------------------------------------- - -----------------Variables and functions prototypes used in multiple games------------------ - --------------------------------------------------------------------------------------------*/ - // Select game to play int selectGame(); -/* -------------------------------------------------------------------------------------------- - ----------Rock, Paper, Scissors, Lizard, Spock variables and function prototypes------------ - --------------------------------------------------------------------------------------------*/ - - -/* -------------------------------------------------------------------------------------------- - --------------------------------------Main function----------------------------------------- - --------------------------------------------------------------------------------------------*/ - int main() { - start: - int game = selectGame(); + int gameNumber = selectGame(); // Play Simon Says - if (game == 0) { + if (gameNumber == 0) { // Analog noise AnalogIn noise(p15); @@ -64,22 +64,22 @@ PinDetect button3(p20); PinDetect button4(p16); - SimonSays simon = SimonSays(noise, button1, button2, button3, button4, sd, uLCD, waver); - simon.playSimonSays(); + Simon simon = Simon(noise, reset, button1, button2, button3, button4, sd, XBee, uLCD, waver); + simon.playSimon(); // Play Super Tic-Tac-Toe - } else if (game == 1) { + } else if (gameNumber == 1) { // Touch keypad InterruptIn input(p21); I2C i2c(p9, p10); Mpr121 MPR121(&i2c, Mpr121::ADD_VSS); - + // RGB LED RGBLED RGB(p25, p23, p22); - SuperTicTacToe super = SuperTicTacToe(input, MPR121, RGB, sd, uLCD, waver); - super.playSuperTicTacToe(); + RedX player = RedX(reset, input, MPR121, RGB, sd, XBee, uLCD, waver); + player.playSuperTicTacToe(); // Play Pac-Man - } else if (game == 2) { + } else if (gameNumber == 2) { // Pac-Man controller PinDetect PacmanRight(p9); PinDetect PacmanDown(p10); @@ -106,19 +106,18 @@ stage.initialize(); // Set up Pac-Man - Pacman pacman(PacmanRight, PacmanDown, PacmanLeft, PacmanUp, stage, uLCD); + Pacman pacman(PacmanRight, PacmanDown, PacmanLeft, PacmanUp, stage, uLCD, waver); pacman.initialize(); // Set up the red ghost Ghost redGhost(RED, pacman, redGhostRight, redGhostDown, redGhostLeft, redGhostUp, stage, uLCD); redGhost.initialize(60, 60, FACELEFT); - + // Set up the yellow ghost Ghost yellowGhost(YELLOW, pacman, yellowGhostRight, yellowGhostDown, yellowGhostLeft, yellowGhostUp, stage, uLCD); yellowGhost.initialize(68, 60, FACERIGHT); - - // Wait 3 seconds - wait(3); + + pacman.playSound(THEME); // Checks to see whether the game is over bool gameOver; @@ -152,18 +151,18 @@ RPSLK rpslk = RPSLK(reset, rock, paper, scissors, lizard, spock, sd, XBee, uLCD, waver); rpslk.playRPSLK(); } - - wait(3); - goto start; } -/* -------------------------------------------------------------------------------------------- - ------------------------Functions used in multiple games------------------------------------ - --------------------------------------------------------------------------------------------*/ - // Select game to play int selectGame() { + // Set up XBee + reset = 0; + wait(0.001); + reset = 1; + wait(0.001); + + selection: DigitalIn button1(p17); DigitalIn button2(p19); DigitalIn button3(p20); @@ -208,7 +207,38 @@ gameNumber = 3; break; } - } + } + + uLCD.cls(); + XBee.putc(gameNumber); + int otherGame = -1; + bool print = true; + + if ((gameNumber == 0) || (gameNumber == 1) || (gameNumber == 3)) { + while (otherGame == -1) { + if (XBee.readable() == true) { + otherGame = XBee.getc(); + print = false; + } + + if (print == true) { + uLCD.printf("Waiting for other player..."); + print = false; + } + } + + if (otherGame != gameNumber) { + uLCD.cls(); + uLCD.printf("Sorry, but the "); + uLCD.printf("other player chose"); + uLCD.printf("a different game. "); + uLCD.printf("Returning to game "); + uLCD.printf("selection menu."); + wait(2); + uLCD.cls(); + goto selection; + } + } uLCD.cls(); return gameNumber;