Jump to content


Yesurbius's Content

There have been 13 items by Yesurbius (Search limited from 10-February 22)


By content type

See this member's

Sort by                Order  

#109330 [lua][coroutine][noerror] Having trouble debugging my coroutine implementation

Posted by Yesurbius on 12 April 2013 - 06:11 PM in Ask a Pro

Well - I think its safe to say I have it figured out. My program is working flawlessly, even with the sleep calls in the coroutines (which was causing issues before). I also managed to remove the tablify altogether and streamline the code a tad.

Note I use the assert(param1,param2)as shorthand for writing if <param1> == false then error(param2) end

When I get some time I'll modify my original program in this style. This was the first turtle program I wanted to make, to learn coroutines. My real project is a turtle autorun to upload arbitrary programs to the turtle... which I think I am in a better position to tackle now.

Thanks for the help,

function main(cmds)

  local routines = {}
  local eventdata = {}
  local filter = {}
  local status
  local n

  routines[1] = coroutine.create(go)
  routines[2] = coroutine.create(fuelManager)

  while true do
	for i,r in ipairs(routines) do
	  if filter[r] == nil or filter[r] == eventdata[1] or eventdata[1] == "terminate" then
		status, param = coroutine.resume(r, unpack(eventdata))
		assert(status,paraam)
		filter[r] = param
		if coroutine.status(r) == "dead" then
		  return i
		end
	  end
	end

	for i,r in ipairs(routines) do
	  if coroutine.status(r) == "dead" then
		return i
	  end
	end

	os.queueEvent("docmds", unpack(cmds))
	eventdata = { coroutine.yield() }
  end

end

function go()
  local tcmds = { }
  tcmds = { coroutine.yield("docmds") }
  local eventID = tcmds[1]
  table.remove(tcmds,1)
  if eventID == "docmds" then
	for i,v in ipairs(tcmds) do
	   print(v)
	   sleep(1)
	end
  end
end

function fuelManager()
  FuelOnHand = 40
  while FuelOnHand > 10 do
	FuelOnHand = FuelOnHand - 5
	print("Fuel: " .. FuelOnHand)
	sleep(1)
  end
end

local targs = { ... }
local func = ""
local i = 0
local func = main(targs)

if func == 1 then
  print("Commands Completed")
elseif func == 2 then
  print("Out of Gas")
else
  print("Not sure what happened ... " .. func)
end



#109252 [lua][coroutine][noerror] Having trouble debugging my coroutine implementation

Posted by Yesurbius on 12 April 2013 - 12:23 PM in Ask a Pro

Actually I was implying that given the way the event system is set up - you don't need to pass parameters in to the coroutine via the resume - you can pass it in to the coroutine via queueEvent (assuming you are setting your coroutine up to respond to events)

As for reading your posts - I can assure you I am reading them multiple times . I appreciate the time you are spending trying to answer my questions - it is far more than I expected to receive. I have gotten different pieces mixed up in my head at times however .. For example - we were using the count function as an example and I kind of thought that coroutines would be returning values everytime they yield. While its true that they can .. it was complicating the issue .. that's why I went back to the original example .. which actually has a need for a dedicated event system.

As for my code - does it look like I finally got the concept or is it also wrong? The code isn't working but I'm hoping its syntax error or a bug - and not my design.



#109015 [lua][coroutine][noerror] Having trouble debugging my coroutine implementation

Posted by Yesurbius on 11 April 2013 - 08:25 PM in Ask a Pro

Believe it or not - I was lying awake in bed and this was bugging me LOL

But I realized a few things. First off .. I was thinking that when we are calling resume - we are calling the function itself... Not the case ... we are restarting the execution of the thread within the function - so the parameters of the function don't matter at all to resuming...

So then I realized that it wouldn't matter if a queueEvent was placed within the main control loop - because that would simply ensure that our task is getting its share of attention from computercraft...

So I hammered out a quick version of my original program ... from scratch ... I'ts hanging up in Go .. which is frustrating .. I'll figure out what's causing that .. but looking beyond the syntactical substance .. is this the type of design I'm looking to achieve for my purpose?

