/** Simon Game for ESP32 with Score display Copyright (C) 2022, Uri Shaked Released under the MIT License. */ /* Constants - define pin numbers for LEDs, buttons and speaker, and also the game tones: */ const uint8_t ledPins[] = {2, 4, 5, 15}; // Updated to use ESP32 GPIO pins const uint8_t buttonPins[] = {23, 22, 21, 19}; // Button pin assignments #define MAX_GAME_LENGTH 100 /* Global variables - store the game state */ uint8_t gameSequence[MAX_GAME_LENGTH] = {0}; uint8_t gameIndex = 0; /** Set up the ESP32 board and initialize Serial communication */ void setup() { Serial.begin(9600); for (byte i = 0; i < 4; i++) { pinMode(ledPins[i], OUTPUT); pinMode(buttonPins[i], INPUT_PULLUP); } // The following line primes the random number generator. randomSeed(analogRead(36)); // Use a floating analog pin for randomness } /** Lights the given LED and plays a suitable tone */ void lightLedAndPlayTone(byte ledIndex) { digitalWrite(ledPins[ledIndex], HIGH); delay(300); digitalWrite(ledPins[ledIndex], LOW); } /** Plays the current sequence of notes that the user has to repeat */ void playSequence() { for (int i = 0; i < gameIndex; i++) { byte currentLed = gameSequence[i]; lightLedAndPlayTone(currentLed); delay(50); } } /** Waits until the user presses one of the buttons, and returns the index of that button */ byte readButtons() { while (true) { for (byte i = 0; i < 4; i++) { byte buttonPin = buttonPins[i]; if (digitalRead(buttonPin) == LOW) { return i; } } delay(1); } } /** Play the game over sequence, and report the game score */ void gameOver() { Serial.print("Game over! Your score: "); Serial.println(gameIndex - 1); gameIndex = 0; delay(200); } /** Get the user's input and compare it with the expected sequence. */ bool checkUserSequence() { for (int i = 0; i < gameIndex; i++) { byte expectedButton = gameSequence[i]; byte actualButton = readButtons(); lightLedAndPlayTone(actualButton); if (expectedButton != actualButton) { return false; } } return true; } /** The main game loop */ void loop() { // Add a random color to the end of the sequence gameSequence[gameIndex] = random(0, 4); gameIndex++; if (gameIndex >= MAX_GAME_LENGTH) { gameIndex = MAX_GAME_LENGTH - 1; } playSequence(); if (!checkUserSequence()) { gameOver(); } delay(300); }