VersionFinal

Dependencies:   mbed

main.cpp

Committer:
NIcolasFernandezSanz
Date:
2019-06-17
Revision:
1:2aa790d91fb0
Parent:
0:9475a54ade9e

File content as of revision 1:2aa790d91fb0:

/*
                FERNANDEZ-CLERICI
                  EJER02 - TP01
 
PTB0 -- Pulsador Azul
PTB1 -- Pulsador Verde
PTB2 -- Pulsador Rojo

*/

/* Librerias*/
#include "mbed.h"

#define ESTADO_COMENZAR     0
#define ESTADO_REINICIO     1
#define ESTADO_MUESTREO     2
#define ESTADO_JUEGO        3
#define ESTADO_PERDER       4
#define ESTADO_GANAR        5

#define INICIO_P            0
#define RISING_P            1
#define RETENCION_P         2

#define NIVELES 25
#define PA      PTB0
#define PV      PTB1
#define PR      PTB2

//Creamos los tres leds para usar
DigitalOut Rojo(LED1);
DigitalOut Verde(LED2);
DigitalOut Azul(LED3);

void timer();
void simon();
bool antirrebote_A(bool lectura);
bool antirrebote_R(bool lectura);
bool antirrebote_V(bool lectura);
int estado_a = 0, estado_r = 0, estado_v = 0;
char Pulsador ();
void leds(int num); // led(0b000) = apagados,  led(0b100) = rojo, led(0b010) = Verde, led(0b001) = Azul, led(0b111) = Blanco,

unsigned int semilla = 0;
char sec[50] = {0};
char nivelSec = 1;
char posSec = 0;
char posJuego = 0;
int times = 0, espera = 0, tp_v = 0, tp_r = 0, tp_a = 0;
bool flagPulsador = 0;
char pulsador = 0;
char estado = ESTADO_COMENZAR;

bool pulsador1 = 1, pulsador2 = 1, pulsador3 = 1;
bool st1= 0, st2 = 0, st3 = 0, loop = 1, apagado = 0;


Ticker ti;


