#include <cstdlib>
#include <ctime>
#include <iostream>
#include <curses.h>
#include <string>
using namespace std;
int map[80][25];
bool rM[80][25];
bool checked[80][25];
int tally;
int px = 0;
int py = 0;
void expand(int x, int y)
{
if (x >= 0 && y >= 0 && x < 80 && y < 25)
{
if (!checked[x][y])
{
checked[x][y] = true;
tally ++;
if (map[x-1][y] != 1)
{
expand(x-1,y);
}
if (map[x+1][y] != 1)
{
expand(x+1,y);
}
if (map[x][y-1] != 1)
{
expand(x,y-1);
}
if (map[x][y+1] != 1)
{
expand(x,y+1);
}
}
}
}
int sizeOfArea(int x, int y)
{
int size = 0;
tally = 0;
expand(x, y);
size = tally;
return size;
}
void gen()
{
for (int x = 0; x < 80; x++)
{
for (int y = 0; y < 25; y++)
{
checked[x][y] = false;
rM[x][y] = false;
map[x][y] = 1;
}
}
bool working = true;
int roomsMade = 0;
int att = 0;
while(working)
{
int nx = rand()%73+1;
int ny = rand()%18+1;
int w = 7 + rand() % 10;
int h = 7 + rand() % 7;
bool allowed = true;
if (nx + w > 79 || ny + h > 24)
{
allowed = false;
}
if (allowed)
{
for (int x = nx; x < nx + w; x++)
{
for (int y = ny; y < ny + h; y++)
{
if (rM[x][y])
{
allowed = false;
}
}
}
}
if (allowed)
{
roomsMade ++;
for (int x = nx + 1; x < nx + w - 1; x++)
{
for (int y = ny + 1; y < ny + h - 1; y++)
{
rM[x][y] = true;
map[x][y] = 0;
}
}
map[nx+(w/2)][ny+(h/2)] = 2;
}
att++;
if (att > 250)
{
working = false;
}
}
for (int x = 1; x < 79; x++)
{
for (int y = 1; y < 24; y++)
{
if (map[x][y] == 2)
{
bool success = false;
int att = 0;
while(!success)
{
att ++;
if (att > 5)
{
success = true;
}
bool r = false;
for (int i = x+1; i < x + 20; i++)
{
if (i < 80)
{
if (map[i][y] == 0)
{
success = true;
r = true;
for (int j = x; j < i; j++)
{
if (map[j][y] != 2)
{
map[j][y] = 0;
}
}
}
}
}
for (int i = y+1; i < y + 20; i++)
{
if (i < 25)
{
if (map[x][i] == 0)
{
success = true;
r = true;
for (int j = y; j < i; j++)
{
if (map[x][j] != 2)
{
map[x][j] = 0;
}
else
{
px = x;
py = j;
}
}
}
}
}
if (!r)
{
for (int i = x-1; x > x - 20; x--)
{
if (i >= 0)
{
if (map[i][y] == 0)
{
success = true;
for (int j = x; j > i; j--)
{
if (map[j][y] != 2)
{
map[j][y] = 0;
}
}
}
}
}
for (int i = y-1; y > y - 20; y--)
{
if (i >= 0)
{
if (map[x][i] == 0)
{
success = true;
for (int j = y; j > i; j--)
{
if (map[x][j] != 2)
{
map[x][j] = 0;
}
}
}
}
}
}
}
map[x][y] = 0;
}
}
}
//Chance to generate decrepit dungeon floor
if (rand()%100 > 95)
{
for (int x = 1; x < 79; x++)
{
for (int y = 1; y < 24; y++)
{
if (map[x][y] == 1)
{
if (map[x-1][y] == 0 || map[x-1][y-1] == 0 || map[x][y-1] == 0 || map[x+1][y] == 0)
{
if (map[x+1][y+1] == 0 || map[x+1][y-1] == 0 || map[x][y+1] == 0 || map[x-1][y+1] == 0)
{
map[x][y] = 5;
}
}
}
}
}
for (int x = 1; x < 79; x++)
{
for (int y = 1; y < 24; y++)
{
if (map[x][y] == 5)
{
if (rand()%100 > 75)
{
map[x][y] = 0;
}
else
{
map[x][y] = 1;
}
}
}
}
}
//Check map is acceptable size
if (sizeOfArea(px,py) < 500)
{
gen();
}
else
{
//Fill in the areas (for now) that aren't connected to the main chamber
//Later on, they will be flagged as vaults or side areas (so as to avoid stair placement at the very least)
for (int x = 0; x < 80; x++)
{
for (int y = 0; y < 25; y++)
{
if (!checked[x][y])
{
map[x][y] = 1;
}
else
{
if (map[x][y] == 0)
{
if (px == 0 || py == 0)
{
px = x;
py = y;
}
else
{
if (rand()%1000 > 995)
{
px = x;
py = y;
}
}
}
}
}
}
}
//Generate doors
for (int x = 0; x < 80; x++)
{
for (int y = 0; y < 25; y++)
{
if (map[x][y] == 0)
{
if (y - 1 > 0 && y + 1 < 25 && x - 1 > 0 && x + 1 < 80)
{
if (map[x][y-1] == 1 && map[x][y+1] == 1)
{
if (map[x-1][y-1] == 0 && map[x-1][y+1] == 0 && map[x+1][y] == 0)
{
if (rand()%10>7)
map[x][y] = 2;
}
if (map[x+1][y-1] == 0 && map[x+1][y+1] == 0 && map[x-1][y] == 0)
{
if (rand()%10>7)
map[x][y] = 2;
}
}
if (map[x-1][y] == 1 && map[x+1][y] == 1)
{
if (map[x-1][y-1] == 0 && map[x+1][y-1] == 0 && map[x][y+1] == 0)
{
if (rand()%10>7)
map[x][y] = 2;
}
if (map[x-1][y+1] == 0 && map[x+1][y+1] == 0 && map[x][y-1] == 0)
{
if (rand()%10>7)
map[x][y] = 2;
}
}
}
}
}
}
}
void draw(int x1, int y1, int w, int h)
{
for (int x = x1; x < x1+w; x++)
{
for (int y = y1; y < y1+h; y++)
{
if (x >= 0 && y >= 0 && x < 80 && y < 25)
{
move(y, x);
if (map[x][y] == 0)
{
attron(COLOR_PAIR(1));
addch(' ');
}
if (map[x][y] == 1)
{
attroff(A_BOLD);
attron(COLOR_PAIR(1));
addch('#');
}
if (map[x][y] == 2)
{
attron(COLOR_PAIR(2) | A_BOLD);
addch('+');
attroff(A_BOLD);
}
}
}
}
}
int main()
{
PDC_set_title("Roguelike");
srand ((unsigned int) time (NULL));
int ch = 0;
initscr();
curs_set(0);
if(has_colors() == FALSE || can_change_color() == FALSE)
{
endwin();
printf("You need color support to play this game.\n");
exit(1);
}
start_color();
init_pair(1, COLOR_WHITE, COLOR_BLACK);
init_pair(2, COLOR_RED, COLOR_BLACK);
init_pair(3, COLOR_GREEN, COLOR_BLACK);
raw();
keypad(stdscr, TRUE);
noecho();
gen();
draw(0,0,80,25);
while (ch != 27)
{
move(py, px);
attron(COLOR_PAIR(1) | A_BOLD);
addch('@');
ch = getch();
if (ch == 'r')
{
gen();
draw(0,0,80,25);
}
if (ch == 'o')
{
addch('o');
draw(px-2,py-2,3,3);
}
if (ch == KEY_LEFT)
{
if (map[px-1][py] == 0)
{
px--;
draw(px, py, 2, 1);
}
}
if (ch == KEY_RIGHT)
{
if (map[px+1][py] == 0)
{
px++;
draw(px - 1, py, 2, 1);
}
}
if (ch == KEY_UP)
{
if (map[px][py-1] == 0)
{
py--;
draw(px, py, 1, 2);
}
}
if (ch == KEY_DOWN)
{
if (map[px][py+1] == 0)
{
py++;
draw(px, py-1, 1, 2);
}
}
refresh();
}
endwin();
}