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

[Help] Turtle Program for Mining

Started by TerminatorII, 21 September 2014 - 10:05 PM
TerminatorII #1
Posted 22 September 2014 - 12:05 AM
Im attempting to make a tunneling program for my turtle and I have 0 experience in lua. As a result I am basing my program off another program (and I think this is where the problem arises) It is giving me this error

AdvTunnel:133 'for' limit must be a number
Spoiler

local tArgs = { ... }
-- Explain how to use the program

if tArgs[1] == 'help' then
  print('Usage:')
  print('enter advTunnel : [length]')
  return
end

-- Set our distance to mine

local mDistance = tArgs[1] or 1

function fuelLevel()
  if turtle.getFuelLevel() > 80 then
	turtle.refuel()
  return
  end
end

function turnAround()
  turtle.turnRight(2)
end

function paveDown()
  turtle.select(2)
  turtle.placeDown()
end

function paveUp()
  turtle.select(2)
  turtle.placeUp()
end

function paveFront()
  turtle.select(2)
  turtle.place()
end

function detectFront()
  if turtle.detect() then
  paveFront()
  end
end

function detectDown()
  if turtle.detectDown() then
  paveDown()
  end
end

function detectUp()
  if turtle.detectUp() then
  paveUp()
  end
end

function pave()
  detectUp()
  detectDown()
  detectFront()
end

function reinforce()
  detectUp()
  detectFront()
end

function returnHome()
  turnAround()

  for returnLocation = 0, mDistance do
	 -- Make sure to deal with sand and friends
	while turtle.detect() do turtle.dig() end

	turtle.forward()
  end
end

function digTunnel()
  while turtle.detect() do turtle.dig() end
  turtle.forward()
  pave()
  turtle.turnRight()
  while turtle.detect() do turtle.dig() end
  pave()
  turtle.dig()
  turtle.forward()
  while turtle.detect() do turtle.dig() end
  pave()
  turtle.dig()
  turtle.forward()
  pave()  
  turtle.digUp()
  turtle.up()
  reinforce()
  turtle.turnLeft()
  reinforce()
  turtle.turnLeft()
  while turtle.detect() do turtle.dig() end
  reinforce()
  turtle.dig()
  turtle.forward()
  while turtle.detect() do turtle.dig() end
  reinforce()
  turtle.dig()
  turtle.forward()
  reinforce()
  turtle.digUp()
  turtle.up()
  reinforce()
  turtle.turnRight()
  reinforce()
  turtle.turnRight()
  while turtle.detect() do turtle.dig() end
  reinforce()
  turtle.dig()
  turtle.forward()
  while turtle.detect() do turtle.dig() end
  reinforce()
  turtle.dig()
  turtle.forward()
  reinforce()
  turtle.turnLeft()
  reinforce()
  turtle.down(2)
  turtle.turnLeft()
  turtle.forward(2)
  turtle.turnRight()
  fuelLevel()
end

for currentLocation = 0, mDistance do
  digTunnel(currentLocation)
end

returnHome()

Im probably inefficient as all get with my main program loop, but I was mostly trying to get it to work and not worrying about elegance. Any help would be apreciated.


EDIT: I modified the code (changed mdistance to mDistance and made sure it was consistant through.) the program runs now, but I have a new problem. in the following section I tell it to move down two then turn left and forward 2 then turn right. however, it just goes down 1 and over 1.


  turtle.turnLeft()
  reinforce()
  turtle.down(2)
  turtle.turnLeft()
  turtle.forward(2)
  turtle.turnRight()
  fuelLevel()
end

also, It doesnt handle sand or gravel at all. it just stops infront of them. I thought that this line would make it keep mining as long as it detected anything in front?


  while turtle.detect() do turtle.dig() end

do I just need to loop it? if so I should just make the entire thing more optimized and repeat with loops.

I also just noticed that it isnt even placing blocks. which I wanted it to do (goal was to eliminate any liquids it comes in contact with,) so Im obviously missing something in the way Im constructing the code, or using the turtle commands.
Edited on 23 September 2014 - 01:16 AM
KingofGamesYami #2
Posted 22 September 2014 - 03:07 AM
You define "mDistance", but later referance "distance", which is nil, therefor causing that error.

PS: Use code tags!
TerminatorII #3
Posted 22 September 2014 - 05:04 AM
ok added code tags inside and will test this tomorrow after classes.
TerminatorII #4
Posted 23 September 2014 - 02:40 AM
added changes to code, please reference first post.
Bomb Bloke #5
Posted 23 September 2014 - 03:20 AM
EDIT: I modified the code (changed mdistance to mDistance and made sure it was consistant through.) the program runs now, but I have a new problem. in the following section I tell it to move down two then turn left and forward 2 then turn right. however, it just goes down 1 and over 1.

