Advertisement
yesurbius

LUA - ComputerCraft Turtle Controller (Doesn't Work)

Apr 7th, 2013
189
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 12.21 KB | None | 0 0
  1. local fuelMatchSlot=16  -- Slot holding Fuel
  2. local fuelMin = 10      -- Fuel leverl to trigger refuel
  3. local fuelRefill = 50   -- Refuel to this amount
  4. local seedMatchSlot=15  -- Slot holding Seed to plant
  5.  
  6. -- Determine Mode and start coroutines
  7. function main( tArgs )
  8.   local fHandler
  9.   local cmds = ""
  10.   local coGo
  11.   local coFuel
  12.   local status
  13.   local yy
  14.  
  15.   -- Verify Command Line Arguments were correct
  16.   if #tArgs < 1 then
  17.     print( "Usage: work <routefile>     -or-" )
  18.     print( "       work <command> <command> ... etc    -or-")
  19.     print( "       work program")
  20.     return false
  21.   end
  22.  
  23.   if #tArgs == 2 and tArgs[1] == "program" then
  24.     interactiveMode(tArgs[2])
  25.     return
  26.   end
  27.     -- test if we have a filename or a command
  28.   if fs.exists(tArgs[1]) then
  29.     fileOrCmds = "file"
  30.   else
  31.     fileOrCmds = "cmds"
  32.   end
  33.  
  34.   -- Read in our command list from the file
  35.   if fileOrCmds == "file" then
  36.     if fs.exists(tArgs[1]) then
  37.       fHandler = fs.open(tArgs[1],"r")
  38.       if fHandler then
  39.         cmds = fHandler.readAll
  40.       end          
  41.     end
  42.   else -- Read in our commands from the command line
  43.     -- Convert from a table into a space separated list
  44.     for i,v in ipairs(tArgs) do
  45.       if cmds == "" then
  46.         cmds = v
  47.       else
  48.         cmds = cmds .. " " .. v
  49.       end
  50.     end
  51.   end
  52.  
  53.   -- Create our Coroutines
  54.   coGo = coroutine.create(go)
  55.   coFuel = coroutine.create(fuelManager)
  56.  
  57.   -- Continuously resume coroutines in sequence as they yield
  58.   while true do
  59.  
  60.     -- Start/Resume our Go coroutine
  61.     yy = coroutine.resume(coGo,cmds)
  62.     if yy == false then
  63.       print("Coroutine Go Reports error")
  64.       print("Status: " .. coroutine.status(coGo))
  65.     end
  66.     -- If the coroutine has terminated, then exit our loop
  67.     if coroutine.status(coGo) == "dead" then
  68.       break
  69.     end
  70.  
  71.     -- Start/Resume our Fuel coroutine
  72.     yy = coroutine.resume(coFuel)
  73.     if yy == false then
  74.       print("Coroutine Fuel Reports error")
  75.       print("Status: " .. coroutine.status(coFuel))
  76.     end
  77.     -- If the coroutine has terminated, then exit our loop
  78.     if coroutine.status(coFuel) == "dead" then
  79.       print("Out of Fuel")
  80.       break
  81.     end
  82.   end
  83.   return true
  84. end
  85.  
  86. -- Interactive Mode
  87. function interactiveMode(saveFile)
  88.   term.clear()
  89.   print("Welcome to Interactive Mode")
  90.   print("Instructions enter one command per line, followed by the enter key.")
  91.   print("The turtle will execute the instructions and the instructions will")
  92.   print("be recorded to the file '" .. saveFile .. "'.")
  93.   print("")
  94.   print("Enter the command 'end' to stop")
  95.   print("")
  96.   local fHandler = fs.open(saveFile,"a")
  97.   while true do
  98.     write("Command: ")
  99.     cmd = io.read()
  100.     if go(cmd) then
  101.       if string.lower(cmd) == "end" then
  102.         break
  103.       end
  104.       fHandler.writeLine(cmd)
  105.     end
  106.   end
  107.   fHandler.close()
  108. end
  109.  
  110. -- Checks fuel status on predictable intervals
  111. function fuelManager()
  112.   local currentFuelLevel = 0
  113.   local avgFuelConsumptionPerSecond = 1
  114.   local estFuelLife = 0
  115.    
  116.   --- Keep this function active continously
  117.   while true do
  118.     --- Assess current Fuel Level
  119.     currentFuelLevel = turtle.getFuelLevel()
  120.     ---   If fuel near Min level, then we need to refuel up to refuel level
  121.     if currentFuelLevel <= fuelMin then
  122.       return false
  123.     end
  124.     --- Calculate approximate time until earliest fuel low warning
  125.     estFuelLife = (currentFuelLevel * avgFuelConsumptionPerSecond)
  126.     --- Sleep for half that time (coroutine should yield here)
  127.     os.sleep(math.floor(estFuelLife/2))
  128.   end -- endless loop
  129. end
  130.  
  131. -- Processes a series of instructions
  132. function go(cmds)
  133.   local tArgs = { }
  134.   local cmd = ""
  135.   local nPos = 1
  136.   local nCmd = 1
  137.   local c = ""
  138.  
  139.   -- Convert List of cmds into a table
  140.   while nPos < #cmds do
  141.     c = string.sub(cmds,nPos,nPos)
  142.     if c == " " then
  143.       if cmd ~= "" then
  144.         tArgs[nCmd] = cmd
  145.         cmd = ""
  146.         nCmd = nCmd + 1
  147.       end
  148.     else
  149.       cmd = cmd .. c
  150.     end
  151.     nPos = nPos + 1
  152.   end
  153.   if cmd ~= "" then
  154.     tArgs[nCmd] = cmd
  155.   end
  156.    
  157.   -- If no commands were found in the table then exit
  158.   if #tArgs < 1 then
  159.     print("No arguments given to go")
  160.     return false
  161.   end
  162.  
  163.   -- These are our defined handlers.   Each handler is defined with a condition and an action.
  164.   -- before an action is executed, a condition must be met
  165.   -- successful actions, will deducated distance values.  
  166.   -- Failed conditions or actions will set distance to 0
  167.   local tHandlers = {
  168.         -- Forward, Back, Up, Down
  169.         ["F"] = { condition=function() return true end, action=turtle.forward },
  170.         ["B"] = { condition=function() return true end, action=turtle.back },
  171.         ["U"] = { condition=function() return true end, action=turtle.up },
  172.         ["D"] = { condition=function() return true end, action=turtle.down },
  173.         -- Left, Right
  174.         ["L"] = { condition=function() return true end, action=turtle.turnLeft },
  175.         ["R"] = { condition=function() return true end, action=turtle.turnRight },
  176.         -- Dig Over, Dig uNder
  177.         ["O"] = { condition=turtle.detect, action=turtle.digUp },
  178.         ["N"] = { condition=turtle.detect, action=turtle.digDown },
  179.         -- Plant, Eject
  180.         ["P"] = { condition=function() return not(turtle.detectDown()) end, action=plantSeed },
  181.         ["E"] = { condition=function() return true end, action=dropExtras }
  182.       }
  183.    
  184.   -- Iterate for each command present
  185.   local nArg = 1
  186.   local sCmd = ""
  187.   for nArg,sCmd in ipairs(tArgs) do
  188.     local nDistance = 1
  189.     -- Determine the Distance for the command
  190.     if #sCmd > 1 then
  191.       local num = tonumber(string.sub(sCmd, 2))
  192.       if num then
  193.         nDistance = num
  194.       else
  195.         nDistance = 1
  196.       end
  197.     else
  198.       nDistance = 1
  199.     end
  200.     sOperation = string.sub(sCmd,1,1)
  201.  
  202.     -- Use the function handler that corresponds with the command
  203.     local fnHandler = tHandlers[string.upper(sOperation)]
  204.     if fnHandler then
  205.       -- Set our condition and action functions
  206.       local condition = fnHandler["condition"]
  207.       local action = fnHandler["action"]
  208.       -- Repeat based on distance
  209.       while nDistance > 0 do
  210.         local status = false  -- whether condition and action both returned true
  211.         if condition() then
  212.           if action() then
  213.             status = true
  214.           end
  215.         else
  216.           status = true
  217.         end
  218.         -- If the action did not succeed, lets check some common reasons
  219.         if status == false then
  220.           -- Out of Fuel?
  221.           if turtle.getFuelLevel() == 0 then
  222.             print( "Out of fuel" )
  223.             return false
  224.           else
  225.             -- Best report his even though it may correct itself in half a second
  226.             print(string.upper(sOperation) .. " returned error")
  227.             sleep(0.5)
  228.           end
  229.         else  -- action DID succeed, so lets reduce distance
  230.           nDistance = nDistance - 1
  231.         end
  232.       end  -- while distance > 0
  233.     else  -- if there was no valid function handler found ...
  234.       print( "No such Handler: " .. string.upper(sOperation) )
  235.       return false
  236.     end
  237.   end -- Process Next Command
  238.   return true
  239. end
  240.  
  241. -- Finds a seed in our inventory and plants it
  242. -- Should be clear that there needs to be an empty block below in order to properly plant
  243. function plantSeed()
  244.   local slotNumber = 0
  245.   local itemCount = 0
  246.   local attempt = 0
  247.   local seedItem = false
  248.    
  249.   for slotNumber=1,16 do
  250.     -- There is a goto command in the new beta Lua .. cannot wait
  251.     local skipIt = false
  252.     while skipIt == false do
  253.       skipIt = true
  254.       if (slotNumber ~= fuelMatchSlot) and (slotNumber ~= seedMatchSlot) then
  255.         -- See if there is any items in the slot
  256.         itemCount = turtle.getItemCount(slotNumber)
  257.         if itemCount == 0 then
  258.           -- goto skipIt
  259.           break
  260.         end
  261.    
  262.         -- Select the Slot
  263.         while turtle.select(slotNumber) == false do
  264.           attempt = attempt + 1
  265.           if attempt == 3 then
  266.             print("Unable to Select Slot#" .. slotNumber)
  267.             return false
  268.           end
  269.           -- Lets wait - maybe it will clear up
  270.           -- We will only make 3 attemps though
  271.           sleep(5)
  272.         end
  273.    
  274.         -- Compare it to our seed slot
  275.         seedItem = turtle.compareTo(seedMatchSlot)
  276.         if not seedItem then
  277.           -- goto skipIt
  278.           break
  279.         end
  280.  
  281.         -- We found a seed item - lets plant it
  282.         if not turtle.placeDown() then
  283.           print("Could not place seed")
  284.           return false
  285.         end
  286.       end  -- slot <> seedslot condition
  287.     end -- while
  288.     -- ::skipit::
  289.   end  -- next slot number
  290.   return true
  291. end
  292.  
  293. -- Drops all items that are "extra"
  294. -- at the time of writing, that means anything not fuel or seed
  295. function dropExtras()
  296.   local slotNumber = 0
  297.   local keepItem = false
  298.   local itemCount = 0
  299.   local attempt = 0
  300.  
  301.   -- iterate through our slots
  302.   for slotNumber=1,16 do
  303.     -- Can remove these two lines when LUA gets a GOTO statement
  304.     local skipIt = false
  305.     while skipIt == false do
  306.       if (slotNumber ~= fuelMatchSlot) and (slotNumber ~= seedMatchSlot) then
  307.         -- See if there is any items in the slot    
  308.         itemCount = turtle.getItemCount(slotNumber)
  309.         if itemCount == 0 then
  310.           -- goto skipIt
  311.           break
  312.         end
  313.    
  314.         -- Select the Slot, give up after 3 attempts
  315.         while turtle.select(slotNumber) == false do
  316.           attempt = attempt + 1
  317.           if attempt == 3 then
  318.             print("Unable to Select Slot#" .. slotNumber)
  319.             return false
  320.           end
  321.           sleep(5)
  322.         end  
  323.            
  324.         -- Is it an extra?
  325.         keepItem = (turtle.compareTo(fuelMatchSlot) or turtle.compareTo(seedMatchSlot))
  326.         if keepItem then
  327.           -- goto skipIt
  328.           break
  329.         end
  330.  
  331.         -- We found an extra item - lets drop it
  332.         turtle.dropDown()
  333.       end  -- valid slot check
  334.     end  -- while loop
  335.     -- :: skipIt ::
  336.   end  -- next slot number
  337.   return true
  338. end
  339.  
  340. function reFuel()
  341.   local slotNumber = 0
  342.   local fuelItem = false
  343.   local itemCount = 0
  344.   local attempt = 0
  345.    
  346.   for slotNumber=1,16 do
  347.     -- Remove these two lines when LUA gets a goto statement
  348.     local skipIt = false
  349.     while skipIt == false do
  350.       skipIt = true
  351.       if not (slotNumber == fuelMatchSlot) then
  352.  
  353.         -- See if there is any items in the slot    
  354.         itemCount = turtle.getItemCount(slotNumber)
  355.         if itemCount == 0 then
  356.           -- goto skipIt
  357.           break
  358.         end
  359.  
  360.         -- Select the Slot
  361.         while turtle.select(slotNumber) == false do
  362.           attempt = attempt + 1
  363.           if attempt == 3 then
  364.             print("Unable to Select Slot#" .. slotNumber)
  365.             return false
  366.           end
  367.           sleep(5)
  368.         end    
  369.  
  370.         -- Compare it to our fuel slot
  371.         fuelItem = turtle.compareTo(fuelMatchSlot)
  372.         if not fuelItem then
  373.           break
  374.         end
  375.  
  376.         -- We found a fuel item - lets refuel to the refuel limit
  377.         while turtle.getFuelLevel() < fuelRefill do
  378.           -- Attempt to Refuel with one unit
  379.           attempt = 0
  380.           while turtle.refuel(1) == false do
  381.             attempt = attempt + 1
  382.             if attempt == 1 then
  383.               print("Unable to refuel from slot #" .. slotNumber)
  384.             end
  385.             if attempt == 3 then
  386.               break   -- give up on this slot
  387.             end
  388.             os.sleep(1)
  389.           end
  390.        
  391.           -- If this slot does not appear to refilling then skip the slot
  392.           if attempt == 3 then
  393.             break
  394.           end
  395.  
  396.           -- Keep refueling until we reach our refill level            
  397.         end  -- While Refueling
  398.       end  -- slot <> fuelslot condition
  399.       -- if we have refueled sufficiently, lets stop checking slots
  400.       if turtle.getFuelLevel() >= fuelRefill then
  401.         break
  402.       end
  403.     end  -- end while loop
  404.   end  -- next slot number
  405.        
  406.   -- Return Refuel success
  407.   if turtle.getFuelLevel() < fuelRefill then
  408.     return false
  409.   else
  410.     return true
  411.   end
  412. end
  413.  
  414. local tArgs = { ... }
  415.  
  416. main(tArgs)
  417.  
  418. print("Finished")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement