ToLazyToThink

BUD Farmer v0.4

May 5th, 2013
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.94 KB | None | 0 0
  1. -- This program is meant to harvest crops like netherwart, carrots,
  2. --   potatos, etc. that serve as their own seeds, and that have growth stages
  3. --   that can be monitored by a BUD (block update detector).
  4.  
  5. local growStates = 3
  6.  
  7. local dropFn  = turtle.dropDown
  8. local digFn   = turtle.dig
  9. local placeFn = turtle.place
  10.  
  11. local maxWait    = 60*45
  12. local budSide    = "back"
  13.  
  14. local dropWait = 30
  15.  
  16. local trackMax = 50
  17.  
  18. function usage()
  19.   print("usage: " .. shell.getRunningProgram() .. " <growStates>")
  20.   print("           [ <cropDir> <dropChestDir> [(<maxWaitMin> m|<maxWaitSec> s)")
  21.   print("             [<budSide> [(<dropWaitMin> m|<dropWaitSec> s) [<trackMax>]]]]] ")
  22.  
  23.   -- e.g: budFarmer 3 front down 45 m back 30 s 10
  24.   --    Plant crop in front [<cropDir>] of the turtle.
  25.   --    Wait for 3 block updates [<growStates>] (indicated by a redstone
  26.   --    pulse on the back side of the turtle [<budSide>]) or up to
  27.   --    45 minutes [<maxWaitMin>].  If the drop chest underneath
  28.   --    [<dropChestDir>] is full, wait 30 seconds [<dropWaitSec>]
  29.   --    and try again.  Track statistics for the last 10 cycles [<trackMax>].
  30.  
  31.   error()
  32. end
  33.  
  34. function numArg(str)
  35.   local ret = tonumber(str)
  36.   if ret == nil then
  37.     usage()
  38.   end
  39.   return ret
  40. end
  41.  
  42. function timeArg(arg, unit)
  43.   if unit == "m" then
  44.     return numArg(arg) * 60
  45.   elseif unit == "s" then
  46.     return numArg(arg)
  47.   else
  48.     usage()
  49.   end
  50. end
  51.  
  52. local argc = 0
  53. local args = {...}
  54.  
  55. argc = argc + 1
  56. if args[argc] == nil then
  57.   usage()
  58. else
  59.   growStates = numArg(args[argc])
  60. end
  61.  
  62. argc = argc + 1
  63. if args[argc] ~= nil then
  64.   if args[argc] == "front" then
  65.     digFn   = turtle.dig
  66.     placeFn = turtle.place
  67.   elseif args[argc] == "down" then
  68.     digFn = turtle.digDown
  69.     paceFn = turtle.placeDown
  70.   else
  71.     usage()
  72.   end
  73. end
  74.  
  75. argc = argc + 1
  76. if args[argc] ~= nil then
  77.   if args[argc] == "front" then
  78.     dropFn = turtle.drop
  79.   elseif args[argc] == "down" then
  80.     dropFn = turtle.dropDown
  81.   elseif args[argc] == "up" then
  82.     dropFn = turtle.dropUp
  83.   else
  84.     usage()
  85.   end
  86. end
  87.  
  88. argc = argc + 1
  89. if args[argc] ~= nil then
  90.   maxWait = timeArg(args[argc], args[argc+1])
  91.   argc = argc+ 1
  92. end
  93.  
  94. argc = argc + 1
  95. if args[argc] ~= nill then
  96.   budSide = args[argc]
  97. end
  98.  
  99. argc = argc + 1
  100. if args[argc] ~= nil then
  101.   dropWait = timeArg(args[argc], args[argc+1])
  102.   argc = argc+ 1
  103. end
  104.  
  105. argc = argc + 1
  106. if args[argc] ~= nill then
  107.   trackMax = args[argc]
  108. end
  109.  
  110.  
  111. local next = 1
  112. local total = 0
  113. local timeouts   = { }
  114. local growTimes  = { }
  115. local growYields = { }
  116.  
  117. local lastTime = os.clock()
  118.  
  119. for i = 1, trackMax do
  120.   timeouts[i]   = 0
  121.   growTimes[i]  = 0
  122.   growYields[i] = 0
  123. end
  124.  
  125. function println(str)
  126.   local x, y = term.getCursorPos()
  127.   term.setCursorPos(1, y)
  128.   term.clearLine()
  129.   print(str)
  130. end
  131.  
  132. function printover(str)
  133.   local x, y = term.getCursorPos()
  134.   term.setCursorPos(1, y)
  135.   term.clearLine()
  136.   term.write(str)
  137.   term.setCursorPos(1, y)
  138. end
  139.  
  140. function trackYields(growYield, growTime, dropTime, timedOut)
  141.   local cur = next
  142.   next = (next % trackMax) + 1
  143.   total = total + 1
  144.  
  145.   if timedOut then
  146.     timeouts[cur] = 1
  147.   else
  148.     timeouts[cur] = 0
  149.   end
  150.  
  151.   growTimes[cur] = growTime
  152.   growYields[cur] = growYield
  153.  
  154.   local n = math.min(total, trackMax)
  155.   local avgTime  = 0
  156.   local avgYield = 0
  157.   local numTimeouts = 0
  158.   for i = 1, n do
  159.     avgTime  = avgTime  + growTimes[i]
  160.     avgYield = avgYield + growYields[i]
  161.     numTimeouts = numTimeouts + timeouts[i]
  162.   end
  163.  
  164.   if avgTime ~= 0 then
  165.     avgTime  = avgTime / n
  166.   end
  167.  
  168.   if avgYield ~= 0 then
  169.     avgYield = avgYield / n
  170.   end
  171.  
  172.   local timeoutStr
  173.   if timedOut then
  174.     timeoutStr = "t"
  175.   else
  176.     timeoutStr = "h"
  177.   end
  178.  
  179.   -- %2.2f seems to be bugged??
  180.   println(string.format("%3i %s %1i %2i:%02i ~%2i %1i.%1i %2i:%02i, %i t",
  181.                         total,
  182.                         timeoutStr,
  183.                         growYield,
  184.                         growTime / 60,
  185.                         growTime % 60,
  186.                         n,
  187.                         avgYield,
  188.                         (avgYield * 10) % 10,
  189.                         avgTime / 60,
  190.                         avgTime % 60,
  191.                         numTimeouts))
  192. end
  193.  
  194. local lastPlant = os.clock()
  195. function sincePlantStr()
  196.   local time = os.clock() - lastPlant
  197.   return string.format("%2i:%02i", time / 60, time % 60)
  198. end
  199.  
  200. local timerID = nil
  201. function harvest()
  202.   local growYield = 0
  203.   local growTime  = 0
  204.   local dropTime  = 0
  205.  
  206.   growTime = os.clock() - lastPlant
  207.  
  208.   local time = os.clock()
  209.   -- Keep 1 spare for planting
  210.   while not dropFn(turtle.getItemCount(1) - 1) do
  211.     dropFail = true
  212.     dropTime = os.clock() - time
  213.     printover(string.format("Failed dropping crop %2i:%02i", dropTime / 60, dropTime % 60))
  214.     sleep(dropWait)
  215.     dropTime = os.clock() - time
  216.   end
  217.   term.clearLine()
  218.  
  219.   if not dropTime == 0 then
  220.     println(string.format("Waited %2i:%02i for space to drop", dropTime / 60, dropTime % 60))
  221.   end
  222.  
  223.   digFn()
  224.   placeFn()
  225.   lastPlant = os.clock()
  226.   timerID = os.startTimer(maxWait)
  227.  
  228.   growYield = turtle.getItemCount(1)
  229.  
  230.   return growYield, growTime, dropTime
  231. end
  232.  
  233. function main()
  234.   local firstYield = harvest()
  235.   println("Initial Yield " .. tostring(firstYield))
  236.  
  237.   local budCount = 0
  238.   while true do
  239.     local e, p1 = os.pullEvent()
  240.    
  241.     if e == "redstone" then
  242.       if redstone.getInput(budSide) then
  243.         budCount = budCount + 1
  244.         printover(sincePlantStr() .. " budCount " .. tostring(budCount))
  245.         if budCount >= growStates then
  246.           budCount = 0
  247.           local growYield, growTime, dropTime = harvest()
  248.           trackYields(growYield, growTime, dropTime, false)
  249.         end
  250.       end
  251.     end
  252.     if e == "timer" and timerID == p1 then
  253.       local growYield, growTime, dropTime = harvest()
  254.       trackYields(growYield, growTime, dropTime, true)
  255.     end
  256.   end
  257. end
  258.  
  259. main()
Advertisement
Add Comment
Please, Sign In to add comment