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

Newbie Mining Program Thread: First Issue Solved

Started by Burger, 11 September 2015 - 11:48 PM
Burger #1
Posted 12 September 2015 - 01:48 AM
Hey there all.

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.

EDIT: This first issue has now been solved, however as I progress I'm constantly running into errors which I may need assistance with. I'll be adding them to this thread as they arise, please check my last few posts here for the latest info..


=====

Old issue:

Onto my problem: I'm trying to write a mining code for a Turtle, to make it dig vertical columns from surface to bedrock, digging out any ores it finds on the way (I'm aware there are already many programs out there that do this, but as I said I want to learn how to do these codes myself). So far the Turtle will pickup fuel from a chest, then start digging down, refueling itself and picking up ores on the way. The problem is when it hits bedrock, it does not trigger the 'retstart()' function to return to the surface - instead it simply gets stuck in a loop spinning around and around at bedrock level, constantly checking the blocks around it over and over. It does not throw an error, just repeats the actions indefinitely.

Here's the code I have so far. I hope it isn't too long to post on the forum - if it is let me know and I'll host the file on Dropbox or somewhere instead. Also I hope the indentation is okay…like I said, newbie ;)/>

Spoiler

local posx = 0
local posy = 0
local posz = 0
local column = 0
local row = 0
local turn = 0
local invfull = false
local bed = false
local notores = {
"minecraft:dirt",
"minecraft:stone",
"minecraft:bedrock",
"minecraft:gravel",
"minecraft:cobblestone",
"minecraft:torch",
"minecraft:chest",
"minecraft:grass",
	}

local function restock()
if turtle.getItemCount(16) <= 10 then
  turtle.select(16)
  turtle.suck(50)
end
end

local function fuel()
if turtle.getFuelLevel() < 10 then
  turtle.select(16)
  turtle.refuel(1)
end
end

local function invcheck()
if turtle.getItemCount(15) > 0 then
  invfull = true
end
end

local function look()
for i=1,4 do
  local success, data = turtle.inspect()
	 if success then
	 if data.name == notores[1] then
		  elseif data.name == notores[2] then
	   elseif data.name == notores[3] then
	   elseif data.name == notores[4] then
		elseif data.name == notores[5] then
		 elseif data.name == notores[6] then
		  elseif data.name == notores[7] then
			elseif data.name == notores[8] then
			   print("Nothing detected.")
				else
		 print("Ore detected. Mining...")
	turtle.dig()
	 end		
	end
  turtle.turnRight()
  turn = turn + 1
  invcheck()
end
end

local function digdown()
look()
if turtle.detectDown() then
  local bedcheck, data = turtle.inspectDown()
   if bedcheck then
	if data.name == notores[3] then
	 print("Bedrock detected. Quarry column complete.")
	 bed = true
	else
	 turtle.digDown()
	 turtle.down()
	 invcheck()
	 fuel()
	 posz = posz + 1
	end
   end
else
  turtle.down()
  invcheck()
  fuel()
  posz = posz + 1
end
end

local function retstart()
while posz > 0 do
  turtle.up()
  posz = posz - 1
end
end

restock()
fuel()
if bed == false then
while invfull == false do
	print("Inventory is not full")
	digdown()
end
else
retstart()
end

I'd be greatful for any aid you could give, thanks in advance.

~Burger
Edited on 12 September 2015 - 05:56 PM
safetyscissors #2
Posted 12 September 2015 - 03:29 AM
Hey burger, welcome to the computercraft forums. I must say that your code is quite neat and well laid out. It makes it fast to read and debug.


restock()
fuel()
while not bed or not invfull do
    digdown()
end
rerstart()

In the above code, it will repeat until either bed=true OR invfull=true. If either triggers, it will stop and return to top.
Your if statement checking for bed is only run once and if false, the else will exclude the retstart command .
valithor #3
Posted 12 September 2015 - 05:02 AM
If it was not clear Safetyscissors' answer is actually something you could use in place of the last 8 lines of code of your code. Just putting that out there as it took me a good 10 minutes to figure that out… lmao

So I will try to actually explain what is going on, and give a alternative solution in case you ever find another loop you need to break.

When you run the code the if statement:

if bed == false then

runs and returns true causing, which runs

while invfull == false do
  print("Inventory is not full")
  digdown()
end

Your problem is that loop will repeat indefinitely, unless if the inventory gets full. However, the inventory can never be full if the turtle is stuck on bedrock, which would just cause it to spin around in circles from the look() function in the beginning of the digdown() function. So there are two ways you could get around this. The first being what safetyscissors suggested, which applied to your code would look something like:

while invfull == false and bed == false do --# this will check both conditions, and if one of them is true will stop the loop
  print("Inventory is not full")
  digdown()
end

The second solution would be using a if statement and the "break" keyword:

while invfull == false do
  print("Inventory is not full")
  digdown()
  if bed then --# checking if bed is true
	break --# jumps out of the loop
  end
end

The first solution would be the better of the two, but I showed the second simply so you would be able to see the break keyword in action.

This brings us to another problem. When the loop is finished the program will end, because the restart function is inside the else part of the if statement. The best way would be to just do as safetyscissors did, and remove the if statement all together.

The next thing I will talk about is the use of the "not" keyword. Just because safetyscissors used it in his example.

The "not" keyword essentially just changes whatever the next thing that follows it to the opposite. A few examples:

not true == false
not false == true
not nil == true
not "anything other than nil" == false

It is essentially just a alternative to doing "if var == false"

Lastly is the "and" and "or" keywords. They are fairly simple, but why not? :P/>

true and true == true
false and true == false
false and false == false
--# and requires both things to be true

true or true == true
false or true == true
false or false == false
--# or requires only one of the things to be true
Edited on 12 September 2015 - 03:06 AM
Burger #4
Posted 12 September 2015 - 09:30 AM
Right…so if I'm understanding you guys correctly you're saying that it's checking for bedrock, then just dropping into a repeated check for the inventory being full and not returning to the bedrock check again? I see - I was under the impression it would run the whole check from the beginning with each loop, bedrock and all. But I see what you mean about the bedrock check being separate to the loop now. Heh, now that it's explained it seems so simple that I'm surprised I didn't get it myself, but I guess that's where being a newbie comes in.

Thanks very much for your replies guys, and for the welcome^^

I'll try this solution out when I'm next on the game (probably tomorrow as I should really be in bed by now). However I do have an awful lot still to do on this program yet (I'd like to get it automatically unloading resources into a chest, dropping cobblestone and even moving on to dig other shafts out from the start point eventually), and I have no doubt those additions will throw up issues of their own as I try to muddle my way through them. So would it be okay for me to come back to this thread and update it if I run into another issue, perhaps get a bit more assistance as the code continues to evolve? If so that would also be much appreciated, or if it would be better for me to just create a new thread if I run into another problem then I can do that instead, whatever is best.

Either way, thanks again for the pointers, and the explanations of what is going on with the code. Think I'm finally beginning to get my head around some of this logic lol


EDIT UPDATE: I tried the solutions mentioned above and they worked great, thanks again for the help! I also tried to add on a few more sections of code, but I'm having a little trouble with them, so I may post those issues here as well if I can't figure them out. I did have an 'attempt to call ?' issue which I posted about in this thread, however just moments after posting I spotted the cause of that issue, so managed to fix it. Sorry for being so noobish with my difficulties lol
Edited on 12 September 2015 - 05:58 PM