Simple cave map generator
Jump to navigation
Jump to search
A cave map generator by Ray Dillinger from rec.games.roguelike.development:
Message-Id: <48d8aa27$0$33580$742ec2ed@news.sonic.net>
Here, have a cave generator. I wrote this, anybody can use it.
Creates caves like this:
#.# ##.## #.....#..# #..........# #..##.....# ######....# #..#...#..# #..##....### # ##..##...#..##..##...##..# #.#......##..#.##...###.###..#...##..# ## #.#......##....#....#....# #...## #...# # # #........# #.......##.....#.....# #...# #.##.# #........# ###...## #.........#.# #..# #..#.# ##...##.##.# #..# ##.........## ## #....## #....###...##...#.##........# #......#####.....##....#...#..#.....##..# #.#####.#......### #.#...#.##...##.# #.# # #.#..#....##..##.####.#.######..###.###..# #.#..............##......#.##...####...#.##.# ##.#.#..#..........#.##..##.#....# #..#...# # #....#..#.............#...## #...##..##...# ##...####...##..##.##...## #...## ## #..# #...# #...##..###.....# ###.....### ##..# ##..#..#..#....#.#..# #...........##.....# #....##.###.......##..###.##....### ##.#..# #......##...##.......#...##.....# ###.##..# #....#.........####......##.#..## #.....#..# #..#.##..#....####.......# ##....# #.### ## ## # #.###......##......# #..##..# # #............###.....# ###....# #...#.....#.......##.#####.#..# #...##....##..###....#....##..# #.## ###.#...# #..###....##.# #..# #......# #...##....#..#
Annotated Javascript port available at http://jsfiddle.net/JesterBLUE/tfk9eo28/
/* a simple program for generating caves. */ #include <stdio.h> #include <stdlib.h> #define X 60 #define XCENTER 30 #define Y 30 #define YCENTER 15 char map[X][Y]; int dieroll (int min, int max){ int randomnum; int range = (max + 1 - min); int divisor = RAND_MAX / range; for (randomnum = random(); RAND_MAX-randomnum < RAND_MAX % range; randomnum = random()); randomnum /= divisor; return(randomnum + min); } void cavegen(){ int adjfloor; int adjwall; int uncommittedcount = X * Y - 1; int wallcount = 0; int floorcount = 1; int x; int y; int xmin = XCENTER - 1; int ymin = YCENTER - 1; int xmax = XCENTER + 1; int ymax = YCENTER + 1; int iterationlimit = 0; /* initialize to all uncommitted. */ for (x = 0; x < X; x++){ for (y = 0; y < Y; y++){ map[x][y]='?'; } } /* clear a center starting point. */ map[XCENTER][YCENTER] = '.'; do{ iterationlimit++; x = dieroll (xmin, xmax); y = dieroll (ymin, ymax); if (map[x][y] == '?' || dieroll(1,100) == 1){ if (x == xmin && x > 1) xmin--; if (x == xmax && x < X-2) xmax++; if (y == ymin && y > 1) ymin--; if (y == ymax && y < Y-2) ymax++; adjfloor = 0; if (map[x-1][y] == '.') adjfloor++; if (map[x+1][y] == '.') adjfloor++; if (map[x][y-1] == '.') adjfloor++; if (map[x][y+1] == '.') adjfloor++; adjwall = 0; if (map[x-1][y] == '#') adjwall++; if (map[x+1][y] == '#') adjwall++; if (map[x][y-1] == '#') adjwall++; if (map[x][y+1] == '#') adjwall++; if (adjfloor){ if (uncommittedcount + floorcount > X * Y / 2 && (adjwall > adjfloor || wallcount * 3 < floorcount * 2)){ if (map[x][y] == '?')uncommittedcount--; if (map[x][y] == '.') floorcount--; if (map[x][y] != '#') wallcount++; map[x][y]='#'; } else { if (map[x][y] == '?' ) uncommittedcount--; if (map[x][y] == '#' ) wallcount--; if (map[x][y] != '.' ) floorcount++; map[x][y] = '.'; } } } }while (iterationlimit < X * Y * 500 && floorcount < X * Y / 3); for (x = 1; x < X-1; x++){ for (y = 1; y < Y-1; y++){ adjfloor = 0; if (map[x-1][y] == '.') adjfloor++; if (map[x+1][y] == '.') adjfloor++; if (map[x][y-1] == '.') adjfloor++; if (map[x][y+1] == '.') adjfloor++; if (adjfloor && map[x][y] == '?') map[x][y] = '#'; if (adjfloor == 4) map[x][y] = '.'; if (!adjfloor) map[x][y] = ' '; } } } int main() /* just a testing harness: hit spacebar to quit. */ { int x; int y; do{ cavegen(); for (y = 1; y < Y-1; y++){ for (x = 1; x < X-1; x++){ printf("%c", map[x][y]); } printf("\n"); } } while (getchar() != ' '); return(0); }