/* Game: Chase the Lights, by Sagax.K
LEDs Lights up in a random sequence,
the player must press the corresponding buttons to match the sequence and increase their score.
As the level progresses, the game intensifies, increasing the pace and adding an extra layer of excitement.
*/
#include <LiquidCrystal_I2C.h>
// LCD configuration, number of rows and cols
int lcdColumns = 16;
int lcdRows = 2;
// Define pins for LEDs, buttons, and buzzer
#define redLED 19
#define greenLED 18
#define yellowLED 5
#define blueLED 17
#define redButton 15
#define greenButton 2
#define yellowButton 4
#define blueButton 16
#define buzzer 23
#define defultinterval 1500 //hold time for game over page
// Arrays to store LEDs and buttons
int leds[4] = { redLED, greenLED, yellowLED, blueLED };
int buttons[4] = { redButton, greenButton, yellowButton, blueButton };
int buttonstatus[4] = { 1, 1, 1, 1 };
// Variables to control game state
int randset = 0;
int count = 0;
int score = 0;
int highscore = 0;
int level = 1;
int statusSum = 1;
int interval = defultinterval;
unsigned long strttime = 0;
// LCD object
LiquidCrystal_I2C lcd_1(0x27, lcdColumns, lcdRows);
// Function prototypes
void gameover();
void updatescore();
void setup() {
// Initialize LCD
lcd_1.init();
lcd_1.backlight();
// Set pin modes
pinMode(buzzer, OUTPUT);
for (int i = 0; i < 4; i++) {
pinMode(leds[i], OUTPUT);
pinMode(buttons[i], INPUT_PULLUP);
}
// Display initial message
Serial.begin(9600);
lcd_1.setCursor(0, 0);
lcd_1.print("CHASE THE LIGHTS");
lcd_1.setCursor(0, 1);
lcd_1.print(" Starting in: ");
lcd_1.print("3");
delay(1000);
lcd_1.setCursor(14, 1);
lcd_1.print("2");
delay(1000);
lcd_1.setCursor(14, 1);
lcd_1.print("1");
delay(1000);
lcd_1.clear();
}
void loop() {
// Generate a random LED to light up
randset = random(0, 4);
// Check if the level is complete
if (count == 4) {
interval -= 50;
level += 1;
count = 0;
}
// Display game information on the LCD
lcd_1.setCursor(0, 0);
lcd_1.print("Lvl: ");
lcd_1.print(level);
lcd_1.print(" Scr: ");
lcd_1.print(score);
lcd_1.setCursor(0, 1);
lcd_1.print("High Scr: ");
lcd_1.print(highscore);
// set random LED ON
digitalWrite(leds[randset], HIGH);
strttime = millis();
// Wait for user input or timeout
while (1) {
if (millis() - strttime > interval) {
Serial.println("timeup");
break;
}
statusSum = 0;
for (int i = 0; i < 4; i++) {
buttonstatus[i] = 1;
buttonstatus[i] = digitalRead(buttons[i]);
statusSum += buttonstatus[i];
}
if (statusSum != 4 ) break;
}
// Check user input and update game state
if (statusSum != 4 && buttonstatus[randset] == 0) {
updatescore();
} else if (statusSum != 4 && buttonstatus[randset] != 0) {
gameover();
} else if (statusSum == 4) {
gameover();
}
// Turn off all LEDs and delay before next iteration
for (int i = 0; i < 4; i++) {
digitalWrite(leds[i], 0);
}
delay(1000);
}
void gameover() {
// Display game over message, play buzzer, and reset game state
for (int i = 0; i < 4; i++) {
digitalWrite(leds[i], 1);
}
Serial.println("\n*******GAME OVER*******");
lcd_1.setCursor(0, 1);
lcd_1.print("** GAME OVER **");
Serial.print("Score: ");
Serial.println(score);
Serial.print("level: ");
Serial.println(level);
// play the gameover tone
tone(buzzer, 800);
delay(150);
noTone(buzzer);
delay(10);
tone(buzzer, 850);
delay(200);
noTone(buzzer);
delay(5000);
// update highscore if made
score > highscore ? highscore = score : highscore = highscore;
// reset the scores for next game
score = 0;
level = 1;
count = 0;
interval = defultinterval;
lcd_1.setCursor(0, 0);
lcd_1.print(" Restart: Green ");
// hold until green button is pressed
while (digitalRead(buttons[1]) == 1) {}
lcd_1.setCursor(0, 1);
lcd_1.print(" ");
lcd_1.setCursor(0, 1);
lcd_1.print(" Starting in: ");
lcd_1.print("3");
delay(1000);
lcd_1.setCursor(14, 1);
lcd_1.print("2");
delay(1000);
lcd_1.setCursor(14, 1);
lcd_1.print("1");
delay(1000);
lcd_1.clear();
}
void updatescore() {
// Update score and play a sound
tone(buzzer, 700);
delay(80);
noTone(buzzer);
Serial.println("\n**Score Up**");
count += 1;
score += 1;
Serial.print("Score: ");
Serial.println(score);
Serial.print("level: ");
Serial.println(level);
}