Random-number ordering game controlled via Bluetooth.

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

Fork of Random number ordering with Bluetooth by Anteneh Haile

main.cpp

Committer:
antenehtes
Date:
2016-03-17
Revision:
0:a78403083f60

File content as of revision 0:a78403083f60:

#include <string>
#include "mbed.h"
#include "uLCD_4DGL.h"
#include "wave_player.h"
#include "rtos.h"
#include "SDFileSystem.h"

DigitalOut led1(LED1);
DigitalOut led2(LED2);
uLCD_4DGL uLCD(p28,p27,p30);
SDFileSystem sd(p5, p6, p7, p8, "sd");
//BusOut mbedleds(LED1,LED2,LED3,LED4);
//BusOut/In is faster than multiple DigitalOut/Ins

Serial blue(p9,p10);
Serial pc(USBTX, USBRX);


AnalogOut DACout(p18);
wave_player waver(&DACout);
Ticker ticker;
Mutex lcd_mutex;
Mutex count_mutex;
int count = 0;
bool done = true;

int xloc = 60;
int yloc = 60;
int rv[9][4] = {{1,1,41,41},{43,1,84,41},{86,1,127,41},{1,43,41,84},{43,43,84,84},{86,43,127,84},{1,86,41,127},{43,86,84,127},{86,86,127,127}};
int spots[9] = {-1,-1,-1,-1,-1,-1,-1,-1,-1};
int emptyloc = -1;
int temploc = -1;

// Number print variables
int printx[9] = {2,8,14,2,8,14,2,8,14};
int printy[9] = {2,2,2,7,7,7,13,13,13};

// Menu variables
int selection = 0;
int difficulty = 1; // Default difficulty is hard
int setselect = 1;


void increment()
{
    count_mutex.lock();
    ++count;
    count_mutex.unlock();
}


void thread4(void const *args)
{
    while(true) {         // thread loop
        FILE *wave_file;
        string sfx = "/sd/club1.wav";
        wave_file=fopen(sfx.c_str(),"r");
        waver.play(wave_file);
        fclose(wave_file);
    }
}

int getInput()
{

    int direction = -1;

//    pc.printf("getInput()\n");
    pc.printf("blue.getc() = %d\n\n\n",blue.getc());
    while(direction < 0) {
        char bnum=0;
        char bhit=0;
        if (blue.getc()=='!') {
            pc.printf("first if\n");
            if (blue.getc()=='B') { //button data packet
                bnum = blue.getc(); //button number
                bhit = blue.getc(); //1=hit, 0=release
                if (blue.getc()==char(~('!' + 'B' + bnum + bhit))) { //checksum OK?
                    pc.printf("before switch\n");
                    pc.printf("bnum %d\n\n",bnum);
                    switch (bnum) {
                        case '1': //number button 1
                            if (bhit=='1') {
                                direction = 5;
                                pc.printf("fire");
                            }
                            break;
                        case '2': //number button 2
                            if (bhit=='1') {
                                //add hit code here
                            }
                            break;
                        case '3': //number button 3
                            if (bhit=='1') {
                                //add hit code here
                            }
                            break;
                        case '4': //number button 4
                            if (bhit=='1') {
                                //add hit code here
                            }
                            break;
                        case '5': //button 5 up arrow
                            if (bhit=='1') {
                                direction = 1;
                                pc.printf("up");
                            }
                            break;
                        case '6': //button 6 down arrow
                            if (bhit=='1') {
                                direction = 3;
                                pc.printf("down");
                            }
                            break;
                        case '7': //button 7 left arrow
                            if (bhit=='1') {
                                direction = 2;;
                                pc.printf("left");
                            }
                            break;
                        case '8': //button 8 right arrow
                            if (bhit=='1') {
                                direction = 0;
                                pc.printf("right");
                            }
                            break;
                        default:
                            break;
                    }
                }
            }
        }

        wait(0.01);
    }

    return direction;
}


