#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 20, 4);
unsigned long previousMillis = 0;
unsigned long interval = 1000;
int timer = 30;
const int ledBlue1 = 2;
const int ledBlue2 = 3;
const int ledRed1 = 4;
const int ledRed2 = 5;
const int ledYellow1 = 6;
const int ledYellow2 = 7;
const int buttonBlue = 8;
const int buttonRed = 9;
const int buttonYellow = 10;
const int buttonSpecialYellow1 = 11;
const int buttonSpecialYellow2 = 12;
const int buttonSpecialBlue = 13;
const int potPin = A0;
int currentLed1, currentLed2;
int prevPotValue, potValue;
int potThreshold = 50;
int score = 0;
unsigned long lastResponseTime = 0;
void setup() {
lcd.init();
lcd.clear();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Time: ");
lcd.setCursor(0, 3);
lcd.print("Score: 0");
pinMode(ledBlue1, OUTPUT);
pinMode(ledBlue2, OUTPUT);
pinMode(ledRed1, OUTPUT);
pinMode(ledRed2, OUTPUT);
pinMode(ledYellow1, OUTPUT);
pinMode(ledYellow2, OUTPUT);
pinMode(buttonBlue, INPUT_PULLUP);
pinMode(buttonRed, INPUT_PULLUP);
pinMode(buttonYellow, INPUT_PULLUP);
pinMode(buttonSpecialYellow1, INPUT_PULLUP);
pinMode(buttonSpecialYellow2, INPUT_PULLUP);
pinMode(buttonSpecialBlue, INPUT_PULLUP);
randomSeed(analogRead(0));
newRound();
Serial.begin(9600);
}
bool anyOtherAction(int correctButton1 = -1, int correctButton2 = -1) {
return (digitalRead(buttonBlue) == LOW && buttonBlue != correctButton1 && buttonBlue != correctButton2) ||
(digitalRead(buttonRed) == LOW && buttonRed != correctButton1 && buttonRed != correctButton2) ||
(digitalRead(buttonYellow) == LOW && buttonYellow != correctButton1 && buttonYellow != correctButton2) ||
(digitalRead(buttonSpecialYellow1) == LOW && buttonSpecialYellow1 != correctButton1 && buttonSpecialYellow1 != correctButton2) ||
(digitalRead(buttonSpecialYellow2) == LOW && buttonSpecialYellow2 != correctButton1 && buttonSpecialYellow2 != correctButton2) ||
(digitalRead(buttonSpecialBlue) == LOW && buttonSpecialBlue != correctButton1 && buttonSpecialBlue != correctButton2);
}
void loop() {
if (timer <= 0) {
lcd.clear();
lcd.setCursor(0, 1);
lcd.print("Final Score: ");
lcd.print(score);
delay(10000);
resetGame();
return;
}
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
timer--;
lcd.setCursor(6, 0);
lcd.print(" ");
lcd.setCursor(6, 0);
lcd.print(timer);
}
prevPotValue = potValue;
delay(100);
potValue = analogRead(potPin);
int potChange = abs(potValue - prevPotValue);
Serial.println(potChange);
if (isDoubleYellow()) {
if (digitalRead(buttonSpecialYellow1) == LOW && digitalRead(buttonSpecialYellow2) == LOW) {
correctAnswer();
} else if (anyOtherAction(buttonSpecialYellow1, buttonSpecialYellow2) || potChange > potThreshold) {
wrongAnswer();
}
} else if (isDoubleBlue()) {
if (digitalRead(buttonSpecialBlue) == LOW) {
correctAnswer();
} else if (anyOtherAction(buttonSpecialBlue) || potChange > potThreshold) {
wrongAnswer();
}
} else if (isDoubleRed()) {
if (potChange > 100) {
correctAnswer();
} else if (anyOtherAction()) {
wrongAnswer();
}
} else {
checkRegularButtons();
if (potChange > 100) {
wrongAnswer();
}
}
}
void newRound() {
turnOffAllLeds();
int line1Leds[] = {ledBlue1, ledRed1, ledYellow1};
currentLed1 = line1Leds[random(0, 3)];
int line2Leds[] = {ledBlue2, ledRed2, ledYellow2};
currentLed2 = line2Leds[random(0, 3)];
digitalWrite(currentLed1, HIGH);
digitalWrite(currentLed2, HIGH);
lastResponseTime = millis();
}
void checkRegularButtons() {
int correctButton = determineCorrectButton();
if (digitalRead(correctButton) == LOW) {
correctAnswer();
} else if (anyOtherAction(correctButton)) {
wrongAnswer();
}
}
int determineCorrectButton() {
if ((isRedLed(currentLed1) && isYellowLed(currentLed2)) || (isYellowLed(currentLed1) && isRedLed(currentLed2))) {
return buttonBlue;
}
if ((isBlueLed(currentLed1) && isYellowLed(currentLed2)) || (isYellowLed(currentLed1) && isBlueLed(currentLed2))) {
return buttonRed;
}
if ((isBlueLed(currentLed1) && isRedLed(currentLed2)) || (isRedLed(currentLed1) && isBlueLed(currentLed2))) {
return buttonYellow;
}
if (isBlueLed(currentLed1) || isBlueLed(currentLed2)) {
return buttonBlue;
}
if (isRedLed(currentLed1) || isRedLed(currentLed2)) {
return buttonRed;
}
return buttonYellow;
}
bool isDoubleBlue() {
return isBlueLed(currentLed1) && isBlueLed(currentLed2);
}
bool isDoubleRed() {
return isRedLed(currentLed1) && isRedLed(currentLed2);
}
bool isDoubleYellow() {
return isYellowLed(currentLed1) && isYellowLed(currentLed2);
}
bool isBlueLed(int led) {
return (led == ledBlue1 || led == ledBlue2);
}
bool isRedLed(int led) {
return (led == ledRed1 || led == ledRed2);
}
bool isYellowLed(int led) {
return (led == ledYellow1 || led == ledYellow2);
}
void correctAnswer() {
unsigned long reactionTime = millis() - lastResponseTime;
int points = 333 - reactionTime / 10;
points = max(0, points);
score += points;
blinkAllLeds(5);
newRound();
updateScore();
}
void wrongAnswer() {
turnOnAllLeds();
delay(2000);
newRound();
}
void turnOffAllLeds() {
digitalWrite(ledBlue1, LOW);
digitalWrite(ledBlue2, LOW);
digitalWrite(ledRed1, LOW);
digitalWrite(ledRed2, LOW);
digitalWrite(ledYellow1, LOW);
digitalWrite(ledYellow2, LOW);
}
void turnOnAllLeds() {
digitalWrite(ledBlue1, HIGH);
digitalWrite(ledBlue2, HIGH);
digitalWrite(ledRed1, HIGH);
digitalWrite(ledRed2, HIGH);
digitalWrite(ledYellow1, HIGH);
digitalWrite(ledYellow2, HIGH);
}
void blinkAllLeds(int times) {
for (int i = 0; i < times; i++) {
turnOffAllLeds();
delay(200);
turnOnAllLeds();
delay(200);
}
}
void updateScore() {
lcd.setCursor(7, 3);
lcd.print(" ");
lcd.setCursor(7, 3);
lcd.print(score);
}
void resetGame() {
timer = 30;
score = 0;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Time: 30");
lcd.setCursor(0, 3);
lcd.print("Score: 0");
newRound();
}
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.