Advertisement
yumetodo

BranchMiningVer5.lua

Jun 1st, 2021
822
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 13.61 KB | None | 0 0
  1. -- 高さ2
  2. -- a0 = 9
  3. -- an+1 = an + 8
  4. -- 最初の周回は1週目
  5.  
  6. local TORCH_INTERVAL = 12
  7.  
  8. ---@param str string
  9. local function debug_print(str)
  10.     http.post("http://127.0.0.1:25763/", str)
  11. end
  12.  
  13. ---@param name string
  14. ---@param arr any[]
  15. local function PrintArray(name, arr)
  16.     local re = "["
  17.     for i, v in ipairs(arr) do
  18.         if i ~= 1 then re = re.."," end
  19.         re = re..tostring(v)
  20.     end
  21.     debug_print(name..": "..re.."]")
  22. end
  23.  
  24. ---@param ForwardCount integer
  25. local function MoveForwardImpl(ForwardCount)
  26.     for i = 1, ForwardCount do
  27.         if not turtle.forward() then return i - 1 end
  28.     end
  29.     return ForwardCount
  30. end
  31.  
  32. local function TurnBack()
  33.     turtle.turnLeft()
  34.     turtle.turnLeft()
  35. end
  36.  
  37. local function InventoryIsFull()
  38.     for i = 1, 16 do
  39.         if turtle.getItemCount(i) == 0 then return false end
  40.     end
  41.     return true
  42. end
  43.  
  44. ---@class WindmillManager
  45. ---@field LoopCount number
  46. ---@field DistanceFromLineStart number
  47. ---@field ReachedCrossDigPoint fun(self:WindmillManager)
  48. ---@field private __MoveOnEdge fun(self:WindmillManager, FirstTurnFunc:fun(), SecondTurnFunc:fun())
  49. ---@field private __MoveOnCrossLine fun(TurnFunc:fun(), FirstMoveCount:integer, SecondMoveCount:integer)
  50. ---@field private __MoveToChest fun(self:WindmillManager)
  51. ---@field private __MoveFromChest fun(self:WindmillManager)
  52. ---@field SaveItems fun(self:WindmillManager, DropList:"fun(Slot: integer):boolean")
  53. ---@field MoveForward fun(self:WindmillManager)
  54. ---@field ShouldPutTorch fun(self:WindmillManager):boolean
  55. ---@field GetLineDigCount fun(self:WindmillManager):integer
  56. local WindmillManager = {}
  57. WindmillManager.New = function ()
  58.     return{
  59.         LoopCount = 2,
  60.         CurrentProcessLine = 1,
  61.         DistanceFromLineStart = 0,
  62.         ReachedCrossDigPoint = function(self)
  63.             return 4 * self.LoopCount == self.DistanceFromLineStart
  64.         end,
  65.         __MoveOnEdge = function(self, FirstTurnFunc, SecondTurnFunc)
  66.             for i = 1, self.LoopCount do
  67.                 MoveForwardImpl(4)
  68.                 FirstTurnFunc()
  69.                 MoveForwardImpl(4)
  70.                 if i == self.LoopCount then break end
  71.                 SecondTurnFunc()
  72.             end
  73.         end,
  74.         __MoveOnCrossLine = function(TurnFunc, FirstMoveCount, SecondMoveCount)
  75.             MoveForwardImpl(FirstMoveCount)
  76.             TurnFunc()
  77.             MoveForwardImpl(SecondMoveCount)
  78.         end,
  79.         __MoveToChest = function(self)
  80.             self.TurnBack()
  81.             local CrossDigPoint = self.LoopCount * 4
  82.             if  CrossDigPoint < self.DistanceFromLineStart then
  83.                 self.__MoveOnCrossLine(turtle.turnLeft, self.DistanceFromLineStart - CrossDigPoint, CrossDigPoint)
  84.             else
  85.                 MoveForwardImpl(self.DistanceFromLineStart)
  86.                 turtle.turnLeft()
  87.                 self:__MoveOnEdge(turtle.turnLeft, turtle.turnRight)
  88.             end
  89.         end,
  90.         __MoveFromChest = function(self)
  91.             self.TurnBack()
  92.             local CrossDigPoint = self.LoopCount * 4
  93.             if  CrossDigPoint < self.DistanceFromLineStart then
  94.                 self.__MoveOnCrossLine(turtle.turnLeft, CrossDigPoint, self.DistanceFromLineStart - CrossDigPoint)
  95.             else
  96.                 self:__MoveOnEdge(turtle.turnRight, turtle.turnLeft)
  97.                 turtle.turnRight()
  98.                 MoveForwardImpl(self.DistanceFromLineStart)
  99.             end
  100.         end,
  101.         SaveItems = function (self, AllowDropFunc)
  102.             self:__MoveToChest()
  103.             local CurrentSelectedSlot = turtle.getSelectedSlot()
  104.             for i = 1, 16 do
  105.                 if AllowDropFunc(i) then
  106.                     turtle.select(i)
  107.                     turtle.dropUp()
  108.                 end
  109.             end
  110.             turtle.select(CurrentSelectedSlot)
  111.             self:__MoveFromChest()
  112.         end,
  113.         MoveForward = function (self, ForwardCount)
  114.             self.DistanceFromLineStart = self.DistanceFromLineStart + MoveForwardImpl(ForwardCount)
  115.         end,
  116.         ShouldPutTorch = function(self)
  117.             return 1 == self.DistanceFromLineStart % TORCH_INTERVAL
  118.         end,
  119.         GetLineDigCount = function(self)
  120.             return self.LoopCount * 8 - 5
  121.         end,
  122.         ToNext = function(self, ToNextLineFunc, ToNextLoopFunc)
  123.             if self.CurrentProcessLine == 4 then
  124.                 ToNextLoopFunc()
  125.                 self.CurrentProcessLine = 1
  126.                 self.LoopCount = self.LoopCount + 1
  127.             else
  128.                 ToNextLineFunc()
  129.                 self.CurrentProcessLine = self.CurrentProcessLine + 1
  130.             end
  131.             DistanceFromLineStart = 0
  132.         end
  133.     }
  134. end
  135.  
  136. ---@class ItemManager
  137. ---@field __ReservedSlot number
  138. ---@field __AllowDropWhenExceed boolean
  139. ---@field private __AllowSave boolean
  140. ---@field private __Slots integer[]
  141. ---@field private __GetName fun(self: ItemManager):string
  142. ---@field private __Scanimpl fun(self: ItemManager, WhenFoundFunc: "fun(Slot: integer):void")
  143. ---@field Scan fun(self: ItemManager)
  144. ---@field private __GetItemSlot fun(self:ItemManager):integer|nil
  145. ---@field Place fun(self: ItemManager, place_fn: "fun():boolean,string"):boolean,string
  146. ---@field DropWhenExceed fun(self: ItemManager):void `AllowDropWhenExceed`が`true`のとき、手持ちに1slot分だけ残して後ろにアイテムをすべて吐き出す。`Scan`を呼んだのと同じ事後効果を持つ
  147. ---@field IsSavableSlot fun(self: ItemManager, Slot: integer):boolean
  148. local ItemManager = {}
  149. ---@param ReservedSlot number 管理対象アイテムが必ず存在するスロット番号
  150. ---@param AllowDropWhenExceed boolean 一定数ストックした後はドロップを許可するか
  151. ---@param AllowSave boolean 一定数ストックを残してチェストへの格納を許可するか
  152. ItemManager.New = function (ReservedSlot, AllowDropWhenExceed, AllowSave)
  153.     local re = {
  154.         __ReservedSlot = ReservedSlot,
  155.         __AllowDropWhenExceed = AllowDropWhenExceed,
  156.         __AllowSave = AllowSave,
  157.         __Slots = {},
  158.         ---@param self ItemManager
  159.         ---@param WhenFoundFunc fun(Slot: integer)
  160.         __Scanimpl = function (self, WhenFoundFunc)
  161.             local init_slot = turtle.getSelectedSlot() -- 退避
  162.             ---@type integer[]
  163.             for i = 1, 16 do
  164.                 if i ~= self.__ReservedSlot then
  165.                     turtle.select(i)
  166.                     if turtle.compareTo(self.__ReservedSlot) then
  167.                         WhenFoundFunc(i)
  168.                     end
  169.                 end
  170.             end
  171.             turtle.select(init_slot)
  172.         end,
  173.         __GetName = function (self)
  174.             return turtle.getItemDetail(self.__ReservedSlot).name
  175.         end,
  176.         ---@param self ItemManager
  177.         Scan = function (self)
  178.             ---@type integer[]
  179.             local re = { self.__ReservedSlot }
  180.             self:__Scanimpl(function (Slot) table.insert(re, Slot) end)
  181.             self.__Slots = re
  182.             PrintArray(self:__GetName(), self.__Slots)
  183.         end,
  184.         ---使用するスロット番号を求める
  185.         ---
  186.         ---末尾のスロットから使うようにする
  187.         ---@param self ItemManager
  188.         __GetItemSlot = function (self)
  189.             if #self.__Slots == 0 then
  190.                 return nil
  191.             elseif 1 < #self.__Slots then
  192.                 return self.__Slots[#self.__Slots]
  193.             elseif turtle.getItemCount(self.__Slots[#self.__Slots]) == 1 then
  194.                 return nil
  195.             end
  196.             return self.__Slots[#self.__Slots]
  197.         end,
  198.         ---@param self ItemManager
  199.         ---@param place_fn fun():boolean,string
  200.         Place = function (self, place_fn)
  201.             local slot = self:__GetItemSlot()
  202.             if not slot then return false end
  203.             local init_slot = turtle.getSelectedSlot() -- 退避
  204.             debug_print(string.format("ItemManager(%s): %d -> %d", self:__GetName(), init_slot, slot))
  205.             turtle.select(slot)
  206.             local re, message = place_fn()
  207.             PrintArray(self:__GetName(), self.__Slots)
  208.             if re and turtle.getItemCount(self.__Slots[#self.__Slots]) == 0 then
  209.                 table.remove(self.__Slots, #self.__Slots)
  210.             end
  211.             debug_print(string.format("ItemManager(%s): %d -> %d", self:__GetName(), slot, init_slot))
  212.             turtle.select(init_slot)
  213.             return re, message
  214.         end,
  215.         ---`AllowDropWhenExceed`が`true`のとき、手持ちに1slot分だけ残して後ろにアイテムをすべて吐き出す。`Scan`を呼んだのと同じ事後効果を持つ
  216.         ---@param self ItemManager
  217.         DropWhenExceed = function (self)
  218.             if not self.__AllowDropWhenExceed then
  219.                 return
  220.             end
  221.             self:__Scanimpl(function (Slot)
  222.                 TurnBack()
  223.                 turtle.drop()
  224.                 TurnBack()
  225.             end)
  226.             self.__Slots = { self.__ReservedSlot }
  227.         end,
  228.         ---@param self ItemManager
  229.         ---@param Slot integer
  230.         IsSavableSlot = function(self, Slot)
  231.             if self.__AllowSave then
  232.                 return Slot ~= self.__ReservedSlot
  233.             end
  234.             for _, value in ipairs(self.__Slots) do
  235.                 if Slot == value then
  236.                     return false
  237.                 end
  238.             end
  239.             return true
  240.         end
  241.     }
  242.     re:Scan()
  243.     return re
  244. end
  245.  
  246. local StoneManager = ItemManager.New(2, true, true)
  247. local TorchManager = ItemManager.New(1, false, false)
  248. ---@param Slot integer
  249. local function IsSavableSlot(Slot)
  250.     --TorchManagerのほうの探索はforが回るので重い
  251.     return StoneManager:IsSavableSlot(Slot) and TorchManager:IsSavableSlot(Slot)
  252. end
  253.  
  254. local Windmill = WindmillManager.New()
  255.  
  256. local function SaveItems()
  257.     WindmillManager:SaveItems(IsSavableSlot)
  258. end
  259.  
  260. local function DigForward()
  261.     if turtle.detect() and InventoryIsFull() then SaveItems() end
  262.     while turtle.detect() do
  263.         local Flag, Message = turtle.dig()
  264.         if not Flag then return Flag, Message end
  265.     end
  266.     return true
  267. end
  268.  
  269. local function DigUp()
  270.     if InventoryIsFull() then SaveItems() end
  271.     return turtle.digUp()
  272. end
  273.  
  274. ---@param TryCount integer
  275. local function DigAndMoveForward(TryCount)
  276.     for i = 1, TryCount do
  277.         DigForward()
  278.         Windmill:MoveForward(1)
  279.         DigUp()
  280.         if not turtle.detectDown() then StoneManager:Place(turtle.placeDown) end
  281.     end
  282. end
  283.  
  284. local function PlaceTorchToBack()
  285.     TurnBack()
  286.     debug_print(TorchManager:__GetName())
  287.     TorchManager:Place(turtle.place)
  288.     TurnBack()
  289. end
  290.  
  291. local function NormalFlow()
  292.     local DigMaxCount = Windmill:GetLineDigCount()
  293.     debug_print(string.format("NormalFlow:: Dig count: %d", DigMaxCount))
  294.     for i = 1, DigMaxCount do
  295.         DigAndMoveForward(1)
  296.         if i == 1 then
  297.             TurnBack()
  298.             TorchManager:Place(turtle.place)
  299.             TurnBack()
  300.         end
  301.         if Windmill:ReachedCrossDigPoint() then
  302.             turtle.turnRight()
  303.             for j = 1, 3 do
  304.                 -- 進行マス数カウントやインベントリチェックが行われると戻るコードが働かないのでラッパー不使用
  305.                 turtle.dig()
  306.                 turtle.forward()
  307.                 turtle.digUp()
  308.             end
  309.             for j = 1, 3 do turtle.back() end
  310.             turtle.turnLeft()
  311.         end
  312.         if Windmill:ShouldPutTorch() then
  313.             StoneManager:DropWhenExceed()
  314.             PlaceTorchToBack()
  315.         end
  316.     end
  317.     StoneManager:DropWhenExceed()
  318. end
  319.  
  320.  
  321. local function ToNextLineLatterHalfProcess()
  322.     turtle.turnLeft()
  323.     DigAndMoveForward(4)
  324.     TurnBack()
  325.     for i = 1, 4 do
  326.         turtle.forward()
  327.         if i == 1 then PlaceTorchToBack() end
  328.     end
  329. end
  330.  
  331. local function ToNextLine()
  332.     for i = 1, 5 do
  333.         DigAndMoveForward(1)
  334.         if i == 2 then PlaceTorchToBack() end
  335.     end
  336.     ToNextLineLatterHalfProcess()
  337. end
  338.  
  339. local function ToNextLoopLatterHalfProcess()
  340.     turtle.turnRight()
  341.     turtle.dig()
  342.     turtle.forward()
  343.     turtle.digDown()
  344.     turtle.down()
  345.     DigAndMoveForward(3)
  346.     ToNextLineLatterHalfProcess()
  347. end
  348.  
  349. local function Initialize()
  350.     local CommonProcessOnFirstLineAndOthers = function()
  351.         turtle.turnLeft()
  352.         DigAndMoveForward(4)
  353.         turtle.back()
  354.         TorchManager:Place(turtle.place)
  355.         TurnBack()
  356.         DigAndMoveForward(4)
  357.         PlaceTorchToBack()
  358.         DigAndMoveForward(3)
  359.     end
  360.     debug_print("Initialize:: phase 1")
  361.     DigAndMoveForward(4)
  362.     CommonProcessOnFirstLineAndOthers()
  363.     debug_print("Initialize:: phase 2")
  364.     for i = 1, 4 do
  365.         CommonProcessOnFirstLineAndOthers()
  366.  
  367.         turtle.turnRight()
  368.         if turtle.detect() then
  369.             debug_print("Initialize:: detected")
  370.             DigAndMoveForward(3)
  371.             for j = 1, 3 do turtle.back() end
  372.         end
  373.         turtle.turnLeft()
  374.         DigAndMoveForward(4)
  375.     end
  376.  
  377.     debug_print("Initialize:: phase 3")
  378.     turtle.turnLeft()
  379.     DigAndMoveForward(1)
  380.     PlaceTorchToBack()
  381.     DigAndMoveForward(3)
  382.  
  383.     debug_print("Initialize:: phase 4")
  384.     turtle.turnRight()
  385.     DigAndMoveForward(1)
  386.     PlaceTorchToBack()
  387.     DigAndMoveForward(3)
  388.     ToNextLineLatterHalfProcess()
  389. end
  390.  
  391. local function ToNextLoop()
  392.     turtle.up()
  393.     MoveForwardImpl(5)
  394.     turtle.turnLeft()
  395.     MoveForwardImpl(4)
  396.     ToNextLoopLatterHalfProcess()
  397. end
  398.  
  399. Initialize()
  400. while true do
  401.     NormalFlow()
  402.     Windmill:ToNext(ToNextLine, ToNextLoop)
  403. end
  404.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement