// --- PIN DEFINITIONS ---
const int ledPins[] = {2, 3, 4, 5, 6};
const int switchPins[] = {8, 9, 10, 11, 12};
const int numSwitches = 5;
// --- GAME STATE VARIABLES ---
int expectedSwitch = 1;
int lastSwitchPressed = 0;
String outputString = "";
// --- NON-BLOCKING LED TIMER VARIABLES ---
unsigned long ledOnTime = 0;
int activeLedPin = -1;
const long ledInterval = 500; // How long an LED stays on (1000ms = 1 second)
// --- ROBUST DEBOUNCE VARIABLES ---
int buttonState[numSwitches];
// Initialize lastButtonState to HIGH (unpressed) for all switches
int lastButtonState[numSwitches] = {HIGH, HIGH, HIGH, HIGH, HIGH};
unsigned long lastDebounceTime[numSwitches] = {0};
unsigned long debounceDelay = 50; // 50 millisecond debounce period
//================================================================
//  SETUP FUNCTION - Runs once at the beginning
//================================================================
void setup() {
  Serial.begin(9600);
  Serial.println("Arduino Sequence Started.");
  Serial.println("Press Switch 1 to begin.");
  for (int i = 0; i < numSwitches; i++) {
    pinMode(ledPins[i], OUTPUT);
    pinMode(switchPins[i], INPUT_PULLUP);
  }
}
//================================================================
//  MAIN LOOP - Runs continuously
//================================================================
void loop() {
  // Check if it's time to turn an active LED off
  if (activeLedPin != -1) {
    if (millis() - ledOnTime >= ledInterval) {
      digitalWrite(activeLedPin, LOW);
      activeLedPin = -1; // Reset the tracker
    }
  }
  // Check all switches with robust debouncing
  for (int i = 0; i < numSwitches; i++) {
    int reading = digitalRead(switchPins[i]);
    // If the switch state has changed (due to press or bounce), reset the debounce timer
    if (reading != lastButtonState[i]) {
      lastDebounceTime[i] = millis();
    }
    // After the reading has been stable for longer than the debounce delay...
    if ((millis() - lastDebounceTime[i]) > debounceDelay) {
      // ...and if the state has truly changed...
      if (reading != buttonState[i]) {
        buttonState[i] = reading;
        // ...and if the button was just pressed (transitioned from HIGH to LOW)...
        if (buttonState[i] == LOW) {
          processSwitchPress(i); // ...then process it as a single, valid press.
        }
      }
    }
    lastButtonState[i] = reading;
  }
}
//================================================================
//  PROCESS SWITCH PRESS - Handles the game logic and feedback
//================================================================
void processSwitchPress(int switchIndex){
   //Serial.print("\nPressed switch ");
  //Serial.println(switchIndex+1); 
  // If another LED is on, turn it off immediately before turning the new one on
  if (activeLedPin != -1) {
    digitalWrite(activeLedPin, LOW);
  }
  int currentSwitch = switchIndex + 1;
  // --- Game Logic ---
  if (currentSwitch == lastSwitchPressed) {
    outputString += "0";
    Serial.print("\r" + outputString);
    lastSwitchPressed = 0;
  }
  else if (currentSwitch == expectedSwitch) {
    outputString += "1";
    Serial.print("\r" + outputString);
    lastSwitchPressed = currentSwitch;
    expectedSwitch++;
    if (expectedSwitch > numSwitches) {
      Serial.println("\nSequence Complete. Resetting.");
      resetSequence();
    }
  }
  else {
    Serial.println("\nError. Sequence Resetting.");
    resetSequence();
  }
  // --- Visual Feedback ---
  // Turn the new LED on and start its timer
  digitalWrite(ledPins[switchIndex], HIGH);
  activeLedPin = ledPins[switchIndex];
  ledOnTime = millis();
}
//================================================================
//  RESET SEQUENCE - Resets game variables to their initial state
//================================================================
void resetSequence() {
  expectedSwitch = 1;
  lastSwitchPressed = 0;
  outputString = "";
}