#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Pin Definitions
const int BUTTON_PINS[] = {8, 9, 10, 11}; // Buttons
const int LED_PINS[] = {2, 3, 4, 5}; // LEDs
const int BUZZER_PIN = 6; // Buzzer pin
// Initialize LCD
LiquidCrystal_I2C lcd(0x27, 16, 2); // Address 0x27, 16 columns, 2 rows
// Game variables
int sequence[50];
int userInput[50];
int sequenceLength = 0;
int score = 0;
int highScore = 0;
bool gameOver = false;
bool mode_2=false;
unsigned long time=0;
float avg_time=0;
void setup() {
// Initialize serial communication
Serial.begin(9600);
// Initialize LCD
lcd.init();
lcd.backlight();
// Set button pins as inputs with pull-down resistors
for (int i = 0; i < 4; i++) {
DDRB&=~(1<<(BUTTON_PINS[i]-8));
PORTB|=(1<<(BUTTON_PINS[i]-8));
//pinMode(BUTTON_PINS[i], INPUT_PULLUP);
}
// Set LED pins as outputs
for (int i = 0; i < 4; i++) {
DDRD|=(1<<LED_PINS[i]);
//pinMode(LED_PINS[i], OUTPUT);
}
// Set buzzer pin as output
DDRD|=(1<<BUZZER_PIN);
//pinMode(BUZZER_PIN, OUTPUT);
// Seed random number generator
randomSeed(analogRead(0));
// Display initial message
}
void loop() {
displayMessage("BLUE MODE 1", "YELLO MODE 2");
while(1){
if(!( PINB & (1<<1)))
{
mode_2=false;
mode_1();
break;
}
if(!( PINB & (1<<0)))
{
mode_2=true;
mode2();
break;
}
}
}
void mode2()
{
while(1){
lcd.clear();
lcd.setCursor(0, 0);
displayMessage("MODE 2", "Press RED 2 play");
if (!gameOver) {
while(PINB&(1<<(BUTTON_PINS[3]-8)));
displayMessage("Game", "Active");
playGame();
}
else {
endGame();
return;
}
}
}
void mode_1()
{
while(1){
lcd.clear();
lcd.setCursor(0, 0);
displayMessage("MODE 1", "Press RED 2 play");
if (!gameOver) {
while(PINB&(1<<(BUTTON_PINS[3]-8)));
displayMessage("Game", "Active");
playGame();
} else {
endGame();
return;
}
}
}
void playGame() {
delay(500);
addStepToSequence();
displaySequence();
getUserInput();
checkUserInput();
}
void addStepToSequence() {
sequence[sequenceLength] = random(4); // Randomly select a button
sequenceLength++;
}
void displaySequence() {
for (int i = 0; i < sequenceLength; i++) {
PORTD |=(1<<LED_PINS[sequence[i]]);
//digitalWrite(LED_PINS[sequence[i]], HIGH);
playTone(500 + (sequence[i] * 100), 300); // Play a tone corresponding to the
//LED color
delay(2000);
PORTD &=~(1<<LED_PINS[sequence[i]]);
//digitalWrite(LED_PINS[sequence[i]], LOW);
delay(1000);
}
}
void getUserInput() {
unsigned long current_time=0;
if(mode_2==true)
{
current_time=millis();
}
for (int i = 0; i < sequenceLength; i++) {
int buttonPressed = waitForButtonPress();
userInput[i] = buttonPressed;
delay(500); // Debounce delay
}
if(mode_2==true)
{
time+=(millis()-current_time)/1000;
lcd.setCursor(0, 1);
lcd.print(" TIME: ");
lcd.print(((millis()-current_time))/1000);
delay(1500);
}
}
int waitForButtonPress() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter seq");
while(1){
for (int i = 0; i < 4; i++) {
if (!(PINB & (1<<(BUTTON_PINS[i]-8)))) {
return i;
}
}
}
return -1; // No button pressed
}
void checkUserInput() {
for (int i = 0; i < sequenceLength; i++) {
if (userInput[i] != sequence[i]) {
gameOver = true;
return;
}
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("GOOD JOB");
score++;
delay(1500);
}
void endGame() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Game Over!");
delay(1500);
lcd.setCursor(0, 1);
lcd.print("Score: ");
lcd.print(score);
delay(1500);
if (score > highScore) {
highScore = score;
}
lcd.setCursor(0, 1);
lcd.print(" High Score: ");
lcd.print(highScore);
delay(1500);
if((mode_2==true)&&(score>0))
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Game Over!");
avg_time=time/(score+1);
lcd.setCursor(0, 1);
lcd.print(" TOTAL TIME: ");
lcd.print(time);
delay(1500);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Game Over!");
avg_time=(float)time/(score+1);
lcd.setCursor(0, 1);
lcd.print(" AVG TIME: ");
lcd.print(avg_time);
delay(1500);
}
gameOver = false;
sequenceLength = 0;
score = 0;
}
void displayMessage(String line1, String line2) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(line1);
lcd.setCursor(0, 1);
lcd.print(line2);
}
void playTone(int frequency, int duration) {
tone(BUZZER_PIN, frequency, duration);
}