Gonzalo Martinez
/
TPSimon
SIMON
Revision 1:6cb3e90ec4f3, committed 2019-06-22
- Comitter:
- gonzaloMS
- Date:
- Sat Jun 22 00:02:57 2019 +0000
- Parent:
- 0:31131c8fdcfb
- 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:44:51 2019 +0000 +++ b/main.cpp Sat Jun 22 00:02:57 2019 +0000 @@ -1,53 +1,52 @@ #include "mbed.h" -enum{MUESTRA,MUESTRA2,NO_MUESTRA,NO_MUESTRA2,NO_INGRESA,INGRESA,ESPERA,FAIL}; +//Creo los estados +enum{MUESTRA,MUESTRA2,NO_MUESTRA,NO_MUESTRA2,NO_INGRESA,INGRESA,ESPERA,FIN,LEE,APAGA,AGUARDA}; +// |--------------------------------------|-----------------------------|-----------------| +// GENERACIÓN DE SECUENCIA CONFIRMACIÓN PULSADORES -const int MaxElem=5; +//Defino la cantidad máxima de elementos +const int MaxElem=24; +//Defino como salidas el led RGB en los tres colores, Red, Green y Blue DigitalOut ledR(LED1); DigitalOut ledG(LED2); DigitalOut ledB(LED3); -DigitalIn E1r(D2); -DigitalIn E2r(D3); -DigitalIn E3r(D4); +//Defino como entradas los 3 pulsadores (para Red, Green y Blue) y el pulsador para el reseteo +DigitalIn E1r(D2); //Pulsador para el color Rojo (R) +DigitalIn E2r(D3); //Pulsador para el color Verde (G) +DigitalIn E3r(D4); //Pulsador para el color Azul (B) DigitalIn reseteo(D5); +//Variables donde guardo los valores de las entradas de los 3 colores +int E1; // <-- E1r +int E2; // <-- E2r +int E3; // <-- E3r + +//Creo los tickers Ticker pantalla; -Ticker leer; +Ticker mostrarLeds; Ticker Interludio; -int HG=1; -int E1; -int E2; -int E3; +//Las funciones de cada ticker respectivamente +void visualizaTexto(); //Muestra en el Hercules los datos cada vez que se entra a la función +void visualizaSecuencia(); //Hace que, cada cierto tiempo, se prenda el led correspondiente a la parte de la secuencia en la que está +void tiempoLedsOn(); //Define básicamente cuánto tiempo quedan prendidos los leds antes de apagarse otra vez para esperar el próx.color o botón presionado + +//Función encargada del reseteo de todas las variables y volver al estado inicial de cada máquina de estados +void reset(); -int i=0; -int i2=0; -int i3=0; -int i4=0; -int iMuestra=0; +//Funciones que son las máquinas de estados +void detectorPulsado(); //Detecta qué botón de los 3 de colores tocaste quitando el rebote +void generadorSecuencia(); //Genera la secuencia +void confirmacion(); //Confirma si lo ingresado con los pulsadores corresponde con la secuencia -int a=0; -int b=0; -int c=0; - +//Variables que indican los estados de las máquinas de estados +int estadosPulsadores; int estadosSecuencia; int estadosConfirm; -int CT=0; -int EP; -int LED; - -int print=0; - -int contar=0; - -int j; -int x; -int w; -int p; -int l=0; int vecR[MaxElem]; int vecG[MaxElem]; @@ -56,59 +55,71 @@ int vecE2[MaxElem]; int vecE3[MaxElem]; -void generadorSecuencia(); -void detectorPulsado(); -void confirmacion(); -void leerFuncion(); -void cutled(); -void pantalleate(); +//Variable que determina si se tiene que generar una nueva secuencia o no (Habilita Generación) +int HG; +//Variable que indica la Cantidad Total de posiciones de la secuencia +int CT=0; +//Variable que indica en cuál de las posiciones de la secuencia está en el momento (Estado Parcial) +int EP; +//Variable que guarda un número random del cuál depende cuál color se va a guardar en esa posición de la secuencia +int LED; + +//Variables que cuentan diferentes cosas +int iSecuencia=0; //Posición de la secuencia para generar la secuencia +int iIngresado=0; //Cantidad de veces que algo fue ingresado mediante los pulsadores +int iCorrecto=0; //Cantidad de veces que lo ingresado fue correcto / coincide con la secuencia +int iChequeo=0; //Posición para chequear si lo ingresado fue correcto / coincide con la secuencia +int iMuestra=0; //Posición para mostrar la secuencia en los leds + +//Variables que sirven para eliminar el rebote de los pulsadores y detectar solo el flanco ascendente +int mantieneRojo=0; +int mantieneVerde=0; +int mantieneAzul=0; + +//Variable que indica si se tienen que mostrar los printf o no en el Hercules +int print=0; +//Variable que, según su valor, indica si los leds tienen que estar apagados o mantener su estado +int decideLedOff=0; + +//Variables que se usan para pasar por las posiciones de los vectores cuando estos se tienen que reiniciar o se quiere mostrar la secuencia en el Hercules +int j; +int w; +int p; + +//Variable que indica si se tienen que prender los leds con respecto a las posiciones de la secuencia +int doSec=0; int main(void) { + //Configuro en modo Pull-Up las 4 entradas con pulsadores + E1r.mode(PullUp); + E2r.mode(PullUp); + E3r.mode(PullUp); reseteo.mode(PullUp); + //Apago los leds ledR=1; ledG=1; ledB=1; - leer.attach(&leerFuncion,0.4); - Interludio.attach(&cutled,0.2); - pantalla.attach(&pantalleate,1); - while (true) { - if(reseteo==0) - { - for(j=0;j<MaxElem;j++){ - vecR[j]=0; - vecG[j]=0; - vecB[j]=0; - vecE1[j]=0; - vecE2[j]=0; - vecE3[j]=0; - } - CT=0; - HG=0; - EP=0; - l=0; - contar=0; - print=0; - LED=0; - a=0; - b=0; - c=0; - i=0; - i2=0; - i3=0; - i4=0; - estadosSecuencia=NO_MUESTRA; - estadosConfirm=NO_INGRESA; - - - } + //Asigno las funciones a los tickers + pantalla.attach(&visualizaTexto,1); //Se ejecuta visualizaTexto cada 1 segundo + mostrarLeds.attach(&visualizaSecuencia,0.6); //Se ejecuta visualizaSecuencia cada 0,6 segundos + Interludio.attach(&tiempoLedsOn,0.2); //Se ejecuta tiempoLedsOn cada 0,2 segundos + while(true) { + //Llamo a la función reset todo el tiempo + reset(); + //Si la cantidad total de elementos de una secuencia todavía no pasó el máximo permitido, se ejecutan las funciones y muestran los printf + //Sino, se para todo y se indica al jugador que debe apretar el botón reset para empezar de nuevo if(CT<=MaxElem) { + detectorPulsado(); + confirmacion(); + generadorSecuencia(); if(print==1) { printf("Cant. Total Secuencia:%d \n",CT); - printf("Cant. Total de veces Ingresado:%d \n",i2); - printf("Cant. Total de veces que fue correcto lo ingresado:%d \n",i3); + printf("Cant. Total de veces Ingresado:%d \n",iIngresado); + printf("Cant. Total de veces que fue correcto lo ingresado:%d \n",iCorrecto); printf("Secuencia a lograr: \n"); + printf("R G B \n"); for(p=0;p<=(CT-1);p++) { if(CT==MaxElem+1) @@ -120,43 +131,174 @@ printf("\n \n"); print=0; } - if(l==1) - { - detectorPulsado(); - generadorSecuencia(); - confirmacion(); - l=0; - } } else { - if(l==1) + if(print==1) { printf("Por favor, empiece otra vez \n"); - l=0; + print=0; } } } } -void pantalleate() +void reset() { + //Resetea todas las variables, los vectores y vuelve a los estados iniciales de las máquinas de estados + if(reseteo==0) + { + for(j=0;j<MaxElem;j++) + { + vecR[j]=0; + vecG[j]=0; + vecB[j]=0; + vecE1[j]=0; + vecE2[j]=0; + vecE3[j]=0; + } + CT=0; + HG=0; + EP=0; + doSec=0; + decideLedOff=0; + print=0; + LED=0; + mantieneRojo=0; + mantieneVerde=0; + mantieneAzul=0; + iSecuencia=0; + iIngresado=0; + iCorrecto=0; + iChequeo=0; + estadosSecuencia=NO_MUESTRA; + estadosConfirm=NO_INGRESA; + } +} + +void visualizaTexto() +{ + //Cada 1 segundo, esto se pone en 1 para mostrar los printf. Al instante se vuelve 0 y deja de mostrar los printf, esperando que se vuelva a llamar a la función print=1; } -void cutled() +void visualizaSecuencia() +{ + //Cada 0,6 segundos, la variable se hace 1. Cuando llegue la parte de mostrar la secuencia, la variable se va a hacer 0 y va a esperar a que se llame a la función otra vez + doSec=1; +} + +void tiempoLedsOn() { - if(contar%2==0) + //Cada 0,2 segundos, se le suma 1 a la variable y, cada vez que es par, apaga los leds sin importar sus estados anteriores + if(decideLedOff%2==0) { ledR=1; ledG=1; ledB=1; } - contar++; + decideLedOff++; } -void leerFuncion() + +void detectorPulsado() { - l=1; + switch(estadosPulsadores) + { + default: + case LEE: + //Espera a que se toque el pulsador de rojo + //Si es así guarda eso en los vectores, pone la variable E1 en 1, suma 1 a iIngresado y prende el led rojo, que va a ser apagado por la función tiempoLedsOn + //También se pone en 1 la variable mantieneRojo que es un indicador del estado anterior + //Cambia el estado a APAGA + if(E1r==0 && mantieneRojo==0) + { + E1=1; + mantieneRojo=1; + vecE1[iIngresado]=1; + vecE2[iIngresado]=0; + vecE3[iIngresado]=0; + ledR=0; + iIngresado++; + estadosPulsadores=APAGA; + } + //Espera a que se toque el pulsador de Verde + //Si es así guarda eso en los vectores, pone la variable E2 en 1, suma 1 a iIngresado y prende el led verde, que va a ser apagado por la función tiempoLedsOn + //También se pone en 1 la variable mantieneVerde que es un indicador del estado anterior + //Cambia el estado a APAGA + if(E2r==0 && mantieneVerde==0) + { + E2=1; + mantieneVerde=1; + vecE1[iIngresado]=0; + vecE2[iIngresado]=1; + vecE3[iIngresado]=0; + ledG=0; + iIngresado++; + estadosPulsadores=APAGA; + } + //Espera a que se toque el pulsador de Azul + //Si es así guarda eso en los vectores, pone la variable E3 en 1, suma 1 a iIngresado y prende el led verde, que va a ser apagado por la función tiempoLedsOn + //También se pone en 1 la variable mantieneAzul que es un indicador del estado anterior + //Cambia el estado a APAGA + if(E3r==0 && mantieneAzul==0) + { + E3=1; + mantieneAzul=1; + vecE1[iIngresado]=0; + vecE2[iIngresado]=0; + vecE3[iIngresado]=1; + ledB=0; + iIngresado++; + estadosPulsadores=APAGA; + } + break; + + case APAGA: + //Si el pulsador de uno de los colores se mantiene pulsado y ya pasó por el estado anterior, E1 se vuelve 0 (E1 va a estar en 1 por muy poco tiempo) + //Se pasa al estado AGUARDA + if(E1r==0 && mantieneRojo==1) + { + E1=0; + estadosPulsadores=AGUARDA; + } + //Si el pulsador de uno de los colores se mantiene pulsado y ya pasó por el estado anterior, E2 se vuelve 0 (E2 va a estar en 1 por muy poco tiempo) + //Se pasa al estado AGUARDA + if(E2r==0 && mantieneVerde==1) + { + E2=0; + estadosPulsadores=AGUARDA; + } + //Si el pulsador de uno de los colores se mantiene pulsado y ya pasó por el estado anterior, E3 se vuelve 0 (E3 va a estar en 1 por muy poco tiempo) + //Se pasa al estado AGUARDA + if(E3r==0 && mantieneAzul==1) + { + E3=0; + estadosPulsadores=AGUARDA; + } + break; + + case AGUARDA: + //Si ya se tocó el pulsador una vez y ahora se suelta, el E se mantiene como estaba, se indica con la otra variable que terminó el proceso y vuelve al estado LEE + if(E1r==1 && mantieneRojo==1) + { + E1=0; + mantieneRojo=0; + estadosPulsadores=LEE; + } + if(E2r==1 && mantieneVerde==1) + { + E2=0; + mantieneVerde=0; + estadosPulsadores=LEE; + } + if(E3r==1 && mantieneAzul==1) + { + E3=0; + mantieneAzul=0; + estadosPulsadores=LEE; + } + break; + } } void confirmacion(){ @@ -164,52 +306,67 @@ { default: case NO_INGRESA: + //Se reinicia el contenido de los vectores de entrada, así cuando completás una secuencia tenés que escribir toda la que sigue desde cero + //El contenido de los vectores de secuencia, que guardan los colores y su posición en la secuencia, no se reinicia porque es parte del juego que la secuencia + //siguiente siempre es igual que la anterior solo que con un color random más agregado al final for(w=0;w<MaxElem;w++) { vecE1[w]=0; vecE2[w]=0; vecE3[w]=0; } - i2=0; - i4=0; - i3=0; + //Se reinician los indicadores cuando completás una secuencia + iIngresado=0; + iChequeo=0; + iCorrecto=0; + //Se habilita la generación de una nueva secuencia HG=1; + //Se pasa directamente al siguiente estado estadosConfirm=ESPERA; break; case INGRESA: - i4++; + //Se le suma 1 a iChequeo para que la proxima vez que se ingrese algo lo verifique con la siguiente posición de la secuencia + iChequeo++; + //Pasa directamente a ESPERA estadosConfirm=ESPERA; break; case ESPERA: + //Automáticamente se deshabilita la generación HG=0; + //Si no se ingresa nada mediante los pulsadores, queda en ESPERA if(E1==0 && E2==0 && E3==0) { estadosConfirm=ESPERA; } + //Si se ingresa algo, se fija si esa posición concuerda con la misma posición de la secuencia + //De ser correcto, va a INGRESA + //De ser incorrecto, el jugador perdió cambia el estado a FIN else { - if(i3!=CT) + if(iCorrecto!=CT) { - if((vecR[i4]==vecE1[i4]) && (vecG[i4]==vecE2[i4]) && (vecB[i4]==vecE3[i4])) + if((vecR[iChequeo]==vecE1[iChequeo]) && (vecG[iChequeo]==vecE2[iChequeo]) && (vecB[iChequeo]==vecE3[iChequeo])) { - i3++; + iCorrecto++; estadosConfirm=INGRESA; } else { - estadosConfirm=FAIL; + estadosConfirm=FIN; } } } - if(i3==CT) + //Si se ingresó toda la secuencia correctamente, vuelve al estado inicial NO_INGRESA donde se va a habilitar una nueva generación y reiniciar variables + if(iCorrecto==CT) { estadosConfirm=NO_INGRESA; } break; - case FAIL: + case FIN: + //En caso de perder, se hace que CT sea mayor a la máxima cantidad de elementos posibles, condición en la que se termina el juego y espera el reseteo CT=MaxElem+1; break; } @@ -219,136 +376,93 @@ { default: case NO_MUESTRA: - LED=0; - if(HG==0) - { - estadosSecuencia=NO_MUESTRA; - } - else - { - estadosSecuencia=NO_MUESTRA2; - } - break; + //La variable LED empieza en 0, que no hace nada + LED=0; + //Si se habilitó la generación de una secuencia, pasa al siguiente estado, NO_MUESTRA2 + //Sino, se queda en este estado + if(HG==0) + { + estadosSecuencia=NO_MUESTRA; + } + else + { + estadosSecuencia=NO_MUESTRA2; + } + break; case NO_MUESTRA2: + //De ser habilitada la generación de una nueva secuencia, se le suma 1 a la cantidad total de elementos/posiciones que va a tener la secuencia + //CT empieza en 0, cuando se habilita la generación, CT pasa a ser 1, entonces dentro de la secuencia solo va a haber un color random + //Cuando se toque bien ese color, vuelve a generar una secuencia, solo que ahora va a hacer CT++ otra vez y la secuencia va a constar de 2 colores random CT++; + //Pasa a MUESTRA directamente estadosSecuencia=MUESTRA; break; case MUESTRA: - if(EP!=CT) + //Si el estado parcial en que se encuentra no es último de la secuencia, hace que LED sea un número random entre 1 y 3 + //Basado en eso decide que color corresponde a ese estado parcial/posición de la secuencia + //Eso lo guarda en los vectores de secuencia, que tienen qué color corresponde a qué posición + //EP empieza en 0 y solo se reinicia en el reset, de manera que siempre se va a añadir un color random al final de la secuencia anterior para hacer la nueva + if(EP!=CT) + { + LED=rand()%3+1; + if(LED==1) + { + vecR[iSecuencia]=1; + vecG[iSecuencia]=0; + vecB[iSecuencia]=0; + } + else if(LED==2) + { + vecR[iSecuencia]=0; + vecG[iSecuencia]=1; + vecB[iSecuencia]=0; + } + else if(LED==3) { - LED=rand()%3+1; - if(LED==1) - { - vecR[i]=1; - vecG[i]=0; - vecB[i]=0; - } - else if(LED==2) - { - vecR[i]=0; - vecG[i]=1; - vecB[i]=0; - } - else if(LED==3) - { - vecR[i]=0; - vecG[i]=0; - vecB[i]=1; - } - if(i<CT) - { - i++; - } - EP++; + vecR[iSecuencia]=0; + vecG[iSecuencia]=0; + vecB[iSecuencia]=1; + } + if(iSecuencia<CT) + { + iSecuencia++; } - else - { - estadosSecuencia=MUESTRA2; - } - break; + EP++; + } + //Al hacerlo una vez, EP pasa a ser igual que CT, por lo que cambia al estado MUESTRA2 y espera a que el proceso se vuelva a hacer para que CT valga más que EP + //(En el estado anterior con CT++) + else + { + estadosSecuencia=MUESTRA2; + } + break; - case MUESTRA2: + case MUESTRA2: + //Cada 1 segundo que doSec se hace 1 y pasa a ser 0 instantáneamente, los leds se prenden con respecto a la secuencia generada (guardada en los vectores) + //Se apagan con la funcion tiempoLedsOn + //El estado de los leds es igual a lo que contiene la posición del vector -negado- porque los leds se prenden con 0, no con 1 + //Los vectores guardan con 1 los leds que se tienen que prender + //Cuando se muestra toda la secuencia en los leds, se reinicia iMuestra y vuelve al estado inicial NO_MUESTRA + if(doSec==1) + { + //La secuencia se guarda desde la posición 0 de los vectores. La primera secuencia se hace con CT=1. Por eso el CT-1 if(iMuestra<=CT-1) { ledR=!vecR[iMuestra]; ledG=!vecG[iMuestra]; ledB=!vecB[iMuestra]; iMuestra++; - estadosSecuencia=MUESTRA2; } else { iMuestra=0; estadosSecuencia=NO_MUESTRA; } - break; + doSec=0; + } + break; } } -void detectorPulsado() -{ - if(E1r==1 && a==0) - { - E1=1; - a=1; - vecE1[i2]=1; - vecE2[i2]=0; - vecE3[i2]=0; - ledR=0; - i2++; - } - else if(E1r==1 && a==1) - { - ledR=1; - E1=0; - } - else if(E1r==0 && a==1) - { - E1=0; - a=0; - } - - if(E2r==1 && b==0) - { - E2=1; - b=1; - vecE1[i2]=0; - vecE2[i2]=1; - vecE3[i2]=0; - ledG=0; - i2++; - } - else if(E2r==1 && b==1) - { - ledG=1; - E2=0; - } - else if(E2r==0 && b==1) - { - E2=0; - b=0; - } - - if(E3r==1 && c==0) - { - E3=1; - c=1; - vecE1[i2]=0; - vecE2[i2]=0; - vecE3[i2]=1; - ledB=0; - i2++; - } - else if(E3r==1 && c==1) - { - ledB=1; - E3=0; - } - else if(E3r==0 && c==1) - { - E3=0; - c=0; - } -} \ No newline at end of file