#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
// Define LED pins
#define BLUE_LED_PIN 13
#define WHITE_LED_PIN 17
#define GREEN_LED_PIN 14
#define YELLOW_LED_PIN 15
#define RED_LED_PIN 16
char* inputCode();
void resetGame();
void showWaitScreen(int delayMillis);
void handleLEDs(unsigned long remainingTime);
// Initialize the LCD library with the I2C address (usually 0x27 or 0x3F)
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Define the Keypad pins
const byte ROWS = 4; // four rows
const byte COLS = 4; // four columns
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {2, 3, 4, 5}; // Connect to the row pinouts of the keypad (D2 to D5)
byte colPins[COLS] = {6, 7, 8}; // Connect to the column pinouts of the keypad (D6 to D8)
// Create the Keypad object
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
// Define the speaker pin
const int speakerPin = 9; // Assuming you're using pin D9 for the speaker
// Define the buffer and the target sequences
const int bufferSize = 6; // For both attacker and defender
char buffer[bufferSize + 1] = ""; // +1 for null-terminator
char plantingCode[] = "221295"; // Attacker's activation code
char diffusingCode[] = "123456"; // Defender's defusal code
bool bombActivated = false;
unsigned long bombActivationTime = 0;
unsigned long bombDuration = 10000;
// Variables to track LCD content
String lcdContent = ""; // Store the current content displayed on the LCD
// Variables to track number of times 1 or 2 is pressed
int pressCount_star = 0;
int pressCount_0 = 0;
int pressCount_hash = 0;
// Function prototype
char* inputCode();
void setup() {
// Initialize the LCD
lcd.init();
lcd.backlight(); // Turn on the backlight
// Print a message to the LCD
lcd.setCursor(4,0);
lcd.print("BOMB MODE");
delay(2000); // wait for 2 seconds
lcd.clear(); // clear the display
lcd.print("BOMB CODE:");
lcd.setCursor(4,1);
}
void resetGame() {
// Reset bomb state variables
bombActivated = false;
bombActivationTime = 0;
// Reset buffer for new code input
buffer[0] = '\0';
// Clear the LCD and prompt for code input
lcd.clear();
lcd.print("BOMB CODE:");
// Reset LED states
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, LOW);
}
void loop() {
char key = keypad.getKey();
// Check if any key is pressed
if (key != NO_KEY) {
// Check if the key is 1 or 2 to set planting or diffusing code
if (key == '*') {
pressCount_star++;
if (pressCount_star == 5) {
lcd.clear();
delay(100); // Add a short delay after clearing the LCD
lcd.setCursor(2, 0);
lcd.print("NEW PLANTING");
lcd.setCursor(5, 1);
lcd.print("CODE");
while (keypad.getKey() != NO_KEY); // Wait for key release
delay(1000); // Delay to prevent multiple key presses
memset(plantingCode, 0, sizeof(plantingCode)); // Clear previous planting code
strcpy(plantingCode, inputCode()); // Input new planting code
resetGame(); // Reset game after setting code
lcd.clear(); // Reset LCD to display "Enter code:"
lcd.print("Enter code:");
return;
}
} else if (key == '0') {
pressCount_0++;
if (pressCount_0 == 5) {
lcd.clear();
delay(100); // Add a short delay after clearing the LCD
lcd.setCursor(2, 0);
lcd.print("NEW DIFFUSE");
lcd.setCursor(5, 1);
lcd.print("CODE");
while (keypad.getKey() != NO_KEY); // Wait for key release
delay(1000); // Delay to prevent multiple key presses
memset(diffusingCode, 0, sizeof(diffusingCode)); // Clear previous diffusing code
strcpy(diffusingCode, inputCode()); // Input new diffusing code
resetGame(); // Reset game after setting code
lcd.clear(); // Reset LCD to display "Enter code:"
lcd.print("Enter code:");
return;
}
} else if (key == '#') {
pressCount_hash++;
if (pressCount_hash == 5) {
lcd.clear();
delay(100); // Add a short delay after clearing the LCD
lcd.setCursor(1, 0);
lcd.print("NEW BOMB TIMER");
lcd.setCursor(0, 1);
lcd.print("IN SEC-#TO VALID");
while (keypad.getKey() != NO_KEY); // Wait for key release
delay(1000); // Delay to prevent multiple key presses
char* durationString = inputCode();
int durationValue = atoi(durationString); // Convert the string to an integer
// Multiply the duration value as needed
bombDuration = durationValue * 1000;
resetGame(); // Reset game after setting code
lcd.clear(); // Reset LCD to display "Enter code:"
lcd.print("ENTER CODE:");
return;
}
} else {
pressCount_star = 0; // Reset press count if any other key is pressed
pressCount_0 = 0;
pressCount_hash = 0;
}
// If the bomb is not activated, handle input for activation
if (!bombActivated) {
// Check if the entered code matches the attacker's code
strncat(buffer, &key, 1);
lcd.setCursor(4,1);
lcd.print(buffer);
// Check if the entered code matches the attacker's code
if (strcmp(buffer, plantingCode) == 0) {
bombActivated = true;
bombActivationTime = millis();
lcd.clear();
lcd.print("BOMB ACTIVATED");
buffer[0] = '\0'; // Reset the buffer
} else if (strlen(buffer) == bufferSize) {
// Entered code doesn't match planting code and buffer is full
lcd.clear();
lcd.print("WRONG CODE");
buffer[0] = '\0'; // Reset the buffer
delay(2000); // Display "Wrong code" for 2 seconds
lcd.clear(); // Clear the LCD for next input
lcd.print("BOMB CODE:"); // Prompt for code entry again
}
}
// If the bomb is activated, handle input for defusal
else {
// Add the pressed key to the buffer for bomb defusal
strncat(buffer, &key, 1);
lcd.setCursor(10,1);
lcd.print(buffer);
// Check if the buffer matches the defender's code
if (strcmp(buffer, diffusingCode) == 0) {
bombActivated = false;
lcd.clear();
showWaitScreen(200);
lcd.clear();
lcd.setCursor(2, 0);
lcd.print("BOMB DIFFUSED");
buffer[0] = '\0'; // Reset the buffer
lcd.setCursor(2, 0);
lcdContent = "BOMB DIFFUSED"; // Update lcdContent
// Blink LEDs while beeping for 4 seconds
unsigned long blinkStartTime = millis();
while (millis() - blinkStartTime < 4000) {
digitalWrite(BLUE_LED_PIN, HIGH);
tone(speakerPin, 1000, 200); // Beep for 200 milliseconds
delay(100); // Blink rate
digitalWrite(BLUE_LED_PIN, LOW);
digitalWrite(WHITE_LED_PIN, HIGH);
tone(speakerPin, 1000, 200); // Beep for 200 milliseconds
delay(100); // Blink rate
digitalWrite(WHITE_LED_PIN, LOW);
}
lcd.clear();
lcd.setCursor(4, 0);
lcd.print("DEFENDERS");
lcd.setCursor(7, 1);
lcd.print("WIN");
delay(5000);
digitalWrite(BLUE_LED_PIN, LOW); // Ensure LEDs are off after blinking
digitalWrite(WHITE_LED_PIN, LOW);
// Reset the game after bomb is diffused
resetGame();
return;
} else if (strlen(buffer) == bufferSize) {
// Entered code doesn't match diffusing code and buffer is full
lcd.clear();
lcd.print("Wrong code");
buffer[0] = '\0'; // Reset the buffer
delay(1000); // Display "Wrong code" for 1 seconds
lcd.clear(); // Clear the LCD for next input
lcd.print("DEFUSE CODE:"); // Prompt for code entry again
}
}
}
// Check if the bomb is activated
if (bombActivated) {
unsigned long elapsedTime = millis() - bombActivationTime;
unsigned long remainingTime = bombDuration - elapsedTime;
// Update LED colors based on remaining time
if (remainingTime < bombDuration * 0.33) {
// Less than 33% remaining time
digitalWrite(GREEN_LED_PIN, HIGH);
digitalWrite(YELLOW_LED_PIN, HIGH);
digitalWrite(RED_LED_PIN, HIGH);
} else if (remainingTime < bombDuration * 0.66) {
// Less than 66% remaining time
digitalWrite(GREEN_LED_PIN, HIGH);
digitalWrite(YELLOW_LED_PIN, HIGH);
digitalWrite(RED_LED_PIN, LOW);
} else if (remainingTime < bombDuration * 0.99) {
// Less than 99% remaining time
digitalWrite(GREEN_LED_PIN, HIGH);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, LOW);
} else {
// More than 99% remaining time
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, LOW);
}
if (remainingTime <= 0) {
// Explode the bomb
// Clear the LCD screen
lcd.clear();
lcd.print("BOUM BOUM BOUM");
lcd.setCursor(0, 1);
lcd.print("BOUM BOUM BOUM");
// Get the current time in milliseconds
unsigned long blinkStartTime = millis();
// Loop for 4 seconds to create blinking effect
while (millis() - blinkStartTime < 4000) {
tone(speakerPin, 1000, 200); // Beep for 200 milliseconds
digitalWrite(GREEN_LED_PIN, HIGH);
digitalWrite(YELLOW_LED_PIN, HIGH);
digitalWrite(RED_LED_PIN, HIGH);
delay(100); // Blink rate
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, LOW);
delay(100); // Blink rate
}
delay(2500);
// Ensure LEDs are off after blinking
digitalWrite(GREEN_LED_PIN, LOW);
digitalWrite(YELLOW_LED_PIN, LOW);
digitalWrite(RED_LED_PIN, LOW);
lcd.clear();
lcd.setCursor(3, 0);
lcd.print("ATTACKERS");
lcd.setCursor(6, 1);
lcd.print("WIN");
// Delay for 5 seconds
delay(5000);
// Reset the game after bomb explodes
resetGame();
return;
// End the game loop
while (true);
} else {
// If time is remaining, display the remaining time on the LCD
String timeString = "TIME LEFT: " + String(remainingTime / 1000) + "sec";
// Check if the timeString is different from what is currently displayed on the LCD
if (timeString != lcdContent) {
// Clear the LCD screen
lcd.clear();
// Display remaining time on the LCD
lcd.print(timeString);
// Update lcdContent
lcdContent = timeString;
lcd.setCursor(0,1);
lcd.print("DEFUSE CODE:");
}
}
}
}
void showWaitScreen(int delayMillis) {
unsigned long startTime = millis(); // Get the current time
digitalWrite(WHITE_LED_PIN, HIGH);
digitalWrite(BLUE_LED_PIN, HIGH);
while (millis() - startTime < 5000) { // Loop for 5 seconds
lcd.setCursor(1, 0);
lcd.print((char)235);
lcd.print((char)235);
lcd.print("[DIFFUSING]");
lcd.print((char)235);
lcd.print((char)235);
lcd.print((char)235);
lcd.setCursor(1, 1);
lcd.print((char)235);
lcd.print((char)235);
lcd.print("[DIFFUSING]");
lcd.print((char)235);
lcd.print((char)235);
lcd.print((char)235);
if ((millis() / 500) % 2 == 0) { // Blink effect every 500 ms (half a second)
lcd.setCursor(1, 0);
lcd.print((char)235);
lcd.print((char)235);
lcd.print("[DIFFUSING]");
lcd.print((char)235);
lcd.print((char)235);
lcd.print((char)235);
lcd.setCursor(1, 1);
lcd.print((char)235);
lcd.print((char)235);
lcd.print("[DIFFUSING]");
lcd.print((char)235);
lcd.print((char)235);
lcd.print((char)235);
} else {
lcd.setCursor(1, 0);
lcd.print(" "); // Print spaces to clear the previous text
lcd.setCursor(1, 1);
lcd.print(" "); // Print spaces to clear the previous text
}
delay(delayMillis);
}
lcd.setCursor(2, 1);
lcd.print(" "); // Clear the progress bar
}
// Function to input the code
char* inputCode() {
static char code[bufferSize + 1]; // Static array to hold the code
code[0] = '\0'; // Initialize code as empty string
int index = 0; // Index to track the current position in the code array
// Set the cursor position to the second row
lcd.setCursor(0, 1);
while (true) {
char key = keypad.getKey(); // Get the pressed key
// Check if a key is pressed
if (key != NO_KEY) {
// Check if the key is a valid code character
if (key >= '0' && key <= '9') {
// Add the key to the code array
code[index++] = key;
code[index] = '\0'; // Null-terminate the string
// Display an asterisk on the LCD for each entered digit
lcd.print("*");
// Check if the code is complete
if (index >= bufferSize) {
break; // Exit the loop if the code is complete
}
} else if (key == '#') {
break; // Exit the loop if '#' is pressed (end of code entry)
}
}
}
return code; // Return the entered code
}