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

Revision:
0:a78403083f60
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Mar 17 17:57:51 2016 +0000
@@ -0,0 +1,446 @@
+#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);
+
+    }
+}
\ No newline at end of file