Advertisement
rdalkire

farm071

Jun 1st, 2014
255
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[ com.ape42.turtle.Farm 0.7.1
  2.   For computercraft 1.63
  3.   Farms X rows, trying to alternate
  4.      crops according to the reference
  5.      slots, which are the first
  6.      contiguous slots that have seeds.
  7.      If it doesn't have enough seed to
  8.      alternate,  it will leave a gap.
  9.      There are two globals constants -
  10.      to sleep GROW_WAIT minutes, and
  11.      repeat MAX_REPEATS or until out
  12.      of fuel.
  13.   @author R David Alkire, IGN ian_xw
  14.    
  15. Feature Changes by version:
  16.      0.1.0: Reaps one row.
  17.      0.2.0: Reaps & sows X rows, then
  18.       retrieves the harvest.
  19.      0.2.1: You now get a whole row of
  20.       a given plantable,if there are
  21.       enough seeds.
  22.      0.2.2: Better stoppage for out-of
  23.       -fuel or if blocked.
  24.      0.3.1: Sleeps and runs twice more
  25.      0.4.1: Tries to plant each row,
  26.       alternating crops if possible
  27.     0.5.0: After first harvest, it
  28.       finds fuel required per harvest.
  29.       If there isn't enough for the
  30.       next one it stops.
  31.     0.5.1: if it has to stop, it
  32.       shouldn't bother to sleep, so now
  33.       it doesn't.
  34.     0.6.1: No functional changes, but
  35.       beginning to refactor
  36.     0.7.1: Improved fuel-use. Now at
  37.       the end of each row it sees if
  38.       there's enough fuel to do another
  39.       row and make it back to base. If
  40.       not it goes back to the start
  41.       right away.
  42.       Added auto-refueling:  Slot 9.
  43.      
  44. TODO:
  45. - Estimate max field size plantable
  46.     for two harvests, given the fuel.
  47. - After run - Estimate how many more
  48.     runs & rows it'll be able to do
  49.     with current fuel level.
  50. - Change param meaning so that the
  51.   result is N rows, N blocks long
  52. - Add melon/pumpkin slots, handling.
  53. - Give more explicit usage instructions
  54. - Allow use of blockers instead of row
  55.     parameter.
  56. - Allow the turtle to start at right
  57.     corner, depending which way is
  58.     open.
  59. - Create a routine for automated field
  60.     creation, given flat grassy area,
  61.     a bucket and a source of water.
  62.  
  63. This work is licensed under the
  64.  Creative Commons Attribution 4.0
  65.  International License. To view a copy
  66.  of this license, visit
  67.  http://creativecommons.org/licenses/by/4.0/
  68.  or send a letter to Creative Commons,
  69.  444 Castro Street, Suite 900, Mountain
  70.  View, California, 94041, USA.
  71. ]]
  72.  
  73. -- The wait time between beginning of
  74. -- each harvest, in minutes.
  75. GROW_WAIT = 40
  76.  
  77. -- The number of times to farm the
  78. -- field, baring other constraints
  79. MAX_REPEATS = 3
  80.  
  81. -- Initial slots indicate what items
  82. -- the user deems plantable.
  83. local plntblCnt = 1
  84.  
  85. -- Initializes the Plantable Count.
  86. -- Called before any work is done, this
  87. -- finds the last populated inventory
  88. -- slot.  That and the ones below
  89. -- will be used as reference.
  90. -- @return plntblCnt
  91. local function initPlntblCnt()
  92.   local indx = 0
  93.   local isPlntbl = true
  94.   while isPlntbl and indx < 16 do
  95.     indx = indx + 1
  96.     turtle.select(indx)
  97.     isPlntbl= turtle.getItemCount()> 0
  98.   end
  99.   plntblCnt = indx - 1
  100.   return plntblCnt
  101. end
  102.  
  103. -- For the non - reference slots,
  104. -- find one that matches the
  105. -- currently selected and match that.
  106. -- Or return false.
  107. local function selectNonRefSlot()
  108.  
  109.   local s = plntblCnt + 1
  110.   local seedy = false
  111.   while s < 16 and seedy == false do
  112.     seedy = turtle.compareTo( s )
  113.     if seedy then
  114.       turtle.select(s)
  115.     end
  116.     s = s + 1
  117.   end --while
  118.   return seedy
  119. end
  120.  
  121. -- Decides what to plant based the
  122. --  reference slots (plntblCnt)
  123. -- @param rowIndex the current row
  124. -- @block block # within the row,
  125. --  starting with 1.
  126. -- @param prevRow an array of crop
  127. --  types for previous row
  128. local function sow( rowIndex, block,
  129.     prevRow )
  130.   local seedy = false
  131.  
  132.   -- Alternate among the plantables:
  133.   -- loop through reference slots.
  134.   local i = 0
  135.   local refSlt = 0
  136.   while i < plntblCnt and seedy == false do
  137.     --use what was for a given reference slot
  138.     refSlt = ( (rowIndex + i )% plntblCnt) + 1
  139.    
  140.     turtle.select(refSlt)
  141.     if turtle.getItemCount(refSlt) > 1 then
  142.       seedy = true
  143.     else
  144.       seedy = selectNonRefSlot()
  145.     end
  146.     i = i + 1
  147.   end
  148.  
  149.   if seedy then
  150.     if prevRow[block]== refSlt then
  151.       prevRow[block] = 0
  152.     else
  153.       prevRow[block] = refSlt
  154.       turtle.place()
  155.     end -- if matches
  156.   end -- if seedy
  157.  
  158.   return seedy
  159. end
  160.  
  161. -- Harvests a row: Digs (hoes) and
  162. -- moves forward the length or until
  163. -- the way is blocked
  164. -- @param lth the expected length of
  165. --  the row or 0 if not yet determined
  166. -- @return how long the row was, or
  167. --  0 if there was an unexpected stop
  168. --  due to fuel outage after first row.
  169. local function reapRow( lth )
  170.   print( "Reaping a row ")
  171.  
  172. -- Loop until length is reached or
  173. -- the way is blocked
  174.   local keepGoing = true
  175.   local placeR = 1
  176.  
  177. -- lth 0 just means that really
  178. -- the length is not yet determined
  179.   local firstRow = lth == 0
  180.   if firstRow then
  181.     local fuel = turtle.getFuelLevel()
  182.     lth = fuel/2 - 1
  183.     print(string.format("First row. "
  184.         .."fuel %d, max length %d",
  185.         fuel, lth))
  186.   end
  187.   while keepGoing do
  188.    
  189.     turtle.dig() -- reaps
  190.     keepGoing = turtle.forward()
  191.  
  192.     -- sees if it can keepGoing
  193.     if keepGoing then
  194.       placeR = placeR + 1
  195.       if placeR >= lth and lth > 0 then
  196.         keepGoing = false
  197.       end
  198.       -- prevents infinite loop
  199.       if placeR > 1023 then
  200.         keepGoing = false
  201.       end
  202.     else
  203.       if firstRow == false then
  204.         print("Stopped unexpectedly")
  205.         placeR = 0
  206.         print("placeR="..placeR)
  207.       end
  208.     end
  209.    
  210.   end -- while loop
  211.  
  212.   lth = placeR
  213.   return lth
  214. end
  215.  
  216. -- Backs up, tilling & planting
  217. -- @param lnth row length
  218. -- @param indx which row
  219. -- @param prevRow array of crop plantings
  220. --  for the previous row
  221. -- @return true if successful.  False
  222. --  means seeds or fuel ran out, or
  223. --  there was a blockage.
  224. local function sowRow(lnth, indx, prevRow)
  225.         print( "Sowing a row." )
  226.   local block = 1
  227.   local seedy = true
  228.  
  229.   -- while it has length & seeds
  230.   while block < lnth and seedy do
  231.    
  232.     seedy = turtle.back()
  233.     turtle.dig()
  234.  
  235.     -- if there are still seeds
  236.     if seedy then
  237.       seedy = sow(indx, block, prevRow)
  238.     else
  239.         print("sowRow(): seedy== false" )
  240.     end
  241.     block = block + 1
  242.   end
  243.  
  244.   -- return if there's seeds still.
  245.   return seedy
  246.  
  247. end
  248.  
  249. -- Determines whether there's enough
  250. -- fuel to: move to another row,
  251. -- reap it, sow it, and return to
  252. -- base
  253. -- @param rowIndex, rowLength
  254. local function isFuelOKForNextRow(
  255.     rowIndex, rowLength)
  256.  
  257.   local fuelNeed = 1 + rowIndex
  258.       + ( rowLength * 2 )
  259.  
  260.   local fuelLevel = turtle.getFuelLevel()
  261.  
  262.   local isEnough= fuelLevel >= fuelNeed
  263.   if isEnough ~= true then
  264.     print("Not enough fuel for next "
  265.         .."row and return trip.")
  266.     print( string.format(
  267.         "fuelNeed %d, rowIndex %d, "
  268.         .."rowLength %d", fuelNeed,
  269.         rowIndex, rowLength ) )
  270.        
  271.     print( string.format( "fuelLevel %d",
  272.         fuelLevel ) )
  273.    
  274.   end
  275.  
  276.   return isEnough
  277.  
  278. end
  279.  
  280. -- Checks fuel, and if good, moves to
  281. --    next row, reaps and sows.
  282. -- @param rowLength, isFirst, prevRow,
  283. --    rowIndex.
  284. --    prevRow is array of ints, each
  285. --    a reference item slot, from, you
  286. --    guessed it: the previous row.
  287. -- @return isFuelOK, rowLength, isSeedy
  288. local function moveOnAndDoOne( rowLength,
  289.     isFirst, prevRow, rowIndex )
  290.  
  291.   local isFuelOK = true
  292.  
  293.   -- After the first row
  294.   if isFirst == false then
  295.  
  296.     isFuelOK = isFuelOKForNextRow(rowIndex,
  297.         rowLength)
  298.    
  299.     if isFuelOK then
  300.       -- Move to the next row
  301.       turtle.turnRight()
  302.       turtle.forward()
  303.       turtle.turnLeft()
  304.     end
  305.    
  306.   end -- if after first
  307.  
  308.   local isSeedy = true
  309.   if isFuelOK then
  310.     rowLength= reapRow( rowLength )
  311.     if isFirst then
  312.       -- initializes previous array
  313.       for i = 1, rowLength do
  314.         prevRow[i] = 0
  315.       end
  316.     end
  317.    
  318.     if rowLength > 0 then
  319.       isSeedy=sowRow( rowLength, rowIndex, prevRow)
  320.       -- if stopped, zeroes-out.
  321.       rowLength= isSeedy and rowLength or 0
  322.     end -- if rowLength
  323.    
  324.   end -- if fuel OK
  325.  
  326.   return isFuelOK, rowLength, isSeedy
  327.  
  328. end
  329.  
  330. -- Harvests and plants the rows
  331. -- @param rows number of plantable rows
  332. -- @return number of rows planted.
  333. --  If stopped unexpectedly this will
  334. --  be 0.
  335. local function reapAndSow( rows )
  336.   print("beginning reapAndSow()")
  337.   -- Find out how many slots are for
  338.   -- reference.
  339.   local plntbl = initPlntblCnt()
  340.  
  341.   print("The first "..plntbl..
  342.     " slots \nare deemed plantable")
  343.  
  344.   local prevRow = {}
  345.   print("rows = ".. rows)
  346.   local rowLength = 0
  347.   local rowIndex = 0
  348.   local isSeedy = true
  349.   local isFuelOK = true
  350.   local isFirst = true
  351.  
  352.   while (rowIndex< rows) and isSeedy
  353.       and isFuelOK do
  354.     print( "rowIndex ".. rowIndex )
  355.    
  356.     -- If there was an unexpected
  357.     -- stop in previous row, then
  358.     -- rowLength will be its initial
  359.     -- value, 0
  360.     if rowLength<= 0 and isFirst== false then  
  361.       -- Stops loop
  362.       isSeedy = false
  363.     else
  364.      
  365.       isFuelOK, rowLength, isSeedy =
  366.           moveOnAndDoOne(rowLength,
  367.               isFirst, prevRow,
  368.               rowIndex )
  369.      
  370.       print( string.format(  
  371.           "in farm(), after "
  372.           .."moveOnAndDoOne( rowLength %d, "
  373.           .."isFirst %s, rowIndex %d)",
  374.           rowLength, tostring(isFirst),
  375.           rowIndex ) )
  376.      
  377.       print( string.format(
  378.           "Which returned isFuelOK %s, "
  379.           .."rowLength %d, isSeedy %s",
  380.           tostring( isFuelOK ), rowLength,
  381.           tostring(isSeedy) ) )
  382.      
  383.     end -- if rowLength > 0 & not first
  384.    
  385.     isFirst = false
  386.     rowIndex = rowIndex + 1
  387.    
  388.   end -- while rows & isSeedy
  389.  
  390.   -- The number of rows traversed
  391.   -- or 0 if unexpected problem
  392.   local rtrnVal = 0
  393.   if rowLength > 0 then
  394.     -- If fuel was too low, it did not
  395.     -- move to next row, so therefore
  396.     -- its row is one less than otherwise
  397.     rtrnVal = isFuelOK and rowIndex or rowIndex - 1
  398.   else
  399.     rtrnVal = 0
  400.   end
  401.  
  402.   return rtrnVal
  403.  
  404. end
  405.  
  406. -- Returns to the start and drops all
  407. -- inventory except one of each
  408. -- reference item. (It's assumed there
  409. -- are hoppers & a chest.)
  410. -- @param rows how many rows are
  411. --  planted.
  412. -- @return true if successful. False
  413. --  means there was blockage or fuel
  414. --  outage.
  415. local function returnAndStore(rows)
  416.   print( "Returning to the start.")
  417.  
  418.   turtle.turnLeft()
  419.   local canGo = true
  420.   local forwards = (rows - 1)
  421.   local stp = 1
  422.   while (stp <= forwards) and canGo do
  423.     canGo = turtle.forward()
  424.     stp = stp + 1
  425.   end
  426.  
  427.   turtle.turnLeft()
  428.  
  429.   if canGo then
  430.     for i = 16, 1, -1 do
  431.       turtle.select(i)
  432.       if i > plntblCnt then
  433.         turtle.drop()
  434.       else
  435.         turtle.drop(
  436.             turtle.getItemCount(i)- 1)
  437.       end
  438.     end
  439.   else
  440.     print( string.format(
  441.         "returnAndStore(rows) "
  442.         .."couldn't store.  rows %d, "
  443.         .."forwards %d", rows, forwards ))
  444.   end --canGo
  445.   turtle.turnLeft()
  446.   turtle.turnLeft()
  447.   return canGo
  448. end
  449.  
  450. -- Farms the field repeatedly up to
  451. -- MAX_REPEATS, or the fuel runs out,
  452. -- or there's some unexpected stop.
  453. -- @param rowCntFromUsr is the number
  454. -- of rows to farm, according to user
  455. local function farm( rowCntFromUsr )
  456.  
  457.     --[[ Start ]]
  458.     -- three times, if enough fuel
  459.     local n = 1
  460.     local okSoFar = true
  461.     while n<= MAX_REPEATS and okSoFar do
  462.       local startTime = os.clock();
  463.       turtle.select(9)
  464.       turtle.refuel()
  465.       local fuelStart = turtle.getFuelLevel()
  466.       print("fuelStart = ".. fuelStart)
  467.       local rowsDone = reapAndSow( rowCntFromUsr )
  468.       okSoFar = returnAndStore(rowsDone)
  469.       if rowsDone == rowCntFromUsr then
  470.         if okSoFar then
  471.        
  472.           local fuelLevel = turtle.getFuelLevel()
  473.          
  474.           print("after harvest: "..(n)
  475.               .." of ".. MAX_REPEATS)
  476.              
  477.           print("fuelLevel ".. fuelLevel)
  478.           local fuelPerTurn = (fuelStart-fuelLevel)
  479.           print( "fuelPerTurn ".. fuelPerTurn )
  480.           if fuelLevel< fuelPerTurn and n < MAX_REPEATS then
  481.             print("Next harvest will be partial,")
  482.             print("unless enough more fuel is added.")
  483.             print("Use slot 9 (first slot of 3rd row).")
  484.           end
  485.           local endTime = os.clock()
  486.           local duration = endTime - startTime
  487.           local waitTime = ( GROW_WAIT*60)-duration
  488.           local nextTime = endTime+ waitTime
  489.           if (n < MAX_REPEATS) and okSoFar then
  490.             os.sleep(waitTime)
  491.           end
  492.         end --okSofar
  493.       else
  494.         okSoFar = false
  495.       end
  496.       n = n + 1
  497.     end -- of MAX_REPEATS loop
  498.    
  499.     if okSoFar == false then
  500.       print("Stopped.")
  501.     end
  502.  
  503. end
  504.  
  505. local function main( tArgs )
  506.   local rowCntFromUsr = 0
  507.  
  508.   --[[ If user supplies a good number,
  509.   this uses it as row count.  If user
  510.   supplied a bad argument, it indicates.
  511.   ]]
  512.   local argCount = table.getn(tArgs)
  513.   local badArg = false
  514.   local badArgMsg = "Argument OK"
  515.   if argCount > 0 then
  516.     rowCntFromUsr = tArgs[1]
  517.     if tonumber(rowCntFromUsr)==nil then
  518.       badArg = true
  519.       badArgMsg = "Argument not a number"
  520.     else
  521.       rowCntFromUsr = tonumber(rowCntFromUsr)
  522.     end
  523.    
  524.   else
  525.     badArg = true
  526.     badArgMsg = "Supply how many rows"
  527.   end
  528.    
  529.   if badArg then
  530.     print( badArgMsg )
  531.     print("Put at least 1 of something" )
  532.     print(" plantable in first few slots.")
  533.   else
  534.     farm( rowCntFromUsr )
  535.   end
  536.  
  537. end
  538.  
  539. local tArgs = {...}
  540. main(tArgs)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement