1

I'm trying to pass a table through several functions and return it, but it only works to a certain degree. I'm almost sure it has to do something with the scoping, but I can't work it out since I'm new with LUA. I tried putting the table in line 1 and setting it global, but to no avail. Error: bag argument: expected table but got nil.

function returnToTunnel(movementTable)
    for i = table.maxn(movementTable), 1, -1  do  --this is where I get the error.
        if (movementTable[i] == 1) then
            turtle.down()
        elseif (movementTable[i] == 2) then
            turtle.up()
        elseif (movementTable[i] == 3) then
            turtle.back()
            turtle.turnRight()
        elseif (movementTable[i] == 4) then
            turtle.back()
            turtle.turnLeft()
        elseif (movementTable[i] == 5) then
            turtle.back()
        end
    end
end

function mineOre(locationParam, movementTable)
    if (locationParam == 1) then
        turtle.digUp()
        turtle.suckUp()
        turtle.up()
        table.insert(movementTable, 1)
    elseif (locationParam == 2) then
        turtle.digDown()
        turtle.suckDown()
        turtle.down()
        table.insert(movementTable, 2)
    elseif (locationParam == 3) then
        turtle.turnLeft()
        turtle.dig()
        turtle.suck()
        turtle.forward()
        table.insert(movementTable, 3)
    elseif (locationParam == 4) then
        turtle.turnRight()
        turtle.dig()
        turtle.suck()
        turtle.forward()
        table.insert(movementTable, 4)
    elseif (locationParam == 5) then
        turtle.dig()
        turtle.suck()
        turtle.forward()
        table.insert(movementTable, 5)
    end
    locationParam = oreCheck()
    if (locationParam > 0) then
        mineOre(locationParam, movementTable)
    else
        return movementTable
    end
end

function digTunnel(tunnelLengthParam)
    local oreFound
    local movement = {}

    for i = 1, tunnelLengthParam do
        turtle.dig()
        turtle.forward()
        oreFound = oreCheck()
        if (oreFound > 0) then
            movement = mineOre(oreFound, movement)
            returnToTunnel(movement)
        end
        if ((i % 2) == 1) then
            turtle.digUp()
            turtle.up()
        elseif ((i % 2) == 0) then
            turtle.digDown()
            turtle.down()
        end
        oreFound = oreCheck()
        if (oreFound > 0) then
            movement = mineOre(oreFound, movement)
            returnToTunnel(movement)
        end
    end
end

So, the digTunnel function calls the other two functions mineOre and returnToTunnel.

I've been looking in the LUA manual and several websites but can't figure it out. Thank you for your help!

3
  • Just a hint: If you're trying to implement backtracking, you can very easily do that using recursion :D Commented Mar 30, 2020 at 12:35
  • @DarkWiiPlayer Unfortunately I don't know how. I chose the table, since it documents the movement and I want it to return after it's done mining ore. I don't even have an idea how I could do that with recursion, but I would like to. :) Commented Mar 31, 2020 at 14:46
  • Have a function that: Scans for ores, mines them, moves to that spot, calls itself and then returns to its initial position. Each function only moves one block forward and back again, so you always end up at the same position :D Commented Apr 1, 2020 at 6:06

1 Answer 1

2

Your function mineOre does not return a table but nil, when locationParam is > 0.

if (locationParam > 0) then
  mineOre(locationParam, movementTable)
else
  return movementTable
end

Hence this will cause a nil value end up in table.maxn

 movement = mineOre(oreFound, movement)
 returnToTunnel(movement)
Sign up to request clarification or add additional context in comments.

3 Comments

I see. Where I was going with this was, first when digging the tunnel it will scan for ores. If it finds one it will go into the mineOre function. Since ores come in groups I want it to be recursive. The if condition does just that, the function to scan for ores returns a number higher than 0 if there are any ores nearby. Based on that it will start mining again. So if I correct my code to return mineOre(locationParam, movementTable) it will still be recursive and deliver me a table with multiple entries, right?
yes but you don't have to assign movement = mineOre in the first place as tables are copied by reference. all recursive calls will operate on the very same table value anyway.
Good to know, thanks! The program worked perfectly afterwards.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.