Add argument to control the branching factor

This commit is contained in:
Starbeamrainbowlabs 2020-09-30 01:20:17 +01:00
parent 7b0b127a69
commit 0e6b16dd55
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
3 changed files with 51 additions and 24 deletions

View file

@ -89,6 +89,15 @@ The formula here for the crop is:
![(Horizontal line)](https://starbeamrainbowlabs.com/blog/images/20200831-mazes/hr.png) ![(Horizontal line)](https://starbeamrainbowlabs.com/blog/images/20200831-mazes/hr.png)
## Remarks and Observations
### Branching factor
Higher values reduce the number of attention switches the engine executes, leading to fewer branching paths in the resulting maze - this is implemented with a 1-in-N chance to shift the attention of the engine.
The value here that works best really depends on your maze. Larger mazes tend to benefit from higher branching factors than the default. 3D mazes tend to look better with slightly lower branching factors, but this is an area of ongoing observation (get in touch if you have anything to add here).
## Contributing ## Contributing
Contributions are very welcome - both issues and patches! Please mention in your pull request that you release your work under the MPL-2.0 (see below). Contributions are very welcome - both issues and patches! Please mention in your pull request that you release your work under the MPL-2.0 (see below).

View file

@ -21,6 +21,8 @@ local settings = {
height = 11, height = 11,
depth = 7, depth = 7,
branching_factor = nil, -- Depends on the mode - nil will cause the engine to pick the default mode instead
seed = os.time(), seed = os.time(),
-- TODO: Add branching factor setting here & associated CLI argument -- TODO: Add branching factor setting here & associated CLI argument
filename = nil, filename = nil,
@ -28,7 +30,7 @@ local settings = {
scale = 5, scale = 5,
inverted = true, inverted = true,
colour = "#6495ED", -- Cornflower blue :D colour = "#6495ED", -- Cornflower blue :D (if you get the reference, get in touch for a virtual cookie :D)
path_length = 2, path_length = 2,
path_width = 1, path_width = 1,
@ -36,6 +38,8 @@ local settings = {
} }
local function help() local function help()
--lua main.lua ]]..a.item("maze")..[[ [--width <int:11>] [--height <int:11>] [--seed <string>] [--path-length <int:2>] [--path-width <int:1>] [--branching-factor <int:6>]
--lua main.lua ]]..a.item("maze3d")..[[ [--width <int:11>] [--height <int:11>] [--depth <int:7>] [--seed <string>] [--path-length <int:2>] [--path-width <int:1>] [--path-depth <int:1>] [--branching-factor <int:6>]
print([[ print([[
]]..a.fgreen(a.hicol("multimaze: "))..a.fyellow(a.hicol("Multidimensional maze generator"))..[[ ]]..a.fgreen(a.hicol("multimaze: "))..a.fyellow(a.hicol("Multidimensional maze generator"))..[[
@ -60,15 +64,21 @@ local function help()
]]..a.item("--help")..[[ Shows this message ]]..a.item("--help")..[[ Shows this message
]]..a.item("-w --width")..a.value(" {int}")..[[ Sets the width of the maze ]]..a.item("-w --width")..a.value(" {int}")..[[ Sets the width of the maze
]]..a.item("-h --height")..a.value(" {int}")..[[ Sets the height of the maze ]]..a.item("-h --height")..a.value(" {int}")..[[ Sets the height of the maze
]]..a.item("-d --depth")..a.value(" {int}")..[[ Sets the depth of the maze [3d only] ]]..a.item("-d --depth")..a.value(" {int}")..[[ Sets the depth of the maze ]]..a.locol("[3d only]")..[[
]]..a.item("-s --seed")..a.value(" {string}")..[[ Sets the seed ]]..a.item("-s --seed")..a.value(" {string}")..[[ Sets the seed
]]..a.item("-f --filename")..a.value(" {string}")..[[ Sets the output filename ]]..a.item("-f --filename")..a.value(" {string}")..[[ Sets the output filename
]]..a.item("--toggle-invert")..[[ Toggle inversion of the output [maz_svg, maze3d_openscad only] ]]..a.item("--toggle-invert")..[[ Toggle inversion of the output ]]..a.locol("[maze_svg, maze3d_openscad only]")..[[
]]..a.item("-m --scale")..a.value(" {int}")..[[ Sets the scale of the output [maze_svg, openscad output only]
]]..a.item("-m --scale")..a.value(" {int}")..[[ Sets the scale of the output ]]..a.locol("[maze_svg, openscad output only]")..[[
]]..a.item("-l --path-length")..a.value(" {int}")..[[ Sets the path length ]]..a.item("-l --path-length")..a.value(" {int}")..[[ Sets the path length
]]..a.item("-y --path-width")..a.value(" {int}")..[[ Sets the path width ]]..a.item("-y --path-width")..a.value(" {int}")..[[ Sets the path width
]]..a.item("-z --path-depth")..a.value(" {int}")..[[ Sets the path depth [3d only] ]]..a.item("-z --path-depth")..a.value(" {int}")..[[ Sets the path depth ]]..a.locol("[3d only]")..[[
]]..a.item("--colour")..a.value(" {string}")..[[ Sets the colour [maze_svg only]
]]..a.item("-b --branching-factor")..a.value(" {int}")..[[Sets the path branching factor (higher = fewer branching paths, default: 6 for 2D, 3 for 3D)
]]..a.item("--colour")..a.value(" {string}")..[[ Sets the colour ]]..a.locol("[maze_svg only]")..[[
]]..a.header("Environment Variables:")..[[ ]]..a.header("Environment Variables:")..[[
@ -92,6 +102,9 @@ for i=1,#arg do
elseif arg[i] == "--depth" or arg[i] == "-d" then elseif arg[i] == "--depth" or arg[i] == "-d" then
i = i + 1 i = i + 1
settings.depth = tonumber(arg[i]) settings.depth = tonumber(arg[i])
elseif arg[i] == "--branching-factor" or arg[i] == "-b" then
i = i + 1
settings.branching_factor = tonumber(arg[i])
elseif arg[i] == "--seed" or arg[i] == "-s" then elseif arg[i] == "--seed" or arg[i] == "-s" then
i = i + 1 i = i + 1
settings.seed = strings.makeseed(arg[i]) settings.seed = strings.makeseed(arg[i])
@ -132,7 +145,8 @@ local function maze_text()
settings.width, settings.width,
settings.height, settings.height,
settings.path_length, settings.path_length,
settings.path_width settings.path_width,
settings.branching_factor
) )
maze2d.printspace(world, settings.width, settings.height) maze2d.printspace(world, settings.width, settings.height)
print("Generation completed in " .. time .. "ms with seed "..settings.seed..".") print("Generation completed in " .. time .. "ms with seed "..settings.seed..".")
@ -144,7 +158,8 @@ local function maze_svg()
settings.width, settings.width,
settings.height, settings.height,
settings.path_length, settings.path_length,
settings.path_width settings.path_width,
settings.branching_factor
) )
local svg_settings = { local svg_settings = {
@ -172,7 +187,8 @@ local function maze3d_text()
settings.depth, settings.depth,
settings.path_length, settings.path_length,
settings.path_width, settings.path_width,
settings.path_depth settings.path_depth,
settings.branching_factor
) )
maze3d.printspace(world, settings.width, settings.height, settings.depth) maze3d.printspace(world, settings.width, settings.height, settings.depth)
@ -188,7 +204,8 @@ local function maze3d_openscad()
settings.depth, settings.depth,
settings.path_length, settings.path_length,
settings.path_width, settings.path_width,
settings.path_depth settings.path_depth,
settings.branching_factor
) )
if not settings.filename then if not settings.filename then

View file

@ -43,11 +43,12 @@ end
-- Initialise the world -- Initialise the world
function M.generate_maze(seed, width, height, depth, path_length, path_width, path_depth) function M.generate_maze(seed, width, height, depth, path_length, path_width, path_depth, branching_factor)
local start_time = os.clock() local start_time = os.clock()
if not path_length then path_length = 2 end if not path_length then path_length = 2 end
if not path_width then path_width = 1 end if not path_width then path_width = 1 end
if not path_depth then path_depth = 1 end if not path_depth then path_depth = 1 end
if not branching_factor then branching_factor = 3 end
-- print("Generating maze "..width.."x"..height.."x"..depth.." | path: length "..path_length.." width "..path_width.." depth "..path_depth) -- print("Generating maze "..width.."x"..height.."x"..depth.." | path: length "..path_length.." width "..path_width.." depth "..path_depth)
math.randomseed(seed) -- seed the random number generator with the system clock math.randomseed(seed) -- seed the random number generator with the system clock
@ -94,7 +95,7 @@ function M.generate_maze(seed, width, height, depth, path_length, path_width, pa
end end
-- If this is 1 or less, then we will switch our attention to another candidate node after moving -- If this is 1 or less, then we will switch our attention to another candidate node after moving
local shift_attention = math.random(0, 3) local shift_attention = math.random(0, branching_factor)
--print("radar output: '" .. directions .. "' (length: " .. #directions .. "), curnode: " .. curnode) --print("radar output: '" .. directions .. "' (length: " .. #directions .. "), curnode: " .. curnode)
if #directions > 0 then if #directions > 0 then