Skip to content
Snippets Groups Projects
Commit f663cc54 authored by DarkGod's avatar DarkGod
Browse files

moar

parent 568ab771
No related branches found
No related tags found
No related merge requests found
......@@ -18,10 +18,9 @@
-- darkgod@te4.org
-- This file implements Kruskals algorithm to find a minimum spanning tree in a graph of rooms
-- This file uses Kruskals algorithm to find a MST(minimum spanning tree) in a graph of rooms
local unionfind = require "algorithms.unionfind"
local MST = require "engine.algorithms.MST"
local max_links = args.max_links or 3
local map = args.map
......@@ -29,63 +28,26 @@ local rooms = args.rooms
if #rooms <= 1 then return true end -- Easy !
-----------------------------------------------------------
-- Small Edge class
-----------------------------------------------------------
local Edge_t
Edge_t = { __index = {
hash = function(e)
local s1, s2 = tostring(e.from), tostring(e.to)
if s2 < s1 then s2, s1 = s1, s2 end
return s1..":"..s2
end,
} }
local function Edge(r1, r2)
local c1, c2 = r1:centerPoint(), r2:centerPoint()
return setmetatable({from=r1, to=r2, cost=core.fov.distance(c1.x, c1.y, c2.x, c2.y)}, Edge_t)
end
-----------------------------------------------------------
local mstrun = MST.new()
-- Generate all possible edges
local edges = {}
for i, room in ipairs(rooms) do
local c = room:centerPoint()
for j, proom in ipairs(rooms) do if proom ~= room then
local e = Edge(room, proom)
edges[e:hash()] = e
local c1, c2 = room:centerPoint(), proom:centerPoint()
mstrun:edge(room, proom, core.fov.distance(c1.x, c1.y, c2.x, c2.y))
end end
end
local sorted_edges = table.values(edges)
table.sort(sorted_edges, "cost")
-- print("===TOTAL EDGES / rooms", #edges, #rooms)
-- table.print(edges)
-- Find the MST graph
local uf = unionfind.create()
local mst = {}
for _, edge in ipairs(sorted_edges) do
-- Skip this edge to avoid creating a cycle in MST
if not uf:connected(edge.from, edge.to) then
-- Include this edge
uf:union(edge.from, edge.to)
mst[edge:hash()] = edge
end
end
-- table.print(mst)
-- Compute!
mstrun:run()
-- Add some more randomly selected edges
local nb_adds = args.edges_surplus or 0
while nb_adds > 0 and next(edges) do
local _, edge = next(edges)
edges[edge:hash()] = nil
mst[edge:hash()] = edge
nb_adds = nb_adds - 1
end
mstrun:fattenRandom(args.edges_surplus or 0)
-- Draw the paths
local full = true
for _, edge in pairs(mst) do
for _, edge in pairs(mstrun.mst) do
local pos1, kind1 = edge.from:findRandomClosestExit(7, edge.to:centerPoint(), nil, args.exitable_chars or {'.', ';', '='})
local pos2, kind2 = edge.to:findRandomClosestExit(7, edge.from:centerPoint(), nil, args.exitable_chars or {'.', ';', '='})
if pos1 and pos2 then
......
......@@ -21,64 +21,15 @@
local tm = Tilemap.new(self.mapsize, '#')
-- self.data.greater_vaults_list = {"32-chambers"}
local room_factory = Rooms.new(self, "random_room")
local noise = Noise.new("simplex", 0.2, 4, 12, 1):make(50, 50, {'T', 'T', ';', ';', '=', '='})
local rooms = {}
for i = 1, 20 do
local proom = room_factory:generateRoom()
local pos = tm:findRandomArea(nil, tm.data_size, proom.data_w, proom.data_h, '#', 1)
if pos then
tm:merge(pos, proom:build())
rooms[#rooms+1] = proom
end
end
-- Eliminate water ponds that are too small
noise:applyOnGroups(noise:findGroupsOf{'='}, function(room, idx)
if #room.list < 18 then noise:fillGroup(room, ';') end
end)
local up_stairs = true
for i = 1, 20 do
-- Make a little lake
local r = rng.range(7, 15)
local pond = Heightmap.new(1.6, {up_left=0, down_left=0, up_right=0, down_right=0, middle=1}):make(r, r, {' ', ' ', ';', ';', 'T', '=', '=', up_stairs and '<' or '='})
-- Ensure exit from the lake to exterrior
local pond_exit = pond:findRandomExit(pond:centerPoint(), nil, {';'})
pond:tunnelAStar(pond:centerPoint(), pond_exit, ';', {'T'}, {}, {erraticness=9})
-- If lake is big enough and we find a spot, place it
if pond:eliminateByFloodfill{'T', ' '} > 8 then
local pos = tm:findRandomArea(nil, tm.data_size, pond.data_w, pond.data_h, '#', 1)
if pos then
tm:merge(pos, pond)
rooms[#rooms+1] = pond
up_stairs = false
end
end
end
tm:merge(1, 1, noise)
if not loadMapScript("lib/connect_rooms_multi", {map=tm, rooms=rooms, edges_surplus=0}) then return self:regenerate() end
-- loadMapScript("lib/connect_rooms_multi", {map=tm, rooms=rooms})
self:setEntrance(tm:locateTile('<'))
self:setExit(rooms[#rooms]:centerPoint()) tm:put(rooms[#rooms]:centerPoint(), '>')
-- Elimitate the rest
-- if tm:eliminateByFloodfill{'#', 'T'} < 600 then return self:regenerate() end
tm:printResult()
-- print('---==============---')
-- local noise = Noise.new(nil, 0.5, 2, 3, 6):make(80, 50, {'T', 'T', '=', '=', '=', ';', ';'})
-- noise:printResult()
-- print('---==============---')
-- print('---==============---')
-- local pond = Heightmap.new(1.9, {up_left=0, down_left=0, up_right=0, down_right=0, middle=1}):make(30, 30, {';', 'T', '=', '=', ';'})
-- pond:printResult()
-- print('---==============---')
-- print('---==============---')
-- local maze = Maze.new():makeSimple(31, 31, '.', {'#','T'}, true)
-- maze:printResult()
-- print('---==============---')
-- DGDGDGDG: make at least Tilemap handlers for BSP, roomer (single room), roomers and correctly handle up/down stairs
-- if tm:eliminateByFloodfill{'T','#'} < 800 then return self:regenerate() end
return tm
......@@ -25,7 +25,7 @@ return {
decay = {300, 800},
actor_adjust_level = function(zone, level, e) return zone.base_level + e:getRankLevelAdjust() + level.level-1 + rng.range(-1,2) end,
width = 80, height = 80,
-- all_remembered = true,
all_remembered = true,
all_lited = true,
no_level_connectivity = true,
......
......@@ -30,7 +30,7 @@ function _M:init(mm_mode)
self.ui = "parchment"
self.bsize = 4
self.bsize = 10
local map = game.level.map
local mw, mh = map.w * self.bsize, map.h * self.bsize
local Mw, Mh = math.floor(game.w * 0.9), math.floor(game.h * 0.9)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment