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

Turtle think function?

Started by MrDeeJayy, 30 March 2015 - 03:07 PM
MrDeeJayy #1
Posted 30 March 2015 - 05:07 PM
Hi all.

Been trying to make this turtle that goes around and around this 3x3x1 spot. You see, in the center, is a "Pure Daisy" from Botania. I want the turtle to identify the "Livingwood" and "Livingstone" generated by the daisy, dig it up, replace it with its minecraft counterpart, and move on. 1 hour of coding later, and all the experience I could call upon from my work as a Garry's Mod developer, I made this piece of crap: http://pastebin.com/7xBHcqKE
Spoiler

storeSlots = {
		livingwood = {1,2,3,4},
		livingstone = {5,6,7,8}
}
placeSlots = {
		log = {9,10},
		stone = {11,12}
}
fuelSlots = {13,14,15,16}
mineThese = {"livingwood","livingstone"}
placeThese = {"log","stone"}
fuelThese = {"minecraft:coal","minecraft:charcoal"}


function refuel()
		--Check all slots for fuel.
		local startfuel = turtle.getFuelLevel()
		if startfuel == "unlimited" or startfuel >= 10 then return true end
		local fuelslots = {}
		for k,v in pairs(fuelSlots) do --Reserve 13-16 for fuel to minimize calc time.
				local itemDetail = turtle.getItemDetail(v)
				for i = 1, #fuelThese do
						if itemDetail.name == fuelThese[i] then
								turtle.refuel(turtle.getItemSpace(v))
								break
						end
				end
				if turtle.getFuelLevel() >= 10 then break end
		end
		if turtle.getFuelLevel() < 10 then refuel() end
end

function checkBlock()
		turtle.turnRight() -- Look at the block.
		local success,block = turtle.inspect()
		if success == true then
				for i = 1, #mineThese do
						if block.name == "Botania:" .. mineThese[i] then
								turtle.dig()
								for k,v in pairs( storeSlots[mineThese[i]] ) do
										turtle.select(v)
										turtle.suck()
								end
								for k,v in pairs( placeSlots[placeThese[i]] ) do
										turtle.select(v)
										local placed = nil
										if not turtle.getItemSpace(v) == 0 then
												placed = turtle.place("")
										end
										if placed then break end
								end
						end
				end
		end
		turtle.turnLeft()
		turtle.forward()
end

	  
local function Think()
		refuel()
		checkBlock()
		checkBlock()
		checkblock()
		turtle.turnRight()
		Think() -- again please.
end  

Think()
The painfully obvious problem: A stack overflow in my "Think" function. My question? How do I make (or hook into) some form of Think function that will run each tick (or at least, loop the function)?
Spoiler

For simplicity's sake, here is a screenshot. The turtle (1 turtle when in operation, the extras are just for effect here) follows this redstone path clockwise, at each step, its supposed to turn right and inspect a block). An eventual desire of mine is to have it dump into that chest every once in a while.
MKlegoman357 #2
Posted 30 March 2015 - 06:40 PM
Don't call your Think function over and over again. Just use a 'while true do loop' for that:


local function Think ()
  while true do
    --# code here
  end
end
SquidDev #3
Posted 30 March 2015 - 08:34 PM
Just a couple of things of things I noticed: There is a inspectDown function. So instead of going round the outside you can just go over the top. This means you don't need the turnRight to look at the block. You also don't need the turtle.suck on line 42 as dig will automatically pick it up the drops, though you will need to suck and drop the items into the chest. Also the place text is optional (line 48)
MrDeeJayy #4
Posted 31 March 2015 - 11:02 PM
Thanks for the advice. I'm too used to avoiding while loops like the plague, they have a garbage collection issue in garry's mod that can make variables magically disappear for a full frame/tick.

I'll begin rewriting right away.

EDIT: Ok new problem. After encountering an issue, which is currently in an unapproved post (moderators you may disregard and prune said post).



The fuel is in the correct slot, but its been sitting here for about 15 minutes now? Almost as if it can't refuel. I even went away and made a phone call, nothing changed.

EDIT #2: After a lot of problems, including a stupid stack overflow and some mysterious "138" error, I got it working.

The working code[/url

(LAST MINUTE EDIT) OK, so it was working until it started raining in the overworld, causing a lone enderman to teleport into my base, and stand in the way of the bloody turtle.
Edited on 31 March 2015 - 11:35 PM
valithor #5
Posted 01 April 2015 - 03:31 AM
(LAST MINUTE EDIT) OK, so it was working until it started raining in the overworld, causing a lone enderman to teleport into my base, and stand in the way of the bloody turtle


Something like this might become useful if it is a commonly occuring problem. You would just use this function in the place of turtle.forward.

function forward()
  while not turtle.forward() do
	turtle.attack()
	turtle.dig() -- this is optional
  end
end

Assuming pvp is off your turtle wont accidently kill you :P/>
Edited on 01 April 2015 - 01:32 AM