void drawRectangles()
{
    for(int i = 0; i < 9; i++) {
        if(i != emptyloc)
            uLCD.filled_rectangle(rv[i][0],rv[i][1],rv[i][2],rv[i][3],BLUE);
        else
            uLCD.filled_rectangle(rv[i][0],rv[i][1],rv[i][2],rv[i][3],BLACK);
    }
}

// Registers joystick flick as a directino change
void updateLocations(int direction)
{
    temploc = emptyloc;

    if(direction == 0) {
        if(emptyloc !=2 && emptyloc != 5 && emptyloc != 8)
            emptyloc = emptyloc + 1; //new empty location
    } else if(direction == 3) {
        if(emptyloc != 6 && emptyloc != 7 && emptyloc !=8)
            emptyloc = emptyloc  + 3;
    } else if(direction == 2) {
        if(emptyloc != 0 && emptyloc != 3 && emptyloc != 6)
            emptyloc = emptyloc - 1;
    } else if(direction == 1) {
        if(emptyloc != 0 && emptyloc != 1 && emptyloc != 2)
            emptyloc = emptyloc - 3;
    }
}

// Updates spots array and reprints the numbers in the rectangles
void updateNumbers()
{
    //Flip empty box with box next to its number
    spots[temploc] = spots[emptyloc];
    spots[emptyloc] = 0;

    for(int i=0; i<9; i++) {
        uLCD.locate(printx[i],printy[i]);
        if(spots[i] != 0)
            uLCD.printf("%d",spots[i]);
    }
}

// Check if boxes are ordered correctly
int checkWinCondition()
{
    int winner = 1;

    for(int i=0; i<9; i++) {
        if(spots[i] != i)
            winner = 0;
    }

    return winner;
}

// For help when randomly generating the board
int already(int dist,int lookfor)
{
    int found = 0;

    for(int i=0; i<dist; i++) {
        if(spots[i] == lookfor)
            found = 1;
    }

    return found;
}

// Generates a gameboard based off of the difficulty settings
void generateBoard()
{

    srand(time(NULL));
    int ran = rand() % 9;

    if(difficulty == 0) {
        int easyspots[9] = {1,2,0,3,4,5,6,7,8};

        for(int i=0; i<9; i++) {
            spots[i] = easyspots[i];
        }

        emptyloc = 2;
        temploc = 2;
    } else {
        for(int i=0; i<9; i++) {
            // If already in the spots array
            while(already(i,ran) != 0)
                ran = rand() % 9;

            if(ran == 0) {
                emptyloc = i;
                temploc = i;
            }

            spots[i] = ran;
        }
    }

    uLCD.locate(4,7);
    uLCD.printf("Shuffling");
    wait(0.2);
    uLCD.locate(4,7);
    uLCD.printf("Shuffling..");
    wait(0.2);
    uLCD.locate(4,7);
    uLCD.printf("Shuffling....");
    wait(0.2);
    uLCD.cls();
    wait(0.2);
}

// Game loop
void game()
{
    drawRectangles();
    updateNumbers();

    int win = 0;

    while(1) {
        int direction = getInput();
        // If center button is clicked, keep checking
        if(direction == 5)
            break;

        updateLocations(direction);
        drawRectangles();
        updateNumbers();
        win = checkWinCondition();

        if(win == 1)
            break;

        wait(0.3);
    }
    uLCD.cls();
    wait(0.2);
    //uLCD.textbackground_color(BLACK);
//    uLCD.color(RED);
//    uLCD.locate(5,7);
//    uLCD.printf("Game Over!");


    if(win == 1) {
        //uLCD.locate(6,10);
//        uLCD.printf("You Won!");
        uLCD.media_init();
        uLCD.set_sector_address(0x001D, 0x5C06);
        uLCD.display_image(0,0);
    } else if(win == 0){
        uLCD.media_init();
        uLCD.set_sector_address(0x001D, 0x4C01);
        uLCD.display_image(0,0);
    }

    int direction = getInput();
    while(direction != 5)
        getInput();

    uLCD.cls();
    wait(0.2);
}

