// ------------------------------------------------------
// Sketch to imitate a simple Simon game.
// ------------------------------------------------------
#include <Arduino.h>
#include <TM1637.h>
// Define pins for LEDs and buttons
const uint8_t ledPins[] = {2, 3, 4, 5};
const uint8_t buttonPins[] = {6, 7, 8, 9};
// Define PWM-capable pin for sound
const int tonePin = 11;
// Tones for each color
const int tones[] = {262, 330, 392, 523}; // C, E, G, C
// Define the number of LEDs and buttons
const int numLEDs = 4;
const int numButtons = 4;
// Array to store the current sequence
uint8_t sequence[100]; // The more elements, the more level but less saves memory
uint8_t sequenceLength = 0;
const int CLK = 12;
const int DIO = 13;
TM1637 tm(CLK, DIO);
void setup() {
// Initialize the LEDs as outputs and the buttons as inputs
for (int i = 0; i < numLEDs; i++) {
pinMode(ledPins[i], OUTPUT);
digitalWrite(ledPins[i], LOW);
}
for (int i = 0; i < numButtons; i++) {
pinMode(buttonPins[i], INPUT_PULLUP);
}
// Initialize the sound
pinMode(tonePin, OUTPUT);
noTone(tonePin);
// Initialize the random function
randomSeed(analogRead(0));
tm.init();
tm.set(BRIGHT_TYPICAL);
// Initialize display
tm.display(0, (sequenceLength / 1000) % 10);
tm.display(1, (sequenceLength / 100) % 10);
tm.display(2, (sequenceLength / 10) % 10);
tm.display(3, sequenceLength % 10);
// Startup blinking sequence
for (int n = 0; n < 2; n++) {
for (int i = 0; i < 4; i++) {
digitalWrite(ledPins[i], HIGH);
delay(100);
digitalWrite(ledPins[i], LOW);
delay(200);
}
}
delay(600);
}
void loop() {
// display the level number
tm.display(0, (sequenceLength / 1000) % 10);
tm.display(1, (sequenceLength / 100) % 10);
tm.display(2, (sequenceLength / 10) % 10);
tm.display(3, sequenceLength % 10);
// Generate a random sequence
generateSequence();
// Play the current sequence
playSequence();
// Check user input
if (checkInput()) {
// Correct input
} else {
// Incorrect input, reset the game
gameover(); // Provide feedback for incorrect input
sequenceLength = 0;
}
}
void generateSequence() {
// Add the new random number to the end of the array
if (sequenceLength < sizeof(sequence)) { // Ensure the array does not overflow
sequence[sequenceLength++] = random(0, numLEDs); // Add a new random number and increase the length of the array
}
}
void playSequence() {
for (int i = 0; i < sequenceLength; i++) {
digitalWrite(ledPins[sequence[i]], HIGH);
tone(tonePin, tones[sequence[i]]); // Play tone
delay(400); // Turn on LED and tone for 400 milliseconds
digitalWrite(ledPins[sequence[i]], LOW);
noTone(tonePin); // Stop tone
delay(300); // Pause between LEDs
}
}
bool checkInput() {
int buttonPressed;
for (int i = 0; i < sequenceLength; i++) {
buttonPressed = waitForButton(); // Wait for button press
if (buttonPressed != sequence[i]) {
playIncorrectTone(buttonPressed); // Play incorrect tone for wrong input
return false; // Incorrect input
} else {
playCorrectTone(buttonPressed); // Play correct tone for correct input
}
delay(200); // Delay between button presses
}
delay(500);
return true; // Correct input
}
void playCorrectTone(int buttonIndex) {
digitalWrite(ledPins[buttonIndex], HIGH);
tone(tonePin, tones[buttonIndex]);
delay(400); // Tone duration
noTone(tonePin);
digitalWrite(ledPins[buttonIndex], LOW);
}
void playIncorrectTone(int buttonIndex) {
tone(tonePin, 100); // Incorrect tone
delay(600); // Tone duration
noTone(tonePin);
digitalWrite(ledPins[buttonIndex], LOW);
}
int waitForButton() {
while (true) {
for (int i = 0; i < numButtons; i++) {
if (digitalRead(buttonPins[i]) == LOW) {
// Button pressed
delay(50); // Debouncing
return i;
}
}
}
}
void gameover() {
// Blink the LEDs and play tone C three times
for (int j = 0; j < 3; j++) {
for (int i = 0; i < numLEDs; i++) {
digitalWrite(ledPins[i], HIGH);
}
tone(tonePin, 262); // Play tone C
delay(200);
for (int i = 0; i < numLEDs; i++) {
digitalWrite(ledPins[i], LOW);
}
noTone(tonePin);
delay(200);
}
delay(800);
}