For this code, briefly explain each body: // --- VARIABLES AND CONSTANTS DECLARATION --- // 

// Button and LED pins 
const int buttonPins[] = {12, 10, 8, 4};
const int ledPins[] = {13, 11, 9, 7};
const int tones[] = {265, 330, 392, 494}; // C, E, G, B tones

// RGB LED (Common Anode - only red and blue used)
const int redRGB = 6;
const int blueRGB = 5;

// Buzzer pin
const int buzzerPin = 3;

// 7-Segment Display pins
const int segA = A3;
const int segB = A4;
const int segC = A5;
const int segD = A0;
const int segE = 2;
const int segF = A2;
const int segG = A1;

// Game configuration
const int roundsToWin = 5;
int sequence[6];
int roundCounter = 1;
int pressedButton = 4; // 4 = no button pressed
long startTime = 0;
long timeLimit = 2000;
bool gameStarted = false;

// --- FUNCTION DEFINITIONS --- //

void setup() {
  for (int i = 0; i < 4; i++) {
    pinMode(buttonPins[i], INPUT);
    pinMode(ledPins[i], OUTPUT);
  }
  pinMode(redRGB, OUTPUT);
  pinMode(blueRGB, OUTPUT);
  pinMode(buzzerPin, OUTPUT);

  int segPins[] = {segA, segB, segC, segD, segE, segF, segG};
  for (int i = 0; i < 7; i++) {
    pinMode(segPins[i], OUTPUT);
  }
}

// 7-segment display digits
void showDigit(bool a, bool b, bool c, bool d, bool e, bool f, bool g) {
  digitalWrite(segA, a);
  digitalWrite(segB, b);
  digitalWrite(segC, c);
  digitalWrite(segD, d);
  digitalWrite(segE, e);
  digitalWrite(segF, f);
  digitalWrite(segG, g);
}

void smiley() { showDigit(0, 1, 0, 1, 0, 1, 1); }
void one()    { showDigit(1, 1, 1, 1, 0, 0, 1); }
void two()    { showDigit(0, 0, 1, 0, 0, 1, 0); }
void three()  { showDigit(0, 1, 1, 0, 0, 0, 0); }
void four()   { showDigit(1, 1, 0, 1, 0, 0, 0); }
void five()   { showDigit(0, 1, 0, 0, 1, 0, 0); }

// Round number display using function pointer array
typedef void (*DigitFunc)();
DigitFunc roundDisplay[] = {smiley, one, two, three, four, five};

// Sets LED and buzzer for a pressed button
void flashLED(int index) {
  digitalWrite(ledPins[index], HIGH);
  tone(buzzerPin, tones[index]);
  delay(200);
  digitalWrite(ledPins[index], LOW);
  noTone(buzzerPin);
}

// Lights all LEDs on/off
void setAllLEDs(bool on) {
  for (int i = 0; i < 4; i++) {
    digitalWrite(ledPins[i], on ? HIGH : LOW);
  }
}

// Set RGB color (R/B only due to common anode)
void setRGB(int r, int b) {
  analogWrite(redRGB, r);
  analogWrite(blueRGB, b);
}

// Detects which button is pressed
int getButtonPressed() {
  for (int i = 0; i < 4; i++) {
    if (digitalRead(buttonPins[i]) == HIGH) {
      tone(buzzerPin, tones[i]);
      return i;
    }
  }
  return 4;
}

// Plays losing melody
void playLoseMelody() {
  int tones[] = {130, 73, 65, 98};
  int durations[] = {250, 250, 150, 500};
  for (int i = 0; i < 4; i++) {
    tone(buzzerPin, tones[i], durations[i]);
    delay(durations[i] + 25);
  }
}

// Plays winning melody
void playWinMelody() {
  int tones[] = {1318, 1567, 2637, 2093, 2349, 3135};
  int durations[] = {150, 150, 150, 150, 150, 500};
  for (int i = 0; i < 6; i++) {
    tone(buzzerPin, tones[i], durations[i]);
    delay(durations[i] + 25);
  }
}

// Flash all LEDs before game starts
void flashStartLEDs() {
  for (int i = 0; i < 4; i++) {
    tone(buzzerPin, tones[i], 200);
    setAllLEDs(true);
    delay(100);
    setAllLEDs(false);
    delay(100);
  }
}

void startSequence() {
  while (getButtonPressed() == 4) {
    setRGB(255, 255);
  }
  delay(100);

  for (int i = 0; i <= roundsToWin; i++) {
    sequence[i] = random(0, 4);
  }
  flashStartLEDs();
  smiley();
}

void loseSequence() {
  delay(100);
  setRGB(0, 255);
  delay(250);
  setRGB(255, 255);
  smiley();
  playLoseMelody();
  while (getButtonPressed() == 4);
  delay(100);
  gameStarted = false;
}

void winSequence() {
  delay(100);
  setRGB(255, 0);
  delay(1000);
  setRGB(255, 255);
  smiley();
  playWinMelody();
  while (getButtonPressed() == 4);
  delay(100);
  gameStarted = false;
}

// --- MAIN LOOP --- //

void loop() {
  if (!gameStarted) {
    startSequence();
    roundCounter = 0;
    delay(1500);
    gameStarted = true;
  }

  roundDisplay[roundCounter + 1]();

  for (int i = 0; i <= roundCounter; i++) {
    flashLED(sequence[i]);
    delay(200);
  }

  for (int i = 0; i <= roundCounter; i++) {
    startTime = millis();
    while (true) {
      pressedButton = getButtonPressed();
      if (pressedButton < 4) {
        flashLED(pressedButton);
        if (pressedButton == sequence[i]) {
          delay(250);
          break;
        } else {
          loseSequence();
          return;
        }
      }
      if (millis() - startTime > timeLimit) {
        loseSequence();
        return;
      }
    }
  }

  roundCounter++;
  if (roundCounter >= roundsToWin) {
    winSequence();
  }
  delay(500);
}
