Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- true: passage; false: wall; nil: unexplored
- local map, deadEnd, locationOfIntrest = {}, {}, {}
- local tX, tY = 0, 0
- local tFace = 0 -- tface % 4 = facing direction
- local getFaceXY, getFace, getXY, resolveFace;
- do -- Various positional helper functions
- function getFace()
- return tFace % 4
- end
- local faces = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}
- function getFaceXY(nFace)
- nFace = nFace or tFace
- nFace = (nFace %4)+1 -- Lua, you...
- local fX, fY = faces[nFace][1], faces[nFace][2]
- return fX, fY
- end
- function getXY()
- return tX, tY
- end
- function resolveFace(nX, nY, nFace)
- nX, nY = nX or tX, nY or tY
- nFace = nFace or tFace
- local fX, fY = getFaceXY(nFace)
- return nX + fX, nY + fY
- end
- end
- local safeMap, safeDeadEnd, safeLocationOfIntrest, safeLOI;
- do --Safe* functions
- function safeMap(nX, nY, bState) -- Check/set the map safely
- --print("SafeMap: ", nX, ", ", nY, ", ", bState)
- if not map[nY] then -- Use Y, X because of terminals
- map[nY] = {}
- end
- if bState == nil then -- We're looking up
- return map[nY][nX]
- end
- if map[nY][nX] then
- return false, map[nY][nX]
- --error("Attempting to modify map.")
- end
- map[nY][nX] = bState
- return true, bState
- end
- function safeDeadEnd(nX, nY, bState)
- if not deadEnd[nY] then
- deadEnd[nY] = {}
- end
- if bState == nil then -- We're looking up
- return deadEnd[nY][nX]
- end
- if deadEnd[nY][nX] then
- return false, deadEnd[nY][nX]
- end
- deadEnd[nY][nX] = bState
- return true, bState
- end
- function safeLocationOfIntrest(nX, nY, sValue)
- if not locationOfIntrest[nY] then
- locationOfIntrest[nY] = {}
- end
- if sValue == nil then -- We're looking up
- return locationOfIntrest[nY][nX]
- end
- local oLOI = locationOfIntrest[nY][nX]
- locationOfIntrest[nY][nX] = sValue
- return true, oLOI, sValue
- end
- safeLOI = safeLocationOfIntrest; -- shortcut for lazies
- end
- local render, getDrawChar;
- do -- Graphical functions
- local rX, rY = term.getSize()
- local nCenterY = math.floor(rY / 2)
- local nCenterX = math.floor(rX / 2)
- tLOI = {["Start"] = "S", ["End"] = "E", ["Destination"] = "D"}
- function getDrawChar(x, y)
- -- D = destination, T = turtle, # = wall, * = unexplored
- -- S = Start, E = end, - = closed path
- local sLOI = safeLocationOfIntrest(x, y)
- sLOI = tLOI[sLOI]
- local sMap = safeMap(x, y)
- local sTurt = (x == tX and y == tY) and "T"
- if sMap then
- sMap = " "
- else
- sMap = (sMap == false and "#") or "*"
- end
- return sTurt or sLOI or sMap
- end
- function render() -- 36x12 default
- term.clear()
- for y = 1, rY do
- term.setCursorPos(1, y)
- local dY = (y - nCenterY) + tY -- draw Y
- for x = 1, rX do
- local dX = (x - nCenterX) + tX -- draw X
- term.write(getDrawChar(dX, dY))
- end
- end
- end
- end
- -- Major functions: Pathfinding, mostly
- local function checkDeadEnd(nX, nY, nXOrgin, nYOrgin)
- local checked = {}
- local function isChecked(nX, nY, bAdd)
- if not checked[nY] then
- checked[nY] = {}
- end
- if bAdd and not checked[nY][nX] then
- checked[nY][nX] = true
- return false
- end
- return checked[nY][nX]
- end
- local function isDeadEnd(nX, nY, nXOrgin, nYOrgin)
- local mres = safeMap(nX, nY)
- if mres == nil or mres == true then -- Not a dead end!
- return true
- end
- -- Check faces Do one by one because asdf.
- if not (nX+1 == nXOrgin and nY == nYOrgin) then
- if not isChecked(nX+1, nY, true) and isDeadEnd(nX+1, nY, nX, nY) then
- return true
- end
- end
- if not (nX-1 == nXOrgin and nY == nYOrgin) then
- if not isChecked(nX-1, nY, true) and isDeadEnd(nX-1, nY, nX, nY) then
- return true
- end
- end
- if not (nX == nXOrgin and nY+1 == nYOrgin) then
- if not isChecked(nX, nY+1, true) and isDeadEnd(nX, nY+1, nX, nY) then
- return true
- end
- end
- if not (nX == nXOrgin and nY-1 == nYOrgin) then
- if not isChecked(nX, nY-1, true) and isDeadEnd(nX, nY-1, nX, nY) then
- return true
- end
- end
- safeDeadEnd(nX, nY)
- return false -- Dead end
- end
- return isDeadEnd(nX, nY, nXOrgin, nYOrgin)
- end
- local function checkRedundantPaths() --TODO: Marks Loops as blocked.
- end
- local turnLeft, turnRight, moveForward, moveBackward;
- do -- Movement functions
- function turnLeft()
- tFace = tFace + 1
- turtle.turnLeft()
- end
- function turnRight()
- tFace = tFace - 1
- turtle.turnRight()
- end
- function moveForward()
- local dX, dY = resolveFace()
- if turtle.forward() then
- tX, tY = dX, dY
- safeMap(dX, dY, true)
- return true
- end
- safeMap(dX, dY, false)
- return false
- end
- function moveBackward()
- local fX, fY = getFaceXY()
- if turtle.back() then
- tX, tY = tX - fX, tY - fY
- safeMap(tX, tY, true)
- return true
- end
- safeMap(tX - fX, tY - fY, false)
- return false
- end
- end
- local function findMove() -- Find a suitable move
- end
- local function move_Block()
- if turtle.down() then -- End of maze indicator
- return true
- end
- render()
- -- Turn left once, to set position so we can go forward once, turn left, follow wall, etc.
- turnLeft()
- for i = 1, 3 do
- if moveForward() then
- if move_Block() then
- return true
- end
- end
- turnRight()
- end
- -- Dead end, walk back in shame.
- turnLeft()
- moveBackward()
- return false
- end
- local function main()
- safeMap(tX, tY, true)
- safeLOI(tX, tY, "Start")
- while true do
- --local path = findMove()
- --displayPath(path)
- move_Block()
- end
- print("Maze complete.")
- end
- main()
Advertisement
Add Comment
Please, Sign In to add comment