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

Very simple Tunneling program Question

Started by xasuma, 03 December 2013 - 09:00 PM
xasuma #1
Posted 03 December 2013 - 10:00 PM
Hi, this is my very first program.
It's purpose is to make a 3x3 tunnel to whatever length you tell it to. The features it should have as of now are: Place torches every 9 cycles, check for fuel and refuel when you have less than 80 fuel left, tell you how much fuel you have periodically.

The part that I can't get to work is to place torches. Everything else works as planned for now.
Here is the pastebin: http://pastebin.com/L4qXba4D

The code might not be efficient, but its my first attempt. Thanks!
himdo #2
Posted 04 December 2013 - 06:24 AM
the problem is inside :

function placeTorch()

torch = 0

if torch == 3 then
turtle.turnLeft()
turtle.turnLeft()
turtle.select(2)
turtle.place()
turtle.turnLeft()
turtle.turnLeft()
torch = 0
else
torch = torch + 1
end

end

what happens is that as soon as you use that function it turns torch into 0 nomatter what it was at before. what i would do to fix this is type


function placeTorch(torch)
if torch == 3 then
turtle.turnLeft()
turtle.turnLeft()
turtle.select(2)
turtle.place()
turtle.turnLeft()
turtle.turnLeft()
torch = 0
else
torch = torch + 1
end
return torch
end

and at the very top of your program declare torch as 0.
then whenever you all the funchtion call it as
torch = placeTorch(torch)
that should work
Buho #3
Posted 04 December 2013 - 10:19 AM
Does cycle() work? My reading has it starting at the bottom-center of the future 3x3 area but finishing at the center-center of the 3x3 area.

placeTorch() doesn't work because the variable torch is always 0 at line 40. Also, what slot holds the torch? Let's assume slot 1 holds a maximum of 64 torches:


function placeTorch()
    --Turtle starts here at center of 3x3 area facing forward
    --Torches in slot 1
    turtle.turnLeft()
    if turtle.getItemCount(1) > 1 then
        --Do not place torch if only 1 left in inven!
        turtle.select(1)
        turtle.place()
    end
    turnRight()
end

for i = 1, length do
    cycle()
    if i % 9 == 0 then placeTorch() end
    gettingCoal()
end

The modulus operator % is super-helpful for periodic things like placing torches (or powered rails) every X cycles. My recommendation is to pull the logic of when to place outside of the function. placeTorch() should place a torch every time you call it. If you don't like the messiness in your main loop, pass i into the function and dispense with the torch variable.

Take the example code above with a grain of salt; I didn't follow your code completely.
Buho #4
Posted 04 December 2013 - 10:25 AM
By the way, that's a nice program for being your first! You can optimize the cycle() function. Take a cue from the built-in program "tunnel" that does not strafe left-right as yours does.
xasuma #5
Posted 04 December 2013 - 11:46 AM
Thank you very much for the answers , I got it to work!
There are a few things I will look up some tutorials on, like return and modulus to understand them fully.

The cycle does work correctly but I will look into optimizing it as you mentioned. Next step will be to make it gravel/sand/mob proof.

Thanks again! :)/>
xasuma #6
Posted 04 December 2013 - 03:36 PM
Trying to further improve the program I encountered some questions.

Pastebin Here —> http://pastebin.com/x2K2uSb1

Line 33: I want to say, "If turtle detected a block but turtle did not dug it, then…" –> I don't know how to make this work. It said I couldn't concatenate them when i tried.
Line 144: I want to say, "If the user inputs any of the following, then…" –> I don't know how to write it so it allows all those options.
Line 160: If the user said something else to the question, then terminate the program. How do I command it to terminate?

Thank you in advanced, I feel I am learning quite a lot, I just get stuck on details like these.
Oh and I improved my cycle from spending 11 fuel p/cycle down to 5 fuel p/cycle.


Edit: 2 hours later, I've also managed to make the turtle mob/player proof when moving forward, up or down(kind of). The problem is that, when going down, a player isn't actually tall enough for the turtle to attack him. If I jump under it then it will attack me, but just standing still I am not reached by it. Any thoughts on how to fix this? Is it a bug??
Pastebin for the lastest version with the Edit: http://pastebin.com/hsGRsV4G
Edited on 04 December 2013 - 04:14 PM
Bomb Bloke #7
Posted 04 December 2013 - 06:08 PM
Line 33: I want to say, "If turtle detected a block but turtle did not dug it, then…" –> I don't know how to make this work. It said I couldn't concatenate them when i tried.
To check whether the turtle failed to dig a block, you'd use "if not turtle.dig() then" or "while not turtle.dig() do". Note that this will not cover scenarios where the turtle successfully dug up a block, then another block fell into the same position.

