Skip to content

Instantly share code, notes, and snippets.

@aciceri
Last active August 29, 2015 13:56
Show Gist options
  • Save aciceri/9041809 to your computer and use it in GitHub Desktop.
Save aciceri/9041809 to your computer and use it in GitHub Desktop.
Experimental dungeon generator written in C
#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