ItsNoah

exf

Apr 19th, 2021 (edited)
151
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 10.79 KB | None | 0 0
  1. local size = 16
  2.    
  3. local depth = 0
  4. local unloaded = 0
  5. local collected = 0
  6.  
  7. local xPos,zPos = 0,0
  8. local xDir,zDir = 0,1
  9.  
  10. local Dir = {
  11.   Front = 0,
  12.   Back = 1,
  13.   Left = 2,
  14.   Right = 3,
  15.   Up = 4,
  16.   Down = 5
  17. }
  18.  
  19. local goTo
  20. local refuel
  21.  
  22. local function printr( message )
  23.     print(message)
  24.     rednet.broadcast(message)
  25. end
  26.  
  27. local function myVec(depth, dir)
  28.   return {depth=depth, dir=dir}
  29. end
  30.  
  31. local function alignDir(dir, depth, track)
  32.   if (dir == Dir.Left) then
  33.     turtle.turnLeft()
  34.     table.insert(track, myVec(depth, Dir.Left))
  35.   elseif (dir == Dir.Right) then
  36.     turtle.turnRight()
  37.     table.insert(track, myVec(depth, Dir.Right))
  38.   elseif (dir == Dir.Back) then
  39.     turtle.turnRight()
  40.     turtle.turnRight()
  41.     table.insert(track, myVec(depth, Dir.Right))
  42.     table.insert(track, myVec(depth, Dir.Right))
  43.   end
  44. end
  45.  
  46. local function undoAlignDir(depth, track)
  47.   while (#track > 0 and track[#track].depth == depth) do
  48.     local vec = table.remove(track)
  49.     if (vec.dir == Dir.Left) then
  50.       turtle.turnRight()
  51.     elseif (vec.dir == Dir.Right) then
  52.       turtle.turnLeft()
  53.     end
  54.   end
  55. end
  56.  
  57. local function isMine(hasBlock, blockInfo)
  58.     local mine = hasBlock and string.find(blockInfo.name, "ore")
  59.     if mine then
  60.         printr("Found "..blockInfo.name)
  61.     end
  62.     return mine
  63. end
  64.  
  65. local function inspectDirIsMine(dir)
  66.   local hasBlock, blockInfo
  67.   if (dir == Dir.Up) then
  68.     hasBlock, blockInfo = turtle.inspectUp()
  69.   elseif (dir == Dir.Down) then
  70.     hasBlock, blockInfo = turtle.inspectDown()
  71.   else
  72.     hasBlock, blockInfo = turtle.inspect()
  73.   end
  74.  
  75.   return isMine(hasBlock, blockInfo)
  76. end
  77.  
  78. local function excavateDir(dir, depth, track)
  79.   if (dir == Dir.Up) then
  80.     turtle.digUp()
  81.     turtle.up()
  82.     table.insert(track, myVec(depth, Dir.Up))
  83.   elseif (dir == Dir.Down) then
  84.     turtle.digDown()
  85.     turtle.down()
  86.     table.insert(track, myVec(depth, Dir.Down))
  87.   else
  88.     local counter = 0
  89.     repeat
  90.       turtle.dig()
  91.       counter = counter + 1
  92.     until turtle.forward()
  93.     table.insert(track, myVec(depth, Dir.Front))
  94.     -- if counter > 1 then
  95.     --   printr("WARNING: encountered gravity block during DFS")
  96.     -- end
  97.   end
  98. end
  99.  
  100. local function selectFillBlock()
  101.   for i = 1, 16 do
  102.     local info = turtle.getItemDetail(i)
  103.     if info and info.name == FILL_BLOCK then
  104.       turtle.select(i)
  105.       return
  106.     end
  107.   end
  108.   -- printr("[W] no fill blocks")
  109. end
  110.  
  111. local function backtrack(currentDepth, targetDepth, moveTrack, turnTrack)
  112.   while (currentDepth ~= targetDepth) do
  113.     while (#moveTrack > 0 and moveTrack[#moveTrack].depth == currentDepth - 1) do
  114.       local vec = table.remove(moveTrack)
  115.       if (vec.dir == Dir.Front) then
  116.         turtle.back()
  117.         selectFillBlock()
  118.         turtle.place()
  119.       elseif (vec.dir == Dir.Up) then
  120.         turtle.down()
  121.         selectFillBlock()
  122.         turtle.placeUp()
  123.       elseif (vec.dir == Dir.Down) then
  124.         turtle.up()
  125.         selectFillBlock()
  126.         turtle.placeDown()
  127.       end
  128.     end
  129.     undoAlignDir(currentDepth - 1, turnTrack)
  130.     currentDepth = currentDepth - 1
  131.   end
  132. end
  133.  
  134. local function dfs(initDir)
  135.   local stack = {}
  136.   local turnTrack = {}
  137.   local moveTrack = {}
  138.   local depth = 0
  139.   table.insert(stack, myVec(depth, initDir))
  140.  
  141.   while (#stack > 0) do
  142.     local vec = table.remove(stack)
  143.     backtrack(depth, vec.depth, moveTrack, turnTrack)
  144.     depth = vec.depth
  145.  
  146.     alignDir(vec.dir, depth, turnTrack)
  147.  
  148.     if (inspectDirIsMine(vec.dir)) then
  149.       excavateDir(vec.dir, depth, moveTrack)
  150.       depth = depth + 1
  151.  
  152.       if isMine(turtle.inspect()) then
  153.         table.insert(stack, myVec(depth, Dir.Front))
  154.       end
  155.  
  156.       if isMine(turtle.inspectUp()) then
  157.         table.insert(stack, myVec(depth, Dir.Up))
  158.       end
  159.       if isMine(turtle.inspectDown()) then
  160.         table.insert(stack, myVec(depth, Dir.Down))
  161.       end
  162.       turtle.turnRight()
  163.       if isMine(turtle.inspect()) then
  164.         table.insert(stack, myVec(depth, Dir.Right))
  165.       end
  166.       turtle.turnRight()
  167.       if isMine(turtle.inspect()) then
  168.         table.insert(stack, myVec(depth, Dir.Back))
  169.       end
  170.       turtle.turnRight()
  171.       if isMine(turtle.inspect()) then
  172.         table.insert(stack, myVec(depth, Dir.Left))
  173.       end
  174.       turtle.turnRight()
  175.     else
  176.       undoAlignDir(depth, turnTrack)
  177.     end
  178.   end
  179.  
  180.   backtrack(depth, 0, moveTrack, turnTrack)
  181. end
  182.  
  183. local function triggerDfs(dir)
  184.     local x,y,z,xd,zd = xPos,depth,zPos,xDir,zDir
  185.     if inspectDirIsMine(dir) then
  186.         dfs(dir)
  187.     end
  188.     goTo( x,y,z,xd,zd )
  189. end
  190.  
  191. local function organize()
  192.     for i = 1,16 do
  193.       if turtle.getItemCount(i) > 0 and turtle.getItemCount(i) < 64 then
  194.         turtle.select(i)
  195.         for j = i+1,16 do
  196.           if turtle.compareTo(j) then
  197.             turtle.select(j)
  198.             turtle.transferTo(i)
  199.             turtle.select(i)
  200.           end
  201.         end
  202.       end
  203.     end
  204.      
  205.     for i = 1,16 do
  206.       if turtle.getItemCount(i) > 0 then
  207.         for j = 1,i do
  208.           if turtle.getItemCount(j) == 0 then
  209.             turtle.select(i)
  210.             turtle.transferTo(j)
  211.             break
  212.           end
  213.         end
  214.       end
  215.     end
  216. end
  217.  
  218. local function unload( _bKeepOneFuelStack )
  219.     for n=1,16 do
  220.         local nCount = turtle.getItemCount(n)
  221.         if nCount > 0 then
  222.             turtle.select(n)           
  223.             local bDrop = true
  224.             if _bKeepOneFuelStack and turtle.refuel(0) then
  225.                 bDrop = false
  226.                 _bKeepOneFuelStack = false
  227.             end        
  228.             if bDrop then
  229.                 turtle.drop()
  230.                 unloaded = unloaded + nCount
  231.             end
  232.         end
  233.     end
  234.     collected = 0
  235.     turtle.select(1)
  236. end
  237.  
  238. local function returnSupplies()
  239.     local x,y,z,xd,zd = xPos,depth,zPos,xDir,zDir
  240.     goTo( 0,0,0,0,-1 )
  241.    
  242.     local fuelNeeded = 2*(x+y+z) + 1
  243.     if not refuel( fuelNeeded ) then
  244.         unload( false )
  245.         printr( "Waiting for fuel" )
  246.         while not refuel( fuelNeeded ) do
  247.             os.pullEvent( "turtle_inventory" )
  248.         end
  249.     else
  250.         unload( false )
  251.     end
  252.    
  253.     goTo( x,y,z,xd,zd )
  254. end
  255.  
  256. local function collect()   
  257.     local bFull = true
  258.     local nTotalItems = 0
  259.     for n=1,16 do
  260.         local nCount = turtle.getItemCount(n)
  261.         if nCount == 0 then
  262.             bFull = false
  263.         end
  264.         nTotalItems = nTotalItems + nCount
  265.     end
  266.    
  267.     if nTotalItems > collected then
  268.         collected = nTotalItems
  269.         if math.fmod(collected + unloaded, 50) == 0 then
  270.             printr( "Mined "..(collected + unloaded).." items." )
  271.         end
  272.     end
  273.    
  274.     if bFull then
  275.         printr( "No empty slots left." )
  276.         return false
  277.     end
  278.     return true
  279. end
  280.  
  281. function refuel( ammount )
  282.     local fuelLevel = turtle.getFuelLevel()
  283.     if fuelLevel == "unlimited" then
  284.         return true
  285.     end
  286.    
  287.     local needed = ammount or (xPos + zPos + depth + 2)
  288.     if turtle.getFuelLevel() < needed then
  289.         local fueled = false
  290.         for n=1,16 do
  291.             if turtle.getItemCount(n) > 0 then
  292.                 turtle.select(n)
  293.                 if turtle.refuel(1) then
  294.                     while turtle.getItemCount(n) > 0 and turtle.getFuelLevel() < needed do
  295.                         turtle.refuel(1)
  296.                     end
  297.                     if turtle.getFuelLevel() >= needed then
  298.                         turtle.select(1)
  299.                         return true
  300.                     end
  301.                 end
  302.             end
  303.         end
  304.         turtle.select(1)
  305.         return false
  306.     end
  307.    
  308.     return true
  309. end
  310.  
  311. local function checkInv()
  312.     for n=1,16 do
  313.         if turtle.getItemCount(n) > 0 then
  314.             if turtle.getItemDetail(n).name == "minecraft:cobblestone" then
  315.                 turtle.select(n)
  316.                 turtle.dropUp(64)
  317.             end
  318.         end
  319.     end
  320.     organize()
  321. end
  322.  
  323. local function tryForwards()
  324.     if not refuel() then
  325.         printr( "Not enough Fuel" )
  326.         returnSupplies()
  327.     end
  328.    
  329.     while not turtle.forward() do
  330.         if turtle.detect() then
  331.             if turtle.dig() then
  332.                 if not collect() then
  333.                     checkInv()
  334.                     if not collect() then
  335.                         returnSupplies()
  336.                     end
  337.                 end
  338.             else
  339.                 return false
  340.             end
  341.         end
  342.     end
  343.  
  344.     triggerDfs(Dir.Front)
  345.     triggerDfs(Dir.Up)
  346.     triggerDfs(Dir.Down)
  347.    
  348.     xPos = xPos + xDir
  349.     zPos = zPos + zDir
  350.     return true
  351. end
  352.  
  353. local function tryDown()
  354.     if not refuel() then
  355.         printr( "Not enough Fuel" )
  356.         returnSupplies()
  357.     end
  358.    
  359.     while not turtle.down() do
  360.         if turtle.detectDown() then
  361.             if turtle.digDown() then
  362.                 if not collect() then
  363.                     checkInv()
  364.                     if not collect() then
  365.                         returnSupplies()
  366.                     end
  367.                 end
  368.             else
  369.                 return false
  370.             end
  371.         end
  372.     end
  373.  
  374.     depth = depth + 1
  375.     if math.fmod( depth, 10 ) == 0 then
  376.         printr( "Descended "..depth.." metres." )
  377.     end
  378.  
  379.     return true
  380. end
  381.  
  382. local function turnLeft()
  383.     turtle.turnLeft()
  384.     xDir, zDir = -zDir, xDir
  385. end
  386.  
  387. local function turnRight()
  388.     turtle.turnRight()
  389.     xDir, zDir = zDir, -xDir
  390. end
  391.  
  392. function goTo( x, y, z, xd, zd )
  393.     while depth > y do
  394.         if turtle.up() then
  395.             depth = depth - 1
  396.         elseif turtle.digUp() then
  397.             collect()
  398.         else
  399.             sleep( 0.5 )
  400.         end
  401.     end
  402.  
  403.     if xPos > x then
  404.         while xDir ~= -1 do
  405.             turnLeft()
  406.         end
  407.         while xPos > x do
  408.             if turtle.forward() then
  409.                 xPos = xPos - 1
  410.             elseif turtle.dig() then
  411.                 collect()
  412.             else
  413.                 sleep( 0.5 )
  414.             end
  415.         end
  416.     elseif xPos < x then
  417.         while xDir ~= 1 do
  418.             turnLeft()
  419.         end
  420.         while xPos < x do
  421.             if turtle.forward() then
  422.                 xPos = xPos + 1
  423.             elseif turtle.dig() then
  424.                 collect()
  425.             else
  426.                 sleep( 0.5 )
  427.             end
  428.         end
  429.     end
  430.    
  431.     if zPos > z then
  432.         while zDir ~= -1 do
  433.             turnLeft()
  434.         end
  435.         while zPos > z do
  436.             if turtle.forward() then
  437.                 zPos = zPos - 1
  438.             elseif turtle.dig() then
  439.                 collect()
  440.             else
  441.                 sleep( 0.5 )
  442.             end
  443.         end
  444.     elseif zPos < z then
  445.         while zDir ~= 1 do
  446.             turnLeft()
  447.         end
  448.         while zPos < z do
  449.             if turtle.forward() then
  450.                 zPos = zPos + 1
  451.             elseif turtle.dig()then
  452.                 collect()
  453.             else
  454.                 sleep( 0.5 )
  455.             end
  456.         end
  457.     end
  458.    
  459.     while depth < y do
  460.         if turtle.down() then
  461.             depth = depth + 1
  462.         elseif turtle.digDown()then
  463.             collect()
  464.         else
  465.             sleep( 0.5 )
  466.         end
  467.     end
  468.    
  469.     while zDir ~= zd or xDir ~= xd do
  470.         turnLeft()
  471.     end
  472. end
  473.  
  474. if not refuel() then
  475.     printr( "Out of Fuel" )
  476.     return
  477. end
  478.  
  479. rednet.open("left")
  480.  
  481. goTo( 0,0,0,0,-1 )
  482. unload( false )
  483. goTo( 0,0,0,0,1 )
  484.  
  485. printr( "Excavating..." )
  486.  
  487. local alternate = 0
  488. local done = false
  489. while not done do
  490.     for n = 1, size do
  491.         for m = 1, size - 1 do
  492.             if not tryForwards() then
  493.                 done = true
  494.                 break
  495.             end
  496.         end
  497.         if done then
  498.             break
  499.         end
  500.         if n < size then
  501.             if math.fmod(n + alternate, 2) == 0 then
  502.                 turnLeft()
  503.                 if not tryForwards() then
  504.                     done = true
  505.                     break
  506.                 end
  507.                 turnLeft()
  508.             else
  509.                 turnRight()
  510.                 if not tryForwards() then
  511.                     done = true
  512.                     break
  513.                 end
  514.                 turnRight()
  515.             end
  516.         end
  517.     end
  518.     if done then
  519.         break
  520.     end
  521.    
  522.     if size > 1 then
  523.         if math.fmod(size, 2) == 0 then
  524.             turnRight()
  525.         else
  526.             if alternate == 0 then
  527.                 turnLeft()
  528.             else
  529.                 turnRight()
  530.             end
  531.             alternate = 1 - alternate
  532.         end
  533.     end
  534.    
  535.     if not tryDown() then
  536.         done = true
  537.         break
  538.     end
  539. end
  540.  
  541. printr( "Returning to surface..." )
  542.  
  543. -- Return to where we started
  544. goTo( 0,0,0,0,-1 )
  545. unload( false )
  546. goTo( 0,0,0,0,1 )
  547.  
  548. printr( "Mined "..(collected + unloaded).." items total." )
Add Comment
Please, Sign In to add comment