Almaraz Bettig TP1_Ejer3: Desactiva la Bomba

Dependencies:   mbed

main.cpp

Committer:
nicoalmaraz
Date:
2019-06-15
Revision:
2:88b9ec493af4
Parent:
1:917b402c9b00

File content as of revision 2:88b9ec493af4:

//Almaraz y Bettig
//TP1 Ejercicio 3: Bomba
#include "mbed.h"

char usuario[4]= {4}; //Vector donde se almacena los datos ingresados por el usuario
char patron[4]; //Vector donde se almacena el patron
char ganar=0; //Flag que indica que gané
char perder=0; //Flag que indica que perdí
char ingreso=0; //Variables que cuenta la cantidad de cosas ingresadas
char parpadeo=1; //Flag que indica que debo parpadear
unsigned char decenas=2; //Variable donde almaceno las decenas del display
unsigned char unidades=0; //Variable donde almaceno las unidades del display
int mili_segundos=0; //Variable de tiempo
char mili_segundos_display; //Variable de tiempo
char tiempo_multiplexado=0; //Variable de tiempo
int tiempo_parpadeo=0; //Variable de tiempo
char segundos=20; //Variable de tiempo
char cable_0_verificacion=0; //Flag que indica que ya corte el cable 0
char cable_1_verificacion=0; //Flag que indica que ya corte el cable 1
char cable_2_verificacion=0; //Flag que indica que ya corte el cable 2
char cable_3_verificacion=0; //Flag que indica que ya corte el cable 3

void indicadores_parpadeando();
void timer();
void generar_patron();
unsigned char codificacion();
void displays();
void reset_variables();
void analizo_cables();
void actualizar_valores_display ();

DigitalIn reset(PTE1);
DigitalIn cable_0(PTD1);
DigitalIn cable_1(PTD3);
DigitalIn cable_2(PTD2);
DigitalIn cable_3(PTD0);
DigitalOut led_verde(PTD5);
DigitalOut led_rojo(PTA13);
DigitalOut habilitacion_decenas(PTC0);
DigitalOut habilitacion_unidades(PTC7);
BusOut display(PTC9,PTC8,PTA5,PTA4,PTA12,PTD4,PTA1);

Ticker ticker;

int main()
{
    habilitacion_decenas=1;
    habilitacion_unidades=0;
    char bomba;
    char mostrado=0;
    long i=0;
    ticker.attach(&timer, 0.001);
    printf("Presione el pulsador Reset para iniciar el juego\r\n");
    while (true) {
        //Máquina de estados que analiza si gané o perdí
        switch(bomba) {
            default:
            case 0: //Espero a que se presione el pulsador de reset
                i++;
                if((cable_0+cable_1+cable_2+cable_3!=4)&&(mostrado==0)) {
                    mostrado=1;
                    printf("\r\nDeben estar todos los cables conectados para poder empezar a jugar\r\n");
                }
                if((reset==0)&&(cable_0+cable_1+cable_2+cable_3==4)) {
                    srand(i);
                    printf("\r\nDesconecte los cables en el orden correcto para desactivar la bomba\r\n");
                    printf("Tienes 20 segundos antes de que la bomba explete!\r\n");
                    //Reinicio todas las variables necesarias para un juego nuevo
                    bomba=2;
                    mostrado=0;
                    reset_variables();
                    generar_patron();
                    //printf("\r\nPatron:\r\n");
                    //printf("%d\r\n",patron[0]);
                    //printf("%d\r\n",patron[1]);
                    //printf("%d\r\n",patron[2]);
                    //printf("%d\r\n",patron[3]);
                }
                break;
            case 2://Me fijo si se desconectó algún cable o si se terminó el tiempo
                analizo_cables();
                if(usuario[ingreso]!=4)
                    bomba=3;
                //Si terminó el tiempo levanto el flag "perder"
                if(segundos==0) {
                    printf("\r\nSe acabo el tiempo! La bomba exploto\r\n");
                    bomba=3;
                }
                break;
            case 3://Analizo el dato ingresado
                //Si ingresé un cable mal
                if((usuario[ingreso]!=patron[ingreso])||(segundos==0)) {
                    //Si el dato es incorrecto levanto el flag "perder"
                    perder=1;
                    if(segundos!=0)
                        printf("\r\nCable Incorrecto! La bomba exploto\r\n");
                }
                //Si el dato es correcto sumo la variable "ingreso"
                if((usuario[ingreso]==patron[ingreso]) && (segundos)) {
                    ingreso++;
                    printf("Cable Correcto\r\n");
                    //Si ingresé los 4 datos bien levanto el flag "ganar"
                    if(ingreso==4) {
                        ganar=1;
                        printf("\r\nBuen trabajo, la bomba fue desactivada!\r\n");
                    } else
                        bomba=2;
                }
                if(ganar||perder) {
                    //Si terminó el juego indico que deben parpadear los indicadores con el flag "parpadeo"
                    printf("Presione el pulsador Reset para volver a jugar\r\n");
                    parpadeo=1;
                    tiempo_parpadeo=0;
                    mili_segundos_display=0;
                    bomba=0;
                    printf("\r\n--------------------------------------------------------\r\n");
                }
                break;
        }

        //Máquina de estados que controla los indicadores al usuario
        if(parpadeo)
            //Si el juego terminó hago parpadear al display y al led correspondiente
            indicadores_parpadeando();
        else
            //Si todavía la partida está en curso muetro el display con la función "displays"
            displays();
    }
}

