Warm tip: This article is reproduced from serverfault.com, please click
lua

Lua 3d table lacks object permanence (key values do not consistently match to table data)

发布于 2020-12-02 22:57:51

So I'm having a bit of a strange problem with Lua, I use the following functions to setup, read and write from a global 3D "array" called Cube. However it seems that every time I am reading or writing to this "array", the data is only stored on the instance used by the function, despite Cube being a global variable, can't say I have ever encountered this before, very strange.

-- stole this one from: https://stackoverflow.com/questions/27976526/using-a-coordinate-pair-as-a-key-in-a-lua-table
-- basically the intended use is to store a 2d table of block information for the level the turtle is on

function setUpLevel()
    local test = {_props = {}}
    local mt = {}


    local function coord2index(x, z)
        return ((x-1) * xMax) + z
    end

    mt.__index = function(s, k)
        if s._props[coord2index(k[1], k[2])] ~= nil then
            return s._props[coord2index(k[1], k[2])]
        end
    end

    mt.__newindex = function(s, k, v)
    s._props[coord2index(k[1], k[2])] = v 
    end
    mt.__call = function (t, k)
        if type(k) == "table" then print "Table" end
    end

    setmetatable(test, mt)
    return test
    --test[{1,2}] = 5
end

function setupCube()
    local cube = {}
    cube[relY]=setUpLevel()
    return cube
end

Cube = setupCube()

function readCubeData(x,y,z)
    if (Cube[y]==nil) then
        return nil
    end
    -- debug
    return Cube[y][{x,z}]
end

function storeCubeData(x,y,z,data)
    if (readCubeData(x,y,z)==nil) then
        Cube[y]=setUpLevel()
    end



    Cube[y][{x,z}]=data
    data= readCubeData(x,y,z)
    print (x,",",y,",",z,":",readCubeData(x,y,z))
    sleep(.5)
end

Output Examples:

The print statements in storeCubeData() would provide the correct output of (order doesn't matter, just corresponding data to x,y,z values) Image showing the output from readCubeData() function when used within storeCubeData()

However the following print statements in start()

function start()
    detectAndStore()
    print("=============")
    sleep(1)
    data= readCubeData(0,relY,1)
    print (0,",",relY,",",1,":",readCubeData(0,relY,1))
    sleep(.5)
    data= readCubeData(-1,relY,0)
    print (-1,",",relY,",",0,":",readCubeData(-1,relY,0))
    sleep(.5)
    data= readCubeData(0,y,-1)
    print (0,",",relY,",",-1,":",readCubeData(0,relY,-1))
    sleep(.5)
    data= readCubeData(1,y,0)
    print (1,",",relY,",",0,":",readCubeData(1,relY,0))
    sleep(.5)
end
start()

would produce an output of Output from start() function, incorrect output, mismatch between x,y,z values and data which is supposed to be in it

which is just tragically incorrect, the x,y,z values do not point to the correct values and also tables are not meant to be repeated in the same x,y,z location. I seriously can't for the life of me figure this out

Questioner
Percy Jackson
Viewed
0
Alexander Mashin 2020-12-04 09:43:13

The error is in if (readCubeData(x,y,z)==nil) then in storeCubeData(x,y,z,data). You overwrite the entire 'level' every time you try to store new information in it. It should be if (Cube [y] == nil) then. The whole if statement can be further reduced to Cube [y] = Cube [y] or setUpLevel ().

Also, if s._props[coord2index(k[1], k[2])] ~= nil then is not necessary; and the functions can be defined as local; and the hash function coord2index will cause collisions (e.g. coord2index (1, 5) == coord2index (2, -5), if xMax == 10), so replace it as @Egor Skriptunoff said.