· 8 years ago · Aug 27, 2018, 09:48 AM
1local baseplate = workspace.Baseplate
2local bPos = baseplate.Position
3local rs = game:GetService("RunService")
4local xStart = bPos.X - 210 --require for
5local yStart = bPos.Y + 1
6local zStart = bPos.Z - 210
7local size = Vector3.new(0.2,0.2,0.2)
8local walls = {}
9local cells = {}
10local edgeWalls = {}
11 --cell count should be 400
12
13local function pause() --used instead of wait
14 rs.Stepped:Wait()
15end
16math.randomseed(tick())
17
18--create
19local mazeF = Instance.new("Folder") --maze folder
20mazeF.Name = "Kruskal's Maze"
21mazeF.Parent = workspace
22local floorF = Instance.new("Folder") --pathfinding
23floorF.Name = "Floors"
24floorF.Parent = mazeF
25local wallF = Instance.new("Folder") --wall container
26wallF.Name = "Walls"
27wallF.Parent = mazeF
28local baseFloor = Instance.new("Part")
29baseFloor.Name = "Floor"
30baseFloor.Material = Enum.Material.DiamondPlate
31baseFloor.BrickColor = BrickColor.new("Really black")
32baseFloor.Size = Vector3.new(10,1,10) --aka the cell size for x and z value
33baseFloor.Anchored = true
34baseFloor.TopSurface = Enum.SurfaceType.Smooth
35baseFloor.BottomSurface = Enum.SurfaceType.Smooth
36local baseWall = Instance.new("Part") --base wall for cloning
37baseWall.Name = "Wall"
38baseWall.BrickColor = BrickColor.new("Institutional white")
39baseWall.Material = Enum.Material.DiamondPlate
40baseWall.Reflectance = 0.25
41baseWall.Anchored = true
42baseWall.Size = Vector3.new(10, 20, 10)
43baseWall.TopSurface = Enum.SurfaceType.Smooth
44baseWall.BottomSurface = Enum.SurfaceType.Smooth
45
46--create cells and walls
47local rowCount = 0
48function createMaze() --much use
49 rowCount = 0
50 local serial = 1
51 local evenRow = true
52 local wallID = 1
53 for _, c in ipairs(wallF:GetChildren()) do --destroy each wall
54 c:Destroy()
55 walls = {}
56 end
57 for _, c in ipairs(floorF:GetChildren()) do --destroy each floor
58 c:Destroy()
59 cells = {}
60 end
61 for i=1, 41 do --for each row
62 evenRow = (not evenRow)
63 local currentlyEvenRow = evenRow
64 local evenColumn = true
65 local row = xStart + i*10
66 local function fillRow()
67 for i2 = 1, 41 do --for each column
68 local floor = baseFloor:Clone()
69 floor.Parent = floorF
70 floor.CFrame = CFrame.new(row, yStart, zStart + i2*10)
71 evenColumn = (not evenColumn)
72 if currentlyEvenRow and evenColumn then
73 table.insert(cells,#cells+1,floor)
74 local ID = Instance.new("StringValue")
75 ID.Name = "IDChip"
76 ID.Value = serial
77 ID.Parent = floor
78 local pos = Instance.new("StringValue")
79 pos.Name = "CreationNum"
80 pos.Value = serial
81 pos.Parent = floor
82 serial = serial + 1
83 else
84 local wall = baseWall:Clone()
85 wall.Parent = wallF
86 wall.CFrame = floor.CFrame + Vector3.new(0,10.5,0) --its position according to the floor
87 local ID2 = Instance.new("StringValue")
88 ID2.Name = "WallChip"
89 ID2.Value = wallID
90 ID2.Parent = wall
91 wallID = wallID + 1
92 table.insert(walls, #walls+1,wall)
93 if wall.Position.X == 200 or wall.Position.X == -200 then
94 local edge = Instance.new("BoolValue")
95 edge.Name = "OnEdge"
96 edge.Value = true
97 edge.Parent = wall
98 table.insert(edgeWalls, #edgeWalls+1, wall) --inserting this wall to be identifyable
99 elseif wall.Position.Z == 200 or wall.Position.Z == -200 then
100 local edge = Instance.new("BoolValue")
101 edge.Name = "OnEdge"
102 edge.Value = true
103 edge.Parent = wall
104 table.insert(edgeWalls, #edgeWalls+1, wall) --inserting this wall to be identifyable
105 end
106 end
107 pause()
108 end
109 rowCount = rowCount + 1
110 end
111 coroutine.resume(coroutine.create(fillRow))
112 pause()
113 end
114 repeat wait() until rowCount == 41
115 print("Starter made!")
116end
117
118--stating all functions
119
120function numDifSerials() --for how many different groupings there are
121 local tabel = {}
122 for i=1, #cells do --for each cell
123 local idVal = cells[i].IDChip --get their serial code
124 if idVal and #tabel < 1 then --if there aren't any serials in the table
125 table.insert(tabel,#tabel+1,idVal.Value) --insert into table
126 elseif idVal then --else
127 for i2=1, #tabel do --for each cell in the table
128 if i2 == #tabel then --if we reached max number of loops
129 table.insert(tabel,#tabel+1,idVal) --insert to table
130 end
131 if tabel[i2] == idVal.Value then --unless we have two of the same
132 break --ends this loop
133 end
134 end
135 end
136 end
137 return #tabel
138end
139
140function findCell(currentCell, direction) --find thou cell from curPos
141 local newPos = currentCell.Position + direction
142 local parts = workspace:FindPartsInRegion3(Region3.new(newPos - size, newPos + size))
143 local newCell = parts[1]
144 if newCell and newCell.Name == "Floor" then
145 return newCell
146 end
147end
148
149function closeWalls(CCell) --if surrounded by walls
150 local directions = {Vector3.new(20,0,0),Vector3.new(-20,0,0),Vector3.new(0,0,20),Vector3.new(0,0,-20)}
151 local wall1 = false
152 local wall2 = false
153 local wall3 = false
154 local wall4 = false
155 for i=1, 4 do
156 local cell2 = findCell(CCell, directions[i])
157 if cell2 then
158 local wallPos = ((CCell.Position + cell2.Position)/2) + Vector3.new(0, 20.5, 0)
159 local walls = workspace:FindPartsInRegion3(Region3.new(wallPos - size, wallPos + size))
160 local wall = walls[1]
161 if wall then
162 if i == 1 then
163 wall1 = true
164 elseif i == 2 then
165 wall2 = true
166 elseif i == 3 then
167 wall3 = true
168 elseif i == 4 then
169 wall4 = true
170 end
171 end
172 end
173 end
174 if wall1 or wall2 or wall3 or wall4 then
175 return true
176 else
177 return false
178 end
179end
180
181function getGroup(CCell) --so we may change the groups serial
182 local sTable = {}
183 for i=1, #cells do
184 local id = CCell.IDChip
185 local id2 = cells[i].IDChip
186 if id.Value == id2.Value then
187 table.insert(sTable,#sTable+1,cells[i])
188 end
189 end
190 return sTable
191end
192
193function breakWall(cell1, cell2)
194 local wallPos = ((cell1.Position + cell2.Position)/2) + Vector3.new(0, 20.5, 0)
195 local walls = workspace:FindPartsInRegion3(Region3.new(wallPos - size, wallPos + size))
196 local wall = walls[1]
197 if wall and wall.Name == "Wall" then
198 wall:Destroy()
199 local group = getGroup(cell2)
200 for i=1, #group do
201 local cellI = group[i]
202 local id = cellI.IDChip
203 id.Value = cell1.IDChip.Value
204 end
205 end
206end
207
208function randomCell() --choose a new cell
209 local r = math.random(1,#cells)
210 local c = cells[r]
211 return c
212end
213
214function mazeGenerate()
215 local cell = cells[1] --incase the begining choice doesnt work
216 while numDifSerials() > 2 do
217 cell = randomCell()
218 local IDC = cell.IDChip
219 local directions = {Vector3.new(20,0,0),Vector3.new(-20,0,0),Vector3.new(0,0,20),Vector3.new(0,0,-20)}
220 local newCell = nil
221 while (not newCell) and (#directions > 0) do --find our new cell
222 local choice = math.random(1, #directions)
223 newCell = findCell(cell, directions[choice])
224 local idN = nil
225 if closeWalls(cell) then --if the cell is a 4-way; makes it marginally quicker
226 else
227
228 local pos = cell.CreationNum.Value--remove this to get rid of stand-alone pillars--
229 table.remove(cells, pos)--remove this to get rid of stand-alone pillars--
230 cell = randomCell()
231 newCell = nil
232 break
233
234 end
235 if not newCell then --if cell no exist
236
237 if #directions == 1 then--remove this to get rid of stand-alone pillars--
238 local pos = cell.CreationNum.Value--remove this to get rid of stand-alone pillars--
239 newCell = nil--remove this to get rid of stand-alone pillars--
240 cell = randomCell()--remove this to get rid of stand-alone pillars--
241 table.remove(cells, pos)--remove this to get rid of stand-alone pillars--
242 table.remove(directions, choice)--remove this to get rid of stand-alone pillars--
243 break--remove this to get rid of stand-alone pillars--
244 end--remove this to get rid of stand-alone pillars--
245
246 table.remove(directions, choice)
247 else
248 idN = newCell.IDChip
249 end
250 if idN then --if it exists
251 if idN.Value == IDC.Value then
252 table.remove(directions, choice)
253 newCell = nil
254 end
255 else
256 newCell = nil
257 end
258 pause()
259 end
260 if newCell then
261 breakWall(cell,newCell)
262 end
263 pause()
264 end
265 print("Kruskal maze completed!")
266 --for i=1, #cells do
267 -- local id = cells[i].IDChip
268 -- print("Serial number that conquered all: "..id.Value)
269 --end
270end
271
272local event = game.ReplicatedStorage.RemoteEvents.PlayerSpeaks
273
274local creating = false
275event.OnServerEvent:Connect(function(player, pass)
276 if pass == "MakeMaze" and creating == false then
277 creating = true
278 createMaze()
279 wait()
280 mazeGenerate()
281 creating = false
282 end
283end)