void reset_variables()
//Reseteo variables para un juego nuevo
{
    ganar=0;
    perder=0;
    segundos=20;
    parpadeo=0;
    led_rojo=0;
    led_verde=0;
    cable_0_verificacion=0;
    cable_1_verificacion=0;
    cable_2_verificacion=0;
    cable_3_verificacion=0;
    ingreso=0;
    mili_segundos=0;
    usuario[0]=4;
    usuario[1]=4;
    usuario[2]=4;
    usuario[3]=4;
}

void generar_patron()
//Genero patrón
{
    char elementos=0;
    char n=0;
    for(elementos=0; elementos<4; elementos++) {
        patron[elementos]=rand()%4;
        for(n=0; n<elementos; n++) {
            if(patron[n]==patron[elementos])
                elementos--;
        }
    }
}

unsigned char codificacion(char numero)
//Se encarga de pasar de BCD a 7 segmentos
{
    switch(numero) { //Display A B C D E F G
        default:
        case 0:
            return 0b1111110;
        case 1:
            return 0b0110000;
        case 2:
            return 0b1101101;
        case 3:
            return 0b1111001;
        case 4:
            return 0b0110011;
        case 5:
            return 0b1011011;
        case 6:
            return 0b1011111;
        case 7:
            return 0b1110000;
        case 8:
            return 0b1111111;
        case 9:
            return 0b1111011;
    }
}

void actualizar_valores_display () {
    //Separo en decenas y unidades
    unidades=segundos%10;
    decenas=segundos/10;
    //Codifico los valores en 7 segmentos
    unidades=codificacion(unidades);
    decenas=codificacion(decenas);    
}

void displays()
//Se encarga de mostrar el tiempo en el display
{
    static char estado_display=0;
    //Switcheo cada 10ms entre decenas y unidade
    switch (estado_display) {
        default:
        case 0:
            display=unidades;
            if(mili_segundos_display==5) {
                habilitacion_unidades=0;
                habilitacion_decenas=1;
                mili_segundos_display=0;
                actualizar_valores_display();
                estado_display=1;
            }
            break;
        case 1:
            display=decenas;
            if(mili_segundos_display==5) {
                habilitacion_unidades=1;
                habilitacion_decenas=0;
                mili_segundos_display=0;
                actualizar_valores_display();
                estado_display=0;
            }
            break;
    }
}

void timer()
//Incrementa los contadores cada 1ms
{
    mili_segundos++;
    //Contador de segundos
    if((mili_segundos==1000)&&(parpadeo==0)) {
        segundos--;
        mili_segundos=0;
    }
    tiempo_parpadeo++;
    mili_segundos_display++;
}

void indicadores_parpadeando()
{
    static char estado_parpadeo=0;
    switch(estado_parpadeo) {
        default:
        case 0://Enciendo el display y el led que corresponde
            displays();
            led_verde=ganar;
            led_rojo=perder;
            //Espero 0.5 segundos y cambio de estado
            if(tiempo_parpadeo==500) {
                estado_parpadeo=1;
                tiempo_parpadeo=0;
            }
            break;
        case 1: //Apago los indicadores
            display=0;
            led_rojo=0;
            led_verde=0;
            //Espero 0.5 segundos y cambio de estado
            if(tiempo_parpadeo==500) {
                tiempo_parpadeo=0;
                estado_parpadeo=0;
            }
            break;
    }
}

void analizo_cables()
{
    if((cable_0==0)&&(cable_0_verificacion==0)) {
        usuario[ingreso]=0;
        cable_0_verificacion=1;
        printf("\r\nCable 0 desconectado\r\n");
    }
    if((cable_1==0)&&(cable_1_verificacion==0)) {
        usuario[ingreso]=1;
        cable_1_verificacion=1;
        printf("\r\nCable 1 desconectado\r\n");
    }
    if((cable_2==0)&&(cable_2_verificacion==0)) {
        usuario[ingreso]=2;
        cable_2_verificacion=1;
        printf("\r\nCable 2 desconectado\r\n");
    }
    if((cable_3==0)&&(cable_3_verificacion==0)) {
        usuario[ingreso]=3;
        cable_3_verificacion=1;
        printf("\r\nCable 3 desconectado\r\n");
    }
}