turtle.down(), turtle.forward(), etc don't accept parameters. Passing them a number won't make them repeat that many times - you specifically need to call them the amount of times you want them to run.

They do, however, return a boolean value indicating whether or not they worked. A common loop for getting them to hack their way through blocking materials / mobs looks like this:

while not turtle.forward() do
  turtle.dig()
  turtle.attack()
end

Say you wanted the turtle to go forward twice, you could condense that down to this:

local function forward(amount)
  amount = amount or 1  -- Default value of 1 if an "amount" value wasn't passed to the function.

  for i=1,amount do
    while not turtle.forward() do
      turtle.dig()
      turtle.attack()
    end
  end
end

.
.
.

forward(2)
TerminatorII #6
Posted 23 September 2014 - 03:46 AM
ok that is amazing info. However, I now have a new question (Im apparently very bad at this.) how exactly does detect work? I cant seem to get that or placing working.am I just missing how lua works? Im a complete novice when it comes to programming as I only have a little experience with some scripting languages.
KingofGamesYami #7
Posted 23 September 2014 - 03:55 AM

print( turtle.detect() )
If there is a solid block in front of the turtle, this prints true.

Uses:

if turtle.detect() then
  --#there's a block
else
  --#there isn't a block
end


if not turtle.forward() then --#if the turtle failed to move forward,
  if turtle.detect() then
     --#there is a block
  else
     --#there is an entity
  end
end
Edited on 23 September 2014 - 01:56 AM
TerminatorII #8
Posted 23 September 2014 - 04:39 AM
ok Im a plagerist, but in my defence Im trying to understand how this works. Now I took what you wrote and pluged in some commands to make it do stuff, yet I cant seem to pass it data.

I passed it a 2

local ags = { ... }
local forward = args[1] or 1

for 1 to forward do
	if turtle.detect() then
	  --#there's a block
	  turtle.dig()
	  turtle.forward()
	  if not turtle.forward() then --#if the turtle failed to move forward,
		if turtle.detect() then
		  --#there is a block
		  turtle.dig()
		  turtle.forward()
		else
		  --#there is an entity
		  turtle.attack()
		end
	  end
	else
	  --#there isn't a block
	  turtle.forward()
	end
end

it returns "[string "move"]:4 '<name>' expected

I know the problem is on line 2 or 4, and that it thinks forward is a string. why is it saying string. I thought I was passing it a number and retrieving it as a number. obviously Im calling all passes to the program as strings, but I thought I could call the data passed as a number with line 2. can someone clarify how to pass data types? string/int/float
Edited on 23 September 2014 - 02:43 AM
KingofGamesYami #9
Posted 23 September 2014 - 04:51 AM
Your for loop is defined incorrectly.

Correction:

for i = 1, tonumber( forward ) do

Also, there is a simpler way of doing what I showed you:

while not turtle.forward() do --#each time the loop is called, it attempts to move forward, and if so, skips the loop
  if turtle.detect() then
    turtle.dig() --#dig the block
  else
    turtle.attack() --#attack the entity
  end
end

Which can be further simplified into

while not turtle.forward() do --#attempts to move forward
  turtle.dig() --#digs, regardless if there is a block there or not
  turtle.attack() --#attacks, regardless if there is a block there or not
end
Edited on 23 September 2014 - 02:53 AM
TerminatorII #10
Posted 23 September 2014 - 04:57 AM
Your for loop is defined incorrectly.

Correction:

while not turtle.forward() do --#attempts to move forward
  turtle.dig() --#digs, regardless if there is a block there or not
  turtle.attack() --#attacks, regardless if there is a block there or not
end

quick question on this. I understand what its doing but will this repeat until it can move?

clarification: will this always repeat until it moves forward? are there conditions where it could fail?
Edited on 23 September 2014 - 03:03 AM
Bomb Bloke #11
Posted 23 September 2014 - 05:42 AM
Yes, the loop will repeat over and over until turtle.forward() succeeds once.

If the turtle presses up against bedrock, or runs out of fuel, then the turtle will be stuck within the loop forever.
TerminatorII #12
Posted 23 September 2014 - 06:35 AM
Update: I have a working program! (it only mines right now) Next for me is to get it to place blocks and torches where I want them.

Spoiler

