Code help for Bomb Game

I am making a "bomb" for airsoft based on some designed I saw online for the hardware and code.

However for the "explosion", right now it is just flashing lights and a buzzer. I wanted to add a strobe light and MP3 sounds to it. But I am not sure how to achieve that as when I connected the strobe light, it flashes along with the "ticking" as did the MP3.

Ideally I want these to happen at the "explosion only".

I am using the Uno Rev 3 board and web editor to code.

#include <Wire.h> 
#include <Keypad.h>
//#include <LiquidCrystal_I2C.h>
#include <LiquidCrystal.h>
/*
 Arduino Bomb Pro
 
 The circuit:
 * More info at : http://airsoft-online-japan.com/
 If you need some help mail me to airsoftonlinejapan@gmail.com
 
 created 25,Aug, 2023
 Modified 26, AUG 2023
 by Ben (Airsoft Online Japan)
 
 */

//LiquidCrystal_I2C lcd(0x38,16,2);
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3','a'}
  ,
  {'4','5','6','b'}
  ,
  {'7','8','9','c'}
  ,
  {'*','0','#','d'}
};

byte rowPins[ROWS] = {
  12, 13, A5, A4}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  A3, A2, A1, A0
}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

char codeInput[8];
byte time[4];
boolean refresh=true;//1 refresh one time...
char password[8];
int key=-1;
char lastKey;
char var;
boolean passwordEnable=false;

//Buttons for lcd shield
char BT_RIGHT = '4';
char BT_UP = 'a';
char BT_DOWN = 'b';
char BT_LEFT = '6';
char BT_SEL = 'd';   // Ok key  
char BT_CANCEL = 'c';
char BT_DEFUSER = 'x';   // not implemented

//leds

const int REDLED = 11;
const int GREENLED = 10;
//const int BLUELED = 12;
//RELAYPIN
boolean relayEnable = false;
const int RELAYPIN = 9;
//IS VERY IMPORTANT THAT YOU TEST THIS TIME. BY DEFAULT IS IN 1 SEC. THAT IS NOT TOO MUCH. SO TEST IT!
const int RELAY_TIME = 5000;

//TIME INTS
int GAMEHOURS = 0;
int GAMEMINUTES = 45;
int BOMBMINUTES = 4;
int ACTIVATESECONDS = 5;

boolean endGame = false;

boolean sdStatus = false; //Search and Destroy game enable used in config
boolean saStatus = false; //same but Sabotage
boolean doStatus = false; //for Demolition
boolean start = true;
boolean defusing;
boolean cancelando;
// SOUND TONES
boolean soundEnable = true;
int tonepin = 8; // Pin 13 for the sound
int alarmTone1 = 700;
int alarmTone2 = 2600;
int activeTone = 1330;
int errorTone = 100;

unsigned long iTime;
unsigned long timeCalcVar;
unsigned long redTime;
unsigned long yellowTime;
unsigned long iZoneTime;//initial time for zone
byte team=0; // 0 = neutral, 1 = yellow team, 2 = red team

void setup(){
  lcd.begin(16, 2);
  Serial.begin(9600);
  lcd.setCursor(3,0);
  tone(tonepin,2400,30);
  lcd.print("AIRSOFT ONLINE JP");// you can add your team name or someting cool
  lcd.setCursor(0,1);
  lcd.print(" AIRSOFT BOMB");// you can add your team name or someting cool
  keypad.setHoldTime(50);
  keypad.setDebounceTime(50);
  keypad.addEventListener(keypadEvent);

  //PinModes
  pinMode(GREENLED, OUTPUT);     
  pinMode(REDLED, OUTPUT); 
  pinMode(RELAYPIN, OUTPUT);  
  // CONFIGURE THE BARS OF PROGRESS BAR
  byte bar1[8] = {
    B10000,
    B10000,
    B10000,
    B10000,
    B10000,
    B10000,
    B10000,
    B10000,
  };
  byte bar2[8] = {
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
  };
  byte bar3[8] = {
    B11100,
    B11100,
    B11100,
    B11100,
    B11100,
    B11100,
    B11100,
    B11100,
  };
  byte bar4[8] = {
    B11110,
    B11110,
    B11110,
    B11110,
    B11110,
    B11110,
    B11110,
    B11110,
  };
  byte bar5[8] = {
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
  };
  byte up[8] = {
    B00000,
    B00100,
    B01110,
    B11111,
    B11111,
    B00000,
    B00000,
  };

  byte down[8] = {
    B00000,
    B00000,
    B11111,
    B11111,
    B01110,
    B00100,
    B00000,
  };
  lcd.createChar(0,bar1);
  lcd.createChar(1,bar2);
  lcd.createChar(2,bar3);
  lcd.createChar(3,bar4);
  lcd.createChar(4,bar5);
  lcd.createChar(5,up);
  lcd.createChar(6,down);
}

void loop(){
  menuPrincipal();
}
void keypadEvent(KeypadEvent key){
  switch (keypad.getState()){
    case RELEASED:
      switch (key){
         case 'd': defusing=false;
         break;
         case 'c': cancelando=false;
         break;
      }
    break;
    case HOLD:
      switch (key){
        case 'd': defusing= true;
        break;
        case 'c': cancelando=true;
        break;
      }
    break;
  }
}

//This fuction compare codeInput[8] and password[8] variables
boolean comparePassword(){

  for(int i=0;i<8;i++){
    if(codeInput[i]!=password[i])return false;
  }
  return true;
}

//Set the password variable
void setCode(){

  lcd.setCursor(0, 1);
  for(int i=0;i<8;i++){
    while(1){
      var= getNumber();
      if(var !='x'){
        codeInput[i] = var;

        if (i != 0){
          lcd.setCursor(i-1,1);
          lcd.print("*");
          lcd.print(var);
        }
        else
        {
          lcd.print(var);
        }
        tone(tonepin,2400,30);
        break;
      }
    }
  }
}
void setCodeTime(){

  timeCalcVar=millis();

  for(int i=0;i<8;i++){
    while(1){
      if(ACTIVATESECONDS*1000+timeCalcVar-millis()<=100){
        codeInput[i]='x';
        break;
      }

      lcd.setCursor(11,0);
      printTimeDom(ACTIVATESECONDS*1000+timeCalcVar-millis(),false);

      var= getNumber();
      if(var !='x'){
        codeInput[i] = var;

        if (i != 0){
          lcd.setCursor(i-1,1);
          lcd.print("*");
          lcd.print(var);
        }
        else
        {
          lcd.print(var);
        }
        tone(tonepin,2400,30);
        break;
      }
    }
  }
}
void setPass(){
  lcd.setCursor(0, 1);

  for(int i=0;i<8;i++){ 
    while(1){
      var= getNumber();
      if(var !='x'){
        password[i] =  var;
        if (i != 0){
          lcd.setCursor(i-1,1);
          lcd.print("*");
          lcd.print(var);
        }
        else
        {
          lcd.print(var);
        }
        tone(tonepin,2400,30);
        break;
      }
    }  
  }
}

void setNewPass(){

  while(1){
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Enter New Pass");
    setPass();

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Retype Pass");

    setCode();

    if(comparePassword()){

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Password Set OK!");
      delay(2000); 
      break; 
    }
    else {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("ERROR Dont Match!");
      if(soundEnable)tone(tonepin,errorTone,200);
      delay(2000); 

    }
  }
}
//Whait until a button is pressed is is a number return the number 'char' if not return x



char getNumber(){
  while(1){
    var = keypad.getKey();
    if (var){//
      switch (var) {
      case 'a': 
        return 'x';
        break;
      case 'b': 
        return 'x';
        break;

      case 'c': 
        return 'x';
        break;
      case 'd': 
        return 'x';
        break;
      case '*': 
        return 'x';
        break;
      case '#': 
        return 'x';
        break;
      default:
        return var;
        break;
      }
    }
    return 'x';
  }
}

byte getRealNumber(){

  while(1){
    var = keypad.waitForKey();

    if (var){//
      switch (var) {
      case '1': 
        return 1;
        break;
      case '2': 
        return 2;
        break;

      case '3': 
        return 3;
        break;
      case '4': 
        return 4;
        break;
      case '5': 
        return 5;
        break;
      case '6': 
        return 6;
      case '7': 
        return 7;
        break;
      case '8': 
        return 8;
        break;
      case '9': 
        return 9;
        break;
        case '0': 
        return 0;
        break;
        
      default:
        return 11;
        break;
      }

    }
    return 11;
  }
}


  char* menu1[]={"Search&Destroy","Sabotage","Domination", "Configuration"      };
  char* menu2[]={"Game Config","Sound Config", "Relay Test", "Auto Test"      };   
  char* GAME_TIME="Game Time:";
  char* BOMB_TIME="Bomb Time:";
  char* ZERO_MINUTES="00 minutes";
  char* ARM_TIME="Arm Time:";
  char* ZERO_SECS="00 seconds";
  char* ENABLE_SOUND="Enable Sound?";
  char* YES_OR_NOT="A : Yes B : No";
  char* ENABLE_RELAYPIN="Enable Relay?";
  char* ENABLE_CODE="Enable Code Arm?";
  char* GAME_TIME_TOP="GAME TIME";
  char* ARMING_BOMB = "ARMING BOMB";
  char* ENTER_CODE = "Enter Code";
  char* CODE_ERROR = "Code Error!";
  char* BOMB_ARMED = "BOMB ARMED";
  char* DETONATION_IN = "DETONATION IN";
  char* DISARMING = "DISARMING BOMB" ;
  char* DISARM = "DISARMING";
  char* GAME_OVER = " GAME OVER! ";
  char* DEFENDERS_WIN = " DEFENDERS WIN ";
  char* SABOTAGE_FAIL= "SABOTAGE FAIL!";
                   
  //void getConfig(){
//
////Check first time 
//
//if (EEPROM.read(0)!= 1){
////write default config values
//
//
//
//}
//  
////RELAY_TIME = EEPROM.read(1) * 1000 ;
//
//  
//}
//##################MENUS###############################

void menuPrincipal(){   //MAIN MENU

  digitalWrite(GREENLED, LOW); 
  digitalWrite(REDLED, LOW); 

  //   if we start a new game from another we need to restart propertly this variables
  saStatus=false;
  sdStatus=false;
  doStatus=false;
  //Draw menu
  cls();//clear lcd and set cursor to 0,0
  int i=0;
 // HERE YOU CAN ADD MORE ITEMS ON THE MAIN MENU
  lcd.print(menu1[i]);
  lcd.setCursor(15,1);
  checkArrows(i,2);
  while(1){

    var = keypad.waitForKey();
    if(var == BT_UP && i>0){
      tone(tonepin,2400,30);
      i--;
      cls();
      lcd.print(menu1[i]);
      checkArrows(i,2);
      delay(50);
    }
    if(var == BT_DOWN && i<2){
      tone(tonepin,2400,30);
      i++;
      cls(); 
      lcd.print(menu1[i]);    
      checkArrows(i,2);
      delay(50);
    }

    if(var == BT_SEL){
      tone(tonepin,2400,30);
      cls();
      switch (i){

      case 0:
        sdStatus=true;
        configQuickGame();
        startGameCount();
        search();
        break;
      case 1: 
        saStatus=true;
        configQuickGame();
        startGameCount();
        sabotage();
        break;
      case 2:

        doStatus=true;
        configQuickGame();
        startGameCount();
        domination();
        break;
      case 3:
        config();
        break;

      }
    }
  }
}

void config(){
  //Draw menu
  lcd.clear();
  lcd.setCursor(0, 0);
  int i=0;
  
  delay(500);
  lcd.print(menu2[i]);
  checkArrows(i,3);

  while(1){
    var=keypad.waitForKey();
    if(var == BT_UP && i>0){
      tone(tonepin,2400,30);
      i--;
      lcd.clear();  
      lcd.print(menu2[i]);
      checkArrows(i,3);
      delay(50);

    }
    if(var == BT_DOWN && i<3){
      tone(tonepin,2400,30);
      i++;
      lcd.clear();  
      lcd.print(menu2[i]);
      checkArrows(i,3);
      delay(50);
    }
    if(var == BT_CANCEL){
      tone(tonepin,2400,30);
      menuPrincipal();
    }
    if(var == BT_SEL){
      tone(tonepin,2400,30);
      lcd.clear();
      switch (i){

      case 0:
        //gameConfigMenu();
        break;

      case 1:
        //soundConfigMenu();
        break;

      case 2:
        cls();
        lcd.print("RELAYPIN ON!");
        digitalWrite(RELAYPIN, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(4000);   // wait for 4 second
        cls();
        lcd.print("RELAYPIN OFF!");
        digitalWrite(RELAYPIN, LOW);
        delay(2000);
        config();
        break;        

      }
    }
  }
}

void configQuickGame(){

  cls();
  //GAME TIME
  if(sdStatus || doStatus || saStatus){
    menu1:
    cls();
    lcd.print(GAME_TIME);
    delay(100);
    lcd.setCursor(0,1);
    lcd.print("00:00 hh:mm");
    lcd.cursor();
    lcd.blink();
    lcd.setCursor(0,1);
    byte var2=0;
    for(int i=0;i<4;i++){ 
      while(1){
        if(i==2 && var2==0){
          lcd.print(":");
          var2=1;
        }

        byte varu= getRealNumber();
        if(varu !=11){

          time[i] =  varu;
          Serial.print(varu);


          lcd.print(varu);
          tone(tonepin,2400,30);

          break;
        }
      }  
    }
    lcd.noCursor();
    lcd.noBlink();
    lcd.setCursor(13,1);
    lcd.print("ok?");
    //zona donde pasamos los items a
    //redibujar
    while(1){
      var = keypad.waitForKey();
      if(var == 'd') // Accept
      {
        tone(tonepin,2400,30);
        GAMEMINUTES= ((time[0]*600)+(time[1]*60)+(time[2]*10)+(time[3]));
        break;
      }    
  if(var == 'c') // Cancel or Back Button :')
      {
        tone(tonepin,2400,30);
        goto menu1;
      }           
    }
    tone(tonepin,2400,30);
    cls();
  }
  //BOMB TIME
  if(sdStatus || saStatus){
 
    menu2:
    cls();
    lcd.print(BOMB_TIME);
    delay(100);
    lcd.setCursor(0,1);
    lcd.print(ZERO_MINUTES);
    lcd.cursor();
    lcd.blink();
    lcd.setCursor(0,1);
    for(int i=0;i<2;i++){ 
      while(1){
        byte varu= getRealNumber();
        if(varu !=11){
          time[i] =  varu;
          lcd.print(varu);
          tone(tonepin,2400,30);
          break;
        }
      }  
    }
    lcd.noCursor();
    lcd.noBlink();   
    lcd.setCursor(13,1);
    lcd.print("ok?");
    //zona donde pasamos los items a
    //redibujar
    while(1){
      var = keypad.waitForKey();
      if(var == 'd') //
      {
        tone(tonepin,2400,30);
        BOMBMINUTES= ((time[0]*10)+(time[1]));
        break;
      }    
  if(var == 'c') // Cancel or Back Button :')
      {
        tone(tonepin,2400,30);
        goto menu2;
      }           
    }
    tone(tonepin,2400,30);
    cls();
  }
  cls();
  //ARMING TIME
  if(sdStatus || doStatus || saStatus){
        
    menu3:
    cls();
    lcd.print(ARM_TIME);
    delay(100);
    lcd.setCursor(0,1);
    lcd.print(ZERO_SECS);
    lcd.cursor();
    lcd.blink();
    lcd.setCursor(0,1);
    for(int i=0;i<2;i++){ 
      while(1){
        byte varu= getRealNumber();
        if(varu !=11){
          time[i] =  varu;
          lcd.print(varu);
          tone(tonepin,2400,30);
          break;
        }
      }  
    }
    lcd.noCursor();
    lcd.noBlink(); 
    lcd.setCursor(13,1);
    lcd.print("ok?");  
    
    //zona donde pasamos los items a
    //redibujar
    while(1){
      var = keypad.waitForKey();
      if(var == 'd') // Accept
      {
        tone(tonepin,2400,30);
        ACTIVATESECONDS= ((time[0]*10)+(time[1]));
        break;
      }    
  if(var == 'c') // Cancel or Back Button :')
      {
        tone(tonepin,2400,30);
        goto menu3;
      }           
    }
    tone(tonepin,2400,30);
    cls();
  }
  //sound??
  if(sdStatus || saStatus || doStatus){
    cls();
    lcd.print(ENABLE_SOUND);
    lcd.setCursor(0,1);
    lcd.print(YES_OR_NO);

    while(1)
    {
      var = keypad.waitForKey();
      if(var == 'a' ){
        soundEnable=true;
        tone(tonepin,2400,30);
        break;
      }  

      if(var == 'b' ){
        soundEnable=false;
        tone(tonepin,2400,30);
        break;
      }  
    }
  } 
  //Activate RELAY at Terrorist game ends??? Boom!

  if(sdStatus || saStatus){
    cls();
    lcd.print(ENABLE_RELAYPIN);
    lcd.setCursor(0,1);
    lcd.print(YES_OR_NO);
    while(1)
    {
      var = keypad.waitForKey();
      if(var == 'a' ){
        relayEnable=true;
        tone(tonepin,2400,30);
        break;
      }  
      if(var == 'b' ){
        relayEnable=false;
        tone(tonepin,2400,30);
        break;
      }  
    } 
  }
  //You Want a password enable-disable game?
  if(sdStatus || saStatus){
    cls();
    lcd.print(ENABLE_CODE);
    lcd.setCursor(0,1);
    lcd.print(YES_OR_NO);

    while(1)
    {
      var = keypad.waitForKey();
      if(var == 'a' ){
        tone(tonepin,2400,30);
        setNewPass();
        passwordEnable = true;
        break;
      }  
      if(var == 'b' ){
        tone(tonepin,2400,30);
        passwordEnable = false;
        break;
      }  
    } 
    tone(tonepin,2400,30);
  }  
  //Continue the game :D
}



void search() {
  refresh = true;
  cls();
  digitalWrite(REDLED, LOW);
  digitalWrite(GREENLED, LOW);
  //SETUP INITIAL TIME
  int minutos = GAMEMINUTES - 1;
  unsigned long iTime = millis(); //  initialTime in millisec
  unsigned long aTime;
  //var='o';

  //Starting Game Code
  while (1) { // this is the important code, is a little messy but works good.

    //If you fail disarm.
    if (endGame) {
      failSplash();
    }

    //Code for led blinking
    timeCalcVar = (millis() - iTime) % 1000;
    if (timeCalcVar >= 0 && timeCalcVar <= 50)digitalWrite(GREENLED, HIGH);
    if (timeCalcVar >= 90 && timeCalcVar <= 130)digitalWrite(GREENLED, LOW);

    lcd.setCursor(3, 0);
    lcd.print(GAME_TIME_TOP);
    aTime = millis() - iTime;
    lcd.setCursor(3, 1);

    //PRINT TIME ON LCD

    printTime(minutos, aTime);

    //###########################CHECKINGS##################

    //Check If Game End
    if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0)failSplash();
    //Serial.println(keypad.getKey());
    //USED IN PASSWORD GAME
    if ('d' == keypad.getKey() && passwordEnable) {
      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print(ARMING_BOMB);
      delay(1000);//a little delay to choose the password
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(ENTER_CODE);

      setCodeTime();// we need to set the comparation variable first it writes on codeInput[]

      //then compare :D

      if (comparePassword()) destroy();
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print(CODE_ERROR);
      if (soundEnable)tone(tonepin, errorTone, 200);
      delay(500);
      cls();
    }
    //Check If Is Activating
    while (defusing && !passwordEnable)
    {
      digitalWrite(GREENLED, LOW);
      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print(ARMING_BOMB);
      lcd.setCursor(0, 1);
      unsigned int percent = 0;
      unsigned long xTime = millis(); //start disabling time
      while (defusing)
      {
        keypad.getKey();
                percent = (millis() - xTime) / (ACTIVATESECONDS * 10);
                
        drawBar(percent);
        //check if game time runs out during the disabling
        aTime = millis() - iTime;
        Serial.println(millis()-xTime);
        if ((minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) || minutos - aTime / 60000 > 4000000000) {
          endGame = true;
        }
        timeCalcVar = (millis() - xTime) % 1000;

        if ( timeCalcVar >= 0 && timeCalcVar <= 40)
        {
          digitalWrite(REDLED, HIGH);
          if (soundEnable)tone(tonepin, alarmTone1, 200);
        }
        if (timeCalcVar >= 480 && timeCalcVar <= 520)
        {
          if (soundEnable)tone(tonepin, alarmTone2, 200);
          digitalWrite(REDLED, LOW);
        }



        if (percent >= 100)
        {
          digitalWrite(GREENLED, LOW);
          destroy();// jump to the next gamemode
        }
      }
      cls();
      digitalWrite(REDLED, LOW);

    }
  }
}

