local distance = 0
function invenClear()
for i = 2 , 16 do
turtle.select(i)
turtle.drop()
function move()
repeat
turtle.dig()
until turtle.forward()
turtle.digup()
distance = distance + 1
print(distance)
if turtle.getItemCount(16) >0 then
turtle.turnLeft()
turtle.forward(distance)
InvenClear()
turtle.turnLeft(2)
distance = 0
end
end
end
end
move(10)
This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
[lua] [error] attempt to call nil
Started by pixels_deth, 31 March 2013 - 07:17 PMPosted 31 March 2013 - 09:17 PM
Im kinda new to computercraft, and i'm writing a mining program for a mining turtle. However when I try to run it I get "mine:26: attempt to call nil". Here is the code:
Posted 31 March 2013 - 09:20 PM
I notice however that you have bad cases on function calls, Lua IS case-sensitive so change things such as InvenClear() to invenClear() and turtle.digup() to turtle.digUp()
also turtle.turnLeft(2) there is no parameter for turtle functions that specify how many times to do it. same for turtle.forward(distance)
lastly you call move(10) but do not accept any parameters for the function
function move()
Posted 31 March 2013 - 09:34 PM
Okay, thanks for the trouble shooting tips, I must remember them in every program. I have changed my program to:
However I still get the "attempt to call nill" error. Also I'm afraid I dont understand what you mean by parameters. Surley the 10 is a parameter?
local distance = 0
function invenClear()
for i = 2 , 16 do
turtle.select(i)
turtle.drop()
function move()
repeat
turtle.dig()
until turtle.forward()
turtle.digUp()
distance = distance + 1
print(distance)
if turtle.getItemCount(16) >0 then
turtle.turnLeft()
turtle.turnLeft()
for i = 1,distance do
turtle.forward()
invenClear()
turtle.turnLeft()
turtle.turnLeft()
distance = 0
end
end
end
end
end
move()
However I still get the "attempt to call nill" error. Also I'm afraid I dont understand what you mean by parameters. Surley the 10 is a parameter?
Posted 31 March 2013 - 09:45 PM
ok so im assuming the error was on line 27 this time… and this time I see why :P/>
you have your functions nested, so it cannot see the move function. if you end the for loop and the invenClear functions it should be all good…
the 10 is a parameter, but your move function was not setup to receive the '10'… so it did not have a purpose…
to have it accept a parameter you do this
you have your functions nested, so it cannot see the move function. if you end the for loop and the invenClear functions it should be all good…
local distance = 0
function invenClear()
for i = 2 , 16 do
turtle.select(i)
turtle.drop()
end
end
function move()
repeat
turtle.dig()
until turtle.forward()
turtle.digUp()
distance = distance + 1
print(distance)
if turtle.getItemCount(16) >0 then
turtle.turnLeft()
turtle.turnLeft()
for i = 1,distance do
turtle.forward()
invenClear()
turtle.turnLeft()
turtle.turnLeft()
distance = 0
end
end
end
move()
the 10 is a parameter, but your move function was not setup to receive the '10'… so it did not have a purpose…
to have it accept a parameter you do this
function move( parameterName )
-- function code
end
Posted 31 March 2013 - 10:17 PM
Thank you very much for all your help so far, I have changed my code to:
It runs without any error, but it will only go one block forward. Sorry to be a pain, but I think im nearly there!
local distance = 0
function invenClear()
for i = 2 , 16 do
turtle.select(i)
turtle.drop()
end
end
function move( parameterName )
repeat
turtle.dig()
until turtle.forward()
turtle.digUp()
distance = distance + 1
print(distance)
if turtle.getItemCount(16) >0 then
turtle.turnLeft()
turtle.turnLeft()
for i = 1,distance do
turtle.forward()
invenClear()
turtle.turnLeft()
turtle.turnLeft()
distance = 0
end
end
end
move(10)
It runs without any error, but it will only go one block forward. Sorry to be a pain, but I think im nearly there!
Posted 31 March 2013 - 10:24 PM
you need to change your repeat loop to use the parameter that is passed into the move function… also you can name it whatever you wish, it doesn't need to be named parameterName… :P/>
Posted 31 March 2013 - 10:35 PM
Thanks, i changed the parameterName to moves, how do I make the repeat loop use the parameter?
Posted 31 March 2013 - 11:11 PM
Use a for loop rather
function move( moves )
for i = 1, moves do
turtle.dig()
end
turtle.digUp()
distance = distance + 1
print(distance)
if turtle.getItemCount(16) >0 then
turtle.turnLeft()
turtle.turnLeft()
for i = 1,distance do
turtle.forward()
invenClear()
turtle.turnLeft()
turtle.turnLeft()
distance = 0
end
end
end
Posted 31 March 2013 - 11:53 PM
Remix, I dont think you understand the purpose of the repeat loop. I put it there to deal with gravel and sand, so that the turtle would dig until it could move forward. If I were to use the for loop, the turtle would just dig 10 times without moving.
Posted 01 April 2013 - 12:01 AM
oh is that what it's for. I assumed the same as remiX.Remix, I dont think you understand the purpose of the repeat loop. I put it there to deal with gravel and sand, so that the turtle would dig until it could move forward. If I were to use the for loop, the turtle would just dig 10 times without moving.
here is a solution
function move( moves )
for i = 1, moves do -- this makes it run the amount of times we want
while turtle.detect() do
turtle.dig()
sleep(0.8) -- wait for how long it takes for gravel/sand to fall
end
if not turtle.forward() then
if turtle.getFuelLevel() <= 0 then
-- handle the fact we are out of fuel
elseif not turtle.attack() then
while turtle.attack() do end -- it was a mob
else
error('We cannot move for some reason', 0)
end
end
while turtle.detectUp() do -- we should do this gravel too
turtle.digUp()
sleep(0.8) -- wait for how long it takes for gravel/sand to fall
end
distance = distance + 1
print(distance)
if turtle.getItemCount(16) > 0 then
turtle.turnLeft()
turtle.turnLeft()
for i = 1,distance do
turtle.forward()
invenClear()
turtle.turnLeft()
turtle.turnLeft()
distance = 0
end
end
end
end
Posted 01 April 2013 - 12:03 AM
What if you put a 'while <condition> do' at the top + end at the bottom?Remix, I dont think you understand the purpose of the repeat loop. I put it there to deal with gravel and sand, so that the turtle would dig until it could move forward. If I were to use the for loop, the turtle would just dig 10 times without moving.
With the code Remix put there.
Spoiler
function move( moves )
while true do
for i = 1, moves do
turtle.dig()
sleep(0.8) --The time for gravel and sand to fall
end
turtle.digUp()
distance = distance + 1
print(distance)
if turtle.getItemCount(16) >0 then
turtle.turnLeft()
turtle.turnLeft()
for i = 1,distance do
turtle.forward()
invenClear()
turtle.turnLeft()
turtle.turnLeft()
distance = 0
end
end
end
end
Posted 01 April 2013 - 12:30 AM
remiX's solution doesn't fit even with the infinite loop. if would have problems with sand/gravel still…What if you put a 'while <condition> do' at the top + end at the bottom?
Posted 01 April 2013 - 12:53 AM
But isn't the falling time of sand/gravel 0.8 ?remiX's solution doesn't fit even with the infinite loop. if would have problems with sand/gravel still…What if you put a 'while <condition> do' at the top + end at the bottom?
I think it is, And if you look at the code I added that there.
Posted 01 April 2013 - 12:54 AM
yes but it also means that it will only dig 10 gravel (if it can) and then it will move forever… if you take a look at the code I posted and compare it to remix/yours you should see what I mean…But isn't the falling time of sand/gravel 0.8 ?
I think it is, And if you look at the code I added that there.
Posted 01 April 2013 - 02:32 AM
Thank you for all the help everyone. It seems that after every solution theres another problem. I've decided to just use someone else's mining program for now, but I'll keep trying and hopefully I'll succeed eventually.
Posted 01 April 2013 - 02:35 AM
Welcome to the world of programming… here is a breakdown of how I spend my time when making programs in ComputerCraft:It seems that after every solution theres another problem.
- ~15-20% of my time figuring out the problem and how I am going to approach it
- ~20% of my time design
- ~5-10% of my time coding the solution
- 55% of my time debugging the code and getting it work as best as possible for release
Posted 01 April 2013 - 09:58 AM
Okay, decided to give this another try, wrote this:
It runs without displaying any error messages, but it also doesn't do anything else! The program ends immediatly.
local distance = 0
function forward()
repeat
turtle.dig()
until turtle.forward()
turtle.digUp()
distance = distance + 1
print(distance)
end
function invCheck()
if turtle.getItemCount(15) >= 1 then
print( "Returning items to chest" )
turtle.turnLeft()
turtle.turnLeft()
for i = 1,distance do
turtle.forward()
end
for i =1,15 do
turtle.select(i)
turtle.drop()
end
turtle.select(1)
turtle.turnLeft()
turtle.turnLeft()
distance = 0
end
repeat
forward()
invCheck()
until distance == 100
turtle.turnLeft()
turtle.turnLeft()
for i = 1,100 do
turtle.forward()
end
end
It runs without displaying any error messages, but it also doesn't do anything else! The program ends immediatly.
Posted 01 April 2013 - 04:21 PM
you have 2 functions there, neither of which you call… Lua needs a function call to run a function. so which ever is your main function (im assuming invCheck) run it at the bottom of your codeIt runs without displaying any error messages, but it also doesn't do anything else! The program ends immediatly.
Posted 01 April 2013 - 09:49 PM
How could I have missed that? Anyway, added both the functions at the end:
Still nothing. I dont understand why its not doing anything.
local distance = 0
-- making the turtle dig and move
function forward()
repeat
turtle.dig()
until turtle.forward()
turtle.digUp()
distance = distance + 1
print(distance)
end
-- checking for near full inventory
function invCheck()
if turtle.getItemCount(15) >= 1 then
print( "Returning items to chest" )
turtle.turnLeft()
turtle.turnLeft()
for i = 1,distance do -- returning to chest at the front of the tunnel
turtle.forward()
end
for i =1,15 do
turtle.select(i)
turtle.drop()
end
turtle.select(1)
turtle.turnLeft()
turtle.turnLeft()
distance = 0
end
repeat -- repeat both until turtle has mined 100 blocks
forward()
invCheck()
until distance == 100
turtle.turnLeft() -- move the turtle into position
turtle.turnLeft()
for i = 1,100 do -- return to the chest
turtle.forward()
end
end
Still nothing. I dont understand why its not doing anything.
Posted 02 April 2013 - 12:42 AM
--tunneling programm
local distance = 0
local complete = 0
function invCheck()
return turtle.getItemCount(15) >= 1
end
function returnBack()
print("Returning back")
turtle.turnLeft()
turtle.turnLeft()
for i = 1,distance do -- returning to chest at the front of the tunnel
--Im recommend insert there call of function for fuel checking and refueling
turtle.forward()
end
end
function unloadItems()
print("Unloading items")
for i=1,15 do
turtle.select(i)
turtle.drop()
end
turtle.select(1)
end
function mineForward(up,down,aggresive)
while turtle.detect() do
turtle.dig()
end
if up then
while turtle.detectUp() do
turtle.digUp()
end
end
if down then
while turtle.detectDown() do
turtle.digDown()
end
end
if not turtle.forward() then
if aggresive then
turtle.attack() --if blocking way by monster/player
end
mineForward(up,down,aggresive) --recursing for again attack monster/player and trying move forward
end
end
function tunneling(len,up,down,aggresive)
print("Starting tunneling. Tunnel length == "..tostring(len))
while distance<len do
while not invCheck do
--Im recommend insert there call of function for fuel checking and refueling
turtle.select(1)
mineForward(up,down,aggresive)
end
returnBack()
unloadItems()
turtle.turnLeft()
turtle.turnLeft()
distance = 0
if distance % 10 == distance / 10 then
if distance>complete then
print("Complete "..tostring(distance).." of "..tostring(len).." tunneling.")
complete=distance
end
end
end
returnBack()
unloadItems()
turtle.turnLeft()
turtle.turnLeft()
print("Tunneling complete. Tunnel length == "..tostring(len))
end
tunneling(100,true,false,false)
Try this programm.
Posted 02 April 2013 - 03:12 AM
why oh why are you using recursion…. no! bad Ray_Anor! bad! you should use a loop there.--tunneling programm local distance = 0 local complete = 0 function invCheck() return turtle.getItemCount(15) >= 1 end function returnBack() print("Returning back") turtle.turnLeft() turtle.turnLeft() for i = 1,distance do -- returning to chest at the front of the tunnel --Im recommend insert there call of function for fuel checking and refueling turtle.forward() end end function unloadItems() print("Unloading items") for i=1,15 do turtle.select(i) turtle.drop() end turtle.select(1) end function mineForward(up,down,aggresive) while turtle.detect() do turtle.dig() end if up then while turtle.detectUp() do turtle.digUp() end end if down then while turtle.detectDown() do turtle.digDown() end end if not turtle.forward() then if aggresive then turtle.attack() --if blocking way by monster/player end mineForward(up,down,aggresive) --recursing for again attack monster/player and trying move forward end end function tunneling(len,up,down,aggresive) print("Starting tunneling. Tunnel length == "..tostring(len)) while distance<len do while not invCheck do --Im recommend insert there call of function for fuel checking and refueling turtle.select(1) mineForward(up,down,aggresive) end returnBack() unloadItems() turtle.turnLeft() turtle.turnLeft() distance = 0 if distance % 10 == distance / 10 then if distance>complete then print("Complete "..tostring(distance).." of "..tostring(len).." tunneling.") complete=distance end end end returnBack() unloadItems() turtle.turnLeft() turtle.turnLeft() print("Tunneling complete. Tunnel length == "..tostring(len)) end tunneling(100,true,false,false)
Try this programm.
Posted 02 April 2013 - 03:22 AM
Recursion loops are obviously the better choice at hand. Duh! (Not really.. Use a while loop or repeat until condition is met loop like TOBIT said ^_^/>)why oh why are you using recursion…. no! bad Ray_Anor! bad! you should use a loop there.
Posted 02 April 2013 - 04:28 AM
why oh why are you using recursion…. no! bad Ray_Anor! bad! you should use a loop there.
it's work fine for me. :)/>
But! Better choise to insert some counter for this… and break recursion…
Maybe - insert also os.sleep(0.2) there if wil too bugging….
But! It's work fine in my look :)/>
Posted 02 April 2013 - 04:30 AM
Recursion loops are obviously the better choice at hand. Duh! (Not really.. Use a while loop or repeat until condition is met loop like TOBIT said ^_^/>)why oh why are you using recursion…. no! bad Ray_Anor! bad! you should use a loop there.
and.. it's not my task in this algorithm to do ideal algorithm… it's only give chance to take a look for asker for him errors - how to do better him idea ;)/>
Posted 02 April 2013 - 05:17 AM
Okay, here's my finished product, I may add torches and refuelling if I get around to it. Not much of an issue for me though, I'm on a peaceful world with stacks and stacks of coal.
I think ill refine it a bit more to allow user configuration, and then upload it.
local distance = 0
function move()
repeat
turtle.dig()
until turtle.forward()
turtle.digUp()
distance = distance + 1
print(distance)
end
function invCheck()
if turtle.getItemCount(15) >= 1 then
print("Returning items to chest...")
turtle.turnLeft()
turtle.turnLeft()
for i = 1,distance do
turtle.forward()
end
for i = 1,15 do
turtle.select(i)
turtle.drop()
end
turtle.select(1)
turtle.turnLeft()
turtle.turnLeft()
distance = 0
end
end
repeat
move()
invCheck()
until distance == 500
turtle.turnLeft()
turtle.turnLeft()
for i = 1,500 do
turtle.forward()
end
I think ill refine it a bit more to allow user configuration, and then upload it.
Posted 02 April 2013 - 05:21 AM
That's the thing. It works fine until the stack fills up with function calls then crashes.. Use loops, not recursion(function calls to keep a program running is defined as recursion)why oh why are you using recursion…. no! bad Ray_Anor! bad! you should use a loop there.
it's work fine for me. :)/>
Pixel's latest code does not use recursion to my knowledge.
This is more glorious, wear it with pride young grasshopper:
However, I would do this instead of your repeat loop:
while distance <500 and distance ~=500 do --Just safety precautions :)/>
move()
invCheck()
end