// MENU MIXTO
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// Iniciar la librería
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Pulsadores
const int btnOK = 2; // Pulsador OK
const int btnUp = 3; // Pulsador para subir
const int btnDown = 4; // Pulsador para bajar
// === CONFIGURACIÓN DE PREGUNTAS ===
// MODO 1: Solo Verdadero/Falso
bool preguntasVF[] = {
true, // P1: V
false, // P2: F
true, // P3: V
false // P4: F
// Se pueden agregar más preguntas
};
// Se calcula y obtiene la cantidad de preguntas
int totalVF = sizeof(preguntasVF) / sizeof(preguntasVF[0]);
// MODO 2: Solo Múltiple (0=A, 1=B, 2=C)
int preguntasMultiple[] = {
1, // P1: B
0, // P2: A
2, // P3: C
1 // P4: B
// Se pueden agregar más preguntas
};
// Se calcula y obtiene la cantidad de preguntas
int totalMultiple = sizeof(preguntasMultiple) / sizeof(preguntasMultiple[0]);
// MODO 3: Mixto
struct PreguntaMixta {
int tipo; // 0 = V/F, 1 = Múltiple
int respuesta; // V/F: 0=Falso,1=Verdadero | Múltiple: 0=A,1=B,2=C
};
// Define el tipo y valor de respuesta de cada pregunta en el orden que serán mostradas | {tipo, respuesta}
PreguntaMixta preguntasMixtas[] = {
{0, 1}, // P1: V/F - Verdadero
{1, 2}, // P2: Múltiple - C
{0, 0}, // P3: V/F - Falso
{1, 1}, // P4: Múltiple - B
// Se pueden cargas más preguntas
};
// Se calcula y obtiene la cantidad de preguntas
int totalMixto = sizeof(preguntasMixtas) / sizeof(preguntasMixtas[0]);
// === VARIABLES DEL SISTEMA ===
enum EstadoSistema {
MENU_PRINCIPAL,
JUGANDO,
RESULTADO_PREGUNTA,
RESULTADO_FINAL
};
EstadoSistema estadoActual = MENU_PRINCIPAL;
int modoJuego = 0; // 0=V/F, 1=Múltiple, 2=Mixto
int opcionMenu = 0; // Opción seleccionada en el menú
int opcionPregunta = 0; // Opción seleccionada en la pregunta
int preguntaActual = 0;
int puntaje = 0;
bool esperandoInput = true;
// Opciones de menú principal
String menuPrincipal[] = {"Verdadero/Falso", "Opcion Multiple", "Modo Mixto"};
int totalMenus = 3;
// Opciones de respuesta
String opcionesVF[] = {"Verdadero", "Falso"};
String opcionesMultiple[] = {"Opcion A", "Opcion B", "Opcion C"};
// Carácter de flecha
byte flecha[] = {B00000,B00100,B00110,B11111,B00110,B00100,B00000,B00000};
// Prototipos de funciones
void mostrarBienvenida();
void mostrarMenuPrincipal();
void mostrarInfoJuego();
void mostrarPreguntaActual();
void mostrarOpcionesPregunta(int tipo);
void mostrarCorrecto();
void mostrarIncorrecto();
void mostrarResultadoFinal();
void manejarMenuPrincipal();
void manejarJuego();
void manejarResultadoPregunta();
void manejarResultadoFinal();
void iniciarJuego();
void reiniciarSistema();
void procesarRespuesta();
void siguientePregunta();
int obtenerTipoPreguntaActual();
int obtenerTotalPreguntas();
int obtenerRespuestaCorrecta();
void setup() {
pinMode(btnUp, INPUT_PULLUP);
pinMode(btnDown, INPUT_PULLUP);
pinMode(btnOK, INPUT_PULLUP);
lcd.init();
lcd.backlight();
lcd.createChar(0, flecha);
mostrarBienvenida();
delay(3000);
mostrarMenuPrincipal();
}
void loop() {
switch (estadoActual) {
case MENU_PRINCIPAL:
manejarMenuPrincipal();
break;
case JUGANDO:
manejarJuego();
break;
case RESULTADO_PREGUNTA:
manejarResultadoPregunta();
break;
case RESULTADO_FINAL:
manejarResultadoFinal();
break;
}
}
// ===== MANEJO DEL MENÚ PRINCIPAL =====
void manejarMenuPrincipal() {
if (digitalRead(btnUp) == LOW) {
delay(200);
opcionMenu--;
if (opcionMenu < 0) opcionMenu = totalMenus - 1;
mostrarMenuPrincipal();
}
if (digitalRead(btnDown) == LOW) {
delay(200);
opcionMenu++;
if (opcionMenu >= totalMenus) opcionMenu = 0;
mostrarMenuPrincipal();
}
if (digitalRead(btnOK) == LOW) {
delay(200);
iniciarJuego();
}
}
// ===== MANEJO DEL JUEGO =====
void manejarJuego() {
if (!esperandoInput) return;
// Determinar tipo de pregunta actual
int tipoPregunta = obtenerTipoPreguntaActual();
int maxOpciones = (tipoPregunta == 0) ? 2 : 3; // V/F = 2, Múltiple = 3
if (digitalRead(btnUp) == LOW) {
delay(200);
opcionPregunta--;
if (opcionPregunta < 0) opcionPregunta = maxOpciones - 1;
mostrarOpcionesPregunta(tipoPregunta);
}
if (digitalRead(btnDown) == LOW) {
delay(200);
opcionPregunta++;
if (opcionPregunta >= maxOpciones) opcionPregunta = 0;
mostrarOpcionesPregunta(tipoPregunta);
}
if (digitalRead(btnOK) == LOW) {
delay(200);
procesarRespuesta();
}
}
// ===== MANEJO DE RESULTADO DE PREGUNTA =====
void manejarResultadoPregunta() {
if (digitalRead(btnOK) == LOW) {
delay(200);
siguientePregunta();
}
}
// ===== MANEJO DE RESULTADO FINAL =====
void manejarResultadoFinal() {
if (digitalRead(btnOK) == LOW) {
delay(200);
reiniciarSistema();
}
}
// ===== FUNCIONES DEL DISPLAY =====
void mostrarBienvenida() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("QUIZ ARDUINO");
lcd.setCursor(0, 1);
lcd.print("Cargando...");
}
void mostrarMenuPrincipal() {
lcd.clear();
// Mostrar opción actual y siguiente (si existe)
lcd.setCursor(0, 0);
lcd.write(byte(0));
lcd.setCursor(1, 0);
lcd.print(menuPrincipal[opcionMenu]);
// Mostrar siguiente opción si existe
if (opcionMenu + 1 < totalMenus) {
lcd.setCursor(1, 1);
lcd.print(menuPrincipal[opcionMenu + 1]);
} else if (opcionMenu == totalMenus - 1) {
// Si estamos en la última, mostrar la primera
lcd.setCursor(1, 1);
lcd.print(menuPrincipal[0]);
}
}
void mostrarInfoJuego() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Modo: ");
switch (modoJuego)
{
case 0:
lcd.print("V/F");
break;
case 1:
lcd.print("Multiple");
break;
case 2:
lcd.print("Mixto");
break;
}
lcd.setCursor(0, 1);
lcd.print("Total: ");
lcd.print(obtenerTotalPreguntas());
lcd.print(" pregs.");
}
void mostrarPreguntaActual() {
lcd.clear();
// Mostrar número de pregunta y puntaje
lcd.setCursor(0, 0);
lcd.print("P");
lcd.print(preguntaActual + 1);
lcd.print("/");
lcd.print(obtenerTotalPreguntas());
lcd.print(" Pts:");
lcd.print(puntaje);
delay(2000);
// Mostrar opciones según el tipo de pregunta
int tipoPregunta = obtenerTipoPreguntaActual();
mostrarOpcionesPregunta(tipoPregunta);
}
void mostrarOpcionesPregunta(int tipo) {
lcd.clear();
if (tipo == 0) { // V/F
if (opcionPregunta == 0) {
lcd.setCursor(0, 0);
lcd.write(byte(0));
lcd.print(" ");
lcd.print(opcionesVF[0]);
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.print(opcionesVF[1]);
} else {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.print(opcionesVF[0]);
lcd.setCursor(0, 1);
lcd.write(byte(0));
lcd.print(" ");
lcd.print(opcionesVF[1]);
}
} else { // Múltiple
if (opcionPregunta == 0) {
lcd.setCursor(0, 0);
lcd.write(byte(0));
lcd.print(" ");
lcd.print(opcionesMultiple[0]);
lcd.setCursor(0, 1);
lcd.print(" ");
lcd.print(opcionesMultiple[1]);
} else if (opcionPregunta == 1) {
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.print(opcionesMultiple[0]);
lcd.setCursor(0, 1);
lcd.write(byte(0));
lcd.print(" ");
lcd.print(opcionesMultiple[1]);
} else { // opcionPregunta == 2
lcd.setCursor(0, 0);
lcd.print(" ");
lcd.print(opcionesMultiple[1]);
lcd.setCursor(0, 1);
lcd.write(byte(0));
lcd.print(" ");
lcd.print(opcionesMultiple[2]);
}
}
}
// ===== LÓGICA DEL JUEGO =====
void iniciarJuego() {
modoJuego = opcionMenu;
preguntaActual = 0;
puntaje = 0;
opcionPregunta = 0;
mostrarInfoJuego();
delay(2000);
estadoActual = JUGANDO;
esperandoInput = true;
mostrarPreguntaActual();
}
void procesarRespuesta() {
bool esCorrecta = false;
int respuestaCorrecta = obtenerRespuestaCorrecta();
// Evaluar según el tipo de pregunta
int tipoPregunta = obtenerTipoPreguntaActual();
if (tipoPregunta == 0) { // V/F
esCorrecta = (opcionPregunta == respuestaCorrecta);
} else { // Múltiple
esCorrecta = (opcionPregunta == respuestaCorrecta);
}
if (esCorrecta) {
puntaje++;
mostrarCorrecto();
} else {
mostrarIncorrecto();
}
esperandoInput = false;
estadoActual = RESULTADO_PREGUNTA;
}
void mostrarCorrecto() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("CORRECTO!");
lcd.setCursor(0, 1);
lcd.print("Puntaje: ");
lcd.print(puntaje);
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Presiona OK");
lcd.setCursor(0, 1);
lcd.print("para continuar");
}
void mostrarIncorrecto() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("INCORRECTO");
lcd.setCursor(0, 1);
/*
// Descomentar para dar retroalimentación mostrando la opción correcta
int tipoPregunta = obtenerTipoPreguntaActual();
int respuestaCorrecta = obtenerRespuestaCorrecta();
if (tipoPregunta == 1) { // Múltiple
lcd.print("Era: Opcion ");
lcd.print((char)('A' + respuestaCorrecta));
}
*/
delay(3000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Presiona OK");
lcd.setCursor(0, 1);
lcd.print("para continuar");
}
void siguientePregunta() {
preguntaActual++;
if (preguntaActual >= obtenerTotalPreguntas()) {
mostrarResultadoFinal();
estadoActual = RESULTADO_FINAL;
} else {
opcionPregunta = 0;
esperandoInput = true;
estadoActual = JUGANDO;
mostrarPreguntaActual();
}
}
void mostrarResultadoFinal() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("QUIZ TERMINADO");
lcd.setCursor(0, 1);
lcd.print("Puntos: ");
lcd.print(puntaje);
lcd.print("/");
lcd.print(obtenerTotalPreguntas());
delay(3000);
int porcentaje = (puntaje * 100) / obtenerTotalPreguntas();
lcd.clear();
lcd.setCursor(0, 0);
if (porcentaje >= 80) {
lcd.print("EXCELENTE!");
} else if (porcentaje >= 60) {
lcd.print("BIEN HECHO!");
} else {
lcd.print("DEBES PRACTICAR!");
}
lcd.setCursor(0, 1);
lcd.print("Aciertos: ");
lcd.print(porcentaje);
lcd.print("%");
delay(3000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("OK para volver");
lcd.setCursor(0, 1);
lcd.print("al menu");
}
// ===== FUNCIONES AUXILIARES =====
int obtenerTotalPreguntas() {
switch (modoJuego) {
case 0: return totalVF;
case 1: return totalMultiple;
case 2: return totalMixto;
default: return 0;
}
}
int obtenerTipoPreguntaActual() {
switch (modoJuego) {
case 0: return 0; // Solo V/F
case 1: return 1; // Solo Múltiple
case 2: return preguntasMixtas[preguntaActual].tipo; // Modo Mixto
default: return 0;
}
}
int obtenerRespuestaCorrecta() {
switch (modoJuego) {
case 0: return preguntasVF[preguntaActual] ? 1 : 0;
case 1: return preguntasMultiple[preguntaActual];
case 2: return preguntasMixtas[preguntaActual].respuesta;
default: return 0;
}
}
void reiniciarSistema() {
estadoActual = MENU_PRINCIPAL;
opcionMenu = 0;
preguntaActual = 0;
puntaje = 0;
opcionPregunta = 0;
esperandoInput = true;
mostrarMenuPrincipal();
}OK
Up
Down