Dependencies:   mbed

main.cpp

Committer:
nicoalmaraz
Date:
2019-06-11
Revision:
0:9498d6ad334c
Child:
1:7c6b9d2b09bb

File content as of revision 0:9498d6ad334c:

//Almaraz y Bettig
//TP1 Ejercicio 2: Simon
#include "mbed.h"

char elementos=0; //Cada elemento es cada posicion del vector del patron
char patron[23]; //vector con el patron que hay que seguir
char repeticiones_secuencia_inicio=0; //cuenta las veces que repeti la secuencia antes de que comience el juego
char leds[4]= {0,0,0,0}; //leds de salida
char nivel=1; //Indica por que nivel vas. En total hay 23 niveles
char usuario[23]; //vector con los datos que ingresa el usuario
char mostrado=0; //cuenta cuantos elementos del vector "patron" mostre
char ingreso=0; //es el numero de elemento que ingresó el usuario
char pulsador_rojo=1; //pulsador sin rebote
char pulsador_azul=1; //pulsador sin rebote
char pulsador_verde=1; //pulsador sin rebote
char pulsador_amarillo=1; //pulsador sin rebote
char lectura_pulsador_valida=0; //flag que indica si se guardó un dato ingresado por el usuario correctamente
char ruido=0; //flag que indica que la medicion fue ruido
int tiempo_pulsadores=0; //variable de tiempo
int tiempo_secuencia_inicio=0; //variable de tiempo
int tiempo_patron=0; //variable de tiempo
int tiempo_mostrar=0; //variable de tiempo
char estado_secuencia_inicio=0; //estado de la maquina de estados "secuencia_inicio"

void reset_leds();
void timer();
void secuencia_inicio();
void generar_patron();
void mostrar();
void pulsadores();
void ingresar();

DigitalOut led_rojo(PTB0);
DigitalOut led_azul(PTB1);
DigitalOut led_verde(PTB2);
DigitalOut led_amarillo(PTB3);

DigitalIn pulsador_rojo_con_rebote(PTE23);
DigitalIn pulsador_azul_con_rebote(PTE22);
DigitalIn pulsador_verde_con_rebote(PTE21);
DigitalIn pulsador_amarillo_con_rebote(PTE20);
DigitalIn reset(PTC1);

Ticker ticker;

int main()
{
    ticker.attach(&timer, 0.001);
    char simon=0;
    char fin=0;
    long i=0;
    printf("Presione el pulsador Inicio para iniciar el juego\r\n");
    while(1) {
        switch(simon) {
            default:
            case 0:
                i++;
                if(reset==0) {
                    srand(i);
                    simon=1;
                    tiempo_secuencia_inicio=0;
                }
                break;
            case 1: //Hago la secuencia que hace el simon antes de arrancar 4 veces y genero el patron
                secuencia_inicio();
                generar_patron();
                if((repeticiones_secuencia_inicio==5)&&(elementos==25)) {
                    simon=2;
                    tiempo_mostrar=0;
                    reset_leds();
                }
                break;
            case 2: //Tomo el "patron" y muestro la cantidad de colores que indica "nivel"
                mostrar();
                if(mostrado==nivel) {
                    simon=3;
                    mostrado=0;
                    printf("Realice la secuencia\r\n");
                }
                break;
            case 3: //Espero a que el usuario ingrese un color
                ingresar();
                if(lectura_pulsador_valida==1) {
                    simon=4;
                    lectura_pulsador_valida=0;
                }
                break;
            case 4: //Analizo el datoingresado
                if(usuario[ingreso]!=patron[ingreso]) { //me fijo si ingresé algo distintinto a lo que corresponde y lo indico con el flag "fin"
                    printf("Perdiste!\n");
                    printf("Presione el pulsador Reset para reiniciar el juego\r\n");
                    fin=1;
                }
                if ((usuario[ingreso]==patron[ingreso])&&(ingreso<nivel)) {//Si ingresé un valor correcto vuelvo al estado de ingresar datos y sumo la variable "ingreso"
                    ingreso++;
                    simon=3;
                }
                if((ingreso==nivel)&&(ingreso<24)) { //me fijo si llegué a ingresar la cantidad de cosas que mostré (sin completar el patrón completo)
                    ingreso=0;
                    printf("Nivel %d completado!\r\n",nivel);
                    tiempo_mostrar=0;
                    nivel++;
                    simon=2;
                }
                if(ingreso==24) { //me fijo si llegué a ingresar 24 cosas y lo indico con el flag "fin"
                    printf("Ganaste!\r\n");
                    printf("Presione el pulsador Reset para reiniciar el juego\r\n");
                    fin=1;
                }
                if(fin) //Si perdí o gané reinicio las variables para comenzar un juego nuevo
                {
                    simon=0;
                    repeticiones_secuencia_inicio=0;
                    estado_secuencia_inicio=0;
                    elementos=0;
                    ingreso=0;
                    nivel=1;
                    fin=0;
                    printf("Presione el pulsador de inicio para volcer a jugar");
                }
                break;
        }
        //Enciendo los leds correspondientes
        led_rojo=leds[0];
        led_azul=leds[1];
        led_verde=leds[2];
        led_amarillo=leds[3];
    }
}

