Advertisement
Guest User

dig-imp.lua

a guest
Dec 16th, 2016
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.15 KB | None | 0 0
  1. local component = require("component")
  2. local computer = require("computer")
  3. local robot = require("robot")
  4. local shell = require("shell")
  5. local sides = require("sides")
  6.  
  7. if not component.isAvailable("robot") then
  8.   io.stderr:write("can only run on robots")
  9.   return
  10. end
  11.  
  12. local args, options = shell.parse(...)
  13. if #args < 1 then
  14.   io.write("Usage: dig [-s] <size>\n")
  15.   io.write(" -s: shutdown when done.")
  16.   return
  17. end
  18.  
  19. local size = tonumber(args[1])
  20. if not size then
  21.   io.stderr:write("invalid size")
  22.   return
  23. end
  24.  
  25. local r = component.robot
  26. local x, y, z, f = 0, 0, 0, 0
  27. local dropping = false
  28. local delta = {[0] = function() x = x + 1 end, [1] = function() y = y + 1 end,
  29.                [2] = function() x = x - 1 end, [3] = function() y = y - 1 end}
  30.  
  31. local invSize = r.inventorySize()
  32.  
  33. local function turnRight()
  34.   robot.turnRight()
  35.   f = (f + 1) % 4
  36. end
  37.  
  38. local function turnLeft()
  39.   robot.turnLeft()
  40.   f = (f - 1) % 4
  41. end
  42.  
  43. local function turnTowards(side)
  44.   if f == side - 1 then
  45.     turnRight()
  46.   else
  47.     while f ~= side do
  48.       turnLeft()
  49.     end
  50.   end
  51. end
  52.  
  53. local checkedDrop
  54.  
  55. local function clearBlock(side, cannotRetry)
  56.   while r.suck(side) do
  57.     checkedDrop()
  58.   end
  59.   local result, reason = r.swing(side)
  60.   if result then
  61.     checkedDrop()
  62.   else
  63.     local _, what = r.detect(side)
  64.     if cannotRetry and what ~= "air" and what ~= "entity" then
  65.       return false
  66.     end
  67.   end
  68.   return true
  69. end
  70.  
  71. local function tryMove(side)
  72.   side = side or sides.forward
  73.   local tries = 10
  74.   while not r.move(side) do
  75.     tries = tries - 1
  76.     if not clearBlock(side, tries < 1) then
  77.       return false
  78.     end
  79.   end
  80.   if side == sides.down then
  81.     z = z + 1
  82.   elseif side == sides.up then
  83.     z = z - 1
  84.   else
  85.     delta[f]()
  86.   end
  87.   return true
  88. end
  89.  
  90. local function moveTo(tx, ty, tz, backwards)
  91.   local axes = {
  92.     function()
  93.       while z > tz do
  94.         tryMove(sides.up)
  95.       end
  96.       while z < tz do
  97.         tryMove(sides.down)
  98.       end
  99.     end,
  100.     function()
  101.       if y > ty then
  102.         turnTowards(3)
  103.         repeat tryMove() until y == ty
  104.       elseif y < ty then
  105.         turnTowards(1)
  106.         repeat tryMove() until y == ty
  107.       end
  108.     end,
  109.     function()
  110.       if x > tx then
  111.         turnTowards(2)
  112.         repeat tryMove() until x == tx
  113.       elseif x < tx then
  114.         turnTowards(0)
  115.         repeat tryMove() until x == tx
  116.       end
  117.     end
  118.   }
  119.   if backwards then
  120.     for axis = 3, 1, -1 do
  121.       axes[axis]()
  122.     end
  123.   else
  124.     for axis = 1, 3 do
  125.       axes[axis]()
  126.     end
  127.   end
  128. end
  129.  
  130. function checkedDrop(force)
  131.   local empty = 0
  132.   for slot = 1, invSize do
  133.     if robot.count(slot) == 0 then
  134.       empty = empty + 1
  135.     end
  136.   end
  137.   if not dropping and empty == 0 or force and empty < 16 then
  138.     local ox, oy, oz, of = x, y, z, f
  139.     dropping = true
  140.     moveTo(0, 0, 0)
  141.     turnTowards(2)
  142.  
  143.     for slot = 1, invSiz do
  144.       if robot.count(slot) > 0 then
  145.         robot.select(slot)
  146.         local wait = 1
  147.         repeat
  148.           if not robot.drop() then
  149.             os.sleep(wait)
  150.             wait = math.min(10, wait + 1)
  151.           end
  152.         until robot.count(slot) == 0
  153.       end
  154.     end
  155.     robot.select(1)
  156.  
  157.     dropping = false
  158.     moveTo(ox, oy, oz, true)
  159.     turnTowards(of)
  160.   end
  161. end
  162.  
  163. local function step()
  164.   clearBlock(sides.down)
  165.   if not tryMove() then
  166.     return false
  167.   end
  168.   clearBlock(sides.up)
  169.   return true
  170. end
  171.  
  172. local function turn(i)
  173.   if i % 2 == 1 then
  174.     turnRight()
  175.   else
  176.     turnLeft()
  177.   end
  178. end
  179.  
  180. local function digLayer()
  181.   for i = 1, size do
  182.     for j = 1, size - 1 do
  183.       if not step() then
  184.         return false
  185.       end
  186.     end
  187.     if i < size then
  188.       turn(i)
  189.       if not step() then
  190.         return false
  191.       end
  192.       turn(i)
  193.     else
  194.       turnRight()
  195.       if size % 2 == 1 then
  196.         turnRight()
  197.       end
  198.       for i = 1, 3 do
  199.         if not tryMove(sides.down) then
  200.           return false
  201.         end
  202.       end
  203.     end
  204.   end
  205.   return true
  206. end
  207.  
  208. repeat until not digLayer()
  209. moveTo(0, 0, 0)
  210. turnTowards(0)
  211. checkedDrop(true)
  212.  
  213. if options.s then
  214.   computer.shutdown()
  215. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement