#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH,SCREEN_HEIGHT,&Wire,-1);
#define BTN1 2
#define BTN2 3
#define BTN3 4
#define BTN4 5
#define LED1 6
#define LED2 7
#define LED3 8
#define LED4 9
#define BUZZER 10
#define MAX_SEQUENCE 30
int sequence[MAX_SEQUENCE];
int level = 0;
int userIndex = 0;
const int tones[] = {262,330,392,523};
const int buttons[4] = {BTN1,BTN2,BTN3,BTN4};
const int leds[4] = {LED1,LED2,LED3,LED4};
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(buttons[i],INPUT_PULLUP);
pinMode(leds[i],OUTPUT);
}
pinMode(BUZZER,OUTPUT);
randomSeed(analogRead(A0));
display.begin(SSD1306_SWITCHCAPVCC,0x3C);
display.clearDisplay();
startupScreen();
startupMelody();
delay(1000);
}
void loop() {
startNewGame();
while (true) {
showLevel();
playSequence();
if (!getUserInput()) {
gameOver();
break;
}
level++;
delay(600);
}
}
void startNewGame() {
level = 0;
userIndex = 0;
for (int i=0; i<MAX_SEQUENCE; i++) {
sequence[i] = random(0,4);
}
}
void playSequence() {
for (int i=0; i<=level; i++) {
int step = sequence[i];
digitalWrite(leds[step],HIGH);
tone(BUZZER, tones[step],300);
delay(300);
digitalWrite(leds[step],LOW);
delay(300);
}
}
bool getUserInput() {
userIndex = 0;
while (userIndex <= level) {
int pressed = readButton();
if (pressed != -1) {
digitalWrite(leds[pressed],HIGH);
tone(BUZZER, tones[pressed],300);
delay(500);
digitalWrite(leds[pressed],LOW);
if (pressed != sequence[userIndex]) {
return false;
}
userIndex++;
}
}
return true;
}
int readButton() {
for (int i=0; i<4; i++) {
if (digitalRead(buttons[i]) == LOW) {
while (digitalRead(buttons[i]) == LOW);
delay(20);
return i;
}
}
return -1;
}
void startupScreen() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(38,6);
display.println("Get Ready");
display.setCursor(44,20);
display.println("To Play");
display.setCursor(34,34);
display.println("\"Who Says?\"");
display.setCursor(30,48);
display.println("\"Simon Says!\"");
display.display();
delay(2500);
display.clearDisplay();
display.setCursor(19,19);
display.println("by DIY Machines");
display.setCursor(43,39);
display.println("& by JMA");
display.display();
delay(2500);
}
void showLevel() {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(18,22);
display.print("Level ");
display.print(level+1);
display.display();
}
void gameOver() {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(32,10);
display.println("Oh No!");
display.setCursor(12,30);
display.println("Game Over");
display.display();
gameOverTones();
delay(1500);
display.clearDisplay();
display.setTextSize(2);
display.setCursor(36,2);
display.print("Final");
display.setCursor(36,20);
display.print("Score");
if (level<10){
display.setCursor(54,44);
display.print("0");
display.setCursor(68,44);
display.print(level);
display.display();
}
else{
display.setCursor(56,44);
display.print(level);
display.display();
}
delay(4000);
display.clearDisplay();
display.setTextSize(2);
display.setCursor(10,20);
display.println("Try Again");
display.display();
delay(3000);
}
void startupMelody() {
int melody[] = {262,330,392,523};
for (int i=0; i<4; i++) {
tone(BUZZER,melody[i],200);
delay(150);
}
}
void gameOverTones() {
tone(BUZZER,523,800);
delay(500);
tone(BUZZER,392,800);
delay(500);
tone(BUZZER,262,1200);
}