void destroy() {
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print(BOMB_ARMED);
  delay(1000);
  int minutos = BOMBMINUTES - 1;
  unsigned long iTime = millis();
  unsigned long aTime;
  int largoTono = 50;

  //MAIN LOOP
  while (1) {

    //If you fail disarm.
    if (endGame) {
      explodeSplash();
    }

    //Led Blink

    timeCalcVar = (millis() - iTime) % 1000;
    if (timeCalcVar >= 0 && timeCalcVar <= 40)
    {
      digitalWrite(REDLED, HIGH);
      if (soundEnable)tone(tonepin, activeTone, largoTono);
    }
    if (timeCalcVar >= 180 && timeCalcVar <= 220) {
      digitalWrite(REDLED, LOW);
    }
    //Sound
    aTime = millis() - iTime;
    timeCalcVar = (millis() - iTime) % 1000;
    if (timeCalcVar >= 245 && timeCalcVar <= 255 && minutos - aTime / 60000 < 2 && soundEnable)tone(tonepin, activeTone, largoTono);
    if (timeCalcVar >= 495 && timeCalcVar <= 510 && minutos - aTime / 60000 < 4 && soundEnable)tone(tonepin, activeTone, largoTono);
    if (timeCalcVar >= 745 && timeCalcVar <= 760 && minutos - aTime / 60000 < 2 && soundEnable)tone(tonepin, activeTone, largoTono);
    if ( minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) < 10)largoTono = 300;

    lcd.setCursor(1, 0);
    lcd.print(DETONATION_IN);
    //Passed Time

    lcd.setCursor(3, 1);

    ////////HERE ARE THE TWO OPTIONS THAT ENDS THE GAME///////////

    ////TIME PASED AWAY AND THE BOMB EXPLODES
    if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) // Check if game ends
    {
      explodeSplash();
    }
    //print time

    printTime(minutos, aTime);

    //// SECOND OPTION: YOU PRESS DISARMING BUTTON

    //IF IS A PASSWORD GAME

    if ('d' == keypad.getKey() && passwordEnable) {

      lcd.clear();
      lcd.setCursor(1, 0);
      lcd.print(DISARMING);
      delay(1000);//a little delay to think in the password

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(ENTER_CODE);

      setCodeTime();// we need to set the compare variable first

      //then compare :D

      if (comparePassword()) {
        disarmedSplash();
      }
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print(CODE_ERROR);
      if (soundEnable)tone(tonepin, errorTone, 200);
      delay(500);
      cls();
    }

    if (defusing && !passwordEnable) // disarming bomb
    {
      lcd.clear();
      digitalWrite(REDLED, LOW);
      lcd.setCursor(3, 0);
      lcd.print(DISARM);
      lcd.setCursor(0, 1);
      unsigned int percent = 0;
      unsigned long xTime = millis();
      while (defusing)
      {
        keypad.getKey();
        //check if game time runs out during the disabling
        aTime = millis() - iTime;
        if ((minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) || minutos - aTime / 60000 > 4000000000) {
          endGame = true;
        }
        timeCalcVar = (millis() - xTime) % 1000;
        if (timeCalcVar >= 0 && timeCalcVar <= 20)
        {
          digitalWrite(GREENLED, HIGH);
          if (soundEnable)tone(tonepin, alarmTone1, 200);
        }
        if (timeCalcVar  >= 480 && timeCalcVar <= 500)
        {
          if (soundEnable)tone(tonepin, alarmTone2, 200);
          digitalWrite(GREENLED, LOW);
        }
        unsigned long seconds = (millis() - xTime);
        percent = seconds / (ACTIVATESECONDS * 10);
        drawBar(percent);

        //BOMB DISARMED GAME OVER
        if (percent >= 100)disarmedSplash();
      }
      digitalWrite(REDLED, LOW);
      digitalWrite(GREENLED, LOW);
      cls();
    }
  }
}



void explodeSplash(){
  digitalWrite(REDLED, LOW);  
  digitalWrite(GREENLED, LOW); 
  cls();
  delay(100);
  endGame = false;
  lcd.setCursor(1,0);
  lcd.print("TERRORISTS WIN");
  lcd.setCursor(4,1);
  lcd.print("GAME OVER");
  for(int i = 200; i>0; i--)// this is the ultra hi definition explosion sound xD
  {
    tone(tonepin,i);
    delay(20);
  }
  noTone(tonepin);
  if(relayEnable){
    activateRelay(); 
  }
  delay(5000);
  cls();

  //end code
  lcd.print("Play Again?");
  lcd.setCursor(0,1);
  lcd.print("A : Yes B : No");
  while(1)
  {
    var = keypad.waitForKey();
    if(var == 'a' ){
      tone(tonepin,2400,30);
      //We have two options, search & destroy and sabotage play again options so!
      if(sdStatus){
        startGameCount();
        search();
      }
      if(saStatus){
        saStatus=true;
        startGameCount();
        start=true; //to set iTime to actual millis() :D
        sabotage();
      }
    }  
    if(var == 'b' ){
      tone(tonepin,2400,30);
      menuPrincipal();

      break;
    }  
  } 
}
void failSplash(){
  digitalWrite(REDLED, LOW);  
  digitalWrite(GREENLED, LOW); 
  cls();
  delay(100);
  endGame = false;
  lcd.setCursor(1,0);
  lcd.print("TIME OUT");
  lcd.setCursor(4,1);
  lcd.print("GAME OVER");
  for(int i = 200; i>0; i--)// this is the ultra hi definition explosion sound xD
  {
    tone(tonepin,i);
    delay(20);
  }
  noTone(tonepin);
  if(relayEnable){
    activateRelay(); 
  }
  delay(5000);
  cls();

  //end code
  lcd.print("Play Again?");
  lcd.setCursor(0,1);
  lcd.print("A : Yes B : No");
  while(1)
  {
    var = keypad.waitForKey();
    if(var == 'a' ){
      tone(tonepin,2400,30);
      //We have two options, search & destroy and sabotaje play again options so!
      if(sdStatus){
        startGameCount();
        search();
      }
      if(saStatus){
        saStatus=true;
        startGameCount();
        start=true; //to set iTime to actual millis() :D
        sabotage();
      }
    }  
    if(var == 'b' ){
      tone(tonepin,2400,30);
      menuPrincipal();

      break;
    }  
  } 
}
void disarmedSplash(){
  endGame = false;
  digitalWrite(REDLED, LOW); 
  digitalWrite(GREENLED, LOW);
  if(sdStatus || saStatus){
    lcd.clear();
    lcd.setCursor(2,0);
    lcd.print("BOMB DISARMED");
    lcd.setCursor(3,1);
    lcd.print("MILITARY WINS");
    digitalWrite(GREENLED, HIGH);  
    delay(5000);
    digitalWrite(GREENLED, LOW); 
  }
  //end code
  lcd.clear();
  lcd.print("Play Again?");
  lcd.setCursor(0,1);
  lcd.print("A : Yes B : No");
  digitalWrite(REDLED, LOW);  
  digitalWrite(GREENLED, LOW); 
  while(1)
  {
    var = keypad.waitForKey();
    if(var == 'a' ){
      tone(tonepin,2400,30);
      //We have two options, search & destroy and sabotaje play again options so!
      if(sdStatus){
        startGameCount();
        search();
      }
      if(saStatus){
        saStatus=true;
        startGameCount();
        start=true; //to set iTime to actual millis() :D
        sabotage();
      }
    }  
    if(var == 'b' ){
      tone(tonepin,2400,30);
      menuPrincipal();
      break;
    }  
  } 
}
void drawBar(byte porcent){
  //TODO: Optimize this code 
  int box=(8*porcent)/10;
  lcd.setCursor(0,1);
  while(box>=5){
    if(box>=5)
    {
      lcd.write(4);
      box-=5;
    }
  }
    switch(box){
    case 0:
      break;
    case 1:
      lcd.write((uint8_t)0);
      break;
    case 2:
      lcd.write(1);
      break;
    case 3:
      lcd.write(2);
      break;
    case 4:
      lcd.write(3);
      break;
    }
  

}
void cls(){
  lcd.clear();
  lcd.setCursor(0,0);
}

void printTime(unsigned long minutos, unsigned long aTiempo){

  timeCalcVar=minutos-aTiempo/60000;
  //Hours
  
  if(timeCalcVar/60==0 && refresh){
      lcd.clear();
      refresh=false;
      //delay(100);
      lcd.setCursor(3,1);
      Serial.println("!!!!");
  }
   
  if(timeCalcVar/60>=1){
    
    if(timeCalcVar/60<10)
  {
    lcd.setCursor(2,1);
    lcd.print("0");
    lcd.print(timeCalcVar/60);
  }
  else
  {
    lcd.print(timeCalcVar/60);
  }
  
  lcd.print(":");
  
  }
  //minutes
  if(timeCalcVar%60<10)
  {
    lcd.print("0");
    lcd.print(timeCalcVar%60);
  }
  else
  {
    lcd.print(timeCalcVar%60);
  }
  lcd.print(":");
  //seconds
  timeCalcVar=aTiempo/1000;
  if(59-(timeCalcVar%60)<10)
  {
    lcd.print("0");
    lcd.print(59-(timeCalcVar%60));
  }
  else
  {
    lcd.print(59-(timeCalcVar%60));
  }
  lcd.print(":");
  //this not mach with real time, is just a effect, it says 999 because millis%1000 sometimes give 0 LOL
  lcd.print(999-(millis()%1000));
}

void printTimeDom(unsigned long aTiempo, boolean showMillis){
  //minutes
  if((aTiempo/60000)<10)
  {
    lcd.print("0");
    lcd.print(aTiempo/60000);
  }
  else
  {
    lcd.print(aTiempo/60000);
  }
  lcd.print(":");
  //seconds
  if(((aTiempo/1000)%60)<10)
  {
    lcd.print("0");
    lcd.print((aTiempo/1000)%60);
  }
  else
  {
    lcd.print((aTiempo/1000)%60);
  }
  if(showMillis){
    lcd.print(":");
    //this not mach with real time, is just a effect, it says 999 because millis%1000 sometimes give 0 LOL
      lcd.print(999-millis()%1000);

  }
}

void startGameCount(){
  lcd.clear();
  lcd.setCursor(1,0);
  lcd.print("Ready to Begin");
  lcd.setCursor(0,1);
  lcd.print("Push ANY Button");
  keypad.waitForKey();//if you press a button game start

  cls();
  lcd.setCursor(1,0);
  lcd.print("Starting Game");
  for(int i = 5; i > 0 ; i--){ // START COUNT GAME INIT
    lcd.setCursor(5,1);
    tone(tonepin,2000,100);
    lcd.print("IN ");
    lcd.print(i);
    delay(1000);
  }
  cls();
}

void checkArrows(byte i,byte maxx ){

  if(i==0){
    lcd.setCursor(15,1);
    lcd.write(6); 
  }
  if(i==maxx){  
    lcd.setCursor(15,0);
    lcd.write(5);
  }
  if(i>0 && i<maxx){
    lcd.setCursor(15,1);
    lcd.write(6);
    lcd.setCursor(15,0);
    lcd.write(5);  
  }
}

