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

Mining Turtle Sometimes Operates Code Correctly, Sometimes Not.

Started by Burger, 20 September 2015 - 02:23 AM
Burger #1
Posted 20 September 2015 - 04:23 AM
Hey all. I posted a topic a few weeks ago about a mining turtle program I'm trying to write (I know there are lots out there already, but I want to learn how to code in CC so I'm writing my own). That issue was fixed, but now I'm having another problem, and would like to ask for some more aid if possible.

I'm a newbie, not only to ComputerCraft, but also to coding in general, so my work posted below will probably be of a very poor standard. But I am interested to learn, so any assistance you could give me would be greatly appreciated, thank you. I've done a lot of research on the wiki, on tutorial videos on Youtube, and reading through code snippets on this forum, and I've already learned a great deal. However I would ask that you try and make replies to this thread nice and simple, so I can understand them better, and if possible explain the logic behind them so that I can comprehend just how and why the code is working as it does.

Here is a link to the text file of my code, since it's getting quite long now: https://www.dropbox....3c44p/quar?dl=1

The problem I'm having is strange. It occurs when the turtle has finished digging down to bedrock and is on it's way back up to the surface. Most of the time it climbs all the way up and deposits anything it has dug out in the chest as it should.

However just occasionally, for no apparent reason, it stops moving some way down, and ejects all it's valuables there instead.

There's no reason for it to stop - it isn't blocked from moving, and it throws no errors to suggest what might be going wrong. I tried adding the chkstart() function to it in an attemt to prevent it happening, but this didn't solve the issue - in fact if anything it seemed to make it happen more regularly. When it ejects the valuables the debug code (all the print("") lines) shows that it is cycling through the inventory purge and status update code as it should, so that code is operating effectivley. It's just that for some reason, it triggers that code while burried way below the surface, instead of next to the collection chest as it should. And it only has this problem occasionally, with no apparent trigger to cause it - many times it functions just as it should.

I'm really confused by it. I don't suppose anyone might be able to assist? Thanks in advance if you can.
Bomb Bloke #2
Posted 21 September 2015 - 12:45 AM

Next time, please use something like Pastebin: It's more convenient than having to download a file.

This code here:

 				if (data.name ~= notores[1]) and (data.name ~= notores[2]) and (data.name ~= notores[3]) and (data.name ~= notores[4]) and (data.name ~= notores[5]) and (data.name ~= notores[6]) and (data.name ~= notores[7]) and (data.name ~= notores[8]) and (data.name ~= notores[9]) then
     					print("Ore detected. Mining...")
					turtle.dig()
				else
					print("Nothing detected.")
 				end

… would benefit from a loop, allowing it to automatically adapt to the number of entries in notores:

 				local isOre = true
 				for i = 1, #notores do
 					if data.name == notores[i] then
 						isOre = false
 						break
 					end
 				end
 				if isOre then
 					print("Ore detected. Mining...")
					turtle.dig()
				else
					print("Nothing detected.")
 				end

Or, you could re-arrange the contents of notores like this:

--# List of blocks not to dig out
local notores = {
	["minecraft:dirt"] = true,
	["minecraft:stone"] = true,
	["minecraft:bedrock"] = true,
	["minecraft:gravel"] = true,
	["minecraft:cobblestone"] = true,
	["minecraft:torch"] = true,
	["minecraft:chest"] = true,
	["minecraft:grass"] = true,
	["minecraft:sandstone"] = true,
 			}

… allowing you to turn the check into this:

 				if not notores[data.name] then
 					print("Ore detected. Mining...")
					turtle.dig()
				else
					print("Nothing detected.")
 				end

This block here:

				else
					turtle.digDown()
					turtle.down()
					invcheck()
					fuel()
					posz = posz + 1
				end

… has the potential to increment posz without actually moving the turtle down (because eg a mob is in the way). Better to use a loop to ensure the movement completes:

				else
					repeat
						turtle.digDown()
						turtle.attackDown()
						fuel()
					until turtle.down()  -- Most turtle functions return true/false depending on whether the requested action was successful.
					invcheck()
					posz = posz + 1
				end

Likewise for the downward movement attempt coded in just below.

This sort of thing:

local slotloop = 1
		repeat
		local itemcheck = turtle.getItemDetail(slotloop)
			if itemcheck then
				if (itemcheck.name ~= notores[1]) and (itemcheck.name ~= notores[4]) and (itemcheck.name ~= notores[5]) and (itemcheck.name ~= notores[9]) then
					print("Depositing valuable substance in cache.")
					turtle.select(slotloop)
					turtle.dropUp()
				else
					print("Non-valuable substance detected. Discarding.")
					turtle.select(slotloop)
					turtle.dropDown()
				end
			end
		slotloop = slotloop + 1
		until slotloop == 15

… would be better formatted to use a "for" loop:

		for slotloop = 1, 14 do
			local itemcheck = turtle.getItemDetail(slotloop)
			if itemcheck then
				turtle.select(slotloop)
				if (itemcheck.name ~= notores[1]) and (itemcheck.name ~= notores[4]) and (itemcheck.name ~= notores[5]) and (itemcheck.name ~= notores[9]) then
					print("Depositing valuable substance in cache.")
					turtle.dropUp()
				else
					print("Non-valuable substance detected. Discarding.")
					turtle.dropDown()
				end
			end
		end

restart() could also use a check to ensure that movements are actually being carried out successfully:

--# Return to start
local function retstart()
	while posz > 0 do
		while not turtle.up() do
			turtle.digUp()
			turtle.attackUp()
			fuel()
		end
		posz = posz - 1
	end	
end

In terms of your stated problem, the issue likely boils down to the turtle running out of fuel. One bit of coal provides 80 units, you only consume one bit whenever the remaining level gets below 10, and you don't attempt to refuel at all while retstart() is running. There are fairly good odds that it'll run out midway up the shaft, and since you aren't checking to ensure each movement is successful, the movement loop will "complete" without actually bringing the turtle to the top.
Dustmuz #3
Posted 21 September 2015 - 08:19 AM
Burger: youre not the only one with that problem, i've been coding my own little quarry turtle for the past 2 days now.
the program runs smoothly for maybe the first 2-3 layers (1 layer being 3 blocks) after that it sometimes turn in the wrong direction, move up further than it should or goes further down than it should.. for no apparent reason..

one of the "flaws" i found in my code before finishing it, was if it encountered a mob on the way back, that could throw it off its counter as i couldnt move the mob. i got around that by adding a turtle.attack() to every movement towards the start point.
Burger #4
Posted 21 September 2015 - 09:52 PM
Wow, a lot of information! Thanks very much for the replies guys, your assistance is much appreciated.

Next time, please use something like Pastebin: It's more convenient than having to download a file.

Apologies for any inconvenience. I'm unfamiliar with Pastebin, and would prefer not to have to sign up to another online service if I can help it, so I assumed that hosting the file somewhere where I already had an account would be reasonable. However if that is not the case then can perhaps look into it if nessecary. Does Pastebin allow a person to post there without an account?

Thanks for the hints on streamlining the code though, those will hopefully make things a lot simpler if I can get my head around them lol

This block here:

… has the potential to increment posz without actually moving the turtle down (because eg a mob is in the way). Better to use a loop to ensure the movement completes:

Likewise for the downward movement attempt coded in just below.

restart() could also use a check to ensure that movements are actually being carried out successfully:

one of the "flaws" i found in my code before finishing it, was if it encountered a mob on the way back, that could throw it off its counter as i couldnt move the mob. i got around that by adding a turtle.attack() to every movement towards the start point.

Thanks for these tips too. On my single player game I have a mob spawn mod installed which greatly reduces the number of mobs underground, so the chances of running into anything are scant. However I am trying to account for all variables (like treasure chests, as you can see in the code), and also if this code were adapted to multiplayer games that I play with my friends it would be handy too, as we play with more mobs there. I'll look into this one too.

This sort of thing:

… would be better formatted to use a "for" loop:

