#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // Ancho de la pantalla OLED
#define SCREEN_HEIGHT 64 // Altura de la pantalla OLED
#define OLED_RESET -1 // Reset no es necesario para el SSD1306
#define OLED_SDA 19 // Pin SDA
#define OLED_SCL 22 // Pin SCL
#define OLED_ADDRESS 0x3C // Dirección I2C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define LED_ROJO 26
#define LED_VERDE 25
#define LED_AMARILLO 21
#define LED_AZUL 17
#define BTN_ROJO 13
#define BTN_AMARILLO 5
#define BTN_VERDE 12
#define BTN_AZUL 4
#define BUZZER_PIN 15
int secuencia[100]; // Almacena la secuencia de LEDs
int entradaJugador[100]; // Almacena las entradas del jugador
int nivel = 1; // Nivel inicial del juego
unsigned long timeout = 30000000; // Tiempo de espera para el jugador
void setup() {
// Inicializar el OLED
Wire.begin(OLED_SDA, OLED_SCL);
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) {
Serial.println("Error al inicializar el OLED");
for (;;);
}
display.clearDisplay(); // Limpiar pantalla
mostrarMensaje("Iniciando Juego", 2000); // Mostrar por 2 segundos
mostrarNivel();
// Configurar los LEDs
pinMode(LED_ROJO, OUTPUT);
pinMode(LED_VERDE, OUTPUT);
pinMode(LED_AMARILLO, OUTPUT);
pinMode(LED_AZUL, OUTPUT);
// Configurar los botones
pinMode(BTN_ROJO, INPUT_PULLUP);
pinMode(BTN_AMARILLO, INPUT_PULLUP);
pinMode(BTN_VERDE, INPUT_PULLUP);
pinMode(BTN_AZUL, INPUT_PULLUP);
// Configurar el buzzer
pinMode(BUZZER_PIN, OUTPUT);
Serial.begin(115200);
}
void loop() {
juegoSimonDice();
}
void sonido_buzzer(int frequency, int duration) {
tone(BUZZER_PIN, frequency, duration);
delay(duration);
noTone(BUZZER_PIN);
}
void mostrarSecuencia(int nivel) {
for (int i = 0; i < nivel; i++) {
switch (secuencia[i]) {
case 0:
encender_led(LED_ROJO, 1000, 500);
mostrarMensaje("ROJO", 500);
break;
case 1:
encender_led(LED_VERDE, 1200, 500);
mostrarMensaje("VERDE", 500);
break;
case 2:
encender_led(LED_AMARILLO, 1400, 500);
mostrarMensaje("AMARILLO", 500);
break;
case 3:
encender_led(LED_AZUL, 1600, 500);
mostrarMensaje("AZUL", 500);
break;
}
delay(500);
}
}
void encender_led(int led, int frequency, int duration) {
digitalWrite(led, HIGH);
sonido_buzzer(frequency, duration);
digitalWrite(led, LOW);
}
int leerEntradaJugador() {
unsigned long tiempo_inicial = millis();
while (millis() - tiempo_inicial < timeout) {
if (digitalRead(BTN_ROJO) == LOW) {
delay(300);
return 0;
}
if (digitalRead(BTN_VERDE) == LOW) {
delay(300);
return 1;
}
if (digitalRead(BTN_AMARILLO) == LOW) {
delay(300);
return 2;
}
if (digitalRead(BTN_AZUL) == LOW) {
delay(300);
return 3;
}
}
return -1; // Si no se presionó ningún botón
}
bool verificarEntrada(int nivel) {
for (int i = 0; i < nivel; i++) {
int entrada = leerEntradaJugador();
if (entrada == -1) {
mostrarCaritaTriste();
Serial.println("No se presionó ningún botón a tiempo");
return false;
}
entradaJugador[i] = entrada;
if (entradaJugador[i] != secuencia[i]) {
mostrarCaritaTriste();
Serial.println("Error: La entrada no coincide con la secuencia");
return false;
}
}
mostrarCaritaFeliz();
Serial.println("El jugador ingresó la secuencia correctamente");
return true;
}
void reiniciar_juego() {
nivel = 1;
mostrarNivel();
}
void juegoSimonDice() {
secuencia[nivel - 1] = random(0, 4); // Añadir un paso a la secuencia
Serial.print("Secuencia generada: ");
for (int i = 0; i < nivel; i++) {
Serial.print(secuencia[i]);
Serial.print(" ");
}
Serial.println();
mostrarSecuencia(nivel);
if (verificarEntrada(nivel)) {
Serial.println("¡Correcto!");
nivel++;
mostrarNivel(); // Actualizar la pantalla con el nuevo nivel
} else {
Serial.println("¡Fallaste!");
reiniciar_juego();
}
delay(2000); // Espera antes de comenzar el siguiente nivel
}
void mostrarMensaje(const char* mensaje, int tiempo) {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.println(mensaje);
display.display();
delay(tiempo); // Mantener el mensaje en la pantalla el tiempo especificado
}
void mostrarNivel() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("Nivel: ");
display.print(nivel);
display.display();
}
void mostrarCaritaFeliz() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(5, 10);
display.println("Acertaste");
display.setTextSize(1);
display.setCursor(10, 40);
// Dibujar una cara feliz
display.drawCircle(100, 40, 10, SSD1306_WHITE); // Cabeza
display.fillCircle(96, 38, 2, SSD1306_WHITE); // Ojo izquierdo
display.fillCircle(104, 38, 2, SSD1306_WHITE); // Ojo derecho
display.drawLine(95, 43, 97, 45, SSD1306_WHITE); // Boca feliz izquierda
display.drawLine(97, 45, 100, 46, SSD1306_WHITE); // Boca feliz centro
display.drawLine(100, 46, 103, 45, SSD1306_WHITE); // Boca feliz derecha
display.display();
delay(2000); // Mostrar la cara feliz por 2 segundos
}
void mostrarCaritaTriste() {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 5);
display.println("Game Over");
display.setTextSize(1);
display.setCursor(0, 40);
display.print("Puntaje: ");
display.setTextSize(2);
display.setCursor(55, 35);
display.print(nivel - 1);
// Dibujar una cara triste
display.drawCircle(100, 40, 10, SSD1306_WHITE); // Cabeza
display.fillCircle(96, 38, 2, SSD1306_WHITE); // Ojo izquierdo
display.fillCircle(104, 38, 2, SSD1306_WHITE); // Ojo derecho
display.drawLine(95, 44, 105, 44, SSD1306_WHITE); // Boca triste
display.display();
delay(2000); // Mostrar la cara triste por 2 segundos
}