-- Maze Generator Module Script for Roblox
-- Maze Generator Module Script for Roblox
--[[
Updated: 5/19/2023
This is the script to generate mazes. This script needs to be placed in the ReplicatedStorage folder. The name must be: mazeGenerator
mazeGenerator ModuleScript to be stored in the ReplicatedStorage
Example usage:
m.newMaze({numRows=10, numCols=10, cellWidth=20, cellLength=20, withNumbers=false, withColors=true, wallThickness=3, height=3})
]]
local Amazing = {}
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local s = require(ReplicatedStorage.genericShapes)
local withNumbers = false
local withColors = false
local openDoor = 0
local Arr = {}
local levelDivisionOffset = {2,1,0}
local colors = {'white','red','green','blue','yellow','purple','black'}
local totalLoops = 200
math.randomseed(tick())
function randomIntFromInterval(min, max) -- min and max included
local retVal = Random.new():NextInteger(min, max)
--local retVal = math.floor(math.random() * ((max - min) - 1) + min)
--print(`Random range: {min} {max}; Returning: {retVal}`)
return retVal
end
function divide(minCol, maxCol, minRow, maxRow, level, quadrant)
if level > 5 then return end
totalLoops -= 1
if totalLoops < 0 then return end
print(`Quadrant: {quadrant}; Level: {level}; Divider is: {colors[level]}; Area is: c1={minCol}, c2={maxCol}, r1={minRow}, r2={maxRow}`)
if maxCol-minCol<2 or maxRow-minRow<2 then
if maxCol-minCol<2 then print(`This quadrant {quadrant} does not have required column size {minCol} and {maxCol}`) end
if maxRow-minRow<2 then print(`This quadrant {quadrant} does not have required row size {minRow} and {maxRow}`) end
return
end
local offset = (levelDivisionOffset[level] and levelDivisionOffset[level] or 0)
print(`Getting a random column between {minCol} and {maxCol}`)
local col = randomIntFromInterval(minCol+1+offset, (maxCol-1)-offset)
print(`My column is: {col} is between {minCol} and {maxCol}`)
for i=minRow, maxRow do Arr[i][col].vertical=level end
print(`Getting a random row between {minRow} and {maxRow}`)
local row = randomIntFromInterval(minRow+1+offset, (maxRow-1)-offset)
print(`My row is: {row} is between {minRow} and {maxRow}`)
for j=minCol, maxCol do Arr[row][j].horizontal=level end
print(`I just set the columns in row {row} from Column: {minCol} to {maxCol}`)
-- open some doors
local door = randomIntFromInterval(minCol, col)
--print(`Door at: {door} - horizontal`)
Arr[row][door].horizontal=openDoor
door = randomIntFromInterval(col+1, maxCol)
if(door > #Arr[row]) then door = #Arr[row] end
--print(`Door at: {door} - horizontal`)
Arr[row][door].horizontal=openDoor
door = randomIntFromInterval(minRow, row)
--print(`Door at: {door} - vertical`)
Arr[door][col].vertical=openDoor
door = randomIntFromInterval(row+1, maxRow)
--print(`Door at: {door} - vertical`)
if(door > #Arr) then door = #Arr end
Arr[door][col].vertical=openDoor
-- Draw a text number at the intersection of row and col
if withNumbers then
--local t1 = text(col*colWidth-(numCols*colWidth/2), row*rowHeight, 0, ''+level, 20, 'black', 'Arial Black')
--if (withColors) t1.fill(colors[level])
end
-- Do the recursion here for all four quadrants
print(`About to divide now. Quadrant is {quadrant}; Current level={level}`)
print(`Division 1: minCol={minCol}, col={col}, minRow={minRow}, row={row}, level+1={level+1}`)
divide(minCol, col, minRow, row, level+1, "Quadrant1")
print(`Division 2: minCol={minCol}, col={col}, row={row}, maxRow={maxRow}, level+1={level+1}`)
divide(minCol, col, row+1, maxRow, level+1, 'Quadrant2')
print(`Division 3: col={col}, maxCol={maxCol}, minRow={minRow}, row={row}, level+1={level+1}`)
divide(col+1, maxCol, minRow, row, level+1, 'Quadrant3')
print(`Division 4: col={col}, maxCol={maxCol}, row={row}, maxRow={maxRow}, level+1={level+1}`)
divide(col+1, maxCol, row+1, maxRow, level+1, 'Quadrant4')
end
function Amazing.newMaze(mazeParms)
if typeof(mazeParms) ~= "table" then
print("No maze generated. You need to pass a table to the function newMaze().")
return
end
print("Working on the maze")
local numRows = mazeParms.numRows
local numCols = mazeParms.numCols
local rowHeight = mazeParms.cellLength
local colWidth = mazeParms.cellWidth
withNumbers = mazeParms.withNumbers -- global variable to this module
withColors = mazeParms.withColors -- global variable to this module
local colors = {'white','red','green','blue','yellow','purple','black'}
local r1=s.rectangle(0,numRows*rowHeight/2, numCols*colWidth-(numCols*colWidth/2), numRows*rowHeight)
s.moveTo(r1, 0, 0, 0)
s.rotateBy(r1, 90, 0, 0)
for i = 1, numRows do
Arr[i] = {}
for j = 1, numCols do
Arr[i][j] = {vertical=0, horizontal=0 }
end
end
divide(1, numCols, 1, numRows, 1, 'All')
-- Render
for i=1, numRows do
for j=1, numCols do
local z = (((rowHeight+mazeParms.wallThickness) * (i-1/2)) - (numRows*(rowHeight+mazeParms.wallThickness)/2)) - rowHeight*0.1
local x = (((colWidth+mazeParms.wallThickness) * (j-1)) - (numCols*(colWidth+mazeParms.wallThickness)/2)) + colWidth*0.07
print(`Maze Row {i} Col {j}`)
if Arr[i][j].horizontal>0 then
local wallPart = s.wall( Vector3.new(x, 0, z+rowHeight+mazeParms.wallThickness), Vector3.new(x+colWidth, mazeParms.height, z+rowHeight+mazeParms.wallThickness), mazeParms.wallThickness, (withColors and colors[Arr[i][j].horizontal] or nil) ) --
--s.cube(x,2,z,1,"red")
--s.cube(x-(colWidth-1),2,z,1,"green")
else
--local wallPart = s.wall( Vector3.new(x-colWidth/2-colWidth/4, 0, z), Vector3.new(x-colWidth/2-(colWidth*0.75), mazeParms.height, z), mazeParms.wallThickness, (withColors and Color3.new(0, 0.333333, 0.498039) or nil) ) --
end
if Arr[i][j].vertical>0 then
local wallPart = s.wall( Vector3.new(x+colWidth, 0, z), Vector3.new(x+colWidth, mazeParms.height, z+rowHeight), mazeParms.wallThickness, (withColors and colors[Arr[i][j].vertical] or nil) )
else
--local wallPart = s.wall( Vector3.new(x, 0, z-rowHeight/2-rowHeight/4), Vector3.new(x, mazeParms.height, z-rowHeight/2-(rowHeight*0.75)), mazeParms.wallThickness, (withColors and colors[Arr[i][j].vertical] or nil) )
end
end
end
end
return Amazing