From f3d4d46c43a155fcb18db184e1b92543fb8109da Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Mon, 28 Sep 2020 01:25:47 +0100
Subject: [PATCH] Fix bug causing some parts of mazes to be unexplored Also add
 seed conversion function

---
 main.lua          | 10 +++++-----
 maze.lua          | 10 +++++-----
 utils/strings.lua | 18 ++++++++++++++++++
 3 files changed, 28 insertions(+), 10 deletions(-)

diff --git a/main.lua b/main.lua
index fa277b9..4ee9c9f 100644
--- a/main.lua
+++ b/main.lua
@@ -93,7 +93,7 @@ for i=1,#arg do
 		settings.depth = tonumber(arg[i])
 	elseif arg[i] == "--seed" or arg[i] == "-s" then
 		i = i + 1
-		settings.seed = tonumber(arg[i])
+		settings.seed = strings.makeseed(arg[i])
 	elseif arg[i] == "--filename" or arg[i] == "-f" then
 		i = i + 1
 		settings.filename = arg[i]
@@ -134,7 +134,7 @@ local function maze_text()
 		settings.path_width
 	)
 	maze2d.printspace(world, settings.width, settings.height)
-	print("Generation completed in " .. time .. "ms.")
+	print("Generation completed in " .. time .. "ms with seed "..settings.seed..".")
 end
 
 local function maze_svg()
@@ -159,7 +159,7 @@ local function maze_svg()
 		local out = io.open(settings.filename, "w")
 		out:write(svg)
 		out:close()
-		print("Generation completed in "..time.."ms.")
+		print("Generation completed in "..time.."ms with seed "..settings.seed..".")
 	end
 end
 
@@ -176,7 +176,7 @@ local function maze3d_text()
 	
 	maze3d.printspace(world, settings.width, settings.height, settings.depth)
 	
-	print("Generation completed in " .. time .. "ms.")
+	print("Generation completed in " .. time .. "ms with seed "..settings.seed..".")
 end
 
 local function maze3d_openscad()
@@ -191,7 +191,7 @@ local function maze3d_openscad()
 	)
 	
 	if not settings.filename then
-		print(a.fred(a.hicol("Error: No outupt filename specified.")))
+		print(a.fred(a.hicol("Error: No output filename specified.")))
 		return false
 	end
 	
diff --git a/maze.lua b/maze.lua
index c93f8fc..6d6edb5 100644
--- a/maze.lua
+++ b/maze.lua
@@ -59,11 +59,12 @@ end
 
 -- Initialise the world
 
-function M.generate_maze(seed, width, height, path_length, path_width)
+function M.generate_maze(seed, width, height, path_length, path_width, branching_factor)
 	start_time = os.clock()
 	
     if not path_length then path_length = 2 end
     if not path_width then path_width = 1 end
+	if not branching_factor then branching_factor = 6 end
 	
 	math.randomseed(seed) -- seed the random number generator with the system clock
 
@@ -108,7 +109,7 @@ function M.generate_maze(seed, width, height, path_length, path_width)
 		end
 		-- print("radar output: '" .. directions .. "' (length: " .. #directions .. "), curnode: " .. curnode)
 		
-		local shift_attention = math.random(0, 9)
+		local shift_attention = math.random(0, branching_factor)
 		
 		if #directions > 0 then
 			-- we still have somewhere that we can go
@@ -156,9 +157,8 @@ function M.generate_maze(seed, width, height, path_length, path_width)
 			-- print("Now at ("..cx..", "..cy..")")
 			
 			-- If the number of directions we could travel in was 1, then we've just travelled in the last remaining direction possible
-			if #directions > 1 then
-				table.insert(nodes, { x = cx, y = cy })
-			end
+			-- THIS ISN'T TRUE, because we're analysing the old position and then inserting the new one - so we have to insert regardless
+			table.insert(nodes, { x = cx, y = cy })
 		else
 			--print("The node at " .. curnode .. " is a dead end.")
 			table.remove(nodes, curnode)
diff --git a/utils/strings.lua b/utils/strings.lua
index 8f63755..4e8b059 100644
--- a/utils/strings.lua
+++ b/utils/strings.lua
@@ -8,4 +8,22 @@ function M.ends_with(str, ending)
    return ending == "" or str:sub(-#ending) == ending
 end
 
+--- Makes a seed from a string.
+-- If the input is a number, it is returned as-is.
+-- If the input is a string and can be converted to a number with tonumber(),
+-- the output of tonumber() is returned.
+-- Otherwise, the string is converted to a number via a simple hashing algorithm
+-- (caution: certainlly NOT crypto-secure!).
+
+-- @source https://stackoverflow.com/a/2624210/1460422
+function M.makeseed(str)
+    if type(str) == "number" then return str end
+    if tonumber(str) ~=  nil then return tonumber(str) end
+    local result = 0
+    for i = 1, #str do
+        result = (result*91) + (string.byte(str:sub(i, i)) * 31)
+    end
+    return result
+end
+
 return M
