nerd explination
In reality, my code returns a table. I simply used the __call metamethod to make it act like a function. It recognises #, U, and D as places to move to, and then will move up from the space of U or down from the space of D.
There is only one function: mapreader.path( table[, yield] )
if yield is true, the function will need to be called again for each movement, allowing you to add more code if you like.
the code
function path( tMaps, _yield ) --Find start local function findStart() for k, sMap in ipairs( tMaps ) do local l = 1 for line in sMap:gmatch( '[^\r\n]+' ) do for i = 1, #line do if line:sub( i, i ):upper() == "X" then return {x = i, y = l, z = k} end end l = l + 1 end end end --update removes already used path bits local function update( tbl ) local l = 1 local newString = {} local oldChar for line in tMaps[ tbl.z ]:gmatch( '[^\r\n]+' ) do if l == tbl.y then newString[l] = line:sub( 1, tbl.x - 1 ).." "..line:sub( tbl.x + 1, #line ) oldChar = line:sub( tbl.x, tbl.x ) else newString[l] = line end l = l + 1 end return table.concat( newString, "\n" ), oldChar end --orient function local face = "up" local function orient( direction ) if face == "up" and direction == "up" then return elseif face == "up" and direction == "right" then turtle.turnRight() face = "right" elseif face == "up" and direction == "left" then turtle.turnLeft() face = "left" elseif face == "up" and direction == "down" then turtle.turnRight() turtle.turnRight() face = "down" elseif face == "right" and direction == "up" then turtle.turnLeft() face = "up" elseif face == "right" and direction == "right" then return elseif face == "right" and direction == "left" then turtle.turnLeft() turtle.turnLeft() face = "left" elseif face == "right" and direction == "down" then turtle.turnRight() face = "down" elseif face == "left" and direction == "up" then turtle.turnRight() face = "up" elseif face == "left" and direction == "right" then turtle.turnRight() turtle.turnRight() face = "right" elseif face == "left" and direction == "left" then return elseif face == "left" and direction == "down" then turtle.turnLeft() face = "down" elseif face == "down" and direction == "up" then turtle.turnLeft() turtle.turnLeft() face = "up" elseif face == "down" and direction == "right" then turtle.turnLeft() face = "right" elseif face == "down" and direction == "left" then turtle.turnRight() face = "left" elseif face == "down" and direction == "down" then return end end --Find next position local function findNext( tbl ) local oldChar tMaps[ tbl.z ], oldChar = update( tbl ) local l = 1 local compare = { D = true, U = true, ["#"] = true, d = true, u = true, } --Check current level for line in tMaps[ tbl.z ]:gmatch( '[^\r\n]+' ) do if l == tbl.y - 1 and compare[ line:sub( tbl.x, tbl.x ) ] then --turtle should move "up" return function() orient( "up" ) return turtle.forward() end, {x = tbl.x, y = tbl.y - 1, z = tbl.z} elseif l == tbl.y and compare[ line:sub( tbl.x - 1, tbl.x - 1 ) ] then --turtle should move "left" return function() orient( "left" ) return turtle.forward() end, {x = tbl.x - 1, y = tbl.y, z = tbl.z} elseif l == tbl.y and compare[ line:sub( tbl.x + 1, tbl.x + 1 ) ] then --turtle should move "right" return function() orient( "right" ) return turtle.forward() end, {x = tbl.x + 1, y = tbl.y, z = tbl.z} elseif l == tbl.y + 1 and compare[ line:sub( tbl.x, tbl.x ) ]then --turtle should move "down" return function() orient( "down" ) return turtle.forward() end, {x = tbl.x, y = tbl.y + 1, z = tbl.z} elseif oldChar:upper() == "U" then return function() return turtle.up() end, {x = tbl.x, y = tbl.y, z = tbl.z + 1} elseif oldChar:upper() == "D" then return function() return turtle.down() end, {x = tbl.x, y = tbl.y, z = tbl.z - 1} end l = l + 1 end end local place = findStart() local path = {} while place do path[#path + 1], place = findNext( place ) end path.x = 1 path.yield = _yield local mt = { __call = function() if path[ path.x ] and path.yield then local success = path[ path.x ]() path.x = path.x + 1 return success elseif path[ path.x ] then repeat path[ path.x ]() path.x = path.x + 1 until not path[ path.x ] else return false end end, } setmetatable( path, mt ) return path end
pastebin get XPYenpku mapreader
Screenshots & example code coming soon