Hmm, okay, I'll check that out too. Just one quick question though - if I did change this section to a for loop as you say, would it be affected if I also changed the notOres table as you stated above? So if I were to change the notOres table to read 'true' for each item, would this for loop change still work even with that format, or would I have to tweak this for loop as well so it could still read the table correctly?

In terms of your stated problem, the issue likely boils down to the turtle running out of fuel. One bit of coal provides 80 units, you only consume one bit whenever the remaining level gets below 10, and you don't attempt to refuel at all while retstart() is running. There are fairly good odds that it'll run out midway up the shaft, and since you aren't checking to ensure each movement is successful, the movement loop will "complete" without actually bringing the turtle to the top.

O.O You know, I hadn't considered that at all! I just assumed that since the fuel (I use charcoal) gave so many units and the move up was only 60 or so, it would have no trouble making it. It completely slipped my mind that the thing wouldn't nessecarily refuel right before making the journey up. Thanks for pointing that out, it could perhaps be the problem yeah. I'll test it out when I get the chance and see if it fixes the issue. If not I'll report back the results.

Thanks for all the aid^^
Edited on 21 September 2015 - 07:54 PM
Dustmuz #5
Posted 21 September 2015 - 10:26 PM
for pastebin.. Yes you can post code there as a guest :)/>

btw.. in my code, every time it returns to empty itself, it checks the fuel lvl.. if its below 10% it refuels up till 90% (i just put a stack of charcoal blocks in it, that lasts for about 2 full refuels)
Edited on 21 September 2015 - 08:27 PM
Burger #6
Posted 21 September 2015 - 11:19 PM
for pastebin.. Yes you can post code there as a guest :)/>

btw.. in my code, every time it returns to empty itself, it checks the fuel lvl.. if its below 10% it refuels up till 90% (i just put a stack of charcoal blocks in it, that lasts for about 2 full refuels)

Ah that's good to hear^^ Perhaps Pastebin would be an option then yeah.

And yes, that's not a bad idea about refuelling so high, however am I right in remembering that when a turtle is picked up it loses all it's current fuel? That's the reawson I set it to just refuel one item at once - it seemed a waste to fuel it really high then lose a lot of it when I pick it up and move it to a new area. Yes charcoal is renewable and not exactly hard to get, but I'm a bit of a hoarder and cheapskate with my resources lol
Edited on 21 September 2015 - 09:19 PM
Wojbie #7
Posted 21 September 2015 - 11:21 PM
I right in remembering that when a turtle is picked up it loses all it's current fuel?

I do remember that if turtle is labeled using "label" program before picking up it will keep its fuel level.
Edited on 21 September 2015 - 09:22 PM
Dustmuz #8
Posted 21 September 2015 - 11:33 PM
Burger and Wojbie..

If you label a turtle with the label set *name* then it keep its programs and fuel level :)/>
also makes offline coding a bit easier if you are playing in a single player world (what i do when writing new programs)
Bomb Bloke #9
Posted 21 September 2015 - 11:39 PM
Just one quick question though - if I did change this section to a for loop as you say, would it be affected if I also changed the notOres table as you stated above? So if I were to change the notOres table to read 'true' for each item, would this for loop change still work even with that format, or would I have to tweak this for loop as well so it could still read the table correctly?

You'd need to change all references into the table, not just the ones I specifically pointed out. For example, you'd likewise change line 107 to:

if not notores[itemcheck.name] then

75, 78 and 140 would be better off using hard-coded strings. Variables are handy if you reckon you might want to change those values later, but they're harder to read and you're not going to be changing those particular ones.
Burger #10
Posted 24 September 2015 - 02:17 AM
Ah okay, I knew a labelled turtle kept it's programs, but I didn't realise it worked for fuel as well, thanks again for the info^^

And in other news, I finally got the chance to try the suggestions in this thread out tonight. And aside from a few mistypes on my part causing an odd error or two, the program seems to be working flawlessly now! Thanks muchly for all the aid. Now for me to add on the next few bits of functionallity and break it again so I can come crawling back here asking for assistance again lol. Hopefully it won't be too soon before I run into another impass :)/>