#include <ESP32Servo.h>
// LED pins
int leds[] = {14, 25, 26, 27};
// Button pins
int buttons[] = {32, 33, 18, 19};
// Servo
Servo myServo;
int servoPin = 13;
// Buzzer
int buzzerPin = 23;
// Game variables
int sequence[100];
int level = 0;
// Player data
String playerName;
int totalSets = 3;
// Timing storage
unsigned long reactionTimes[100];
void setup() {
Serial.begin(115200);
for (int i = 0; i < 4; i++) {
pinMode(leds[i], OUTPUT);
pinMode(buttons[i], INPUT_PULLUP);
}
pinMode(buzzerPin, OUTPUT);
digitalWrite(buzzerPin, LOW);
myServo.attach(servoPin);
myServo.write(0);
randomSeed(esp_random());
getPlayerName();
}
void loop() {
Serial.println("\nStarting Game...");
for (int set = 1; set <= totalSets; set++) {
Serial.println("\nSet: " + String(set));
level = 0;
while (true) {
nextLevel();
showSequence();
if (!checkUserInput()) {
gameOver();
break;
}
}
delay(2000);
}
Serial.println("\nGame Finished for " + playerName);
waitForStart(); // restart system
}
// 🟢 Get Player Name
void getPlayerName() {
Serial.println("Enter Player Name:");
while (Serial.available() == 0);
playerName = Serial.readStringUntil('\n');
playerName.trim();
Serial.println("Welcome, " + playerName);
waitForStart();
}
// 🟢 Wait for start
void waitForStart() {
Serial.println("Press any button to start...");
while (true) {
// blinking LEDs
for (int j = 0; j < 4; j++) digitalWrite(leds[j], HIGH);
delay(200);
for (int j = 0; j < 4; j++) digitalWrite(leds[j], LOW);
delay(200);
// detect button press
for (int i = 0; i < 4; i++) {
if (digitalRead(buttons[i]) == LOW) {
delay(200);
while (digitalRead(buttons[i]) == LOW);
return;
}
}
}
}
// 🟢 Smart random generator
int getSmartRandom() {
int newVal;
while (true) {
newVal = random(0, 4);
if (level > 0 && newVal == sequence[level - 1]) continue;
if (level > 1 && newVal == sequence[level - 2]) continue;
return newVal;
}
}
void nextLevel() {
sequence[level] = getSmartRandom();
level++;
}
// 🟢 Show sequence
void showSequence() {
delay(500);
for (int i = 0; i < level; i++) {
digitalWrite(leds[sequence[i]], HIGH);
delay(500);
digitalWrite(leds[sequence[i]], LOW);
delay(300);
}
}
// 🟢 Button + timing capture
int getButtonPress(unsigned long &timeStamp) {
while (true) {
for (int i = 0; i < 4; i++) {
if (digitalRead(buttons[i]) == LOW) {
delay(50);
timeStamp = millis();
while (digitalRead(buttons[i]) == LOW);
return i;
}
}
}
}
// 🟢 Check user input + timing
bool checkUserInput() {
unsigned long t0 = 0;
for (int i = 0; i < level; i++) {
unsigned long pressTime;
int input = getButtonPress(pressTime);
if (i == 0) {
t0 = pressTime;
reactionTimes[i] = 0;
} else {
reactionTimes[i] = pressTime - t0;
}
// LED feedback
digitalWrite(leds[input], HIGH);
delay(300);
digitalWrite(leds[input], LOW);
if (input != sequence[i]) {
printTimings(i);
return false;
}
}
printTimings(level);
return true;
}
// 🟢 Print timings
void printTimings(int count) {
Serial.println("Reaction Times (ms):");
for (int i = 0; i < count; i++) {
Serial.print(reactionTimes[i]);
Serial.print(" ");
}
Serial.println();
}
// 🔊 Buzzer function
void buzzWrong() {
for (int i = 0; i < 3; i++) {
digitalWrite(buzzerPin, HIGH);
delay(200);
digitalWrite(buzzerPin, LOW);
delay(150);
}
}
// 🟢 Game over
void gameOver() {
Serial.println("Game Over!");
// 🔊 Buzzer alert
buzzWrong();
// 🤖 Servo action
myServo.write(90);
delay(1000);
myServo.write(0);
delay(500);
// 💡 LED flashing
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) digitalWrite(leds[j], HIGH);
delay(300);
for (int j = 0; j < 4; j++) digitalWrite(leds[j], LOW);
delay(300);
}
}