-- LOAD DEAD RECKONING API os.loadAPI("apis/reckon") -- BEGIN SETUP -- keep journal files here local j = "dig.journal/" -- refuel when fuel < 2560 local lowFuel = 2560 -- resume running when fuel > 7680 local runFuel = 7680 -- allow the turtle to burn coal fuel -- that it mines. false = not allowed, -- always return for refueling. local burnCoal = false --------------------------------------- -- don't change anything below here. -- --------------------------------------- -- maximum radius -- seriously, don't change it -- you'll be sorry if you do... local rLim = 63 local start = os.clock() local args = {...} local r = tonumber(args[1]) or rLim local d = (tonumber(args[2]) or 2) * 3 - 2 -- calculate how many torches we need -- to cover the requested radius local tMin = math.floor(r / 6) tMin = tMin * tMin if 0 == tMin then tMin = 1 end -- bootstrap if not fs.exists(j) or not fs.isDir(j) then fs.makeDir(j) end -- make sure the radius is sane if r > rLim then print("radius reduced to "..rLim..".") r = rLim end -- load saved arguments if fs.exists(j.."args") then local fh = fs.open(j.."args", "r") r = tonumber(fh.readLine()) d = tonumber(fh.readLine()) fh.close() -- sanity check again if r > rLim then r = rLim end else -- or save them if they don't exist local fh = fs.open(j.."arguments", "w") fh.writeLine(r) fh.writeLine(d) fh.close() end local xs, xe, xd = 1, r, 1 local ys, ye, yd = 1, r, 1 if fs.exists(j.."weave") then local fh = fs.open(j.."weave", "r") xs = tonumber(fh.readLine()) xe = tonumber(fh.readLine()) xd = tonumber(fh.readLine()) ys = tonumber(fh.readLine()) ye = tonumber(fh.readLine()) yd = tonumber(fh.readLine()) fh.close() end -- END SETUP -- BEGIN AUXILIARY FUNCTIONS function tryRefuel () for i = 16, 1, -1 do if 0 ~= turtle.getItemCount(i) then turtle.select(i) turtle.refuel() end end end function refuel () if turtle.getFuelLevel() < lowFuel then print("I need fuel.") repeat sleep(5) tryRefuel() until turtle.getFuelLevel() > runFuel end end function needTorches () if tMin ~= 1 and 1 == turtle.getItemCount(1) then reckon.goHome() print("I need torches.") end repeat sleep(5) until tMin <= turtle.getItemCount(1) end -- place a torch when appropriate function placeTorch () local x, y, z = reckon.getX(), reckon.getY(), reckon.getZ() --[[ rotated grid pattern BROKEN DO NOT USE more efficient torch placement if i ever figure it out... if not turtle.compareDown() and ( 4 == x % 7 and (4 == y or ye - 4 == y) or 4 == y % 7 and (4 == x or xe - 4 == x) ) then -- place every seven on edges turtle.digDown() turtle.placeDown() elseif x > 7 and y > 7 then -- and on a rotated grid inside local g = ((x - y) / 16 - y) % 16 if 4 == g or 12 == g then turtle.digDown() turtle.placeDown() end end ]]-- -- FIXME: this code hurts me. local xl = x <= r / 2 + 1.5 and 4 == x % 7 local xh = x >= r / 2 + 1.5 and 4 == (r - x) % 7 local yl = y <= r / 2 + 1.5 and 4 == y % 7 local yh = y >= r / 2 + 1.5 and 4 == (r - y) % 7 if ( xl and yl or xl and yh or xh and yl or xh and yh ) and not turtle.compareDown() then turtle.digDown() turtle.placeDown() end end -- fancy zig-zagging function saveWeaveState () local fh = fs.open(j.."weave", "w") fh.writeLine(xs) fh.writeLine(xe) fh.writeLine(xd) fh.writeLine(ys) fh.writeLine(ye) fh.writeLine(yd) fh.close() end function diggum () turtle.dig() turtle.suck() reckon.forward() turtle.digUp() turtle.digDown() turtle.suckDown() turtle.suckUp() end function nextRow() -- BUG: batched actions -- which way to turn? mmm mathy. local axis = reckon.getF() % 2 local d = (axis * yd + (axis - 1) * xd) + 2 -- weave if 0 == reckon.getF() % 2 then xs, xe, xd = xe, xs, -xd else ys, ye, yd = ye, ys, -yd end saveWeaveState() reckon.turn(d) diggum() reckon.turn(d) end function nextLevel() -- BUG: batched actions -- weave xs, xe, xd = xe, xs, -xd ys, ye, yd = ye, ys, -yd saveWeaveState() -- which way to turn? mmm mathy. local axis = reckon.getF() % 2 local d = (1 + axis * yd - (axis - 1) * xd) / 2 reckon.turn(d) reckon.down(3) placeTorch() end -- check if inventory needs emptying function inventoryFull () for i = 1, 16 do if turtle.getItemCount(i) == 0 then return false end end return true end -- END AUXILIARY FUNCTIONS -- BEGIN MAIN PROGRAM function saveBookmark () local fh = fs.open(j.."bookmark", "w") for c, c in ipairs({ reckon.getX(), reckon.getY(), reckon.getZ(), reckon.getF() }) do fh.writeLine(c) end fh.close() end function needSomething () if needTorches() or inventoryFull() or not burnCoal then saveBookmark() reckon.goHome() emptyInventory() end if turtle.getFuelLevel() < minFuel then tryRefuel() end end -- returning to dig site function restoreBookmark () if not fs.exists(j.."bookmark") then return end local fh = fs.open(j.."bookmark", "w") local x, y, z, f = tonumber(fh.readLine()), tonumber(fh.readLine()), tonumber(fh.readLine()), tonumber(fh.readLine()) fh.close() reckon.gotoZYXF(x, y, z, f) fs.delete(j.."bookmark") end -- digging phase function goDig () digging = true print("it's off to work i go") turtle.digUp() if not turtle.compareDown() then turtle.digDown() end turtle.suckDown() turtle.suckUp() -- actually dig repeat repeat while 0 == reckon.getF() % 2 and reckon.getX() ~= xe or 1 == reckon.getF() % 2 and reckon.getY() ~= ye do diggum() if inventoryFull() or turtle.getFuelLevel() < lowFuel then return false end end if reckon.getX() == xe and reckon.getY() == ye then if reckon.getZ() == d then return true else nextLevel() end else nextRow() end until cows_come_home until cows_come_home end local phase = 1 function savePhase () local fh = fs.open(j.."phase", "w") fh.writeLine(phase) fh.close() end if fs.exists(j.."phase") then -- interrupted session -- pick up where we left off if reckon.hasState() then reckon.resume() end local fh = fs.open(j.."phase", "r") phase = tonumber(fh.readLine()) fh.close() else -- new session -- make sure we have enough torches turtle.select(1) local t = math.floor(r / 7.1) t = t * t if 0 == t then t = 1 end if turtle.getItemCount(1) < t then print( "place at least "..t.. " torch(es) in the first slot to begin." ) repeat sleep(1) until turtle.getItemCount(1) >= t end -- try to refuel before we complain. if turtle.getFuelLevel() < lowFuel then tryRefuel() end if turtle.getFuelLevel() < lowFuel then refuel() end print("hi hoooooooo!!!") -- move into 1, 1, 1 reckon.down() reckon.forward() end -- main part of the state engine repeat savePhase() print("calling phase "..phase) if ({ [0] = needSomething, [1] = restoreBookmark, [2] = goDig })[phase]() then break end phase = (phase + 1) % 3 until cows_come_home emptyInventory() shell.run("cleanup") start = os.clock() - start print(string.format( "complete. elapsed time: %02d:%02d:%02d", math.floor(start / 3600), math.floor(start / 60) % 60, start % 60 )) -- END ALL THE THINGS