Advertisement
kssr3951

chunkDig4.2

Dec 6th, 2014
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 31.35 KB | None | 0 0
  1. local function showUsage()
  2.   print("chunkDig4")
  3.   print("slot1 : chest x 64")
  4.   print("slot2 : stone x 1")
  5.   print("slot3 : gravel x 1")
  6.   print("slot4 : dart x 1")
  7.   print("slot5 : cobblestone x 32")
  8. end
  9. local SLOT_CHEST           = 1
  10. local SLOT_STONE           = 2
  11. local SLOT_GRAVEL          = 3
  12. local SLOT_DART            = 4
  13. local SLOT_COBBLESTONE     = 5
  14. local SLOTS_FREE           = { 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }
  15. local SLOTS_KEEP_ALL       = { SLOT_CHEST }
  16. local SLOTS_KEEP_32        = { SLOT_COBBLESTONE }
  17. local SLOTS_KEEP_1         = { SLOT_STONE, SLOT_GRAVEL, SLOT_DART }
  18. local SLOTS_USELESS_SAMPLE = { SLOT_COBBLESTONE, SLOT_STONE, SLOT_GRAVEL, SLOT_DART }
  19. -- -------------------------------
  20. -- config
  21. -- -------------------------------
  22. local DEFAULT_WIDTH        = 16
  23. local DEFAULT_DEPTH        = 16 -- forward() direction
  24. local PREVENTION_FROM_FALL = false
  25. local EXCAVATE_ALL         = false
  26. local KEEP_USELESS_BLOCKS  = false
  27. local SHOW_USAGE           = true
  28. --
  29. local ASK_INITIAL_HEIGHT   = true
  30. local TURTLE_INITIAL_Y     = 71
  31. -- HEIGHT_MODE
  32. --   true  : use BEADROCK_HEIGHT
  33. --   false : use RELATIVE_HEIGHT
  34. local HEIGHT_MODE          = true
  35. local BEADROCK_HEIGHT      = 5
  36. local RELATIVE_HEIGHT      = 3
  37. -- repository map
  38. local USE_REPOSITORY_MAP     = true
  39. local PLACE_SUPPLEMENT_CHEST = true
  40. local REPOSITORY_MAP = {
  41.   [3] = " 4 4 4 4 4 4",
  42.   [2] = " 4 4 4 4 4 4",
  43.   [1] = "F C         "} -- 1-9:ore chest / 0:ore chest(no limit) / F:fuel chest / C:chest chest
  44. local REPOSITORY_OFFSET_LR = 0 -- (width direction)
  45. local REPOSITORY_OFFSET_BF = 0 -- (depth direction)
  46. -- refuel
  47. local FUEL_LEVEL_MINIMUM = 1000
  48. local FUEL_LEVEL_REFUEL  = 5000
  49.  
  50. -- for debug
  51. local DEBUG_LOG            = false
  52. local SIMULATION           = false
  53. -- -------------------------------
  54. -- utility
  55. -- -------------------------------
  56. -- local log
  57. local LOCAL_ENABLED        = false
  58. local LOCAL_LOG_FILE_NAME  = "debug.log"
  59. -- remote log
  60. local REMOTE_ENABLED       = false
  61. local REMOTE_ADDR          = 20
  62. local REMOTE_MODEM_DIR     = "right"
  63. local function debug(txt)
  64.   if DEBUG_LOG then
  65.     if LOCAL_ENABLED then
  66.       local hFile
  67.       if fs.exists(LOCAL_LOG_FILE_NAME) then
  68.         hFile = fs.open(LOCAL_LOG_FILE_NAME, "a");
  69.       else
  70.         hFile = fs.open(LOCAL_LOG_FILE_NAME, "w");
  71.       end
  72.       hFile.writeLine(txt);
  73.       hFile.close();
  74.     end
  75.     if REMOTE_ENABLED then
  76.       rednet.open(REMOTE_MODEM_DIR)
  77.       rednet.send(REMOTE_ADDR, txt)
  78.       rednet.close()
  79.     end
  80.   end
  81. end
  82. local function inRange(posX, posY, width, height)
  83.   return 0 <= posX and posX < width and 0 <= posY and posY < height
  84. end
  85. local function sign(val)
  86.   if val == 0 then
  87.     return 0
  88.   else
  89.     return math.abs(val) / val
  90.   end
  91. end
  92. function surelyUp()
  93.   while not turtle.up() do turtle.digUp() end
  94. end
  95. function surelyDown()
  96.   while not turtle.down() do end
  97. end
  98. -- http://hevohevo.hatenablog.com/entry/2014/07/14/213109
  99. function surelyDigUp()
  100.   while turtle.digUp() do
  101.     os.sleep(0.4)
  102.   end
  103. end
  104. -- http://hevohevo.hatenablog.com/entry/2014/07/14/213109
  105. function surelyDig()
  106.   while turtle.dig() do end
  107. end
  108. -- http://hevohevo.hatenablog.com/entry/2014/07/14/213109
  109. function surelyFwd()
  110.   for i=1,4 do
  111.     local status, err = turtle.forward()
  112.     if status then
  113.       return true  -- success!
  114.     elseif err=="Out of fuel" then
  115.       return status, err
  116.     end
  117.  
  118.     surelyDig() -- face to a normal block or a sand(gravel) hill
  119.  
  120.     if turtle.detect() and not turtle.dig() then
  121.       return false, "bedrock!"
  122.     end
  123.  
  124.     if turtle.forward() then return true end -- success!
  125.  
  126.     if turtle.attack() then
  127.       -- face to monster-mob
  128.       while turtle.attack() do end
  129.     else
  130.       -- face to sand-blocks which is dropping long time
  131.       os.sleep(5) -- probably, adjustment is required
  132.     end
  133.   end
  134.   return turtle.forward()
  135. end
  136. -- -------------------------------
  137. -- application
  138. -- -------------------------------
  139. -- ---------------
  140. -- direction control
  141. -- ---------------
  142. local COMPARE_BLOCKS = {SLOT_COBBLESTONE, SLOT_STONE, SLOT_DART, SLOT_GRAVEL }
  143. local DIR_FORWARD = 1
  144. local DIR_RIGHT   = 2
  145. local DIR_BACK    = 3
  146. local DIR_LEFT    = 4
  147. local DIR_NOT     = 5
  148. local DIR_TO_NAME = {
  149.   [DIR_FORWARD] = "F",
  150.   [DIR_RIGHT  ] = "R",
  151.   [DIR_BACK   ] = "B",
  152.   [DIR_LEFT   ] = "L",
  153.   [DIR_NOT    ] = "*"}
  154. local TURN_NOT     = 1
  155. local TURN_LEFT    = 2
  156. local TURN_RIGHT   = 3
  157. local TURN_OPPOSIT = 4
  158. local TURN_COSTS = { [TURN_NOT]   = 0, [TURN_LEFT]    = 1,
  159.                      [TURN_RIGHT] = 2, [TURN_OPPOSIT] = 3 }
  160. local TURN_RULES = { -- dir_forward, dir_right, dir_back, dir_left
  161.   [DIR_FORWARD] = { TURN_NOT    , TURN_RIGHT  , TURN_OPPOSIT, TURN_LEFT    },
  162.   [DIR_RIGHT  ] = { TURN_LEFT   , TURN_NOT    , TURN_RIGHT  , TURN_OPPOSIT },
  163.   [DIR_BACK   ] = { TURN_OPPOSIT, TURN_LEFT   , TURN_NOT    , TURN_RIGHT   },
  164.   [DIR_LEFT   ] = { TURN_RIGHT  , TURN_OPPOSIT, TURN_LEFT   , TURN_NOT     }}
  165. local TURN_RELATIVE = { -- turn_left, turn_right
  166.   [DIR_FORWARD] = { [TURN_LEFT] = DIR_LEFT   , [TURN_RIGHT] = DIR_RIGHT   },
  167.   [DIR_RIGHT  ] = { [TURN_LEFT] = DIR_FORWARD, [TURN_RIGHT] = DIR_BACK    },
  168.   [DIR_BACK   ] = { [TURN_LEFT] = DIR_RIGHT  , [TURN_RIGHT] = DIR_LEFT    },
  169.   [DIR_LEFT   ] = { [TURN_LEFT] = DIR_BACK   , [TURN_RIGHT] = DIR_FORWARD }}
  170. local OPPOSIT_DIR = {DIR_BACK, DIR_LEFT, DIR_FORWARD, DIR_LEFT}
  171. -- ---------------
  172. -- findTarget
  173. -- ---------------
  174. local TargetFinder = {
  175.   iterator = function(width, depth)
  176.     findTarget = function(scanX, scanZ, reverse, rangeWidth, rangeDepth)
  177.       local TILE_PATTERN = {"*","b","r","l","f"}
  178.       local SHAPE_DIRECTION = { DIR_NOT, DIR_FORWARD, DIR_LEFT,
  179.                                 DIR_RIGHT, DIR_BACK }
  180.       local idx = ( (scanZ%5) + (scanX%5)*3 )%5 + 1
  181.       local dirChar = TILE_PATTERN[idx]
  182.       if (not reverse and "b" == dirChar) or
  183.          (    reverse and "f" == dirChar) then
  184.         return false
  185.       end
  186.       local DIR_TO_CENTER = {{ dx =  0, dz =  0 }, -- *
  187.                              { dx =  0, dz = -1 }, -- b
  188.                              { dx =  1, dz =  0 }, -- r
  189.                              { dx = -1, dz =  0 }, -- l
  190.                              { dx =  0, dz =  1 }} -- f
  191.       local isCenter = false
  192.       local found = false
  193.       local newX, newZ
  194.       local shape = {}
  195.       local shapeDbg = ""
  196.       local centerX = scanX + DIR_TO_CENTER[idx].dx
  197.       local centerZ = scanZ + DIR_TO_CENTER[idx].dz
  198.       if inRange(centerX, centerZ, rangeWidth, rangeDepth) then
  199.         found    = true
  200.         isCenter = true
  201.         newX = centerX
  202.         newZ = centerZ
  203.       else
  204.         table.insert(shape, DIR_NOT)
  205.         shapeDbg = shapeDbg .. "*"
  206.       end
  207.       local testX, testZ
  208.       for i = 2, 5 do
  209.         testX = centerX - DIR_TO_CENTER[i].dx
  210.         testZ = centerZ - DIR_TO_CENTER[i].dz
  211.         if inRange(testX, testZ, rangeWidth, rangeDepth) then
  212.           if isCenter then
  213.             table.insert(shape, SHAPE_DIRECTION[i])
  214.             shapeDbg = shapeDbg .. DIR_TO_NAME[SHAPE_DIRECTION[i]]
  215.           end
  216.           if not found then
  217.             newX = testX
  218.             newZ = testZ
  219.           end
  220.           found = true
  221.         end
  222.       end
  223.       if not found then
  224.         return false
  225.       end
  226.       return true, newX, newZ, shape
  227.     end
  228.     local xAxisIterator = function(width)
  229.       local pos = 0
  230.       local loopEnd = math.floor((width + 1) / 3)
  231.       return function()
  232.         local current = pos
  233.         pos = pos + 1
  234.         if loopEnd < current then
  235.           return nil
  236.         else
  237.           return current * 3
  238.         end
  239.       end
  240.     end
  241.     local zAxisIterator = function(x, depth)
  242.       local pos, step
  243.       if 0 == x % 2 then
  244.         pos, step = -1, 1
  245.       else
  246.         pos, step = depth, -1
  247.       end
  248.       return function()
  249.         local current = pos
  250.         pos = pos + step
  251.         if current < -1 or depth < current then
  252.           return nil
  253.         else
  254.           return current
  255.         end
  256.       end
  257.     end
  258.     local xIter = xAxisIterator(width)
  259.     local zIter = nil
  260.     local x
  261.     local previousX
  262.     local previousZ
  263.     return function()
  264.       while true do
  265.         if nil == zIter then
  266.           x = xIter()
  267.           if nil == x then
  268.             return nil
  269.           end
  270.           zIter = zAxisIterator(x, depth)
  271.         end
  272.         local z = zIter()
  273.         if nil == z then
  274.           zIter = nil
  275.         else
  276.           --return x, z
  277.           local found, newX, newZ, shape
  278.             = findTarget(x, z, 0 == x%2, width, depth)
  279.           if found and (previousX ~= newX or previousZ ~= newZ) then
  280.             previousX = newX
  281.             previousZ = newZ
  282.             return newX, newZ, shape
  283.           end
  284.         end
  285.       end
  286.     end
  287.   end
  288. }
  289. -- ---------------
  290. -- mining control
  291. -- ---------------
  292. MOVE_H_TOP    = "MOVE_H_TOP"
  293. MOVE_V_DOWN   = "MOVE_V_DOWN"
  294. MOVE_H_BOTTOM = "MOVE_H_BOTTOM"
  295. MOVE_V_UP     = "MOVE_V_UP"
  296. local mineCtrl = {
  297.   status,
  298.   RANGE_WIDTH,
  299.   RANGE_DEPTH,
  300.   BOTTOM_HEIGHT,
  301.   newX,
  302.   newZ,
  303.   lastX = -1,
  304.   lastZ = -1,
  305.   --reopsitoryMemo = { },
  306.   repositoryInfo = {
  307.       currentLevel = 1,
  308.       currentSeq   = 0
  309.     },
  310.   pointBeforeX,
  311.   pointBeforeZ,
  312.   turtleIsTop = true,
  313.   turtleInitialY = 0,
  314.   interruptX,
  315.   interruptZ,
  316.   interruptY,
  317.   vacantChestList = { },
  318.   occupiedChestList = { },
  319.   underInterruption = false,
  320. }
  321. -- ---------------
  322. -- turtle
  323. -- ---------------
  324. local MyTurtle = {}
  325. MyTurtle.new = function(initialY)
  326.   local obj = {}
  327.   obj.turtleX = 0
  328.   obj.turtleZ = 0
  329.   obj.turtleY = initialY
  330.   obj.turtleDir = DIR_FORWARD
  331.   return setmetatable(obj, {__index = MyTurtle})
  332. end
  333. MyTurtle.turnTo = function(self, direction)
  334.   local turn = TURN_RULES[self.turtleDir][direction]
  335.   if TURN_LEFT == turn then
  336.     if not SIMULATION then
  337.       turtle.turnLeft()
  338.     end
  339.   elseif TURN_RIGHT == turn then
  340.     if not SIMULATION then
  341.       turtle.turnRight()
  342.     end
  343.   elseif TURN_OPPOSIT == turn then
  344.     if not SIMULATION then
  345.       turtle.turnLeft()
  346.       turtle.turnLeft()
  347.     end
  348.   end
  349.   self.turtleDir = direction
  350. end
  351. MyTurtle.runEventHandlers = function(self, evHandlers)
  352.   if nil == evHandlers then
  353.     return
  354.   end
  355.   for _, func in ipairs(evHandlers) do
  356.     func()
  357.   end
  358. end
  359. MyTurtle.adjustX = function(self, aimX, withDigUp, beforeEvHandlers, afterEvHandlers)
  360.   if self.turtleX < aimX and DIR_RIGHT ~= self.turtleDir then
  361.     self:turnTo(DIR_RIGHT)
  362.   elseif aimX < self.turtleX and DIR_LEFT ~= self.turtleDir then
  363.     self:turnTo(DIR_LEFT)
  364.   end
  365.   while self.turtleX ~= aimX do
  366.     if not SIMULATION then
  367.       self:runEventHandlers(beforeEvHandlers)
  368.       surelyFwd()
  369.       self:runEventHandlers(afterEvHandlers)
  370.       if withDigUp then
  371.         surelyDigUp()
  372.       end
  373.     end
  374.     self.turtleX = self.turtleX + sign(aimX - self.turtleX)
  375.   end
  376. end
  377. MyTurtle.adjustZ = function(self, aimZ, withDigUp, beforeEvHandlers, afterEvHandlers)
  378.   if self.turtleZ < aimZ and DIR_FORWARD ~= self.turtleDir then
  379.     self:turnTo(DIR_FORWARD)
  380.   elseif aimZ < self.turtleZ and DIR_BACK ~= self.turtleDir then
  381.     self:turnTo(DIR_BACK)
  382.   end
  383.   while self.turtleZ ~= aimZ do
  384.     if not SIMULATION then
  385.       self:runEventHandlers(beforeEvHandlers)
  386.       surelyFwd()
  387.       self:runEventHandlers(afterEvHandlers)
  388.       if withDigUp then
  389.         surelyDigUp()
  390.       end
  391.     end
  392.     self.turtleZ = self.turtleZ + sign(aimZ - self.turtleZ)
  393.   end
  394. end
  395. MyTurtle.moveTo = function(self, aimX, aimZ, withDigUp, beforeEvHandlers, afterEvHandlers)
  396.   self:adjustX(aimX, withDigUp, beforeEvHandlers, afterEvHandlers)
  397.   self:adjustZ(aimZ, withDigUp, beforeEvHandlers, afterEvHandlers)
  398. end
  399. MyTurtle.backTo = function(self, aimX, aimZ, withDigUp, beforeEvHandlers, afterEvHandlers)
  400.   self:adjustZ(aimZ, withDigUp, beforeEvHandlers, afterEvHandlers)
  401.   self:adjustX(aimX, withDigUp, beforeEvHandlers, afterEvHandlers)
  402. end
  403. MyTurtle.moveVertical = function(self, targetY, beforeEvHandlers, afterEvHandlers)
  404.   local vDir = sign(targetY - self.turtleY)
  405.   while targetY ~= self.turtleY do
  406.     if not SIMULATION then
  407.       if 1 == vDir then
  408.         self:runEventHandlers(beforeEvHandlers)
  409.         turtle.digUp()
  410.         surelyUp()
  411.         self.turtleY = self.turtleY + vDir
  412.         self:runEventHandlers(afterEvHandlers)
  413.       elseif -1 == vDir then
  414.         self:runEventHandlers(beforeEvHandlers)
  415.         turtle.digDown()
  416.         surelyDown()
  417.         self.turtleY = self.turtleY + vDir
  418.         self:runEventHandlers(afterEvHandlers)
  419.       end
  420.     end
  421.   end
  422. end
  423. -- ---------------
  424. -- additional action : vertical mining
  425. -- ---------------
  426. local function verticalMiningAction(_myT, _shape)
  427.   local turnToNearestEdge = function (myT, shape)
  428.     local turnMinCost = 99
  429.     local smallestTurnDir = DIR_NOT
  430.     local turnTmp, costTmp
  431.     for _, dir in ipairs(shape) do
  432.       turnTmp = TURN_RULES[myT.turtleDir][dir]
  433.       costTmp = TURN_COSTS[turnTmp]
  434.       if costTmp < turnMinCost then
  435.         turnMinCost = costTmp
  436.         smallestTurnDir = dir
  437.       end
  438.     end
  439.     myT:turnTo(smallestTurnDir)
  440.   end
  441.   local getTurnFuncName = function(myT, shape)
  442.     local dirWhenTurnLeft  = TURN_RELATIVE[myT.turtleDir][TURN_LEFT ]
  443.     local dirWhenTurnRight = TURN_RELATIVE[myT.turtleDir][TURN_RIGHT]
  444.     for _, dir in ipairs(shape) do
  445.       if dir == dirWhenTurnLeft then
  446.         return TURN_LEFT
  447.       elseif dir == dirWhenTurnRight then
  448.         return TURN_RIGHT
  449.       end
  450.     end
  451.   end
  452.   local digValuableBlockOnly = function()
  453.     local selSlot = 16
  454.     local checkedSlot = -1
  455.     for _, slot in ipairs(COMPARE_BLOCKS) do
  456.       if selSlot == slot then
  457.         if turtle.compare() then
  458.           return
  459.         end
  460.         checkedSlot = slot
  461.         break
  462.       end
  463.     end
  464.     for _, slot in ipairs(COMPARE_BLOCKS) do
  465.       if checkedSlot ~= slot then
  466.         turtle.select(slot)
  467.         if turtle.compare() then
  468.           return
  469.         end
  470.       end
  471.     end
  472.     turtle.dig()
  473.     return true
  474.   end
  475.   local myT = _myT
  476.   local shape = _shape
  477.   local firstFlg = true
  478.   local turnLR
  479.   return function()
  480.     if firstFlg then
  481.       firstFlg = not firstFlg
  482.       if 2 == #shape or 3 == #shape then
  483.         turnToNearestEdge(myT, shape)
  484.         turnLR = getTurnFuncName(myT, shape)
  485.       else
  486.         turnLR = TURN_RIGHT
  487.       end
  488.     end
  489.     if 1 < #shape then
  490.       for i = 1, #shape do
  491.         if not SIMULATION then
  492.           if EXCAVATE_ALL then
  493.             surelyDig()
  494.             dug = true
  495.           else
  496.             dug = digValuableBlockOnly()
  497.           end
  498.         end
  499.         if i < #shape then
  500.           myT:turnTo(TURN_RELATIVE[myT.turtleDir][turnLR])
  501.         end
  502.       end
  503.       if 2 == #shape or 3 == #shape then
  504.         if TURN_LEFT == turnLR then
  505.           turnLR = TURN_RIGHT
  506.         else
  507.           turnLR = TURN_LEFT
  508.         end
  509.       end
  510.     end
  511.   end
  512. end
  513. -- ---------------
  514. -- repository map
  515. -- ---------------
  516. local REPO_C_CHEST = "C"
  517. local REPO_F_FUEL  = "F"
  518. local REPO_O_ORE   = "O"
  519. local REPO_BLANK   = " "
  520. local function makeRepoMap()
  521.   local repoMap = { }
  522.   for i = 1, table.maxn(REPOSITORY_MAP) do
  523.     local line = REPOSITORY_MAP[i]
  524.     local lineAry = { }
  525.     for j = 1, string.len(line) do
  526.       local ch = string.sub(line, j, j)
  527.       table.insert(lineAry, ch)
  528.     end
  529.     table.insert(repoMap, lineAry)
  530.   end
  531.   return repoMap
  532. end
  533. local function nvl(val, subVal)
  534.   if nil == val then
  535.     return subVal
  536.   else
  537.     return val
  538.   end
  539. end
  540. local function findRepo(repoMap, chestType, no)
  541.   local function found(col, chestType)
  542.       for _, v in ipairs(chestType) do
  543.         if REPO_O_ORE == v then
  544.           if nil ~= string.find("0123456789", col) then
  545.             return true
  546.           end
  547.         elseif nil ~= string.find("0123456789", v)
  548.             and nil ~= string.find("0123456789", col) then
  549.           if "0" == col then
  550.             return true
  551.           elseif tonumber(v) <= tonumber(col) then
  552.             return true
  553.           end
  554.         else
  555.           if v == col then
  556.             return true
  557.           end
  558.         end
  559.       end
  560.       return false
  561.     end
  562.   local findNo = 0
  563.   for i = 1, table.maxn(repoMap) do
  564.     local row = repoMap[i]
  565.     for j = 1, table.maxn(row) do
  566.       local col = row[j]
  567.       if found(col, chestType) and no <= findNo then
  568.         debug("fr[" .. col .. "] x, z = " .. tostring(j) .. ", " .. tostring(i))
  569.         return j - 1 + REPOSITORY_OFFSET_LR,
  570.                i - 1 + REPOSITORY_OFFSET_BF,
  571.                findNo,
  572.                col
  573.       end
  574.       findNo = findNo + 1
  575.     end
  576.   end
  577.   return nil
  578. end
  579. -- ---------------
  580. -- additional action : inventory check
  581. -- ---------------
  582. local function checkInventoryAction(_myT, _mineCtrl)
  583.   local function dropUselessBlocks()
  584.     local cnt
  585.     for _, v in ipairs(SLOTS_KEEP_1) do
  586.       cnt = turtle.getItemCount(v)
  587.       if 1 < cnt then
  588.         turtle.select(v)
  589.         turtle.dropDown(cnt - 1)
  590.       end
  591.     end
  592.     for _, v in ipairs(SLOTS_KEEP_32) do
  593.       cnt = turtle.getItemCount(v)
  594.       if 32 < cnt then
  595.         turtle.select(v)
  596.         turtle.dropDown(cnt - 32)
  597.       end
  598.     end
  599.     local freeCnt = 0
  600.     for _, v in ipairs(SLOTS_FREE) do
  601.       cnt = turtle.getItemCount(v)
  602.       if 0 < cnt then
  603.         turtle.select(v)
  604.         for _, w in ipairs(SLOTS_USELESS_SAMPLE) do
  605.           if turtle.compareTo(w) then
  606.             turtle.dropDown()
  607.             freeCnt = freeCnt + 1
  608.             break
  609.           end
  610.         end
  611.       else
  612.         freeCnt = freeCnt + 1
  613.       end
  614.     end
  615.     turtle.select(1)
  616.     debug("==== dropUselessBlocks() makes " .. tostring(freeCnt) .." vacantSlot(s)")
  617.     return 0 < freeCnt
  618.   end
  619.   local function checkInventory()
  620.     if turtle.getFuelLevel() <= FUEL_LEVEL_MINIMUM then
  621.       return false
  622.     end
  623.     for _, i in ipairs(SLOTS_FREE) do
  624.       if 0 == turtle.getItemCount(i) then
  625.         return true
  626.       end
  627.     end
  628.     return false
  629.   end
  630.   local function findNearestAccessPos(mineCtrl, myT, repoMap, xx, zz, currentLevel)
  631.     --local lr = xx - REPOSITORY_OFFSET_LR
  632.     --local bf = zz - REPOSITORY_OFFSET_BF
  633.     local minDist = nil
  634.     local rsltX, rsltZ, rsltDir
  635.  
  636.     local acDirs = {
  637.       { dir = DIR_NOT    , LV1only = true , lr =  0, bf =  0 },
  638.       { dir = DIR_BACK   , LV1only = false, lr =  0, bf =  1 },
  639.       { dir = DIR_LEFT   , LV1only = false, lr =  1, bf =  0 },
  640.       { dir = DIR_FORWARD, LV1only = false, lr =  0, bf = -1 },
  641.       { dir = DIR_RIGHT  , LV1only = false, lr = -1, bf =  0 }}
  642.     for _, v in ipairs(acDirs) do
  643.       local testX = xx + v.lr
  644.       local testZ = zz + v.bf
  645.       local idxX  = testX - REPOSITORY_OFFSET_LR + 1
  646.       local idxZ  = testZ - REPOSITORY_OFFSET_BF + 1
  647.       --debug("testZ - REPOSITORY_OFFSET_BF + 1 = " .. tostring(testZ - REPOSITORY_OFFSET_BF + 1))
  648.       --debug("testX - REPOSITORY_OFFSET_LR + 1 = " .. tostring(testX - REPOSITORY_OFFSET_LR + 1))
  649.       if 0 <= testX and testX < mineCtrl.RANGE_WIDTH and
  650.          0 <= testZ and testZ < mineCtrl.RANGE_DEPTH and
  651.          0 < idxZ and idxZ <= table.maxn(repoMap)    and
  652.          0 < idxX and idxX <= table.maxn(repoMap[1]) and
  653.          REPO_BLANK == repoMap[idxZ][idxX] then
  654.         local dist = math.abs(myT.turtleX - testX) + math.abs(myT.turtleZ - testZ)
  655.         if nil == minDist or dist < minDist then
  656.           minDist = dist
  657.           rsltX   = testX
  658.           rsltZ   = testZ
  659.           rsltDir = v.dir
  660.         end
  661.       end
  662.     end
  663.     if nil == minDist then
  664.       return nil
  665.     else
  666.       return rsltX, rsltZ, rsltDir
  667.     end
  668.   end
  669.   local function doDump(dropFunc)
  670.     local result = true
  671.     for _, v in ipairs(SLOTS_FREE) do
  672.       cnt = turtle.getItemCount(v)
  673.       if 0 < cnt then
  674.         turtle.select(v)
  675.         if KEEP_USELESS_BLOCKS and 0 < turtle.getItemCount(v) then
  676.           if not dropFunc() then
  677.             result = false
  678.           end
  679.         else
  680.           for _, w in ipairs(SLOTS_USELESS_SAMPLE) do
  681.             if not turtle.compareTo(w) and 0 < turtle.getItemCount(v) then
  682.               if not dropFunc() then
  683.                 result = false
  684.               end
  685.             end
  686.             break
  687.           end
  688.         end
  689.       end
  690.     end
  691.     return result
  692.   end
  693.   local function doRefuel(myT, repoMap)
  694.     local xx, zz
  695.     local findSeq = 0
  696.     local fuelChestEmpty = false
  697.     while true do
  698.       xx, zz, findSeq = findRepo(repoMap, {REPO_F_FUEL}, findSeq)
  699.       if nil == xx then
  700.         fuelChestEmpty = true
  701.         xx, zz, findSeq = findRepo(repoMap, {REPO_F_FUEL}, 0)
  702.       end
  703.       findSeq = findSeq + 1
  704.       myT:moveTo(xx, zz, false)
  705.       surelyDigUp()
  706.       surelyUp()
  707.       turtle.select(SLOT_CHEST)
  708.       turtle.placeDown()
  709.       turtle.dropDown()
  710.       debug("refuel before = " .. tostring(turtle.getFuelLevel()))
  711.       while true do
  712.         if fuelChestEmpty then
  713.           print("fuel level is low. put fuel in the chest.")
  714.           while true do
  715.             if turtle.suckUp() then
  716.               break
  717.             end
  718.             print("sleep 5")
  719.             os.sleep(5)
  720.           end
  721.         else
  722.           turtle.suckUp()
  723.         end
  724.         if not fuelChestEmpty then
  725.           if 0 == turtle.getItemCount() then
  726.             break
  727.           end
  728.         end
  729.         local before = turtle.getFuelLevel()
  730.         turtle.refuel(1)
  731.         local after = turtle.getFuelLevel()
  732.         local unitVal = after - before
  733.         local reqCnt = (FUEL_LEVEL_REFUEL - after) / unitVal
  734.         debug("refuel bef, aft, unit, reqCnt = "
  735.           .. tostring(before) .. ", "
  736.           .. tostring(after) .. ", "
  737.           .. tostring(unitVal) .. ", "
  738.           .. tostring(reqCnt))
  739.         if turtle.getItemCount() <= reqCnt then
  740.           turtle.refuel()
  741.         else
  742.           if 0 < reqCnt then
  743.             turtle.refuel(math.floor(reqCnt))
  744.           end
  745.           turtle.dropUp()
  746.         end
  747.         if FUEL_LEVEL_REFUEL <= turtle.getFuelLevel() then
  748.           break
  749.         end
  750.       end
  751.       fuelChestEmpty = false
  752.       turtle.suckDown()
  753.       turtle.digDown()
  754.       surelyDown()
  755.       if FUEL_LEVEL_REFUEL <= turtle.getFuelLevel() then
  756.         break
  757.       end
  758.     end
  759.   end
  760.   local function backToTheRepository(myT, chestType, mineCtrl)
  761.     local repoMap = makeRepoMap()
  762.     local myT4 = MyTurtle.new(0)
  763.     myT4.turtleY = myT.turtleY
  764.     myT4.turtleX = myT.turtleX
  765.     myT4.turtleZ = myT.turtleZ
  766.     myT4.turtleDir = myT.turtleDir
  767.     if turtle.getFuelLevel() <= FUEL_LEVEL_MINIMUM then
  768.       doRefuel(myT4, repoMap)
  769.     end
  770.     local xx, zz
  771.     local cell
  772.     local findSeq   = mineCtrl.repositoryInfo.currentSeq
  773.     local currLevel = mineCtrl.repositoryInfo.currentLevel
  774.     local dumpDone = false
  775.     while true do
  776.       if REPO_O_ORE ~= chestType then
  777.         xx, zz, findSeq, cell = findRepo(repoMap, { chestType }, findSeq)
  778.         if nil == xx then
  779.           break
  780.         end
  781.       else
  782.         xx, zz, findSeq, cell = findRepo(repoMap, { currLevel }, findSeq)
  783.         if nil == xx then
  784.           currLevel = currLevel + 1
  785.           findSeq   = 0
  786.           xx, zz, findSeq, cell = findRepo(repoMap, { currLevel }, findSeq)
  787.           if nil == xx then
  788.             break
  789.           end
  790.         end
  791.       end
  792.       local xx2, zz2, accessDir = findNearestAccessPos(mineCtrl, myT4, repoMap, xx, zz, currLevel)
  793.       if nil ~= xx2 then
  794.         myT4:moveTo(xx2, zz2, false)
  795.         local upDown = currLevel
  796.         if DIR_NOT ~= accessDir then
  797.           myT4:turnTo(accessDir)
  798.           upDown = upDown + 1
  799.         end
  800.         for i = 1, upDown do
  801.           surelyDigUp()
  802.           surelyUp()
  803.         end
  804.  
  805.         local funcs
  806.         if DIR_NOT == accessDir then
  807.           funcs = { compare = turtle.compareUp, dig  = surelyDigUp,
  808.                     place   = turtle.placeUp  , drop = turtle.dropUp }
  809.         else
  810.           funcs = { compare = turtle.compare  , dig  = surelyDig,
  811.                     place   = turtle.place    , drop = turtle.drop }
  812.         end
  813.         turtle.select(1)
  814.         if not funcs.compare() then
  815.           funcs.dig()
  816.           funcs.place()
  817.         end
  818.  
  819.         dumpDone = doDump(funcs.drop)
  820.  
  821.         for i = 1, upDown do
  822.           turtle.digDown()
  823.           surelyDown()
  824.         end
  825.  
  826.         if dumpDone then
  827.           break
  828.         else
  829.           findSeq = findSeq + 1
  830.         end
  831.       end
  832.     end
  833.     mineCtrl.repositoryInfo.currentSeq   = findSeq
  834.     mineCtrl.repositoryInfo.currentLevel = currLevel
  835.     myT4:backTo(myT.turtleX, myT.turtleZ, false)
  836.     myT4:turnTo(myT.turtleDir)
  837.   end
  838.   local function dump()
  839.     surelyDigUp()
  840.     surelyUp()
  841.     turtle.select(SLOT_CHEST)
  842.     turtle.placeUp()
  843.  
  844.     doDump(turtle.dropUp)
  845.  
  846.     turtle.select(1)
  847.     turtle.digDown()
  848.     surelyDown()
  849.   end
  850.   local function backToTheGround(myT, mineCtrl)
  851.     debug("====== backToTheGround()")
  852.     debug("======   status    = " .. mineCtrl.status)
  853.     debug("======   pos x,z,y = " .. myT.turtleX .. ", " .. myT.turtleZ .. ", " .. myT.turtleY)
  854.     debug("======   last x,z  = " .. mineCtrl.lastX .. ", " .. mineCtrl.lastZ)
  855.     local t2 = MyTurtle.new()
  856.     t2.turtleX = myT.turtleX
  857.     t2.turtleZ = myT.turtleZ
  858.     t2.turtleY = myT.turtleY
  859.     t2.turtleDir = myT.turtleDir
  860.     if MOVE_H_TOP == mineCtrl.status then
  861.       debug("<<<>>> backToTheGround [MOVE_H_TOP] begin")
  862.       t2:backTo(mineCtrl.lastX, mineCtrl.lastZ, nil, nil)
  863.       debug("<<<>>> backToTheGround [MOVE_H_TOP] end")
  864.     elseif MOVE_V_DOWN == mineCtrl.status then
  865.       debug("<<<>>> backToTheGround [MOVE_V_DOWN] begin")
  866.       t2:moveVertical(mineCtrl.turtleInitialY, nil, nil)
  867.       debug("<<<>>> backToTheGround [MOVE_V_DOWN] end")
  868.  
  869.     elseif MOVE_H_BOTTOM == mineCtrl.status then
  870.       debug("<<<>>> backToTheGround [MOVE_H_BOTTOM] begin")
  871.       t2:backTo(mineCtrl.lastX, mineCtrl.lastZ, nil, nil)
  872.       t2:moveVertical(mineCtrl.turtleInitialY, nil, nil)
  873.       debug("<<<>>> backToTheGround [MOVE_H_BOTTOM] end")
  874.  
  875.     elseif MOVE_V_UP == mineCtrl.status then
  876.       debug("<<<>>> backToTheGround [MOVE_V_UP] begin")
  877.       t2:moveVertical(mineCtrl.BOTTOM_HEIGHT, nil, nil)
  878.       t2:backTo(mineCtrl.lastX, mineCtrl.lastZ, nil, nil)
  879.       t2:moveVertical(mineCtrl.turtleInitialY, nil, nil)
  880.       debug("<<<>>> backToTheGround [MOVE_V_UP] end")
  881.     end
  882.     if USE_REPOSITORY_MAP then
  883.       backToTheRepository(t2, REPO_O_ORE, mineCtrl)
  884.     else
  885.       dump()
  886.     end
  887.     if MOVE_H_TOP == mineCtrl.status then
  888.       t2:moveTo(myT.turtleX, myT.turtleZ)
  889.  
  890.     elseif MOVE_V_DOWN == mineCtrl.status then
  891.       t2:moveVertical(myT.turtleY, nil, nil)
  892.  
  893.     elseif MOVE_H_BOTTOM == mineCtrl.status then
  894.       t2:moveVertical(mineCtrl.BOTTOM_HEIGHT, nil, nil)
  895.       t2:moveTo(myT.turtleX, myT.turtleZ)
  896.  
  897.     elseif MOVE_V_UP == mineCtrl.status then
  898.       t2:moveVertical(mineCtrl.BOTTOM_HEIGHT, nil, nil)
  899.       t2:moveTo(myT.turtleX, myT.turtleZ)
  900.       t2:moveVertical(myT.turtleY, nil, nil)
  901.     end
  902.     t2:turnTo(myT.turtleDir)
  903.  
  904.     debug("<<<>>>  compreted?")
  905.     debug("  <<<>>>  myT x,z,y = " .. myT.turtleX .. ", " .. myT.turtleZ .. ", " .. myT.turtleY)
  906.     debug("  <<<>>>  t2  x,z,y = " .. t2.turtleX .. ", " .. t2.turtleZ .. ", " .. t2.turtleY)
  907.   end
  908.   return function(force)
  909.     if nil ~= force and force == true then
  910.       backToTheRepository(_myT, REPO_O_ORE, _mineCtrl)
  911.     else
  912.       if not checkInventory() then
  913.         debug("====================================")
  914.         debug("== checkInventory() returns false")
  915.         debug("==   at x : " .. tostring(_myT.turtleX) ..
  916.                    " / z : " .. tostring(_myT.turtleZ) ..
  917.                    " / y : " .. tostring(_myT.turtleY))
  918.         debug("====================================")
  919.         local result = false
  920.         if not KEEP_USELESS_BLOCKS then
  921.           result = dropUselessBlocks()
  922.         end
  923.         if not result then
  924.           backToTheGround(_myT, _mineCtrl)
  925.         end
  926.       end
  927.     end
  928.   end
  929. end
  930. -- ---------------
  931. -- initialize
  932. -- ---------------
  933. local function initialize()
  934.   if SHOW_USAGE then
  935.     showUsage()
  936.     print("Hit any key when ready.")
  937.     read()
  938.   end
  939.   if ASK_INITIAL_HEIGHT then
  940.     print("Input current y")
  941.     term.write(">")
  942.     local ch = read()
  943.     if nil == tonumber(ch) then
  944.       error("Not a Number!")
  945.     end
  946.     mineCtrl.turtleInitialY = tonumber(ch)
  947.   else
  948.     mineCtrl.turtleInitialY = TURTLE_INITIAL_Y
  949.   end
  950.   mineCtrl.RANGE_WIDTH = DEFAULT_WIDTH
  951.   mineCtrl.RANGE_DEPTH = DEFAULT_DEPTH
  952.  
  953.   if HEIGHT_MODE then
  954.     -- true  : use BEADROCK_HEIGHT
  955.     mineCtrl.BOTTOM_HEIGHT = BEADROCK_HEIGHT
  956.   else
  957.     -- false : use RELATIVE_HEIGHT
  958.     mineCtrl.BOTTOM_HEIGHT = mineCtrl.turtleInitialY - RELATIVE_HEIGHT
  959.   end
  960. end
  961. local function placeSupplementChest()
  962.   local reMap = makeRepoMap()
  963.   local myT3 = MyTurtle.new(64)
  964.   local xx, zz
  965.   local findSeq = 0
  966.   while true do
  967.     xx, zz, findSeq = findRepo(reMap, {REPO_C_CHEST, REPO_F_FUEL}, findSeq)
  968.     if nil == xx then
  969.       break
  970.     end
  971.     findSeq = findSeq + 1
  972.     myT3:moveTo(xx, zz, false)
  973.     turtle.select(1)
  974.     surelyDigUp()
  975.     surelyUp()
  976.     turtle.select(1)
  977.     if not turtle.compareUp() then
  978.       surelyDigUp()
  979.       turtle.placeUp()
  980.     end
  981.     turtle.digDown()
  982.     surelyDown()
  983.     xx = xx + 1
  984.   end
  985.   myT3:backTo(0, 0, false)
  986.   myT3:turnTo(DIR_FORWARD)
  987. end
  988. -- -------------------------------
  989. -- main
  990. -- -------------------------------
  991. debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
  992. debug("@@ chunkDig4.2.lua")
  993. debug("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
  994. initialize()
  995. if USE_REPOSITORY_MAP and PLACE_SUPPLEMENT_CHEST then
  996.   placeSupplementChest()
  997. end
  998. local myT = MyTurtle.new(mineCtrl.turtleInitialY)
  999. local beforeEvHandlers = { }
  1000. local afterEvHandlers = { }
  1001. local checkInventoryA = checkInventoryAction(myT, mineCtrl)
  1002. local newX, newZ
  1003. mineCtrl.lastX = -1
  1004. mineCtrl.lastZ = -1
  1005.  
  1006. mineCtrl.status = MOVE_H_TOP
  1007. for newX, newZ, shape in TargetFinder.iterator(mineCtrl.RANGE_WIDTH, mineCtrl.RANGE_DEPTH) do
  1008.   mineCtrl.newX = newX
  1009.   mineCtrl.newZ = newZ
  1010.   if -1 == mineCtrl.lastX then
  1011.     mineCtrl.lastX = mineCtrl.newX
  1012.     mineCtrl.lastZ = mineCtrl.newZ
  1013.   end
  1014.   debug("=[for loop]====================")
  1015.   debug("==  newX,  newZ = " .. tostring(mineCtrl.newX)  .. ", " .. tostring(mineCtrl.newZ ))
  1016.   debug("== lastX, lastZ = " .. tostring(mineCtrl.lastX) .. ", " .. tostring(mineCtrl.lastZ))
  1017.   debug("===============================")
  1018.   myT:moveTo(mineCtrl.newX, mineCtrl.newZ, {}, { checkInventoryA })
  1019.   if MOVE_H_TOP == mineCtrl.status then
  1020.  
  1021.     mineCtrl.status = MOVE_V_DOWN
  1022.     beforeEvHandlers = { }
  1023.     afterEvHandlers  = { verticalMiningAction(myT, shape),
  1024.                          checkInventoryA }
  1025.     myT:moveVertical(mineCtrl.BOTTOM_HEIGHT,
  1026.       beforeEvHandlers, afterEvHandlers)
  1027.  
  1028.     mineCtrl.status = MOVE_H_BOTTOM
  1029.   elseif MOVE_H_BOTTOM == mineCtrl.status then
  1030.  
  1031.     mineCtrl.status = MOVE_V_UP
  1032.     beforeEvHandlers = { verticalMiningAction(myT, shape),
  1033.                          checkInventoryA }
  1034.     afterEvHandlers  = { }
  1035.     myT:moveVertical(mineCtrl.turtleInitialY,
  1036.       beforeEvHandlers, afterEvHandlers)
  1037.  
  1038.     mineCtrl.status = MOVE_H_TOP
  1039.   else
  1040.     error("unexpected condition.")
  1041.   end
  1042.   mineCtrl.lastX = mineCtrl.newX
  1043.   mineCtrl.lastZ = mineCtrl.newZ
  1044. end
  1045. myT:backTo(0, 0, {}, { checkInventoryA })
  1046. myT:turnTo(DIR_FORWARD)
  1047. myT:moveVertical(mineCtrl.turtleInitialY, {checkInventoryA}, {})
  1048. checkInventoryA(true)
  1049. print("chunkDig4.2.lua was compreted!!")
  1050. debug("chunkDig4.2.lua was compreted!!")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement