Skip to content

Instantly share code, notes, and snippets.

@aidansmyth
Forked from deveah/gist:4190454
Created November 13, 2013 12:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aidansmyth/7448386 to your computer and use it in GitHub Desktop.
Save aidansmyth/7448386 to your computer and use it in GitHub Desktop.
map = {}
map.width = 79
map.height = 21
map.cellWidth = 13
map.cellHeight = 7
map.rooms = {}
function isLegal( x, y )
return x > 0 and y > 0 and x <= map.width and y <= map.height
end
function initMap()
for i = 1, map.width do
map[i] = {}
for j = 1, map.height do
map[i][j] = "#"
end
end
map.rooms = {}
end
function showMap()
for j = 1, map.height do
for i =1, map.width do
io.write( map[i][j] )
end
io.write( "\n" )
end
end
function digRoom( x, y, w, h )
for i = x, x+w do
for j = y, y+h do
if isLegal( i, j ) then map[i][j] = "." end
end
end
end
function digCooridor( x1, y1, x2, y2 )
local cx, cy, xo, yo = x1, y1, 0, 0
if x2 > x1 then
xo = 1
else
xo = -1
end
if y2 > y1 then
yo = 1
else
yo = -1
end
while cx ~= x2 do
if isLegal( cx, cy ) then
if map[cx][cy] == "#" then
map[cx][cy] = ","
end
end
cx = cx + xo
end
while cy ~= y2 do
if isLegal( cx, cy ) then
if map[cx][cy] == "#" then
map[cx][cy] = ","
end
end
cy = cy + yo
end
end
function closestRoom( r, loopChance )
local bd, bi = 999, 0
local z = 0
for i = 1, #map.rooms do
z = math.sqrt( math.pow( map.rooms[i].x-map.rooms[r].x, 2 ) + math.pow( map.rooms[i].y-map.rooms[r].y, 2 ) )
if i ~= r and z < bd and ( not map.rooms[i].linked or math.random() < loopChance ) then
bd = z
bi = i
end
end
return bi
end
function allRoomsLinked()
for i = 1, #map.rooms do
if not map.rooms[i].linked then
return false
end
end
return true
end
--[[
makeMap - the main dungeon building function
arguments:
roomChance - chance that a room will be placed in a cell, as the algorithm travels through all the cells
loopChance - the chance of making a cooridor loop
]]
function makeMap( roomChance, loopChance )
local rx, ry, rw, rh = 0, 0, 0, 0
local roomCount = 0
for i = 0, math.floor( map.width / map.cellWidth )-1 do
for j = 0, math.floor( map.height / map.cellHeight )-1 do
if math.random() < roomChance then
while true do
rx = math.random( 2, map.cellWidth-1 )
ry = math.random( 2, map.cellHeight-1 )
rw = math.random( 2, map.cellWidth-1 )
rh = math.random( 2, map.cellHeight-1 )
if rx+rw < map.cellWidth and ry+rh < map.cellHeight then
break
end
end
digRoom( i*map.cellWidth+rx, j*map.cellHeight+ry, rw, rh )
table.insert( map.rooms, {
x = i*map.cellWidth+rx + math.floor( rw/2 ),
y = j*map.cellHeight+ry + math.floor( rh/2 ),
linked = false
} )
roomCount = roomCount + 1
end
end
end
local ra = math.random( 1, #map.rooms )
local rb = 0
map.rooms[ra].linked = true
while not allRoomsLinked() do
rb = closestRoom( ra, loopChance )
if rb ~= 0 then
digCooridor( map.rooms[ra].x, map.rooms[ra].y, map.rooms[rb].x, map.rooms[rb].y )
if map.rooms[ra].linked then
map.rooms[rb].linked = true
end
ra = rb
end
end
return roomCount
end
function countNeighbours( x, y, t )
local r = 0
for i = x-1, x+1 do
for j = y-1, y+1 do
if isLegal( i, j ) then
if map[i][j] == t then r = r + 1 end
end
end
end
return r
end
function postProcess()
for i = 2, map.width-1 do
for j = 2, map.height-1 do
if countNeighbours( i, j, "." ) > 1 and countNeighbours( i, j, "," ) < 4 and map[i][j] == "," and
( ( map[i-1][j] == "#" and map[i+1][j] == "#" ) or
( map[i][j-1] == "#" and map[i][j+1] == "#" ) ) then
map[i][j] = "+"
end
end
end
for i = 1, map.width do
for j = 1, map.height do
if map[i][j] == "," then map[i][j] = "." end
end
end
for i = 1, map.width do
for j = 1, map.height do
if countNeighbours( i, j, "." ) == 0 then
map[i][j] = " "
end
end
end
end
math.randomseed( os.time() )
initMap()
r = makeMap( 0.5, 0.5 )
postProcess()
showMap()
print( r .. " rooms dug" )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment