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