/*
O código gera um número aleatório entre zero e três.
 - se for zero executa a sequência para o LED vermelho;
 - se for um executa a sequência para o LED amarelo;
 - se for dois executa a sequência para o LED verde;
 - se for três executa a sequência para o LED azul;

Após gerar o número ele lê qual botão foi pressionado e compara com o número aleatório:
 - se forem iguais, toca o som de ganhou
 - se forem diferentes ou um botão o botão não foi pressionado no tempo correto, toca o som de perdeu

O código só testa um botão e reinicia. O próximo passo é fazer uma sequência..., mas isto é o próximo programa.
*/
#define pinoBuzzer 10 // se você ligou em outro pino, ajuste aqui
#define LEDAzul 9 // parte positiva no pino 9 e a negativa em série com um resistor de 220 ohms no GND
#define botaoAzul 8 // um lado no pino 8 e o outro no GND
#define LEDVerde 7 // parte positiva no pino 7 e a negativa em série com um resistor de 220 ohms no GND
#define botaoVerde 6 // um lado no pino 6 e o outro no GND
#define LEDAmarelo 5 // parte positiva no pino 5 e a negativa em série com um resistor de 220 ohms no GND
#define botaoAmarelo 4 // um lado no pino 4 e o outro no GND
#define LEDVermelho 3 // parte positiva no pino 3 e a negativa em série com um resistor de 220 ohms no GND
#define botaoVermelho 2 // um lado no pino 2 e o outro no GND

int sorteioAleatorio = 0; // variável para controlar o número aleatório
int velocidade = 500; // usa 500 ms como tempo para controle da velocidade de exibição
int leitura = 4;  // lê o retorno do botão pressionado; se nenhum for pressionado o valor é 4

void setup() {
  pinMode(pinoBuzzer, OUTPUT);  // é uma saída
  pinMode(LEDAzul, OUTPUT); // é uma saída
  pinMode(botaoAzul, INPUT_PULLUP); // entrada que estará alta se não estiver pressionado o botão
  pinMode(LEDVerde, OUTPUT); // é uma saída
  pinMode(botaoVerde, INPUT_PULLUP); // entrada que estará alta se não estiver pressionado o botão  
  pinMode(LEDAmarelo, OUTPUT); // é uma saída
  pinMode(botaoAmarelo, INPUT_PULLUP); // entrada que estará alta se não estiver pressionado o botão 
  pinMode(LEDVermelho, OUTPUT); // é uma saída
  pinMode(botaoVermelho, INPUT_PULLUP); // entrada que estará alta se não estiver pressionado o botão 
  randomSeed(A0); // inicializa o gerador de números aleatórios com uma 'semente' qualquer - ruído na porta A0
}

void loop() {
  sorteioAleatorio = random(4); // gera um número aletaório entre 0 e 3
  switch (sorteioAleatorio){
    case 0:{
        digitalWrite(LEDVermelho, HIGH); // acende o LED vermelho
        tone(pinoBuzzer, 262, 200); // som de 262 Hz
        delay(velocidade);
        digitalWrite(LEDVermelho, LOW); // apaga o LED vermelho
        noTone(pinoBuzzer); // sem som                 
        break;
    }
    case 1:{
        digitalWrite(LEDAmarelo, HIGH); // acende o LED amarelo
        tone(pinoBuzzer, 330, 200); // som de 330 Hz
        delay(velocidade);
        digitalWrite(LEDAmarelo, LOW); // apaga o LED amarelo
        noTone(pinoBuzzer); // sem som                 
        break;
    } 
    case 2:{
        digitalWrite(LEDVerde, HIGH); // acende o LED verde
        tone(pinoBuzzer, 392, 200); // som de 392 Hz
        delay(velocidade);
        digitalWrite(LEDVerde, LOW); // apaga o LED verde
        noTone(pinoBuzzer); // sem som                 
        break;
    }
    case 3:{
        digitalWrite(LEDAzul, HIGH); // acende o LED azul
        tone(pinoBuzzer, 494, 200); // som de 494 Hz
        delay(velocidade);
        digitalWrite(LEDAzul, LOW); // apaga o LED azul
        noTone(pinoBuzzer); // sem som                 
        break;
    }           
  }  
  delay(400); // aguarda 400ms após a apresentação do led
  leitura = qualBotao();  // lê o botão pressionado
  if (sorteioAleatorio == leitura){  // se for igual ao sorteado
    somGanhou();  //  toca o som de ganhou
  }
  else{  //  se não for o mesmo botão ou não for pressionado um botão
    somPerdeu();  //  toca o som de perdeu
  }
  delay(1000);
}

