Flip tile pattern game

Dependencies:   4DGL-uLCD-SE PinDetect SDFileSystem mbed-rtos mbed wave_player

main.cpp

Committer:
jsmith352
Date:
2015-10-22
Revision:
1:4e25bf8e016e
Parent:
0:96656a61e4e3

File content as of revision 1:4e25bf8e016e:

#include "mbed.h"
#include "rtos.h"
#include "PinDetect.h"
#include "uLCD_4DGL.h"
#include "SDFileSystem.h"
#include "wave_player.h"
#include "tile.h"
#include "cursor.h"

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DigitalOut led4(LED4);


#ifndef TILE_OFF
    #define TILE_OFF 0xFF0000
#endif
#ifndef TILE_ON
    #define TILE_ON  0x00FF00
#endif
#ifndef CURSOR
    #define CURSOR   0x0000CC
#endif

//uLCD
uLCD_4DGL lcd(p28, p27, p30);

// speaker
AnalogOut DACout(p18);

// SD card reader
SDFileSystem sd(p5, p6, p7, p8, "sd");

// wave player & FILE objects
wave_player waver(&DACout);
FILE *wave_file;

// 5 way tactical joystick
PinDetect up(p15);      // left  p17
PinDetect center(p19);  
PinDetect left(p20);    // down  p16
PinDetect down(p17);    // right p15
PinDetect right(p16);   // up    p20
// pause button
PinDetect pause(p21);

//tile objects
Tile GameBoard(p28, p27, p30);
bool gameSize;
bool changePattern;
bool unpause;
//cursor objects
Cursor gameCursor(p28, p27, p30);
int newCursor;
int oldCursor;
int oldCursorColor;

//function prototypes
void decideWhereUp();
void decideWhereLeft();
void decideWhereDown();
void decideWhereRight();

enum GameState {START, WAIT, SETUP, GAME, UPDATE, PAUSE, PAUSED, OVER};
/*State Definitions:
* START -- Creates the start screen
* WAIT  -- Waits after the start screen, mbed does nothing
* SETUP -- Sets up one time things
* GAME  -- User actually gets to play the game
* UPDATE-- Updates the screen
* PAUSE -- Pause the screen, gives the user the option to start over
* PAUSED-- Does nothing while game is paused
* OVER  -- Clears the screen, prints you win, goes back to start
*/
GameState GameStatus = START;

// Pushbutton callbacks
void up_hit_callback(void){
    led1 = !led1;
    switch(GameStatus){
        case WAIT:
            gameSize = true;
            GameStatus = SETUP;
            break;
        case GAME:
            if(GameBoard.drawCursor(newCursor) == true)
                oldCursorColor = TILE_ON;
            else
                oldCursorColor = TILE_OFF;
            oldCursor = newCursor;
            decideWhereUp();
            GameStatus = UPDATE;
            break;
    }
}

void center_hit_callback(void){
    switch(GameStatus){
        case GAME:
            changePattern = true;
            GameStatus = UPDATE;
            break;
        case PAUSED:
            //GameBoard.unpause();
            unpause = true;
            GameStatus = UPDATE;
            break;
    }
}

void left_hit_callback(void){
    led2 = !led2;
    switch(GameStatus){
        case GAME:
            if(GameBoard.drawCursor(newCursor) == true)
                oldCursorColor = TILE_ON;
            else
                oldCursorColor = TILE_OFF;
            oldCursor = newCursor;
            decideWhereLeft();
            GameStatus = UPDATE;
            break;
    }
}

void down_hit_callback(void){ //choose 4x4
    led3 = !led3;
    switch(GameStatus){
        case WAIT:
            gameSize = false;
            GameStatus = SETUP;
            break;
        case GAME:
            if(GameBoard.drawCursor(newCursor) == true)
                oldCursorColor = TILE_ON;
            else
                oldCursorColor = TILE_OFF;
            oldCursor = newCursor;
            decideWhereDown();
            GameStatus = UPDATE;
            break;
    }
}

void right_hit_callback(void){
    led4 = !led4;
    switch(GameStatus){
        case GAME:
            if(GameBoard.drawCursor(newCursor) == true)
                oldCursorColor = TILE_ON;
            else
                oldCursorColor = TILE_OFF;
            oldCursor = newCursor;
            decideWhereRight();
            GameStatus = UPDATE;
            break;
    }
}

void pause_hit_callback(void){
    switch(GameStatus){
        case WAIT:
            GameStatus = START;
            break;
        case GAME:
            GameStatus = PAUSE;
            break;
        case PAUSED:
            GameStatus = START;
            break;
    }
}

void lcdSetup(){
    lcd.baudrate(3000000);
    lcd.background_color(0);
    lcd.color(BLUE);
    lcd.text_width(1);
    lcd.text_height(1);
    //lcd.cls();
}


// Music thread
void music(void const *args){
    while(true){
        wave_file = fopen("/sd/myMusic/beethoven.wav", "r");
        waver.play(wave_file);
        fclose(wave_file);
        Thread::wait(1);
    }
}

int main(){
    // setup some modules
    //
    // LCD screen
    lcdSetup();
    wait(0.01);
    
    // Joystick & pushbutton setup
    pause.mode(PullUp);
    wait(0.01);
    up.attach_deasserted(&up_hit_callback);
    center.attach_deasserted(&center_hit_callback);
    left.attach_deasserted(&left_hit_callback);
    down.attach_deasserted(&down_hit_callback);
    right.attach_deasserted(&right_hit_callback);
    pause.attach_deasserted(&pause_hit_callback);
    up.setSampleFrequency();
    center.setSampleFrequency();
    left.setSampleFrequency();
    down.setSampleFrequency();
    right.setSampleFrequency();
    pause.setSampleFrequency();
    wait(0.01);
    
    Thread backgroundMusic(music);
    led1 = led2 = led3 = led4 = 0;
    
    // GAME
    while(true){
        switch(GameStatus){
            case START:
                lcd.cls();
                lcd.locate(0,0);
                lcd.printf("Flip Tile!!!\n\n");
                lcd.printf("Select Game mode:\n");
                lcd.printf("\tup for 3x3\n");
                lcd.printf("\tdown for 4x4\n");
                GameStatus = WAIT;
                break;
            case WAIT:
                break;
            case SETUP:
                lcd.cls();
                GameBoard.setNumberOfTiles(gameSize);
                gameCursor.number_of_circles = gameSize;
                GameBoard.reset();
                newCursor = 0;
                gameCursor.drawCircle(newCursor, CURSOR);
                GameStatus = GAME;
                changePattern = false;
                unpause = false;
                break;
            case GAME:
                if(GameBoard.win == true){
                    GameStatus = OVER;
                }
                break;
            case UPDATE:
                gameCursor.drawCircle(oldCursor, oldCursorColor);
                if(changePattern == true){
                    if(gameSize == true)
                        GameBoard.TilePattern3(newCursor);
                    else
                        GameBoard.TilePattern4(newCursor);
                    changePattern = false;
                }
                if(unpause == true){
                    lcd.cls();
                    GameBoard.unpause();
                    unpause = false;
                }
                gameCursor.drawCircle(newCursor, CURSOR);
                GameStatus = GAME;
                break;
            case PAUSE:
                lcd.cls();
                lcd.printf("Press button to\nstart a new game\n\n");
                lcd.printf("Press center to\nresume");
                GameBoard.pause();
                GameStatus = PAUSED;
                break;
            case PAUSED:
                break;
            case OVER:
                lcd.cls();
                lcd.printf("Completed!!!\n\n");
                lcd.printf("# of Moves: %d\n\n", GameBoard.getScore());
                lcd.printf("Press button for\nnew game");
                GameStatus = WAIT;
                break;
        }
    }
}

// ***************************************** //
//          FUNCTION DEFINITIONS             //
// ***************************************** //


void decideWhereUp(){
    switch(gameSize){
        case true:
            if((newCursor >= 0) && (newCursor <=5))
                newCursor = newCursor + 3;
            break;
            
        case false:
            if((newCursor >= 0) && (newCursor <= 11))
                newCursor = newCursor + 4;
            break;
    }
}

void decideWhereLeft(){
    switch(gameSize){
        case true:
            if((newCursor == 0) || (newCursor == 1) || (newCursor == 3) || (newCursor == 4) || (newCursor == 6) ||(newCursor == 7))
                newCursor = newCursor + 1;
            break;
            
        case false:
            if((newCursor == 0) || (newCursor == 1) || (newCursor == 2) ||
                (newCursor == 4) || (newCursor == 5) || (newCursor == 6) ||
                (newCursor == 8) || (newCursor == 9) || (newCursor == 10) ||
                (newCursor == 12) || (newCursor == 13) || (newCursor == 14))
                newCursor = newCursor + 1;
            break;
    }
}

void decideWhereDown(){
    switch(gameSize){
        case true:
            if((newCursor >= 3) && (newCursor <= 8))
                newCursor = newCursor - 3;
            break;
            
        case false:
            if((newCursor >= 4) && (newCursor <= 15))
                newCursor = newCursor - 4;
            break;
    }
}

void decideWhereRight(){
    switch(gameSize){
        case true:
            if((newCursor == 1) || (newCursor == 2) || (newCursor == 4) ||(newCursor == 5) || (newCursor == 7) || (newCursor == 8))
                newCursor = newCursor - 1;
            break;
            
        case false:
            if((newCursor == 1) || (newCursor == 2) || (newCursor == 3) ||
                    (newCursor == 5) || (newCursor == 6) || (newCursor == 7) ||
                    (newCursor == 9) || (newCursor == 10) || (newCursor == 11) ||
                    (newCursor == 13) || (newCursor == 14) || (newCursor == 15))
                newCursor = newCursor - 1;
            break;
    }
}