function main(cmds)

  local routines = {}
  local eventdata = {}
  local filter = {}
  local status
  local n

  routines[1] = coroutine.create(go)
  routines[2] = coroutine.create(fuelManager)

  while true do
    for i=1,#routines do
      r = routines[i]
      if filter[r] == nil or filter[r] == eventdata[1] or eventdata[1] == "terminate" then
        status, param = coroutine.resume(r, unpack(eventdata))
        assert(status,param)
        if coroutine.status(r) == "dead" then
          return i
        end
        filter[r] = param
      end
    end

    for i=1,#routines do
      r = routines[i]
      if coroutine.status(r) == "dead" then
        return i
      end
    end

    os.queueEvent("docmds",unpack(cmds))
    eventdata = { coroutine.yield() }
  end

end

function go()
  local tcmds = { }
  local eventID, cmds = coroutine.yield("docmds")
  tcmds = tablify(cmds)
  print("event: " .. eventID)
  -- its hanging here - not sure why.
  for i=1,#tcmds do
    print(i .. ". " .. tcmds[i])
  end
  if eventID == "docmds" then
    for i=1,#cmds do
      print(cmds[i])
      sleep(1)
    end
  end
end

function fuelManager()
  FuelOnHand = 40
  while FuelOnHand > 10 do
    sleep(1)
    FuelOnHand = FuelOnHand - 5
  end
end

function tablify(strSeq)
  local retValue = {}
  local nCurrMatchPos = 0
  local nLastMatchPos = 0
  while true do
   nCurrMatchPos = string.find(strSeq, " ", nLastMatchPos + 1)
   if nCurrMatchPos then
     s = string.sub(strSeq,nLastMatchPos+1,nCurrMatchPos-1)
     if s ~= "" then
       table.insert(retValue,s)
       nLastMatchPos = nCurrMatchPos
     end     
   else
     break
   end
  end
  return retValue
end

local targs = { ... }
local func = ""
local i = 0
local func = main(targs)

if func == 1 then
  print("Commands Completed")
elseif func == 2 then
  print("Out of Gas")
else
  print("Not sure what happened ... " .. func)
end