To have a turtle continuously dig until the space in front of it was clear, you'd use something like:

while turtle.detect() do
  turtle.dig()
  sleep(0.8)  -- Wait about the amount of time it takes gravel to fall.
end

Line 144: I want to say, "If the user inputs any of the following, then…" –> I don't know how to write it so it allows all those options.
To correct your current code:

if personInput == "Y" or personInput == "y" or personInput == "yes" or personInput == "Yes" or personInput == "YES" then

However, it can be further improved. Tacking ":lower()" onto the end of a string calls a function that returns a lowercase version, meaning you don't need to check against all possible combinations of letter case. I would also cheat somewhat and just check to see if the first character is a "y", by further pulling a substring:

if personInput:sub(1,1):lower() == "y" then

See here for more details on string manipulation.

Line 160: If the user said something else to the question, then terminate the program. How do I command it to terminate?
error()'s one way. Note that when the Lua interpretor runs out of code to run, it'll kill your program automatically.
xasuma #8
Posted 04 December 2013 - 07:12 PM
To check whether the turtle failed to dig a block, you'd use "if not turtle.dig() then" or "while not turtle.dig() do". Note that this will not cover scenarios where the turtle successfully dug up a block, then another block fell into the same position.

To have a turtle continuously dig until the space in front of it was clear, you'd use something like:

while turtle.detect() do
  turtle.dig()
  sleep(0.8)  -- Wait about the amount of time it takes gravel to fall.
end

What I meant here was : How would I put "if turtle.detect()" but "turtle did not dig" then …

The problem is here:
Spoilerhttp://postimg.org/image/z5mkk7r0z/

Here is the turtle ready to start a cycle, if you note in the left side, gravel will fall when I break the middle left cobblestone Block.

http://postimg.org/image/ohitldh1v/

As gravel falls, the turtle is too slow to mine it as it's falling. So it moves on and this is left:

http://postimg.org/image/p8d4hjccl/

So when that happens , I need the turtle to know that when he detected the gravel falling, but wasnt quick enough to break it, then (to do the commands I have prepared to fix it)

Therefore : if turtle.detect() and if not turtle.dig() then —> ( I just don't know how you would say that)


~~ Everything else worked perfectly thanks for the help! :)/>

SpoilerI am also still curious to know if a turtle will attack a mob/player directly underneath it. Because when I test mine it will not attack me unless I jump. If anyone knows about this would be awesome!
Buho #9
Posted 06 December 2013 - 08:39 AM
The only scenario where a turtle will detect a block but cannot dig it is bedrock, if I'm not mistaken. It's a useful thing to look for. But looking at your code, I'm not sure what you're trying to achieve. Going down one and digging under the undiggable block?

local isBedrock = turtle.detect() and not turtle.dig()

Aside from the variable on the left, that's the simplest of what you're asking for. You almost had it (you had an extra "if"). But where you want this check is inside a block of code that has already successfully dug.

I see your problem with the gravel. I think your best bet is to start your cycle at the top and work down. This way you will get all the gravel.

Not sure if a turtle will attack a mob/player directly under it. It will when in front. I recently have put some "polite" code into my movement functions. (I almost always write fwd(), up(), dwn(), and bck() functions.)


function fwd()
    --Nondestructive move, won't break blocks
    local i = 0
    while not turtle.forward() do
        if i = 4 then
            print("Excuse me, you're in my way.")
        end
        if i = 8 then
            print("Don't make me use force!")
        end
        if i > 10 then
            turtle.attack()
        end
        i = i + 1
        os.sleep(2)
    end
end

Heh.
xasuma #10
Posted 06 December 2013 - 11:06 AM
Thanks very much for the input.
The problem in my code with not attacking down was actually me forgetting to type turtle.attackDown(), ~I had turtle.attack() ~ lol.
I also thought about making the cycle start at the top instead. Since you also mentioned it I think I will do that!

~Now I have a better version (in my opinion) of the tunnel program. :)/>

Nice polite code btw, a little too polite for my purposes though haha.