Thomas Gill / Mbed 2 deprecated LabyrinthOfTheMinotaur

Dependencies:   N5110 PowerControl mbed

main.cpp

Committer:
ThomasBGill
Date:
2015-04-19
Revision:
9:3cad581b5419
Parent:
8:ee857f0147aa
Child:
10:59c874d006ab

File content as of revision 9:3cad581b5419:

#include "mbed.h"
#include "N5110.h"
#include "PowerControl/PowerControl.h"
#include "PowerControl/EthernetPowerControl.h"

//         vcc sce rst dc  mosi clk  led
N5110 lcd (p5, p6, p7, p8, p11, p13, p21);
InterruptIn Act (p22);
InterruptIn Start (p23);
InterruptIn Up (p24);
InterruptIn Down (p25);
InterruptIn Left (p26);
InterruptIn Right (p27);
AnalogIn Noise (p19);

#define USR_POWERDOWN (0x104)

#define WALL 0
#define FLOOR 1
#define ENTER 2
#define EXIT 3

#define RIGHT 0
#define LEFT 1
#define UP 2
#define DOWN 3

#define SOUTH 0
#define EAST 1

struct TILES {
    char    Symbol; // Symbol for this tile
    bool   Passable; // Can tile be walked on
};

TILES  TileList[] = {
    { '#', false },  // 0- WALL
    { '.', true},  // 1- FLOOR
    { '+', true }, // 2- ENTER
    { 'x', true },  // 3- EXIT
};


//Variables
int ActFlag = 0;
int StartFlag = 0;
int UpFlag = 0;
int DownFlag = 0;
int LeftFlag = 0;
int RightFlag = 0;

int map[84][48];

//Enterance coordinates
int enx;
int eny;

//Exit coordinates
int exx;
int exy;

int sx;
int sy;
int dir;

int n;

//Space type player is on
int pSpace;

//Player coordinates
int px;
int py;

//Power Saving
int semihost_powerdown()
{
    uint32_t arg;
    return __semihost(USR_POWERDOWN, &arg);
}

//ISR
void ActPressed()
{
    ActFlag = 1;
}
void StartPressed()
{
    StartFlag = 1;
}
void UpPressed()
{
    UpFlag= 1;
}
void DownPressed()
{
    DownFlag = 1;
}
void LeftPressed()
{
    LeftFlag = 1;
}
void RightPressed()
{
    RightFlag = 1;
}

void Walls()
{
    //Fill map with walls
    for(int i=0; i<84; i++) {
        for (int j=0; j<48; j++) {

            map[i][j] = WALL;
        }
    }
}

void Floors()
{
    //Fill map with floors
    for(int i=0; i<84; i++) {
        for (int j=0; j<48; j++) {
            map[i][j] = FLOOR;
        }
    }
}

void FlashPlayerLocation()
{

    lcd.setPixel(px,py);
    lcd.refresh();
    wait(0.5);
    lcd.clearPixel(px,py);
    lcd.refresh();
    wait(0.5);

}

void DrawMap()
{
    //Draw map on screen
    for(int i=0; i<84; i++) {
        for (int j=0; j<48; j++) {
            if(map[i][j] == FLOOR || map[i][j] == EXIT) {
                lcd.clearPixel(i, j);
            } else {
                lcd.setPixel(i, j);
            }
        }
    }

    lcd.refresh();
}

void FirstRoom()
{
    //Create initial room
    int si = rand()%25 + 1;
    int sj = rand()%15 + 1;

    int sw = rand()%5+5;
    int sh = rand()%5+5;

    for(int i = si, w = si + sw; i <w; i++) {
        for (int j = sj, h = sj + sh; j <h; j++) {
            map[i][j] = FLOOR;
        }
    }
    //Create enterance in room
    enx = rand()%sw + si;
    eny = rand()%sh + sj;
    map[enx][eny] = ENTER;
}

void ExitRoom()
{
    //Create exit room
    int si = rand()%50 + 30;
    int sj = rand()%25 + 20;

    int sw = rand()%5+5;
    int sh = rand()%5+5;

    for(int i = si, w = si + sw; i <w; i++) {
        for (int j = sj, h = sj + sh; j <h; j++) {
            map[i][j] = FLOOR;
        }
    }
    //Create exit in room
    exx = rand()%sw + si;
    exy = rand()%sh + sj;
    map[exx][exy] = EXIT;
}

void DungeonRoomBuilder()
{
    sx = rand()%84;
    sy = rand()%48;

    //Get length
    int sw = rand()%5 + 5;
    int sh = rand()%5 + 5;

    int b = 0;

    //Check each space. +1 to variable if wall. If total = w*h then build room
    for(int i = sx; i < sx + sw; i++) {
        for(int j = sy; j < sy + sh; j++) {
            if(map[i][j] == WALL) {
                b++;
            }
        }
    }
    if(b == sw*sh) {
        for(int i = sx; i < sx + sw; i++) {
            for(int j = sy; j < sy + sh; j++) {
                if(i < 84 && j < 48) {
                    map[i][j] = FLOOR;
                }
            }
        }
    }
}

void Neighbours()
{
    //Check neighbours
    n = 0;

    if(map[sx+1][sy] == FLOOR) {
        n++;
    }
    if(map[sx-1][sy] == FLOOR) {
        n++;
    }
    if(map[sx][sy+1] == FLOOR) {
        n++;
    }
    if(map[sx][sy-1] == FLOOR) {
        n++;
    }
}

void DeadEnds()
{
    for (int del = 20; del > 0; del--) {
        for(int i = 0; i < 84; i++) {
            for(int j = 0; j < 48; j++) {

                sx = i;
                sy = j;

                Neighbours();

                if(n < 2) {
                    map[i][j] = WALL;
                }
            }
        }
    }
}

void Border()
{

    for(int i = 0; i < 84; i++) {
        for(int j = 0; j < 48; j++) {

            if(i == 0 || i == 83 || j == 0 || j == 47) {

                map[i][j] = WALL;

            }
        }
    }
}

void RandFloor(int r)
{

    for(int space = rand()%50 + r; space > 0; space--) {

        int i = rand()% 84;
        int j = rand()% 48;

        if(rand()%2 == 0 && map[i][j] == WALL) {
            map[i][j] = FLOOR;
        }
    }

}

void Maze()
{
    for(int i = 0; i < 84; i+=2) {
        for(int j = 0; j < 48; j+=2) {

            if(map[i][j] == WALL) {
                map[i][j] = FLOOR;
            }

            dir = rand()%2; //South or east


            if(dir == SOUTH && j < 47 && map[i][j+1] == WALL) {
                map[i][j+1] = FLOOR;
            }
            if(dir == EAST && i < 84 && map[i+1][j] == WALL) {
                map[i+1][j] = FLOOR;
            }
        }
    }
}

void DungeonBuilder()
{

    FirstRoom();
    ExitRoom();

    int rn = rand()%20 + 10;

    for(int i = rn; i>0; i--) {
        DungeonRoomBuilder();
    }

    Maze();

    RandFloor(51);

    Border();

    DeadEnds();

}

void LabyrinthBuilder()
{

    FirstRoom();
    ExitRoom();

    DrawMap();
    wait(2.0);

    Maze();

    RandFloor(551);

    Border();

}

void World()
{
    Walls();

//LabyrinthBuilder();
    DungeonBuilder();

    px = enx;
    py = eny;

    wait(1.0);
}

void PlayerCamera()
{
    lcd.clear();

    int tile;

    for(int i = 0; i < 14; i++) {
        for(int j = 0; j < 6; j++) {

            if(i == 6 && j == 2) {
                lcd.printString("@", (6*i)+1, j);
            } else {
                int diffx = i - 6;
                int diffy = j - 2;

                if(px+diffx < 84 && px+diffx > 0 && py+diffy < 48 && py+diffy > 0) {
                    tile = map[px+diffx][py+diffy];
                } else {
                    tile = WALL;
                }
                lcd.printChar(TileList[tile].Symbol, (6*i)+1, j);
            }
        }
    }

    lcd.refresh();
}

void PlayerMove()
{
    if(Up) {
        int tile = map[px][py-1];
        if(TileList[tile].Passable) {
            py--;
        }
    }
    if(Down) {
        int tile = map[px][py+1];
        if(TileList[tile].Passable) {
            py++;
        }
    }
    if(Right) {
        int tile = map[px+1][py];
        if(TileList[tile].Passable) {
            px++;
        }
    }
    if(Left) {
        int tile = map[px-1][py];
        if(TileList[tile].Passable) {
            px--;
        }
    }


}

void StartMenu()
{

    if(Start) {
        lcd.clear();
        DrawMap();
        while(!StartFlag) {
            FlashPlayerLocation();
        }
        StartFlag = 0;
    }

}

int main()
{
    //Power Saving
    PHY_PowerDown ();
    int result = semihost_powerdown();

    Up.rise(&UpPressed);
    Down.rise(&DownPressed);
    Right.rise(&RightPressed);
    Left.rise(&LeftPressed);
    Start.rise(&StartPressed);



    //Generate random seed
    srand(Noise*1000000);

    //Initilize screen
    lcd.init();

    World();

    //Game loop
    while(1) {

        PlayerCamera();
        Sleep();
        if(UpFlag || DownFlag || RightFlag || LeftFlag) {

            UpFlag = 0;
            DownFlag = 0;
            RightFlag = 0;
            LeftFlag = 0;

            PlayerMove();
        }
        if(StartFlag) {

            StartFlag = 0;

            StartMenu();

        }

    }
}