void somPerdeu(){
  //do código da SparkFun
  digitalWrite(LEDAzul, HIGH); // acende o LED azul
  tone(pinoBuzzer, 130, 250);   //E6
  delay(275);
  digitalWrite(LEDAzul, LOW); // apaga o LED azul
  digitalWrite(LEDVermelho, HIGH); // acende o LED vermelho
  tone(pinoBuzzer, 73, 250);   //G6
  delay(275);
  digitalWrite(LEDVermelho, LOW); // apaga o LED amarelo
  digitalWrite(LEDAmarelo, HIGH); // acende o LED amarelo
  tone(pinoBuzzer, 65, 150);   //E7
  delay(175);
  digitalWrite(LEDAmarelo, LOW); // apaga o LED vermelho
  digitalWrite(LEDVerde, HIGH); // acende o LED verde
  tone(pinoBuzzer, 98, 500);   //C7
  delay(500);
  digitalWrite(LEDVerde, LOW); // apaga o LED verde
}

void somGanhou(){
  //do código da SparkFun
  digitalWrite(LEDAzul, HIGH); // acende o LED azul
  tone(pinoBuzzer, 1318, 150);   //E6
  delay(175);
  digitalWrite(LEDAzul, LOW); // apaga o LED azul
  digitalWrite(LEDVermelho, HIGH); // acende o LED vermelho
  tone(pinoBuzzer, 1567, 150);   //G6
  delay(175);
  digitalWrite(LEDVermelho, LOW); // apaga o LED amarelo
  digitalWrite(LEDAmarelo, HIGH); // acende o LED amarelo
  tone(pinoBuzzer, 2637, 150);   //E7
  delay(175);
  digitalWrite(LEDAmarelo, LOW); // apaga o LED vermelho
  digitalWrite(LEDVerde, HIGH); // acende o LED verde
  tone(pinoBuzzer, 2093, 150);   //C7
  delay(175);
  digitalWrite(LEDAzul, HIGH); // acende o LED azul
  digitalWrite(LEDVermelho, HIGH); // acende o LED vermelho
  digitalWrite(LEDAmarelo, HIGH); // acende o LED amarelo
  tone(pinoBuzzer, 2349, 150);   //D7
  delay(175);
  tone(pinoBuzzer, 3135, 500);   //G7
  digitalWrite(LEDAzul, LOW); // apaga o LED azul
  digitalWrite(LEDVermelho, LOW); // apaga o LED amarelo
  digitalWrite(LEDAmarelo, LOW); // apaga o LED vermelho
  digitalWrite(LEDVerde, LOW); // apaga o LED verde
  delay(500);
}

int qualBotao() {
  // deixe o botão pressionado alguns instantes
  if (digitalRead(botaoVermelho) == LOW) {
    return 0;  //  se pressionou o botão vermelho, retorna 0
  } else if (digitalRead(botaoAmarelo) == LOW) {
    return 1;  //  se pressionou o botão amarelo, retorna 1
  } else if (digitalRead(botaoVerde) == LOW) {
    return 2;  //  se pressionou o botão verde, retorna 2
  } else if (digitalRead(botaoAzul) == LOW) {
    return 3;  //  se pressionou o botão azul, retorna 3
  } else {
    return 4; // nenhum botão válido pressionado
  }
}
