¿Cómo hago para que se ejecute una cuenta atrás con otra instrucción a la vez?

Buenas tardes, necesito hacer un juego que consiste en lo siguiente: tres leds de diferentes colores (verde amarillo y rojo) y dos jugadores que se enfrentan entre ellos, cada uno con tres botones (del color de cada led). Al iniciarse el juego, los minutos son 1 y los segundos 59. El objetivo es que en un LCD 16x2 se muestre la cuenta atrás a la vez que se ejecute lo que es el juego en sí… Cuando los
minutos sean 1 (entre 1:59 y 1:00) se enciende un led aleatoriamente (aleatoriobasico) que los jugadores deben apagar con el botón del color correcto. Quien antes lo haga, sumará un punto (los puntos también se mostrarán en el LCD). Al cambiar de minuto (entre el 1:00 y el 0:00) se ejecutaría otro nivel (el aleatoriobásicofalloresta), que es igual que el anterior con la diferencia de que si un botón erroneo es pulsado, baja la puntuación de ese jugador.

El problema es que se me ejecuta la funcion aleatoriobasico todo el rato, ya que no detecta que los segundos bajen, y por tanto los minutos tampoco. (SOLO bajan una vez, pues en el LCD bajan los segundos de 59 a 58 y ahí se queda).

Mi pregunta es: ¿cómo podría combinar ambas “ordenes”: la de restar segundos y las de aleatorio basico y aleatoriobasicofalloresta (cuando toque)?
Os dejo por aquí mi código por si alguien me puede echar una mano; se lo agradecería mucho!!

GRACIAS DE ANTEMANO

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x3F, 16, 2);
unsigned long tiempo ;
unsigned long tguardado ;
int segundos= 59;
int minutos= 1;
int jugador1=0;
int jugador2=0;
int a,b,d;
byte bverde1 = 7, bamarillo1 = 5, brojo1 = 6, bverde2 = 30, bamarillo2 = 34, brojo2 = 32, ledverde = 13, ledamarillo = 11, ledrojo = 12; 

void setup() {
  pinMode(bverde1, INPUT);  pinMode(bamarillo1, INPUT);  pinMode(brojo1, INPUT);  pinMode(bverde2, INPUT);
  pinMode(bamarillo2, INPUT);  pinMode(brojo2, INPUT);  pinMode(ledverde, OUTPUT);   pinMode(ledrojo, OUTPUT);
  pinMode(ledamarillo, OUTPUT);
   Serial.begin(9600);
   }

int sacarnumeroazar()
{
  int randNumber;
  randNumber = random(11, 14);
  Serial.println(randNumber);
  return randNumber;
}


void aleatoriobasico()
{ b = 100;
  a = sacarnumeroazar();
  digitalWrite(a, HIGH); //Enciende un led al azar

  while (b == 100)
  {
    switch (a) {       //suma puntos al jugador que acierte
      case 13:
        if (digitalRead(bverde1) == HIGH) {
          jugador1 = jugador1 + 1; lcd.setCursor(0, 1);
          lcd.print(jugador1); b = 50; break;
        }
        if (digitalRead(bverde2) == HIGH) {
          jugador2 = jugador2 + 1; lcd.setCursor(14, 1);
          lcd.print(jugador2); b = 50; break;
        }
        break;

      case 11:
        if (digitalRead(bamarillo1) == HIGH) {
          jugador1 = jugador1 + 1; lcd.setCursor(0, 1);
          lcd.print(jugador1); b = 50; break;
        }
        if (digitalRead(bamarillo2) == HIGH)  {
          jugador2 = jugador2 + 1; lcd.setCursor(14, 1);
          lcd.print(jugador2); b = 50; break;
        }
        break;
      case 12:
        if (digitalRead(brojo1) == HIGH) {
          jugador1 = jugador1 + 1; lcd.setCursor(0, 1);
          lcd.print(jugador1); b = 50; break;
        }
        if (digitalRead(brojo2) == HIGH)  {
          jugador2 = jugador2 + 1; lcd.setCursor(14, 1);
          lcd.print(jugador2); b = 50; break;
        }
        break;
    }
  }

  digitalWrite (a, LOW); //Apaga el led que se encendió al azar

  delay(1500);
}




