Advertisement
kssr3951

charcoalMaker

May 8th, 2018
107
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 30.69 KB | None | 0 0
  1. -- --------
  2. -- charcoalMaker
  3. -- --------
  4. local function showUsage()
  5.   print("charcoalMaker")
  6.   print("slot1 : sapling (naegi)")
  7.   print("slot2 : wood")
  8. end
  9. local SLOT_1_SAPLING = 1
  10. local SLOT_2_WOOD    = 2
  11. local REQUIRED_FUEL_LEVEL = 1600
  12. -- ---------------
  13. -- Move/Dig Functions
  14. -- ---------------
  15. function surelyUp()
  16.   while not turtle.up() do turtle.digUp() end
  17. end
  18. function surelyDown()
  19.   while not turtle.down() do turtle.digDown() end
  20. end
  21. -- http://hevohevo.hatenablog.com/entry/2014/07/14/213109
  22. function surelyDigUp()
  23.   while turtle.digUp() do
  24.     os.sleep(0.4)
  25.   end
  26. end
  27. -- http://hevohevo.hatenablog.com/entry/2014/07/14/213109
  28. function surelyDig()
  29.   while turtle.dig() do end
  30. end
  31. -- http://hevohevo.hatenablog.com/entry/2014/07/14/213109
  32. function surelyFwd()
  33.   for i=1,4 do
  34.     local status, err = turtle.forward()
  35.     if status then
  36.       return true  -- success!
  37.     elseif err=="Out of fuel" then
  38.       return status, err
  39.     end
  40.  
  41.     surelyDig() -- face to a normal block or a sand(gravel) hill
  42.  
  43.     if turtle.detect() and not turtle.dig() then
  44.       return false, "bedrock!"
  45.     end
  46.  
  47.     if turtle.forward() then return true end -- success!
  48.  
  49.     if turtle.attack() then
  50.       -- face to monster-mob
  51.       while turtle.attack() do end
  52.     else
  53.       -- face to sand-blocks which is dropping long time
  54.       os.sleep(5) -- probably, adjustment is required
  55.     end
  56.   end
  57.   return turtle.forward()
  58. end
  59. -- --------
  60. --
  61. -- --------
  62. local f = function() while not turtle.forward() do end end
  63. local b = function() while not turtle.back() do end end
  64. local l = turtle.turnLeft
  65. local r = turtle.turnRight
  66. local u = function() while not turtle.up() do end end
  67. local d = function() while not turtle.down() do end end
  68. local F = surelyFwd
  69. local U = surelyUp
  70. local D = surelyDown
  71. local e0 = surelyDigUp -- [e]xcavate
  72. local e1 = surelyDig
  73. local e2 = turtle.digDown
  74. local p2 = turtle.placeDown
  75. --local sel = turtle.select
  76. local t0 = turtle.dropUp -- [t]hrow
  77. local t1 = turtle.drop
  78. local t2 = turtle.drowDown
  79. local k0 = turtle.suckUp -- suc[k]
  80. local k1 = turtle.suck
  81. local k2 = turtle.suckDown
  82. local sSapling = function() turtle.select(SLOT_1_SAPLING) end
  83. local sWood    = function() turtle.select(SLOT_2_WOOD) end
  84. function vacuum(slotNo, fullOption)
  85.   local keepCnt
  86.   if nil == fullOption then
  87.     keepCnt = 1
  88.   elseif true == fullOption then
  89.     keepCnt = 0
  90.   end
  91.   local result = false
  92.   turtle.select(slotNo)
  93.   for i = 1, 16 do
  94.     if slotNo ~= i and turtle.compareTo(i) and keepCnt < turtle.getItemCount(i) then
  95.       turtle.select(i)
  96.       turtle.transferTo(slotNo, turtle.getItemSpace(slotNo))
  97.       result = true
  98.       if 0 == turtle.getItemSpace(slotNo) then
  99.         break
  100.       end
  101.       turtle.select(slotNo)
  102.     end
  103.   end
  104.   turtle.select(slotNo)
  105.   return result
  106. end
  107. local function makeVacuumFunc(slotNo)
  108.   return function()
  109.       if 1 == turtle.getItemCount(slotNo) then
  110.         vacuum(slotNo)
  111.       end
  112.     end
  113. end
  114. -- exec()やrep()で使えるように関数を戻す関数にしてみた。
  115. local function sel(slotNo)
  116.   return function()
  117.       turtle.select(slotNo)
  118.     end
  119. end
  120. local vSapling = makeVacuumFunc(SLOT_1_SAPLING)
  121. local vWood    = makeVacuumFunc(SLOT_2_WOOD)
  122. local function getTotal(slotNo)
  123.   local cnt = turtle.getItemCount(slotNo)
  124.   turtle.select(slotNo)
  125.   for i=1,16 do
  126.     if i ~= slotNo and turtle.compareTo(i) then
  127.       cnt = cnt + turtle.getItemCount(i)
  128.     end
  129.   end
  130.   return cnt
  131. end
  132. local function dropDownExceptK(slotNo, dropCnt, keepCnt)
  133.   local function slotAction(i, mustKeep, mustDrop, slotNo)
  134.     local cnt = turtle.getItemCount(i)
  135.     if mustKeep < cnt then
  136.       local dropAble = cnt - mustKeep
  137.       local nowDrop = math.min(dropAble, mustDrop)
  138.       mustKeep = 0
  139.       mustDrop = mustDrop - nowDrop
  140.       turtle.select(i)
  141.       turtle.dropDown(nowDrop)
  142.       turtle.select(slotNo)
  143.     else
  144.       mustKeep = mustKeep - cnt
  145.     end
  146.   end
  147.   turtle.select(slotNo)
  148.   local mustKeep = keepCnt
  149.   local mustDrop = dropCnt
  150.   for i=1,16 do
  151.     if i ~= slotNo and turtle.compareTo(i) then
  152.       slotAction(i, mustKeep, mustDrop, slotNo)
  153.     end
  154.   end
  155.   vacuum(slotNo)
  156.   slotAction(slotNo, mustKeep, mustDrop, slotNo)
  157. end
  158. local function dropDownExcept1(slotNo)
  159.   turtle.select(slotNo)
  160.   turtle.dropDown(turtle.getItemCount()-1)
  161.   for i=1,16 do
  162.     if i ~= slotNo and turtle.compareTo(i) then
  163.       turtle.select(i)
  164.       turtle.dropDown()
  165.       turtle.select(slotNo)
  166.     end
  167.   end
  168.   vacuum(slotNo)
  169. end
  170. local function dropDownHalf(slotNo)
  171.   turtle.select(slotNo)
  172.   local c = turtle.getItemCount(slotNo)
  173.   turtle.dropDown((c-1)/2)
  174.   for i=1,16 do
  175.     if i~=slotNo and turtle.compareTo(i) then
  176.       turtle.select(i)
  177.       c = turtle.getItemCount(i)
  178.       turtle.dropDown(c/2)
  179.       turtle.select(slotNo)
  180.     end
  181.   end
  182. end
  183. local function dropAll(dropFunc)
  184.   local dropFn = turtle.drop
  185.   if nil ~= dropFunc then
  186.     dropFn = dropFunc
  187.   end
  188.   for i = 1, 16 do
  189.     if 1 <= turtle.getItemCount(i) then
  190.       turtle.select(i)
  191.       dropFn()
  192.     end
  193.   end
  194. end
  195. local function dropEx(slot, count, dropFunc)
  196.   local sameItems = { slot }
  197.   turtle.select(slot)
  198.   for i = 1, 16 do
  199.     if slot ~= i and 0 < turtle.getItemCount(i) and turtle.compareTo(i) then
  200.       table.insert(sameItems, i)
  201.     end
  202.   end
  203.   local required = count
  204.   for _, i in ipairs(sameItems) do
  205.     local cnt = math.min(turtle.getItemCount(i), required)
  206.     turtle.select(i)
  207.     dropFunc(cnt)
  208.     required = required - cnt
  209.     if 0 == required then
  210.       break
  211.     end
  212.   end
  213.   if 0 == turtle.getItemCount(slot) then
  214.     for _, i in ipairs(sameItems) do
  215.       if slot ~= i and 0 < turtle.getItemCount(i) then
  216.         turtle.select(i)
  217.         turtle.transferTo(slot)
  218.         break
  219.       end
  220.     end
  221.   end
  222. end
  223. local function suckEx(count, suckFunc, stackLimit)
  224.   local stackLim = 64
  225.   if nil ~= stackLimit then
  226.     stackLim = stackLimit
  227.   end
  228.   local required = count
  229.   local firstSlot = nil
  230.   local rslt
  231.   while true do
  232.     local before = { }
  233.     for i = 1, 16 do
  234.       before[i] = turtle.getItemCount(i)
  235.     end
  236.     rslt = suckFunc(math.min(required, stackLim))
  237.     for i = 1, 16 do
  238.       local cnt = turtle.getItemCount(i)
  239.       if cnt ~= before[i] then
  240.         if nil == firstSlot then
  241.           firstSlot = i
  242.         end
  243.         required = required - (cnt - before[i])
  244.       end
  245.     end
  246.     if 0 == required or false == rslt then
  247.       break
  248.     end
  249.   end
  250.   return firstSlot
  251. end
  252.  
  253. local function countAll(slotNo)
  254.   turtle.select(slotNo)
  255.   local cnt = turtle.getItemCount(slotNo)
  256.   if 0 == cnt then
  257.     return 0
  258.   else
  259.     for i = 1, 16 do
  260.       if i ~= slotNo and turtle.compareTo(i) then
  261.         cnt = cnt + turtle.getItemCount(i)
  262.       end
  263.     end
  264.     return cnt
  265.   end
  266. end
  267. local function tableInsertAll(tbl, list)
  268.   for _, v in ipairs(list) do
  269.     table.insert(tbl, v)
  270.   end
  271. end
  272. local TAG_ANOTHER_WHEN_LAST = "anotherWhenLast"
  273. local TAG_SWITCH_ODD_EVEN = "switchOddEven"
  274. local function toFlatList(list)
  275.   local rslt = { }
  276.   if 3 == #list and "string" == type(list[1])
  277.     and TAG_ANOTHER_WHEN_LAST == list[1] then
  278.     table.insert(rslt, list)
  279.   elseif 3 == #list and "string" == type(list[1])
  280.     and TAG_SWITCH_ODD_EVEN == list[1] then
  281.     table.insert(rslt, list)
  282.   else
  283.     for i, v in ipairs(list) do
  284.       if "function" == type(v) then
  285.         table.insert(rslt, v)
  286.       elseif "table" == type(v) then
  287.         tableInsertAll(rslt, toFlatList(v))
  288.       end
  289.     end
  290.   end
  291.   return rslt
  292. end
  293. local function _breakWhenLast_()
  294. end
  295. local function _anotherWhenLast_(ordinaryList, anotherList)
  296.   return { TAG_ANOTHER_WHEN_LAST, ordinaryList, anotherList }
  297. end
  298. local function _switchOddEven_(firstList, secondList)
  299.   return { TAG_SWITCH_ODD_EVEN, firstList, secondList }
  300. end
  301. local breakLast = _breakWhenLast_
  302. local anotherLast = _anotherWhenLast_
  303. local swOddEven = _switchOddEven_
  304. local function rep(num, ...)
  305.   local function tableInsertAllForRep(rslt, list, i, num)
  306.     for j, v in ipairs(list) do
  307.       if _breakWhenLast_ == v then
  308.         if i == num then
  309.           break
  310.         end
  311.       elseif "table" == type(v) and TAG_ANOTHER_WHEN_LAST == v[1] then
  312.         if i ~= num then
  313.           tableInsertAllForRep(rslt, toFlatList(v[2]), i, num)
  314.         else
  315.           tableInsertAllForRep(rslt, toFlatList(v[3]), i, num)
  316.         end
  317.       elseif "table" == type(v) and TAG_SWITCH_ODD_EVEN == v[1] then
  318.         if i % 2 == 1 then
  319.           tableInsertAllForRep(rslt, toFlatList(v[2]), i, num)
  320.         else
  321.           tableInsertAllForRep(rslt, toFlatList(v[3]), i, num)
  322.         end
  323.       else
  324.         table.insert(rslt, v)
  325.       end
  326.     end
  327.   end
  328.   local list = toFlatList({...})
  329.   local rslt = {}
  330.   for i = 1, num do
  331.     tableInsertAllForRep(rslt, list, i, num)
  332.   end
  333.   return rslt
  334. end
  335. local function exec(...)
  336.   for i, func in ipairs(toFlatList({...})) do
  337.     func()
  338.   end
  339. end
  340.  
  341. -- --------
  342. -- utility
  343. -- --------
  344. local function countAny()
  345.   local cnt = 0
  346.   for i = 1, 16 do
  347.     cnt = cnt + turtle.getItemCount(i)
  348.   end
  349.   return cnt
  350. end
  351. local function countEx(slot)
  352.   local cnt = turtle.getItemCount(slot)
  353.   if 0 == cnt then
  354.     return 0
  355.   end
  356.   turtle.select(slot)
  357.   for i = 1, 16 do
  358.     if slot ~= i and 0 < turtle.getItemCount(i) and turtle.compareTo(i) then
  359.       cnt = cnt + turtle.getItemCount(i)
  360.     end
  361.   end
  362.   return cnt
  363. end
  364. -- --------
  365. -- application
  366. -- --------
  367. -- 管理対象
  368. --   苗木
  369. --   原木
  370. --   木材
  371. --   棒
  372. --   松明
  373. --   木炭
  374. --   チェスト
  375. local function newAcc()
  376.   return { count = 0, chests = { } }
  377. end
  378. local account = {}
  379. account.sapling   = newAcc()
  380. account.wood      = newAcc()
  381. account.woodPlank = newAcc()
  382. account.stick     = newAcc()
  383. account.torch     = newAcc()
  384. account.charcoal  = newAcc()
  385. account.chest     = newAcc()
  386.  
  387. -- 原木3個を原木2個で焼くと木炭が3個できる。燃焼のムダもなさそう。木炭1個で原木8個焼けるので、以降は原木を燃料として使わない。
  388. --
  389. -- 木炭のストックが無いときの原木を使った木炭作成は、プログラムの初回は必ず行うようにすればいい。
  390. -- ①かまど1号を用いて、原木3個を原木2個で焼く(原木2個ロスト)
  391. -- ②かまど1~3号に、出来上がった木炭を1個ずつセット、原木8こずつを焼く(木炭3個ロスト)
  392. local function ddXw(dropCnt)
  393.   local cnt = turtle.getItemCount(SLOT_2_WOOD)
  394.   if 0 == cnt then
  395.     return
  396.   elseif cnt <= dropCnt then
  397.     vacuum(SLOT_2_WOOD)
  398.   end
  399.   turtle.dropDown(dropCnt)
  400. end
  401. local function dd8w()
  402.   ddXw(8)
  403. end
  404. local function findVacantSlot()
  405.   for i = 1, 16 do
  406.     if 0 == turtle.getItemCount(i) then
  407.       return i
  408.     end
  409.   end
  410.   return nil
  411. end
  412. local function suckUp1()
  413.   while not turtle.suckUp(1) do end
  414. end
  415. local function dropUp1()
  416.   turtle.dropUp(1)
  417. end
  418. local function dropExceptSlot(slot)
  419.   for i = 1, 16 do
  420.     if i ~= slot then
  421.       if 1 <= turtle.getItemCount(i) then
  422.         turtle.select(i)
  423.         turtle.drop()
  424.       end
  425.     end
  426.   end
  427. end
  428. local function fillTightly()
  429.   local j = 16
  430.   for i = 1, 15 do
  431.     for j = j, i + 1, -1 do
  432.       local space = turtle.getItemSpace(i)
  433.       local cnt   = turtle.getItemCount(j)
  434.       if 0 == space then
  435.         break
  436.       end
  437.       if 0 < cnt then
  438.         if j ~= turtle.getSelectedSlot() then
  439.           turtle.select(j)
  440.         end
  441.         turtle.transferTo(i, math.min(space, cnt))
  442.         if 0 == turtle.getItemSpace(i) then
  443.           break
  444.         end
  445.       end
  446.     end
  447.   end
  448. end
  449. local function firstCharcoalMake()
  450.   -- 初回のみ実行する木炭作成処理。(原木で木炭を3個作成し、それを元手にかまど1から8で木炭を作成する。)
  451.   -- 原木3個を原木2個で焼く
  452.   vacuum(SLOT_2_WOOD)
  453.   exec(r,f,l,f,f,l,f,r)
  454.   turtle.select(SLOT_2_WOOD)
  455.   turtle.dropUp(2)
  456.   exec(f,u,u,b)
  457.   turtle.dropDown(3)
  458.   -- 原木8個ずつをかまど1から8へ投入
  459.   exec(
  460.     rep(4,dd8w,f,f,dd8w,breakLast,swOddEven({r,f,f,r},{l,f,f,l}))
  461.   )
  462.   exec(r,rep(5,f),d,d,f,r)
  463.   -- 原木8x8個をドロップしているので、空きスロットは必ずある
  464.   vacuum(SLOT_2_WOOD)
  465.   local charcoalSlot = findVacantSlot()
  466.   turtle.select(charcoalSlot)
  467.   -- かまど1で原木を使って焼いた1個めの木炭(1P1)を取り出し、かまど2に燃料として投入。(1P1回収)(1P2開始)(2A開始)
  468.   exec(suckUp1,f,f,dropUp1)
  469.   -- かまど1で原木を使って焼いた2個めの木炭(1P2)を取り出し、かまど3に燃料として投入。(1P2回収)(1P3開始)(3B開始)
  470.   exec(b,b,suckUp1,r,f,f,dropUp1)  
  471.   -- かまど2で焼きあがった木炭(2A)を取り出し、かまど1に燃料として投入。(2A回収)(1C開始?)
  472.   exec(l,f,f,l,f,f,r,suckUp1,b,b,dropUp1)
  473.   -- かまど1で原木を使って焼いた3個めの木炭(1P3)を取り出し、かまど4に燃料として投入。(1P3回収)(4D開始)
  474.   exec(suckUp1,f,f,r,f,f,dropUp1)
  475.   -- かまど3で焼きあがった木炭(3B)を取り出し、かまど5に燃料として投入。(3B回収)(5E開始)
  476.   exec(l,b,b,suckUp1,r,f,f,dropUp1)
  477.   -- かまど1で焼きあがった木炭(1C)を取り出し、かまど6に燃料として投入。(1C回収)(6F開始)
  478.   exec(rep(4,b),suckUp1,rep(4,f),l,f,f,dropUp1)
  479.   -- かまど4で焼きあがった木炭(4D)を取り出し、かまど8に燃料として投入。(4D回収)(8G開始)
  480.   exec(r,b,b,suckUp1,rep(4,f),dropUp1)
  481.   -- かまど5で焼きあがった木炭(5E)を取り出し、かまど7に燃料として投入。(5E回収)(7H開始)
  482.   exec(b,b,l,b,b,r,suckUp1,f,f,dropUp1)
  483.   -- 素材投入用の初期位置に戻る
  484.   exec(b,u,u,rep(5,b),l)
  485.  
  486.   vacuum(SLOT_2_WOOD)
  487. end
  488.  
  489. local function firstCharcoalMake2()
  490.   local woodCnt = countAll(SLOT_2_WOOD)
  491.   local charcoalCnt         = math.floor((woodCnt / 2) / 8) * 8
  492.   local charcoalCntForTorch = math.floor((woodCnt / 4) / 8) * 8
  493.   local woodCntForTorch     = charcoalCntForTorch / 8
  494.   local woodCntForChest     = math.floor((woodCnt / 8) / 2) * 2
  495.   local woodCntReserve      = woodCnt - charcoalCnt - charcoalCntForTorch
  496.                                       - woodCntForTorch - woodCntForChest
  497.   --[[
  498.   print(string.format("total = %d / charCnt = %d / charForTorch = %d",
  499.     woodCnt, charcoalCnt, charcoalCntForTorch))
  500.   print(string.format("woodForTorch = %d / woodForChest = %d / reserve = %d",
  501.     woodCntForTorch, woodCntForChest, woodCntReserve))
  502.   --]]
  503.   -- 木炭の原料を投入する
  504.   local furnaceNo = 1
  505.   local charcoalAllCnt = charcoalCnt + charcoalCntForTorch
  506.   local baseCnt = math.floor(charcoalAllCnt / 64)
  507.   local exNo = (charcoalAllCnt / 8) % 8
  508.   --print(string.format("baseCnt = %d / exNo = %d", baseCnt, exNo))
  509.  
  510.   -- 投入できる限りの量の原木を投入
  511.   local exCnt
  512.   for i = 1, 8 do
  513.     if i <= exNo then
  514.       exCnt = 1
  515.     else
  516.       exCnt = 0
  517.     end
  518.     ddXw(math.min(8*7, (baseCnt + exCnt) * 8))
  519.     if i == 1 or i == 3 or i == 5 or i == 7 then
  520.       exec(f,f)
  521.     elseif i == 2 or i == 6 then
  522.       exec(r,f,f,r)
  523.     elseif i == 4 then
  524.       exec(l,f,f,l)
  525.     end
  526.   end
  527.   exec(r,rep(5,f),d,d,l,f,f,r,f,r)
  528. end
  529. local function gotoWarehousePosFromInitPos()
  530.   exec(rep(4,u),r)
  531. end
  532. local function craftChests()
  533.   -- すべてチェストにしてしまう
  534.   vacuum(SLOT_2_WOOD)
  535.   local woodCnt = countAll(SLOT_2_WOOD)
  536.   dropAll()
  537.   local woodCntForPlank = math.min(woodCnt, 64 * 13)
  538.   -- 原木を木材に加工して木材チェストに保存する位置に移動
  539.   exec(l,f,r,f,r)
  540.   -- 最大13スタックの原木を木材に変える
  541.   for i = 1, 13 do
  542.     turtle.select(1)
  543.     local rslt = turtle.suck()
  544.     if false == rslt then
  545.       break
  546.     end
  547.     exec(l,l)
  548.     for j = 1, 4 do
  549.       local cnt = turtle.getItemCount(1)
  550.       turtle.craft()
  551.       if 16 < cnt then
  552.         dropExceptSlot(1)
  553.       else
  554.         dropAll()
  555.         break
  556.       end
  557.     end
  558.     exec(r,r)
  559.   end
  560.   -- 木材をチェストに加工してチェスト用チェストに保存する位置に移動
  561.   exec(r,f,r,rep(3,f),r,f,r)
  562.   -- 木材チェストの全ての原木からチェストを作ってチェスト用チェストに保存する
  563.   local doughnut = { 1,2,3,5,7,9,10,11 }
  564.   local notFull = false
  565.   while true do
  566.     local maxCnt =  0
  567.     local minCnt = 64
  568.     for i = 1, 8 do
  569.       turtle.select(doughnut[i])
  570.       local rslt = turtle.suck()
  571.       if false == rslt then
  572.         notFull = true
  573.         break
  574.       end
  575.       local cnt = turtle.getItemCount(doughnut[i])
  576.       maxCnt = math.max(maxCnt, cnt)
  577.       minCnt = math.min(minCnt, cnt)
  578.     end
  579.     -- 原木をドーナツ型に配置したつもりだが、数がそろっていない場合はそろえる
  580.     if notFull or minCnt ~= maxCnt then
  581.       local ttl = 0
  582.       for i = 1, 16 do ttl = ttl + turtle.getItemCount(i) end
  583.       if 8 <= ttl then
  584.         local par = math.floor(ttl / 8)
  585.         for _, i in ipairs(doughnut) do
  586.           local iCnt = turtle.getItemCount(i)
  587.           if par < iCnt then
  588.             turtle.select(i)
  589.             for _, j in ipairs(doughnut) do
  590.               if i ~= j then
  591.                 local jCnt = turtle.getItemCount(j)
  592.                 if jCnt < par then
  593.                   turtle.transferTo(j, math.min(iCnt - par, par - jCnt))
  594.                   iCnt = turtle.getItemCount(i)
  595.                   if par == iCnt then
  596.                     break
  597.                   end
  598.                 end
  599.               end
  600.             end
  601.           end
  602.         end
  603.         for _, i in ipairs(doughnut) do
  604.           local cnt = turtle.getItemCount(i)
  605.           if par < cnt then
  606.             turtle.select(i)
  607.             turtle.drop(cnt - par)
  608.           end
  609.         end
  610.       else
  611.         dropAll()
  612.         break
  613.       end
  614.     end
  615.     turtle.craft()
  616.     exec(l,l)
  617.     dropAll()
  618.     exec(r,r)
  619.   end
  620. end
  621. local function gotoInitPosFromWarehousePos()
  622.   exec(l,rep(4,d))
  623. end
  624. local function suckUpDropUp()
  625.   local charcoalSlot = findVacantSlot()
  626.   turtle.select(charcoalSlot)
  627.   turtle.suckUp()
  628.   vacuum(charcoalSlot)
  629.   turtle.dropUp()
  630. end
  631. local function gotoCharcoalHatInitPosFromTreePlantationInitPos()
  632.   exec(rep(3,e0,u),l,e1,f,r,rep(15,e1,f),l,e2,d,rep(3,e1,f),e2,d)
  633. end
  634. local function gotoPlantationFromCharcoalHat()
  635.   exec(u,u,l,l,rep(4,e1,f))
  636.   exec(r,rep(15,e1,f))
  637.   exec(rep(3,e2,d),dropAll,l,l)
  638.   exec(f)
  639.   turtle.select(1)
  640.   turtle.suckDown()
  641.   exec(b,r,f)
  642.   turtle.select(2)
  643.   turtle.suckDown()
  644.   exec(b,l)
  645. end
  646. local function lumberjackPart()
  647.   -- 植林場のプログラム(lumberjack)を実行
  648.   shell.run("lumberjack")
  649.   -- 苗木を前方のチェストに退避
  650.   exec(e1,f)
  651.   while true do
  652.     local sapCnt = turtle.getItemCount(SLOT_1_SAPLING)
  653.     if 1 < sapCnt then
  654.       turtle.select(1)
  655.       turtle.dropDown(sapCnt - 1)
  656.     end
  657.     vacuum(SLOT_1_SAPLING, true)
  658.     sapCnt = turtle.getItemCount(SLOT_1_SAPLING)
  659.     if sapCnt == 1 then
  660.       turtle.dropDown()
  661.       break
  662.     elseif sapCnt < 1 then
  663.       break
  664.     end
  665.   end
  666.   exec(l,l,e1,f,l)
  667.   -- 原木1個(サンプル)を右のチェストに退避
  668.   exec(e1,f)
  669.   vacuum(SLOT_2_WOOD,true)
  670.   turtle.select(SLOT_2_WOOD)
  671.   turtle.dropDown(1)
  672.   exec(l,l,e1,f,r)
  673.   -- 植林場の開始位置から炭焼き小屋の開始位置へ移動
  674.   gotoCharcoalHatInitPosFromTreePlantationInitPos()
  675. end
  676. local function firstAction()
  677.   -- 余計なアイテムを持っていたら捨てる(移動中に苗木を拾う可能性がある)
  678.   turtle.select(SLOT_2_WOOD)
  679.   for i = 1, 16 do
  680.     if i ~= SLOT_2_WOOD and 0 < turtle.getItemCount(i) and false == turtle.compareTo(i) then
  681.       turtle.select(i)
  682.       turtle.dropDown()
  683.       turtle.select(SLOT_2_WOOD)
  684.     end
  685.   end
  686.   -- 初回限定の木炭作成動作その1
  687.   firstCharcoalMake()
  688.   -- 初回限定の木炭作成動作その2。(その1で作った木炭でさらに木炭を作る)
  689.   firstCharcoalMake2()
  690.   -- 倉庫階のスタート位置(&向き)に移動する
  691.   gotoWarehousePosFromInitPos()
  692.   -- 残りの原木をすべて使ってチェストを作成する
  693.   craftChests()
  694.   -- 倉庫のスタート地点(&向き)に戻る
  695.   exec(r,f,l,rep(4,f),l)
  696.   -- かまど階のスタート位置に戻る
  697.   gotoInitPosFromWarehousePos()
  698.   -- 焼きあがった木炭を取り出し、燃料としてセットする
  699.   exec(r,f,l,f,f,l,f,r)
  700.   exec(rep(4,suckUpDropUp,f,f,suckUpDropUp,breakLast,swOddEven({r,f,f,r},{l,f,f,l})))  
  701.   -- かまど階のスタート位置に戻る
  702.   exec(r,rep(5,f),l,f,f,r,f,r)
  703. end
  704. local function secondAction()
  705.   -- 原木の個数を取得
  706.   local woodCnt = countAll(SLOT_2_WOOD)
  707.   -- 原木を一旦全部退避する
  708.   exec(b)
  709.   dropAll(turtle.dropDown)
  710.   exec(f)
  711.   -- 焼きあがった木炭を取り出し、燃料としてセットする。回数が進むとここで余りが発生するはず。
  712.   exec(r,f,l,f,f,l,f,r)
  713.   exec(rep(4,suckUpDropUp,f,f,suckUpDropUp,breakLast,swOddEven({r,f,f,r},{l,f,f,l})))
  714.   -- かまど階のスタート位置に戻る
  715.   exec(r,rep(5,f),l,f,f,r,f,r)
  716.  
  717.   -- 燃料補給
  718.   fillTightly()
  719.   local requiredFuelLv = 3000
  720.   local reqChar = requiredFuelLv / 80 + 1
  721.   local bf = turtle.getFuelLevel()
  722.   turtle.refuel(math.min(reqChar, turtle.getItemCount(1)))
  723.   local af = turtle.getFuelLevel()
  724.   print(string.format("refuel %d -> %d (%d)", bf, af, af - bf))
  725.  
  726.   -- 木炭の個数を数える
  727.   local charCnt = countAny()
  728.   -- 松明
  729.   local torchRate = 8
  730.   local torchChar = math.floor(math.floor(charCnt / torchRate) / 8) * 8
  731.   local torchWood = math.floor(torchChar / 4) * 2 / 4
  732.   -- チェスト
  733.   local chestRate = 8
  734.   local chestWood = math.floor(math.floor(woodCnt / chestRate) / 2) * 2
  735.   -- 原木(貯蔵数)
  736.   local storeRate = 5
  737.   local storeWood = math.floor(woodCnt / storeRate)
  738.   -- 木炭(製造数)
  739.   local charWood = math.floor((woodCnt - torchWood - chestWood - storeWood) / 8) * 8
  740.   -- 木炭(貯蔵数)
  741.   local storeChar = charCnt - torchChar
  742.   -- 原木(貯蔵数)を再計算
  743.   storeWood = woodCnt - torchWood - chestWood - charWood
  744.   -- 確認
  745.   --[[
  746.   print("charCnt = " .. tostring(charCnt))
  747.   print("woodCnt = " .. tostring(woodCnt))
  748.   print("torchChar = " .. tostring(torchChar))
  749.   print("torchWood = " .. tostring(torchWood))
  750.   print("chestWood = " .. tostring(chestWood))
  751.   print("storeWood = " .. tostring(storeWood))
  752.   print(" charWood = " .. tostring( charWood))
  753.   print("storeChar = " .. tostring(storeChar))
  754.   --]]
  755.   if 0 < torchChar or 0 < storeChar then
  756.     -- ------------------------------------------
  757.     -- 木炭を、松明製造用/貯蔵用のチェストに入れる。
  758.     -- TODO 貯蔵用チェストがいっぱいになっている場合はチェストを増設する
  759.     -- ------------------------------------------
  760.     -- 倉庫階のスタート位置(&向き)に移動する
  761.     gotoWarehousePosFromInitPos()
  762.     -- 松明製造用の木炭用のチェストに移動し、松明分の木炭を保存
  763.     exec(l,f,r,rep(3,f),r)
  764.     fillTightly()
  765.     dropEx(1, torchChar, turtle.drop)
  766.     -- 木炭貯蔵用のチェストに移動し、残りの木炭を保存
  767.     exec(l,f,f,r)
  768.     dropAll()
  769.     -- 倉庫階のスタート位置(&向き)に戻る
  770.     exec(r,rep(5,f),l,f,l)
  771.     -- かまど階のスタート位置に戻る
  772.     gotoInitPosFromWarehousePos()
  773.   end
  774.   -- 原木をすべて取り出す
  775.   exec(b)
  776.   for i = 1, 16 do if false == turtle.suckDown() then break end end
  777.   exec(f)
  778.   fillTightly()
  779.   -- 原木をかまどに投入
  780.   exec(r,f,l,f,f,u,u,l,f,r)
  781.   local function makeFnDropDown(count)
  782.     local FURNACE_CNT = 8
  783.     local UNIT_CNT = 8 -- 木炭1個で効率良く焼ける原木の数
  784.     local required = count
  785.     local baseCnt = math.floor(required / FURNACE_CNT / UNIT_CNT) * UNIT_CNT
  786.     local extra = (required - baseCnt * UNIT_CNT) / UNIT_CNT  
  787.     local callCnt = 0
  788.     return function()
  789.         callCnt = callCnt + 1
  790.         local dropCnt = baseCnt
  791.         if callCnt <= extra then
  792.           dropCnt = dropCnt + UNIT_CNT
  793.         end
  794.         fillTightly()
  795.         dropEx(1, dropCnt, turtle.dropDown)
  796.       end
  797.   end
  798.   local ddEx = makeFnDropDown(charWood)
  799.   exec(rep(4,ddEx,f,f,ddEx,breakLast,swOddEven({r,f,f,r},{l,f,f,l})))
  800.   -- かまど階の初期位置に戻る
  801.   exec(r,rep(5,f),d,d,l,f,f,r,f,r)
  802.   -- 倉庫階のスタート位置(&向き)に移動する
  803.   gotoWarehousePosFromInitPos()
  804.   -- 貯蔵分の木材をチェストに保存する
  805.   exec(l,f,r,rep(5,f),l)
  806.   fillTightly()
  807.   dropEx(1, storeWood, turtle.drop)
  808.   -- 倉庫階のスタート位置(&向き)に戻る
  809.   exec(l,rep(4,f),l)
  810.   -- 残りの原木(チェスト用、松明用)を退避
  811.   dropAll()
  812.   -- 松明クラフト用に木材をクラフトする
  813.   local req = torchWood
  814.   while true do
  815.     turtle.select(1)
  816.     turtle.suck(math.min(req, 64))
  817.     local cnt = turtle.getItemCount(1)
  818.     req = req - cnt
  819.     exec(l,l)
  820.     for j = 1, 4 do
  821.       local cnt = turtle.getItemCount(1)
  822.       turtle.craft()
  823.       if 16 < cnt then
  824.         dropExceptSlot(1)
  825.       else
  826.         dropAll()
  827.         break
  828.       end
  829.     end
  830.     if 0 == req then
  831.       break
  832.     end
  833.     exec(r,r)
  834.   end
  835.   -- 松明をクラフトする
  836.   req = torchWood * 4
  837.   local slots = { 1, 5 }
  838.   while true do
  839.     local cnt = 0
  840.     for _, i in ipairs(slots) do
  841.       turtle.select(i)
  842.       turtle.suck(math.min(req / 2, 16))
  843.       cnt = cnt + turtle.getItemCount(i)
  844.     end
  845.     req = req - cnt
  846.     turtle.craft()
  847.     turtle.select(1)
  848.     turtle.transferTo(5)
  849.     exec(r,f,f,r)
  850.     turtle.suck(math.min(cnt * 2, 64))
  851.     exec(l,l)
  852.     for j = 1, 4 do
  853.       local cnt2 = turtle.getItemCount(1)
  854.       turtle.craft()
  855.       if 16 < cnt2 then
  856.         turtle.select(2)
  857.         turtle.drop()
  858.       else
  859.         dropAll()
  860.         break
  861.       end
  862.     end
  863.     if 0 == req then
  864.       break
  865.     end
  866.     exec(l,f,f,r)
  867.   end
  868.   -- 倉庫階のスタート位置(&向き)に移動する
  869.   exec(l,rep(3,f),l,f,l)
  870.   -- craftChests()の変な前提条件に合わせる
  871.   fillTightly()
  872.   turtle.select(1)
  873.   turtle.transferTo(2)
  874.   -- 残りの原木をすべて使ってチェストを作成する
  875.   craftChests()
  876.   -- 倉庫階のスタート位置(&向き)に移動する
  877.   exec(r,f,l,rep(4,f),l)
  878.   -- クラフトした木炭、松明、チェストの数を返す
  879.   local rsltCharCnt = storeChar
  880.   local rsltTorchCnt = torchChar * 4
  881.   local rsltChestCnt = chestWood / 2
  882.   return rsltCharCnt, rsltTorchCnt, rsltChestCnt
  883. end
  884. local function deliveryAction(charCnt, torchCnt, chestCnt)
  885.   -- 4つの採掘拠点の補充用チェストに、木炭、松明、チェストを補充する
  886.   local items = { }
  887.   -- 木炭を取得
  888.   exec(l,f,r,rep(5,f),r)
  889.   local firstSlot = suckEx(charCnt, turtle.suck)
  890.   if nil ~= firstSlot then
  891.     items.charcoal = { }
  892.     items.charcoal.slot = firstSlot
  893.     items.charcoal.cnt = countEx(firstSlot)
  894.   end
  895.   --print("[char ]firstSlot = " .. tostring(firstSlot) .. " / cnt = " .. tostring(items.charcoal.cnt))
  896.   -- 松明を取得
  897.   exec(r,f,f,r)
  898.   firstSlot = suckEx(torchCnt, turtle.suck)
  899.   if nil ~= firstSlot then
  900.     items.torch = { }
  901.     items.torch.slot = firstSlot
  902.     items.torch.cnt = countEx(firstSlot)
  903.   end
  904.   --print("[torch]firstSlot = " .. tostring(firstSlot) .. " / cnt = " .. tostring(items.torch.cnt))
  905.   -- チェストを取得
  906.   exec(l,f,r,rep(3,f),l,f,r)
  907.   firstSlot = suckEx(chestCnt, turtle.suck)
  908.   if nil ~= firstSlot then
  909.     items.chest = { }
  910.     items.chest.slot = firstSlot
  911.     items.chest.cnt = countEx(firstSlot)
  912.   end
  913.   --print("[chest]firstSlot = " .. tostring(firstSlot) .. " / cnt = " .. tostring(items.chest.cnt))
  914.   -- 採掘拠点に移動
  915.   exec(l,f,r,f,l,f,d,d)
  916.   exec(f,f,r,f,l,rep(3,f))
  917.   exec(rep(4,d),r,f,l,f,u,f)
  918.  
  919.   for i = 1, 4 do
  920.     exec(l)
  921.     local sbj = items.charcoal
  922.     if nil ~= sbj then
  923.       turtle.select(sbj.slot)
  924.       dropEx(sbj.slot, sbj.cnt / 4, turtle.drop)
  925.     end
  926.     exec(u)
  927.     sbj = items.torch
  928.     if nil ~= sbj then
  929.       turtle.select(sbj.slot)
  930.       dropEx(sbj.slot, sbj.cnt / 4, turtle.drop)
  931.     end
  932.     exec(u)
  933.     sbj = items.chest
  934.     if nil ~= sbj then
  935.       turtle.select(sbj.slot)
  936.       dropEx(sbj.slot, sbj.cnt / 4, turtle.drop)
  937.     end
  938.     exec(d,d,r)
  939.     exec(f,f,l,b)
  940.   end
  941.   -- 倉庫のチェスト置場まで戻る
  942.   exec(r,r,f,d,f)
  943.   exec(r,f,rep(6,u),f,l,rep(6,f))
  944.   -- 余ったアイテムを戻す(チェスト)
  945.   sbj = items.chest
  946.   if nil ~= sbj then
  947.     if 0 < turtle.getItemCount(sbj.slot) then
  948.       dropEx(sbj.slot, countEx(sbj.slot), turtle.drop)
  949.     end
  950.   end
  951.   -- 余ったアイテムを戻す(松明)
  952.   exec(r,f,l,rep(3,f),r)
  953.   sbj = items.torch
  954.   if nil ~= sbj then
  955.     if 0 < turtle.getItemCount(sbj.slot) then
  956.       dropEx(sbj.slot, countEx(sbj.slot), turtle.drop)
  957.     end
  958.   end
  959.   -- 余ったアイテムを戻す(木炭)
  960.   exec(l,f,r,rep(3,f),l,f,r)
  961.   sbj = items.charcoal
  962.   if nil ~= sbj then
  963.     if 0 < turtle.getItemCount(sbj.slot) then
  964.       dropEx(sbj.slot, countEx(sbj.slot), turtle.drop)
  965.     end
  966.   end
  967.   -- 倉庫階のスタート位置(&向き)に移動する
  968.   exec(r,rep(5,f),l,f,l)
  969.   -- かまど階のスタート位置に戻る
  970.   gotoInitPosFromWarehousePos()
  971. end
  972. -- -------------------------------
  973. -- main
  974. -- -------------------------------
  975. for i = 1, 10 do
  976.   -- 現在のFuelLevelを取得
  977.   print("[" .. tostring(i) .."] fuelLv = " .. tostring(turtle.getFuelLevel()))
  978.   if turtle.getFuelLevel() < 5000 then
  979.     error("stop")
  980.   end
  981.   -- 植林場のプログラム(lumberjack)を実行し、炭焼き小屋の初期位置に移動する
  982.   lumberjackPart()
  983.   if i == 1 then
  984.     -- 炭焼き小屋での1回目のアクションを実行し、炭焼き小屋の初期位置に戻る
  985.     firstAction()
  986.   else
  987.     -- 炭焼き小屋での2回目以降のアクションを実行し、倉庫部分の初期位置に戻る
  988.     local charCnt, torchCnt, chestCnt = secondAction()
  989.  
  990.     -- 少しは倉庫に溜める
  991.     --print(string.format("result  chr=%d / torch=%d / chest=%d", charCnt, torchCnt, chestCnt))
  992.     local deliverChar  = math.floor(charCnt  * 0.9)
  993.     local deliverTorch = math.floor(torchCnt * 0.9)
  994.     local deliverChest = math.floor(chestCnt * 0.9)
  995.     --print(string.format("deliver chr=%d / torch=%d / chest=%d", deliverChar, deliverTorch, deliverChest))
  996.  
  997.     -- 4つの採掘拠点の補充用チェストに、木炭、松明、チェストを補充し、炭焼き小屋の初期位置に戻る
  998.     deliveryAction(deliverChar, deliverTorch, deliverChest)
  999.   end
  1000.   -- 植林場に移動する
  1001.   gotoPlantationFromCharcoalHat()
  1002. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement