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
Diff: main.cpp
- 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