
4 Cables con pulsadores y pull-up con 2 Displays en paralelo
Revision 1:2f8c5940c425, committed 2019-06-22
- Comitter:
- gonzaloMS
- Date:
- Sat Jun 22 00:05:36 2019 +0000
- Parent:
- 0:d644ac0f96b0
- Child:
- 2:e7e06ee2d6b0
- Commit message:
- Comentado
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Wed Jun 19 12:45:45 2019 +0000 +++ b/main.cpp Sat Jun 22 00:05:36 2019 +0000 @@ -1,106 +1,129 @@ + + //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" -enum{INICIO,GENERA1,GENERA2,GENERA3,FIN,BEGGINING,CHECK1,CHECK2,CHECK3,ENDGAME,WINGAME}; - +//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); -DigitalIn E3r(PTC3); +DigitalIn E2r(PTC13); // 0 1 2 3 (Entradas reales/físicas) +DigitalIn E3r(PTC3); // E1r E2r E3r E4r DigitalIn E4r(PTC4); -DigitalIn pulsadorReset(PTE29); //Normalmente 1 - -DigitalOut ledWin(LED2); -DigitalOut ledLost(LED1); - -BusOut Displays(D2,D3,D4,D5,A3,A2,A1,A0,D8); //HAB.2 - HAB.1 -G-F-E-D-C-B-A // - +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; +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 -int numerosD[]={0b111111010,0b011000010,0b110110110,0b111100110,0b011001110,0b101101110,0b101111110,0b111000010,0b111111110,0b111001110}; -int numerosU[]={0b111111001,0b011000001,0b110110101,0b111100101,0b011001101,0b101101101,0b101111101,0b111000001,0b111111101,0b111001101}; - -Ticker Tempo; +//Inicializo Tickers que ejecutan una función cada cierto tiempo en segundos +Ticker Tempo; Ticker Display; Ticker parpadeoTicker; -void generacion(); -void chequeo(); -void Chronos(); -void theviewer(); -void ganopierdoreaccion(); -void parpadeoFuncion(); -void reset(); +//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 -int parimpar=0; +//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 -int regresor=60; -int Decenas; -int Unidades; -int secuencia; -int check; +//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) -int cantIgual=0; -int cantIgual2=0; -int cantIgual3=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 -int gSec1; -int gSec2; -int gSec3; -int vecSec[]={0,0,0,0}; -int vecSec2[]={0,0,0,0}; -int vecSec3[]={0,0,0,0}; -int vecSec4[]={0,0,0,0}; +//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 g=61; 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); - Tempo.attach(&Chronos,1); - Display.attach(&theviewer,0.005); - parpadeoTicker.attach(&parpadeoFuncion,0.5); + //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(); - ganopierdoreaccion(); + winReaccion(); reset(); - if(regresor < g) - { - E1=E1r; - E2=E2r; - E3=E3r; - E4=E4r; - g=regresor; - printf("Entradas: %d %d %d %d \n", E1,E2,E3,E4); - printf("Tiempo (en segundos): %d \n \n",g); - } + //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; - parimpar=0; + ledLost=1; + switcheo=0; cantIgual=0; cantIgual2=0; cantIgual3=0; @@ -125,43 +148,47 @@ vecChq[2]=0; vecChq[3]=0; parpadeoDisplay=0; - regresor=60; - g=61; + tiempo=60; win=0; fin=0; secuencia=INICIO; - check=BEGGINING; + check=BEGINNING; } } - -void ganopierdoreaccion() + +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 Chronos() + +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(regresor>0) + if(tiempo>0) { - regresor--; + tiempo--; } else { @@ -172,196 +199,91 @@ 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 theviewer() + +void visualizacionDisplays() { - Decenas=regresor/10; - Unidades=regresor-((regresor/10)*10); - if(parpadeoDisplay==0) - { - if(parimpar%2==0) - { - Displays=numerosD[Decenas]; - } - else - { - Displays=numerosU[Unidades]; - } - } - else + //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) { - if(parimpar%2==0) - { - Displays=0; - } - else - { - Displays=0; - } - } - if(parimpar==201) - { - parimpar=0; - } - parimpar++; -} - -void chequeo(){ - switch(check) - { - default: - case BEGGINING: - if(E1!=0 || E2!=0 || E3!=0 || E4!=0) - { - check=CHECK1; + Displays=numerosD[Decenas]; } else { - check=BEGGINING; - } - break; - - case CHECK1: - vecChq[0]=E1; - vecChq[1]=E2; - vecChq[2]=E3; - vecChq[3]=E4; - if(cantIgual<=2) - { - for(i=0;i<4;i++) - { - if(vecSec[i]==vecChq[i]) - { - cantIgual++; - } - } - } - if(cantIgual!=4) - { - check=ENDGAME; - } - if(cantIgual==4 && ((E1==0 && E2==0 && E3==0) || (E1==0 && E2==0 && E4==0) || (E1==0 && E3==0 && E4==0) || (E2==0 && E3==0 && E4==0))) - { - check=CHECK1; - } - else if(cantIgual==4 && ((E1!=0 && E2==0 && E3==0) || (E1==0 && E2!=0 && E3==0) || (E1==0 && E2==0 && E3!=0) || (E1!=0 && E2==0 && E4==0) || (E1==0 && E2!=0 && E4==0) || (E1==0 && E2==0 && E4!=0) || (E1!=0 && E3==0 && E4==0) || (E1==0 && E3!=0 && E4==0) || (E1==0 && E3==0 && E4!=0) || (E2!=0 && E3==0 && E4==0) || (E2==0 && E3!=0 && E4==0) || (E2==0 && E3==0 && E4!=0))) - { - check=CHECK2; - } - break; - - case CHECK2: - vecChq[0]=E1; - vecChq[1]=E2; - vecChq[2]=E3; - vecChq[3]=E4; - if(cantIgual2<=2) - { - for(y=0;y<4;y++) - { - if(vecSec2[y]==vecChq[y]) - { - cantIgual2++; - } - } + Displays=numerosU[Unidades]; } - if(cantIgual2!=4) - { - check=ENDGAME; - } - if(cantIgual==4 && ((E1==0 && E2==0) || (E2==0 && E3==0) || (E1==0 && E3==0) || (E1==0 && E4==0) || (E2==0 && E4==0) || (E3==0 && E4==0))) - { - check=CHECK2; - } - else if(cantIgual==4 && ((E1!=0 && E2==0) || (E1==0 && E2!=0) || (E2!=0 && E3==0) || (E2==0 && E3!=0) || (E1!=0 && E3==0) || (E1==0 && E3!=0) || (E1!=0 && E4==0) || (E1==0 && E4!=0) || (E2!=0 && E4==0) || (E2==0 && E4!=0) || (E3!=0 && E4==0) || (E3==0 && E4!=0) )) - { - check=CHECK3; - } - break; - - case CHECK3: - vecChq[0]=E1; - vecChq[1]=E2; - vecChq[2]=E3; - vecChq[3]=E4; - if(cantIgual3<=2) - { - for(k=0;k<4;k++) - { - if(vecSec3[k]==vecChq[k]) - { - cantIgual3++; - } - } - } - if(cantIgual3!=4) - { - check=ENDGAME; - } - if(cantIgual3==4 && (E1==0 || E2==0 || E3==0 || E4==0)) - { - check=CHECK3; - } - if(cantIgual3==4 && E1==1 && E2==1 && E3==1 && E4==1) - { - check=WINGAME; - } - break; - - case ENDGAME: - fin=1; - check=ENDGAME; - break; - - case WINGAME: - win=1; - check=WINGAME; - break; - } + } + 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: - + default: case INICIO: - gSec1=0; - gSec2=0; - gSec3=0; + //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: - gSec1=rand()%4+1; - if(gSec1==1) + //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(gSec1==2) + else if(genSec1==2) { vecSec[1]++; } - else if(gSec1==3) + else if(genSec1==3) { vecSec[2]++; } - else if(gSec1==4) + else if(genSec1==4) { vecSec[3]++; } + //Pasa directamente al estado GENERA2 secuencia=GENERA2; break; case GENERA2: - gSec2=rand()%4+1; + //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]; - if(gSec2==1) + //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) { @@ -372,7 +294,7 @@ vecSec2[0]++; } } - else if(gSec2==2) + else if(genSec2==2) { if(vecSec2[1]==1) { @@ -383,7 +305,7 @@ vecSec2[1]++; } } - else if(gSec2==3) + else if(genSec2==3) { if(vecSec2[2]==1) { @@ -394,7 +316,7 @@ vecSec2[2]++; } } - else if(gSec2==4) + else if(genSec2==4) { if(vecSec2[3]==1) { @@ -405,6 +327,8 @@ 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; @@ -416,12 +340,16 @@ break; case GENERA3: - gSec3=rand()%4+1; + //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]; - if(gSec3==1) + //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) { @@ -432,7 +360,7 @@ vecSec3[0]++; } } - else if(gSec3==2) + else if(genSec3==2) { if(vecSec3[1]==1) { @@ -443,7 +371,7 @@ vecSec3[1]++; } } - else if(gSec3==3) + else if(genSec3==3) { if(vecSec3[2]==1) { @@ -454,7 +382,7 @@ vecSec3[2]++; } } - else if(gSec3==4) + else if(genSec3==4) { if(vecSec3[3]==1) { @@ -465,6 +393,8 @@ 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; @@ -476,6 +406,7 @@ 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; @@ -483,4 +414,134 @@ 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; + } } \ No newline at end of file