Skip to content

Commit

Permalink
Update brogue generator algo
Browse files Browse the repository at this point in the history
The Brogue algorithm is something along the lines of:
Build the first room (wether it be the standard first floor room, a cave,
or a rectangle.)
Try 600 random wall spots
on each spot try 15 times to build a corridor+room(.8 random chance) or
room(forced on last 215 iterations.)

That reliably takes three seconds in my code. Whether because I'm bad at
this or whatever.

changing that to try 1000 wall spots once each cuts the time down to about
a half second. That's what this commit does.

I'll keep trying to speed up the room and corridor building (those eat up
most of the time), but for now this is a significant improvement and the
level doesn't really suffer for it.
  • Loading branch information
paulofmandown committed Sep 23, 2013
1 parent d3a0cf1 commit ff64bff
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 57 deletions.
62 changes: 30 additions & 32 deletions rotLove/rotLove.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3768,7 +3768,7 @@ end

function ROT.Map.Brogue:_generateRooms()
local rooms=0
for i=1,600 do
for i=1,1000 do
if rooms>self._maxrooms then break end
if self:_buildRoom(i>375) then
rooms=rooms+1
Expand All @@ -3777,41 +3777,40 @@ function ROT.Map.Brogue:_generateRooms()
end

function ROT.Map.Brogue:_buildRoom(forceNoCorridor)
local p=table.remove(self._walls,self._rng:random(1,#self._walls))
--local p=self._walls[self._rng:random(1,#self._walls)]
--local p=table.remove(self._walls,self._rng:random(1,#self._walls))
local p=self._walls[self._rng:random(1,#self._walls)]
if not p then return false end
local d=self:_getDiggingDirection(p[1], p[2])
if d then
for j=1,15 do
if self._rng:random()<self._options.corridorChance and not forceNoCorridor then
if d[1]~=0 then cd=self._options.corridorWidth
else cd=self._options.corridorHeight
end
local corridor=ROT.Map.Corridor:createRandomAt(p[1]+d[1],p[2]+d[2],d[1],d[2],{corridorLength=cd}, self._rng)
if corridor:isValid(self, self._isWallCallback, self._canBeDugCallback) then
local dx=corridor._endX
local dy=corridor._endY

local room=ROT.Map.BrogueRoom:createRandomAt(dx, dy ,d[1],d[2], self._options, self._rng)

if room:isValid(self, self._isWallCallback, self._canBeDugCallback) then
corridor:create(self, self._digCallback)
room:create(self, self._digCallback)
self:_insertWalls(room._walls)
self._map[p[1]][p[2]]=0
self._map[dx][dy]=0
return true
end
end
else
local room=ROT.Map.BrogueRoom:createRandomAt(p[1],p[2],d[1],d[2], self._options, self._rng)
if self._rng:random()<self._options.corridorChance and not forceNoCorridor then
if d[1]~=0 then cd=self._options.corridorWidth
else cd=self._options.corridorHeight
end
local corridor=ROT.Map.Corridor:createRandomAt(p[1]+d[1],p[2]+d[2],d[1],d[2],{corridorLength=cd}, self._rng)
if corridor:isValid(self, self._isWallCallback, self._canBeDugCallback) then
local dx=corridor._endX
local dy=corridor._endY

local room=ROT.Map.BrogueRoom:createRandomAt(dx, dy ,d[1],d[2], self._options, self._rng)

if room:isValid(self, self._isWallCallback, self._canBeDugCallback) then
corridor:create(self, self._digCallback)
room:create(self, self._digCallback)
self:_insertWalls(room._walls)
table.insert(self._doors, room._doors[1])
self._map[p[1]][p[2]]=0
self._map[dx][dy]=0
return true
end
end
else
local room=ROT.Map.BrogueRoom:createRandomAt(p[1],p[2],d[1],d[2], self._options, self._rng)
if room:isValid(self, self._isWallCallback, self._canBeDugCallback) then
room:create(self, self._digCallback)
self._map[p[1]][p[2]]=0
self:_insertWalls(room._walls)
table.insert(self._doors, room._doors[1])
return true
end
end
end
return false
Expand Down Expand Up @@ -3853,11 +3852,11 @@ function ROT.Map.Brogue:_generateLoops()
count=count+1
end
local function pass(x,y)
return m[x][y]~=1
return m[x][y]==0
end
for i=1,300 do
if #self._walls<1 then return end
local w=table.remove(self._walls, self._rng:random(1,#self._walls))
local w=table.remove(self._walls, 1)--self._rng:random(1,#self._walls))
for j=1,2 do
local x=w[1] +dirs[j][1]
local y=w[2] +dirs[j][2]
Expand All @@ -3869,8 +3868,8 @@ function ROT.Map.Brogue:_generateLoops()
then
local path=ROT.Path.AStar(x,y,pass)
path:compute(x2, y2, cb)
if count>20 then
m[w[1]][w[2]]=3
if count>30 then
m[w[1]][w[2]]=0
end
count=0
end
Expand All @@ -3882,7 +3881,6 @@ function ROT.Map.Brogue:_closeDiagonalOpenings()
end

function ROT.Map.Brogue:_getDoors() return self._doors end
function ROT.Map.Brogue:getDoors() return self._doors end

function ROT.Map.Brogue:_digCallback(x, y, value)
self._map[x][y]=value
Expand Down
48 changes: 23 additions & 25 deletions src/brogue.lua
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ end

function Brogue:_generateRooms()
local rooms=0
for i=1,600 do
for i=1,1000 do
if rooms>self._maxrooms then break end
if self:_buildRoom(i>375) then
rooms=rooms+1
Expand All @@ -175,41 +175,39 @@ function Brogue:_generateRooms()
end

function Brogue:_buildRoom(forceNoCorridor)
local p=table.remove(self._walls,self._rng:random(1,#self._walls))
--local p=self._walls[self._rng:random(1,#self._walls)]
--local p=table.remove(self._walls,self._rng:random(1,#self._walls))
local p=self._walls[self._rng:random(1,#self._walls)]
if not p then return false end
local d=self:_getDiggingDirection(p[1], p[2])
if d then
for j=1,15 do
if self._rng:random()<self._options.corridorChance and not forceNoCorridor then
if d[1]~=0 then cd=self._options.corridorWidth
else cd=self._options.corridorHeight
end
local corridor=ROT.Map.Corridor:createRandomAt(p[1]+d[1],p[2]+d[2],d[1],d[2],{corridorLength=cd}, self._rng)
if corridor:isValid(self, self._isWallCallback, self._canBeDugCallback) then
local dx=corridor._endX
local dy=corridor._endY
if self._rng:random()<self._options.corridorChance and not forceNoCorridor then
if d[1]~=0 then cd=self._options.corridorWidth
else cd=self._options.corridorHeight
end
local corridor=ROT.Map.Corridor:createRandomAt(p[1]+d[1],p[2]+d[2],d[1],d[2],{corridorLength=cd}, self._rng)
if corridor:isValid(self, self._isWallCallback, self._canBeDugCallback) then
local dx=corridor._endX
local dy=corridor._endY

local room=ROT.Map.BrogueRoom:createRandomAt(dx, dy ,d[1],d[2], self._options, self._rng)
local room=ROT.Map.BrogueRoom:createRandomAt(dx, dy ,d[1],d[2], self._options, self._rng)

if room:isValid(self, self._isWallCallback, self._canBeDugCallback) then
corridor:create(self, self._digCallback)
room:create(self, self._digCallback)
self:_insertWalls(room._walls)
self._map[p[1]][p[2]]=0
self._map[dx][dy]=0
return true
end
end
else
local room=ROT.Map.BrogueRoom:createRandomAt(p[1],p[2],d[1],d[2], self._options, self._rng)
if room:isValid(self, self._isWallCallback, self._canBeDugCallback) then
corridor:create(self, self._digCallback)
room:create(self, self._digCallback)
self:_insertWalls(room._walls)
table.insert(self._doors, room._doors[1])
self._map[p[1]][p[2]]=0
self._map[dx][dy]=0
return true
end
end
else
local room=ROT.Map.BrogueRoom:createRandomAt(p[1],p[2],d[1],d[2], self._options, self._rng)
if room:isValid(self, self._isWallCallback, self._canBeDugCallback) then
room:create(self, self._digCallback)
self:_insertWalls(room._walls)
table.insert(self._doors, room._doors[1])
return true
end
end
end
return false
Expand Down

0 comments on commit ff64bff

Please sign in to comment.