#include "pitches.h"
/* Constantes: define los números de pin para los LEDs,
botones y altavoz, y también los tonos del juego: */
const uint8_t pinesLED[] = {9, 10, 11, 12};
const uint8_t pinesBoton[] = {2, 3, 4, 5};
#define PIN_ALTAVOZ 8
#define LONGITUD_MAX_JUEGO 100
const int tonosJuego[] = { NOTE_G3, NOTE_C4, NOTE_E4, NOTE_G5};
/* Variables globales: almacenan el estado del juego */
uint8_t secuenciaJuego[LONGITUD_MAX_JUEGO] = {0};
uint8_t indiceJuego = 0;
/**
Configura la placa Arduino e inicializa la comunicación serial
*/
void setup() {
Serial.begin(9600);
for (byte i = 0; i < 4; i++) {
pinMode(pinesLED[i], OUTPUT);
pinMode(pinesBoton[i], INPUT_PULLUP);
}
// La siguiente línea inicializa el generador de números aleatorios.
// Supone que el pin A3 está flotante (desconectado):
randomSeed(analogRead(A0));
}
/**
Enciende el LED dado y reproduce un tono adecuado
*/
void encenderLEDYReproducirTono(byte indiceLED) {
digitalWrite(pinesLED[indiceLED], HIGH);
tone(PIN_ALTAVOZ, tonosJuego[indiceLED]);
delay(300);
digitalWrite(pinesLED[indiceLED], LOW);
noTone(PIN_ALTAVOZ);
}
/**
Reproduce la secuencia actual de notas que el usuario debe repetir
*/
void reproducirSecuencia() {
for (int i = 0; i < indiceJuego; i++) {
byte LEDActual = secuenciaJuego[i];
encenderLEDYReproducirTono(LEDActual);
delay(50);
}
}
/**
Espera hasta que el usuario presione uno de los botones,
y devuelve el índice de ese botón
*/
byte leerBotones() {
while (true) {
for (byte i = 0; i < 4; i++) {
byte pinBoton = pinesBoton[i];
if (digitalRead(pinBoton) == LOW) {
return i;
}
}
delay(1);
}
}
/**
Reproduce la secuencia de fin de juego y muestra la puntuación del juego
*/
void finDeJuego() {
Serial.print("¡Ohh, perdiste! Tu puntuación es ");
Serial.println(indiceJuego - 1);
indiceJuego = 0;
delay(200);
// Reproduce un sonido de "Wah-Wah-Wah-Wah"
tone(PIN_ALTAVOZ, NOTE_DS5);
delay(300);
tone(PIN_ALTAVOZ, NOTE_D5);
delay(300);
tone(PIN_ALTAVOZ, NOTE_CS5);
delay(300);
for (byte i = 0; i < 10; i++) {
for (int tono = -10; tono <= 10; tono++) {
tone(PIN_ALTAVOZ, NOTE_C5 + tono);
delay(5);
}
}
noTone(PIN_ALTAVOZ);
}
/**
Obtiene la entrada del usuario y la compara con la secuencia esperada.
*/
bool verificarSecuenciaUsuario() {
for (int i = 0; i < indiceJuego; i++) {
byte botonEsperado = secuenciaJuego[i];
byte botonActual = leerBotones();
encenderLEDYReproducirTono(botonActual);
if (botonEsperado != botonActual) {
return false;
}
}
return true;
}
/**
Reproduce un sonido de celebración cuando el usuario completa un nivel
*/
void reproducirSonidoNivel() {
tone(PIN_ALTAVOZ, NOTE_C5);
delay(150);
tone(PIN_ALTAVOZ, NOTE_D5);
delay(150);
tone(PIN_ALTAVOZ, NOTE_G5);
delay(150);
noTone(PIN_ALTAVOZ);
}
/**
El bucle principal del juego
*/
void loop() {
// Agrega un color aleatorio al final de la secuencia
secuenciaJuego[indiceJuego] = random(0, 4);
indiceJuego++;
if (indiceJuego >= LONGITUD_MAX_JUEGO) {
indiceJuego = LONGITUD_MAX_JUEGO - 1;
}
reproducirSecuencia();
if (!verificarSecuenciaUsuario()) {
finDeJuego();
}
delay(300);
if (indiceJuego > 0) {
reproducirSonidoNivel();
delay(300);
}
}