#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
const int ledPins[4] = {2, 3, 4, 5};
const int buttonPins[4] = {6, 7, 8, 9};
const int buzzerPin = 10;
const int tones[4] = {440, 554, 622, 880}; // A4, C#5, D#5, A5
int sequence[100];
int sequenceLength = 0;
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
pinMode(buttonPins[i], INPUT_PULLUP);
}
pinMode(buzzerPin, OUTPUT);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Simon Says");
playStartMelody(); // ▶ Startmelodie
delay(2000);
lcd.clear();
randomSeed(analogRead(0));
}
void loop() {
delay(1000);
sequence[sequenceLength] = random(0, 4);
sequenceLength++;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Level: ");
lcd.print(sequenceLength);
playSequence();
if (!getUserInput()) {
gameOver();
sequenceLength = 0;
}
else {
// Mario-Pilz-Sound bei Level 7, 14, 21
if (sequenceLength == 7 || sequenceLength == 14 || sequenceLength == 21)
{playPowerUpSound();
}
}
}
void playSequence() {
static int lastSpeedStep = -1;
int pauseStep = min(sequenceLength / 7, 3);
int pauseDuration = 200 - pauseStep * 20;
if (pauseStep != lastSpeedStep && pauseStep > 0) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Speed up!");
delay(1000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Level: ");
lcd.print(sequenceLength);
lastSpeedStep = pauseStep;
}
for (int i = 0; i < sequenceLength; i++) {
int led = sequence[i];
digitalWrite(ledPins[led], HIGH);
tone(buzzerPin, tones[led], 200);
delay(200);
digitalWrite(ledPins[led], LOW);
delay(pauseDuration);
}
}
bool getUserInput() {
for (int i = 0; i < sequenceLength; i++) {
int input = waitForButton();
if (input != sequence[i]) return false;
}
return true;
}
int waitForButton() {
while (true) {
for (int i = 0; i < 4; i++) {
if (digitalRead(buttonPins[i]) == LOW) {
digitalWrite(ledPins[i], HIGH);
tone(buzzerPin, tones[i], 200);
delay(400);
digitalWrite(ledPins[i], LOW);
while (digitalRead(buttonPins[i]) == LOW);
delay(100);
return i;
}
}
}
}
void gameOverLEDSequence() {
// 1. Äußere LEDs an (Pin 5 ist links, also index 3 und 0)
digitalWrite(ledPins[3], HIGH);
digitalWrite(ledPins[0], HIGH);
delay(200);
digitalWrite(ledPins[3], LOW);
digitalWrite(ledPins[0], LOW);
delay(0);
// 2. Alle LEDs an
for (int i = 0; i < 4; i++) digitalWrite(ledPins[i], HIGH);
delay(200);
for (int i = 0; i < 4; i++) digitalWrite(ledPins[i], LOW);
delay(0);
// 3. Mittlere LEDs an (index 1 und 2)
digitalWrite(ledPins[1], HIGH);
digitalWrite(ledPins[2], HIGH);
delay(200);
digitalWrite(ledPins[1], LOW);
digitalWrite(ledPins[2], LOW);
delay(200);
// 4. Verlauf von links nach rechts (Pin 5 ist links = index 3 runter bis 0)
for (int i = 3; i >= 0; i--) {
digitalWrite(ledPins[i], HIGH);
delay(250);
digitalWrite(ledPins[i], LOW);
}
delay(200);
// 5. 2x alle LEDs zusammen blinken
for (int count = 0; count < 4; count++) {
for (int i = 0; i < 4; i++) digitalWrite(ledPins[i], HIGH);
delay(200);
for (int i = 0; i < 4; i++) digitalWrite(ledPins[i], LOW);
delay(200);
}
}
void gameOver() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Game Over!");
lcd.setCursor(0, 1);
lcd.print("Level: ");
lcd.print(sequenceLength);
gameOverLEDSequence();
delay(1000);
playGameOverMelody(); // ▶ Individuelle Melodie
lcd.clear();
lcd.setCursor(0, 0);
if (sequenceLength <= 5) {
lcd.print("a little bit sad...");
} else if (sequenceLength <= 10) {
lcd.print("Not bad!");
} else if (sequenceLength <= 15) {
lcd.print("Impressive!");
} else {
lcd.print("Simon Master!");
}
delay(3000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Simon Says");
}
// ▶ Startmelodie
void playStartMelody() {
tone(buzzerPin, 880, 150); // A5
delay(200);
tone(buzzerPin, 988, 150); // B5
delay(200);
tone(buzzerPin, 1046, 150); // C6
delay(200);
tone(buzzerPin, 1318, 300); // E6
delay(350);
tone(buzzerPin, 1046, 200); // C6
delay(250);
}
// ▶ Game Over Melodien je nach Score
void playGameOverMelody() {
if (sequenceLength <= 5) {
// Wah-Wah-Wah-Wah Melodie
tone(buzzerPin, 622); // NOTE_DS5
delay(300);
tone(buzzerPin, 587); // NOTE_D5
delay(300);
tone(buzzerPin, 554); // NOTE_CS5
delay(300);
for (byte i = 0; i < 10; i++) {
for (int pitch = -10; pitch <= 10; pitch++) {
tone(buzzerPin, 523 + pitch); // NOTE_C5 + pitch
delay(5);
}
}
noTone(buzzerPin); // Ton beenden
} else if (sequenceLength <= 10) {
tone(buzzerPin, 330, 200);
delay(250);
tone(buzzerPin, 440, 200);
delay(250);
tone(buzzerPin, 392, 300);
delay(300);
} else if (sequenceLength <= 15) {
tone(buzzerPin, 523, 200); // C5
delay(250);
tone(buzzerPin, 622, 200); // D#5
delay(250);
tone(buzzerPin, 784, 400); // G5
delay(400);
} else {
tone(buzzerPin, 659, 150); // E5
delay(150);
tone(buzzerPin, 784, 150); // G5
delay(150);
tone(buzzerPin, 880, 150); // A5
delay(150);
tone(buzzerPin, 698, 150); // F5
delay(150);
tone(buzzerPin, 784, 150); // G5
delay(150);
tone(buzzerPin, 659, 150); // E5
delay(150);
tone(buzzerPin, 523, 150); // C5
delay(150);
tone(buzzerPin, 587, 150); // D5
delay(150);
tone(buzzerPin, 494, 300); // B4
delay(300);
}
}
void playPowerUpSound() {
tone(buzzerPin, 1319, 100); // E6
delay(150);
tone(buzzerPin, 1568, 100); // G6
delay(150);
tone(buzzerPin, 1760, 100); // A6
delay(150);
tone(buzzerPin, 2093, 100); // C7
delay(200);
noTone(buzzerPin);
}