Last active
August 29, 2015 13:56
-
-
Save aciceri/9041809 to your computer and use it in GitHub Desktop.
Experimental dungeon generator written in C
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <stdio.h> | |
#include <time.h> | |
#define height_max 1000 | |
#define width_max 1000 | |
typedef enum {false, true} bool; | |
typedef struct { | |
int width, height; | |
char grid[height_max][width_max]; | |
} dungeon_t; | |
typedef struct { | |
int x, y, width, height; | |
} room_t; | |
typedef enum {nord, est, sud, ovest} direction_t; | |
int random_range(int a, int b); | |
void generate(dungeon_t* dungeon); | |
void print(dungeon_t dungeon); | |
int main(int argc, char **argv) { | |
if(argc != 3) { | |
printf("Usage: %s WIDTH HEIGHT\n", *argv); | |
return 127; | |
} | |
else { | |
dungeon_t dungeon; | |
dungeon.width = atoi(argv[1]); | |
dungeon.height = atoi(argv[2]); | |
generate(&dungeon); | |
print(dungeon); | |
return 0; | |
} | |
} | |
int random_range(int a, int b) { | |
return a + (rand() % (b - a)); | |
} | |
void generate(dungeon_t* dungeon) { | |
int i, x, y, start_x, start_y, width, height; | |
bool again; | |
int n_rooms = 8; | |
room_t rooms[n_rooms]; | |
direction_t direction; | |
srand((unsigned) time(NULL) * getpid()); | |
/* Fill the grid of '#' */ | |
for(y = 0; y < dungeon->height; y++) | |
for(x = 0; x < dungeon->width; x++) | |
dungeon->grid[y][x] = '#'; | |
/* Rooms generation */ | |
for(i = 0; i < n_rooms; i++) { | |
again = true; | |
/* Generate a room randomly */ | |
while(again) { | |
again = false; | |
start_x = random_range(1, dungeon->width - 15); | |
start_y = random_range(1, dungeon->height - 7); | |
width = random_range(2, 16); | |
height = random_range(2, 8); | |
for(y = start_y - 1; y < start_y + height + 1 && !again; y++) | |
for(x = start_x - 1; x < start_x + width + 1 && !again; x++) | |
if(dungeon->grid[y][x] == '.') | |
again = true; | |
} | |
rooms[i].x = start_x; | |
rooms[i].y = start_y; | |
rooms[i].width = width; | |
rooms[i].height = height; | |
/* Dig rooms */ | |
for(y = start_y; y < start_y + height; y++) | |
for(x = start_x; x < start_x + width; x++) | |
dungeon->grid[y][x] = '.'; | |
} | |
/* Corridors generation */ | |
for(i = 0; i < n_rooms - 1; i++) { | |
x = random_range(rooms[i].x, rooms[i].x + rooms[i].width); | |
y = random_range(rooms[i].y, rooms[i].y + rooms[i].height); | |
if(x < rooms[i + 1].x) | |
direction = est; | |
else if(x > rooms[i + 1].x + rooms[i + 1].width) | |
direction = ovest; | |
else if(y < rooms[i + 1].y) | |
direction = sud; | |
else if(y > rooms[i + 1].y + rooms[i + 1].height) { | |
direction = nord; | |
} | |
while(x < rooms[i + 1].x || x >= rooms[i + 1].x + rooms[i + 1].width || y < rooms[i + 1].y || y >= rooms[i + 1].y + rooms[i + 1].y + height) { | |
dungeon->grid[y][x] = '.'; | |
switch(direction) { | |
case nord: | |
y--; | |
break; | |
case est: | |
x++; | |
break; | |
case sud: | |
y++; | |
break; | |
case ovest: | |
x--; | |
break; | |
} | |
if(x == 1) | |
direction = est; | |
else if(y == 1) | |
direction = sud; | |
else if(x == dungeon->width - 2) | |
direction = ovest; | |
else if(y == dungeon->height - 2) | |
direction = nord; | |
else if(random_range(0, 101) < 50) { /* Manatthan change direction */ | |
if(random_range(0, 101) < 50) { /* Est - Ovest */ | |
if(x < rooms[i + 1].x) | |
direction = est; | |
else if(x > rooms[i + 1].x + rooms[i + 1].width) | |
direction = ovest; | |
else if(y < rooms[i + 1].y) | |
direction = sud; | |
else if(y > rooms[i + 1].y + rooms[i + 1].height) { | |
direction = nord; | |
} | |
} | |
else { /* Nord - Sud */ | |
if(y < rooms[i + 1].y) | |
direction = sud; | |
else if(y > rooms[i + 1].y + rooms[i + 1].height) { | |
direction = nord; | |
} | |
else if(x < rooms[i + 1].x) | |
direction = est; | |
else if(x > rooms[i + 1].x + rooms[i + 1].width) | |
direction = ovest; | |
} | |
} | |
else if(random_range(0, 101) < 10) { | |
switch(random_range(0, 4)) { | |
case 0: | |
direction = nord; | |
break; | |
case 1: | |
direction = est; | |
break; | |
case 2: | |
direction = sud; | |
break; | |
case 3: | |
direction = ovest; | |
break; | |
} | |
} | |
} | |
} | |
} | |
void print(dungeon_t dungeon) { | |
int y; | |
for(y = 0; y < dungeon.height; y++) | |
printf("%s\n", dungeon.grid[y]); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment