Difference between revisions of "Cellular Automata Method for Generating Random Cave-Like Levels"
m (Reverted edits by 46.33.241.195 (talk) to last revision by Recourse) |
|||
Line 1: | Line 1: | ||
It is an old and fairly well documented trick to use [http://en.wikipedia.org/wiki/Cellular_automaton cellular automata] to generate cave-like structures. The basic idea is to fill the first map randomly, then repeatedly create new maps using the 4-5 rule: a tile becomes a wall if it was a wall and 4 or more of its nine neighbors were walls, or if it was not a wall and 5 or more neighbors were. Put more succinctly, a tile is a wall if the 3x3 region centered on it contained at least 5 walls. Each iteration makes each tile more like its neighbors, and the amount of overall "noise" is gradually reduced: | |||
original: iteration 1: 2: 3: 4: | |||
# ### ## #### ########## #### ########## #### ########## #### ########## | |||
# ## ## ## # # # ##### # ### ####### ### ####### ### ####### | |||
# # ## #### # # # # #### # ## ###### ## ###### ## ###### | |||
# # # # ## # ### # ### # ## ##### ## ##### ## ##### | |||
### # # # # # # ##### ## ##### ## ##### ## ###### | |||
# # ## ##### ## ### #### # ## ##### ## ######## ## ######## | |||
## #### # # #### #### ## #### ### ## #### #### ## ######### | |||
## ## # ## # ## ### #### # ### ### ### ### #### ### ### ######### | |||
# ## ### # # ##### ### ### #### ##### ### #### ##### #### #### ######### | |||
# # # # # ### # ### ########## ###### ######### ##### ######### #### ######### | |||
## ## #### # # ##### ####### #### ######## #### ######## #### ######## | |||
#### # # # # # # ####### ## ###### ## ####### ## ####### | |||
# ## ## # ##### # ###### # ###### # ###### | |||
# # # #### ##### # ###### # ###### # ###### | |||
# # # ## ###### # ####### # ####### ## ####### ## ####### | |||
# # # #### # ################ ################ ################ ################ | |||
If the map | If 45% of the original random map contains walls and the process is repeated 5 times, the output might look like the following: | ||
############################################################ | ############################################################ | ||
Line 37: | Line 52: | ||
############################################################ | ############################################################ | ||
The problem is | The problem is that the results are inconsistent. The algorithm prone to generating disconnected maps: | ||
############################################################ | ############################################################ | ||
Line 70: | Line 85: | ||
############################################################ | ############################################################ | ||
It also sometimes generates maps which consist of one huge open space: | |||
############################################################ | ############################################################ | ||
Line 103: | Line 118: | ||
############################################################ | ############################################################ | ||
We can fix the disjoint segments problem in one of three ways. Either throw away maps that have disjoint segments in them, connect | We can fix the disjoint segments problem in one of three ways. Either throw away maps that have disjoint segments in them, connect the segments after the fact, or fill in all but the biggest segment. We can't just retry when we get a disjoint map, because if the map is big then, statistically, that will be almost 100% of the time. Filling in all but the biggest segment will tend to produce a small area in a map that was supposed to be big. Connecting up the regions works, but it tends to look unnatural, as in the example from above, now connected: | ||
############################################################ | ############################################################ | ||
Line 153: | Line 168: | ||
Or more formally, | Or more formally, | ||
* Rn(p) = the number of tiles | * Rn(p) = the number of tiles within n steps of p which are walls | ||
* W?(p) = R1(p)?5 || R2(p)=0 | * W?(p) = R1(p)?5 || R2(p)=0 | ||
Line 379: | Line 394: | ||
Finally, here is the C program I used to try out different parameters. Before putting this into an actual game, handling of disconnected regions is needed. | Finally, here is the C program I used to try out different parameters. Before putting this into an actual game, handling of disconnected regions is needed. | ||
<pre> | |||
#include <stdio.h> | #include <stdio.h> | ||
#include <stdlib.h> | #include <stdlib.h> | ||
Line 443: | Line 459: | ||
for(yi=1; yi<size_y-1; yi++) | for(yi=1; yi<size_y-1; yi++) | ||
for(xi=1; xi<size_x-1; xi++) | for(xi=1; xi<size_x-1; xi++) | ||
{ | |||
int adjcount_r1 = 0, | |||
adjcount_r2 = 0; | |||
for(ii=-1; ii<=1; ii++) | |||
for(jj=-1; jj<=1; jj++) | for(jj=-1; jj<=1; jj++) | ||
{ | |||
if(grid[yi+ii][xi+jj] != TILE_FLOOR) | |||
adjcount_r1++; | |||
} | |||
for(ii=yi-2; ii<=yi+2; ii++) | |||
for(jj=xi-2; jj<=xi+2; jj++) | |||
{ | |||
if(abs(ii-yi)==2 && abs(jj-xi)==2) | |||
continue; | |||
if(ii<0 || jj<0 || ii>=size_y || jj>=size_x) | |||
continue; | |||
if(grid[ii][jj] != TILE_FLOOR) | |||
adjcount_r2++; | |||
} | |||
if(adjcount_r1 >= params->r1_cutoff || adjcount_r2 <= params->r2_cutoff) | |||
grid2[yi][xi] = TILE_WALL; | |||
else | |||
grid2[yi][xi] = TILE_FLOOR; | |||
} | |||
for(yi=1; yi<size_y-1; yi++) | |||
for(xi=1; xi<size_x-1; xi++) | |||
grid[yi][xi] = grid2[yi][xi]; | |||
} | |||
void printfunc(void) | |||
{ | |||
int ii; | |||
printf("W[0](p) = rand[0,100) < %i\n", fillprob); | |||
for(ii=0; ii<generations; ii++) | |||
{ | |||
printf("Repeat %i: W'(p) = R[1](p) >= %i", | |||
params_set[ii].reps, params_set[ii].r1_cutoff); | |||
if(params_set[ii].r2_cutoff >= 0) | |||
printf(" || R[2](p) <= %i\n", params_set[ii].r2_cutoff); | |||
else | |||
putchar('\n'); | |||
} | |||
} | |||
void printmap(void) | |||
{ | |||
int xi, yi; | |||
for(yi=0; yi<size_y; yi++) | |||
{ | |||
for(xi=0; xi<size_x; xi++) | |||
{ | |||
switch(grid[yi][xi]) { | |||
case TILE_WALL: putchar('#'); break; | |||
case TILE_FLOOR: putchar('.'); break; | |||
} | |||
} | |||
putchar('\n'); | |||
} | |||
} | |||
int main(int argc, char **argv) | |||
{ | |||
int ii, jj; | |||
if(argc < 7) { | |||
printf("Usage: %s xsize ysize fill (r1 r2 count)+\n", argv[0]); | |||
return 1; | |||
} | |||
size_x = atoi(argv[1]); | |||
size_y = atoi(argv[2]); | |||
fillprob = atoi(argv[3]); | |||
generations = (argc-4)/3; | |||
params = params_set = (generation_params*)malloc( sizeof(generation_params) * generations ); | |||
for(ii=4; ii+2<argc; ii+=3) | |||
{ | |||
params->r1_cutoff = atoi(argv[ii]); | |||
params->r2_cutoff = atoi(argv[ii+1]); | |||
params->reps = atoi(argv[ii+2]); | |||
params++; | |||
} | |||
srand(time(NULL)); | |||
initmap(); | |||
for(ii=0; ii<generations; ii++) | |||
{ | |||
params = ¶ms_set[ii]; | |||
for(jj=0; jj<params->reps; jj++) | |||
generation(); | |||
} | |||
printfunc(); | |||
printmap(); | |||
return 0; | |||
} | } | ||
</pre> | |||
(Original article by [[Jim Babcock]]) | |||
==Tips== | |||
I used this method on my game ([[Arcan Myth RL]] but only in developing version) but I limited the repetition cycle to 3: I like the result very much and I don't have the problem about big isolated cave. However very good method. Thank you :-) --[[Provolik]] | |||
==External Links== | |||
* [http://pixelenvy.ca/wa/ca_cave.html Implementation of cave generation using cellular automata in Python] | |||
[[Category:Articles]] | |||
[[Category:WorldGeneration]] |
Revision as of 21:55, 29 August 2011
It is an old and fairly well documented trick to use cellular automata to generate cave-like structures. The basic idea is to fill the first map randomly, then repeatedly create new maps using the 4-5 rule: a tile becomes a wall if it was a wall and 4 or more of its nine neighbors were walls, or if it was not a wall and 5 or more neighbors were. Put more succinctly, a tile is a wall if the 3x3 region centered on it contained at least 5 walls. Each iteration makes each tile more like its neighbors, and the amount of overall "noise" is gradually reduced:
original: iteration 1: 2: 3: 4: # ### ## #### ########## #### ########## #### ########## #### ########## # ## ## ## # # # ##### # ### ####### ### ####### ### ####### # # ## #### # # # # #### # ## ###### ## ###### ## ###### # # # # ## # ### # ### # ## ##### ## ##### ## ##### ### # # # # # # ##### ## ##### ## ##### ## ###### # # ## ##### ## ### #### # ## ##### ## ######## ## ######## ## #### # # #### #### ## #### ### ## #### #### ## ######### ## ## # ## # ## ### #### # ### ### ### ### #### ### ### ######### # ## ### # # ##### ### ### #### ##### ### #### ##### #### #### ######### # # # # # ### # ### ########## ###### ######### ##### ######### #### ######### ## ## #### # # ##### ####### #### ######## #### ######## #### ######## #### # # # # # # ####### ## ###### ## ####### ## ####### # ## ## # ##### # ###### # ###### # ###### # # # #### ##### # ###### # ###### # ###### # # # ## ###### # ####### # ####### ## ####### ## ####### # # # #### # ################ ################ ################ ################
If 45% of the original random map contains walls and the process is repeated 5 times, the output might look like the following:
############################################################ ###....####################################.....############ ##......######################..#########.........########## ##......#####################....#######...........####.#### ##......###################.........................##...### ##......##################..........................###...## #........##############.............................###...## #........#############...............................#....## ##.......##############..................................### ##.......###..############..............................#### ##.......##....############.............................#### #..............############...###........................### #...............###########..#####...............##.......## #................#################...............##.......## ##.....#####..........###########....#..........###.......## ##....#######...........########....###.........####......## ##....#######............######....####........#####......## ##....#######.............####....#####.......#####......### #......######..............###....####........####......#### #.......######.............###...####.........###.......#### #........#####.............###..####.....................### ##........####..............#...####.....................### #####......##...................####.....................### ######...........................##.....................#### ######..................................................#### ######.........###.....................####.............#### ######......#########.................######............#### #######....#############.......##############.....###..##### ##############################################..############ ############################################################
The problem is that the results are inconsistent. The algorithm prone to generating disconnected maps:
############################################################ #####################################################..##### #####.....##################...###############............## #####......###########.####....########.#####..............# #####.......#########..###.....###############.............# ####.............#####.###....###################.........## ###...............########...####################........### ##.................#######...####################........### ##.......##.........#####.....##################.........### ##......####.........###.......################...........## ##.....########.................#######..######...........## ##...###########................######...#######..........## #########..######..............######....########........### ########....######..#####......#####.....##########......### #######......#############.....#####.....###########.....### #######.......############......###.......###########.....## #######.......###########.......###.......###########.....## ######.......####..######.......####.......#########......## #####.......####....#####.......####..........######.....### ####........####......####......####...........#####.....### ####.........###.......###......####...##......######.....## ####...##.....###.......#......###########.....#######.....# #####.####.....#####...........############....########....# ##########.....######..........############....#########..## #########.......#####...........##########.....############# #########.......####...............#####........############ ##########......####................###...........########## ###########....#####.....######.....####...........######### ################################...##########.....########## ############################################################
It also sometimes generates maps which consist of one huge open space:
############################################################ ############################################################ #################.####.######..######........############### ########...#####...##...####....####..........######...##### ###.####...####....###..####....####..........#####.....#### ##...###....##.....###...##.....###............###......#### ###.####...........###..........###.....###.........######## ########...........###...........#.......#.........######### #######.............#..............................######### ######.....##..........................................##### ###.......###...........................................#### ##.......####...........................................#### ##......................................................#### ##.....................................................##### ##.....................................................##### #.....................................##...............##### #.....................................##................#### #...........................###......###................#### ##...........###............###.....#####...............#### ###...........#..............##.....######............###### ######.......................##......######........######### ##########..................##.........#####......########## ###########................###..........####......########## ############................#...........####......########## ###.....#####.........##...............#####.......####..### ###.....#####.......#####.............#####..............### ###.....####.......#####..............#####.....##.......### ####...#####.......#####.....#####...######....####.....#### #############.##########....################..############## ############################################################
We can fix the disjoint segments problem in one of three ways. Either throw away maps that have disjoint segments in them, connect the segments after the fact, or fill in all but the biggest segment. We can't just retry when we get a disjoint map, because if the map is big then, statistically, that will be almost 100% of the time. Filling in all but the biggest segment will tend to produce a small area in a map that was supposed to be big. Connecting up the regions works, but it tends to look unnatural, as in the example from above, now connected:
############################################################ #####################################################..##### #####.....##################...###############............## #####......###########.####....########....................# #####.......#########..###.....###############.............# ####.............####..###....###################.........## ###...............###.####...####################........### ##.................##.####...####################........### ##.......##.........#.###.....##################.........### ##......####..........##.......################...........## ##.....########.................#######..######...........## ##...###########................######...#######..........## #########..######..............######....########........### ########............#####......#####.....##########......### #######......#############...............###########.....### #######.......############......###.......###########.....## #######.......###########.......###.......###########.....## ######.......####..######.......####.......#########......## #####.......####....#####.......####.....................### ####........####......####......####...........#####.....### ####.........###.......###......####...##......######.....## ####...##.....###.......#......###########.....#######.....# #####.####.....#####...........############....########....# ##########.....######..........############....#########..## #########.......#####...........##########.....############# #########.......####...............#####........############ ##########......####................###...........########## ###########....#####.....######.....####...........######### ################################...##########.....########## ############################################################
The solution to both problems, as it turns out, is to revisit the original cellular automata rules. Recall that the original rule was
- There is a wall initially at P with 45% probability
- In the next generation, there is a wall at spot P if the number of tiles around P which are walls is at least 5
Or, in more compact notation:
- Winit(p) = rand[0,100) < 45
- R(p) = the number of tiles within 1 step of p which are walls
- W?(p) = R(p) ? 5
Now, one of the problems was that we tend to get big, open areas. So why not try filling those areas in? Change the rule to
- W?(p) = R(p) ? 5 or p is in the middle of an open space
Or more formally,
- Rn(p) = the number of tiles within n steps of p which are walls
- W?(p) = R1(p)?5 || R2(p)=0
So how does it look?
Winit(p) = rand[0,100) < 45 Repeat 5: W?(p) = R1(p) ? 5 || R2(p) ? 1
############################################################ ##....###################################################### #.......###..#####..####....###########################..### #...#.........###.............##########..############....## ##...###...#..###..............########....######..###....## ###...######...#..##...........######.....######....###..### ####..######......##..##........####...#..######....######## ####..###.#.......#...##...#.....##...###..######...######## #####.........##...........##........####.....##.....####### #####.........##...........#.......##.....#.............#### ####...###...##................#...##......###...........### ####...###..##...###....##.....##..##..##..###....##.....### #########..###..####...###.............###..##..####.....### ########...##..#####...##...............#...#...####....#### #######........######......###...##....................##### #######..##.....######....##########...................##### ######..####.......####...#########...................###### ####....####..##....##.....#######...##..............####### ###.....###..#####......#...####....##................###### ##..##..###..###........##.........#....#......##......##### #..####..##...##.................###...##.....####......#### #.....#..###..#..##..........#..###..###.....#####......#### ##.......####.....#...##........##..###....#######......#### ######....###.......................###...#######....####### #######......................##.....###...#######...######## ########.................#######....####...#####....######## ########..............###########..######...........######## #########....####....######################........######### ###################.######################################## ############################################################
This is more interesting - it doesn't have any big open areas, it has a decent layout. It's almost fully connected. Still, it has some new problems: there are isolated single-tile walls in places, and in general it's not very smooth. But with a little tweaking:
Winit(p) = rand[0,100) < 40 Repeat 4: W?(p) = R1(p) ? 5 || R2(p) ? 2 Repeat 3: W?(p) = R1(p) ? 5
############################################################ ###...###########..#############################.....####### ##..........####....################..#########.........#### ##...........##.....####..#########.......####..######...### ##.......#..........###....###.................########..### ##......###........###........................#########..### ##.......##.........#........................##########...## ##.......###...........##.............###....#########.....# ##.......######.......####...........#####....#####........# ###.....#########....#####...........######...#####........# ###########################...........#####...#######.....## #############...###########.............##....########....## ############.........#######...................#######....## ###########...........########......###............##....### ###..#####.............#########...##########............### ##....###...............######################..........#### ###..........................######..#########..........#### ####..........................###.....#######...........#### ####.................##................##................### ####...###..........####...............#..................## ###...#####.........####..............##......##...........# ##....########......#####............####....####..........# ##....#########.....#####............####....####..........# ##.....######.......#####.............##.....####...##.....# ##......##..........#####....................####..####....# ###.................####.........###........############..## ###............##..######.###...############################ ####..........############################################## ######..#################################################### ############################################################
Notice that the initial fill percentage is a little lower, the cutoffs are different, and we switch rules after a few generations. This is more like the desired result. So, with these parameters, I give you some more samples, at various sizes.
############################## ##..###....###.....########### #...........................## #.................##.........# ##..###..........#######.....# ########.........#######.....# ############......####......## #############...............## ###..########...............## ##....#######...###..#......## ##.....######...#######.....## ##......#####...######......## ##...#...###....#####.......## ##..##.........######.......## ##..........##########......## ###........#####..####.....### ###........####....###.....### ###....##...##.....###.....### ###...####........####......## ###...#####......#####......## ##....#####.....#####.......## ##.....###.....####.........## ##..............##..........## ###.........................## ####........................## ####.......................### ####..........##...........### #####...###..####.........#### ####################.....##### ##############################
############################################################ #########......###...##........####...####.....############# ####............................##.....##............####### ###................###.....##..........................##### ###...............#####...####..........................#### ###...............#####....####............#............#### ####...###.........####.......##.......................##### ##########..........###........##.....................###### ##########...........#..........##...................####### #########.......................#####..............######### ######.........................#######...#......############ #####..........................############....############# ####...........................###########......######..#### ###..........##.................#########................### ##.......#######........#..........######...###.........#### ##......########.......##............###...######.....###### ###.....#######...............#####........########..####### ###......#####...##...........######........################ ###......#####..####...........#####.........############### #######..#####..####............###...........#######....### ########..###...#####......###.................#####......## ########.......######......####.................###.......## ########.......######.......##....##..................##..## #######.......######....##.......####................####..# ######.......#######....###......####..........###..#####..# #####........######.....######....##..........##########...# ######........###........######...............########.....# ##########...............#######.............########.....## #############...#######..###########...##################### ############################################################
################################################################ #######..#####............####..####...###....###########...#### ###......####..................................#########.....### ##.......###.......................................####......### ##......####.............##.........................##......#### ##......#####......##...####................##..............#### ##......##############..#####...............###.............#### ##.....###############...#####...............##........##...#### ##.....################..######.........#.............####...### ##.....################...#####........###............####....## ###.....#####..##...##....####.........###.............###....## ####....####..............###..........###...................### ####....####.............####..........##....................### ###.....####...........#####.........................##.....#### ##.......##............#####....................##..####...##### ##.....................######................###########...##### ###..##........##......###############.....############....##### ########......####....#################..###############..###### #########...#################################################### ################################################################
############################################################ #########......###...##........####...####.....############# ####............................##.....##............####### ###................###.....##..........................##### ###...............#####...####..........................#### ###...............#####....####............#............#### ####...###.........####.......##.......................##### ##########..........###........##.....................###### ##########...........#..........##...................####### #########.......................#####..............######### ######.........................#######...#......############ #####..........................############....############# ####...........................###########......######..#### ###..........##.................#########................### ##.......#######........#..........######...###.........#### ##......########.......##............###...######.....###### ###.....#######...............#####........########..####### ###......#####...##...........######........################ ###......#####..####...........#####.........############### #######..#####..####............###...........#######....### ########..###...#####......###.................#####......## ########.......######......####.................###.......## ########.......######.......##....##..................##..## #######.......######....##.......####.........##.....####..# #####........#######....###......####........#####..#####..# ####........#######.....######...#####.......############..# ####.......######..........####..#########..#############..# ###........#####............###..########################.## ##.........####.............###..################.######..## #....###...####......####....#...######..#######...#####..## #.....#.....##......######.......#####....#####....#####..## #...................######........####....###.....#####...## #....................#####........#####..###......##......## #....................######........########................# ##......#............########.......#######................# ##......##...........#########......#######...............## ###.....#............####...##.....#######..##...........### ###..........#......####...........######..####..........### ##..........####....####...........#####..######.........### ##...........####..#####............##....######.........### ##............###..######......#...........####..........### ##............###..#######.....##........................### ##.......###...#....#######....#..........................## ###......###.........######.........................##.....# ###.......#..........######........#####...........####....# ###............###...######......########.........#####....# ###...........#####..######.....#########.........####.....# ###...........#####.#######.....########...........###.....# ###...........####..########...#########......##...###....## ###...........####...##################......####..###....## ###...........####......##############.......####..###....## ###...........####..........##########........##...###....## ###............####..........#########.............####..### ###...........#####...........#######..............######### ###.....##########............######.......##......######### ##.....###########.....###.....####.......####......######## ##.....############....###......##.......#####........###### ###...##############..#####.............#######.......###### ################################...##..##################### ############################################################
There's still no guarantee of connectedness, though. However, it's now consistently almost-connected, so that you can reasonably just drop the isolated chunks.
Finally, here is the C program I used to try out different parameters. Before putting this into an actual game, handling of disconnected regions is needed.
#include <stdio.h> #include <stdlib.h> #include <time.h> #define TILE_FLOOR 0 #define TILE_WALL 1 typedef struct { int r1_cutoff, r2_cutoff; int reps; } generation_params; int **grid; int **grid2; int fillprob = 40; int r1_cutoff = 5, r2_cutoff = 2; int size_x = 64, size_y = 20; generation_params *params; generation_params *params_set; int generations; int randpick(void) { if(rand()%100 < fillprob) return TILE_WALL; else return TILE_FLOOR; } void initmap(void) { int xi, yi; grid = (int**)malloc(sizeof(int*) * size_y); grid2 = (int**)malloc(sizeof(int*) * size_y); for(yi=0; yi<size_y; yi++) { grid [yi] = (int*)malloc(sizeof(int) * size_x); grid2[yi] = (int*)malloc(sizeof(int) * size_x); } for(yi=1; yi<size_y-1; yi++) for(xi=1; xi<size_x-1; xi++) grid[yi][xi] = randpick(); for(yi=0; yi<size_y; yi++) for(xi=0; xi<size_x; xi++) grid2[yi][xi] = TILE_WALL; for(yi=0; yi<size_y; yi++) grid[yi][0] = grid[yi][size_x-1] = TILE_WALL; for(xi=0; xi<size_x; xi++) grid[0][xi] = grid[size_y-1][xi] = TILE_WALL; } void generation(void) { int xi, yi, ii, jj; for(yi=1; yi<size_y-1; yi++) for(xi=1; xi<size_x-1; xi++) { int adjcount_r1 = 0, adjcount_r2 = 0; for(ii=-1; ii<=1; ii++) for(jj=-1; jj<=1; jj++) { if(grid[yi+ii][xi+jj] != TILE_FLOOR) adjcount_r1++; } for(ii=yi-2; ii<=yi+2; ii++) for(jj=xi-2; jj<=xi+2; jj++) { if(abs(ii-yi)==2 && abs(jj-xi)==2) continue; if(ii<0 || jj<0 || ii>=size_y || jj>=size_x) continue; if(grid[ii][jj] != TILE_FLOOR) adjcount_r2++; } if(adjcount_r1 >= params->r1_cutoff || adjcount_r2 <= params->r2_cutoff) grid2[yi][xi] = TILE_WALL; else grid2[yi][xi] = TILE_FLOOR; } for(yi=1; yi<size_y-1; yi++) for(xi=1; xi<size_x-1; xi++) grid[yi][xi] = grid2[yi][xi]; } void printfunc(void) { int ii; printf("W[0](p) = rand[0,100) < %i\n", fillprob); for(ii=0; ii<generations; ii++) { printf("Repeat %i: W'(p) = R[1](p) >= %i", params_set[ii].reps, params_set[ii].r1_cutoff); if(params_set[ii].r2_cutoff >= 0) printf(" || R[2](p) <= %i\n", params_set[ii].r2_cutoff); else putchar('\n'); } } void printmap(void) { int xi, yi; for(yi=0; yi<size_y; yi++) { for(xi=0; xi<size_x; xi++) { switch(grid[yi][xi]) { case TILE_WALL: putchar('#'); break; case TILE_FLOOR: putchar('.'); break; } } putchar('\n'); } } int main(int argc, char **argv) { int ii, jj; if(argc < 7) { printf("Usage: %s xsize ysize fill (r1 r2 count)+\n", argv[0]); return 1; } size_x = atoi(argv[1]); size_y = atoi(argv[2]); fillprob = atoi(argv[3]); generations = (argc-4)/3; params = params_set = (generation_params*)malloc( sizeof(generation_params) * generations ); for(ii=4; ii+2<argc; ii+=3) { params->r1_cutoff = atoi(argv[ii]); params->r2_cutoff = atoi(argv[ii+1]); params->reps = atoi(argv[ii+2]); params++; } srand(time(NULL)); initmap(); for(ii=0; ii<generations; ii++) { params = ¶ms_set[ii]; for(jj=0; jj<params->reps; jj++) generation(); } printfunc(); printmap(); return 0; }
(Original article by Jim Babcock)
Tips
I used this method on my game (Arcan Myth RL but only in developing version) but I limited the repetition cycle to 3: I like the result very much and I don't have the problem about big isolated cave. However very good method. Thank you :-) --Provolik