/*Arduino Oyuna Başla
Ateşbey, June 2025
*/
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Pin Definitions
const int buttonPins1[] = { 5, 6, 7, 8, 9, 10, 11, 12 }; // Button pins
const int ledPins1[] = { 14, 15, 16, 17, 18, 19, 22, 23 }; // LED pins
const int buttonPins2[] = { 24, 26, 28, 30, 32, 34, 36, 38 }; // Button pins
const int ledPins2[] = { 25, 27, 29, 31, 33, 35, 37, 39 }; // LED pins
const int buzzerPin = 13; // Buzzer pin (digital 13)
const int numMoles = 8; // Number of moles/buttons/LEDs
// Game variables
int currentMole = -1; // Current mole (LED) to be lit
int score = 0; // Player's score
unsigned long reactionTime = 1000; // Initial reaction time (milliseconds)
unsigned long lastMoleTime = 0; // Time when the last mole was lit
unsigned long gameStartTime = 0; // Start time of the game
unsigned long gameDuration = 90000; // Total game duration (30 seconds)
// Reaction time adjustment
const unsigned long reactionTimeDecrement = 0; // Time to reduce reaction by (milliseconds)
const unsigned long minReactionTime = 0; // Minimum reaction time (milliseconds)
void setup()
{
int Button = A0;
pinMode(Button, INPUT_PULLUP);
lcd.backlight();
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("Butona bas");
lcd.setCursor(3, 1);
lcd.print("Oyuna Basla");
delay(2000);
lcd.clear();
while (digitalRead(Button) == HIGH) {}; // wait for Button (A0) press to create LOW when pressed
gameStartTime = millis(); // Record game start time
// Initialize button pins and LED pins
for (int i = 0; i < numMoles; i++)
{
pinMode(buttonPins1[i], INPUT_PULLUP); // Set button pins as input with pull-up resistors
pinMode(buttonPins2[i], INPUT_PULLUP); // Set button pins as input with pull-up resistors
pinMode(ledPins1[i], OUTPUT); // Set LED pins as output
pinMode(ledPins2[i], OUTPUT); // Set LED pins as output
digitalWrite(ledPins1[i], LOW); // Turn off all LEDs initially
digitalWrite(ledPins2[i], LOW); // Turn off all LEDs initially
}
pinMode(buzzerPin, OUTPUT); // Set buzzer pin as output
Serial.begin(9600); // For debugging and displaying the score
randomSeed(analogRead(0)); // Initialize random seed from an unused analog pin
Serial.println("Oyun Basladı!");
lcd.setCursor(2, 0);
lcd.print("Oyun Basladı!");
delay(500);
lcd.clear();
gameStartTime = millis(); // Record game start time
}
void loop()
{
unsigned long currentMillis = millis(); // Get the current time
// Update the progress bar
unsigned long elapsedTime = currentMillis - gameStartTime;
if (elapsedTime <= gameDuration)
{
int barLength = map(gameDuration - elapsedTime, 0, gameDuration, 0, 16);
lcd.setCursor(0, 1);
for (int i = 0; i < 16; i++)
{
lcd.print(i < barLength ? '-' : ' '); // Print '-' for remaining time, ' ' for elapsed
}
}
// Light up a mole after a certain amount of time (based on reactionTime)
if (currentMillis - lastMoleTime >= reactionTime)
{
if (currentMole != -1)
{
digitalWrite(ledPins1[currentMole], LOW); // Turn off the previous mole
digitalWrite(ledPins2[currentMole], LOW); // Turn off the previous mole
}
currentMole = random(0, numMoles); // Randomly pick a mole (LED)
digitalWrite(ledPins1[currentMole], HIGH); // Light up the chosen LED
digitalWrite(ledPins2[currentMole], HIGH); // Light up the chosen LED
lastMoleTime = currentMillis; // Update the time when the mole was lit
}
// Check if the player pressed the correct button for the lit mole
for (int i = 0; i < numMoles; i++)
{
if (digitalRead(buttonPins1[i]) == LOW) // Button pressed (LOW due to INPUT_PULLUP)
{
if (i == currentMole)
{
score++; // Correct mole hit
if (digitalRead(buttonPins2[i]) == LOW) // Button pressed (LOW due to INPUT_PULLUP)
{
if (i == currentMole)
{
score++; // Correct mole hit
lcd.setCursor(2, 0);
lcd.print(" Score: "); // Clear the score field with extra spaces
lcd.setCursor(12, 0);
lcd.print(score); // Update the score
tone(buzzerPin, 1000, 200); // High-pitched sound (1000Hz) for 200ms
if (reactionTime > minReactionTime)
{
reactionTime -= reactionTimeDecrement;
}
}
else
{
score--; // Wrong mole hit
lcd.setCursor(2, 0);
lcd.print(" Score: "); // Clear the score field with extra spaces
lcd.setCursor(12, 0);
lcd.print(score); // Update the score
tone(buzzerPin, 400, 200); // Low-pitched sound (400Hz) for 200ms
}
digitalWrite(ledPins1[currentMole], LOW); // Turn off the current mole
currentMole = -1; // Reset the mole to indicate no active mole
delay(500); // Short delay to debounce button press
digitalWrite(ledPins2[currentMole], LOW); // Turn off the current mole
currentMole = -1; // Reset the mole to indicate no active mole
delay(500); // Short delay to debounce button press
}
}
// End the game after the set duration
if (elapsedTime >= gameDuration)
{
lcd.setCursor(3, 0);
lcd.print("Game Over! ");
lcd.setCursor(0, 1);
lcd.print("Final Score: ");
lcd.setCursor(13, 1);
lcd.print(" "); // Clear any leftover characters
lcd.setCursor(13, 1);
lcd.print(score); // Print the final score
// Flash all LEDs and play a sound three times
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < numMoles; j++)
{
digitalWrite(ledPins1[j], HIGH);
}
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < numMoles; j++)
{
digitalWrite(ledPins2[j], HIGH);
}
tone(buzzerPin, 1000, 300); // Play sound
delay(300); // Keep LEDs on
for (int j = 0; j < numMoles; j++)
{
digitalWrite(ledPins1[j], LOW);
}
tone(buzzerPin, 1000, 300); // Play sound
delay(300); // Keep LEDs on
for (int j = 0; j < numMoles; j++)
{
digitalWrite(ledPins2[j], LOW);
}
delay(300); // Keep LEDs off
}
delay(2000); // Pause before resetting the game
lcd.clear();
score = 0;
currentMole = -1;
for (int i = 0; i < numMoles; i++)
{
digitalWrite(ledPins1[i], LOW);
}
delay(2000); // Pause before resetting the game
lcd.clear();
score = 0;
currentMole = -1;
for (int i = 0; i < numMoles; i++)
{
digitalWrite(ledPins2[i], LOW);
}
lcd.setCursor(0, 0);
lcd.print(" Start New Game");
}
delay(5000);
}
lcd.clear();
}
gameStartTime = millis();
}
reactionTime = 1000;
}