MigukNamja

MigukNamja's Quarry Program - WIP

Aug 16th, 2013
242
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ----------------------------------
  2. -- Warning ! WORK IN PROGRESS ! --
  3. -- Has not been fully tested !  --
  4. ----------------------------------
  5. --
  6. -- MigukNamja's 1st Quarry Program
  7. -- Copyright 2013 MigukNamja
  8. --
  9. -- Setup:
  10. --   The quarried block drop-off container should be placed on the mining turtle's *LEFT* side
  11. --   A chest or container with solid fuel (ex. charcoal) should be placed directly *BEHIND* the turtle
  12. --   These inventories may (should) be automatically emptied and re-supplied, respectively, to ensure smooth
  13. --   operation. The turtle will drop-off and refuel from the start, so it is not necessary to pre-fuel the
  14. --   mining turtle
  15. --
  16. -- The command line arguments are:
  17. -- 1st : The number of blocks to move forward. It needs to be a positive, even number
  18. -- 2nd : The number of blocks to move rightward. It can be any positive number, including 0
  19. -- 3rd : (Optional) The number of blocks down to begin quarry.
  20. --
  21. -- It will stop if it cannot:
  22. -- (A) Drop-off its inventory
  23. -- (B) Its inventory somehow fills up before it can drop it off
  24. -- (C) Runs out of fuel or cannot refuel to minimum level
  25. -- (D) Overcome an obstacle, such as multiple undiggable entities, like multiple mobs or a quickly-moving mob
  26. --
  27. -- Note this also does a vertical striping by shafts rather than the usual "strip mine" approach.
  28. -- This means lower-layer minerals like diamond and gold will show up *faster* then the usual "strip mine"
  29. --  approach that automated machines like the BC Quarry use. You can furthemore tell it to start its quarry
  30. --  a variable depth below the surface so minerals like gold, diamond, restone, lapis, etc.,. can be focused.
  31. --
  32. -- It can also handle an arbitrary quarry size, so quarries (much larger) then 64x64 are possible.
  33. -- In theory, if chunks are loaded it could do near-infinite-size quarries, though the round-trip travel
  34. -- time to the drop-off chest and the refuel chest would make it woefully inefficient.
  35. --
  36. -- The turtle will then attempt to dig a quarry forward by rightward and "down to bedrock" depth.
  37. -- It will do so by first digging straight down, then up, and forward (repeat down and up), then when done
  38. -- with a complete forward 'column', will move rightward 1 and repeat.
  39. --
  40. -- It will return to the drop-off chest and the fuel supply chest after every down-up run.
  41. --
  42. -- The usual turtle robot caveats apply, such as being in a loaded chunk, limited inventory, etc.,.
  43. --
  44. -- This program does *not* use the Wireless modem and GPS api. Instead, it tries very hard
  45. --  to track the x, y, and z deltas. It is therefore suitable for early-game turtle mining and could be used
  46. --  as soon as one has 3 diamonds to build a mining turtle. Later or different versions of this program may
  47. --  use the gps API for more robust behavior and fewer trips back to the drop-off and refuel chests
  48. --
  49.  
  50. tForward = 0
  51. tRight = 0
  52. tDown = 0
  53.  
  54. function down()
  55.   if turtle.down() then
  56.     tDown = tDown + 1
  57.     return true
  58.   else
  59.     return false
  60.   end
  61. end
  62.  
  63. function up()
  64.   if turtle.up() then
  65.     tDown = tDown - 1
  66.     return true
  67.   else
  68.     return false
  69.   end
  70. end
  71.  
  72. --
  73. -- Drop off items in inventory
  74. -- Will return true if it could successfully drop off everything
  75. -- Will return false if it could not, i.e. target inventory was full
  76. --
  77. function dropOffItems()
  78.   turtle.turnLeft()
  79.  
  80.   for i=1,16 do
  81.     turtle.select(i)
  82.     if turtle.getItemCount(i) > 0 and not turtle.drop() then
  83.       return false
  84.     end
  85.   end
  86.  
  87.   turtle.turnRight()
  88.   turtle.select(1)
  89.  
  90.   return true
  91. end
  92.  
  93. -- Refuel
  94. -- Input : Minimum fuel level in turtle units
  95. --         http://computercraft.info/wiki/Turtle.refuel#Fuel_Values
  96. -- Precondition : Turtle is facing 180 degrees away from chest with fuel in it,
  97. --                but is adjacent to it
  98. -- Postcondition : Turtle has at least the minimum fuel level in its fuel buffer
  99. --
  100. -- If no arguments are given, it defaults to a minimum of a stack of charcoal
  101. --
  102. function refuel(minFuelLevel)
  103.   if minFuelLevel == nil then
  104.     minFuelLevel = 80 * 64 -- a stack of charcoal
  105.   elseif turtle.getFuelLevel() >= minFuelLevel then
  106.     return true
  107.   end
  108.  
  109.   turtle.turnRight()
  110.   turtle.turnRight()
  111.   turtle.select(16)
  112.  
  113.   while turtle.getFuelLevel() < minFuelLevel do
  114.     if not turtle.suck() then
  115.       return false
  116.     else
  117.       turtle.refuel()
  118.     end
  119.   end
  120.  
  121.   turtle.select(1)
  122.   turtle.turnLeft()
  123.   turtle.turnLeft()
  124.  
  125.   return true
  126. end
  127.  
  128. --
  129. -- Check to see if we have enough fuel to keep going a little while longer
  130. --
  131. function enoughFuel()
  132.   if turtle.getFuelLevel() >= (64 * 8) then
  133.     return true
  134.   else
  135.     return false
  136.   end
  137. end
  138.  
  139. --
  140. -- Check to see if we have enough fuel to keep going a little while longer
  141. -- Perhaps 6 slots out of 16 free is enough
  142. --
  143. function enoughFreeSpace()
  144.   local slotsUsed = 0
  145.   for i=1,16 do
  146.     --turtle.select(i)
  147.     if turtle.getItemCount(i) > 0 then
  148.       slotsUsed = slotsUsed + 1
  149.     end
  150.   end
  151.  
  152.   turtle.select(1)
  153.  
  154.   if slotsUsed <= 10 then
  155.     return true
  156.   else
  157.     return false
  158.   end
  159. end
  160.  
  161. -- Move forward 'blocks' number of blocks, digging when necessary
  162. -- Hitting bedrock or something undiggable like an entity (creature) will
  163. --   prevent forward movement, and attempts will be made to go around
  164. --
  165. -- Return actual blocks moved forward
  166. function moveForward(blocks)
  167.   if blocks < 0 then return moveBack(0-blocks) end
  168.   if blocks == 0 then return 0 end
  169.  
  170.   local moved = 0
  171.  
  172.   while moved < blocks do
  173.     if turtle.forward() then -- air, nothing to dig, but go down
  174.       moved = moved + 1
  175.     elseif turtle.dig() then -- had to dig to go forwards
  176.       if not turtle.forward() then
  177.         local attempts = 0
  178.         while turtle.dig() and attempts < 20 do
  179.           attempts = attempts + 1 -- take care water won't cause infinite digging
  180.           sleep(0.25) -- might have to chew through a stack of sand or gravel
  181.         end
  182.        
  183.         if turtle.forward() then
  184.           moved = moved + 1
  185.         end
  186.       else
  187.         moved = moved + 1
  188.       end
  189.     else -- undiggable, give up (for now)
  190.       return moved
  191.     end
  192.    
  193.     sleep(0.25) -- sleep to avoid yielding error
  194.   end
  195.  
  196.   return moved
  197. end
  198.  
  199. -- Move downwards 'blocks' number of blocks, digging when necessary
  200. -- Hitting bedrock or something undiggable like an entity (creature) will
  201. --   prevent downwards movement, and attempts will be made to go around
  202. --
  203. -- Return actual blocks moved down
  204. function moveDown(blocks)
  205.   if blocks < 0 then return moveUp(0-blocks) end
  206.   if blocks == 0 then return 0 end
  207.  
  208.   local moved = 0
  209.  
  210.   while moved < blocks do
  211.     if down() then -- air, nothing to dig, but go down
  212.       moved = moved + 1
  213.     elseif turtle.digDown() then -- had to dig to go down
  214.       if not down() then
  215.         while turtle.digDown() do end
  216.         if down() then
  217.           moved = moved + 1
  218.         end
  219.       else
  220.         moved = moved + 1
  221.       end
  222.     else -- undiggable, give up (for now)
  223.       return moved
  224.     end
  225.    
  226.     sleep(0.25) -- sleep to avoid yielding error
  227.   end
  228.  
  229.   return moved
  230. end
  231.  
  232. -- Move upwards 'blocks' number of blocks, digging when necessary
  233. -- Hitting bedrock or something undiggable like an entity (creature) will
  234. --   prevent upwards movement, and attempts will be made to go around
  235. --
  236. -- Return actual blocks moved up
  237. function moveUp(blocks)
  238.   if blocks < 0 then return moveDown(0-blocks) end
  239.   if blocks == 0 then return 0 end
  240.  
  241.   local moved = 0
  242.  
  243.   while moved < blocks do
  244.     if up() then -- air, nothing to dig, but go up
  245.       moved = moved + 1
  246.     elseif turtle.digUp() then -- dig up to go up
  247.       if not up() then
  248.         local attempts = 0
  249.         while turtle.digUp() and attempts < 20 do
  250.           attempts = attempts + 1 -- take care water won't cause infinite digging
  251.           sleep(0.25) -- there may be a stack of sand or gravel above us, wait for it to fall
  252.         end
  253.            
  254.         if up() then
  255.           moved = moved + 1
  256.         else -- try to go around
  257.           assert( moveForward( 1 ) == 1 )
  258.           assert( moveUp( 1 ) == 1 )
  259.           assert( moveBack( 1 ) == 1 )
  260.           moved = moved + 1
  261.         end
  262.       else
  263.         moved = moved + 1
  264.       end
  265.     else -- undiggable, likely an entity (aka mob), try to go around
  266.       assert( moveForward( 3 ) == 3 )
  267.       assert( moveUp( 1 ) == 1 )
  268.       assert( moveBack( 3 ) == 3 )
  269.       moved = moved + 1
  270.     end
  271.  
  272.     sleep(0.25) -- sleep to avoid yielding error
  273.   end
  274.  
  275.   return moved
  276. end
  277.  
  278. -- Move backwards, digging when necessary
  279. function moveBack(blocks)
  280.   if blocks < 0 then return moveForward(0-blocks) end
  281.   if blocks == 0 then return 0 end
  282.  
  283.   local moved = 0
  284.  
  285.   turtle.turnRight()
  286.   turtle.turnRight()
  287.   moved = moveForward(blocks)
  288.   turtle.turnRight()
  289.   turtle.turnRight()
  290.  
  291.   tForward = tForward - moved
  292.  
  293.   return moved
  294. end
  295.  
  296. -- Move to the right, digging when necessary
  297. function moveRight(blocks)
  298.   if blocks < 0 then return moveLeft(0-blocks) end
  299.   if blocks == 0 then return 0 end
  300.  
  301.   local moved = 0
  302.  
  303.   turtle.turnRight()
  304.   moved = moveForward(blocks)
  305.   turtle.turnLeft()
  306.  
  307.   tRight = tRight + moved
  308.  
  309.   return moved
  310. end
  311.  
  312. -- Move to the left, digging when necessary
  313. function moveLeft(blocks)
  314.   if blocks < 0 then return moveRight(0-blocks) end
  315.   if blocks == 0 then return 0 end
  316.  
  317.   local moved = 0
  318.    
  319.   turtle.turnLeft()
  320.   moved = moveForward(blocks)
  321.   turtle.turnRight()
  322.  
  323.   tRight = tRight - moved
  324.  
  325.   return moved
  326. end
  327.  
  328. -- Preconditions:
  329. -- (1) Turtle is directly above bedrock and cannot go down further
  330. -- (2) Anything above turtle will be dug and is diggable
  331. -- (3) Return value is how many blocks up we moved
  332. --
  333. -- Note : the chunks I'm in have perfectly flat bedrock, so this extra code to handle uneven
  334. --        bedrock is commented out
  335. function bedrockForward()
  336.  
  337.   -- Largest delta between lowest possible bedrock and highest possible bedrock....right ?
  338.   --local blocksUp = 4
  339.  
  340.   --assert( moveUp(blocksUp) == blocksUp )
  341.   assert( moveForward(1) == 1 )
  342.   --local movedDn = moveDown(blocksUp * 2) -- We might have been on top layer of bedrock
  343.  
  344.   --return blocksUp - movedDn
  345.  
  346.   return tonumber(0)
  347. end
  348.  
  349. -- Dig straight down to bedrock or otherwise undiggable, then move forward 1, and dig straight up
  350. -- This is a 2 deep by 1 width by <as deep as we can go> shaft
  351. function downAndUp(maxDig)
  352.   local bDn = tonumber(moveDown(maxDig))
  353.   print( "downAndUp(), moved down ", bDn )
  354.  
  355.   bedrockForward()
  356.   --print( "downAndUp(), bedworkForward() returned ", delta )
  357.  
  358.   local movedUp = moveUp(bDn)
  359.   if movedUp ~= bDn then
  360.     print( "downAndUp(), movedUp", movedUp, " ~= ", bDn )  
  361.     return false
  362.   end
  363.  
  364.   return true
  365. end
  366.  
  367. function usage()
  368.   print( "Usage: quarry <blocks_forward> <blocks_right> [max depth] [start depth]" )
  369.   print( "Forward must be at least 2 and right at least 1. Max depth must be at least 1 if specified." )
  370. end
  371.  
  372. function parseArgs(args)
  373.   local validSyntax = false
  374.   local bForward = 0
  375.   local bRight = 0
  376.   local maxDig = 256
  377.   local startDig = 0
  378.  
  379.   if #args < 2 or #args > 3 then
  380.     return false
  381.   elseif args[1] == "help" then
  382.     return false
  383.   elseif args[1] == nil or args[2] == nil then
  384.     return false
  385.   else
  386.     bForward = tonumber( args[1] )
  387.     bRight   = tonumber( args[2] )
  388.    
  389.     if #args >= 3 then
  390.       maxDig = tonumber( args[3] )
  391.     end
  392.    
  393.     if #args == 4 then
  394.       startDig = tonumber( args[4] )
  395.     end
  396.  
  397.     if bForward < 2 or bRight < 1 or maxDig < 1 or startDig < 0 then
  398.       validSyntax = false
  399.     else
  400.       validSyntax = true
  401.     end
  402.   end
  403.  
  404.   return validSyntax, bForward, bRight, maxDig, startDig
  405. end
  406.  
  407. local tArgs = { ... }
  408. validSyntax, bForward, bRight, maxDig, startDig = parseArgs(tArgs)
  409. if not validSyntax then
  410.   usage()
  411.   return
  412. end
  413.  
  414. print( "Quarrying ", bForward, " forward, ", bRight, " right ", maxDig, " layers down starting from ", startDig, " layers down." )
  415.  
  416. local minFuelLevel = 1000
  417.  
  418. local rLimit = bRight
  419. local fLimit = bForward
  420.  
  421. local r = 0
  422. local f = 0
  423.  
  424. while r < rLimit do
  425.   while f + 1 < fLimit do
  426.  
  427.     --print( "1st r = ", r, " f = ", f, "rLimit = ", rLimit, " fLimit = ", fLimit )
  428.  
  429.     if not dropOffItems() then
  430.       error( "Could not drop off items. Perhaps chest or other inventory is full." )
  431.     end
  432.    
  433.     if not refuel( minFuelLevel ) then
  434.       error( "Could not refuel to minimum level ", minFuelLevel, ". Please check fuel container." )
  435.     end
  436.    
  437.     -- Optional feature to start the main part of the dig below the current level
  438.     -- This serves two main benefits : keeping the current level (usually the ground level) intact
  439.     --   and getting to the premium ores faster, if that is desired
  440.     assert( moveDown( startDig ) == startDig )
  441.    
  442.     -- Traverse to the next dig coordinates
  443.     assert( moveRight( r ) == r )
  444.     assert( moveForward( f ) == f )
  445.  
  446.     -- The main part of the dig that goes all the way down, moves 1 forward, then comes straight back up
  447.     while enoughFuel() and enoughFreeSpace() do
  448.    
  449.       -- Yield to avoid a "Too long without yielding" error !
  450.       sleep(1)
  451.    
  452.       assert( downAndUp( maxDig )  )      
  453.       f = f + 1
  454.      
  455.       if f + 1 < fLimit then
  456.         assert( moveForward( 1 ) )
  457.         f = f + 1
  458.       else
  459.         break
  460.       end
  461.     end
  462.  
  463.     --print( "2nd r = ", r, " f = ", f, "rLimit = ", rLimit, " fLimit = ", fLimit )
  464.  
  465.     -- Traverse in the reverse direction from the dig coordinates
  466.     assert( moveBack( f ) == f )
  467.     assert( moveLeft( r ) == r )
  468.    
  469.     -- Come back up to the main level
  470.     assert( moveUp( startDig ) == startDig )
  471.    
  472.     -- Yield to avoid a "Too long without yielding" error !
  473.     sleep(1)
  474.   end
  475.  
  476.   --print( "3rd r = ", r, " f = ", f, "rLimit = ", rLimit, " fLimit = ", fLimit )
  477.  
  478.   r = r + 1
  479.   f = 0
  480. end
  481.  
  482. -- The last drop-off !
  483. dropOffItems()
  484.  
  485. print( "I have finished the assigned task, my master !" )
Add Comment
Please, Sign In to add comment