#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Dirección I2C 0x27, 16 columnas y 2 filas
int boton_si = 6;
int boton_no = 7;
String preguntas[] = {
"El boro es B?",
"El agua es HO2?",
"Es el oxigeno O?",
"El hierro es Fe?",
"Es el carbono C 222222 3333333333 22 AAAA?",
"El cloro es Cl?",
"El azufre es S?",
"Es el sodio Na?",
"El oro Au?",
"Es el calcio H RTTTTTTTTTTTTT 222222222 ?",
"Hidrogeno es H?",
"Nitrogeno es N?",
"Potasio es Po?",
"Mercurio es Hg?",
"Litio es Li?"
};
bool respuestas[] = {true, false, true, true, true, true, true, true, true, false, true, true, false, false, true};
bool preguntas_usadas[sizeof(preguntas) / sizeof(preguntas[0])] = {false}; // Lista para controlar las preguntas usadas
int pregunta_actual = 0, aciertos = 0, errores = 0, preguntas_restantes = sizeof(preguntas) / sizeof(preguntas[0]);
unsigned long lastButtonPress = 0;
const unsigned long debounceDelay = 50; // Anti-rebote en milisegundos
bool preguntaMostrada = false;
const int textoVentana = 16; // Número de caracteres visibles en la pantalla
const unsigned long desplazamientoIntervalo = 200; // Intervalo para el desplazamiento en milisegundos
unsigned long desplazamientoStart = 0;
int offset = 0;
void setup() {
lcd.init();
lcd.backlight();
pinMode(boton_si, INPUT_PULLUP);
pinMode(boton_no, INPUT_PULLUP);
iniciarJuego();
}
void loop() {
unsigned long currentTime = millis();
// Manejo de botones con debounce
if (digitalRead(boton_si) == LOW || digitalRead(boton_no) == LOW) {
if (currentTime - lastButtonPress > debounceDelay) {
lastButtonPress = currentTime;
if (preguntaMostrada) {
bool respuestaSi = digitalRead(boton_si) == LOW;
procesarRespuesta(respuestaSi);
mostrarSiguientePregunta();
}
}
}
// Desplazamiento del texto
if (preguntaMostrada && preguntas[pregunta_actual].length() > textoVentana) {
desplazarPregunta();
} else if (preguntaMostrada) {
mostrarPreguntaCorta(); // Mostrar pregunta corta si el texto es más corto que el área visible
}
}
void iniciarJuego() {
lcd.clear();
lcd.print("Bienvenido!");
delay(2000);
reiniciarEstado();
mostrarSiguientePregunta();
}
void reiniciarEstado() {
for (int i = 0; i < sizeof(preguntas_usadas) / sizeof(preguntas_usadas[0]); i++) {
preguntas_usadas[i] = false;
}
pregunta_actual = 0;
aciertos = 0;
errores = 0;
preguntas_restantes = sizeof(preguntas) / sizeof(preguntas[0]);
}
void mostrarSiguientePregunta() {
if (preguntas_restantes > 0) {
int index;
do {
index = random(sizeof(preguntas) / sizeof(preguntas[0]));
} while (preguntas_usadas[index]);
preguntas_usadas[index] = true;
pregunta_actual = index;
lcd.clear();
preguntaMostrada = true;
desplazamientoStart = millis(); // Iniciar desplazamiento
offset = 0; // Reiniciar el desplazamiento
} else {
mostrarResultados();
}
}
void desplazarPregunta() {
String pregunta = preguntas[pregunta_actual];
int preguntaLength = pregunta.length();
if (millis() - desplazamientoStart >= desplazamientoIntervalo) {
desplazamientoStart = millis();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(pregunta.substring(offset, min(offset + textoVentana, preguntaLength)));
offset++;
if (offset >= preguntaLength) {
offset = 0; // Reiniciar el desplazamiento
}
// Mostrar los botones solo una vez por ciclo de desplazamiento
lcd.setCursor(0, 1);
lcd.print("Si No");
}
}
void mostrarPreguntaCorta() {
// Mostrar la pregunta completa si es más corta que el área visible
String pregunta = preguntas[pregunta_actual];
lcd.setCursor(0, 0);
lcd.print(pregunta);
// Asegurarse de que los botones estén siempre visibles
lcd.setCursor(0, 1);
lcd.print("Si No");
}
void procesarRespuesta(bool respuestaSi) {
if (respuestaSi && respuestas[pregunta_actual]) aciertos++;
else if (!respuestaSi && !respuestas[pregunta_actual]) aciertos++;
else errores++;
preguntas_restantes--;
}
void mostrarResultados() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Aciertos: ");
lcd.print(aciertos);
lcd.setCursor(0, 1);
lcd.print("Errores: ");
lcd.print(errores);
delay(3000);
iniciarJuego(); // Reiniciar el juego
}