Multi-game multiplayer arcade gaming system meant for the blue O when playing Super Tic-Tac-Toe.
Dependencies: 4DGL-uLCD-SE PinDetect SDFileSystem mbed wave_player
Simon.h
- Committer:
- soapy12312
- Date:
- 2015-12-04
- Revision:
- 2:da0f01fbd25c
File content as of revision 2:da0f01fbd25c:
/****************************************************** * 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); } } };