A game created using the uLCD and an Analog Joystick.

Dependencies:   4DGL-uLCD-SE mbed

main.cpp

Committer:
sjsm3
Date:
2014-10-21
Revision:
0:c034c9e5fb77

File content as of revision 0:c034c9e5fb77:

#include "mbed.h"
#include "uLCD_4DGL.h"
 
uLCD_4DGL uLCD(p9,p10,p11); // serial tx, serial rx, reset pin;

AnalogIn vert(p18);
AnalogIn horz(p19);
AnalogIn sel(p20);

// In current layout vert->0 = left, vert->1 = right, horz->0 = down, horz->1 = up
// 0=left 1=up 2=right 3=down

// Box variables
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;

// Waits until a big enough change in joystick to select direction
int getInput() {
    int direction = -1;
    
    while(direction < 0) {
        float v = vert.read();
        float h = horz.read();
        float s = sel.read();
        
        wait(0.01);
    
        if(v < .2)
            direction = 0;
        else if(v > .8)
            direction = 2;
        else if(h < .2)
            direction = 3;
        else if(h > .8)
            direction = 1;
        else if(s < .01)
            direction = 5;
    }
    
    return direction;
}

// Draws the rectanges on the screen
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 == 1) {
        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 == 3) {
        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!");
    }
    
    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);   
}

// Main menu loop
int main() {
    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);
    
    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);
           
    }
}