// Settings menu loop
void settings()
{
    uLCD.locate(5,4);
    uLCD.printf("Easy Mode");
    uLCD.locate(5,11);
    uLCD.printf("Hard Mode");

    if(setselect == 0)
        uLCD.line(22, 42, 106, 42, WHITE);
    else
        uLCD.line(22, 98, 106, 98, WHITE);

    int direction = getInput();

    while(direction !=5 ) {
        if(direction == 1 && setselect == 1) {
            uLCD.line(22, 98, 106, 98, BLACK);
            uLCD.line(22, 42, 106, 42, WHITE);
            setselect = 0;
        } else if(direction == 3 && setselect == 0) {
            uLCD.line(22, 42, 106, 42, BLACK);
            uLCD.line(22, 98, 106, 98, WHITE);
            setselect = 1;
        }

        direction = getInput();
    }

    difficulty = setselect;
    uLCD.cls();
    wait(0.2);
}

// Help screen loop
void help()
{
    uLCD.locate(1,1);
    uLCD.printf("Change difficulty in settings");
    uLCD.locate(1,4);
    uLCD.printf("Flick stick to\n move blocks");
    uLCD.locate(1,7);
    uLCD.printf("Empty block in\n top left");
    uLCD.locate(1,10);
    uLCD.printf("Click to reset\n back to menu");
    uLCD.locate(1,14);
    uLCD.printf("Click to return\n to menu now");

    int direction = getInput();

    while(direction != 5) {
        direction = getInput();
    }

    uLCD.cls();
    wait(0.2);
}


int main()
{
    uLCD.cls();  
    uLCD.baudrate(3000000);

    uLCD.textbackground_color(BLACK);
    uLCD.color(RED);

    uLCD.locate(4,4);
    uLCD.printf("Start Game");
    uLCD.locate(5,7);
    uLCD.printf("Settings");
    uLCD.locate(7,11);
    uLCD.printf("Help");
    uLCD.line(22, 42, 106, 42, WHITE);
    Thread thread4task(thread4);
    ticker.attach(&increment, 1.0);
    while(1) {

        int direction = getInput();

        while(direction == 0 || direction == 2)
            direction = getInput();

        // If clicked in
        if(direction == 5) {
            if(selection == 0) {
                uLCD.cls();
                wait(0.2);
                //uLCD.textbackground_color(BLUE);
                generateBoard();
                game();
            } else if(selection == 1) {
                uLCD.cls();
                wait(0.2);
                settings();
                selection = 0;
            } else if(selection == 2) {
                uLCD.cls();
                wait(0.2);
                help();
                selection = 0;
            }

            uLCD.locate(4,4);
            uLCD.printf("Start Game");
            uLCD.locate(5,7);
            uLCD.printf("Settings");
            uLCD.locate(7,11);
            uLCD.printf("Help");

            uLCD.line(22, 42, 106, 42, WHITE);
        } else if(direction == 1 && (selection == 1 || selection == 2)) {
            selection = selection-1;
            if(selection == 0) {
                uLCD.line(22, 42, 106, 42, WHITE);
                uLCD.line(22, 68, 106, 68, BLACK);
                uLCD.line(22, 98, 106, 98, BLACK);
            } else {
                uLCD.line(22, 42, 106, 42, BLACK);
                uLCD.line(22, 68, 106, 68, WHITE);
                uLCD.line(22, 98, 106, 98, BLACK);
            }
        } else if(direction == 3 && (selection == 0 || selection == 1)) {
            selection = selection+1;
            if(selection == 1) {
                uLCD.line(22, 42, 106, 42, BLACK);
                uLCD.line(22, 68, 106, 68, WHITE);
                uLCD.line(22, 98, 106, 98, BLACK);
            } else {
                uLCD.line(22, 42, 106, 42, BLACK);
                uLCD.line(22, 68, 106, 68, BLACK);
                uLCD.line(22, 98, 106, 98, WHITE);
            }
        }

        //Wait to essentialially debounce (want to flick switch)
        wait(0.3);

    }
}