Juego Simon Dice
GRUPO 8
Formado por los integrantes:
- Ayma Nogueira Santiago
- Nassir Yassine
- Seone Bernal Jorge
- Introducción
- Material usado
- Código Arduino
- Etapas
- Resultado final
Introducción
Nuestra idea es crear un juego parecido al ya conocido Simon Dice, consistirá en interactuar con una secuencia de luces en distintos modos de juego que comentaremos a continuación.
Hemos pensado en desarrollar dos modos de juego distintos ,uno tirando a la version clasica de un jugador y otra segunda opcion que consistirá en un duelo entre dos jugadores en el cual el primero tendrá que repetir una secuencia y cuando la supere el contrario deberá realizar la suya y el ganador será aquel que complete más secuencias. El turno de cada jugador se mostrará en la pantalla.
Material usado
Material | Precio |
26 cables | Proporcionado por la universidad |
6 resistencias de 0.33 Kohms | Proporcionado por la universidad |
Placa Arduino | Proporcionado por la universidad |
Cable alimentación | Proporcionado por la universidad |
5 pulsadores | 6 |
1 buzzer | Proporcionado por la universidad |
6 leds | Proporcionado por la universidad |
1 caja de madera | 12 |
1 tabla de madera | 2.5 |
Cables y resistencias extras | 2 |
Pantalla I2C | 17 |
Estaño para soldar | 6 |
Pila | 2 |
Silicona para pegar | Casera |
Cinta aislante para aislar los cables | Casera |
Spray de pintura negra | Casero |
Coste TTl | 47,5€ |
Código Arduino
Circuito Tinkercad
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#define LED_RED 11
#define LED_GREEN 9
#define LED_BLUE 7
#define LED_YELLOW 5
#define LED_CORRECT 4
#define LED_WRONG 2
#define BUTTON_RED 12
#define BUTTON_GREEN 10
#define BUTTON_BLUE 8
#define BUTTON_YELLOW 6
#define BUTTON_2P 13
#define BUZZER 3
#define RED_TONE 220
#define GREEN_TONE 262
#define BLUE_TONE 330
#define YELLOW_TONE 392
#define TONE_DURATION 250
LiquidCrystal_I2C lcd(0x27, 16, 2);
int GAME_SPEED = 250;
int GAME_STATUS = 0;
int GAME_SEQUENCE1[100];
int GAME_SEQUENCE2[100];
int GAME_STEP1 = 0;
int GAME_STEP2 = 0;
int READ_STEP1 = 0;
int READ_STEP2 = 0;
int GAME_SEQUENCE[100];
int GAME_STEP = 0;
int READ_STEP = 0;
int currentPlayer = 1;
int NEW_COLOR = 0;
bool imprimir= false;
bool fin= false;
void setup(){
Serial.begin(9600);
randomSeed(analogRead(0));
pinMode(LED_RED, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
pinMode(LED_YELLOW, OUTPUT);
pinMode(BUTTON_RED, INPUT_PULLUP);
pinMode(BUTTON_GREEN, INPUT_PULLUP);
pinMode(BUTTON_BLUE, INPUT_PULLUP);
pinMode(BUTTON_YELLOW, INPUT_PULLUP);
pinMode(BUTTON_2P, INPUT_PULLUP);
pinMode(BUZZER, OUTPUT);
lcd.begin();
lcd.backlight();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Elija modo de juego");
}
void loop() {
int buttonValue = readButtons();
if (!imprimir){
lcd.clear(); // Limpiar la pantalla LCD
lcd.setCursor(0, 0); // Establecer el cursor en la primera fila, primera columna
lcd.print("Elija modo de juego");
// Mostrar el modo de juego en la segunda fila
lcd.setCursor(0, 1);
lcd.print("1P o 2P");
imprimir = true;
}
if (buttonValue==5){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Modo seleccionado:");
lcd.setCursor(0, 1);
lcd.print("Dos jugadores");
twoPlayerMode();
finDelJuego2Jugadores();
}
else{
if (buttonValue==1){
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Modo seleccionado:");
lcd.setCursor(0, 1);
lcd.print("Un jugador");
modo1Player();
finDelJuego1Jugador();
}
}
}
void modo1Player(){
while (true) {
switch (GAME_STATUS) {
case 0:
// iniciar juego nuevo
READ_STEP = 0;
GAME_STEP = 0;
// Crear secuencia nueva
for(int i=0; i<100; i++){
GAME_SEQUENCE[i] = random(4) + 1;
}
// Go to next game state; show led sequence
GAME_STATUS = 1;
break;
case 1:
// play a step of our sequence
for(int i=0; i<=GAME_STEP; i++){
Serial.print("Set LED");
Serial.println(GAME_SEQUENCE[i]);
delay(GAME_SPEED*2);
setLED(GAME_SEQUENCE[i]);
playTone(GAME_SEQUENCE[i]);
delay(GAME_SPEED);
setLEDs(false,false,false,false);
}
// Leer combinacion del jugador
GAME_STATUS = 2;
break;
case 2:
int button_value = readButtons();
if(button_value > 0){
if(button_value == GAME_SEQUENCE[READ_STEP]){
// Correcto
setLED(button_value);
playTone(button_value);
digitalWrite(LED_CORRECT, HIGH);
delay(GAME_SPEED);
setLEDs(false,false,false,false);
digitalWrite(LED_CORRECT, LOW);
Serial.println("Correct!");
if(READ_STEP == GAME_STEP){
// reset read step
READ_STEP = 0;
// Go to next game step
GAME_STEP++;
// Go to playback sequence mode of our game
GAME_STATUS = 1;
// Light all LEDs to indicate next sequence
setLEDs(true,true,true,true);
delay(GAME_SPEED);
setLEDs(false,false,false,false);
}else{
READ_STEP++;
}
delay(10);
}else{
// wrong value!
// Go to game over mode
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Se acabo");
// Red RGB
digitalWrite(LED_WRONG, HIGH);
// Play Pwa Pwa Pwa
tone(BUZZER, 98, TONE_DURATION);
delay(TONE_DURATION);
tone(BUZZER, 93, TONE_DURATION);
delay(TONE_DURATION);
tone(BUZZER, 87, TONE_DURATION);
delay(TONE_DURATION);
delay(GAME_SPEED);
return;
}
}
}
}
}
void twoPlayerMode() {
while (true) {
switch (GAME_STATUS) {
case 0: // reset game
READ_STEP1 = 0;
READ_STEP2 = 0;
GAME_STEP1 = 0;
GAME_STEP2 = 0;
for (int i = 0; i < 50; i++) {
GAME_SEQUENCE1[i] = random(4) + 1;
GAME_SEQUENCE2[i] = random(4) + 1;
}
GAME_STATUS = 1;
Serial.println("Turno del jugador " + String(currentPlayer));
break;
case 1: // Secuencia
for (int i = 0; i <= (currentPlayer == 1 ? GAME_STEP1 : GAME_STEP2); i++) {
Serial.print("Encender LED");
Serial.println(currentPlayer == 1 ? GAME_SEQUENCE1[i] : GAME_SEQUENCE2[i]);
setLED(currentPlayer == 1 ? GAME_SEQUENCE1[i] : GAME_SEQUENCE2[i]);
playTone(currentPlayer == 1 ? GAME_SEQUENCE1[i] : GAME_SEQUENCE2[i]);
delay(GAME_SPEED*2);
setLEDs(false, false, false, false);
}
GAME_STATUS = 2;
break;
case 2: // Insertar secuencia del jugador
int buttonValue = readButtons();
if (buttonValue > 0) {
if (buttonValue == (currentPlayer == 1 ? GAME_SEQUENCE1[READ_STEP1] : GAME_SEQUENCE2[READ_STEP2])) {
setLED(buttonValue);
playTone(buttonValue);
digitalWrite(LED_CORRECT, HIGH);
delay(GAME_SPEED);
setLEDs(false, false, false, false);
digitalWrite(LED_CORRECT, LOW);
if ((currentPlayer == 1 ? READ_STEP1 : READ_STEP2) == (currentPlayer == 1 ? GAME_STEP1 : GAME_STEP2)) {
currentPlayer = 3 - currentPlayer; // switch player
if (currentPlayer == 1) {
READ_STEP1 = 0;
GAME_STEP1++;
} else {
READ_STEP2 = 0;
GAME_STEP2++;
}
GAME_STATUS = 1;
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Turno del j " + String(currentPlayer));
setLEDs(true, true, true, true);
delay(GAME_SPEED);
setLEDs(false, false, false, false);
} else {
if (currentPlayer == 1) {
READ_STEP1++;
} else {
READ_STEP2++;
}
}
delay(10);
}
return;
}
}
}
}
void finDelJuego2Jugadores() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Fin del juego");
lcd.setCursor(0, 1);
lcd.print("El j " + String(3 - currentPlayer) + " gana!");
digitalWrite(LED_WRONG, HIGH);
tone(BUZZER, 523, TONE_DURATION);
delay(TONE_DURATION);
tone(BUZZER, 784, TONE_DURATION);
delay(TONE_DURATION);
delay(GAME_SPEED);
Serial.println("Presione cualquier botón para volver a la selección de modo de juego.");
while (readButtons() == 0) {
delay(100);
}
GAME_STATUS = 0;
currentPlayer = 1;
imprimir = false;
}
void finDelJuego1Jugador() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Fin del juego");
lcd.setCursor(0, 1);
lcd.print("Presione cualquier boton");
tone(BUZZER, 523, TONE_DURATION);
delay(TONE_DURATION);
tone(BUZZER, 784, TONE_DURATION);
delay(TONE_DURATION);
delay(GAME_SPEED);
while (readButtons() == 0) {
delay(100);
}
// Reiniciar variables
GAME_STATUS = 0;
imprimir = false;
}
void setLED(int id){
switch(id){
case 0:
setLEDs(false,false,false,false);
break;
case 1:
setLEDs(true,false,false,false);
break;
case 2:
setLEDs(false,true,false,false);
break;
case 3:
setLEDs(false,false,true,false);
break;
case 4:
setLEDs(false,false,false,true);
break;
}
}
void playTone(int id){
switch(id){
case 0:
noTone(BUZZER);
break;
case 1:
tone(BUZZER, RED_TONE, TONE_DURATION);
break;
case 2:
tone(BUZZER, GREEN_TONE, TONE_DURATION);
break;
case 3:
tone(BUZZER, BLUE_TONE, TONE_DURATION);
break;
case 4:
tone(BUZZER, YELLOW_TONE, TONE_DURATION);
break;
}
}
void setLEDs(boolean red, boolean green, boolean blue, int yellow ){
if (red) digitalWrite(LED_RED, HIGH);
else digitalWrite(LED_RED, LOW);
if (green) digitalWrite(LED_GREEN, HIGH);
else digitalWrite(LED_GREEN, LOW);
if (blue) digitalWrite(LED_BLUE, HIGH);
else digitalWrite(LED_BLUE, LOW);
if (yellow) digitalWrite(LED_YELLOW, HIGH);
else digitalWrite(LED_YELLOW, LOW);
}
int readButtons(void){
if (digitalRead(BUTTON_RED) == 0) return 1;
else if (digitalRead(BUTTON_GREEN) == 0) return 2;
else if (digitalRead(BUTTON_BLUE) == 0) return 3;
else if (digitalRead(BUTTON_YELLOW) == 0) return 4;
else if (digitalRead(BUTTON_2P) == 0) return 5;
return 0;
}
El proyecto utilzia una placa Arduino, un módulo LCD I2C, 6 LEDs de colores, botones y un buzzer. Utilizaremos la biblioteca
LiquidCrystal_I2C para controlar el LCD y la biblioteca Tone para generar sonidos.
El juego tiene un modo de juego para uno y dos jugadores. Al iniciar
el juego, se muestra en el LCD la opción para elegir el modo de juego.
El jugador puede seleccionar el modo presionando los botones
correspondientes. En el modo de un jugador, el Arduino generará una
secuencia de colores aleatoria y cada fase de la secuencia se guardara
en un array(GAME_SEQUENCE[i]) al cual se le ira añadiendo una
iteracion cada vez que el jugador repita la secuencia correctamente.
Para el funcionamiento de todo el proceso, hemos optado por dividir
cada fase de la iteracion en un case donde una variable ira pasando
entre las distintas opciones de este a medida que el juego avance
(GAME_STATUS) el case 0 sera para inicializar las variables GAME_STEP
Y READ_STEP que seran las que confirmaran si la secuencia pulsada por
el jugador coincide con la secuencia establecida. De ahi pasara al
case 1 donde se emitira la secuencia con el color nuevo aleatorio y el
case 2 el cual se dividira en un if donde volvera a repetir el proceso
de añadir un color nuevo si el jugador ejecuta la secuencia
correctamente y en una salida hacia el lcd mostrando que el juego se
acabo y mostrando por el buzzer una melodia indicando que el juego se
ha acabado.
En el modo de dos jugadores, se asignará una secuencia a cada jugador,
alternando turnos. El ganador será el jugador que reproduzca
correctamente la secuencia más larga. El funcionamiento es similar
pero manejando dos secuencias de manera simultanea.
Etapas
Antes de explicar el circuito y como se ha montado ,vamos a detallar el producto final y como sera la caja.
La idea es transformar una caja grande en un producto final más adecuado para nuestras necesidades. Consiste en cortar la caja, añadir una tapa y dividirla en dos plantas. En la primera planta se ubicará el Arduino y la pila, con la consideración de que la pila no debe ser demasiado grande. La segunda planta estará diseñada para la placa de inserción y otros componentes, sobresaliendo por encima de la tapa para permitir el acceso fácil. Además, se podrán retirar los componentes para modificarlos o verificar conexiones, facilitando el desmontaje. Se perforarán agujeros para los cables hacia el ordenador, las bombillas, los botones y otros componentes necesarios. Se considerará la estética final con embellecedores para las bombillas y botones, así como pintura y otros detalles estéticos. Tendra un design parecido a la foto:
Como se puede ver los agujeros sera donde saldran los cables para el ordenador como ya esta mencionado arriba .
Ahora vamos a detallar el proceso un poco del montaje de nuestro circuito con fotos.
Primero enchufar los cuatro LEDs, esos de colores, son los LEDs que se van a iluminar con la secuencia aleatoria generada con el código y tal, y luego con los botones o el botón respectivo a cada LED, los botones son los cuatro puestos en el medio .
Como se puede tenemos cables conectados entre los LEDs y lo botones con unas resistencias obligatorias que conecta todo a la placa arduino y con la segunda foto vamos a ver la otra mitad.
Ahora con esta foto podemos ver que la segunda parte enseña la funciona de acertar o no con los leds verde y rojo ,siendo en paralelo correcto y falso.
Y tambien podemos ver que tenemos el buzzer que hace un sonido.
Esta foto enseña el ultimo montaje que tiene conectado la placa arduino con nuestras dos placas y pantalla con los cables ya soldados listos para ser encajado en nuestra caja.
Esta foto enseña nuestra primera «Planta» donde hemos puesto la placa arduino junto con los cables que llevan al juego que esta ubicado en nuestra segunda «Planta» ,lo hemos diseñado asi para no tener un juego con bastantes cables y una vista poco agradable.
Esta foto enseña nuestra segunda «Planta» donde hemos puesto basicamente el juego mas limpio y sin los cables que ya estan abajo y esto es basicamente el resultado final fuera de la caja de madera que sera pintada.
Resultado final
Esta es la caja con el juego ya he hecho
Como el video pesa mucho os dejamos el link:
https://drive.google.com/file/d/1brSCh1yG6pH10KFqZwXDD5o0B0E8bpAQ/view?usp=drive_link
.