int main()
{
    ti.attach(&timer, 0.1);

//Prendemos los LEDS
    leds(0b111);
    printf("Toque cualquier pulsador para comenzar: \r\n");

    while(true) {
        //Cambio el estado de los pulsadores
        Pulsador();
        //Ejecuto la funcion principal
        simon();
        //Aseguro el reset de la habilitacion del pulsador
        flagPulsador = 0;
    }
}
void simon()
{
    static int i;
    switch(estado) {
        case ESTADO_COMENZAR:
            //Espero que pulsen un pulsador para empezar
            times = 0;
            if(pulsador != 0 && flagPulsador == 1) {
                leds(0b000);
                printf("Comencemos: \r\n\n");
                estado = ESTADO_REINICIO;
                flagPulsador = 0;
            }
            break;

        case ESTADO_REINICIO:
            //Seteo la semilla
            srand (semilla*4920*1912);
            //Genero la secuencia
            for(i = 0; i <= NIVELES ; i ++) {
                sec[i] = rand() % 3 + 1;
            }
            nivelSec = 1;
            posSec = 0;
            posJuego = 0;
            estado = ESTADO_MUESTREO;
            times = 0;
            loop = 0;
            break;

        case ESTADO_MUESTREO:
            //Muestro la secuencia generada
            if(loop) {
                //Cada vez que termino de mostrar un LED
                if (apagado == 0) {
                    //Evaluo si mostre la cantidad de LEDs segun el nivel
                    if(posSec >= nivelSec) {
                        estado = ESTADO_JUEGO;
                        printf("\nA jugar Bro :) \r");
                        printf("\r\n\n");
                        espera = 0;
                        break;
                    }
                    switch(sec[posSec]) {
                        case 1:
                            //Muestro LED rojo
                            leds(0b100);
                            if(times > 5) {
                                times = 0;
                                printf("ROJO\r\n");
                                apagado = 1;
                                posSec++;
                            }
                            break;
                        case 2:
                            //Muestro LED verde
                            leds(0b010);
                            if(times > 5) {
                                apagado = 1;
                                times = 0;
                                printf("VERDE\r\n");
                                posSec++;
                            }
                            break;
                        case 3:
                            //Muestro LED azul
                            leds(0b001);
                            if(times > 5) {
                                apagado = 1;
                                times = 0;
                                printf("AZUL\r\n");
                                posSec++;
                            }
                            break;
                    }
                } else {
                    //Dejo un espacio apagado entre los colores de las secuencias
                    leds(0b000);
                    if (times > 5) {
                        times = 0;
                        apagado = 0;
                    }
                }
            } else {
                //Espero 5 times el ultimo LED encendido y lo apago
                if (times > 5)
                    leds(0b000);
                //Espero 5 times mas para separar el final de muestreo con el inicio del Juego
                if (times > 10) {
                    loop = 1;
                    times = 0;
                }
            }
            break;
        case ESTADO_JUEGO:
            //Detecto si el jugador tarda mucho tiempo en apretar un boton
            if (espera > 50) {
                printf("Tardaste demaciado tiempo en elegir\r\n");
                estado = ESTADO_PERDER;
                break;
            }
            //Detecto un cambio en los pulsadores
            if(flagPulsador) {
                espera = 0;
                flagPulsador = 0;
                times = 0;
                //Detecto que pulsador precionaron y enciendo el LED
                switch(pulsador) {
                    case 1:
                        printf("ROJO \r\n");
                        leds(0b100);
                        break;
                    case 2:
                        printf("VERDE \r\n");
                        leds(0b010);
                        break;
                    case 3:
                        printf("AZUL \r\n");
                        leds(0b001);
                        break;
                }
                //Comparo si el pulsador apretado es el correcto segun la secuencia
                if(pulsador == sec[posJuego]) {
                    posJuego++;
                    //Si alcancé el nivel en el que estoy paso de nivel
                    if(posJuego == nivelSec) {
                        nivelSec++;
                        printf("\n\t--------------------------------\r");
                        //Si alcancé el máximo nivel paso al estado GANAR
                        if (nivelSec == NIVELES + 1) {
                            estado = ESTADO_GANAR;
                        } else {
                            //Si no llegué al máximo nivel paso de nivel
                            printf("\nPasaste al nivel %d!\r\n\n", nivelSec);
                            posSec = 0;
                            posJuego = 0;
                            estado = ESTADO_MUESTREO;
                            loop = 0;
                            times = 0;
                        }
                    }
                } else {
                    //Si el pulsador no corresponde con la secuencia paso al estado PERDER
                    estado = ESTADO_PERDER;
                }
            }
            //Espero 5 times el LED encendido
            if (times > 5) {
                leds(0b000);

            }
            break;
        case ESTADO_PERDER:
            //Prendo el LED blanco para mostrar que termino el juego y vuelvo al estado COMENZAR
            printf("\nPerdiste Bro :(\r\n");
            printf("Apreta cualquier boton para reiniciar!\r\n\n");
            leds(0b111);
            estado = ESTADO_COMENZAR;
            break;

        case ESTADO_GANAR:
            //Mustro el LED blanco para mostrar que termino el juego y aviso que completo la secuencia
            printf("\nGANASTE!!! :)\r\n\n");
            printf("Apreta cualquier boton para reiniciar!\r\n\n");
            leds(0b111);
            estado = ESTADO_COMENZAR;
            break;
    }
}
void leds(int num)
{
    //Funcion que codifica el encendido y apagado de los LEDs
    switch(num) {
        case 0:
            Rojo = 1;
            Verde = 1;
            Azul = 1;
            break;
        case 4:
            Rojo = 0;
            Verde = 1;
            Azul = 1;
            break;
        case 2:
            Rojo = 1;
            Verde = 0;
            Azul = 1;
            break;
        case 1:
            Rojo = 1;
            Verde = 1;
            Azul = 0;
            break;
        case 7:
            Rojo = 0;
            Verde = 0;
            Azul = 0;
            break;
    }
}

