Advertisement
yesurbius

LUA - ComputerCraft Turtle Controller (Debugging Model)

Apr 14th, 2013
51
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 9.20 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.  
  7.  
  8. function main(cmds)
  9.  
  10.   local routines = {}
  11.   local eventdata = {}
  12.   local filter = {}
  13.   local status
  14.   local param
  15.   local n
  16.  
  17.   if #cmds == 1 and fs.exists(cmds[1]) then
  18.     local fileHandler = fs.open(cmds[1],"r")
  19.     if fileHandler then
  20.       local data = fileHandler.readAll()
  21.       cmds = { }
  22.       for k, v in string.gmatch(data,"%a%d+") do
  23.         table.insert(cmds,k)
  24.       end
  25.     end
  26.     fileHandler.close()
  27.   end    
  28.  
  29.   routines[1] = coroutine.create(go)
  30.   routines[2] = coroutine.create(fuelManager)
  31.   routines[3] = coroutine.create(refuel)
  32.  
  33.   os.queueEvent("fuelCheck")  
  34.   os.queueEvent("docmds", unpack(cmds))
  35.   while true do
  36.     for i,r in ipairs(routines) do
  37.       assert(r,"Routine #" .. i .. " does not exist")
  38.       if filter[r] == nil or filter[r] == eventdata[1] or eventdata[1] == "terminate" then
  39.         status, param = coroutine.resume(r, unpack(eventdata))
  40.         assert(status,"Main(): #" .. i .. ", " .. tostring(param))
  41.         filter[r] = param
  42.         if coroutine.status(r) == "dead" then
  43.           print("")
  44.           print("#" .. i .. ": Dead. status=" .. tostring(status) .. ", param=" .. tostring(param))
  45.           if i == 1 then
  46.             return i
  47.           end
  48.         end
  49.       end
  50.     end
  51.    
  52.     for i,r in ipairs(routines) do
  53.       if coroutine.status(r) == "dead" then
  54.         if i == 1 then
  55.           return i
  56.         end
  57.       end
  58.     end
  59.  
  60.     eventdata = { coroutine.yield() }
  61.   end
  62.  
  63. end
  64.  
  65. function go()
  66.  
  67.   -- Set up our Turtle Handlers
  68.   local TurtleHandlers = {
  69.     -- Forward, Back, Up, Down
  70.     ["F"] = { condition=function() return true end, action=turtle.forward },
  71.     ["B"] = { condition=function() return true end, action=turtle.back },
  72.     ["U"] = { condition=function() return true end, action=turtle.up },
  73.     ["D"] = { condition=function() return true end, action=turtle.down },
  74.     -- Left, Right
  75.     ["L"] = { condition=function() return true end, action=turtle.turnLeft },
  76.     ["R"] = { condition=function() return true end, action=turtle.turnRight },
  77.     -- Dig Over, Dig UNder
  78.     ["O"] = { condition=turtle.detect, action=turtle.digUp },
  79.     ["N"] = { condition=turtle.detect, action=turtle.digDown }
  80.     -- Plant, Eject
  81. --    ["P"] = { condition=function() return not(turtle.detectDown()) end, action=plantSeed },
  82. --    ["E"] = { condition=function() return true end, action=dropExtras }
  83.   }
  84.    
  85.   -- Set up Event Variables
  86.   local EventParams = { }
  87.   repeat
  88.     EventParams = { coroutine.yield("docmds") }
  89.     if EventParams[1] == "terminate" then
  90.       error("Terminated.during.go()", 0)
  91.     end
  92.   until EventParams[1] == "docmds"
  93.   local eventID = EventParams[1]
  94.   table.remove(EventParams,1)
  95.  
  96.  
  97.   -- Ensure this is the proper event starting us
  98.   if eventID == "docmds" then
  99.     write("(G)")
  100.     -- For each command, separate it into a command and a distance
  101.     for CommandNumber,CommandFull in ipairs(EventParams) do
  102.       --- Reset our Distance
  103.       local CommandDistanceRemaining = 1
  104.  
  105.       --- If the command is 2 or more letters long, lets separate the command from the distance
  106.       if #CommandFull > 1 then
  107.         -- Extract from position 2 onwards and convert text to a number
  108.         local tmpNum = tonumber(string.sub(CommandFull,2))
  109.         if tmpNum then
  110.           -- Set our distance value for this command
  111.           CommandDistanceRemaining = tmpNum
  112.         else
  113.           -- there was no distance value, so lets repeat only once
  114.           CommandDistanceRemaining = 1
  115.         end
  116.        
  117.         --- Extract our Command
  118.         CommandOperation = string.sub(CommandFull,1,1)
  119.  
  120.         --- Execute our Command
  121.         local FunctionHandler = TurtleHandlers[string.upper(CommandOperation)]
  122.         if FunctionHandler then
  123.           -- Set our condition and action functions
  124.           local condition = FunctionHandler["condition"]
  125.           local action    = FunctionHandler["action"]
  126.           -- Repeat based on distance
  127.           while CommandDistanceRemaining > 0 do
  128.             local cResult = condition()
  129.             if cResult and action() and (write(string.upper(CommandOperation))) then
  130.               CommandDistanceRemaining = CommandDistanceRemaining - 1
  131.             else
  132.               if cResult then
  133.                 return false
  134.               end
  135.             end
  136.           end -- Distance Countdown
  137.         else
  138.           -- No such Function Handler
  139.           error("No such Turtle Function Handler exists: " .. string.upper(CommandOperation))
  140.         end -- If FunctionHandler
  141.       end -- If 2-char command text
  142.     end -- For every command
  143.   end -- If the event is docmds
  144.   return true
  145. end
  146.  
  147.  
  148. function fuelManager()
  149.  
  150.   -- Set up Fuel Variables
  151.   local CFL = 0
  152.   local AFCPS = 1
  153.   local EFL = 0
  154.  
  155.   --- Set up Event Variables
  156.   local EventParams = { }
  157.  
  158.   repeat
  159.     EventParams = { coroutine.yield("fuelCheck") }
  160.     if EventParams[1] == "terminate" then
  161.       error("Terminated during fuelManager()",0)    
  162.     end
  163.   until EventParams[1] == "fuelCheck"
  164.  
  165.   local eventID = EventParams[1]
  166.   table.remove(EventParams,1)
  167.  
  168.   if eventID == "fuelCheck" then
  169.     write("(F)")
  170.     CFL = turtle.getFuelLevel()
  171.  
  172.     ---   Keep going until fuel is near the Min level
  173.     ---   then we need to refuel up to refuel level    
  174.     while CFL >= fuelMin do
  175.       --- Calculate approximate time until earliest fuel low warning
  176.       local EFL = CFL * AFCPS
  177.       --- Calculate half that time
  178.       EFL = math.floor(EFL / 2)
  179.       -- If our sleep time is less than 5 seconds, lets just exit for a refuel
  180.       if EFL < 5 then
  181.         os.queueEvent("refuel")
  182.         repeat
  183.           eventParams = { coroutine.yield("refueled") }
  184.           if eventParams[1] == "terminate" then
  185.             error("Terminated in WaitForRefuel()")
  186.           end
  187.         until eventParams[1] == "refueled"
  188.         eventID = eventParams[1]
  189.         table.remove(eventParams,1)
  190.       else
  191.         --- Sleep until next scheduled fuel check (coroutine should yield here)
  192.         os.sleep(EFL)
  193.       end
  194.     end
  195.   end
  196.  
  197. end
  198.  
  199. function refuel()
  200.  
  201.   -- Set up Local Variables
  202.   local slotNumber = 0
  203.   local fuelItem = false
  204.   local itemCount = 0
  205.   local attempt = 0
  206.  
  207.   -- Set up Event Variables
  208.   local EventParams = { }
  209.   repeat
  210.     EventParams = os.pullEvent("refuel")
  211.     if EventParams[1] == "terminate" then
  212.       error("Terminated in refuel()")
  213.     end
  214.   until EventParams[1] == "refuel"
  215.   local eventID = EventParams[1]
  216.   table.remove(EventParams,1)
  217.  
  218.   if eventID == "refuel" then
  219.     write("(R)")
  220.     for slotNumber=1,16 do
  221.       -- Remove these two lines when LUA gets a goto statement
  222.       local skipIt = false
  223.       while skipIt == false do
  224.         skipIt = true
  225.         if not (slotNumber == fuelMatchSlot) then
  226.  
  227.           -- See if there is any items in the slot    
  228.           itemCount = turtle.getItemCount(slotNumber)
  229.           if itemCount == 0 then
  230.             -- goto skipIt
  231.             break
  232.           end
  233.  
  234.           -- Select the Slot
  235.           while turtle.select(slotNumber) == false do
  236.             attempt = attempt + 1
  237.             if attempt == 3 then
  238.               print("Unable to Select Slot#" .. slotNumber)
  239.               return false
  240.             end
  241.             sleep(5)
  242.           end      
  243.  
  244.           -- Compare it to our fuel slot
  245.           fuelItem = turtle.compareTo(fuelMatchSlot)
  246.           if not fuelItem then
  247.             break
  248.           end
  249.  
  250.           -- We found a fuel item - lets refuel to the refuel limit
  251.           while turtle.getFuelLevel() < fuelRefill do
  252.             -- Attempt to Refuel with one unit
  253.             attempt = 0
  254.             while turtle.refuel(1) == false do
  255.               attempt = attempt + 1
  256.               if attempt == 1 then
  257.                 print("Unable to refuel from slot #" .. slotNumber)
  258.               end
  259.               if attempt == 3 then
  260.                 break   -- give up on this slot
  261.               end
  262.               os.sleep(1)
  263.             end
  264.          
  265.             -- If this slot does not appear to refilling then skip the slot
  266.             if attempt == 3 then
  267.               break
  268.             end
  269.  
  270.             -- Keep refueling until we reach our refill level              
  271.           end  -- While Refueling
  272.         end  -- slot <> fuelslot condition
  273.         -- if we have refueled sufficiently, lets stop checking slots
  274.         if turtle.getFuelLevel() >= fuelRefill then
  275.           break
  276.         end
  277.       end  -- end while loop
  278.     end  -- next slot number
  279.  
  280.     -- Return Refuel success
  281.     print("Exiting Refuel")
  282.     if turtle.getFuelLevel() < fuelRefill then
  283.       return false
  284.     else
  285.       os.queueEvent("refueled")
  286.       return true
  287.     end
  288.  
  289.   end  -- If its our Event
  290. end
  291.  
  292.  
  293.  
  294. local targs = { ... }
  295. local func = ""
  296. local i = 0
  297. local func = main(targs)
  298.  
  299. if func == 1 then
  300.   print("Commands Completed")
  301. elseif func == 2 then
  302.   print("Out of Gas")
  303. elseif func == 3 then
  304.   print("Unable to Refuel")
  305. else
  306.   print("Not sure what happened ... " .. tostring(func))
  307. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement