#include "Dungeon.h"
Dungeon::Dungeon()
{
//ctor
}
bool Dungeon::check(char** dungeon, char dir)
{
//Check if it is possible to make room in the direction(%dir) that was passed {{{
bool is_available;
switch(dir){
case 's':
is_available = y_pos + height <= D_HEIGHT && x_pos + width <= D_WIDTH;
if(is_available){
for (int y = y_pos; y < y_pos + height; y++){
for(int x = x_pos; x < x_pos + width; x++){
if (y == y_pos || y == y_pos + (height-1) || x == x_pos || x == x_pos + (width-1)) continue;
if (dungeon[y][x] != NOTHING) is_available = false;
}
}
}
break;
case 'S':
is_available = y_pos + height <= D_HEIGHT && x_pos - width >= 0;
if(is_available){
for (int y = y_pos; y < y_pos + height; y++){
for(int x = x_pos; x > x_pos - width; x--){
if (y == y_pos || y == y_pos + (height-1) || x == x_pos || x == x_pos - (width-1)) continue;
if (dungeon[y][x] != NOTHING) is_available = false;
}
}
}
break;
case 'n':
is_available = y_pos - height >= 0 && x_pos + width <= D_WIDTH;
if(is_available){
for (int y = y_pos; y > y_pos - height; y--){
for(int x = x_pos; x < x_pos + width; x++){
if (y == y_pos || y == y_pos - (height-1) || x == x_pos || x == x_pos + (width-1)) continue;
if (dungeon[y][x] != NOTHING) is_available = false;
}
}
}
break;
case 'N':
is_available = y_pos - height >= 0 && x_pos - width >= 0;
if(is_available){
for (int y = y_pos; y > y_pos - height; y--){
for(int x = x_pos; x > x_pos - width; x--){
if (y == y_pos || y == y_pos - (height-1) || x == x_pos || x == x_pos - (width-1)) continue;
if (dungeon[y][x] != NOTHING) is_available = false;
}
}
}
break;
}
return is_available;
//}}}
}
void Dungeon::genDungeon(char** &dungeon)
{
for (int y = 0; y<D_HEIGHT; y++){
for (int x = 0; x<D_WIDTH; x++){
dungeon[y][x] = NOTHING;
}
}
//Starting point
y_pos = rand() % D_HEIGHT;
x_pos = rand() % D_WIDTH;
do{
genRoom(dungeon);
}while(!dirs.empty());
}
void Dungeon::genRoom(char** &dungeon)
{
dirs.clear();
//S - south west; s - south east; N - north west; n - north east;
char s_w = 'S'; char s_e = 's'; char n_w = 'N'; char n_e = 'n';
char dir;
//Room width and height {{{
constexpr int MIN_WIDTH = D_WIDTH / 20;
constexpr int MIN_HEIGHT = D_HEIGHT / 20;
constexpr int MAX_WIDTH = D_WIDTH / 4;
constexpr int MAX_HEIGHT = D_HEIGHT / 4;
width = rand() % MAX_WIDTH + MIN_WIDTH;
height = rand() % MAX_HEIGHT + MIN_HEIGHT;
//}}}
//Store possible directions in %dirs vector {{{
if (check(dungeon, s_e)){
dirs.push_back(s_e);
}
if (check(dungeon, s_w)){
dirs.push_back(s_w);
}
if (check(dungeon, n_e)){
dirs.push_back(n_e);
}
if (check(dungeon, n_w)){
dirs.push_back(n_w);
}
//Break if there is no possible directions
if(dirs.empty()) return;
//}}}
//Make room in the randomly selected direction {{{
dir = dirs[rand()%dirs.size()];
switch (dir){
case 's':
for (int y = y_pos; y < y_pos + height; y++){
for (int x = x_pos; x < x_pos + width; x++){ //HOW THIS WORKS: It just draws WALL if current y||x pos is the first||last, i.e. y||x == starting_point or y||x == ending_point
if (y == y_pos || y == y_pos + (height-1) || x == x_pos || x == x_pos + (width-1)){
dungeon[y][x] = WALL;
}else{
dungeon[y][x] = FLOOR;
}
}
}
y_pos += (height - 1);
x_pos += (width - 1);
break;
case 'S':
for (int y = y_pos; y < y_pos + height; y++){
for (int x = x_pos; x > x_pos - width; x--){
if (y == y_pos || y == y_pos + (height-1) || x == x_pos || x == x_pos - (width-1)){
dungeon[y][x] = WALL;
}else{
dungeon[y][x] = FLOOR;
}
}
}
y_pos += (height - 1);
x_pos -= (width - 1);
break;
case 'n':
for (int y = y_pos; y > y_pos - height; y--){
for (int x = x_pos; x < x_pos + width; x++){
if (y == y_pos || y == y_pos - (height-1) || x == x_pos || x == x_pos + (width-1)){
dungeon[y][x] = WALL;
}else{
dungeon[y][x] = FLOOR;
}
}
}
y_pos -= (height - 1);
x_pos += (width - 1);
break;
case 'N':
for (int y = y_pos; y > y_pos - height; y--){
for (int x = x_pos; x > x_pos - width; x--){
if (y == y_pos || y == y_pos - (height-1) || x == x_pos || x == x_pos - (width-1)){
dungeon[y][x] = WALL;
}else{
dungeon[y][x] = FLOOR;
}
}
}
y_pos -= (height - 1);
x_pos -= (width - 1);
break;
}
//}}}
}