This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
Luckie's profile picture

Help me out here.

Started by Luckie, 20 October 2012 - 05:28 AM
Luckie #1
Posted 20 October 2012 - 07:28 AM
I've been trying to make a turtle program to mine a variable width, 3 block high tunnel where the turtle will return to the start point when full and drop off before resuming mining.

Here's what I got so far:

Spoiler

-- Set up arguments for variables
local tArgs = {...}
if #tArgs ~= 1 then
  print("Incorrect usage of Function.")
  print("mine <width>")
  return
end




-- Set up variables
-- local sEvent, param = os.pullEvent("key")
local w = tonumber(tArgs[1]-1)
local f = 0
local d = 0
local l = 0

-- Setup functions
local function unload() -- Selects each slot in inventory and dumps it on the ground or in chest if available at start
	local rf = f
	setFace(2)
	for i=1,d do
		turtle.forward()
	end
	setFace(3)
	for i=1,l do
		turtle.forward()
	end
	for i=2,16 do
		turtle.select(i)
		turtle.dropDown()
	end
	turtle.select(2)
	setFace(1)
	for i=1,l do
		turtle.forward()
	end
	setFace(0)
	for i=1,d do
		turtle.forward()
	end
	setFace(rf)
	return
end

local function collect() -- running count of inventory to see if full
	local bFull = true
	local nTotalItems = 0
	for n=1,16 do
		local nCount = turtle.getItemCount(n)
		if nCount == 0 then
			bFull = false
		end
		nTotalItems = nTotalItems + nCount
	end	
	if bFull then
		print( "No empty slots left." )
		return false
	end
	return true
end

-- Start of dig functions
local function digDown()
	if turtle.digDown() then
		if not collect() then
			unload()
		end
	end
end

local function digUp()
	if turtle.digUp() then
		if not collect() then
			unload()
		end
	end
end

local function digForward()
	while not turtle.forward() do
		if turtle.dig() then
			if not collect() then
				unload()
			end
		end
	end
end
-- End of dig function

local function digStep() -- setup to dig 3 block high, first in the middle and then top and bottom
	digForward()
	digUp()
	digDown()
end

local function torch()
end

local function face(adj) -- Sets a running number for which way the turtle is facing
	if adj == pos then
		if f == 3 then
			f = 0
		else
			f = f + 1
		end
	elseif adj == neg then
		if f == 0 then
			f = 3
		else
			f = f - 1
		end
	end
end

local function faceRight() -- Turn right and set the current facing direction
	turtle.turnRight()
	face(pos)
end

local function faceLeft() -- Turn left and set the current facing direction
	turtle.turnLeft()
	face(neg)
end

local function setFace(dir) -- Has turtle turn right untill the current facing direction matches the desired facing direction
	local df = tonumber(dir)
	while f ~= df do
		faceRight()
	end
end

local function mine() -- function to mine
	digStep() -- starts the mine forward
	d = d + 1 -- running total of how far from start he's run
	faceRight() -- turn right to start mining the width of the mine
	for i=1,w do -- mines the desired width and keeps a running tally of how far from the left most wall turtle is
		digStep()
		l = l + 1
	end
	faceLeft() -- turn in the other direction to mine back to the leftmost wall
	digStep()
	d = d + 1
	faceLeft()
	for i=1,w do -- mines back to the left most wall
		digStep()
		l = l - 1
	end
	faceRight() -- set to start the next mine cycle
end

mine()
unload()

I have it to debug so I can make sure the main functions work so it'll just mine 2 deep and then try and unload. At unload it gives an error calling line 22 as attempting to call nil. However if I just run the setFace function outside of the unload function it works just fine. Anyone have any idea where I'm messing up.
ChunLing #2
Posted 20 October 2012 - 08:41 AM
This is a problem with local definitions of functions. You have unload being interpreted into binary before the value for setFace has been established. So that line ends up with a nil value, even though setFace does get defined eventually. If you use global function definitions, then this problem doesn't occur. But then you have globally declared functions hanging about after your program exits.

For now, try to organize your functions so that those that are needed for later functions get defined first. If this isn't possible, then put the functions that you need to have called by functions that have to be defined first (for some reason or other, usually recursion) inside of a global table. You can always set the table to nil when you're done and let lua clean up the contents.

But first see if you can organize the functions by dependency. My first glance suggests that you can.
Luckie #3
Posted 20 October 2012 - 07:19 PM
That makes sense. I'm pretty sure I can pull that off. Thank you very much.
Cloudy #4
Posted 20 October 2012 - 08:37 PM
This is a problem with local definitions of functions. You have unload being interpreted into binary before the value for setFace has been established. So that line ends up with a nil value, even though setFace does get defined eventually. If you use global function definitions, then this problem doesn't occur.

Wrong. It is nothing to do with it being global or not - they can sometimes work out of order or before being declared, but that's not predictable - a fluke of Lua.

All you need to do is make sure that all functions are declared in order of dependency - which is one correct thing you said.
ChunLing #5
Posted 20 October 2012 - 08:44 PM
Being global doesn't help? It's always worked for me.
ChunLing #6
Posted 20 October 2012 - 09:52 PM
Hah, this helped me with my other thing.

It turns out that you can declare a local table (with any string indexes you'll need), then go back and fill it with functions later. See, that's why making a table global worked for me, globals get their identifiers/spaces reserved first, before any locals. So you can define a global after the locals that it needs to function, even if the locals need the global to function, and it all works.

But you get the same effect by just declaring the local table as empty, then define the locals that need that table, then redefine the table to use the locals that in turn use it…why does this not make sense to me when I put it into English? It worked fine in lua :)/>/>