local tArgs = { ... }
-- Explain how to use the program

if tArgs[1] == 'help' then
  print('Usage:')
  print('enter advTunnel : [length]')
  return
end

-- Set our distance to mine

local mDistance = tArgs[1] or 1

local function forward(amount)
  amount = amount or 1  -- Default value of 1 if an "amount" value wasn't passed to the function.
  for i=1,amount do
    while not turtle.forward() do --#attempts to move forward
      turtle.dig() --#digs, regardless if there is a block there or not
      turtle.attack() --#attacks, regardless if there is a block there or not
    end
  end
end

local function up(amount)
  amount = amount or 1  -- Default value of 1 if an "amount" value wasn't passed to the function.
  for i=1,amount do
    while not turtle.up() do --#attempts to move up
      turtle.digUp() --#digs, regardless if there is a block there or not
      turtle.attackUp() --#attacks, regardless if there is a block there or not
    end
  end
end

local function down(amount)
  amount = amount or 1  -- Default value of 1 if an "amount" value wasn't passed to the function.
  for i=1,amount do
    while not turtle.down() do --#attempts to move down
      turtle.digDown() --#digs, regardless if there is a block there or not
      turtle.attackDown() --#attacks, regardless if there is a block there or not
    end
  end
end

local function fuelLevel()
  local fuelNow = 0
  turtle.getFuelLevel(fuelNow)
  if fuelNow < 80 then
    turtle.select(1)
    turtle.refuel()
  return
  end
end

local function turnAround()
  turtle.turnRight()
  turtle.turnRight()
end

local function returnHome()
  turnAround() 
  for returnLocation = 0, (mDistance * 4) -1 do
    forward()
  end
end

local function digFront()
  forward()
  turtle.turnRight()
  forward(2)
  up()
  turnAround()
  forward(2)
  up()
  turnAround()
  forward(2)
end

local function digTorch()
  turtle.turnLeft()
  forward()
  turtle.turnLeft()
  forward(2)
  down()
  forward()
  turnAround()
  forward(4)
  turnAround()
  forward()
  down()
  forward(2)
end

local function digRear()
  turtle.turnRight()
  forward()
  turtle.turnRight()
  forward(2)
  up()
  turnAround()
  forward(2)
  up()
  turnAround()
  forward(2)
end

local function digRear2()
  turtle.turnLeft()
  forward()
  turtle.turnLeft()
  forward(2)
  down()
  turnAround()
  forward(2)
  down()
  turnAround()
  forward(2)
  turtle.turnRight()
end

local function digTunnel()
  digFront()
  digTorch()
  digRear()
  digRear2()
  fuelLevel()
end

for currentLocation = 0, mDistance - 1 do
  digTunnel(currentLocation)
end

returnHome()

KingofGames and Bomb Bloke you guys have been awesome and thankyou so much for helping me out!
Edited on 23 September 2014 - 04:38 AM
TerminatorII #13
Posted 23 September 2014 - 11:45 PM
Ok I have now implemented routines to place torches, and place blocks in any perimeter holes the turtle encounters. I also put in options for a second type of mine shaft.

Im sure there is a better way to do the selection, in fact I know there is. I would really like it to dump back at the top waiting for an input if you dont put in any input. Ill work on that tomorrow (or later today if someone tells me how :P/> ) but I figured I should show you guys my current sucesses which would not have happened except for
KingofGamesYami

and
Bomb Bloke


Spoiler

local tArgs = { ... }
local tunnel = "false"
local moved = 0
-- Explain how to use the program

if tArgs[1] == 'help' then
  print('Usage:')
  print("select branch : [1]")
  print("or main shaft: [2]")
  print("after the first number enter the length of the tunnel.")
  print("ex: advmine 1 4")
  print("this selects branch and tunnels 4 sections.")
  return
end
-- Set our distance to mine

if tArgs[1] == "1" then
  tunnel = "branch"
end

if tArgs[1] == "2" then
  tunnel = "main"
end

local mDistance = tArgs[2] or 0

print("I am making a ",tunnel, " tunnel, which is ",mDistance," long.")
local function forward(amount)
  amount = amount or 1  -- Default value of 1 if an "amount" value wasn't passed to the function.
  for i=1,amount do
    while not turtle.forward() do --#attempts to move forward
      turtle.dig() --#digs, regardless if there is a block there or not
      turtle.attack() --#attacks, regardless if there is a block there or not
    end
  end
end

