Posted 02 July 2014 - 05:26 PM
I've created an api that takes a table of multiline strings and turns it into a function that moves the turtle from start to end. Mark the starting position with "X", continue the path with #, and go up and down by using "U" or "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.
pastebin get XPYenpku mapreader
Screenshots & example code coming soon
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