Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
- Committer:
- gonzaloMS
- Date:
- 2019-06-22
- Revision:
- 1:2f8c5940c425
- Parent:
- 0:d644ac0f96b0
- Child:
- 2:e7e06ee2d6b0
File content as of revision 1:2f8c5940c425:
//Tenemos 2 displays en paralelo, y manejamos cada uno por separado a través de sus habilitaciones (con transistores al corte y saturación)
#include "mbed.h"
//Creo los Estados para las Máquinas de Estados
enum{INICIO,GENERA1,GENERA2,GENERA3,FIN,BEGINNING,CHECK1,CHECK2,CHECK3,ENDGAME,WINGAME};
DigitalIn E1r(PTC12);
DigitalIn E2r(PTC13); // 0 1 2 3 (Entradas reales/físicas)
DigitalIn E3r(PTC3); // E1r E2r E3r E4r
DigitalIn E4r(PTC4);
DigitalIn pulsadorReset(PTE29); //Pulsador externo para hacer reset, normalmente 1
DigitalOut ledWin(LED2); //Configuro Led RGB en verde para cuando ganás el juego
DigitalOut ledLost(LED1); //Configuro Led RGB en rojo para cuando perdés el juego
BusOut Displays(D2,D3,D4,D5,A3,A2,A1,A0,D8); //Salidas en este orden: HAB.2 (UNIDADES) - HAB.1 (DECENAS) - G - F - E - D - C - B - A respectivamente //
int E1=0;
int E2=0; //Variables donde se van a guardar los estados de las entradas reales (Ej.: E1r en E1)
int E3=0;
int E4=0;
//Cada número del 0 al 9 en binario dentro de un vector, para después asignarlo al BusOut (El menos significativo acá es el más significativo del BusOut)
int numerosD[]={0b111111010,0b011000010,0b110110110,0b111100110,0b011001110,0b101101110,0b101111110,0b111000010,0b111111110,0b111001110}; //0-9 Decenas
int numerosU[]={0b111111001,0b011000001,0b110110101,0b111100101,0b011001101,0b101101101,0b101111101,0b111000001,0b111111101,0b111001101}; //0-9 Unidades
//Inicializo Tickers que ejecutan una función cada cierto tiempo en segundos
Ticker Tempo;
Ticker Display;
Ticker parpadeoTicker;
//Funciones de cada Ticker respectivamente
void descuentaTiempo(); //Cada 1 seg le resta 1 a una variable que lleva el tiempo. Al llegar a 0, indica a través de una variable que el jugador perdió
void visualizacionDisplays(); //Genera Unidades y Decenas en base al tiempo. Maneja el BusOut que va a las patas de los displays para mostrar el tiempo
void parpadeoFuncion(); //Hace que parpadee el led rojo cuando perdés y que parpadeen los segmentos de los displays cuando termine el juego
//Funciones de las Máquinas de estados
void generacion(); //Genera secuencia
void chequeo(); //Chequea si el estado de las entradas concuerda con la secuencia generada
//Funciones extra
void winReaccion(); //Prende el led verde si ganás (desconectas todos los cables en el orden correcto)
void reset(); //Si presionás el botón reset reinicia las variables necesarias, hace que las máquinas de estados vuelvan a empezar por su estado default y apaga los leds
//Varible que se encarga de decidir cuándo mostrar las decenas y cuándo las unidades
int switcheo=0;
//Variables relacionadas con el tiempo que se muestra en los displays
int tiempo=60; //Guarda el tiempo en segundos
int Decenas; //Guarda solamente la unidad del tiempo
int Unidades; //Guarda solamente la decena del tiempo
//Variables en las que se guarda el estado de las máquinas de estados
int secuencia; //Para la máquina de estados de generación de secuencia
int check; //Para la máquina de estados de chequeo de las entradas
//Variables que guardan cuántas de las entradas concuerdan con la secuencia generada
int cantIgual=0; //Para cuando se corta un cable (1 entrada en 1, las otras 3 en 0)
int cantIgual2=0; //Para cuando se corta el segundo cable (2 entradas en 1, las otras 2 en 0)
int cantIgual3=0; //Para cuando se corta el tercer cable (3 entradas en 1, la otra en 0)
//Variables donde se guardan valores random que van a determinar cómo queda la secuencia
int genSec1; //primer cable a cortar
int genSec2; //segundo cable a cortar
int genSec3; //tercer cable a cortar
//Vectores que guardan cada parte de la secuencia (que empieza en 0000 y termina en 1111)
int vecSec[]={0,0,0,0}; //Primer cable a cortar
int vecSec2[]={0,0,0,0}; //Segundo cable a cortar
int vecSec3[]={0,0,0,0}; //Tercer cable a cortar
int vecSec4[]={0,0,0,0}; //Cuarto cable a cortar
//Vector que guarda el estado de las entradas para compararlo con los vectores que guardan la secuencia
int vecChq[]={0,0,0,0};
//Variable que se queda en 0 si no tiene que parpadear el display y que alterna entre 1 y 0 constantemente en el caso contrario (0 muestra el tiempo y 1 apaga el display)
int parpadeoDisplay=0;
//Variables que informan si el jugador perdió o ganó el juego
int fin=0;
int win=0;
//Variables para los "for" del programa
int i;
int y;
int k;
int main() {
//Apago los Leds
ledWin=1;
ledLost=1;
//Configuro modo de PullUp interno para las 4 entradas (los cuatro cables) y el botón de Reset
E1r.mode(PullUp);
E2r.mode(PullUp);
E3r.mode(PullUp);
E4r.mode(PullUp);
pulsadorReset.mode(PullUp);
//Asingo las funciones a los Tickers
Tempo.attach(&descuentaTiempo,1); //La funcion descuentaTiempo se va a ejecutar cada 1 segundo
Display.attach(&visualizacionDisplays,0.005); //La funcion visualizacionDisplays se va a ejecutar cada 5 milisegundos
parpadeoTicker.attach(&parpadeoFuncion,0.5); //La funcion parpadeoFuncion se va a ejecutar cada 0,5 segundos
while(1) {
//Llamo a las funciones
generacion();
chequeo();
winReaccion();
reset();
//Pongo los estados de las entradas en las variables
E1=E1r;
E2=E2r;
E3=E3r;
E4=E4r;
}
}
void reset()
{
if(pulsadorReset==0)
{
//si se presiona el pulsador resetea todas las variables, los vectores (vuelven a empezar en 0000) y las máq. de estados empiezan por su estado default
ledWin=1;
ledLost=1;
switcheo=0;
cantIgual=0;
cantIgual2=0;
cantIgual3=0;
vecSec[0]=0;
vecSec[1]=0;
vecSec[2]=0;
vecSec[3]=0;
vecSec2[0]=0;
vecSec2[1]=0;
vecSec2[2]=0;
vecSec2[3]=0;
vecSec3[0]=0;
vecSec3[1]=0;
vecSec3[2]=0;
vecSec3[3]=0;
vecSec4[0]=0;
vecSec4[1]=0;
vecSec4[2]=0;
vecSec4[3]=0;
vecChq[0]=0;
vecChq[1]=0;
vecChq[2]=0;
vecChq[3]=0;
parpadeoDisplay=0;
tiempo=60;
win=0;
fin=0;
secuencia=INICIO;
check=BEGINNING;
}
}
void winReaccion()
{
//Si el jugador ganó, se prende el led verde y se apaga el rojo
if(win==1)
{
ledWin=0;
ledLost=1;
}
}
void parpadeoFuncion()
{
//Si el jugador perdió, cada 0,5 segundos que entra en la funcion cambia el estado del led rojo de 0 a 1
if(fin==1)
{
ledLost=!ledLost;
}
//Si el jugador perdió o ganó, cada 0,5 segundos que entra en la funcion va a cambiar entre 0 y 1 la variable que indica si se tiene que mostrar el tiempo o apagar los displays
if(fin==1 || win==1)
{
parpadeoDisplay=!parpadeoDisplay;
}
}
void descuentaTiempo()
{
//Si el juego no terminó, cada 1 segundo le resta 1 a la variable tiempo, que empieza en 60, hasta que llega a 0 e indica que el jugador perdió.
//También cada 1 segundo muestra el estado de las variables importantes para el jugador para facilitar la depuración
if(fin==0 && win==0)
{
if(tiempo>0)
{
tiempo--;
}
else
{
fin=1;
}
printf("A lograr: \n");
printf("%d %d %d %d \n",*vecSec,*(vecSec+1),*(vecSec+2),*(vecSec+3));
printf("%d %d %d %d \n",*vecSec2,*(vecSec2+1),*(vecSec2+2),*(vecSec2+3));
printf("%d %d %d %d \n",*vecSec3,*(vecSec3+1),*(vecSec3+2),*(vecSec3+3));
printf("%d %d %d %d \n",*vecSec4,*(vecSec4+1),*(vecSec4+2),*(vecSec4+3));
printf("Entradas: %d %d %d %d \n", E1,E2,E3,E4);
printf("Tiempo (en segundos): %d \n \n",tiempo);
}
}
void visualizacionDisplays()
{
//Consigo el numero perteneciente a las decenas del tiempo y lo guardo en la variable. Lo mismo para las unidades del tiempo
Decenas=tiempo/10;
Unidades=tiempo-((tiempo/10)*10);
//Si no tiene que parpadear el display, va cambiar entre mostrar las decenas y unidades cada 5 milisegundos que entra a la funcion
//Si tiene que parpadear, parpadeoDisplay cambia entre 0 y 1, mostrando el tiempo en un momento y apagando los displays en otro
if(parpadeoDisplay==0)
{
//Si switcheo es par, muestra decenas, y si es impar, muestra unidades. La posicion 0 del vector corresponde al numero 0, y así hasta el 9
if(switcheo%2==0)
{
Displays=numerosD[Decenas];
}
else
{
Displays=numerosU[Unidades];
}
}
else
{
Displays=0;
}
//Como no importa el número en sí, para que no se haga muy grande para en 200 y vuelve a 0
if(switcheo==200)
{
switcheo=0;
}
//switcheo aumenta en 1 cada vez que se entra a la funcion
switcheo++;
}
void generacion(){
switch(secuencia)
{
default:
case INICIO:
//Se reinician las variables que se encargan de generar la secuencia
genSec1=0;
genSec2=0;
genSec3=0;
//Pasa directamente al estado GENERA1
secuencia=GENERA1;
break;
case GENERA1:
//Se le asigna un valor random entre 1 y 4 a la variable genSec1
genSec1=rand()%4+1;
//Dependiendo del valor, se le suma 1 a 1 de las 4 posiciones del vector
if(genSec1==1)
{
vecSec[0]++;
}
else if(genSec1==2)
{
vecSec[1]++;
}
else if(genSec1==3)
{
vecSec[2]++;
}
else if(genSec1==4)
{
vecSec[3]++;
}
//Pasa directamente al estado GENERA2
secuencia=GENERA2;
break;
case GENERA2:
//Se le asigna un valor random entre 1 y 4 a la variable genSec2
genSec2=rand()%4+1;
//Se copia el contenido del vector de la primera parte de la secuencia al del vector de la segunda parte de la secuencia
vecSec2[0]=vecSec[0];
vecSec2[1]=vecSec[1];
vecSec2[2]=vecSec[2];
vecSec2[3]=vecSec[3];
//Dependiendo del valor, se le suma 1 a 1 de las 4 posiciones del vector, excepto que la posicion a la que busca sumar 1 ya sea 1 de la generacion anterior
//Si la posicion ya era 1 de antes, se vuelve a hacer el proceso (que incluye volver a generar un número random)
if(genSec2==1)
{
if(vecSec2[0]==1)
{
secuencia=GENERA2;
}
else
{
vecSec2[0]++;
}
}
else if(genSec2==2)
{
if(vecSec2[1]==1)
{
secuencia=GENERA2;
}
else
{
vecSec2[1]++;
}
}
else if(genSec2==3)
{
if(vecSec2[2]==1)
{
secuencia=GENERA2;
}
else
{
vecSec2[2]++;
}
}
else if(genSec2==4)
{
if(vecSec2[3]==1)
{
secuencia=GENERA2;
}
else
{
vecSec2[3]++;
}
}
//Se busca verificar que el vector de la segunda parte de la secuencia contenga dos posiciones en 1. En ese caso, pasa al estado GENERA3
//Sino vuelve a hacer el proceso
if((vecSec2[0]+vecSec2[1]+vecSec2[2]+vecSec2[3]) == 2)
{
secuencia=GENERA3;
}
else
{
secuencia=GENERA2;
}
break;
case GENERA3:
//Se le asigna un valor random entre 1 y 4 a la variable genSec3
genSec3=rand()%4+1;
//Se copia el contenido del vector de la segunda parte de la secuencia al del vector de la tercera parte de la secuencia
vecSec3[0]=vecSec2[0];
vecSec3[1]=vecSec2[1];
vecSec3[2]=vecSec2[2];
vecSec3[3]=vecSec2[3];
//Dependiendo del valor, se le suma 1 a 1 de las 4 posiciones del vector, excepto que la posicion a la que busca sumar 1 ya sea 1 de la generacion anterior
//Si la posicion ya era 1 de antes, se vuelve a hacer el proceso (que incluye volver a generar un número random)
if(genSec3==1)
{
if(vecSec3[0]==1)
{
secuencia=GENERA3;
}
else
{
vecSec3[0]++;
}
}
else if(genSec3==2)
{
if(vecSec3[1]==1)
{
secuencia=GENERA3;
}
else
{
vecSec3[1]++;
}
}
else if(genSec3==3)
{
if(vecSec3[2]==1)
{
secuencia=GENERA3;
}
else
{
vecSec3[2]++;
}
}
else if(genSec3==4)
{
if(vecSec3[3]==1)
{
secuencia=GENERA3;
}
else
{
vecSec3[3]++;
}
}
//Se busca verificar que el vector de la tercera parte de la secuencia contenga tres posiciones en 1. En ese caso, pasa al estado FIN
//Sino vuelve a hacer el proceso
if((vecSec3[0]+vecSec3[1]+vecSec3[2]+vecSec3[3]) == 3)
{
secuencia=FIN;
}
else
{
secuencia=GENERA3;
}
break;
case FIN:
//Termina con todas las posiciones en 1. Se mantiene en este estado hasta que se presione el botón de reset
vecSec4[0]=1;
vecSec4[1]=1;
vecSec4[2]=1;
vecSec4[3]=1;
secuencia=FIN;
break;
}
}
void chequeo(){
switch(check)
{
default:
case BEGINNING:
//Si todas las entradas están conectadas (ningún cable sin cortar), se queda en este estado, sino cambia a CHECK1
if(E1!=0 || E2!=0 || E3!=0 || E4!=0)
{
check=CHECK1;
}
else
{
check=BEGINNING;
}
break;
case CHECK1:
//El estado de las entradas al "desconectar" una se guarda en los vectores
vecChq[0]=E1;
vecChq[1]=E2;
vecChq[2]=E3;
vecChq[3]=E4;
//Se fija si el estado de las 4 entradas corresponde con la secuencia al desconectar solo una de las entradas
for(i=0;i<4;i++)
{
if(vecSec[i]==vecChq[i])
{
cantIgual++;
}
}
//Si solo se desconectó una y era la que debía ser según la secuencia, se vuelve a hacer el proceso. Si era una incorrecta, perdiste el juego
if((vecChq[0]+vecChq[1]+vecChq[2]+vecChq[3])==1)
{
if(cantIgual!=4)
{
check=ENDGAME;
}
else
{
cantIgual=0;
check=CHECK1;
}
}
//Si la primera que se había desconectado era la correcta y se desconecta otra más, pasa al estado CHECK2
else if(vecChq[0]+vecChq[1]+vecChq[2]+vecChq[3])==2)
{
check=CHECK2;
}
break;
case CHECK2:
//El estado de las entradas al desconectar la segunda se guarda en los vectores
vecChq[0]=E1;
vecChq[1]=E2;
vecChq[2]=E3;
vecChq[3]=E4;
//Se fija si el estado de las 4 entradas corresponde con a la secuencia al desconectar la segunda entrada
for(y=0;y<4;y++)
{
if(vecSec2[y]==vecChq[y])
{
cantIgual2++;
}
}
//Si al desconectar la segunda entrada era la que debía ser según la secuencia, se vuelve a hacer el proceso. Si era una incorrecta, perdiste el juego
if(vecChq[0]+vecChq[1]+vecChq[2]+vecChq[3])==2)
{
if(cantIgual2!=4)
{
check=ENDGAME;
}
if(cantIgual==4)
{
check=CHECK2;
}
}
//Si la segunda que se había desconectado era la correcta y se desconecta otra más, pasa al estado CHECK3
else if(vecChq[0]+vecChq[1]+vecChq[2]+vecChq[3])==3)
{
check=CHECK3;
}
break;
case CHECK3:
//El estado de las entradas al desconectar la tercera se guarda en los vectores
vecChq[0]=E1;
vecChq[1]=E2;
vecChq[2]=E3;
vecChq[3]=E4;
//Se fija si el estado de las 4 entradas corresponde con a la secuencia al desconectar la tercera entrada
for(k=0;k<4;k++)
{
if(vecSec3[k]==vecChq[k])
{
cantIgual3++;
}
}
//Si al desconectar la tercera entrada era la que debía ser según la secuencia, se vuelve a hacer el proceso. Si era una incorrecta, perdiste el juego
if(vecChq[0]+vecChq[1]+vecChq[2]+vecChq[3])==3)
{
if(cantIgual3!=4)
{
check=ENDGAME;
}
if(cantIgual3==4)
{
check=CHECK3;
}
}
//Si la tercera que se había desconectado era la correcta y se desconecta la última, evidentemente es la correcta y ganaste el juego
else if(vecChq[0]+vecChq[1]+vecChq[2]+vecChq[3])==4)
{
check=WINGAME;
}
break;
case ENDGAME:
//Indica que se perdió el juego
fin=1;
check=ENDGAME;
break;
case WINGAME:
//Indica que se ganó el juego
win=1;
check=WINGAME;
break;
}
}