Does it look like I finally figured this out? (despite not having a working version? LOL Only reason I'm posting it unfinished is because its 1:30am and I work at 6am LOL)

As a side note - maybe there is an easier way to get rid of tablify ..



#108990 [lua][coroutine][noerror] Having trouble debugging my coroutine implementation

Posted by Yesurbius on 11 April 2013 - 05:36 PM in Ask a Pro

Man I don't get this at all. Shouldn't be that hard . I get the concepts - I'm just not sure how they can be used.

I read that ...
coroutine.yield will pass its parameters as the return value for resume
similarily, resume's parameters will be the return value for yield.

That cleared up some of the questions.

I'm struggling with the parameters right now.

The program I posted in the very beginning.

There is two routines: go and fuelManager.

Go needs a list of cmds in order to do its thing. Fuelmanager and go are both coroutines because they both need to run at the same time.

So in my main function - if I set up a coroutine manager .. its going to essentially pull an event from os.pullEvent() .. and if any of my managed coroutines are looking for that pulled event, it'll resume the coroutine.
Similarly, each coroutine will do its thing - and return when its pausing waiting for something to be done.

In the case of Go - the yields are going to be from turtle movements.
In the case of FuelManager - the yields are going to be from the sleep (and maybe the refuel - not sure)
So both coroutines are spending a lot of time yielding back .. and everything's all happy and merry until either Go or FuelManager exit .. then we're done - show's over.

The problem is .. how do you start the function? It needs a variable passed to it ... a list of turtle commands.
You said that all coroutines should treat parameters passed to them as events they are receiving. So that would mean that they are resumed always with coroutine.resume(r,unpack(eventdata)). And eventdata always contains events .. so there is no piggybacking parameters in on that. Do I use a global variable?

I could us os.queueEvent() but I can't call that until after the first iteration of the coroutine manager runs .. and it has to be called from outside the loop - otherwise it'll repeat nonstop.



#108746 [lua][coroutine][noerror] Having trouble debugging my coroutine implementation

Posted by Yesurbius on 11 April 2013 - 04:12 AM in Ask a Pro

Thank you for the clear explanation Lyqyd.

So to attempt to answer my own question. If you need to pass parameters to a coroutine, its suggested (for the sake of making life easy) to design the coroutine to respond to one or more event, and pass the arguments in as parameters to an event.

Lets see if I got it through my head yet ... (forgive me if my code is wrong - I'm at work where I cannot test it)

function count(eventID, StartingValue, IterateAmount, IterateCount )
  local currentValue = StartingValue
  local iterations = 0
  while true do
	if eventID == "terminate" then
	  break
	end
	if eventID="iterate" then
	  currentValue = currentValue + IterateAmount
	  iterations = iterations + 1
	  if iterations => IterateCount then
		return
	  end
	  coroutine.yield(eventID, currentValue)
	end
  end
end

local coIter = courtine.create(count)
local eventdata = {}
os.queueEvent("iterate",10,5,5)
while true do
  if (filter == nil) or (filter == eventdata[1]) or (eventdata[1] == "terminate") then
  status, value = coroutine.resume(coIter, eventdata)
  assert(status,value)
  filter = value
  if coroutine.status == "dead" then
	break
  end
  eventdata = { os.pullEventRaw() }
end

Did I finally wrap my head around it?


If I did then I'll take a stab next at adding a 1 second os.sleep() call into my coroutine. Is the source code for os.sleep() available anywhere?

Thanks



#108607 [lua][coroutine][noerror] Having trouble debugging my coroutine implementation

Posted by Yesurbius on 10 April 2013 - 05:27 PM in Ask a Pro

I'm trying hard to wrap my head around this I swear. LOL

Am I correct in saying:
The Lua coroutines functions (outside ComputerCraft) can pass arguments to the coroutines by indicating a parameter to resume()....
... however .. in order to make computercraft work - those arguments must be event messages if your coroutine calls any computercraft function calls that have a yield in them (which I will guess is most).

So ... is it even possible to pass your own arguments?

function A(MyArg)
  for i=1,5 do
	coroutine.yield(i .. ". " .. MyArg)
  end
end

local coA = coroutine.create(A)

while true do
  status, value = coroutine.resume(coA,"Test")
  if not status then
	break
  end
  if coroutine.status(coA) == "dead" then
	break
  end
  print(value)
end

Produces:
1. Test
2. Test
3. Test
4. Test
5. Test

That works as expected. But if I add a sleep command in there...

  function A(MyArg)
	for i=1,5 do
	  coroutine.yield(i .. ". " .. MyArg)
	  os.sleep(1)
	end
  end

it continuously repeats "Timer"

If I understand it correctly - its because the sleep command itself starts a timer event.
So I'm stuck here - not sure how you can handle the yield from the sleep command

Would it be possible to handle the sleep event explicitly?
if value == "timer" then
  // Pass on the Timer value somehow to computercraft
end


I must be missing something else too ... because ..

courtine.resume takes at least one argument which is the coroutine thread. The subsequent arguments are arguments passed on to the thread.

Even in the parallel API snippet I posted earlier ... I don't understand it - because you are at no time defining parameters for the parallel coroutines .. so the parallel coroutine functions you pass will not have any parameters ... and yet .. the resume call is passing unpack(eventdata) ...

Is there a filter somewhere in there? Although I see TFilters in the code - I don't see any code that would intercept and wrap the user-supplied coroutine passed to the parallel API. Therefore I don't see where the user-supplied coroutine can accept the unpack(eventdata) parameters ..

My head hurts LOL



#108357 [lua][coroutine][noerror] Having trouble debugging my coroutine implementation

Posted by Yesurbius on 10 April 2013 - 02:33 AM in Ask a Pro

I'm just out the door to work now ... but I'm going to read up on this page (http://www.lua.org/pil/9.2.html) and see if I can wrap my head around what filters are.

What kind of events would pass through our little app? Timer? KeyStroke .. RedNetMessage received? etc?



#108199 [lua][coroutine][noerror] Having trouble debugging my coroutine implementation

Posted by Yesurbius on 09 April 2013 - 05:33 PM in Ask a Pro

View PostJokerRH, on 09 April 2013 - 08:53 AM, said:

-- Best report his even though it may correct itself in half a second
print(string.upper(sOperation) .. " returned error")
sleep(0.5)
[In function go]

-- Start/Resume our Go coroutine
yy = coroutine.resume(coGo,cmds)

sleep yields until it gets it's timer event. However, you resume it with cmd

Edit: same with refuel()

Hmm this may be an ah-ha moment ... consider the simplified example:

function A()
  print("Hello")
  sleep(5)
  print("World")
end

function B()
  sleep(3)
  print("Cruel")
  sleep(5)
end

local coA = coroutine.create(A)
local coB = coroutine.create(B)/>

while true do
  coroutine.resume(coA)
  coroutine.resume(coB)
  if coroutine.status(coA) == "dead" or coroutine.status(coB) == "dead" then
	break
  end
end

How I imagined it would work is
  • it would create the two coroutines .. with coroutine.create
  • it would resume (or start) the first coroutine (-A-). .. and print "Hello", then going to sleep
  • When A sleeps, the Sleep() function would yield, passing control back to the main function
  • it would resume (or start) the second coroutine (-B-)
  • when B sleeps, the Sleep() function would yield, passing control back to the main function.
  • The while loop repeats again and again.
  • Eventually coroutine B's sleep() would finish first (only 3 seconds) .. and print "Cruel" ... then sleep
  • Finally, the sleep routine from coroutine A would hit 5 seconds - print "World" and then terminate ..
  • .. thus ending the program.
If I'm understanding you correctly .. when sleep() yields .. its sending back some sort of timer event parameters .. that we need to do something with ... otherwise when we resume .. it just yields again .. with no timer progression?

Am I close to being on the right track?



#108191 [lua][coroutine][noerror] Having trouble debugging my coroutine implementation

Posted by Yesurbius on 09 April 2013 - 05:17 PM in Ask a Pro

As I eluded to - my coroutines were probably dead wrong. My understanding was that resume runs a function until that function yields - plain and simple.


View PostPixelToast, on 09 April 2013 - 05:43 AM, said:

look at the parallel API, how it yeilds and passes it to the routines
you want to do something like that

I took a look at the parallel API - while the code makes sense - I don't understand what its doing. So maybe you can help me with that. Lets take it from the top.

From the Wiki, the two functions for programs to call are:

parallel.waitForAny(function1, function2, ...) Runs all the functions at the same time, and stops when any of them returns.
parallel.waitForAll(function1, function2, ...) Runs all the functions at the same time, and stops when all of them have returned.

I'm going to add some comments into the code in a (failed) effort to make sense of it. Maybe you can help explain the code. I added the quotes into the lua comments so the forum highlights the comments easier.

parallel API
-- 'Calls itself recursively, with each invocation returning one more coroutine than the last'
-- 'When the end is reached, it returns nil'
local function create( first, ... )
  if first ~= nil then
	return coroutine.create(first), create( ... )
  end
  return nil
end

-- 'Not fully sure ..'
local function runUntilLimit( _routines, _limit )
  local count = #_routines
  local living = count
  local tFilters = {}
  local eventData = {}
  while true do

	for n=1,count do
	  local r = _routines[n]
	  if r then
	   -- 'Not sure what we are checking here:'
		if tFilters[r] == nil or tFilters[r] == eventData[1] or eventData[1] == "terminate" then
		  -- 'The yield from r will return two parameters (ok, parm).'
		  -- 'I am guessing OK is an indicator if the coroutine exited fine.'
		  -- 'not sure what param is'
		  local ok, param = coroutine.resume( r, unpack(eventData) )  -- 'unpack() converts the eventData array into individual arguments'
		  if not ok then
			error( param )  -- returns an error if not OK.
							-- 'from my reading on error() it seems this is the same as: assert(ok,param)'
		  else
			tFilters[r] = param  -- 'not sure - need to know what param is to understand what tFilters is.'
		  end
		  -- 'if the coroutine has exited on its own .. then neutralize the coroutine from the coroutine array'
		  -- 'Reduce the counter variable for the number of active coroutines ..'
		  -- 'If we hit our limit then return which coroutine index stopped'
		  if coroutine.status( r ) == "dead" then
			_routines[n] = nil
			living = living - 1
			if living <= _limit then
			  return n
			end
		  end
		end
	  end
	end

	-- 'looks like this runs through all the coroutines and cleans them up if they are dead.'
	for n=1,count do
	  local r = _routines[n]
	  if r and coroutine.status( r ) == "dead" then
		_routines[n] = nil
		living = living - 1
		if living <= _limit then
		  return n
		end
	  end
	end

	-- 'No idea what this does.'
	eventData = { os.pullEventRaw() }
  end
end

-- 'Uses the create() function recursively to build an array of coroutines.'
-- 'It then runs the coroutines until any one of them terminates.'
function waitForAny( ... )
  local routines = { create( ... ) }  
  return runUntilLimit( routines, #routines - 1 )
end

-- 'Uses the create() function recursively to build an array of coroutines.'
-- 'It then runs the coroutines until all terminate.'
function waitForAll( ... )
  local routines = { create( ... ) }
  runUntilLimit( routines, 0 )
end



#107956 Checking turtle fuel level

Posted by Yesurbius on 09 April 2013 - 04:04 AM in Ask a Pro

Whilst mining, a turtle will no doubt encounter coal.

What I usually do is put coal into a specific slot of the turtle, and then when the fuel gets below a threshold "Min Fuel Reserve Level", it scans the turtle's inventory for coal and refuels (1 unit at a time) until we hit a "Full Tank Level".

If it finds no fuel in the inventory, it'll go home.



#107603 Registration Issue on Website

Posted by Yesurbius on 08 April 2013 - 09:26 AM in Bugs

I just tried it now and its working. When I was registering it continuously brought me back to the same form saying I must check the terms of service box. Its now displaying the popup correctly.



#107592 [lua][coroutine][noerror] Having trouble debugging my coroutine implementation

Posted by Yesurbius on 08 April 2013 - 08:58 AM in Ask a Pro

The problem: I have two coroutines created. I have a while loop that resumes them sequentially again and again. When tested without coroutines (calling each function directly) it works. When coroutines are active, both functions will yield (one with a turtle command, one with sleep) but the turtle command (when completed) doesn't resume execution. The turtle ends up powering off. I've tested and the coroutine while loop is looping - the coroutines ARE being resumed. I see the turtle do only the first command then it hangs.

My suspicion: I'm probably using the coroutines dead wrong. I apologize - I am learning. I've checked the lua tutorials on coroutine .. I think I understand the single-thread concept... I think I understand yield - but I haven't used it in my program because I assume sleep and turtle movements yield until completed (which I've concluded on my own during troubleshooting)

What is my application? My application is a replacement for the go application. I call it 'work'. Calling work f10 r2 f10 will cause the turtle to go forward 10, right 2 turns then forward 10 again. Alternative it can read the commands from a text file (although I haven't tested this functionality). Once I get it working I also plan to have an interactive "training" mode where I can input the commands one at a time and it'll record them to a text file. The aim is to walk a turtle through a process once (ie. tilling the field) .. then be able to recall and re-execute that process anytime in the future.

Other thoughts: I realize that one solution is to simply remove the coroutines and manually check for fuel - I can do that for sure, but I'd like to learn why its failing under this design. Also I am running ComputerCraft 1.5.2 on a Minecraft 1.5.1 server (which is running on an Ubuntu box in my livingroom) Other than the default Forge mods and ComputerCraft, no other mods are installed.

The Code: (Pastebin Link)
local fuelMatchSlot=16  -- Slot holding Fuel
local fuelMin = 10	  -- Fuel leverl to trigger refuel
local fuelRefill = 50   -- Refuel to this amount
local seedMatchSlot=15  -- Slot holding Seed to plant

-- Determine Mode and start coroutines
function main( tArgs )
  local fHandler
  local cmds = ""
  local coGo
  local coFuel
  local status
  local yy

  -- Verify Command Line Arguments were correct
  if #tArgs < 1 then
	print( "Usage: work <routefile>	 -or-" )
	print( "	   work <command> <command> ... etc	-or-")
	print( "	   work program")
	return false
  end

  if #tArgs == 2 and tArgs[1] == "program" then
	interactiveMode(tArgs[2])
	return
  end
	-- test if we have a filename or a command
  if fs.exists(tArgs[1]) then
	fileOrCmds = "file"
  else
	fileOrCmds = "cmds"
  end

  -- Read in our command list from the file
  if fileOrCmds == "file" then
	if fs.exists(tArgs[1]) then
	  fHandler = fs.open(tArgs[1],"r")
	  if fHandler then
		cmds = fHandler.readAll
	  end
	end
  else -- Read in our commands from the command line
	-- Convert from a table into a space separated list
	for i,v in ipairs(tArgs) do
	  if cmds == "" then
		cmds = v
	  else
		cmds = cmds .. " " .. v
	  end
	end
  end

  -- Create our Coroutines
  coGo = coroutine.create(go)
  coFuel = coroutine.create(fuelManager)

  -- Continuously resume coroutines in sequence as they yield
  while true do

	-- Start/Resume our Go coroutine
	yy = coroutine.resume(coGo,cmds)
	if yy == false then
	  print("Coroutine Go Reports error")
	  print("Status: " .. coroutine.status(coGo))
	end
	-- If the coroutine has terminated, then exit our loop
	if coroutine.status(coGo) == "dead" then
	  break
	end

	-- Start/Resume our Fuel coroutine
	yy = coroutine.resume(coFuel)
	if yy == false then
	  print("Coroutine Fuel Reports error")
	  print("Status: " .. coroutine.status(coFuel))
	end
	-- If the coroutine has terminated, then exit our loop
	if coroutine.status(coFuel) == "dead" then
	  print("Out of Fuel")
	  break
	end
  end
  return true
end

-- Interactive Mode
function interactiveMode(saveFile)
  term.clear()
  print("Welcome to Interactive Mode")
  print("Instructions enter one command per line, followed by the enter key.")
  print("The turtle will execute the instructions and the instructions will")
  print("be recorded to the file '" .. saveFile .. "'.")
  print("")
  print("Enter the command 'end' to stop")
  print("")
  local fHandler = fs.open(saveFile,"a")
  while true do
	write("Command: ")
	cmd = io.read()
	if go(cmd) then
	  if string.lower(cmd) == "end" then
		break
	  end
	  fHandler.writeLine(cmd)
	end
  end
  fHandler.close()
end

-- Checks fuel status on predictable intervals
function fuelManager()
  local currentFuelLevel = 0
  local avgFuelConsumptionPerSecond = 1
  local estFuelLife = 0

  --- Keep this function active continously
  while true do
	--- Assess current Fuel Level
	currentFuelLevel = turtle.getFuelLevel()
	---   If fuel near Min level, then we need to refuel up to refuel level
	if currentFuelLevel <= fuelMin then
	  return false
	end
	--- Calculate approximate time until earliest fuel low warning
	estFuelLife = (currentFuelLevel * avgFuelConsumptionPerSecond)
	--- Sleep for half that time (coroutine should yield here)
	os.sleep(math.floor(estFuelLife/2))
  end -- endless loop
end

-- Processes a series of instructions
function go(cmds)
  local tArgs = { }
  local cmd = ""
  local nPos = 1
  local nCmd = 1
  local c = ""

  -- Convert List of cmds into a table
  while nPos < #cmds do
	c = string.sub(cmds,nPos,nPos)
	if c == " " then
	  if cmd ~= "" then
		tArgs[nCmd] = cmd
		cmd = ""
		nCmd = nCmd + 1
	  end
	else
	  cmd = cmd .. c
	end
	nPos = nPos + 1
  end
  if cmd ~= "" then
	tArgs[nCmd] = cmd
  end

  -- If no commands were found in the table then exit
  if #tArgs < 1 then
	print("No arguments given to go")
	return false
  end

  -- These are our defined handlers.   Each handler is defined with a condition and an action.
  -- before an action is executed, a condition must be met
  -- successful actions, will deducated distance values.  
  -- Failed conditions or actions will set distance to 0
  local tHandlers = {
		-- Forward, Back, Up, Down
		["F"] = { condition=function() return true end, action=turtle.forward },
		["B"] = { condition=function() return true end, action=turtle.back },
		["U"] = { condition=function() return true end, action=turtle.up },
		["D"] = { condition=function() return true end, action=turtle.down },
		-- Left, Right
		["L"] = { condition=function() return true end, action=turtle.turnLeft },
		["R"] = { condition=function() return true end, action=turtle.turnRight },
		-- Dig Over, Dig uNder
		["O"] = { condition=turtle.detect, action=turtle.digUp },
		["N"] = { condition=turtle.detect, action=turtle.digDown },
		-- Plant, Eject
		["P"] = { condition=function() return not(turtle.detectDown()) end, action=plantSeed },
		["E"] = { condition=function() return true end, action=dropExtras }
	  }

  -- Iterate for each command present
  local nArg = 1
  local sCmd = ""
  for nArg,sCmd in ipairs(tArgs) do
	local nDistance = 1
	-- Determine the Distance for the command
	if #sCmd > 1 then
	  local num = tonumber(string.sub(sCmd, 2))
	  if num then
		nDistance = num
	  else
		nDistance = 1
	  end
	else
	  nDistance = 1
	end
	sOperation = string.sub(sCmd,1,1)

	-- Use the function handler that corresponds with the command
	local fnHandler = tHandlers[string.upper(sOperation)]
	if fnHandler then
	  -- Set our condition and action functions
	  local condition = fnHandler["condition"]
	  local action = fnHandler["action"]
	  -- Repeat based on distance
	  while nDistance > 0 do
		local status = false  -- whether condition and action both returned true
		if condition() then
		  if action() then
			status = true
		  end
		else
		  status = true
		end
		-- If the action did not succeed, lets check some common reasons
		if status == false then
		  -- Out of Fuel?
		  if turtle.getFuelLevel() == 0 then
			print( "Out of fuel" )
			return false
		  else
			-- Best report his even though it may correct itself in half a second
			print(string.upper(sOperation) .. " returned error")
			sleep(0.5)
		  end
		else  -- action DID succeed, so lets reduce distance
		  nDistance = nDistance - 1
		end
	  end  -- while distance > 0
	else  -- if there was no valid function handler found ...
	  print( "No such Handler: " .. string.upper(sOperation) )
	  return false
	end
  end -- Process Next Command
  return true
end

-- Finds a seed in our inventory and plants it
-- Should be clear that there needs to be an empty block below in order to properly plant
function plantSeed()
  local slotNumber = 0
  local itemCount = 0
  local attempt = 0
  local seedItem = false

  for slotNumber=1,16 do
	-- There is a goto command in the new beta Lua .. cannot wait
	local skipIt = false
	while skipIt == false do
	  skipIt = true
	  if (slotNumber ~= fuelMatchSlot) and (slotNumber ~= seedMatchSlot) then
		-- See if there is any items in the slot
		itemCount = turtle.getItemCount(slotNumber)
		if itemCount == 0 then
		  -- goto skipIt
		  break
		end

		-- Select the Slot
		while turtle.select(slotNumber) == false do
		  attempt = attempt + 1
		  if attempt == 3 then
			print("Unable to Select Slot#" .. slotNumber)
			return false
		  end
		  -- Lets wait - maybe it will clear up
		  -- We will only make 3 attemps though
		  sleep(5)
		end

		-- Compare it to our seed slot
		seedItem = turtle.compareTo(seedMatchSlot)
		if not seedItem then
		  -- goto skipIt
		  break
		end

		-- We found a seed item - lets plant it
		if not turtle.placeDown() then
		  print("Could not place seed")
		  return false
		end
	  end  -- slot <> seedslot condition
	end -- while
	-- ::skipit::
  end  -- next slot number
  return true
end

-- Drops all items that are "extra"
-- at the time of writing, that means anything not fuel or seed
function dropExtras()
  local slotNumber = 0
  local keepItem = false
  local itemCount = 0
  local attempt = 0

  -- iterate through our slots
  for slotNumber=1,16 do
	-- Can remove these two lines when LUA gets a GOTO statement
	local skipIt = false
	while skipIt == false do
	  if (slotNumber ~= fuelMatchSlot) and (slotNumber ~= seedMatchSlot) then
		-- See if there is any items in the slot	
		itemCount = turtle.getItemCount(slotNumber)
		if itemCount == 0 then
		  -- goto skipIt
		  break
		end

		-- Select the Slot, give up after 3 attempts
		while turtle.select(slotNumber) == false do
		attempt = attempt + 1
		  if attempt == 3 then
			print("Unable to Select Slot#" .. slotNumber)
			return false
		  end
		  sleep(5)
		end  

		-- Is it an extra?
		keepItem = (turtle.compareTo(fuelMatchSlot) or turtle.compareTo(seedMatchSlot))
		if keepItem then
		  -- goto skipIt
		  break
		end

		-- We found an extra item - lets drop it
		turtle.dropDown()
	  end  -- valid slot check
	end  -- while loop
	-- :: skipIt ::
  end  -- next slot number
  return true
end

function reFuel()
  local slotNumber = 0
  local fuelItem = false
  local itemCount = 0
  local attempt = 0

  for slotNumber=1,16 do
	-- Remove these two lines when LUA gets a goto statement
	local skipIt = false
	while skipIt == false do
	  skipIt = true
	  if not (slotNumber == fuelMatchSlot) then

		-- See if there is any items in the slot	
		itemCount = turtle.getItemCount(slotNumber)
		if itemCount == 0 then
		  -- goto skipIt
		  break
		end

		-- Select the Slot
		while turtle.select(slotNumber) == false do
		  attempt = attempt + 1
		  if attempt == 3 then
			print("Unable to Select Slot#" .. slotNumber)
			return false
		  end
		 sleep(5)
		end

		-- Compare it to our fuel slot
		fuelItem = turtle.compareTo(fuelMatchSlot)
		if not fuelItem then
		  break
		end

		-- We found a fuel item - lets refuel to the refuel limit
		while turtle.getFuelLevel() < fuelRefill do
		  -- Attempt to Refuel with one unit
		  attempt = 0
		  while turtle.refuel(1) == false do
			attempt = attempt + 1
			if attempt == 1 then
			  print("Unable to refuel from slot #" .. slotNumber)
			end
			if attempt == 3 then
			  break   -- give up on this slot
			end
			os.sleep(1)
		  end

		  -- If this slot does not appear to refilling then skip the slot
		  if attempt == 3 then
			break
		  end

		  -- Keep refueling until we reach our refill level
		end  -- While Refueling
	  end  -- slot <> fuelslot condition
	  -- if we have refueled sufficiently, lets stop checking slots
	  if turtle.getFuelLevel() >= fuelRefill then
		break
	  end
	end  -- end while loop
  end  -- next slot number

  -- Return Refuel success
  if turtle.getFuelLevel() < fuelRefill then
	return false
  else
	return true
  end
end

local tArgs = { ... }

main(tArgs)

print("Finished")

Any assistance would be appreciated. Thank you in Advance.



#107300 Registration Issue on Website

Posted by Yesurbius on 07 April 2013 - 06:34 PM in Bugs

When you are registering for a new account, you are required to check the box "I have read the terms of use" ... unfortunately when you click on the link for the terms of use, it takes you to the same page.