local function up(amount)
  amount = amount or 1  -- Default value of 1 if an "amount" value wasn't passed to the function.
  for i=1,amount do
    while not turtle.up() do --#attempts to move up
      turtle.digUp() --#digs, regardless if there is a block there or not
      turtle.attackUp() --#attacks, regardless if there is a block there or not
    end
  end
end

local function down(amount)
  amount = amount or 1  -- Default value of 1 if an "amount" value wasn't passed to the function.
  for i=1,amount do
    while not turtle.down() do --#attempts to move down
      turtle.digDown() --#digs, regardless if there is a block there or not
      turtle.attackDown() --#attacks, regardless if there is a block there or not
    end
  end
end

local function fuelLevel()
  local fuelNow = 0
  fuelNow = turtle.getFuelLevel()
  print("Fuel level is: ",fuelNow)
  if fuelNow < 80 then
    turtle.select(1)
    turtle.refuel()
    turtle.getFuelLevel(fuelNow)
    print("Fuel level is now: ",fuelNow)
  end
end

local function turnAround()
  turtle.turnRight()
  turtle.turnRight()
end

local function returnHome()
  turnAround() 
  if tunnel == "branch" then
    for returnLocation = 0, (mDistance * 4) -1 do
      forward()
    end
  else
    for returnLocation = 0, (mDistance * 6) -1 do
      forward()
    end
  end
end

local function torchPlace()
  turtle.back()
  if turtle.getItemCount(3) > 0 then
    turtle.select(3)
    turtle.place()
  else
    print("Error not enough torches.")
  end
  print("Torch Count: ", turtle.getItemCount(3))  
end

local function placeF()
  turtle.select(2)
  turtle.place()
end

local function placeD()
  turtle.select(2)
  turtle.placeDown()
end

local function placeU()
  turtle.select(2)
  turtle.placeUp()
end

local function digFront()
  forward()
  turtle.turnLeft()
  placeF()
  placeD()
  turnAround()
  forward()
  placeD()
  forward()
  placeD()
  placeF()
  up()
  placeF()
  turnAround()
  forward(2)
  placeF()
  up()
  placeF()
  placeU()
  turnAround()
  forward()
  placeU()
  forward()
  placeU()
  placeF()
  turtle.turnLeft()
end

local function digTorch()
  forward()
  turtle.turnRight()
  placeF()
  placeU()
  turnAround()
  forward()
  placeU()
  forward()
  placeU()
  placeF()
  down()
  forward()
  placeF()
  torchPlace()
  turnAround()
  forward(3)
  placeF()
  torchPlace()
  down()
  placeF()
  turnAround()
  placeD()
  forward()
  placeD()
  forward()
  placeD()
  placeF()
  turtle.turnRight()
end

local function digRear()
  forward()
  turtle.turnLeft()
  placeF()
  placeD()
  turnAround()
  forward()
  placeD()
  forward()
  placeD()
  placeF()
  up()
  placeF()
  turnAround()
  forward(2)
  placeF()
  up()
  placeF()
  turnAround()
  placeU()
  forward()
  placeU()
  forward()
  placeU()
  placeF()
  turtle.turnLeft()
end

local function digRear2()
  forward()
  turtle.turnRight()
  placeF()
  placeU()
  turnAround()
  forward()
  placeU()
  forward()
  placeU()
  placeF()
  down()
  placeF()
  turnAround()
  forward(2)
  placeF()
  down()
  placeF()
  placeD()
  turnAround()
  forward()
  placeD()
  forward()
  placeD()
  placeF()
  turtle.turnRight()
end

function digTunnel()
  if tunnel == "branch" or tunnel == "main" then
    digFront()
    digTorch()
    digRear()
    digRear2()
    if tunnel == "main" then
      digRear()
      digRear2()
    end
    fuelLevel()
    moved = 1
  end
end

-- Main line
for currentLocation = 0, mDistance - 1 do
  digTunnel(currentLocation)
end

if moved == 1 then
  print("heading home!")
  returnHome()
end

Edit: I actually did have a question…. I want my refuel routine to refuel once if it finds itself below 80 units. is that what it is actually doing?
Edited on 23 September 2014 - 10:50 PM
KingofGamesYami #14
Posted 24 September 2014 - 01:03 AM
Edit: I actually did have a question…. I want my refuel routine to refuel once if it finds itself below 80 units. is that what it is actually doing?

No, because you never call it!

When I created my branch miner (you can find it on the forums), I used a "main" function and a "refuel" function (and another one, but it's not relevant at the moment) which I ran in parallel. It was nice, because I didn't have to keep calling my refuel function every time I moved (which consumes 1 fuel).