Gatech ECE 4180 Lab 4 Deal or No Deal Game -Alex Ferrara -Luke LeFeve

Dependencies:   4DGL-uLCD-SE SDFileSystem mbed wave_player

main.cpp

Committer:
AlexFerrara
Date:
2016-10-31
Revision:
6:a487ee40d30c
Parent:
5:610461a90e3a

File content as of revision 6:a487ee40d30c:

#include "mbed.h"
#include "uLCD_4DGL.h"
#include "SDFileSystem.h"
#include "wave_player.h"
#include <mpr121.h>
#include <algorithm>
DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);
DigitalIn pb1(p11);
DigitalIn pb2(p12);
FILE *wave_file;
SDFileSystem sd(p5, p6, p7, p8, "sd"); //SD card
AnalogOut DACout(p18);
wave_player waver(&DACout);
bool offer;
int myCaseKeyCode = 0;
volatile bool stateTrigger;       // true if hit , false if released
volatile int buttonValue;         // value of the pin touched.
int key_code;
void draw_case(int x, int y);
void draw_case_grid(void);
void draw_grid_info(void);
void draw_single_case(int caseNum);
void flashCase(int caseNum);
void draw_banker_screen(void);
void Case_Init(void);
void start_screen(void);
int bankOfferGen(void);
uLCD_4DGL uLCD(p28,p27,p30);
bool isCase[] = {false,false,false,false,false,false,false,false,false,false,false,false};
bool isOpen[] = {false,false,false,false,false,false,false,false,false,false,false,false};
int case_values[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
int prizes[] = {0, 5, 10, 20, 50, 100, 250, 500, 1000, 2500, 5000, 10000};
int current_value = 4;
int num_cases_picked = 0;
int num_cases_to_pick = 6;
// Create the interrupt receiver object on pin 26
InterruptIn interrupt(p26);

// Setup the i2c bus on pins 9 and 10
I2C i2c(p9, p10);

// Setup the Mpr121:
// constructor(i2c object, i2c address of the mpr121)
Mpr121 mpr121(&i2c, Mpr121::ADD_VSS);

void start_screen(){
    uLCD.media_init();
    uLCD.set_sector_address(0x003B, 0x9000);
    uLCD.display_image(0,0);
    uLCD.locate(1, 12);
    uLCD.text_mode(TRANSPARENT);
    uLCD.printf("Press Deal Button      to Start");
    wave_file=fopen("/sd/theme.wav","r");
    waver.play(wave_file);
    fclose(wave_file);
    while(pb1 == 1){};
    uLCD.cls();
    uLCD.set_sector_address(0x003B, 0x9041);
    uLCD.display_image(0,0);
    uLCD.text_mode(OPAQUE);
}

int G_HANDLE_HEIGHT = 1;
int G_HANDLE_LENGTH = 2;
int G_CASE_HEIGHT   = 2;
int G_CASE_LENGTH   = 3;
void draw_case(int x, int y, int scale, bool gold, bool open){
    int HANDLE_HEIGHT = G_HANDLE_HEIGHT * scale;
    int HANDLE_LENGTH = G_HANDLE_LENGTH * scale;
    int CASE_HEIGHT   = G_CASE_HEIGHT * scale;
    int CASE_LENGTH   = G_CASE_LENGTH * scale;
    int HANDLE_OFFSET = (CASE_LENGTH - HANDLE_LENGTH) /2;
    int c1,c2,c3;
    (gold) ? (c1=0xfff08c) : (c1=LGREY);
    (gold) ? (c2=0xc99700) : (c2=DGREY);
    (gold) ? (c3= 0xFFDF00) : (c3=WHITE);
    //handle
    uLCD.rectangle(x+HANDLE_OFFSET, y, x+HANDLE_OFFSET+HANDLE_LENGTH, y+HANDLE_HEIGHT, c1);
    //main section
    uLCD.filled_rectangle(x, y+HANDLE_HEIGHT, x+CASE_LENGTH, y+HANDLE_HEIGHT+CASE_HEIGHT, c3);    
    uLCD.rectangle(x, y+HANDLE_HEIGHT, x+CASE_LENGTH, y+HANDLE_HEIGHT+CASE_HEIGHT, c2);    
    //uLCD.printf("%d, %d",x+HANDLE_HEIGHT+(CASE_HEIGHT/2), y+CASE_LENGTH/2);
    if(open){
        uLCD.line(x,y,x+CASE_LENGTH,y+HANDLE_HEIGHT+CASE_HEIGHT,RED);        
        uLCD.line(x+1,y,x+CASE_LENGTH+1,y+HANDLE_HEIGHT+CASE_HEIGHT,RED);  
        uLCD.line(x-1,y,x+CASE_LENGTH-1,y+HANDLE_HEIGHT+CASE_HEIGHT,RED);    

        uLCD.line(x,y+HANDLE_HEIGHT+CASE_HEIGHT,x+CASE_LENGTH,y,RED);
        uLCD.line(x+1,y+HANDLE_HEIGHT+CASE_HEIGHT,x+CASE_LENGTH+1,y,RED);
        uLCD.line(x-1,y+HANDLE_HEIGHT+CASE_HEIGHT,x+CASE_LENGTH-1,y,RED);
    }
}

int text_offset_x = 7;
int text_offset_y = 4;
int xPos[] = {0,33,66,99};//,0,33,66,99,0,33,66,99};
int yPos[] = {0,33,66};//0,0,0,33,33,33,33,66,66,66,66};
char* caseLabel[] = {"1"," 2"," 3","4","5"," 6"," 7","8","9","10","11","12"};
int labelCol[] = {2,6,11,16};//,2,6,11,16,2,6,11,16};
int labelRow[] = {2,6,10};//2,2,2,6,6,6,6,10,10,10,10};
void draw_case_grid(void){
    //draw 12 case grid
    for(int i=0; i<12; i++){
        uLCD.text_mode(TRANSPARENT);
        draw_case(xPos[i%4]+text_offset_x,yPos[i/4]+text_offset_y,7,isCase[i],isOpen[i]);
        uLCD.text_string(caseLabel[i],labelCol[i%4],labelRow[i/4], NULL, BLACK);
    }     
    uLCD.text_mode(OPAQUE);
    draw_case(60,100,9, false, false);
    /*uLCD.locate(9,14);
    uLCD.textbackground_color(WHITE);
    uLCD.printf("%d",12);*/
    uLCD.textbackground_color(BLACK);
    uLCD.color(GREEN);
    uLCD.locate(0,13);
    uLCD.printf("%d cases",num_cases_to_pick-1);
    uLCD.locate(0,14);
    uLCD.printf("left to");
    uLCD.locate(0,15);
    uLCD.printf("pick");
    /*uLCD.locate(10,15);
    uLCD.printf("$%d",current_value);*/
}
void flashCase(int caseNum){
    int i = caseNum - 1;
    int scale = 8;
    int tempX = xPos[i%4]+text_offset_x-1;
    int tempY = yPos[i/4]+text_offset_y-1;
    int HANDLE_HEIGHT = G_HANDLE_HEIGHT * scale;
    int CASE_HEIGHT   = G_CASE_HEIGHT * scale;
    int CASE_LENGTH   = G_CASE_LENGTH * scale;
    for(int j=0;j<2;j++){
        uLCD.filled_rectangle(tempX,tempY,tempX+CASE_LENGTH+2,tempY+CASE_HEIGHT+HANDLE_HEIGHT+2,BLACK);
        wait(0.2);
        draw_single_case(i+1);
        wait(0.2);
    }
}
void draw_single_case(int caseNum){
    int i = caseNum-1;
    uLCD.text_mode(TRANSPARENT);
    draw_case(xPos[i%4]+text_offset_x,yPos[i/4]+text_offset_y,7,isCase[i],isOpen[i]);
    uLCD.text_string(caseLabel[i],labelCol[i%4],labelRow[i/4], NULL, BLACK);
}
void draw_grid_info(){
    //update case #, amount, cases left
    uLCD.text_mode(OPAQUE);
    uLCD.locate(10,15);
    uLCD.printf("        ");
    draw_case(60,100,9, false, false);
    uLCD.locate(9,14);
    uLCD.textbackground_color(WHITE);
    uLCD.printf("%d",key_code+1);
    uLCD.textbackground_color(BLACK);
    uLCD.color(GREEN);
    uLCD.locate(0,13);
    uLCD.printf("%d cases",num_cases_to_pick);
    uLCD.locate(0,14);
    uLCD.printf("left to");
    uLCD.locate(0,15);
    uLCD.printf("pick");
    uLCD.locate(10,15);
    uLCD.printf("$%d",case_values[key_code]);
}

int values[] = {0,5,10,20,50,100,250,500,1000,2500,5000,10000};
char* valuesStr[] = {"0","5","10","20","50","100","$ 250","$ 500","$  1k","$2.5k","$  5k","$ 10k"};
bool valueOpen[]= {false,false,false,false,false,false,false,false,false,false,false,false};
void update_bank_table(void){
    for(int i=0;i<12;i++){
        if(case_values[key_code] == values[i]){
        valueOpen[i] = true;
        break;}    
    }    
}
void draw_banker_screen(void){
    //uLCD.locate(0,0);
    //uLCD.printf("test");
    offer = true;
    for(int i=0;i<6;i++){
        uLCD.locate(0,i);
        (valueOpen[i]) ? uLCD.color(RED) : uLCD.color(GREEN);
        uLCD.printf("$%d",values[i]);
    }
    for(int i=6;i<12;i++){
        //int j = ((int) log10((double)values[i]) + 1);
        uLCD.locate(13,(i-6));
        (valueOpen[i]) ? uLCD.color(RED) : uLCD.color(GREEN);
        /*char* val;
        (values[i]>500) ? val=values[i] : valuesStr[i];*/
        uLCD.printf(valuesStr[i]);
    }
    wave_file=fopen("/sd/banker_calling.wav","r");
    waver.play(wave_file);
    fclose(wave_file);
    uLCD.color(GREEN);
    uLCD.locate(0,8);
    uLCD.printf("The banker's");
    uLCD.locate(0,9);
    uLCD.printf("offer is:");
    wait(1);
    wave_file=fopen("/sd/case_opened.wav","r");
    waver.play(wave_file);
    fclose(wave_file);
    uLCD.printf("$%d",bankOfferGen());
    
}

//initialize case values
void Case_Init()
{
    int A[12] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    srand(time(0));
    random_shuffle(&A[0], &A[12]);
    
 /*   num = rand() % 12 + 1;
    num = rand() % 12 + 1;
    uLCD.locate(0,0);
    uLCD.printf("%d", num);*/
    
    for(int i=0; i<12; i++)
        case_values[i] = prizes[A[i]];
        
}

int bankOfferGen(){
    float multiplier;
    int offer = 0;
    if(num_cases_picked == 6)
        multiplier = .36;
    else if(num_cases_picked == 8)
        multiplier = .28;
    else if(num_cases_picked == 10)
        multiplier = .36;
    else if(num_cases_picked == 11)
        multiplier = .42;
        
    for(int i=0; i<12; i++){
        if(!isOpen[i])
            offer += case_values[i];
    }
    
    offer = multiplier * (offer/(12 - num_cases_picked));
    
    return offer;
}

volatile int prevVal = 0;
// Key hit/release interrupt routine for MPR121
void fallInterrupt() {
 
//Only read the device when the previous interrupt has been handled by main
  //led1=led2=led3=led4=0;
  if (stateTrigger == false) {   // test global variable
    prevVal = buttonValue;
    buttonValue = mpr121.read(0x00);    
    buttonValue += mpr121.read(0x01)<<8;
    if(((buttonValue != prevVal) && buttonValue != 0) || (buttonValue ==0 && prevVal == 0))
    stateTrigger = true;   // set global variable
  }
}

int main() {
    //uLCD.baudrate(299999);
    //draw_case_grid();
    //wait(2);
    //flashCase(2);    
    //draw_banker_screen();
    pb1.mode(PullUp); pb2.mode(PullUp);
    start_screen();
    Case_Init();
    stateTrigger = false;   
    buttonValue = 0;             
    bool round1 = true;
    interrupt.mode(PullUp);              
    interrupt.fall(&fallInterrupt);            // Attach interrupt and its mode respectively.
    draw_case_grid(); 
    while (1) {
        if(pb1 == 0)
            led1 = !led1;
        if(pb2 == 0)
            led2 = !led2;
            
        while(offer){
            //wait for pb to update state as deal or no deal
            if(pb1 == 0 ) //deal
            {
                uLCD.locate(0,12);
                uLCD.printf("Congratulations,  you have accepted the offer!");   
            }
            if(pb2 == 0 ) //no deal
            {
                offer=false;
                uLCD.locate(0,12);
                uLCD.printf("Offer declined.   You won $%d",case_values[myCaseKeyCode]);
                uLCD.locate(0,14);
                uLCD.printf("from your case.");   
                /*draw_case_grid();
                stateTrigger == false; */
            }
        } 
    //Test for state change
    //led1=led2=1;
    //led3=led4=0;
    if (stateTrigger == true) {
        led1=led2=led3=led4=1;
        
    /*while(offer){
        //wait for pb to update state as deal or no deal
        if(key_code == 8) //deal
        {
            uLCD.locate(0,13);
            uLCD.printf("Congratulations,  you have accepted the offer");
            stateTrigger == false;
            break;   
        }
        if(key_code == 11 ) //no deal
        {
            offer=false;
            uLCD.cls();
            draw_case_grid();
            stateTrigger == false;
            break;
        }
    }*/  
        
        
        
        key_code=0;
        int i=0;
        int value=mpr121.read(0x00);
        value +=mpr121.read(0x01)<<8;
        // LED demo mod
        // puts key number out to LEDs for demo
        for (i=0; i<12; i++) {
            if (((value>>i)&0x01)==1) key_code=i;
        }
        current_value = case_values[key_code];
        led4=key_code & 0x01;
        led3=(key_code>>1) & 0x01;
        led2=(key_code>>2) & 0x01;
        led1=(key_code>>3) & 0x01;
        

 /*       if(offer && (key_code == 8) ) //deal
        {
            uLCD.locate(0,13);
            uLCD.printf("Congratulations,  you have accepted the offer");   
        }
        if(offer && (key_code == 11) ) //no deal
        {
            offer=false;
            uLCD.cls();
            draw_case_grid();
            stateTrigger == false;  
        }
 */       
        if(round1){
            isCase[key_code] = true;
            round1 = false;
            myCaseKeyCode = key_code;
        }
        else {
            isOpen[key_code] = true;
            draw_grid_info();
            /*wait(0.5);
            wave_file=fopen("/sd/case_opened.wav","r");
            waver.play(wave_file);
            fclose(wave_file);*/
            update_bank_table();
        }
        draw_single_case(key_code+1);
        num_cases_to_pick -= 1;
        num_cases_picked += 1;
        if(num_cases_picked>1 && num_cases_to_pick == 0){
            wait(2);
            uLCD.cls();
            uLCD.set_sector_address(0x003B, 0x9041);
            uLCD.display_image(0,0);
            draw_banker_screen(); 
        }
        
        //if(num_cases_picked == 1)
        //    num_cases_to_pick = 4;
        if(num_cases_picked == 6)
            num_cases_to_pick = 3;
        else if(num_cases_picked == 8)
            num_cases_to_pick = 2;
        else if(num_cases_picked == 10)
            num_cases_to_pick = 1;
        else if(num_cases_picked == 11)
            num_cases_to_pick = 1;
        
        stateTrigger = false; //main is done, release interrupt handler for next button
        }
    }// while
}// main