#include <Adafruit_NeoPixel.h>
#include "pitches.h"
// Define ENDOFSONG to indicate the end of a song sequence
#define ENDOFSONG -1
// NeoPixel setup
#define PIXEL_PIN 6
#define NUMPIXELS 40
Adafruit_NeoPixel pixels(NUMPIXELS, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
// Button setup (connect to GND and use INPUT_PULLUP)
const int BUTTON_PINS[7] = {2, 3, 4, 5, 7, 8, 9}; // 7 buttons
const int BUZZER_PIN = 10;
const int FADEINDURATION = 200;
const int FADEOUTDURATION = 150;
const int PAUSEB4SEQ = 500;
const int SEQDELAY = 50;
const int MINLEVEL = 2;
const int MAXLEVEL = 16;
int gameLevel;
int simonSez[MAXLEVEL];
const int NOTES[7] = {NOTE_C4, NOTE_D4, NOTE_E4, NOTE_F4, NOTE_G4, NOTE_A4, NOTE_B4};
// Group pixel ranges
int groupStart[7] = {0, 8, 15, 21, 26, 30, 34};
int groupEnd[7] = {7, 14, 20, 25, 29, 33, 36};
void setup() {
Serial.begin(9600);
pixels.begin();
pixels.show(); // Initialize all pixels to 'off'
pinMode(BUZZER_PIN, OUTPUT);
// Set button pins as input with pull-up resistors
for (int i = 0; i < 7; i++) {
pinMode(BUTTON_PINS[i], INPUT_PULLUP);
}
randomSeed(analogRead(A0)); // Seed for randomization
gameLevel = MINLEVEL;
setGroupColors(); // Set initial colors for each group
playWinSequence(); // Initial feedback to confirm startup
}
void loop() {
initGameSequence(gameLevel);
while (true) {
waitForButtonPress(); // Wait for the first button press to start
delay(PAUSEB4SEQ);
playGameSequence(gameLevel);
if (playerGuess(gameLevel)) {
playCorrectSequence();
if (++gameLevel > MAXLEVEL) {
playWinSequence();
while (true); // Game over, wait for manual reset
}
} else {
playLoseSequence();
gameLevel = MINLEVEL;
}
}
}
void setGroupColors() {
setColorRange(0, 7, pixels.Color(255, 0, 0)); // Red
setColorRange(8, 14, pixels.Color(255, 165, 0)); // Orange
setColorRange(15, 20, pixels.Color(255, 255, 0)); // Yellow
setColorRange(21, 25, pixels.Color(173, 216, 230)); // Light Blue
setColorRange(26, 29, pixels.Color(0, 0, 139)); // Dark Blue
setColorRange(30, 33, pixels.Color(128, 0, 128)); // Purple
pixels.show();
}
void setColorRange(int start, int end, uint32_t color) {
for (int i = start; i <= end; i++) {
pixels.setPixelColor(i, color);
}
}
void waitForButtonPress() {
while (true) {
if (anyButtonPressed()) break;
}
}
bool anyButtonPressed() {
for (int i = 0; i < 7; i++) {
if (digitalRead(BUTTON_PINS[i]) == LOW) {
Serial.print("Button ");
Serial.print(i);
Serial.println(" pressed!");
return true;
}
}
return false;
}
void initGameSequence(int level) {
for (int i = 0; i < level; i++) {
simonSez[i] = random(7);
}
}
void playGameSequence(int level) {
Serial.print("Sequence: ");
for (int i = 0; i < level; i++) {
playGroup(simonSez[i]);
Serial.print(simonSez[i]);
if (i < level - 1) Serial.print(", ");
}
Serial.println();
}
void playGroup(int group) {
int start = groupStart[group];
int end = groupEnd[group];
for (int i = start; i <= end; i++) {
pixels.setPixelColor(i, pixels.Color(255, 255, 255)); // Flash white
}
pixels.show();
tone(BUZZER_PIN, NOTES[group], 100);
delay(FADEINDURATION);
setGroupColors(); // Restore original group colors
pixels.show();
delay(FADEOUTDURATION);
}
bool playerGuess(int level) {
for (int i = 0; i < level; i++) {
int guess = getButtonPress();
if (guess != simonSez[i]) return false;
playGroup(guess);
}
return true;
}
int getButtonPress() {
while (true) {
for (int i = 0; i < 7; i++) {
if (digitalRead(BUTTON_PINS[i]) == LOW) {
Serial.print("Button ");
Serial.print(i);
Serial.println(" released!");
while (digitalRead(BUTTON_PINS[i]) == LOW); // Wait for release
return i;
}
}
}
}
void playSong(int song[][3]) {
for (int i = 0; song[i][0] != ENDOFSONG; i++) {
int note = song[i][0];
int duration = song[i][1] * 125;
int group = song[i][2];
if (note > 0) tone(BUZZER_PIN, note, duration);
playGroup(group);
delay(duration);
noTone(BUZZER_PIN);
}
}
void playWinSequence() {
int WINSONG[][3] = {{NOTE_C4, 1, 0}, {NOTE_D4, 1, 1}, {NOTE_E4, 1, 2}, {ENDOFSONG, ENDOFSONG, ENDOFSONG}};
playSong(WINSONG);
Serial.println("You won!");
}
void playLoseSequence() {
int LOSESONG[][3] = {{NOTE_A4, 2, 6}, {NOTE_G4, 2, 5}, {NOTE_F4, 2, 4}, {ENDOFSONG, ENDOFSONG, ENDOFSONG}};
playSong(LOSESONG);
Serial.println("You lost!");
}
void playCorrectSequence() {
Serial.println("Correct!");
}