This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Jack's profile picture

Maze Generator

Started by Jack, 26 December 2012 - 07:33 PM
Jack #1
Posted 26 December 2012 - 08:33 PM
This is a maze generator for turtles! It's just a rough draft; I wanted to work out the essentials before ironing out details. It uses the well-known recursive backtracker algorithm. Just load it into a turtle on solid terrain and watch it carve the passages.

Known issues:
-Does not yet refuel. If it's a big issue, this should be easy enough for you to add.
-If you use it underground, it will be very dark and monster-prone.
-No current known problems!

Please let me know if you discover bugs. Criticism is requested and constructive criticism is preferred.

Screenshots:
A size-8 maze under construction
Spoiler
A completed size-8 maze
Spoiler
A completed size-16 maze
Spoiler

Code:
http://pastebin.com/LACe82ar
Spoiler

--Creates a square maze with specified side length-
args = {...}
if #args < 1 then
  print("Usage: maze <size>")
  return
end
print("Place torches in slot 1 and fuel in slot 16, then press enter.")
read()
turtle.select(16)
size = tonumber(args[1])
maze = {}
for x = 1,size do
  maze[x] = {}
  for y = 1,size do
    maze[x][y] = false
  end
end
mx = 1 --X-coordinate
my = 1 --Y-coordinate
md = 1 --Direction
maze[1][1] = true
-------------------------
-------------------------
function isOpen(d)
  x = mx + dx(d)
  y = my + dy(d)
  if x < 1 or y < 1 or x > size or y > size then
    return false
  end  
  m = maze[x][y]
  return not m
end  
-------------------------
function dx(d)
  if d == 2 then
    return 1
  elseif d == 4 then
    return -1
  end
  return 0
end
-------------------------
function dy(d)
  if d == 1 then
    return 1
  elseif d == 3 then
    return -1
  end
  return 0
end
-------------------------
function face(d)
  if d > 4 then d = d - 4 end
  if math.abs(md - d) == 1 then
    if md > d then
	  turnLeft()
    else
	  turnRight()
    end
  elseif math.abs(md - d) == 2 then
    turnRight()
    turnRight()
  elseif math.abs(md - d) == 3 then
    if md > d then
	  turnRight()
    else
	  turnLeft()
    end
  end
  md = d
end
-------------------------
function turnLeft()
  md = md - 1
  if md == 0 then md = 4 end
  turtle.turnLeft()
end
function turnRight()
  md = md + 1
  if md == 5 then md = 1 end
  turtle.turnRight()
end
-------------------------
torches = 0
function carve(t)
  for i = 1,2 do
    if turtle.getFuelLevel() == 0 then
	  if not turtle.refuel(1) then
	    shell.run("reboot")
	  end
    end
    while not turtle.forward() do
	  turtle.dig()
    end
    if t then turtle.digDown() end
  end
  mx = mx + dx(md)
  my = my + dy(md)
  maze[mx][my] = true
  if t then
    torches = torches + 1
    if torches == 5 then
	  turtle.select(1)
	  torches = 0
	  turtle.placeDown()
	  turtle.select(16)
    end
  end
end
-------------------------
--Fisher-Yates shuffle---
function shuffle(t)
  local n = #t
  while n >= 2 do
    local k = math.random(n)
    t[n], t[k] = t[k], t[n]
    n = n - 1
  end
  return t
end
-------------------------
function main()
  local last = 0
  local dirs = {1,2,3,4}
  dirs = shuffle(dirs)
  last = md
  for k,v in ipairs(dirs) do
    if isOpen(v) then
	  face(v)
	  carve(true)
	  main()
    end
  end
  face(last + 2)
  carve(false)
end
-------------------------
main()
Jack #2
Posted 29 December 2012 - 03:39 AM
Updated! Added screenshots to OP.
Ulthean #3
Posted 29 December 2012 - 05:30 AM
Looks nice.

Does the maze always stretch out across the entire square? Or is there a possibility that some parts might be left untouched?
Cranium #4
Posted 29 December 2012 - 06:23 AM
I do like this. I might have to use this in an ice dungeon I'm plannign on making.
Jack #5
Posted 29 December 2012 - 09:19 AM
Looks nice.

Does the maze always stretch out across the entire square? Or is there a possibility that some parts might be left untouched?

It is a perfect maze, which means that any point can be reached from any other point by exactly one path. No untouched passages will remain. The algorithm doesn't actually choose an exit, but any point might work for one. It's up to you to choose a path.
Jack #6
Posted 29 December 2012 - 09:22 AM
Updated again.
Amdusias #7
Posted 01 January 2013 - 01:21 PM
You've probably still got the version without the automatic refuel thing?
Because i m playing Tekkit and its still CC 1.3 over there.
But look good so far!
AndreWalia #8
Posted 01 January 2013 - 01:50 PM
I suggest the turtle places lime wool at start and red wool at end
AndreWalia #9
Posted 01 January 2013 - 02:02 PM
I made it so that begining the maze is better. So you cant type in anything, its a press any key.
replace

print("Place torches in slot 1 and fuel in slot 16, then press enter.")
read()
with

print("Place torches in slot 1 and fuel in slot 16")
print("Press any key to continue...")
os.pullEvent("key")
steel_toed_boot #10
Posted 01 January 2013 - 07:51 PM
Looks awesome.
Churik #11
Posted 03 January 2013 - 08:23 AM
Hehe, noob question:
Do I have to change anything about it to use it on tekkit?
I know tekkit has a older version, but don't know the exact changes between the old and new version.
If so, what do I need to change? :$
DocHuzz #12
Posted 14 January 2013 - 07:24 PM
Hey mate I have been fooling around with this program of yours and I noticed a couple of issues. Following the right hand rule (always pick the right hand passage) nearly always gets you to the ending. I could change this by putting the end somewhere in the middle, so no big deal. The other issue I found is that the maze size is not related to the number you put in all that well. For instance, a size 8 maze was 14x14. What's the algorithm for the size? Great freaking program though!
Jack #13
Posted 20 January 2013 - 06:29 PM
walia6: That's a nice interface change, and a good idea with the red and green wool.

steel_toed_boot: Thank you!

Churik: Sadly, I know nothing about Tekkit or related compatabilities.

DocHuzz: Yes, since it generates a perfect maze, it is acyclic, which means that sticking to either wall is guaranteed to find you the exit eventually, regardless of which points you choose as start and end. Also, the size 8 maze wasn't actually 14x14, it was 16x16 (counting the outer edges). This is because the code deals with nodes rather than adjacent blocks. Each node is separated from each other node by a one-block space. I suppose I could have just divided the user's input by 2 and saved this trouble… but I'm lazy. :P/> Good question, though!
YoYoYonnY #14
Posted 14 November 2013 - 11:35 AM
I made it so that begining the maze is better. So you cant type in anything, its a press any key.
replace

print("Place torches in slot 1 and fuel in slot 16, then press enter.")
read()
with

print("Place torches in slot 1 and fuel in slot 16")
print("Press any key to continue...")
os.pullEvent("key")
Better use os.pullEvent("char") or the event might happen as soon as you press enter (after entering the command "maze <size>" in CraftOS)
Zudo #15
Posted 14 November 2013 - 11:45 AM
Nice.
DarkShadowsX #16
Posted 05 April 2014 - 08:04 AM
this will be great to test with my maze solver turtle program
thanks.