void reset_leds()
//Apaga todos los leds
{
    leds[0]=0;
    leds[1]=0;
    leds[2]=0;
    leds[3]=0;
}

void timer()
//Incrementa los contadores cada 1ms
{
    tiempo_pulsadores++;
    tiempo_secuencia_inicio++;
    tiempo_patron++;
    tiempo_mostrar++;
}

void secuencia_inicio()
//Hace una secuencia introductoria al juego que el Simon original hace
{
    if(tiempo_secuencia_inicio==300) {
        switch(estado_secuencia_inicio) {
            default:
            case 0: //rojo
                reset_leds();
                leds[0]=1;
                estado_secuencia_inicio=0;
                repeticiones_secuencia_inicio++;
                break;
            case 1: //azul
                reset_leds();
                leds[1]=1;
                break;
            case 2: //verde
                reset_leds();
                leds[2]=1;
                break;
            case 3: //amarillo
                reset_leds();
                leds[3]=1;
                break;
        }
        estado_secuencia_inicio++;
        tiempo_secuencia_inicio=0;
    }
}

void generar_patron()
//Genera el patron de 23 colores y los guarda en el vector "patron"
{
    if(elementos>24)
        return;
    patron[elementos]=rand()%4;
    elementos++;
}

void mostrar() 
//Muestra la secuencia guardada en "patron" y la variable "mostrado" indica cuantos colores mostré
{
    static char estado_mostrar;
    switch (estado_mostrar) {
        default:
        case 0:
            if(tiempo_mostrar==400) {//espero 0.4s para volver a encender los leds
                estado_mostrar=1;
                tiempo_mostrar=0;
                leds[patron[mostrado]]=1; //enciendo el led que corresponde
            }
            break;
        case 1:
            if(tiempo_mostrar==1000) {//espero 1s para apagar los leds
                estado_mostrar=0;
                tiempo_mostrar=0;
                mostrado++; //indico que mostré un elemento más
                reset_leds();
            }
            break;
    }
}

void pulsadores(char pulsador_con_rebote, char valor_salida)
// leo el pulsador, le quito el rebote y guardo el dato ingresado en el vector "usuario". Además distingo entre ruido o una lectura valida
{
    static char estado_pulsadores;
    switch(estado_pulsadores) {
        default:
        case 0: //Espero a que se apreten pulsadores y los prendo cuando lo hacen
            reset_leds();
            if(pulsador_con_rebote==0) {
                tiempo_pulsadores=0;
                estado_pulsadores=1;
            }
            break;
        case 1: //Espero 50ms para quitar el rebote rise y analizo si fue ruido o realmente presionaron
            if(tiempo_pulsadores>=50) {
                if(pulsador_con_rebote==0) {
                    estado_pulsadores=2;
                    usuario[ingreso]=valor_salida;
                    leds[valor_salida]=1;
                } else {
                    estado_pulsadores=0;
                    ruido=1;
                }
            }
            break;
        case 2: //Si se habia apretado espero a que se suelte
            if(pulsador_con_rebote==1) {
                reset_leds();
                tiempo_pulsadores=0;
                estado_pulsadores=3;
            }
            break;
        case 3: //Espero 50ms para quitar el rebote fall y analizo si ya se fue o debo darle más tiempo
            if(tiempo_pulsadores>=50) {
                if(pulsador_con_rebote==1) {
                    estado_pulsadores=0;
                    lectura_pulsador_valida=1;
                } else
                    tiempo_pulsadores=0; // si todavia no se fue el rebote espero más tiempo
            }
            break;
    }
}

void ingresar()
//Espera a que un pulsador se presione y analiza el dato ingresado con la función "pulsadores"
{
    static char estado_ingresar;
    switch(estado_ingresar) {
        default:
        case 0:
            if(pulsador_rojo_con_rebote==0)
                estado_ingresar=1;
            if(pulsador_azul_con_rebote==0)
                estado_ingresar=2;
            if(pulsador_verde_con_rebote==0)
                estado_ingresar=3;
            if(pulsador_amarillo_con_rebote==0)
                estado_ingresar=4;
            break;
        case 1:
            pulsadores(pulsador_rojo_con_rebote,0);
            break;
        case 2:
            pulsadores(pulsador_azul_con_rebote,1);
            break;
        case 3:
            pulsadores(pulsador_verde_con_rebote,2);
            break;
        case 4:
            pulsadores(pulsador_amarillo_con_rebote,3);
            break;
    }
    if(lectura_pulsador_valida==1) {
        estado_ingresar=0;
        printf("Ingreso valido\r\n");
    }
    if(ruido==1) {
        estado_ingresar=0;
        ruido=0;
        printf("Deteccion de ruido\r\n");
    }
}