Advertisement
Guest User

Untitled

a guest
Jan 19th, 2017
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.15 KB | None | 0 0
  1. ocal 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 -- avoid recursing into drop()
  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 function turnRight()
  32.   robot.turnRight()
  33.   f = (f + 1) % 4
  34. end
  35.  
  36. local function turnLeft()
  37.   robot.turnLeft()
  38.   f = (f - 1) % 4
  39. end
  40.  
  41. local function turnTowards(side)
  42.   if f == side - 1 then
  43.     turnRight()
  44.   else
  45.     while f ~= side do
  46.       turnLeft()
  47.     end
  48.   end
  49. end
  50.  
  51. local checkedDrop -- forward declaration
  52.  
  53. local function clearBlock(side, cannotRetry)
  54.   while r.suck(side) do
  55.     checkedDrop()
  56.   end
  57.   local result, reason = r.swing(side)
  58.   if result then
  59.     checkedDrop()
  60.   else
  61.     local _, what = r.detect(side)
  62.     if cannotRetry and what ~= "air" and what ~= "entity" then
  63.       return false
  64.     end
  65.   end
  66.   return true
  67. end
  68.  
  69. local function tryMove(side)
  70.   side = side or sides.forward
  71.   local tries = 10
  72.   while not r.move(side) do
  73.     tries = tries - 1
  74.     if not clearBlock(side, tries < 1) then
  75.       return false
  76.     end
  77.   end
  78.   if side == sides.down then
  79.     z = z + 1
  80.   elseif side == sides.up then
  81.     z = z - 1
  82.   else
  83.     delta[f]()
  84.   end
  85.   return true
  86. end
  87.  
  88. local function moveTo(tx, ty, tz, backwards)
  89.   local axes = {
  90.     function()
  91.       while z > tz do
  92.         tryMove(sides.up)
  93.       end
  94.       while z < tz do
  95.         tryMove(sides.down)
  96.       end
  97.     end,
  98.     function()
  99.       if y > ty then
  100.         turnTowards(3)
  101.         repeat tryMove() until y == ty
  102.       elseif y < ty then
  103.         turnTowards(1)
  104.         repeat tryMove() until y == ty
  105.       end
  106.     end,
  107.     function()
  108.       if x > tx then
  109.         turnTowards(2)
  110.         repeat tryMove() until x == tx
  111.       elseif x < tx then
  112.         turnTowards(0)
  113.         repeat tryMove() until x == tx
  114.       end
  115.     end
  116.   }
  117.   if backwards then
  118.     for axis = 3, 1, -1 do
  119.       axes[axis]()
  120.     end
  121.   else
  122.     for axis = 1, 3 do
  123.       axes[axis]()
  124.     end
  125.   end
  126. end
  127.  
  128. function checkedDrop(force)
  129.   local empty = 0
  130.   for slot = 1, 16 do
  131.     if robot.count(slot) == 0 then
  132.       empty = empty + 1
  133.     end
  134.   end
  135.   if not dropping and empty == 0 or force and empty < 16 then
  136.     local ox, oy, oz, of = x, y, z, f
  137.     dropping = true
  138.     moveTo(0, 0, 0)
  139.     turnTowards(2)
  140.  
  141.     for slot = 1, 16 do
  142.       if robot.count(slot) > 0 then
  143.         robot.select(slot)
  144.         local wait = 1
  145.         repeat
  146.           if not robot.drop() then
  147.             os.sleep(wait)
  148.             wait = math.min(10, wait + 1)
  149.           end
  150.         until robot.count(slot) == 0
  151.       end
  152.     end
  153.     robot.select(1)
  154.  
  155.     dropping = false
  156.     moveTo(ox, oy, oz, true)
  157.     turnTowards(of)
  158.   end
  159. end
  160.  
  161. local function step()
  162.   clearBlock(sides.down)
  163.   if not tryMove() then
  164.     return false
  165.   end
  166.   clearBlock(sides.up)
  167.   return true
  168. end
  169.  
  170. local function turn(i)
  171.   if i % 2 == 1 then
  172.     turnRight()
  173.   else
  174.     turnLeft()
  175.   end
  176. end
  177.  
  178. local function digLayer()
  179.   --[[ We move in zig-zag lines, clearing three layers at a time. This means we
  180.        have to differentiate at the end of the last line between even and odd
  181.        sizes on which way to face for the next layer:
  182.        For either size we rotate once to the right. For even sizes this will
  183.        cause the next layer to be dug out rotated by ninety degrees. For odd
  184.        ones the return path is symmetrical, meaning we just turn around.
  185.        Examples for two layers:
  186.        s--x--x      e--x--x      s--x--x--x      x--x  x--x
  187.              |            |               |      |  |  |  |
  188.        x--x--x  ->  x--x--x      x--x--x--x      x  x  x  x
  189.        |            |            |           ->  |  |  |  |
  190.        x--x--e      x--x--s      x--x--x--x      x  x  x  x
  191.                                           |      |  |  |  |
  192.                                  e--x--x--x      s  x--x  e
  193.        Legend: s = start, x = a position, e = end, - = a move
  194.   ]]
  195.   for i = 1, size do
  196.     for j = 1, size - 1 do
  197.       if not step() then
  198.         return false
  199.       end
  200.     end
  201.     if i < size then
  202.       -- End of a normal line, move the "cap".
  203.       turn(i)
  204.       if not step() then
  205.         return false
  206.       end
  207.       turn(i)
  208.     else
  209.       turnRight()
  210.       if size % 2 == 1 then
  211.         turnRight()
  212.       end
  213.       for i = 1, 3 do
  214.         if not tryMove(sides.down) then
  215.           return false
  216.         end
  217.       end
  218.     end
  219.   end
  220.   return true
  221. end
  222.  
  223. repeat until not digLayer()
  224. moveTo(0, 0, 0)
  225. turnTowards(0)
  226. checkedDrop(true)
  227.  
  228. if options.s then
  229.   computer.shutdown()
  230. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement