Introducción
¿Recuerdas el clásico juego de Simón Dice? Es el proyecto perfecto para aprender sobre arrays, máquinas de estado y manejo de entrada de usuario en Arduino. En este tutorial, construiremos un juego de Simón Dice completamente funcional usando cuatro LEDs y cuatro pulsadores, todo simulado directamente en tu navegador con Velxio. ¡No necesitas hardware!

Recorrido del Circuito
Veamos los componentes y cómo están conectados.
Componentes
| Componente | ID | Propósito |
|---|---|---|
| Arduino Uno | arduino-uno | El cerebro del juego |
| LED Rojo | led-red | Salida para la secuencia roja |
| LED Verde | led-green | Salida para la secuencia verde |
| LED Azul | led-blue | Salida para la secuencia azul |
| LED Amarillo | led-yellow | Salida para la secuencia amarilla |
| Botón Rojo | button-red | Entrada del usuario para el rojo |
| Botón Verde | button-green | Entrada del usuario para el verde |
| Botón Azul | button-blue | Entrada del usuario para el azul |
| Botón Amarillo | button-yellow | Entrada del usuario para el amarillo |
Cableado
El ánodo (A) de cada LED se conecta a un pin digital del Arduino, y su cátodo (C) va a GND a través de una resistencia limitadora de corriente (simulada internamente). Los botones se cablean con una pata (1.l) a un pin digital y la otra pata (2.l) a GND, usando las resistencias de pull-up internas del Arduino.
- LED Rojo: Pin 8 (cable rojo) al ánodo, cátodo a GND (cable negro).
- LED Verde: Pin 9 (cable verde) al ánodo, cátodo a GND.
- LED Azul: Pin 10 (cable azul) al ánodo, cátodo a GND.
- LED Amarillo: Pin 11 (cable amarillo) al ánodo, cátodo a GND.
- Botón Rojo: Pin 2 (cable azul claro) a 1.l, 2.l a GND.
- Botón Verde: Pin 3 (cable azul claro) a 1.l, 2.l a GND.
- Botón Azul: Pin 4 (cable azul claro) a 1.l, 2.l a GND.
- Botón Amarillo: Pin 5 (cable azul claro) a 1.l, 2.l a GND.
Todas las conexiones a tierra comparten el pin GND del Arduino.
Recorrido del Código
Abre el editor de código en Velxio para ver el sketch completo.

Constantes y Variables
const int LED_PINS[] = {8, 9, 10, 11};
const int BUTTON_PINS[] = {2, 3, 4, 5};
const int NUM_LEDS = 4;
int sequence[100];
int sequenceLength = 0;
int currentStep = 0;
Definimos arrays para los pines de los LEDs y botones, coincidiendo con el cableado. sequence almacena el patrón aleatorio (hasta 100 pasos). sequenceLength rastrea cuántos pasos debe repetir el jugador, y currentStep rastrea el progreso del jugador.
Configuración
void setup() {
Serial.begin(9600);
for (int i = 0; i < NUM_LEDS; i++) {
pinMode(LED_PINS[i], OUTPUT);
pinMode(BUTTON_PINS[i], INPUT_PULLUP);
}
randomSeed(millis());
newGame();
}
Configuramos los pines de los LEDs como salidas y los pines de los botones como entradas con pull-ups internos (así los botones leen LOW cuando se presionan). randomSeed(millis()) asegura una secuencia diferente en cada partida. newGame() inicia la primera ronda.
Lógica del Juego
newGame() reinicia la longitud de la secuencia a 1, añade un paso aleatorio y reproduce la secuencia.
void newGame() {
sequenceLength = 1;
currentStep = 0;
addToSequence();
playSequence();
}
void addToSequence() {
sequence[sequenceLength - 1] = random(0, NUM_LEDS);
}
void playSequence() {
for (int i = 0; i < sequenceLength; i++) {
flashLED(sequence[i]);
delay(500);
}
}
void flashLED(int led) {
digitalWrite(LED_PINS[led], HIGH);
delay(300);
digitalWrite(LED_PINS[led], LOW);
}
playSequence() itera a través de la secuencia almacenada, encendiendo cada LED durante 300ms con un intervalo de 500ms.
Bucle Principal
void loop() {
for (int i = 0; i < NUM_LEDS; i++) {
if (digitalRead(BUTTON_PINS[i]) == LOW) {
flashLED(i);
if (i == sequence[currentStep]) {
currentStep++;
if (currentStep == sequenceLength) {
delay(1000);
sequenceLength++;
currentStep = 0;
addToSequence();
playSequence();
}
} else {
// Botón incorrecto - fin del juego
for (int j = 0; j < 3; j++) {
for (int k = 0; k < NUM_LEDS; k++) {
digitalWrite(LED_PINS[k], HIGH);
}
delay(200);
for (int k = 0; k < NUM_LEDS; k++) {
digitalWrite(LED_PINS[k], LOW);
}
delay(200);
}
newGame();
}
delay(300);
while (digitalRead(BUTTON_PINS[i]) == LOW);
}
}
}
El bucle comprueba continuamente todos los botones. Cuando se presiona un botón (LOW), enciende el LED correspondiente. Si el botón presionado coincide con el paso esperado (sequence[currentStep]), avanzamos. Si el jugador completa la secuencia, añadimos un nuevo paso y reproducimos la secuencia más larga. Si es incorrecto, todos los LEDs parpadean tres veces y comienza una nueva partida.
Conceptos Clave
- Arrays: Usar arrays para almacenar números de pines y la secuencia del juego hace que el código sea escalable y limpio.
- Resistencias de Pull-up Internas:
INPUT_PULLUPelimina resistencias externas; los botones leen LOW cuando se presionan. - Antirrebotes: El
delay(300)y el buclewhile(digitalRead(...)==LOW)proporcionan un antirrebote simple. - Aleatoriedad:
randomSeed(millis())yrandom()generan secuencias impredecibles. - Máquina de Estados: El juego rastrea
currentStepysequenceLengthpara gestionar el progreso.
Errores Comunes y Consejos de Depuración
- ¿Los botones no responden? Verifica que los pines de los botones estén configurados como
INPUT_PULLUPy cableados correctamente (1.l al pin, 2.l a GND). - ¿Los LEDs no se encienden? Verifica que los pines de los LEDs sean
OUTPUTy que las conexiones de ánodo/cátodo sean correctas. - ¿Secuencia demasiado rápida? Ajusta los valores de
delay()enflashLED()yplaySequence(). - ¿El juego se reinicia inesperadamente? Asegúrate de que
randomSeed(millis())se llame solo una vez ensetup(). - Usa el Monitor Serie: Añade sentencias
Serial.println()para depurar los valores de la secuencia.
Extensiones Sugeridas
- Añade un zumbador: Reproduce un tono para cada color de LED.
- Niveles de dificultad: Aumenta la velocidad a medida que crece la secuencia.
- Puntuación máxima: Registra la secuencia más larga alcanzada.
- Multijugador: Alterna turnos entre dos jugadores.
- Retroalimentación visual: Usa diferentes brillos o patrones de LED.
¡Pruébalo Tú Mismo!
¿Listo para jugar? Abre el ejemplo en vivo en Velxio e inicia la simulación. Presiona los botones para repetir la secuencia. ¿Hasta dónde puedes llegar?
¡Feliz construcción!