void aleatoriobasicofalloresta()
{ b = 100;
  a = sacarnumeroazar();
  digitalWrite(a, HIGH); //Enciende un led al azar

  while (b == 100)
  {
    switch (a) {       //suma puntos al jugador que acierte
      case 13:
        if (digitalRead(bverde1) == HIGH) {
          jugador1 = jugador1 + 1; lcd.setCursor(0, 1);
          lcd.print(jugador1); b = 50; break;
        }
        if (digitalRead(bverde2) == HIGH) {
          jugador2 = jugador2 + 1; lcd.setCursor(14, 1);
          lcd.print(jugador2); b = 50; break;
        }
        if ((digitalRead(bamarillo1) == HIGH) || (digitalRead(brojo1) == HIGH)); {
          jugador1 = jugador1 - 1; lcd.setCursor(0, 1);
          lcd.print(jugador1); b = 50; break;
        }
        if ((digitalRead(bamarillo2) == HIGH) || (digitalRead(brojo2) == HIGH)); {
          jugador2 = jugador2 - 1; lcd.setCursor(14, 1);
          lcd.print(jugador2); b = 50; break;
        }
        break;

      case 11:
        if (digitalRead(bamarillo1) == HIGH) {
          jugador1 = jugador1 + 1; lcd.setCursor(0, 1);
          lcd.print(jugador1); b = 50; break;
        }
        if (digitalRead(bamarillo2) == HIGH)  {
          jugador2 = jugador2 + 1; lcd.setCursor(14, 1);
          lcd.print(jugador2); b = 50; break;
        }
        if ((digitalRead(bverde1) == HIGH) || (digitalRead(brojo1) == HIGH)); {
          jugador1 = jugador1 - 1; lcd.setCursor(0, 1);
          lcd.print(jugador1); b = 50; break;
        }
        if ((digitalRead(bverde2) == HIGH) || (digitalRead(brojo2) == HIGH)); {
          jugador2 = jugador2 - 1; lcd.setCursor(14, 1);
          lcd.print(jugador2); b = 50; break;
        }
        break;

      case 12:
        if (digitalRead(brojo1) == HIGH) {
          jugador1 = jugador1 + 1; lcd.setCursor(0, 1);
          lcd.print(jugador1); b = 50; break;
        }
        if (digitalRead(brojo2) == HIGH) {
          jugador2 = jugador2 + 1; lcd.setCursor(14, 1);
          lcd.print(jugador2); b = 50; break;
        }
        if ((digitalRead(bamarillo1) == HIGH) || (digitalRead(bverde1) == HIGH)); {
          jugador1 = jugador1 - 1; lcd.setCursor(0, 1);
          lcd.print(jugador1); b = 50; break;
        }
        if ((digitalRead(bamarillo2) == HIGH) || (digitalRead(bverde2) == HIGH)); {
          jugador2 = jugador2 - 1; lcd.setCursor(14, 1);
          lcd.print(jugador2); b = 50; break;
        }
        break;
    }
  }

  digitalWrite (a, LOW); //Apaga el led que se encendió al azar

  delay(1500);
}

void loop() {
  tiempo=millis();
  if (tiempo-tguardado>=1000){ //produce un evento cada 1000 milisegundo (1 seg)
      tguardado=tiempo;
          if  (segundos > 0 ){
               segundos--;
                } 
          if(segundos==0) {
                  delay (1000);               
                  segundos=59;
                  minutos--;
                  } }
    lcd.setCursor(0,0);
    lcd.print("J1   TIEMPO   J2");
    lcd.setCursor(0,1);
    lcd.print(jugador1);
    lcd.setCursor(14,1);
    lcd.print(jugador2);
    lcd.setCursor(6,1);
    lcd.print(minutos);
    lcd.setCursor(7,1);
    lcd.print(":");
    lcd.setCursor(8,1);
    lcd.print(segundos);
  
  while(minutos==1)
  {aleatoriobasico();}
  while(minutos==0)
  {aleatoriobasicofalloresta();} 
}

Tu loop() no va a funcionar gracias al delay(1000);. Quitalo.

tiempo = millis();
if (tiempo - tguardado >= 1000){ //produce un evento cada 1000 milisegundo (1 seg)
   tguardado = tiempo;
   if (segundos == 0) {
       //delay (1000);               
       segundos = 59;
       minutos--;
   }else{
       segundos--;
   }
}
***
***
***
if (minuto == 1){
   aleatoriobasico();
}else{
   aleatoriobasicofalloresta();
}

No distingo bien la diferencia entre las funciones aleatoriobasico() y aleatoriobasicofalloresta() me parece que son iguales y con los mismos errores.

  1. No es necesario poner break; a los if()
  2. Quita los delay(1500);
  3. Si en cada función declaras b = 100; para que preguntas while (b == 100) ? mas aun si en cada opcion la haces b = 50; elimina eso.

Finalmente y creo el principal error es que no estas "esperando" una respuesta de quien presiono el botón primero. En otras palabras en tu juego siempre gana Arduino, que sera mas rapido que la reaccion de cualquiera de los jugadores

Eso podría tener una solución por hardware (interconectando el segundo contacto entre los pulsadores) o por software.

PD: Hay un tema de rebotes en los pulsadores que también deberías tener en cuenta.