char Pulsador()
{
    //Funcion que aciva un flag con el cambio del pulsador y guarda el pulsado en una variable
    pulsador = 0;

    if (antirrebote_A(PA)) {
        flagPulsador = 1;
        pulsador = 1;
        return 0;
    }
    if (antirrebote_V(PV)) {
        flagPulsador = 1;
        pulsador = 2;
        return 0;
    }
    if (antirrebote_R(PR)) {
        flagPulsador = 1;
        pulsador = 3;
        return 0;
    }

    pulsador = 0;
    flagPulsador = 0;
    return 0;
}

bool antirrebote_V(bool lectura)
{
    //Funcion que hace un anti rebote y detecta el cambio de un pulsador
    static bool lecant_v = 0;
 
    switch(estado_v) {
        case INICIO_P:
            //Si tengo un flanco ascendente
            if((lectura == 1) && (lecant_v == 0)) {
                estado_v = RISING_P;
            }
            break;
        case RISING_P:
            /*Devuelvo el estado uno , una unica vez (Saco el rebote)*/
            estado_v = RETENCION_P;
            tp_v = 0;
            return 1;   //Devuelvo el estado alto ya que tuve un flanco
        case RETENCION_P:
            /*Durante un segundo y siempre que la lectura siga siendo alta retengo*/
            if((tp_v >= 3) && (lectura == 0)) {
                estado_v = INICIO_P;
            }
            break;
    }
    lecant_v = lectura;   //Asigno el estado previo para el proximo ciclo..
    return 0;           //Devuelvo el estado nulo o cero
}

bool antirrebote_R(bool lectura)
{
    //Funcion que hace un anti rebote y detecta el cambio de un pulsador
    static bool lecant_r=0;
 
    switch(estado_r) {
        case INICIO_P:
            //Si tengo un flanco ascendente
            if((lectura == 1) && (lecant_r == 0)) {
                estado_r = RISING_P;
            }
            break;
        case RISING_P:
            /*Devuelvo el estado uno , una unica vez (Saco el rebote)*/
            estado_r = RETENCION_P;
            tp_r = 0;
            return 1;   //Devuelvo el estado alto ya que tuve un flanco
        case RETENCION_P:
            /*Durante un segundo y siempre que la lectura siga siendo alta retengo*/
            if((tp_r >= 3) && (lectura == 0)) {
                estado_r = INICIO_P;
            }
            break;
    }
    lecant_r = lectura;   //Asigno el estado previo para el proximo ciclo..
    return 0;           //Devuelvo el estado nulo o cero
}

bool antirrebote_A(bool lectura)
{
    //Funcion que hace un anti rebote y detecta el cambio de un pulsador
    static bool lecant_a = 0;
 
    switch(estado_a) {
        case INICIO_P:
            //Si tengo un flanco ascendente
            if((lectura == 1) && (lecant_a == 0)) {
                estado_a = RISING_P;
            }
            break;
        case RISING_P:
            /*Devuelvo el estado uno , una unica vez (Saco el rebote)*/
            estado_a = RETENCION_P;
            tp_a = 0;
            return 1;   //Devuelvo el estado alto ya que tuve un flanco
        case RETENCION_P:
            /*Durante un segundo y siempre que la lectura siga siendo alta retengo*/
            if((tp_a >= 3) && (lectura == 0)) {
                estado_a = INICIO_P;
            }
            break;
    }
    lecant_a = lectura;   //Asigno el estado previo para el proximo ciclo..
    return 0;           //Devuelvo el estado nulo o cero
}

void timer()
{
    //Funcion que detecta las interrupciones del timer
    times++;
    semilla ++;
    espera++;
    tp_a++;
    tp_v++;
    tp_r++;
}