void activateRelay(){

  digitalWrite(RELAYPIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(RELAY_TIME); 
  digitalWrite(RELAYPIN, LOW);

}













FOR FUTURE READERS: OP ADDED THE FULL SKETCH INTO THE CODE BOX AFTER THIS REPLY WAS POSTED

You are missing the minimum functions as described in this link:

The code (even if you put the bare minimum function) does not compile... so can not become a program as it is "written." Before trying to tackle this game idea, try some of Arduino's built-in examples to get you started. When you see a similarity in one of the examples, learn how to use it in your own program. Draw those parts into a whole picture of how your game will run. Pasting a bunch of code from various sources is not going to create a running program... here's why...

sketch.ino: In function 'void search()':
sketch.ino:2:3: error: 'refresh' was not declared in this scope
   refresh = true;
   ^~~~~~~
sketch.ino:3:3: error: 'cls' was not declared in this scope
   cls();
   ^~~
sketch.ino:3:3: note: suggested alternative: 'cos'
   cls();
   ^~~
   cos
sketch.ino:4:16: error: 'REDLED' was not declared in this scope
   digitalWrite(REDLED, LOW);
                ^~~~~~
sketch.ino:4:16: note: suggested alternative: 'EULER'
   digitalWrite(REDLED, LOW);
                ^~~~~~
                EULER
sketch.ino:5:16: error: 'GREENLED' was not declared in this scope
   digitalWrite(GREENLED, LOW);
                ^~~~~~~~
sketch.ino:7:17: error: 'GAMEMINUTES' was not declared in this scope
   int minutos = GAMEMINUTES - 1;
                 ^~~~~~~~~~~
sketch.ino:16:9: error: 'endGame' was not declared in this scope
     if (endGame) {
         ^~~~~~~
sketch.ino:16:9: note: suggested alternative: 'rename'
     if (endGame) {
         ^~~~~~~
         rename
sketch.ino:17:7: error: 'failSplash' was not declared in this scope
       failSplash();
       ^~~~~~~~~~
sketch.ino:21:5: error: 'timeCalcVar' was not declared in this scope
     timeCalcVar = (millis() - iTime) % 1000;
     ^~~~~~~~~~~
sketch.ino:25:5: error: 'lcd' was not declared in this scope
     lcd.setCursor(3, 0);
     ^~~
sketch.ino:26:15: error: 'GAME_TIME_TOP' was not declared in this scope
     lcd.print(GAME_TIME_TOP);
               ^~~~~~~~~~~~~
sketch.ino:32:5: error: 'printTime' was not declared in this scope
     printTime(minutos, aTime);
     ^~~~~~~~~
sketch.ino:32:5: note: suggested alternative: 'iTime'
     printTime(minutos, aTime);
     ^~~~~~~~~
     iTime
sketch.ino:37:73: error: 'failSplash' was not declared in this scope
     if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0)failSplash();
                                                                         ^~~~~~~~~~
sketch.ino:40:16: error: 'keypad' was not declared in this scope
     if ('d' == keypad.getKey() && passwordEnable) {
                ^~~~~~
sketch.ino:40:35: error: 'passwordEnable' was not declared in this scope
     if ('d' == keypad.getKey() && passwordEnable) {
                                   ^~~~~~~~~~~~~~
sketch.ino:43:17: error: 'ARMING_BOMB' was not declared in this scope
       lcd.print(ARMING_BOMB);
                 ^~~~~~~~~~~
sketch.ino:47:17: error: 'ENTER_CODE' was not declared in this scope
       lcd.print(ENTER_CODE);
                 ^~~~~~~~~~
sketch.ino:49:7: error: 'setCodeTime' was not declared in this scope
       setCodeTime();// we need to set the comparation variable first it writes on codeInput[]
       ^~~~~~~~~~~
sketch.ino:53:11: error: 'comparePassword' was not declared in this scope
       if (comparePassword()) destroy();
           ^~~~~~~~~~~~~~~
sketch.ino:53:11: note: suggested alternative: 'pgm_read_word'
       if (comparePassword()) destroy();
           ^~~~~~~~~~~~~~~
           pgm_read_word
sketch.ino:56:17: error: 'CODE_ERROR' was not declared in this scope
       lcd.print(CODE_ERROR);
                 ^~~~~~~~~~
sketch.ino:56:17: note: suggested alternative: '_FDEV_ERR'
       lcd.print(CODE_ERROR);
                 ^~~~~~~~~~
                 _FDEV_ERR
sketch.ino:57:11: error: 'soundEnable' was not declared in this scope
       if (soundEnable)tone(tonepin, errorTone, 200);
           ^~~~~~~~~~~
sketch.ino:57:28: error: 'tonepin' was not declared in this scope
       if (soundEnable)tone(tonepin, errorTone, 200);
                            ^~~~~~~
sketch.ino:57:28: note: suggested alternative: 'tone'
       if (soundEnable)tone(tonepin, errorTone, 200);
                            ^~~~~~~
                            tone
sketch.ino:57:37: error: 'errorTone' was not declared in this scope
       if (soundEnable)tone(tonepin, errorTone, 200);
                                     ^~~~~~~~~
sketch.ino:57:37: note: suggested alternative: 'noTone'
       if (soundEnable)tone(tonepin, errorTone, 200);
                                     ^~~~~~~~~
                                     noTone
sketch.ino:62:12: error: 'defusing' was not declared in this scope
     while (defusing && !passwordEnable)
            ^~~~~~~~
sketch.ino:62:25: error: 'passwordEnable' was not declared in this scope
     while (defusing && !passwordEnable)
                         ^~~~~~~~~~~~~~
sketch.ino:67:17: error: 'ARMING_BOMB' was not declared in this scope
       lcd.print(ARMING_BOMB);
                 ^~~~~~~~~~~
sketch.ino:73:9: error: 'keypad' was not declared in this scope
         keypad.getKey();
         ^~~~~~
sketch.ino:74:41: error: 'ACTIVATESECONDS' was not declared in this scope
         percent = (millis() - xTime) / (ACTIVATESECONDS * 10);
                                         ^~~~~~~~~~~~~~~
sketch.ino:76:9: error: 'drawBar' was not declared in this scope
         drawBar(percent);
         ^~~~~~~
sketch.ino:81:11: error: 'endGame' was not declared in this scope
           endGame = true;
           ^~~~~~~
sketch.ino:81:11: note: suggested alternative: 'rename'
           endGame = true;
           ^~~~~~~
           rename
sketch.ino:88:15: error: 'soundEnable' was not declared in this scope
           if (soundEnable)tone(tonepin, alarmTone1, 200);
               ^~~~~~~~~~~
sketch.ino:88:32: error: 'tonepin' was not declared in this scope
           if (soundEnable)tone(tonepin, alarmTone1, 200);
                                ^~~~~~~
sketch.ino:88:32: note: suggested alternative: 'tone'
           if (soundEnable)tone(tonepin, alarmTone1, 200);
                                ^~~~~~~
                                tone
sketch.ino:88:41: error: 'alarmTone1' was not declared in this scope
           if (soundEnable)tone(tonepin, alarmTone1, 200);
                                         ^~~~~~~~~~
sketch.ino:92:15: error: 'soundEnable' was not declared in this scope
           if (soundEnable)tone(tonepin, alarmTone2, 200);
               ^~~~~~~~~~~
sketch.ino:92:32: error: 'tonepin' was not declared in this scope
           if (soundEnable)tone(tonepin, alarmTone2, 200);
                                ^~~~~~~
sketch.ino:92:32: note: suggested alternative: 'tone'
           if (soundEnable)tone(tonepin, alarmTone2, 200);
                                ^~~~~~~
                                tone
sketch.ino:92:41: error: 'alarmTone2' was not declared in this scope
           if (soundEnable)tone(tonepin, alarmTone2, 200);
                                         ^~~~~~~~~~
sketch.ino: In function 'void destroy()':
sketch.ino:112:3: error: 'lcd' was not declared in this scope
   lcd.clear();
   ^~~
sketch.ino:114:13: error: 'BOMB_ARMED' was not declared in this scope
   lcd.print(BOMB_ARMED);
             ^~~~~~~~~~
sketch.ino:116:17: error: 'BOMBMINUTES' was not declared in this scope
   int minutos = BOMBMINUTES - 1;
                 ^~~~~~~~~~~
sketch.ino:125:9: error: 'endGame' was not declared in this scope
     if (endGame) {
         ^~~~~~~
sketch.ino:125:9: note: suggested alternative: 'rename'
     if (endGame) {
         ^~~~~~~
         rename
sketch.ino:126:7: error: 'explodeSplash' was not declared in this scope
       explodeSplash();
       ^~~~~~~~~~~~~
sketch.ino:131:5: error: 'timeCalcVar' was not declared in this scope
     timeCalcVar = (millis() - iTime) % 1000;
     ^~~~~~~~~~~
sketch.ino:134:20: error: 'REDLED' was not declared in this scope
       digitalWrite(REDLED, HIGH);
                    ^~~~~~
sketch.ino:134:20: note: suggested alternative: 'EULER'
       digitalWrite(REDLED, HIGH);
                    ^~~~~~
                    EULER
sketch.ino:135:11: error: 'soundEnable' was not declared in this scope
       if (soundEnable)tone(tonepin, activeTone, largoTono);
           ^~~~~~~~~~~
sketch.ino:135:28: error: 'tonepin' was not declared in this scope
       if (soundEnable)tone(tonepin, activeTone, largoTono);
                            ^~~~~~~
sketch.ino:135:28: note: suggested alternative: 'tone'
       if (soundEnable)tone(tonepin, activeTone, largoTono);
                            ^~~~~~~
                            tone
sketch.ino:135:37: error: 'activeTone' was not declared in this scope
       if (soundEnable)tone(tonepin, activeTone, largoTono);
                                     ^~~~~~~~~~
sketch.ino:138:20: error: 'REDLED' was not declared in this scope
       digitalWrite(REDLED, LOW);
                    ^~~~~~
sketch.ino:138:20: note: suggested alternative: 'EULER'
       digitalWrite(REDLED, LOW);
                    ^~~~~~
                    EULER
sketch.ino:143:84: error: 'soundEnable' was not declared in this scope
     if (timeCalcVar >= 245 && timeCalcVar <= 255 && minutos - aTime / 60000 < 2 && soundEnable)tone(tonepin, activeTone, largoTono);
                                                                                    ^~~~~~~~~~~
sketch.ino:143:101: error: 'tonepin' was not declared in this scope
     if (timeCalcVar >= 245 && timeCalcVar <= 255 && minutos - aTime / 60000 < 2 && soundEnable)tone(tonepin, activeTone, largoTono);
                                                                                                     ^~~~~~~
sketch.ino:143:101: note: suggested alternative: 'tone'
     if (timeCalcVar >= 245 && timeCalcVar <= 255 && minutos - aTime / 60000 < 2 && soundEnable)tone(tonepin, activeTone, largoTono);
                                                                                                     ^~~~~~~
                                                                                                     tone
sketch.ino:143:110: error: 'activeTone' was not declared in this scope
     if (timeCalcVar >= 245 && timeCalcVar <= 255 && minutos - aTime / 60000 < 2 && soundEnable)tone(tonepin, activeTone, largoTono);
                                                                                                              ^~~~~~~~~~
sketch.ino:144:84: error: 'soundEnable' was not declared in this scope
     if (timeCalcVar >= 495 && timeCalcVar <= 510 && minutos - aTime / 60000 < 4 && soundEnable)tone(tonepin, activeTone, largoTono);
                                                                                    ^~~~~~~~~~~
sketch.ino:144:101: error: 'tonepin' was not declared in this scope
     if (timeCalcVar >= 495 && timeCalcVar <= 510 && minutos - aTime / 60000 < 4 && soundEnable)tone(tonepin, activeTone, largoTono);
                                                                                                     ^~~~~~~
sketch.ino:144:101: note: suggested alternative: 'tone'
     if (timeCalcVar >= 495 && timeCalcVar <= 510 && minutos - aTime / 60000 < 4 && soundEnable)tone(tonepin, activeTone, largoTono);
                                                                                                     ^~~~~~~
                                                                                                     tone
sketch.ino:144:110: error: 'activeTone' was not declared in this scope
     if (timeCalcVar >= 495 && timeCalcVar <= 510 && minutos - aTime / 60000 < 4 && soundEnable)tone(tonepin, activeTone, largoTono);
                                                                                                              ^~~~~~~~~~
sketch.ino:145:84: error: 'soundEnable' was not declared in this scope
     if (timeCalcVar >= 745 && timeCalcVar <= 760 && minutos - aTime / 60000 < 2 && soundEnable)tone(tonepin, activeTone, largoTono);
                                                                                    ^~~~~~~~~~~
sketch.ino:145:101: error: 'tonepin' was not declared in this scope
     if (timeCalcVar >= 745 && timeCalcVar <= 760 && minutos - aTime / 60000 < 2 && soundEnable)tone(tonepin, activeTone, largoTono);
                                                                                                     ^~~~~~~
sketch.ino:145:101: note: suggested alternative: 'tone'
     if (timeCalcVar >= 745 && timeCalcVar <= 760 && minutos - aTime / 60000 < 2 && soundEnable)tone(tonepin, activeTone, largoTono);
                                                                                                     ^~~~~~~
                                                                                                     tone
sketch.ino:145:110: error: 'activeTone' was not declared in this scope
     if (timeCalcVar >= 745 && timeCalcVar <= 760 && minutos - aTime / 60000 < 2 && soundEnable)tone(tonepin, activeTone, largoTono);
                                                                                                              ^~~~~~~~~~
sketch.ino:149:15: error: 'DETONATION_IN' was not declared in this scope
     lcd.print(DETONATION_IN);
               ^~~~~~~~~~~~~
sketch.ino:159:7: error: 'explodeSplash' was not declared in this scope
       explodeSplash();
       ^~~~~~~~~~~~~
sketch.ino:163:5: error: 'printTime' was not declared in this scope
     printTime(minutos, aTime);
     ^~~~~~~~~
sketch.ino:163:5: note: suggested alternative: 'iTime'
     printTime(minutos, aTime);
     ^~~~~~~~~
     iTime
sketch.ino:169:16: error: 'keypad' was not declared in this scope
     if ('d' == keypad.getKey() && passwordEnable) {
                ^~~~~~
sketch.ino:169:35: error: 'passwordEnable' was not declared in this scope
     if ('d' == keypad.getKey() && passwordEnable) {
                                   ^~~~~~~~~~~~~~
sketch.ino:173:17: error: 'DISARMING' was not declared in this scope
       lcd.print(DISARMING);
                 ^~~~~~~~~
sketch.ino:173:17: note: suggested alternative: 'RISING'
       lcd.print(DISARMING);
                 ^~~~~~~~~
                 RISING
sketch.ino:178:17: error: 'ENTER_CODE' was not declared in this scope
       lcd.print(ENTER_CODE);
                 ^~~~~~~~~~
sketch.ino:180:7: error: 'setCodeTime' was not declared in this scope
       setCodeTime();// we need to set the compare variable first
       ^~~~~~~~~~~
sketch.ino:184:11: error: 'comparePassword' was not declared in this scope
       if (comparePassword()) {
           ^~~~~~~~~~~~~~~
sketch.ino:184:11: note: suggested alternative: 'pgm_read_word'
       if (comparePassword()) {
           ^~~~~~~~~~~~~~~
           pgm_read_word
sketch.ino:185:9: error: 'disarmedSplash' was not declared in this scope
         disarmedSplash();
         ^~~~~~~~~~~~~~
sketch.ino:189:17: error: 'CODE_ERROR' was not declared in this scope
       lcd.print(CODE_ERROR);
                 ^~~~~~~~~~
sketch.ino:189:17: note: suggested alternative: '_FDEV_ERR'
       lcd.print(CODE_ERROR);
                 ^~~~~~~~~~
                 _FDEV_ERR
sketch.ino:190:11: error: 'soundEnable' was not declared in this scope
       if (soundEnable)tone(tonepin, errorTone, 200);
           ^~~~~~~~~~~
sketch.ino:190:28: error: 'tonepin' was not declared in this scope
       if (soundEnable)tone(tonepin, errorTone, 200);
                            ^~~~~~~
sketch.ino:190:28: note: suggested alternative: 'tone'
       if (soundEnable)tone(tonepin, errorTone, 200);
                            ^~~~~~~
                            tone
sketch.ino:190:37: error: 'errorTone' was not declared in this scope
       if (soundEnable)tone(tonepin, errorTone, 200);
                                     ^~~~~~~~~
sketch.ino:190:37: note: suggested alternative: 'noTone'
       if (soundEnable)tone(tonepin, errorTone, 200);
                                     ^~~~~~~~~
                                     noTone
sketch.ino:192:7: error: 'cls' was not declared in this scope
       cls();
       ^~~
sketch.ino:192:7: note: suggested alternative: 'cos'
       cls();
       ^~~
       cos
sketch.ino:195:9: error: 'defusing' was not declared in this scope
     if (defusing && !passwordEnable) // disarming bomb
         ^~~~~~~~
sketch.ino:195:22: error: 'passwordEnable' was not declared in this scope
     if (defusing && !passwordEnable) // disarming bomb
                      ^~~~~~~~~~~~~~
sketch.ino:198:20: error: 'REDLED' was not declared in this scope
       digitalWrite(REDLED, LOW);
                    ^~~~~~
sketch.ino:198:20: note: suggested alternative: 'EULER'
       digitalWrite(REDLED, LOW);
                    ^~~~~~
                    EULER
sketch.ino:200:17: error: 'DISARM' was not declared in this scope
       lcd.print(DISARM);
                 ^~~~~~
sketch.ino:200:17: note: suggested alternative: 'DIDR0'
       lcd.print(DISARM);
                 ^~~~~~
                 DIDR0
sketch.ino:206:9: error: 'keypad' was not declared in this scope
         keypad.getKey();
         ^~~~~~
sketch.ino:210:11: error: 'endGame' was not declared in this scope
           endGame = true;
           ^~~~~~~
sketch.ino:210:11: note: suggested alternative: 'rename'
           endGame = true;
           ^~~~~~~
           rename
sketch.ino:215:24: error: 'GREENLED' was not declared in this scope
           digitalWrite(GREENLED, HIGH);
                        ^~~~~~~~
sketch.ino:216:15: error: 'soundEnable' was not declared in this scope
           if (soundEnable)tone(tonepin, alarmTone1, 200);
               ^~~~~~~~~~~
sketch.ino:216:32: error: 'tonepin' was not declared in this scope
           if (soundEnable)tone(tonepin, alarmTone1, 200);
                                ^~~~~~~
sketch.ino:216:32: note: suggested alternative: 'tone'
           if (soundEnable)tone(tonepin, alarmTone1, 200);
                                ^~~~~~~
                                tone
sketch.ino:216:41: error: 'alarmTone1' was not declared in this scope
           if (soundEnable)tone(tonepin, alarmTone1, 200);
                                         ^~~~~~~~~~
sketch.ino:216:41: note: suggested alternative: 'largoTono'
           if (soundEnable)tone(tonepin, alarmTone1, 200);
                                         ^~~~~~~~~~
                                         largoTono
sketch.ino:220:15: error: 'soundEnable' was not declared in this scope
           if (soundEnable)tone(tonepin, alarmTone2, 200);
               ^~~~~~~~~~~
sketch.ino:220:32: error: 'tonepin' was not declared in this scope
           if (soundEnable)tone(tonepin, alarmTone2, 200);
                                ^~~~~~~
sketch.ino:220:32: note: suggested alternative: 'tone'
           if (soundEnable)tone(tonepin, alarmTone2, 200);
                                ^~~~~~~
                                tone
sketch.ino:220:41: error: 'alarmTone2' was not declared in this scope
           if (soundEnable)tone(tonepin, alarmTone2, 200);
                                         ^~~~~~~~~~
sketch.ino:220:41: note: suggested alternative: 'largoTono'
           if (soundEnable)tone(tonepin, alarmTone2, 200);
                                         ^~~~~~~~~~
                                         largoTono
sketch.ino:221:24: error: 'GREENLED' was not declared in this scope
           digitalWrite(GREENLED, LOW);
                        ^~~~~~~~
sketch.ino:224:30: error: 'ACTIVATESECONDS' was not declared in this scope
         percent = seconds / (ACTIVATESECONDS * 10);
                              ^~~~~~~~~~~~~~~
sketch.ino:225:9: error: 'drawBar' was not declared in this scope
         drawBar(percent);
         ^~~~~~~
sketch.ino:228:28: error: 'disarmedSplash' was not declared in this scope
         if (percent >= 100)disarmedSplash();
                            ^~~~~~~~~~~~~~
sketch.ino:231:20: error: 'GREENLED' was not declared in this scope
       digitalWrite(GREENLED, LOW);
                    ^~~~~~~~
sketch.ino:232:7: error: 'cls' was not declared in this scope
       cls();
       ^~~
sketch.ino:232:7: note: suggested alternative: 'cos'
       cls();
       ^~~
       cos

Error during build: exit status 1

I started a cleanup on your project by making loop() and setup() declaring variables, assigning pins, and moving tasks into functions. You have a few big things to do:

  • keypad
  • tone ** lots of Tone() errors...
  • search
  • password
  • setCodeTime();

Here it is for you to edit:

// https://forum.arduino.cc/t/code-help-for-bomb-game/1162639

#include <LiquidCrystal_I2C.h> // call LCD library for communicating with the LCD
LiquidCrystal_I2C lcd(0x27, 16, 2); // LCD address 0x27, 16 characterss, 2 lines
// To find an I2C address use an I2C scanner first: https://playground.arduino.cc/Main/I2cScanner/

#include <Tone.h> // for tones

#include <Keypad.h>
const uint8_t ROWS = 4;
const uint8_t COLS = 4;
char keys[ROWS][COLS] = {
  { '1', '2', '3', 'A' },
  { '4', '5', '6', 'B' },
  { '7', '8', '9', 'C' },
  { '*', '0', '#', 'D' }
};

uint8_t colPins[COLS] = { 12, 11, 10, 9 }; // Pins connected to C1, C2, C3, C4
uint8_t rowPins[ROWS] = { 8, 7, 6, 5 }; // Pins connected to R1, R2, R3, R4
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

byte REDLED = 2; // the RED LED pin
byte GREENLED = 3; // the GREEN LED pin
byte tonepin = 4;

unsigned long GAMEMINUTES = 2 * 60 * 1000UL; // 2 * 60 seconds per minute * 1000 milliseconds per second
unsigned long minutos = GAMEMINUTES - 1;
unsigned long iTime = millis(); //  initialTime in millisec
unsigned long aTime; // millis() - iTime
unsigned long ACTIVATESECONDS; // probably int ACTIVATESECONDS from aTime (millis)
unsigned long BOMBMINUTES; // probably int BOMBMINUTES 
unsigned long xTime; // disabling time
unsigned long seconds; // millis() - xTime

int percent = 0;
int errorTone = NOTE_A4; // intended to be 440 Hz
int alarmTone1 = NOTE_A3; //
int alarmTone2 = NOTE_B3; //
int activeTone = NOTE_C3; // 
int largoTono = 50;

bool endGame; // Game Over flag
bool passwordEnable; //
bool defusing; //
bool soundEnable; // enable Tone();

unsigned long timeCalcVar; // for blinking LEDs

//var='o'; // probably not doing anything, but left it in anyway

void setup() {
  Serial.begin(115200); // start the Serial Monitor

  lcd.init(); // start the LCD
  lcd.backlight(); // turn LCD backlight on

  pinMode(REDLED, OUTPUT); // configure the RED LED pin to be an OUTPUT pin
  pinMode(GREENLED, OUTPUT); // configure the GREEN LED pin to be an OUTPUT pin

  digitalWrite(REDLED, LOW); // turn RED LED OFF
  digitalWrite(GREENLED, LOW); // turn GREEN LED OFF

  // refresh = true; // probably was to start another game, probably not needed
  lcd.clear();  // Clear the LCD display - replaces cls();;
}

void loop() {
  //Starting Game Code -  write tasks as functions and call functions from loop();
  search();
}

void search() {
  if (endGame) {  //If you fail disarm.
    failSplash(); // call game over function
  }

  //Code for led blinking
  timeCalcVar = (millis() - iTime) % 1000;
  if (timeCalcVar >= 0 && timeCalcVar <= 50)digitalWrite(GREENLED, HIGH);
  if (timeCalcVar >= 90 && timeCalcVar <= 130)digitalWrite(GREENLED, LOW);

  lcd.setCursor(3, 0);
  lcd.print("GAME_TIME_TOP");
  aTime = millis() - iTime;
  lcd.setCursor(3, 1);

  //PRINT TIME ON LCD
  printTime(minutos, aTime);

  //###########################CHECKINGS##################

  //Check If Game End
  if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0)
    failSplash();
  //Serial.println(keypad.getKey());
  //USED IN PASSWORD GAME
  if ('d' == keypad.getKey() && passwordEnable) {
    lcd.clear();
    lcd.setCursor(2, 0);
    lcd.print("ARMING_BOMB");
    delay(1000);//a little delay to choose the password
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("ENTER_CODE");

    setCodeTime();// we need to set the comparation variable first it writes on codeInput[]

    //then compare :D

    if (comparePassword()) destroy();
    lcd.clear();
    lcd.setCursor(3, 0);
    lcd.print("CODE_ERROR");
    if (soundEnable)
      tone(tonepin, errorTone, 200);
    delay(500);
    lcd.clear();
  }
  //Check If Is Activating
  while (defusing && !passwordEnable)
  {
    digitalWrite(GREENLED, LOW);
    lcd.clear();
    lcd.setCursor(2, 0);
    lcd.print("ARMING_BOMB");
    // lcd.setCursor(0, 1); // there is no lcd.print(); to follow - remove

    percent = 0;
    xTime = millis(); //start disabling time

    while (defusing)
    {
      keypad.getKey();
      percent = (millis() - xTime) / (ACTIVATESECONDS * 10);

      drawBar(percent);

      //check if game time runs out during the disabling
      aTime = millis() - iTime;
      Serial.println(millis() - xTime);

      if ((minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) || minutos - aTime / 60000 > 4000000000) {
        endGame = true;
      }

      timeCalcVar = (millis() - xTime) % 1000;

      if ( timeCalcVar >= 0 && timeCalcVar <= 40)
      {
        digitalWrite(REDLED, HIGH);
        if (soundEnable)
          tone(tonepin, alarmTone1, 200);
      }

      if (timeCalcVar >= 480 && timeCalcVar <= 520)
      {
        if (soundEnable)
          tone(tonepin, alarmTone2, 200);
        digitalWrite(REDLED, LOW);
      }

      if (percent >= 100)
      {
        digitalWrite(GREENLED, LOW);
        destroy();// jump to the next gamemode
      }
    }
    lcd.clear();
    digitalWrite(REDLED, LOW);
  }
}

void destroy() {
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("BOMB ARMED");
  delay(1000);

  minutos = BOMBMINUTES - 1;
  iTime = millis();

  //MAIN LOOP // this was part of a second game - remove it
  // while (1) { // this does not belong here - remove it

  //If you fail disarm.
  if (endGame) {
    explodeSplash();
  }

  //Led Blink

  timeCalcVar = (millis() - iTime) % 1000;
  if (timeCalcVar >= 0 && timeCalcVar <= 40)
  {
    digitalWrite(REDLED, HIGH);
    if (soundEnable)tone(tonepin, activeTone, largoTono);
  }
  if (timeCalcVar >= 180 && timeCalcVar <= 220) {
    digitalWrite(REDLED, LOW);
  }
  //Sound
  aTime = millis() - iTime;
  timeCalcVar = (millis() - iTime) % 1000;
  if (timeCalcVar >= 245 && timeCalcVar <= 255 && minutos - aTime / 60000 < 2 && soundEnable)
    tone(tonepin, activeTone, largoTono);
  if (timeCalcVar >= 495 && timeCalcVar <= 510 && minutos - aTime / 60000 < 4 && soundEnable)
    tone(tonepin, activeTone, largoTono);
  if (timeCalcVar >= 745 && timeCalcVar <= 760 && minutos - aTime / 60000 < 2 && soundEnable)
    tone(tonepin, activeTone, largoTono);
  if ( minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) < 10)largoTono = 300;

  lcd.setCursor(1, 0);
  lcd.print("DETONATION_IN");

  //Passed Time
  lcd.setCursor(3, 1);

  ////////HERE ARE THE TWO OPTIONS THAT ENDS THE GAME///////////

  ////TIME PASED AWAY AND THE BOMB EXPLODES
  if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) // Check if game ends
  {
    explodeSplash();
  }
  //print time

  printTime(minutos, aTime);

  //// SECOND OPTION: YOU PRESS DISARMING BUTTON

  //IF IS A PASSWORD GAME

  if ('d' == keypad.getKey() && passwordEnable) {

    lcd.clear();
    lcd.setCursor(1, 0);
    lcd.print("DISARMING");
    delay(1000);//a little delay to think in the password

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("ENTER_CODE");

    setCodeTime();// we need to set the compare variable first

    //then compare :D

    if (comparePassword()) {
      disarmedSplash();
    }
    lcd.clear();
    lcd.setCursor(3, 0);
    lcd.print("CODE_ERROR");
    if (soundEnable)
      tone(tonepin, errorTone, 200);
    delay(500);
    lcd.clear();
  }

  if (defusing && !passwordEnable) // disarming bomb
  {
    lcd.clear();
    digitalWrite(REDLED, LOW);
    lcd.setCursor(3, 0);
    lcd.print("DISARM");
    lcd.setCursor(0, 1);
    unsigned int percent = 0;
    unsigned long xTime = millis();
    while (defusing)
    {
      keypad.getKey();
      //check if game time runs out during the disabling
      aTime = millis() - iTime;
      if ((minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) || minutos - aTime / 60000 > 4000000000) {
        endGame = true;
      }
      timeCalcVar = (millis() - xTime) % 1000;
      if (timeCalcVar >= 0 && timeCalcVar <= 20)
      {
        digitalWrite(GREENLED, HIGH);
        if (soundEnable)
          tone(tonepin, alarmTone1, 200);
      }
      if (timeCalcVar  >= 480 && timeCalcVar <= 500)
      {
        if (soundEnable)
          tone(tonepin, alarmTone2, 200);
        digitalWrite(GREENLED, LOW);
      }
      seconds = (millis() - xTime);
      percent = seconds / (ACTIVATESECONDS * 10);
      drawBar(percent);

      //BOMB DISARMED GAME OVER
      if (percent >= 100)
        disarmedSplash();
    }
    digitalWrite(REDLED, LOW);
    digitalWrite(GREENLED, LOW);
    lcd.clear();
  }
}

void disarmedSplash() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("BOMB DISARMED");
  gameOver();
}

void failSplash() { // original name
  gameOver(); // a better name
}

void gameOver() {
  lcd.setCursor(3, 0);
  lcd.print("GAME  OVER");
  for (int i = 0; i < 4; i++)
  {
    lcd.backlight();
    delay(250);
    lcd.noBacklight();
    delay(250);
  }
  lcd.backlight();
  delay(500);
  lcd.setCursor(3, 0);
  lcd.print("          ");
  lcd.setCursor(3, 1);
  lcd.print("GAME  OVER");
  delay(500);
  lcd.clear();
  delay(500);
  lcd.noBacklight();
}

void drawBar(int percent) {
  lcd.setCursor(0, 1);
  lcd.print("0%");
  lcd.setCursor(12, 1);
  if (percent < 100)
    lcd.print(" ");
  lcd.print(percent);
  lcd.print("%");
  lcd.setCursor(2, 1);
  for (int i = 0; i < percent / 10; i++) {
    lcd.print("#");
  }
  // For a better gauge see upir
  // YouTube: https://www.youtube.com/watch?v=Mq0WBPKGRew
  // Wokwi:   https://wokwi.com/projects/336618647787143762
}

void printTime(int minutos, int atime) {
  lcd.setCursor(0, 0);
  lcd.print("MIN: ");
  lcd.print(minutos);
  lcd.setCursor(8, 0);
  lcd.print("aT: ");
  lcd.print(atime);
}

void setCodeTime() {
  // function unknown - placed here for compiling
  // probably a timer for when decoding starts
}

bool comparePassword() {
  // function unknown - placed here for compiling
}

void explodeSplash() {
  // function unknown - placed here for compiling
}
1 Like

I have amended it as best as I can now.

Thank you very much. I will get right on that.

I do not suppose you could look at this segment?
This is the code for when it "explodes" and I was wondering if there is a way to engage certain things when it activates like in my main post for starting up a strobe and MP3.


void explodeSplash(){
  digitalWrite(REDLED, LOW);  
  digitalWrite(GREENLED, LOW); 
  cls();
  delay(100);
  endGame = false;
  lcd.setCursor(1,0);
  lcd.print("TERRORISTS WIN");
  lcd.setCursor(4,1);
  lcd.print("GAME OVER");
  for(int i = 200; i>0; i--)// this is the ultra hi definition explosion sound xD
  {
    tone(tonepin,i);
    delay(20);
  }
  noTone(tonepin);
  if(relayEnable){
    activateRelay(); 
  }
  delay(5000);
  cls();

  //end code
  lcd.print("Play Again?");
  lcd.setCursor(0,1);
  lcd.print("A : Yes B : No");
  while(1)
  {
    var = keypad.waitForKey();
    if(var == 'a' ){
      tone(tonepin,2400,30);
      //We have two options, search & destroy and sabotage play again options so!
      if(sdStatus){
        startGameCount();
        search();
      }
      if(saStatus){
        saStatus=true;
        startGameCount();
        start=true; //to set iTime to actual millis() :D
        sabotage();
      }
    }  
    if(var == 'b' ){
      tone(tonepin,2400,30);
      menuPrincipal();

      break;
    }  
  } 
}
void failSplash(){
  digitalWrite(REDLED, LOW);  
  digitalWrite(GREENLED, LOW); 
  cls();
  delay(100);
  endGame = false;
  lcd.setCursor(1,0);
  lcd.print("TIME OUT");
  lcd.setCursor(4,1);
  lcd.print("GAME OVER");
  for(int i = 200; i>0; i--)// this is the ultra hi definition explosion sound xD
  {
    tone(tonepin,i);
    delay(20);
  }
  noTone(tonepin);
  if(relayEnable){
    activateRelay(); 
  }
  delay(5000);
  cls();

  //end code
  lcd.print("Play Again?");
  lcd.setCursor(0,1);
  lcd.print("A : Yes B : No");
  while(1)
  {
    var = keypad.waitForKey();
    if(var == 'a' ){
      tone(tonepin,2400,30);
      //We have two options, search & destroy and sabotaje play again options so!
      if(sdStatus){
        startGameCount();
        search();
      }
      if(saStatus){
        saStatus=true;
        startGameCount();
        start=true; //to set iTime to actual millis() :D
        sabotage();
      }
    }  
    if(var == 'b' ){
      tone(tonepin,2400,30);
      menuPrincipal();

      break;
    }  
  } 
}
void disarmedSplash(){
  endGame = false;
  digitalWrite(REDLED, LOW); 
  digitalWrite(GREENLED, LOW);
  if(sdStatus || saStatus){
    lcd.clear();
    lcd.setCursor(2,0);
    lcd.print("BOMB DISARMED");
    lcd.setCursor(3,1);
    lcd.print("MILITARY WINS");
    digitalWrite(GREENLED, HIGH);  
    delay(5000);
    digitalWrite(GREENLED, LOW); 
  }
  //end code
  lcd.clear();
  lcd.print("Play Again?");
  lcd.setCursor(0,1);
  lcd.print("A : Yes B : No");
  digitalWrite(REDLED, LOW);  
  digitalWrite(GREENLED, LOW); 
  while(1)
  {
    var = keypad.waitForKey();
    if(var == 'a' ){
      tone(tonepin,2400,30);
      //We have two options, search & destroy and sabotaje play again options so!
      if(sdStatus){
        startGameCount();
        search();
      }
      if(saStatus){
        saStatus=true;
        startGameCount();
        start=true; //to set iTime to actual millis() :D
        sabotage();
      }
    }  
    if(var == 'b' ){
      tone(tonepin,2400,30);
      menuPrincipal();
      break;
    }  
  } 
}

This chunk has the same errors as the first chunk of code. If I created the same function name as this chunk, just paste your function over mine. You have a lot of work to do, but it will be fun for you.

if anyone has insight, please advise... These errors are from the IDE, but they also are reported on Wokwi (see simulation link above) I think these errors are due to shared timers... tone() is sharing with something, maybe millis()...

Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
(.text+0x0): multiple definition of `timer0_pin_port'
C:\Users\newuser\AppData\Local\Temp\arduino\sketches\1CB74D3DC27D52D7B9A1E9346023CA28\libraries\Tone\Tone.cpp.o (symbol from plugin):(.text+0x0): first defined here
Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
(.text+0x0): multiple definition of `timer0_pin_mask'
C:\Users\newuser\AppData\Local\Temp\arduino\sketches\1CB74D3DC27D52D7B9A1E9346023CA28\libraries\Tone\Tone.cpp.o (symbol from plugin):(.text+0x0): first defined here
Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
(.text+0x0): multiple definition of `timer1_pin_port'
C:\Users\newuser\AppData\Local\Temp\arduino\sketches\1CB74D3DC27D52D7B9A1E9346023CA28\libraries\Tone\Tone.cpp.o (symbol from plugin):(.text+0x0): first defined here
Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
(.text+0x0): multiple definition of `timer1_pin_mask'
C:\Users\newuser\AppData\Local\Temp\arduino\sketches\1CB74D3DC27D52D7B9A1E9346023CA28\libraries\Tone\Tone.cpp.o (symbol from plugin):(.text+0x0): first defined here
Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
(.text+0x0): multiple definition of `timer2_pin_port'
C:\Users\newuser\AppData\Local\Temp\arduino\sketches\1CB74D3DC27D52D7B9A1E9346023CA28\libraries\Tone\Tone.cpp.o (symbol from plugin):(.text+0x0): first defined here
Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
(.text+0x0): multiple definition of `timer2_pin_mask'
C:\Users\newuser\AppData\Local\Temp\arduino\sketches\1CB74D3DC27D52D7B9A1E9346023CA28\libraries\Tone\Tone.cpp.o (symbol from plugin):(.text+0x0): first defined here
Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
(.text+0x0): multiple definition of `timer0_toggle_count'
C:\Users\newuser\AppData\Local\Temp\arduino\sketches\1CB74D3DC27D52D7B9A1E9346023CA28\libraries\Tone\Tone.cpp.o (symbol from plugin):(.text+0x0): first defined here
Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
(.text+0x0): multiple definition of `timer1_toggle_count'
C:\Users\newuser\AppData\Local\Temp\arduino\sketches\1CB74D3DC27D52D7B9A1E9346023CA28\libraries\Tone\Tone.cpp.o (symbol from plugin):(.text+0x0): first defined here
Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
(.text+0x0): multiple definition of `timer2_toggle_count'
C:\Users\newuser\AppData\Local\Temp\arduino\sketches\1CB74D3DC27D52D7B9A1E9346023CA28\libraries\Tone\Tone.cpp.o (symbol from plugin):(.text+0x0): first defined here
Tone.cpp.o (symbol from plugin): In function `timer0_pin_port':
(.text+0x0): multiple definition of `__vector_7'
C:\Users\newuser\AppData\Local\Temp\arduino\sketches\1CB74D3DC27D52D7B9A1E9346023CA28\libraries\Tone\Tone.cpp.o (symbol from plugin):(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1
1 Like

@airsoftonlinejapan - Where (online) is the original code... because I can see that you have not shown all of it.

1 Like

Thank you for the feedback.
Sorry, I am very new to coding as I am more familiar with the hardware aspect

The Code is here

The Diagram I used is here

I am sorry for my poor knowledge on this. I modified some parts of the code and added on addition game modes. They all work fine. But I was hoping to tidy up the code a little, make it more simple and give various options for the detonation sequence as mentioned in the original post. But honestly, I am at a loss.

I found the reason for these errors when compiling...

with that "Tone" library you need to create a Tone object, such as:

#include <Tone.h>
Tone tonePin;
const uint8_t speaker = 9;
void setup() 
{
    tonePin.begin(speaker);
    tonePin.play(NOTE_A4);
    delay(1000);
    tonePin.stop();
}
void loop() {}
1 Like

That is okay. But, you should start with programs that you can make work, or learn how to make work. Next program, do it all yourself and you will be more satisfied with the results.

But for now... I have found the problem with the "tone/timer" errors (shown above). I am adding that to the current code to stop the errors while compiling. Somewhere, a relay is being called, but I have not seen that pin show in the code. Anyway... I will be working on this today... maybe I can get it done in a few days.

1 Like

Ahahaha.... secrets! : ) Now I can see I will need to clean up the code more because I have been using some of the wrong pins... more homework for me. : ) That's okay.

Do me/you/everyone a favor: Download EasyEDA.com and learn how to make it work (and ask questions for help on this forum). It will make you a superstar here, your projects will be of professional quality, and your coding will be much easier.

See you in a day or two...

I will give that a go. Thanks for the resource.
I can program websites and HTML easily, but this is a bit beyond me. While I can make it work to the best of my ability. I know it is a mess.
I will register and try that site after the kids are in bed. Thank you again!!

Thank you very much, sir!!

Hey. You changed the sketch in the original post#1.

  1. Cool - the new code compiles after a few changes to array declarations (with two exceptions)
  2. Not cool - The old code was labor intensive... and the code you supplied was incomplete.

What needs to be done (with #1 above, and code below): Find these two functions (sabotage(); and domination(); they are probably complete sketches in external files) and add them to the following sketch. For error-free compiling, I have added two "place-holder" functions for sabotage() and domination().

// https://forum.arduino.cc/t/code-help-for-bomb-game/1162639

#include <Wire.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
// #include <LiquidCrystal.h>

/*
 Arduino Bomb Pro
 
 The circuit:
 * More info at : http://airsoft-online-japan.com/
 If you need some help mail me to airsoftonlinejapan@gmail.com
 
 created 25,Aug, 2023
 Modified 26, AUG 2023
 by Ben (Airsoft Online Japan)
 
 */

// LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // SPI connection
// LiquidCrystal_I2C lcd(0x38,16,2); // old I2C
#define I2C_ADDR    0x27 // new address... 0x38 does not work
#define LCD_COLUMNS 16
#define LCD_LINES   2
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);

const byte ROWS = 4;  //four rows
const byte COLS = 4;  //three columns
char keys[ROWS][COLS] = {
  { '1', '2', '3', 'a' },
  { '4', '5', '6', 'b' },
  { '7', '8', '9', 'c' },
  { '*', '0', '#', 'd' }
};

byte rowPins[ROWS] = {
  // 12, 13, A5, A4 // old pins
  12, 11, 10, 9 // new pins
};  //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  // A3, A2, A1, A0 // old pins
  8, 7, 6, 5 // new pins
};  //connect to the column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

char codeInput[8];
byte time[4];
boolean refresh = true;  //1 refresh one time...
char password[8];
int key = -1;
char lastKey;
char var;
boolean passwordEnable = false;

//Buttons for lcd shield
char BT_RIGHT = '4';
char BT_UP = 'a';
char BT_DOWN = 'b';
char BT_LEFT = '6';
char BT_SEL = 'd';  // Ok key
char BT_CANCEL = 'c';
char BT_DEFUSER = 'x';  // not implemented

//leds
const int REDLED = 11;
const int GREENLED = 10;
const int BLUELED = 14;

//RELAYPIN
boolean relayEnable = false;
const int RELAYPIN = 13;

//IS VERY IMPORTANT THAT YOU TEST THIS TIME. BY DEFAULT IS IN 1 SEC. THAT IS NOT TOO MUCH. SO TEST IT!

const int RELAY_TIME = 5000;

//TIME INTS
int GAMEHOURS = 0;
int GAMEMINUTES = 45;
int BOMBMINUTES = 4;
int ACTIVATESECONDS = 5;

boolean endGame = false;

boolean sdStatus = false;  //Search and Destroy game enable used in config
boolean saStatus = false;  //same but Sabotage
boolean doStatus = false;  //for Demolition
boolean start = true;
boolean defusing;
boolean cancelando;
// SOUND TONES
boolean soundEnable = true;
int tonepin = 8;  // Pin 13 for the sound
int alarmTone1 = 700;
int alarmTone2 = 2600;
int activeTone = 1330;
int errorTone = 100;

unsigned long iTime;
unsigned long timeCalcVar;
unsigned long redTime;
unsigned long yellowTime;
unsigned long iZoneTime;  //initial time for zone
byte team = 0;            // 0 = neutral, 1 = yellow team, 2 = red team

void setup() {
  // lcd.begin(16, 2); // SPI
  lcd.init();
  lcd.backlight();

  Serial.begin(9600);

  welcomeLCD();
  welcomeSerial();

  //PinModes
  pinMode(GREENLED, OUTPUT);
  pinMode(REDLED, OUTPUT);
  pinMode(RELAYPIN, OUTPUT);
  // CONFIGURE THE BARS OF PROGRESS BAR
  byte bar1[8] = {
    B10000,
    B10000,
    B10000,
    B10000,
    B10000,
    B10000,
    B10000,
    B10000,
  };
  byte bar2[8] = {
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
  };
  byte bar3[8] = {
    B11100,
    B11100,
    B11100,
    B11100,
    B11100,
    B11100,
    B11100,
    B11100,
  };
  byte bar4[8] = {
    B11110,
    B11110,
    B11110,
    B11110,
    B11110,
    B11110,
    B11110,
    B11110,
  };
  byte bar5[8] = {
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
  };
  byte up[8] = {
    B00000,
    B00100,
    B01110,
    B11111,
    B11111,
    B00000,
    B00000,
  };

  byte down[8] = {
    B00000,
    B00000,
    B11111,
    B11111,
    B01110,
    B00100,
    B00000,
  };
  lcd.createChar(0, bar1);
  lcd.createChar(1, bar2);
  lcd.createChar(2, bar3);
  lcd.createChar(3, bar4);
  lcd.createChar(4, bar5);
  lcd.createChar(5, up);
  lcd.createChar(6, down);
}

void loop() {
  menuPrincipal();
}
void keypadEvent(KeypadEvent key) {
  switch (keypad.getState()) {
    case RELEASED:
      switch (key) {
        case 'd':
          defusing = false;
          break;
        case 'c':
          cancelando = false;
          break;
      }
      break;
    case HOLD:
      switch (key) {
        case 'd':
          defusing = true;
          break;
        case 'c':
          cancelando = true;
          break;
      }
      break;
  }
}

//This fuction compare codeInput[8] and password[8] variables
boolean comparePassword() {

  for (int i = 0; i < 8; i++) {
    if (codeInput[i] != password[i]) return false;
  }
  return true;
}

//Set the password variable
void setCode() {

  lcd.setCursor(0, 1);
  for (int i = 0; i < 8; i++) {
    while (1) {
      var = getNumber();
      if (var != 'x') {
        codeInput[i] = var;

        if (i != 0) {
          lcd.setCursor(i - 1, 1);
          lcd.print("*");
          lcd.print(var);
        } else {
          lcd.print(var);
        }
        tone(tonepin, 2400, 30);
        break;
      }
    }
  }
}
void setCodeTime() {

  timeCalcVar = millis();

  for (int i = 0; i < 8; i++) {
    while (1) {
      if (ACTIVATESECONDS * 1000 + timeCalcVar - millis() <= 100) {
        codeInput[i] = 'x';
        break;
      }

      lcd.setCursor(11, 0);
      printTimeDom(ACTIVATESECONDS * 1000 + timeCalcVar - millis(), false);

      var = getNumber();
      if (var != 'x') {
        codeInput[i] = var;

        if (i != 0) {
          lcd.setCursor(i - 1, 1);
          lcd.print("*");
          lcd.print(var);
        } else {
          lcd.print(var);
        }
        tone(tonepin, 2400, 30);
        break;
      }
    }
  }
}
void setPass() {
  lcd.setCursor(0, 1);

  for (int i = 0; i < 8; i++) {
    while (1) {
      var = getNumber();
      if (var != 'x') {
        password[i] = var;
        if (i != 0) {
          lcd.setCursor(i - 1, 1);
          lcd.print("*");
          lcd.print(var);
        } else {
          lcd.print(var);
        }
        tone(tonepin, 2400, 30);
        break;
      }
    }
  }
}

void setNewPass() {

  while (1) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Enter New Pass");
    setPass();

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Retype Pass");

    setCode();

    if (comparePassword()) {

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Password Set OK!");
      delay(2000);
      break;
    } else {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("ERROR Dont Match!");
      if (soundEnable) tone(tonepin, errorTone, 200);
      delay(2000);
    }
  }
}
//Whait until a button is pressed is is a number return the number 'char' if not return x



char getNumber() {
  while (1) {
    var = keypad.getKey();
    if (var) {  //
      switch (var) {
        case 'a':
          return 'x';
          break;
        case 'b':
          return 'x';
          break;

        case 'c':
          return 'x';
          break;
        case 'd':
          return 'x';
          break;
        case '*':
          return 'x';
          break;
        case '#':
          return 'x';
          break;
        default:
          return var;
          break;
      }
    }
    return 'x';
  }
}

byte getRealNumber() {

  while (1) {
    var = keypad.waitForKey();

    if (var) {  //
      switch (var) {
        case '1':
          return 1;
          break;
        case '2':
          return 2;
          break;

        case '3':
          return 3;
          break;
        case '4':
          return 4;
          break;
        case '5':
          return 5;
          break;
        case '6':
          return 6;
        case '7':
          return 7;
          break;
        case '8':
          return 8;
          break;
        case '9':
          return 9;
          break;
        case '0':
          return 0;
          break;

        default:
          return 11;
          break;
      }
    }
    return 11;
  }
}


char menu1[][15] = { "Search&Destroy", "Sabotage", "Domination", "Configuration" };
char menu2[][13] = { "Game Config", "Sound Config", "Relay Test", "Auto Test" };
// char *menu1[][] = { "Search&Destroy", "Sabotage", "Domination", "Configuration" };
// char *menu2[][] = { "Game Config", "Sound Config", "Relay Test", "Auto Test" };
char GAME_TIME[] = "Game Time:";
char BOMB_TIME[] = "Bomb Time:";
char ZERO_MINUTES[] = "00 minutes";
char ARM_TIME[] = "Arm Time:";
char ZERO_SECS[] = "00 seconds";
char ENABLE_SOUND[] = "Enable Sound?";
char YES_OR_NO[] = "A : Yes B : No";
char ENABLE_RELAYPIN[] = "Enable Relay?";
char ENABLE_CODE[] = "Enable Code Arm?";
char GAME_TIME_TOP[] = "GAME TIME";
char ARMING_BOMB[] = "ARMING BOMB";
char ENTER_CODE[] = "Enter Code";
char CODE_ERROR[] = "Code Error!";
char BOMB_ARMED[] = "BOMB ARMED";
char DETONATION_IN[] = "DETONATION IN";
char DISARMING[] = "DISARMING BOMB";
char DISARM[] = "DISARMING";
char GAME_OVER[] = " GAME OVER! ";
char DEFENDERS_WIN[] = " DEFENDERS WIN ";
char SABOTAGE_FAIL[] = "SABOTAGE FAIL!";

//void getConfig(){
//
////Check first time
//
//if (EEPROM.read(0)!= 1){
////write default config values
//
//
//
//}
//
////RELAY_TIME = EEPROM.read(1) * 1000 ;
//
//
//}
//##################MENUS###############################

void menuPrincipal() {  //MAIN MENU

  digitalWrite(GREENLED, LOW);
  digitalWrite(REDLED, LOW);

  //   if we start a new game from another we need to restart propertly this variables
  saStatus = false;
  sdStatus = false;
  doStatus = false;
  //Draw menu
  lcd.clear();  //clear lcd and set cursor to 0,0
  int i = 0;
  // HERE YOU CAN ADD MORE ITEMS ON THE MAIN MENU
  lcd.print(menu1[i]);
  lcd.setCursor(15, 1);
  checkArrows(i, 2);
  while (1) {

    var = keypad.waitForKey();
    if (var == BT_UP && i > 0) {
      tone(tonepin, 2400, 30);
      i--;
      lcd.clear();
      lcd.print(menu1[i]);
      checkArrows(i, 2);
      delay(50);
    }
    if (var == BT_DOWN && i < 2) {
      tone(tonepin, 2400, 30);
      i++;
      lcd.clear();
      lcd.print(menu1[i]);
      checkArrows(i, 2);
      delay(50);
    }

    if (var == BT_SEL) {
      tone(tonepin, 2400, 30);
      lcd.clear();
      switch (i) {

        case 0:
          sdStatus = true;
          configQuickGame();
          startGameCount();
          search();
          break;
        case 1:
          saStatus = true;
          configQuickGame();
          startGameCount();
          sabotage();
          break;
        case 2:

          doStatus = true;
          configQuickGame();
          startGameCount();
          domination();
          break;
        case 3:
          config();
          break;
      }
    }
  }
}

void config() {
  //Draw menu
  lcd.clear();
  lcd.setCursor(0, 0);
  int i = 0;

  delay(500);
  lcd.print(menu2[i]);
  checkArrows(i, 3);

  while (1) {
    var = keypad.waitForKey();
    if (var == BT_UP && i > 0) {
      tone(tonepin, 2400, 30);
      i--;
      lcd.clear();
      lcd.print(menu2[i]);
      checkArrows(i, 3);
      delay(50);
    }
    if (var == BT_DOWN && i < 3) {
      tone(tonepin, 2400, 30);
      i++;
      lcd.clear();
      lcd.print(menu2[i]);
      checkArrows(i, 3);
      delay(50);
    }
    if (var == BT_CANCEL) {
      tone(tonepin, 2400, 30);
      menuPrincipal();
    }
    if (var == BT_SEL) {
      tone(tonepin, 2400, 30);
      lcd.clear();
      switch (i) {

        case 0:
          //gameConfigMenu();
          break;

        case 1:
          //soundConfigMenu();
          break;

        case 2:
          lcd.clear();
          lcd.print("RELAYPIN ON!");
          digitalWrite(RELAYPIN, HIGH);  // turn the LED on (HIGH is the voltage level)
          delay(4000);                   // wait for 4 second
          lcd.clear();
          lcd.print("RELAYPIN OFF!");
          digitalWrite(RELAYPIN, LOW);
          delay(2000);
          config();
          break;
      }
    }
  }
}

void configQuickGame() {

  lcd.clear();
  //GAME TIME
  if (sdStatus || doStatus || saStatus) {
menu1:
    lcd.clear();
    lcd.print(GAME_TIME);
    delay(100);
    lcd.setCursor(0, 1);
    lcd.print("00:00 hh:mm");
    lcd.cursor();
    lcd.blink();
    lcd.setCursor(0, 1);
    byte var2 = 0;
    for (int i = 0; i < 4; i++) {
      while (1) {
        if (i == 2 && var2 == 0) {
          lcd.print(":");
          var2 = 1;
        }

        byte varu = getRealNumber();
        if (varu != 11) {

          time[i] = varu;
          Serial.print(varu);


          lcd.print(varu);
          tone(tonepin, 2400, 30);

          break;
        }
      }
    }
    lcd.noCursor();
    lcd.noBlink();
    lcd.setCursor(13, 1);
    lcd.print("ok?");
    //zona donde pasamos los items a
    //redibujar
    while (1) {
      var = keypad.waitForKey();
      if (var == 'd')  // Accept
      {
        tone(tonepin, 2400, 30);
        GAMEMINUTES = ((time[0] * 600) + (time[1] * 60) + (time[2] * 10) + (time[3]));
        break;
      }
      if (var == 'c')  // Cancel or Back Button :')
      {
        tone(tonepin, 2400, 30);
        goto menu1;
      }
    }
    tone(tonepin, 2400, 30);
    lcd.clear();
  }
  //BOMB TIME
  if (sdStatus || saStatus) {

menu2:
    lcd.clear();
    lcd.print(BOMB_TIME);
    delay(100);
    lcd.setCursor(0, 1);
    lcd.print(ZERO_MINUTES);
    lcd.cursor();
    lcd.blink();
    lcd.setCursor(0, 1);
    for (int i = 0; i < 2; i++) {
      while (1) {
        byte varu = getRealNumber();
        if (varu != 11) {
          time[i] = varu;
          lcd.print(varu);
          tone(tonepin, 2400, 30);
          break;
        }
      }
    }
    lcd.noCursor();
    lcd.noBlink();
    lcd.setCursor(13, 1);
    lcd.print("ok?");
    //zona donde pasamos los items a
    //redibujar
    while (1) {
      var = keypad.waitForKey();
      if (var == 'd')  //
      {
        tone(tonepin, 2400, 30);
        BOMBMINUTES = ((time[0] * 10) + (time[1]));
        break;
      }
      if (var == 'c')  // Cancel or Back Button :')
      {
        tone(tonepin, 2400, 30);
        goto menu2;
      }
    }
    tone(tonepin, 2400, 30);
    lcd.clear();
  }
  lcd.clear();
  //ARMING TIME
  if (sdStatus || doStatus || saStatus) {

menu3:
    lcd.clear();
    lcd.print(ARM_TIME);
    delay(100);
    lcd.setCursor(0, 1);
    lcd.print(ZERO_SECS);
    lcd.cursor();
    lcd.blink();
    lcd.setCursor(0, 1);
    for (int i = 0; i < 2; i++) {
      while (1) {
        byte varu = getRealNumber();
        if (varu != 11) {
          time[i] = varu;
          lcd.print(varu);
          tone(tonepin, 2400, 30);
          break;
        }
      }
    }
    lcd.noCursor();
    lcd.noBlink();
    lcd.setCursor(13, 1);
    lcd.print("ok?");

    //zona donde pasamos los items a
    //redibujar
    while (1) {
      var = keypad.waitForKey();
      if (var == 'd')  // Accept
      {
        tone(tonepin, 2400, 30);
        ACTIVATESECONDS = ((time[0] * 10) + (time[1]));
        break;
      }
      if (var == 'c')  // Cancel or Back Button :')
      {
        tone(tonepin, 2400, 30);
        goto menu3;
      }
    }
    tone(tonepin, 2400, 30);
    lcd.clear();
  }
  //sound??
  if (sdStatus || saStatus || doStatus) {
    lcd.clear();
    lcd.print(ENABLE_SOUND);
    lcd.setCursor(0, 1);
    lcd.print(YES_OR_NO);

    while (1) {
      var = keypad.waitForKey();
      if (var == 'a') {
        soundEnable = true;
        tone(tonepin, 2400, 30);
        break;
      }

      if (var == 'b') {
        soundEnable = false;
        tone(tonepin, 2400, 30);
        break;
      }
    }
  }
  //Activate RELAY at Terrorist game ends??? Boom!

  if (sdStatus || saStatus) {
    lcd.clear();
    lcd.print(ENABLE_RELAYPIN);
    lcd.setCursor(0, 1);
    lcd.print(YES_OR_NO);
    while (1) {
      var = keypad.waitForKey();
      if (var == 'a') {
        relayEnable = true;
        tone(tonepin, 2400, 30);
        break;
      }
      if (var == 'b') {
        relayEnable = false;
        tone(tonepin, 2400, 30);
        break;
      }
    }
  }
  //You Want a password enable-disable game?
  if (sdStatus || saStatus) {
    lcd.clear();
    lcd.print(ENABLE_CODE);
    lcd.setCursor(0, 1);
    lcd.print(YES_OR_NO);

    while (1) {
      var = keypad.waitForKey();
      if (var == 'a') {
        tone(tonepin, 2400, 30);
        setNewPass();
        passwordEnable = true;
        break;
      }
      if (var == 'b') {
        tone(tonepin, 2400, 30);
        passwordEnable = false;
        break;
      }
    }
    tone(tonepin, 2400, 30);
  }
  //Continue the game :D
}



void search() {
  refresh = true;
  lcd.clear();
  digitalWrite(REDLED, LOW);
  digitalWrite(GREENLED, LOW);
  //SETUP INITIAL TIME
  int minutos = GAMEMINUTES - 1;
  unsigned long iTime = millis();  //  initialTime in millisec
  unsigned long aTime;
  //var='o';

  //Starting Game Code
  while (1) {  // this is the important code, is a little messy but works good.

    //If you fail disarm.
    if (endGame) {
      failSplash();
    }

    //Code for led blinking
    timeCalcVar = (millis() - iTime) % 1000;
    if (timeCalcVar >= 0 && timeCalcVar <= 50) digitalWrite(GREENLED, HIGH);
    if (timeCalcVar >= 90 && timeCalcVar <= 130) digitalWrite(GREENLED, LOW);

    lcd.setCursor(3, 0);
    lcd.print(GAME_TIME_TOP);
    aTime = millis() - iTime;
    lcd.setCursor(3, 1);

    //PRINT TIME ON LCD

    printTime(minutos, aTime);

    //###########################CHECKINGS##################

    //Check If Game End
    if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) failSplash();
    //Serial.println(keypad.getKey());
    //USED IN PASSWORD GAME
    if ('d' == keypad.getKey() && passwordEnable) {
      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print(ARMING_BOMB);
      delay(1000);  //a little delay to choose the password
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(ENTER_CODE);

      setCodeTime();  // we need to set the comparation variable first it writes on codeInput[]

      //then compare :D

      if (comparePassword()) destroy();
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print(CODE_ERROR);
      if (soundEnable) tone(tonepin, errorTone, 200);
      delay(500);
      lcd.clear();
    }
    //Check If Is Activating
    while (defusing && !passwordEnable) {
      digitalWrite(GREENLED, LOW);
      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print(ARMING_BOMB);
      lcd.setCursor(0, 1);
      unsigned int percent = 0;
      unsigned long xTime = millis();  //start disabling time
      while (defusing) {
        keypad.getKey();
        percent = (millis() - xTime) / (ACTIVATESECONDS * 10);

        drawBar(percent);
        //check if game time runs out during the disabling
        aTime = millis() - iTime;
        Serial.println(millis() - xTime);
        if ((minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) || minutos - aTime / 60000 > 4000000000) {
          endGame = true;
        }
        timeCalcVar = (millis() - xTime) % 1000;

        if (timeCalcVar >= 0 && timeCalcVar <= 40) {
          digitalWrite(REDLED, HIGH);
          if (soundEnable) tone(tonepin, alarmTone1, 200);
        }
        if (timeCalcVar >= 480 && timeCalcVar <= 520) {
          if (soundEnable) tone(tonepin, alarmTone2, 200);
          digitalWrite(REDLED, LOW);
        }



        if (percent >= 100) {
          digitalWrite(GREENLED, LOW);
          destroy();  // jump to the next gamemode
        }
      }
      lcd.clear();
      digitalWrite(REDLED, LOW);
    }
  }
}

void destroy() {
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print(BOMB_ARMED);
  delay(1000);
  int minutos = BOMBMINUTES - 1;
  unsigned long iTime = millis();
  unsigned long aTime;
  int largoTono = 50;

  //MAIN LOOP
  while (1) {

    //If you fail disarm.
    if (endGame) {
      explodeSplash();
    }

    //Led Blink

    timeCalcVar = (millis() - iTime) % 1000;
    if (timeCalcVar >= 0 && timeCalcVar <= 40) {
      digitalWrite(REDLED, HIGH);
      if (soundEnable) tone(tonepin, activeTone, largoTono);
    }
    if (timeCalcVar >= 180 && timeCalcVar <= 220) {
      digitalWrite(REDLED, LOW);
    }
    //Sound
    aTime = millis() - iTime;
    timeCalcVar = (millis() - iTime) % 1000;
    if (timeCalcVar >= 245 && timeCalcVar <= 255 && minutos - aTime / 60000 < 2 && soundEnable) tone(tonepin, activeTone, largoTono);
    if (timeCalcVar >= 495 && timeCalcVar <= 510 && minutos - aTime / 60000 < 4 && soundEnable) tone(tonepin, activeTone, largoTono);
    if (timeCalcVar >= 745 && timeCalcVar <= 760 && minutos - aTime / 60000 < 2 && soundEnable) tone(tonepin, activeTone, largoTono);
    if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) < 10) largoTono = 300;

    lcd.setCursor(1, 0);
    lcd.print(DETONATION_IN);
    //Passed Time

    lcd.setCursor(3, 1);

    ////////HERE ARE THE TWO OPTIONS THAT ENDS THE GAME///////////

    ////TIME PASED AWAY AND THE BOMB EXPLODES
    if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0)  // Check if game ends
    {
      explodeSplash();
    }
    //print time

    printTime(minutos, aTime);

    //// SECOND OPTION: YOU PRESS DISARMING BUTTON

    //IF IS A PASSWORD GAME

    if ('d' == keypad.getKey() && passwordEnable) {

      lcd.clear();
      lcd.setCursor(1, 0);
      lcd.print(DISARMING);
      delay(1000);  //a little delay to think in the password

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(ENTER_CODE);

      setCodeTime();  // we need to set the compare variable first

      //then compare :D

      if (comparePassword()) {
        disarmedSplash();
      }
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print(CODE_ERROR);
      if (soundEnable) tone(tonepin, errorTone, 200);
      delay(500);
      lcd.clear();
    }

    if (defusing && !passwordEnable)  // disarming bomb
    {
      lcd.clear();
      digitalWrite(REDLED, LOW);
      lcd.setCursor(3, 0);
      lcd.print(DISARM);
      lcd.setCursor(0, 1);
      unsigned int percent = 0;
      unsigned long xTime = millis();
      while (defusing) {
        keypad.getKey();
        //check if game time runs out during the disabling
        aTime = millis() - iTime;
        if ((minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) || minutos - aTime / 60000 > 4000000000) {
          endGame = true;
        }
        timeCalcVar = (millis() - xTime) % 1000;
        if (timeCalcVar >= 0 && timeCalcVar <= 20) {
          digitalWrite(GREENLED, HIGH);
          if (soundEnable) tone(tonepin, alarmTone1, 200);
        }
        if (timeCalcVar >= 480 && timeCalcVar <= 500) {
          if (soundEnable) tone(tonepin, alarmTone2, 200);
          digitalWrite(GREENLED, LOW);
        }
        unsigned long seconds = (millis() - xTime);
        percent = seconds / (ACTIVATESECONDS * 10);
        drawBar(percent);

        //BOMB DISARMED GAME OVER
        if (percent >= 100) disarmedSplash();
      }
      digitalWrite(REDLED, LOW);
      digitalWrite(GREENLED, LOW);
      lcd.clear();
    }
  }
}



void explodeSplash() {
  digitalWrite(REDLED, LOW);
  digitalWrite(GREENLED, LOW);
  lcd.clear();
  delay(100);
  endGame = false;
  lcd.setCursor(1, 0);
  lcd.print("TERRORISTS WIN");
  lcd.setCursor(4, 1);
  lcd.print("GAME OVER");
  for (int i = 200; i > 0; i--)  // this is the ultra hi definition explosion sound xD
  {
    tone(tonepin, i);
    delay(20);
  }
  noTone(tonepin);
  if (relayEnable) {
    activateRelay();
  }
  delay(5000);
  lcd.clear();

  //end code
  lcd.print("Play Again?");
  lcd.setCursor(0, 1);
  lcd.print("A : Yes B : No");
  while (1) {
    var = keypad.waitForKey();
    if (var == 'a') {
      tone(tonepin, 2400, 30);
      //We have two options, search & destroy and sabotage play again options so!
      if (sdStatus) {
        startGameCount();
        search();
      }
      if (saStatus) {
        saStatus = true;
        startGameCount();
        start = true;  //to set iTime to actual millis() :D
        sabotage();
      }
    }
    if (var == 'b') {
      tone(tonepin, 2400, 30);
      menuPrincipal();

      break;
    }
  }
}
void failSplash() {
  digitalWrite(REDLED, LOW);
  digitalWrite(GREENLED, LOW);
  lcd.clear();
  delay(100);
  endGame = false;
  lcd.setCursor(1, 0);
  lcd.print("TIME OUT");
  lcd.setCursor(4, 1);
  lcd.print("GAME OVER");
  for (int i = 200; i > 0; i--)  // this is the ultra hi definition explosion sound xD
  {
    tone(tonepin, i);
    delay(20);
  }
  noTone(tonepin);
  if (relayEnable) {
    activateRelay();
  }
  delay(5000);
  lcd.clear();

  //end code
  lcd.print("Play Again?");
  lcd.setCursor(0, 1);
  lcd.print("A : Yes B : No");
  while (1) {
    var = keypad.waitForKey();
    if (var == 'a') {
      tone(tonepin, 2400, 30);
      //We have two options, search & destroy and sabotaje play again options so!
      if (sdStatus) {
        startGameCount();
        search();
      }
      if (saStatus) {
        saStatus = true;
        startGameCount();
        start = true;  //to set iTime to actual millis() :D
        sabotage();
      }
    }
    if (var == 'b') {
      tone(tonepin, 2400, 30);
      menuPrincipal();

      break;
    }
  }
}
void disarmedSplash() {
  endGame = false;
  digitalWrite(REDLED, LOW);
  digitalWrite(GREENLED, LOW);
  if (sdStatus || saStatus) {
    lcd.clear();
    lcd.setCursor(2, 0);
    lcd.print("BOMB DISARMED");
    lcd.setCursor(3, 1);
    lcd.print("MILITARY WINS");
    digitalWrite(GREENLED, HIGH);
    delay(5000);
    digitalWrite(GREENLED, LOW);
  }
  //end code
  lcd.clear();
  lcd.print("Play Again?");
  lcd.setCursor(0, 1);
  lcd.print("A : Yes B : No");
  digitalWrite(REDLED, LOW);
  digitalWrite(GREENLED, LOW);
  while (1) {
    var = keypad.waitForKey();
    if (var == 'a') {
      tone(tonepin, 2400, 30);
      //We have two options, search & destroy and sabotaje play again options so!
      if (sdStatus) {
        startGameCount();
        search();
      }
      if (saStatus) {
        saStatus = true;
        startGameCount();
        start = true;  //to set iTime to actual millis() :D
        sabotage();
      }
    }
    if (var == 'b') {
      tone(tonepin, 2400, 30);
      menuPrincipal();
      break;
    }
  }
}
void drawBar(byte porcent) {
  //TODO: Optimize this code
  int box = (8 * porcent) / 10;
  lcd.setCursor(0, 1);
  while (box >= 5) {
    if (box >= 5) {
      lcd.write(4);
      box -= 5;
    }
  }
  switch (box) {
    case 0:
      break;
    case 1:
      lcd.write((uint8_t)0);
      break;
    case 2:
      lcd.write(1);
      break;
    case 3:
      lcd.write(2);
      break;
    case 4:
      lcd.write(3);
      break;
  }
}
void cls() {
  lcd.clear();
  lcd.setCursor(0, 0);
}

void printTime(unsigned long minutos, unsigned long aTiempo) {

  timeCalcVar = minutos - aTiempo / 60000;
  //Hours

  if (timeCalcVar / 60 == 0 && refresh) {
    lcd.clear();
    refresh = false;
    //delay(100);
    lcd.setCursor(3, 1);
    Serial.println("!!!!");
  }

  if (timeCalcVar / 60 >= 1) {

    if (timeCalcVar / 60 < 10) {
      lcd.setCursor(2, 1);
      lcd.print("0");
      lcd.print(timeCalcVar / 60);
    } else {
      lcd.print(timeCalcVar / 60);
    }

    lcd.print(":");
  }
  //minutes
  if (timeCalcVar % 60 < 10) {
    lcd.print("0");
    lcd.print(timeCalcVar % 60);
  } else {
    lcd.print(timeCalcVar % 60);
  }
  lcd.print(":");
  //seconds
  timeCalcVar = aTiempo / 1000;
  if (59 - (timeCalcVar % 60) < 10) {
    lcd.print("0");
    lcd.print(59 - (timeCalcVar % 60));
  } else {
    lcd.print(59 - (timeCalcVar % 60));
  }
  lcd.print(":");
  //this not mach with real time, is just a effect, it says 999 because millis%1000 sometimes give 0 LOL
  lcd.print(999 - (millis() % 1000));
}

void printTimeDom(unsigned long aTiempo, boolean showMillis) {
  //minutes
  if ((aTiempo / 60000) < 10) {
    lcd.print("0");
    lcd.print(aTiempo / 60000);
  } else {
    lcd.print(aTiempo / 60000);
  }
  lcd.print(":");
  //seconds
  if (((aTiempo / 1000) % 60) < 10) {
    lcd.print("0");
    lcd.print((aTiempo / 1000) % 60);
  } else {
    lcd.print((aTiempo / 1000) % 60);
  }
  if (showMillis) {
    lcd.print(":");
    //this not mach with real time, is just a effect, it says 999 because millis%1000 sometimes give 0 LOL
    lcd.print(999 - millis() % 1000);
  }
}

void startGameCount() {
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Ready to Begin");
  lcd.setCursor(0, 1);
  lcd.print("Push ANY Button");
  keypad.waitForKey();  //if you press a button game start

  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Starting Game");
  for (int i = 5; i > 0; i--) {  // START COUNT GAME INIT
    lcd.setCursor(5, 1);
    tone(tonepin, 2000, 100);
    lcd.print("IN ");
    lcd.print(i);
    delay(1000);
  }
  lcd.clear();
}

void checkArrows(byte i, byte maxx) {

  if (i == 0) {
    lcd.setCursor(15, 1);
    lcd.write(6);
  }
  if (i == maxx) {
    lcd.setCursor(15, 0);
    lcd.write(5);
  }
  if (i > 0 && i < maxx) {
    lcd.setCursor(15, 1);
    lcd.write(6);
    lcd.setCursor(15, 0);
    lcd.write(5);
  }
}

void activateRelay() {
  digitalWrite(RELAYPIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(RELAY_TIME);
  digitalWrite(RELAYPIN, LOW);
}

void sabotage() {  // search and destroy function is search();
  // function unknown - placed here for compiling
  lcd.clear();
  lcd.print("Sabotage");
}

void domination() {  // search and destroy function is search();
  // function unknown - placed here for compiling
  lcd.clear();
  lcd.print("Domination");
}

void welcomeSerial() {
  Serial.println("RIGHT  = 4");
  Serial.println("UP     = A");
  Serial.println("DOWN   = B");
  Serial.println("LEFT   = 6");
  Serial.println("SELECT = D"); // OK key
  Serial.println("CANCEL = C");
  Serial.println("DEFUSE = X"); // not implemented
}

void welcomeLCD() {
  lcd.setCursor(3, 0);
  tone(tonepin, 2400, 30);
  lcd.print("AIRSOFT ONLINE JP");  // you can add your team name or someting cool
  lcd.setCursor(0, 1);
  lcd.print(" AIRSOFT BOMB");  // you can add your team name or someting cool
  keypad.setHoldTime(50);
  keypad.setDebounceTime(50);
  keypad.addEventListener(keypadEvent);
}

Here is the new code in the old simulation. The devices and pins need to be changed to reflect the new code.fixed the pin definitions

diagram.json for wokwi.com

{
  "version": 1,
  "author": "Anonymous maker",
  "editor": "wokwi",
  "parts": [
    { "type": "wokwi-arduino-nano", "id": "nano", "top": 4.8, "left": -0.5, "attrs": {} },
    {
      "type": "wokwi-led",
      "id": "led1",
      "top": -166.8,
      "left": -130.6,
      "attrs": { "color": "red" }
    },
    {
      "type": "wokwi-led",
      "id": "led2",
      "top": -166.8,
      "left": -111.4,
      "attrs": { "color": "green" }
    },
    {
      "type": "wokwi-lcd1602",
      "id": "lcd1",
      "top": -166.4,
      "left": -13.6,
      "attrs": { "pins": "i2c" }
    },
    {
      "type": "wokwi-buzzer",
      "id": "bz1",
      "top": 0,
      "left": 211.2,
      "rotate": 180,
      "attrs": { "volume": "0.1" }
    },
    { "type": "wokwi-membrane-keypad", "id": "keypad1", "top": -530, "left": -42.4, "attrs": {} },
    {
      "type": "wokwi-relay-module",
      "id": "relay1",
      "top": -121.8,
      "left": 262.8,
      "rotate": 270,
      "attrs": {}
    },
    {
      "type": "wokwi-led",
      "id": "led3",
      "top": -166.8,
      "left": -149.8,
      "attrs": { "color": "red" }
    },
    {
      "type": "wokwi-led",
      "id": "led4",
      "top": -166.8,
      "left": -169,
      "attrs": { "color": "blue" }
    }
  ],
  "connections": [
    [ "led2:A", "nano:3", "green", [ "v105.6", "h192" ] ],
    [ "led1:A", "nano:2", "green", [ "v105.6", "h220.8" ] ],
    [ "lcd1:SCL", "nano:A5", "green", [ "h-13.8", "v192.3", "h119.4" ] ],
    [ "lcd1:SDA", "nano:A4", "green", [ "h-23.14", "v201.8", "h119.14" ] ],
    [ "lcd1:VCC", "nano:5V", "red", [ "h-30.47", "v230.5", "h164.87" ] ],
    [ "lcd1:GND", "nano:GND.1", "black", [ "h-40.47", "v249.6", "h194.07" ] ],
    [ "bz1:2", "nano:4", "green", [ "v-6.38", "h-129.67" ] ],
    [ "nano:12", "keypad1:R1", "green", [ "v-11.74", "h-82.46", "v-180.88", "h119.37" ] ],
    [ "nano:11", "keypad1:R2", "green", [ "v-11.74", "h-92.11", "v-180.88", "h129.42" ] ],
    [ "nano:10", "keypad1:R3", "green", [ "v-11.74", "h-101.56", "v-180.32", "h138.77" ] ],
    [ "nano:9", "keypad1:R4", "green", [ "v-12.42", "h-111.23", "v-180.19", "h148.34" ] ],
    [ "nano:8", "keypad1:C1", "green", [ "v-12.29", "h-120.72", "v-180.02", "h157.73" ] ],
    [ "nano:7", "keypad1:C2", "green", [ "v-12.12", "h-130.36", "v-180.49", "h167.27" ] ],
    [ "nano:6", "keypad1:C3", "green", [ "v-12.29", "h-139.99", "v-180.32", "h177.05" ] ],
    [ "nano:5", "keypad1:C4", "green", [ "v-12.29", "h-149.49", "v-180.02", "h186.7" ] ],
    [ "nano:GND.2", "bz1:1", "black", [ "v0" ] ],
    [ "nano:GND.1", "led1:C", "black", [ "v48", "h-259.6" ] ],
    [ "nano:GND.1", "led2:C", "black", [ "v48", "h-240.4" ] ],
    [ "relay1:VCC", "nano:5V", "red", [ "v134.4", "h-192" ] ],
    [ "relay1:IN", "nano:13", "green", [ "v124.8", "h-317" ] ],
    [ "relay1:GND", "nano:GND.1", "black", [ "v144", "h-182.8" ] ],
    [ "led3:A", "nano:2", "green", [ "v105.6", "h240" ] ],
    [ "nano:GND.1", "led3:C", "black", [ "v48", "h-278.8" ] ],
    [ "led4:A", "nano:A0", "green", [ "v211.2", "h192" ] ],
    [ "nano:GND.1", "led4:C", "black", [ "v48", "h-298" ] ]
  ],
  "dependencies": {}
}

I doubt the two "functions" (full games inside functions) will fit in memory. Here is the compile report from these 1000+ lines of code:

Sketch uses 15590 bytes (50%) of program storage space. Maximum is 30720 bytes.
Global variables use 1392 bytes (67%) of dynamic memory, leaving 656 bytes for local variables. Maximum is 2048 bytes.
1 Like

Holy...... I am speechless!!

Thank you so, so much!! I really appreciate your efforts on this.

I will upload to my Arduino Uno and try it again tonight and let you know the result. But that simulation went perfectly. Thank you so so much

The code compiles... but the code is not complete... and it does not run smoothly as a command/response game. Maybe you can find those two functions mentioned in post #15 in the links you have in post #9? If you do find the functions, they can be written into the full code.

1 Like

I spent the last few hours of tinkering with it using your code modifications on the search and destroy game to compile the other two game modes.

After trial and error, I got them all working, so far flawlessly!!

// https://forum.arduino.cc/t/code-help-for-bomb-game/1162639

#include <Wire.h>
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
// #include <LiquidCrystal.h>

/*
 Arduino Bomb Pro
 
 The circuit:
 * More info at : http://airsoft-online-japan.com/
 If you need some help mail me to airsoftonlinejapan@gmail.com
 
 created 25,Aug, 2023
 Modified 26, AUG 2023
 by Ben (Airsoft Online Japan)
 
 */

// LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // SPI connection
// LiquidCrystal_I2C lcd(0x38,16,2); // old I2C
#define I2C_ADDR    0x27 // new address... 0x38 does not work
#define LCD_COLUMNS 16
#define LCD_LINES   2
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);

const byte ROWS = 4;  //four rows
const byte COLS = 4;  //three columns
char keys[ROWS][COLS] = {
  { '1', '2', '3', 'a' },
  { '4', '5', '6', 'b' },
  { '7', '8', '9', 'c' },
  { '*', '0', '#', 'd' }
};

byte rowPins[ROWS] = {
  // 12, 13, A5, A4
  12, 11, 10, 9
};  //connect to the row pinouts of the keypad
byte colPins[COLS] = {
  // A3, A2, A1, A0
  8, 7, 6, 5
};  //connect to the column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

char codeInput[8];
byte time[4];
boolean refresh = true;  //1 refresh one time...
char password[8];
int key = -1;
char lastKey;
char var;
boolean passwordEnable = false;

//Buttons for lcd shield
char BT_RIGHT = '4';
char BT_UP = 'a';
char BT_DOWN = 'b';
char BT_LEFT = '6';
char BT_SEL = 'd';  // Ok key
char BT_CANCEL = 'c';
char BT_DEFUSER = 'x';  // not implemented

//leds
const int REDLED = 11;
const int GREENLED = 10;
const int BLUELED = 14;

//RELAYPIN
boolean relayEnable = false;
const int RELAYPIN = 13;

//IS VERY IMPORTANT THAT YOU TEST THIS TIME. BY DEFAULT IS IN 1 SEC. THAT IS NOT TOO MUCH. SO TEST IT!

const int RELAY_TIME = 5000;

//TIME INTS
int GAMEHOURS = 0;
int GAMEMINUTES = 45;
int BOMBMINUTES = 4;
int ACTIVATESECONDS = 5;

boolean endGame = false;

boolean sdStatus = false;  //Search and Destroy game enable used in config
boolean saStatus = false;  //same but Sabotage
boolean doStatus = false;  //for Demolition
boolean start = true;
boolean defusing;
boolean cancel;
// SOUND TONES
boolean soundEnable = true;
int tonepin = 8;  // Pin 13 for the sound
int alarmTone1 = 700;
int alarmTone2 = 2600;
int activeTone = 1330;
int errorTone = 100;

unsigned long iTime;
unsigned long timeCalcVar;
unsigned long redTime;
unsigned long yellowTime;
unsigned long iZoneTime;  //initial time for zone
byte team = 0;            // 0 = neutral, 1 = yellow team, 2 = red team

void setup() {
  // lcd.begin(16, 2); // SPI
  lcd.init();
  lcd.backlight();

  Serial.begin(9600);

  welcomeLCD();
  welcomeSerial();

  //PinModes
  pinMode(GREENLED, OUTPUT);
  pinMode(REDLED, OUTPUT);
  pinMode(RELAYPIN, OUTPUT);
  // CONFIGURE THE BARS OF PROGRESS BAR
  byte bar1[8] = {
    B10000,
    B10000,
    B10000,
    B10000,
    B10000,
    B10000,
    B10000,
    B10000,
  };
  byte bar2[8] = {
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
    B11000,
  };
  byte bar3[8] = {
    B11100,
    B11100,
    B11100,
    B11100,
    B11100,
    B11100,
    B11100,
    B11100,
  };
  byte bar4[8] = {
    B11110,
    B11110,
    B11110,
    B11110,
    B11110,
    B11110,
    B11110,
    B11110,
  };
  byte bar5[8] = {
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
    B11111,
  };
  byte up[8] = {
    B00000,
    B00100,
    B01110,
    B11111,
    B11111,
    B00000,
    B00000,
  };

  byte down[8] = {
    B00000,
    B00000,
    B11111,
    B11111,
    B01110,
    B00100,
    B00000,
  };
  lcd.createChar(0, bar1);
  lcd.createChar(1, bar2);
  lcd.createChar(2, bar3);
  lcd.createChar(3, bar4);
  lcd.createChar(4, bar5);
  lcd.createChar(5, up);
  lcd.createChar(6, down);
}

void loop() {
  menuPrincipal();
}
void keypadEvent(KeypadEvent key) {
  switch (keypad.getState()) {
    case RELEASED:
      switch (key) {
        case 'd':
          defusing = false;
          break;
        case 'c':
          cancel = false;
          break;
      }
      break;
    case HOLD:
      switch (key) {
        case 'd':
          defusing = true;
          break;
        case 'c':
          cancel = true;
          break;
      }
      break;
  }
}

//This fuction compare codeInput[8] and password[8] variables
boolean comparePassword() {

  for (int i = 0; i < 8; i++) {
    if (codeInput[i] != password[i]) return false;
  }
  return true;
}

//Set the password variable
void setCode() {

  lcd.setCursor(0, 1);
  for (int i = 0; i < 8; i++) {
    while (1) {
      var = getNumber();
      if (var != 'x') {
        codeInput[i] = var;

        if (i != 0) {
          lcd.setCursor(i - 1, 1);
          lcd.print("*");
          lcd.print(var);
        } else {
          lcd.print(var);
        }
        tone(tonepin, 2400, 30);
        break;
      }
    }
  }
}
void setCodeTime() {

  timeCalcVar = millis();

  for (int i = 0; i < 8; i++) {
    while (1) {
      if (ACTIVATESECONDS * 1000 + timeCalcVar - millis() <= 100) {
        codeInput[i] = 'x';
        break;
      }

      lcd.setCursor(11, 0);
      printTimeDom(ACTIVATESECONDS * 1000 + timeCalcVar - millis(), false);

      var = getNumber();
      if (var != 'x') {
        codeInput[i] = var;

        if (i != 0) {
          lcd.setCursor(i - 1, 1);
          lcd.print("*");
          lcd.print(var);
        } else {
          lcd.print(var);
        }
        tone(tonepin, 2400, 30);
        break;
      }
    }
  }
}
void setPass() {
  lcd.setCursor(0, 1);

  for (int i = 0; i < 8; i++) {
    while (1) {
      var = getNumber();
      if (var != 'x') {
        password[i] = var;
        if (i != 0) {
          lcd.setCursor(i - 1, 1);
          lcd.print("*");
          lcd.print(var);
        } else {
          lcd.print(var);
        }
        tone(tonepin, 2400, 30);
        break;
      }
    }
  }
}

void setNewPass() {

  while (1) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Enter New Pass");
    setPass();

    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Retype Pass");

    setCode();

    if (comparePassword()) {

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Password Set OK!");
      delay(2000);
      break;
    } else {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("ERROR Dont Match!");
      if (soundEnable) tone(tonepin, errorTone, 200);
      delay(2000);
    }
  }
}
//Whait until a button is pressed is is a number return the number 'char' if not return x



char getNumber() {
  while (1) {
    var = keypad.getKey();
    if (var) {  //
      switch (var) {
        case 'a':
          return 'x';
          break;
        case 'b':
          return 'x';
          break;

        case 'c':
          return 'x';
          break;
        case 'd':
          return 'x';
          break;
        case '*':
          return 'x';
          break;
        case '#':
          return 'x';
          break;
        default:
          return var;
          break;
      }
    }
    return 'x';
  }
}

byte getRealNumber() {

  while (1) {
    var = keypad.waitForKey();

    if (var) {  //
      switch (var) {
        case '1':
          return 1;
          break;
        case '2':
          return 2;
          break;

        case '3':
          return 3;
          break;
        case '4':
          return 4;
          break;
        case '5':
          return 5;
          break;
        case '6':
          return 6;
        case '7':
          return 7;
          break;
        case '8':
          return 8;
          break;
        case '9':
          return 9;
          break;
        case '0':
          return 0;
          break;

        default:
          return 11;
          break;
      }
    }
    return 11;
  }
}


char menu1[][15] = { "Search&Destroy", "Sabotage", "Domination", "Configuration" };
char menu2[][13] = { "Game Config", "Sound Config", "Relay Test", "Auto Test" };
// char *menu1[][] = { "Search&Destroy", "Sabotage", "Domination", "Configuration" };
// char *menu2[][] = { "Game Config", "Sound Config", "Relay Test", "Auto Test" };
char GAME_TIME[] = "Game Time:";
char BOMB_TIME[] = "Bomb Time:";
char ZERO_MINUTES[] = "00 minutes";
char ARM_TIME[] = "Arm Time:";
char ZERO_SECS[] = "00 seconds";
char ENABLE_SOUND[] = "Enable Sound?";
char YES_OR_NO[] = "A : Yes B : No";
char ENABLE_RELAYPIN[] = "Enable Relay?";
char ENABLE_CODE[] = "Enable Code Arm?";
char GAME_TIME_TOP[] = "GAME TIME";
char ARMING_BOMB[] = "ARMING BOMB";
char ENTER_CODE[] = "Enter Code";
char CODE_ERROR[] = "Code Error!";
char BOMB_ARMED[] = "BOMB ARMED";
char DETONATION_IN[] = "DETONATION IN";
char DISARMING[] = "DISARMING BOMB";
char DISARM[] = "DISARMING";
char GAME_OVER[] = " GAME OVER! ";
char DEFENDERS_WIN[] = " DEFENDERS WIN ";
char SABOTAGE_FAIL[] = "SABOTAGE FAIL!";

//void getConfig(){
//
////Check first time
//
//if (EEPROM.read(0)!= 1){
////write default config values
//
//
//
//}
//
////RELAY_TIME = EEPROM.read(1) * 1000 ;
//
//
//}
//##################MENUS###############################

void menuPrincipal() {  //MAIN MENU

  digitalWrite(GREENLED, LOW);
  digitalWrite(REDLED, LOW);

  //   if we start a new game from another we need to restart propertly this variables
  saStatus = false;
  sdStatus = false;
  doStatus = false;
  //Draw menu
  lcd.clear();  //clear lcd and set cursor to 0,0
  int i = 0;
  // HERE YOU CAN ADD MORE ITEMS ON THE MAIN MENU
  lcd.print(menu1[i]);
  lcd.setCursor(15, 1);
  checkArrows(i, 2);
  while (1) {

    var = keypad.waitForKey();
    if (var == BT_UP && i > 0) {
      tone(tonepin, 2400, 30);
      i--;
      lcd.clear();
      lcd.print(menu1[i]);
      checkArrows(i, 2);
      delay(50);
    }
    if (var == BT_DOWN && i < 2) {
      tone(tonepin, 2400, 30);
      i++;
      lcd.clear();
      lcd.print(menu1[i]);
      checkArrows(i, 2);
      delay(50);
    }

    if (var == BT_SEL) {
      tone(tonepin, 2400, 30);
      lcd.clear();
      switch (i) {

        case 0:
          sdStatus = true;
          configQuickGame();
          startGameCount();
          search();
          break;
        case 1:
          saStatus = true;
          configQuickGame();
          startGameCount();
          sabotage();
          break;
        case 2:

          doStatus = true;
          configQuickGame();
          startGameCount();
          domination();
          break;
        case 3:
          config();
          break;
      }
    }
  }
}

void config() {
  //Draw menu
  lcd.clear();
  lcd.setCursor(0, 0);
  int i = 0;

  delay(500);
  lcd.print(menu2[i]);
  checkArrows(i, 3);

  while (1) {
    var = keypad.waitForKey();
    if (var == BT_UP && i > 0) {
      tone(tonepin, 2400, 30);
      i--;
      lcd.clear();
      lcd.print(menu2[i]);
      checkArrows(i, 3);
      delay(50);
    }
    if (var == BT_DOWN && i < 3) {
      tone(tonepin, 2400, 30);
      i++;
      lcd.clear();
      lcd.print(menu2[i]);
      checkArrows(i, 3);
      delay(50);
    }
    if (var == BT_CANCEL) {
      tone(tonepin, 2400, 30);
      menuPrincipal();
    }
    if (var == BT_SEL) {
      tone(tonepin, 2400, 30);
      lcd.clear();
      switch (i) {

        case 0:
          //gameConfigMenu();
          break;

        case 1:
          //soundConfigMenu();
          break;

        case 2:
          lcd.clear();
          lcd.print("RELAYPIN ON!");
          digitalWrite(RELAYPIN, HIGH);  // turn the LED on (HIGH is the voltage level)
          delay(4000);                   // wait for 4 second
          lcd.clear();
          lcd.print("RELAYPIN OFF!");
          digitalWrite(RELAYPIN, LOW);
          delay(2000);
          config();
          break;
      }
    }
  }
}

void configQuickGame() {

  lcd.clear();
  //GAME TIME
  if (sdStatus || doStatus || saStatus) {
menu1:
    lcd.clear();
    lcd.print(GAME_TIME);
    delay(100);
    lcd.setCursor(0, 1);
    lcd.print("00:00 hh:mm");
    lcd.cursor();
    lcd.blink();
    lcd.setCursor(0, 1);
    byte var2 = 0;
    for (int i = 0; i < 4; i++) {
      while (1) {
        if (i == 2 && var2 == 0) {
          lcd.print(":");
          var2 = 1;
        }

        byte varu = getRealNumber();
        if (varu != 11) {

          time[i] = varu;
          Serial.print(varu);


          lcd.print(varu);
          tone(tonepin, 2400, 30);

          break;
        }
      }
    }
    lcd.noCursor();
    lcd.noBlink();
    lcd.setCursor(13, 1);
    lcd.print("ok?");
    //zona donde pasamos los items a
    //redibujar
    while (1) {
      var = keypad.waitForKey();
      if (var == 'd')  // Accept
      {
        tone(tonepin, 2400, 30);
        GAMEMINUTES = ((time[0] * 600) + (time[1] * 60) + (time[2] * 10) + (time[3]));
        break;
      }
      if (var == 'c')  // Cancel or Back Button :')
      {
        tone(tonepin, 2400, 30);
        goto menu1;
      }
    }
    tone(tonepin, 2400, 30);
    lcd.clear();
  }
  //BOMB TIME
  if (sdStatus || saStatus) {

menu2:
    lcd.clear();
    lcd.print(BOMB_TIME);
    delay(100);
    lcd.setCursor(0, 1);
    lcd.print(ZERO_MINUTES);
    lcd.cursor();
    lcd.blink();
    lcd.setCursor(0, 1);
    for (int i = 0; i < 2; i++) {
      while (1) {
        byte varu = getRealNumber();
        if (varu != 11) {
          time[i] = varu;
          lcd.print(varu);
          tone(tonepin, 2400, 30);
          break;
        }
      }
    }
    lcd.noCursor();
    lcd.noBlink();
    lcd.setCursor(13, 1);
    lcd.print("ok?");
    //zona donde pasamos los items a
    //redibujar
    while (1) {
      var = keypad.waitForKey();
      if (var == 'd')  //
      {
        tone(tonepin, 2400, 30);
        BOMBMINUTES = ((time[0] * 10) + (time[1]));
        break;
      }
      if (var == 'c')  // Cancel or Back Button :')
      {
        tone(tonepin, 2400, 30);
        goto menu2;
      }
    }
    tone(tonepin, 2400, 30);
    lcd.clear();
  }
  lcd.clear();
  //ARMING TIME
  if (sdStatus || doStatus || saStatus) {

menu3:
    lcd.clear();
    lcd.print(ARM_TIME);
    delay(100);
    lcd.setCursor(0, 1);
    lcd.print(ZERO_SECS);
    lcd.cursor();
    lcd.blink();
    lcd.setCursor(0, 1);
    for (int i = 0; i < 2; i++) {
      while (1) {
        byte varu = getRealNumber();
        if (varu != 11) {
          time[i] = varu;
          lcd.print(varu);
          tone(tonepin, 2400, 30);
          break;
        }
      }
    }
    lcd.noCursor();
    lcd.noBlink();
    lcd.setCursor(13, 1);
    lcd.print("ok?");

    //zona donde pasamos los items a
    //redibujar
    while (1) {
      var = keypad.waitForKey();
      if (var == 'd')  // Accept
      {
        tone(tonepin, 2400, 30);
        ACTIVATESECONDS = ((time[0] * 10) + (time[1]));
        break;
      }
      if (var == 'c')  // Cancel or Back Button :')
      {
        tone(tonepin, 2400, 30);
        goto menu3;
      }
    }
    tone(tonepin, 2400, 30);
    lcd.clear();
  }
  //sound??
  if (sdStatus || saStatus || doStatus) {
    lcd.clear();
    lcd.print(ENABLE_SOUND);
    lcd.setCursor(0, 1);
    lcd.print(YES_OR_NO);

    while (1) {
      var = keypad.waitForKey();
      if (var == 'a') {
        soundEnable = true;
        tone(tonepin, 2400, 30);
        break;
      }

      if (var == 'b') {
        soundEnable = false;
        tone(tonepin, 2400, 30);
        break;
      }
    }
  }
  //Activate RELAY at Terrorist game ends??? Boom!

  if (sdStatus || saStatus) {
    lcd.clear();
    lcd.print(ENABLE_RELAYPIN);
    lcd.setCursor(0, 1);
    lcd.print(YES_OR_NO);
    while (1) {
      var = keypad.waitForKey();
      if (var == 'a') {
        relayEnable = true;
        tone(tonepin, 2400, 30);
        break;
      }
      if (var == 'b') {
        relayEnable = false;
        tone(tonepin, 2400, 30);
        break;
      }
    }
  }
  //You Want a password enable-disable game?
  if (sdStatus || saStatus) {
    lcd.clear();
    lcd.print(ENABLE_CODE);
    lcd.setCursor(0, 1);
    lcd.print(YES_OR_NO);

    while (1) {
      var = keypad.waitForKey();
      if (var == 'a') {
        tone(tonepin, 2400, 30);
        setNewPass();
        passwordEnable = true;
        break;
      }
      if (var == 'b') {
        tone(tonepin, 2400, 30);
        passwordEnable = false;
        break;
      }
    }
    tone(tonepin, 2400, 30);
  }
  //Continue the game :D
}



void search() {
  refresh = true;
  lcd.clear();
  digitalWrite(REDLED, LOW);
  digitalWrite(GREENLED, LOW);
  //SETUP INITIAL TIME
  int minutos = GAMEMINUTES - 1;
  unsigned long iTime = millis();  //  initialTime in millisec
  unsigned long aTime;
  //var='o';

  //Starting Game Code
  while (1) {  // this is the important code, is a little messy but works good.

    //If you fail disarm.
    if (endGame) {
      failSplash();
    }

    //Code for led blinking
    timeCalcVar = (millis() - iTime) % 1000;
    if (timeCalcVar >= 0 && timeCalcVar <= 50) digitalWrite(GREENLED, HIGH);
    if (timeCalcVar >= 90 && timeCalcVar <= 130) digitalWrite(GREENLED, LOW);

    lcd.setCursor(3, 0);
    lcd.print(GAME_TIME_TOP);
    aTime = millis() - iTime;
    lcd.setCursor(3, 1);

    //PRINT TIME ON LCD

    printTime(minutos, aTime);

    //###########################CHECKINGS##################

    //Check If Game End
    if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) failSplash();
    //Serial.println(keypad.getKey());
    //USED IN PASSWORD GAME
    if ('d' == keypad.getKey() && passwordEnable) {
      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print(ARMING_BOMB);
      delay(1000);  //a little delay to choose the password
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(ENTER_CODE);

      setCodeTime();  // we need to set the comparation variable first it writes on codeInput[]

      //then compare :D

      if (comparePassword()) destroy();
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print(CODE_ERROR);
      if (soundEnable) tone(tonepin, errorTone, 200);
      delay(500);
      lcd.clear();
    }
    //Check If Is Activating
    while (defusing && !passwordEnable) {
      digitalWrite(GREENLED, LOW);
      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print(ARMING_BOMB);
      lcd.setCursor(0, 1);
      unsigned int percent = 0;
      unsigned long xTime = millis();  //start disabling time
      while (defusing) {
        keypad.getKey();
        percent = (millis() - xTime) / (ACTIVATESECONDS * 10);

        drawBar(percent);
        //check if game time runs out during the disabling
        aTime = millis() - iTime;
        Serial.println(millis() - xTime);
        if ((minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) || minutos - aTime / 60000 > 4000000000) {
          endGame = true;
        }
        timeCalcVar = (millis() - xTime) % 1000;

        if (timeCalcVar >= 0 && timeCalcVar <= 40) {
          digitalWrite(REDLED, HIGH);
          if (soundEnable) tone(tonepin, alarmTone1, 200);
        }
        if (timeCalcVar >= 480 && timeCalcVar <= 520) {
          if (soundEnable) tone(tonepin, alarmTone2, 200);
          digitalWrite(REDLED, LOW);
        }



        if (percent >= 100) {
          digitalWrite(GREENLED, LOW);
          destroy();  // jump to the next gamemode
        }
      }
      lcd.clear();
      digitalWrite(REDLED, LOW);
    }
  }
}

void destroy() {
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print(BOMB_ARMED);
  delay(1000);
  int minutos = BOMBMINUTES - 1;
  unsigned long iTime = millis();
  unsigned long aTime;
  int largoTono = 50;

  //MAIN LOOP
  while (1) {

    //If you fail disarm.
    if (endGame) {
      explodeSplash();
    }

    //Led Blink

    timeCalcVar = (millis() - iTime) % 1000;
    if (timeCalcVar >= 0 && timeCalcVar <= 40) {
      digitalWrite(REDLED, HIGH);
      if (soundEnable) tone(tonepin, activeTone, largoTono);
    }
    if (timeCalcVar >= 180 && timeCalcVar <= 220) {
      digitalWrite(REDLED, LOW);
    }
    //Sound
    aTime = millis() - iTime;
    timeCalcVar = (millis() - iTime) % 1000;
    if (timeCalcVar >= 245 && timeCalcVar <= 255 && minutos - aTime / 60000 < 2 && soundEnable) tone(tonepin, activeTone, largoTono);
    if (timeCalcVar >= 495 && timeCalcVar <= 510 && minutos - aTime / 60000 < 4 && soundEnable) tone(tonepin, activeTone, largoTono);
    if (timeCalcVar >= 745 && timeCalcVar <= 760 && minutos - aTime / 60000 < 2 && soundEnable) tone(tonepin, activeTone, largoTono);
    if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) < 10) largoTono = 300;

    lcd.setCursor(1, 0);
    lcd.print(DETONATION_IN);
    //Passed Time

    lcd.setCursor(3, 1);

    ////////HERE ARE THE TWO OPTIONS THAT ENDS THE GAME///////////

    ////TIME PASED AWAY AND THE BOMB EXPLODES
    if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0)  // Check if game ends
    {
      explodeSplash();
    }
    //print time

    printTime(minutos, aTime);

    //// SECOND OPTION: YOU PRESS DISARMING BUTTON

    //IF IS A PASSWORD GAME

    if ('d' == keypad.getKey() && passwordEnable) {

      lcd.clear();
      lcd.setCursor(1, 0);
      lcd.print(DISARMING);
      delay(1000);  //a little delay to think in the password

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(ENTER_CODE);

      setCodeTime();  // we need to set the compare variable first

      //then compare :D

      if (comparePassword()) {
        disarmedSplash();
      }
      lcd.clear();
      lcd.setCursor(3, 0);
      lcd.print(CODE_ERROR);
      if (soundEnable) tone(tonepin, errorTone, 200);
      delay(500);
      lcd.clear();
    }

    if (defusing && !passwordEnable)  // disarming bomb
    {
      lcd.clear();
      digitalWrite(REDLED, LOW);
      lcd.setCursor(3, 0);
      lcd.print(DISARM);
      lcd.setCursor(0, 1);
      unsigned int percent = 0;
      unsigned long xTime = millis();
      while (defusing) {
        keypad.getKey();
        //check if game time runs out during the disabling
        aTime = millis() - iTime;
        if ((minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) || minutos - aTime / 60000 > 4000000000) {
          endGame = true;
        }
        timeCalcVar = (millis() - xTime) % 1000;
        if (timeCalcVar >= 0 && timeCalcVar <= 20) {
          digitalWrite(GREENLED, HIGH);
          if (soundEnable) tone(tonepin, alarmTone1, 200);
        }
        if (timeCalcVar >= 480 && timeCalcVar <= 500) {
          if (soundEnable) tone(tonepin, alarmTone2, 200);
          digitalWrite(GREENLED, LOW);
        }
        unsigned long seconds = (millis() - xTime);
        percent = seconds / (ACTIVATESECONDS * 10);
        drawBar(percent);

        //BOMB DISARMED GAME OVER
        if (percent >= 100) disarmedSplash();
      }
      digitalWrite(REDLED, LOW);
      digitalWrite(GREENLED, LOW);
      lcd.clear();
    }
  }
}

void sabotage() {

  endGame = false;
  refresh = true;
  lcd.clear();
  digitalWrite(REDLED, LOW);
  digitalWrite(GREENLED, LOW);
  //SETUP INITIAL TIME
  int minutos = GAMEMINUTES - 1;

  if (start) {
    iTime = millis(); //  initial Time of the game, use this because sabotage mode goes can return to sabotage()
    start = false;
  }

  unsigned long aTime;
			

  //Starting Game Code
  while (1) { 

						 
    if (endGame) {
      failSplash();
    }

    //Code for led blinking
    timeCalcVar = (millis() - iTime) % 1000;
    if (timeCalcVar >= 0 && timeCalcVar <= 50) digitalWrite(GREENLED, HIGH);
    if (timeCalcVar >= 90 && timeCalcVar <= 130) digitalWrite(GREENLED, LOW);

    lcd.setCursor(3, 0);
    lcd.print(GAME_TIME);
    aTime = millis() - iTime;
    lcd.setCursor(3, 1);

    //PRINT TIME ON LCD

    printTime(minutos, aTime);

    //###########################CHECKING##################

    //Check If Game End
    if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) {
      failSplash();
    }

    //USED IN PASSWORD GAME
    if ('d' == keypad.getKey() && passwordEnable) {
      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print(ARMING_BOMB);
      delay(1000); //a little delay to choose the password
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(ENTER_CODE);

      setCodeTime(); // we need to set the compare variable first

					

      if (comparePassword()) {
        destroySabotage();
      }
      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print(CODE_ERROR);
      if (soundEnable) tone(tonepin, errorTone, 200);
      delay(500);
      lcd.clear();
    }

    //Check If Is Activating
    while (defusing && !passwordEnable) {
     
      keypad.getKey();
      cls();
      digitalWrite(GREENLED, LOW);
      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print(ARMING_BOMB);
      lcd.setCursor(0, 1);
      unsigned int percent = 0;
      unsigned long xTime = millis(); //start disabling time
      while (defusing) {
        
        keypad.getKey();
															  

						 
        //check if game time runs out during the disabling
        aTime = millis() - iTime;
										 
        if ((minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) || minutos - aTime / 60000 > 4000000000)endGame = true;
						 
		 
        timeCalcVar = (millis() - xTime) % 1000;

        if (timeCalcVar >= 0 && timeCalcVar <= 40) {
          
          digitalWrite(REDLED, HIGH);
          if (soundEnable) tone(tonepin, alarmTone1, 200);
        }
        if (timeCalcVar >= 480 && timeCalcVar <= 520) {
          
          if (soundEnable) tone(tonepin, alarmTone2, 200);
          digitalWrite(REDLED, LOW);
        }
        unsigned long seconds = millis() - xTime;
        percent = (seconds) / (ACTIVATESECONDS * 10);
        drawBar(percent);

        if (percent >= 100) {
          
          digitalWrite(GREENLED, LOW);
          destroySabotage(); // jump to the next game mode
        }
      }
      cls();
      digitalWrite(REDLED, LOW);
    }
  }
}

void destroySabotage() {
  endGame = false;
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print(BOMB_ARMED);
  delay(1000);
  int minutos = BOMBMINUTES - 1;
  unsigned long iTime = millis();
  unsigned long aTime;
  int largoTono = 50;

  //MAIN LOOP
  while (1) {

    //If you fail disarm.
    if (endGame) {
      explodeSplash();
    }

    //Led Blink

    timeCalcVar = (millis() - iTime) % 1000;
    if (timeCalcVar >= 0 && timeCalcVar <= 40) {
      digitalWrite(REDLED, HIGH);
      if (soundEnable) tone(tonepin, activeTone, largoTono);
    }
    if (timeCalcVar >= 180 && timeCalcVar <= 220) {
      digitalWrite(REDLED, LOW);
    }
    //Sound
							 
    timeCalcVar = (millis() - iTime) % 1000;
    aTime = millis() - iTime;
    if (timeCalcVar >= 245 && timeCalcVar <= 255 && minutos - aTime / 60000 < 2 && soundEnable) tone(tonepin, activeTone, largoTono);
    if (timeCalcVar >= 495 && timeCalcVar <= 510 && minutos - aTime / 60000 < 4 && soundEnable) tone(tonepin, activeTone, largoTono);
    if (timeCalcVar >= 745 && timeCalcVar <= 760 && minutos - aTime / 60000 < 2 && soundEnable) tone(tonepin, activeTone, largoTono);
    if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) < 10) largoTono = 300;

    lcd.setCursor(1, 0);
    lcd.print(DETONATION_IN);
    //Passed Time

    lcd.setCursor(3, 1);

    ////////TWO OPTIONS THAT ENDS THE GAME///////////

    ////TIME PASSED AND THE BOMB EXPLODES
    if (minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) // Check if game ends
    {
      failSplash();
    }
    //print time

    printTime(minutos, aTime);

    //// SECOND OPTION: DISARMED BOMB

    //IF IS A PASSWORD GAME

    if ('d' == keypad.getKey() && passwordEnable) {

      lcd.clear();
      digitalWrite(REDLED, LOW);
      digitalWrite(GREENLED, HIGH);
      lcd.print(DISARMING);
      delay(1000); //a little delay to choose the password

      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(ENTER_CODE);

      setCodeTime(); //compare variable first

      //then compare

      if (comparePassword()) {
        sabotage();
      }
      lcd.clear();
      lcd.setCursor(2, 0);
      lcd.print(CODE_ERROR);
      if (soundEnable) tone(tonepin, errorTone, 200);
      delay(500);
      cls();
    }

    if (defusing && !passwordEnable) // disarming bomb
    {
      lcd.clear();
      digitalWrite(REDLED, LOW);
      lcd.setCursor(3, 0);
      lcd.print(DISARM);
      lcd.setCursor(0, 1);
      unsigned int percent = 0;
      unsigned long xTime = millis();
      while (defusing) {
        
        keypad.getKey();
        //check if game time runs out during the disabling
        aTime = millis() - iTime;
        if ((minutos - aTime / 60000 == 0 && 59 - ((aTime / 1000) % 60) == 0) || minutos - aTime / 60000 > 4000000000) {
          endGame = true;
        }

        timeCalcVar = (millis() - xTime) % 1000;
        if (timeCalcVar >= 0 && timeCalcVar <= 20) {
          
          digitalWrite(GREENLED, HIGH);
          if (soundEnable) tone(tonepin, alarmTone1, 200);
        }
        if (timeCalcVar >= 480 && timeCalcVar <= 500) {
          
          if (soundEnable) tone(tonepin, alarmTone2, 200);
          digitalWrite(GREENLED, LOW);
        }
        unsigned long seconds = (millis() - xTime);
        percent = seconds / (ACTIVATESECONDS * 10);
        drawBar(percent);

        //BOMB DISARMED RETURN TO SABOTAGE
        if (percent >= 100)
        {
          lcd.clear();
          lcd.print("Bomb Disarmed");
          delay(1000);
          sabotage();
        }
      }
      digitalWrite(REDLED, LOW);
      digitalWrite(GREENLED, LOW);
      lcd.clear();
    }
  }
}

void domination() {

  //SETUP INITIAL TIME 
  int minutes = GAMEMINUTES-1;
  boolean showGameTime=true;
  unsigned long a;
  unsigned long iTime=millis(); //  initialTime in millisec 
  unsigned long aTime;
 
  team=0;
  iZoneTime=0;
  aTime=0;
  redTime=0;
  yellowTime=0;

  int largoTono = 50;
  // 0 = neutral, 1 = yellow team, 2 = red team
  a=millis();
  //Starting Game Code
  while(1) 
  {
    if(endGame){
      gameOver();
    }
    
    keypad.getKey();
    aTime=millis()- iTime;
    //Code for led blinking
    timeCalcVar=(millis()- iTime)%1000;
    if(timeCalcVar >= 0 && timeCalcVar <= 40)
    {
      if(team==1)digitalWrite(GREENLED, HIGH);  
      if(team==2)digitalWrite(REDLED, HIGH);  
    }
    if(timeCalcVar >= 50 && timeCalcVar <= 100)
    {    
      if(team==1)digitalWrite(GREENLED, LOW);  
      if(team==2)digitalWrite(REDLED, LOW);
    }
    // Sound!!! same as Destroy 
    if(timeCalcVar >= 0 && timeCalcVar <= 40 && soundEnable)tone(tonepin,activeTone,largoTono);

    if(timeCalcVar >= 245 && timeCalcVar <= 255 && minutes-aTime/60000<2 && soundEnable)tone(tonepin,activeTone,largoTono);
    if(timeCalcVar >= 495 && timeCalcVar <= 510 && minutes-aTime/60000<4 && soundEnable)tone(tonepin,activeTone,largoTono);
    if(timeCalcVar >= 745 && timeCalcVar <= 760 && minutes-aTime/60000<2 && soundEnable)tone(tonepin,activeTone,largoTono);
    //Help to count 3 secs
    if(a+2000<millis()){
      a=millis();   
      showGameTime=!showGameTime;
      cls();
    }
    //THE NEXT TO METHODS SHOW "GAME TIME" AND "CONTROLED ZONE TIME" IT SHOWS 2 AND 2 SEC EACH

    if(showGameTime){ //THE SECOND IS /2
      lcd.setCursor(3,0);
      lcd.print("GAME TIME");
      lcd.setCursor(3,1);
      printTime(minutes, aTime);
    }
    else if (!showGameTime){

      lcd.setCursor(2,0);
      if(team == 0)lcd.print("NEUTRAL ZONE");
      if(team == 1)lcd.print(" YELLOW ZONE");
      if(team == 2)lcd.print("  RED ZONE");

      if(team>0){
        lcd.setCursor(3,1);
        printTimeDom(millis()-iZoneTime,true);
      }
    }

    //###########################CHECKINGS##################

    //Check If Game End
    if(minutes-aTime/60000==0 && 59-((aTime/1000)%60)==0)
    {
      gameOver();
    }

    //Check If IS neutral
    while((defusing || cancel) && team > 0)
    {
      cls();
      if(team>0)lcd.print("NEUTRALIZING...");
      lcd.setCursor(0,1);
      unsigned int percent=0;
      unsigned long xTime=millis(); //start disabling time
      while(defusing || cancel)
      {
        //check if game time runs out during the disabling
        aTime= millis()- iTime;
        if((minutes-aTime/60000==0 && 59-((aTime/1000)%60)==0) || minutes-aTime/60000>4000000000){ 
          endGame = true;
        }
        
        keypad.getKey();
        timeCalcVar = (millis()- xTime)%1000;

        if( timeCalcVar >= 0 && timeCalcVar <= 20)
        {
          if(soundEnable)tone(tonepin,alarmTone1,200);
        }
        if(timeCalcVar >= 480 && timeCalcVar <= 500)
        {
          if(soundEnable)tone(tonepin,alarmTone2,200);
          digitalWrite(REDLED, LOW);
        }

        unsigned long seconds= millis() - xTime;
        percent = (seconds)/(ACTIVATESECONDS*10);
        drawBar(percent);

        if(percent >= 100)
        {
          delay(1000);

          if(team==1){ 
            yellowTime+=millis()-iZoneTime;
            iZoneTime=0; 

          }
          if(team==2){ 
            redTime+=millis()-iZoneTime;
            iZoneTime=0; 
          }
          team=0;
          break;
        }
      }
      cls();
    }

    //Capturing red

    while(defusing && team == 0 )
    {
      cls();
      if(team==0)lcd.print(" CAPTURING ZONE");
      lcd.setCursor(0,1);
      unsigned int percent=0;
      unsigned long xTime=millis(); //start disabling time
      while(defusing)
      {
        keypad.getKey();
        //check if game time runs out during the disabling
        aTime= millis()- iTime;
        if((minutes-aTime/60000==0 && 59-((aTime/1000)%60)==0) || minutes-aTime/60000>4000000000){ 
          endGame = true;
        }
        timeCalcVar = (millis()- xTime)%1000;

        if( timeCalcVar >= 0 && timeCalcVar <= 20)
        {
          digitalWrite(REDLED, HIGH);  
          if(soundEnable)tone(tonepin,alarmTone1,200);
        }
        if(timeCalcVar >= 480 && timeCalcVar <= 500)
        {
          if(soundEnable)tone(tonepin,alarmTone2,200);
          digitalWrite(REDLED, LOW);
        }

        unsigned long seconds= millis() - xTime;
        percent = (seconds)/(ACTIVATESECONDS*10);
        drawBar(percent);

        if(percent >= 100)
        {
          digitalWrite(GREENLED, LOW);
          team=2;
          iZoneTime=millis();
          delay(1000);
          break;
        }
      }
      cls();
      digitalWrite(REDLED, LOW);
    }

    //getting to yellow zone
    while(cancel && team == 0 )
    {
      cls();
      if(team==0)lcd.print(" CAPTURING ZONE");
      lcd.setCursor(0,1);
      unsigned int percent=0;
      unsigned long xTime=millis(); //start disabling time
      while(cancel)
      {
        keypad.getKey();
        //check if game time runs out during the disabling
        aTime= millis()- iTime;
        if((minutes-aTime/60000==0 && 59-((aTime/1000)%60)==0) || minutes-aTime/60000>4000000000){ 
          endGame = true;
        }
        timeCalcVar = (millis()- xTime)%1000;

        if( timeCalcVar >= 0 && timeCalcVar <= 20)
        {
          digitalWrite(GREENLED, HIGH);  
          if(soundEnable)tone(tonepin,alarmTone1,200);
        }
        if(timeCalcVar >= 480 && timeCalcVar <= 500)
        {
          if(soundEnable)tone(tonepin,alarmTone2,200);
          digitalWrite(GREENLED, LOW);
        }

        unsigned long seconds= millis() - xTime;
        percent = (seconds)/(ACTIVATESECONDS*10);
        drawBar(percent);

        if(percent >= 100)
        {
          digitalWrite(GREENLED, LOW);
          team=1;
          iZoneTime=millis();
          delay(1000);
          break;
        }
      }
      cls();
      digitalWrite(GREENLED, LOW);  
    }
  }
}

void gameOver(){

  if(team==1)yellowTime+=millis()-iZoneTime;
  if(team==2)redTime+=millis()-iZoneTime;
  digitalWrite(GREENLED, LOW);
  digitalWrite(REDLED, LOW);
  while(!defusing){
    keypad.getKey();
    if(defusing){
      keypad.getKey();
      break;
    }
    lcd.clear();
    lcd.setCursor(3,0);
    lcd.print("TIME OVER!");
    lcd.setCursor(0,1);

    //check who team win the base
    if(yellowTime>redTime){
      //greenteam wins
      lcd.print(" YELLOW TEAM WINS");
      digitalWrite(GREENLED, HIGH);
    }
    else{
      //redteam wins 
      lcd.print("  RED TEAM WINS");
      digitalWrite(REDLED, HIGH);
    }
    delay(3000);
    keypad.getKey();
    if(defusing){
      keypad.getKey();
      break;
    }
    cls();
    lcd.print("Red Time:");
    lcd.setCursor(5,1);
    printTimeDom(redTime,false);
    delay(3000);
    keypad.getKey();
    if(defusing){
      
      break;
    }
    cls();
    lcd.print("Yellow Time:");
    lcd.setCursor(5,1);
    printTimeDom(yellowTime,false);
    delay(3000);
    keypad.getKey();
    if(defusing){
      keypad.getKey();
      break;
    }
  }
  cls();
  delay(100);
  lcd.print("Play Again?");
  lcd.setCursor(0,1);
  lcd.print("A : Yes B : No");
  while(1)
  {
    var = keypad.waitForKey();
    if(var == 'a' ){
      tone(tonepin,2400,30);
      cls();
      domination();
      break;
    }  
    if(var == 'b' ){
      tone(tonepin,2400,30);
      menuPrincipal();
      break;
    }  
  } 
}


void explodeSplash() {
  digitalWrite(REDLED, LOW);
  digitalWrite(GREENLED, LOW);
  lcd.clear();
  delay(100);
  endGame = false;
  lcd.setCursor(1, 0);
  lcd.print("TERRORISTS WIN");
  lcd.setCursor(4, 1);
  lcd.print("GAME OVER");
  for (int i = 200; i > 0; i--)  // this is the ultra hi definition explosion sound xD
  {
    tone(tonepin, i);
    delay(20);
  }
  noTone(tonepin);
  if (relayEnable) {
    activateRelay();
  }
  delay(5000);
  lcd.clear();

  //end code
  lcd.print("Play Again?");
  lcd.setCursor(0, 1);
  lcd.print("A : Yes B : No");
  while (1) {
    var = keypad.waitForKey();
    if (var == 'a') {
      tone(tonepin, 2400, 30);
      //We have two options, search & destroy and sabotage play again options so!
      if (sdStatus) {
        startGameCount();
        search();
      }
      if (saStatus) {
        saStatus = true;
        startGameCount();
        start = true;  //to set iTime to actual millis() :D
        sabotage();
      }
    }
    if (var == 'b') {
      tone(tonepin, 2400, 30);
      menuPrincipal();

      break;
    }
  }
}
void failSplash() {
  digitalWrite(REDLED, LOW);
  digitalWrite(GREENLED, LOW);
  lcd.clear();
  delay(100);
  endGame = false;
  lcd.setCursor(1, 0);
  lcd.print("TIME OUT");
  lcd.setCursor(4, 1);
  lcd.print("GAME OVER");
  for (int i = 200; i > 0; i--)  // this is the ultra hi definition explosion sound xD
  {
    tone(tonepin, i);
    delay(20);
  }
  noTone(tonepin);
  if (relayEnable) {
    activateRelay();
  }
  delay(5000);
  lcd.clear();

  //end code
  lcd.print("Play Again?");
  lcd.setCursor(0, 1);
  lcd.print("A : Yes B : No");
  while (1) {
    var = keypad.waitForKey();
    if (var == 'a') {
      tone(tonepin, 2400, 30);
      //We have two options, search & destroy and sabotaje play again options so!
      if (sdStatus) {
        startGameCount();
        search();
      }
      if (saStatus) {
        saStatus = true;
        startGameCount();
        start = true;  //to set iTime to actual millis() :D
        sabotage();
      }
    }
    if (var == 'b') {
      tone(tonepin, 2400, 30);
      menuPrincipal();

      break;
    }
  }
}
void disarmedSplash() {
  endGame = false;
  digitalWrite(REDLED, LOW);
  digitalWrite(GREENLED, LOW);
  if (sdStatus || saStatus) {
    lcd.clear();
    lcd.setCursor(2, 0);
    lcd.print("BOMB DISARMED");
    lcd.setCursor(3, 1);
    lcd.print("MILITARY WINS");
    digitalWrite(GREENLED, HIGH);
    delay(5000);
    digitalWrite(GREENLED, LOW);
  }
  //end code
  lcd.clear();
  lcd.print("Play Again?");
  lcd.setCursor(0, 1);
  lcd.print("A : Yes B : No");
  digitalWrite(REDLED, LOW);
  digitalWrite(GREENLED, LOW);
  while (1) {
    var = keypad.waitForKey();
    if (var == 'a') {
      tone(tonepin, 2400, 30);
      //We have two options, search & destroy and sabotaje play again options so!
      if (sdStatus) {
        startGameCount();
        search();
      }
      if (saStatus) {
        saStatus = true;
        startGameCount();
        start = true;  //to set iTime to actual millis() :D
        sabotage();
      }
    }
    if (var == 'b') {
      tone(tonepin, 2400, 30);
      menuPrincipal();
      break;
    }
  }
}
void drawBar(byte porcent) {
  //TODO: Optimize this code
  int box = (8 * porcent) / 10;
  lcd.setCursor(0, 1);
  while (box >= 5) {
    if (box >= 5) {
      lcd.write(4);
      box -= 5;
    }
  }
  switch (box) {
    case 0:
      break;
    case 1:
      lcd.write((uint8_t)0);
      break;
    case 2:
      lcd.write(1);
      break;
    case 3:
      lcd.write(2);
      break;
    case 4:
      lcd.write(3);
      break;
  }
}
void cls() {
  lcd.clear();
  lcd.setCursor(0, 0);
}

void printTime(unsigned long minutos, unsigned long aTiempo) {

  timeCalcVar = minutos - aTiempo / 60000;
  //Hours

  if (timeCalcVar / 60 == 0 && refresh) {
    lcd.clear();
    refresh = false;
    //delay(100);
    lcd.setCursor(3, 1);
    Serial.println("!!!!");
  }

  if (timeCalcVar / 60 >= 1) {

    if (timeCalcVar / 60 < 10) {
      lcd.setCursor(2, 1);
      lcd.print("0");
      lcd.print(timeCalcVar / 60);
    } else {
      lcd.print(timeCalcVar / 60);
    }

    lcd.print(":");
  }
  //minutes
  if (timeCalcVar % 60 < 10) {
    lcd.print("0");
    lcd.print(timeCalcVar % 60);
  } else {
    lcd.print(timeCalcVar % 60);
  }
  lcd.print(":");
  //seconds
  timeCalcVar = aTiempo / 1000;
  if (59 - (timeCalcVar % 60) < 10) {
    lcd.print("0");
    lcd.print(59 - (timeCalcVar % 60));
  } else {
    lcd.print(59 - (timeCalcVar % 60));
  }
  lcd.print(":");
  //this not mach with real time, is just a effect, it says 999 because millis%1000 sometimes give 0 LOL
  lcd.print(999 - (millis() % 1000));
}

void printTimeDom(unsigned long aTiempo, boolean showMillis) {
  //minutes
  if ((aTiempo / 60000) < 10) {
    lcd.print("0");
    lcd.print(aTiempo / 60000);
  } else {
    lcd.print(aTiempo / 60000);
  }
  lcd.print(":");
  //seconds
  if (((aTiempo / 1000) % 60) < 10) {
    lcd.print("0");
    lcd.print((aTiempo / 1000) % 60);
  } else {
    lcd.print((aTiempo / 1000) % 60);
  }
  if (showMillis) {
    lcd.print(":");
    //this not mach with real time, is just a effect, it says 999 because millis%1000 sometimes give 0 LOL
    lcd.print(999 - millis() % 1000);
  }
}

void startGameCount() {
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Ready to Begin");
  lcd.setCursor(0, 1);
  lcd.print("Push ANY Button");
  keypad.waitForKey();  //if you press a button game start

  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Starting Game");
  for (int i = 5; i > 0; i--) {  // START COUNT GAME INIT
    lcd.setCursor(5, 1);
    tone(tonepin, 2000, 100);
    lcd.print("IN ");
    lcd.print(i);
    delay(1000);
  }
  lcd.clear();
}

void checkArrows(byte i, byte maxx) {

  if (i == 0) {
    lcd.setCursor(15, 1);
    lcd.write(6);
  }
  if (i == maxx) {
    lcd.setCursor(15, 0);
    lcd.write(5);
  }
  if (i > 0 && i < maxx) {
    lcd.setCursor(15, 1);
    lcd.write(6);
    lcd.setCursor(15, 0);
    lcd.write(5);
  }
}

void activateRelay() {
  digitalWrite(RELAYPIN, HIGH);  // turn the LED on (HIGH is the voltage level)
  delay(RELAY_TIME);
  digitalWrite(RELAYPIN, LOW);
}

void destroysabotage() {
  // function unknown - placed here for compiling
  lcd.clear();
  lcd.print("Sabotage");
}

void destroydomination() {
  // function unknown - placed here for compiling
  lcd.clear();
  lcd.print("Domination");
}

void welcomeSerial() {
  Serial.println("RIGHT  = 4");
  Serial.println("UP     = A");
  Serial.println("DOWN   = B");
  Serial.println("LEFT   = 6");
  Serial.println("SELECT = D"); // OK key
  Serial.println("CANCEL = C");
  Serial.println("DEFUSE = X"); // not implemented
}

void welcomeLCD() {
  lcd.setCursor(3, 0);
  tone(tonepin, 2400, 30);
  lcd.print("AIRSOFT ONLINE JP");  // you can add your team name or someting cool
  lcd.setCursor(0, 1);
  lcd.print(" AIRSOFT BOMB");  // you can add your team name or someting cool
  keypad.setHoldTime(50);
  keypad.setDebounceTime(50);
  keypad.addEventListener(keypadEvent);
}

Very good!

Be sure to test domination() and sabotage()

1 Like

I tested them in the simulation and they worked fine. Just need to test them on the Arduino to ensure they work.