# dual pass cave generation algorithm

a guest
Apr 26th, 2017
69
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. local CHANCE_TO_START_ALIVE = 480
2. local BIRTH_LIMIT = 5
3. local DEATH_LIMIT = 5
4. -- in phase 2 there's more death than birth in order to widen paths
5. local BIRTH_LIMIT_PHASE2 = 5
6. local DEATH_LIMIT_PHASE2 = 6
7. local STEPS = 3 -- per phase
8.
9. local distance = 64
10. local pointSize = 11
11.
12. local lastx
13. local lasty
14. -- function for updating last possible x and y indexes
15. function updateLastXY()
16.   -- +1 to make sure we touch the walls
17.   lastx = math.floor(4096/distance) + 1
18.   lasty = math.floor(2048/distance) + 1
19. end
20. -- initialize
21. updateLastXY()
22.
23.
24. function generateCave()
25.
26.   local world = {}
27.
28.   -- PHASE 1
29.
30.   -- generate low resolution world
31.   initializeWorld(world)
32.
33.   for i=1, STEPS do
34.     world = simulationStep(world)
35.   end
36.
37.   -- PHASE 2
38.
39.   -- okay, we got a rough cave shape now
40.   -- double its resolution and simulate again to refine shape
41.   world = doubleWorldResolution(world)
42.
43.   DEATH_LIMIT = DEATH_LIMIT_PHASE2
44.   BIRTH_LIMIT = BIRTH_LIMIT_PHASE2
45.
46.   for i=1, STEPS do
47.     world = simulationStep(world)
48.   end
49.
50.   -- DRAWING
51.
52.   local realx = 0
53.   for x=1, lastx do
54.
55.     local realy = 0
56.     for y=1, lasty do
57.
58.       if world[x][y] then
60.       end
61.
62.       realy = realy + distance
63.     end
64.     realx = realx + distance
65.   end
66.
67.   FlushPoints()
68. end
69.
70. -- doubles the world resolution in both x and y direction
71. -- causing every cell/space become 4 cells/spaces each
72. function doubleWorldResolution(world)
73.
74.   -- update distance to reflect the change
75.   distance = math.floor(distance / 2)
76.   updateLastXY()
77.
78.   local world2 = {}
79.
80.   -- generate 2 lines at once, because they are identical
81.   for x=1, lastx, 2 do
82.     local oddcol = {}
83.     local evencol = {}
84.
85.     -- generate 2 cells per column at once, because they are identical
86.     for y=1, lasty, 2 do
87.       local wx = math.floor(x/2)+1
88.       local wy = math.floor(y/2)+1
89.       local cell = world[wx][wy]
90.       -- add 2 cells in both columns
91.       table.insert(oddcol, cell)
92.       table.insert(oddcol, cell)
93.       table.insert(evencol, cell)
94.       table.insert(evencol, cell)
95.     end
96.
97.     -- add the two columns
98.     table.insert(world2, oddcol)
99.     table.insert(world2, evencol)
100.   end
101.
102.   return world2
103. end
104.
105. function initializeWorld(world)
106.   for x=1, lastx do
107.     table.insert(world, {})
108.     local borderx = (x == 1) or (x == lastx)
109.
110.     for y=1, lasty do
111.       local border = borderx or ((y == 1) or (y == lasty))
112.       if border or GetRandom(1000) < CHANCE_TO_START_ALIVE then
113.         table.insert(world[x], true)
114.       else
115.         table.insert(world[x], false)
116.       end
117.     end
118.   end
119. end
120.
121. function simulationStep(world)
122.   world2 = {}
123.
124.   for x=1, lastx do
125.     table.insert(world2, {})
126.
127.     for y=1, lasty do
128.       local count = countNeigbours(world, x, y)
129.
130.       if world[x][y] then
131.         if count < DEATH_LIMIT then
132.           table.insert(world2[x], false)
133.         else
134.           table.insert(world2[x], true)
135.         end
136.       else
137.         if count > BIRTH_LIMIT then
138.           table.insert(world2[x], true)
139.         else
140.           table.insert(world2[x], false)
141.         end
142.       end
143.     end
144.   end
145.
146.   return world2
147. end
148.
149. function countNeigbours(world, x, y)
150.   count = 0
151.
152.   for dx=-1, 1 do
153.     for dy=-1, 1 do
154.       local x2 = x+dx
155.       local y2 = y+dy
156.
157.       if x2 == 0 or x2 > lastx or y2 == 0 or y2 > lasty or world[x2][y2] then
158.         count = count + 1
159.       end
160.     end
161.   end
162.
163.   return count
164. end
165.
166. function onGameInit()
167.     MapGen = mgDrawn
168.     TemplateFilter = 0
169.     generateCave()
170. end
171.
172. function onPreviewInit()
173.     onGameInit()
174. end
RAW Paste Data