Search code examples
loopsluaiterationpath-finding

lua: comparing entries of tables in tables


I need to duplicate each 'pos' from {CLOSED} into {PATH}, but in order of where they 'came_from' starting with 'target'. It's the last part of a pathfinding method. I've been unsuccessful turning my pseudo-code into lua code and need help doing so. I think it would be easiest for me to understand if someone could convert the pseudocode into code as there are a few underlying fundamentals at play here I'm confusing with eachother.

i.e. path={{x=33,y=44},{x=22,y=25},{x=0,y=0}}

start={x=0,y=0}
target={x=33,y=44}
CLOSED={
    {pos={x=33,y=44},came_from={x=22,y=25}},
    {pos={x=0,y=0},came_from={x=nil,y=nil}},
    {pos={x=22,y=25},came_from={x=0,y=0}}
}
PATH={}

--outline:
current=target

while current~=start do
    add(path,current)
--??    current=CLOSED[i].came_from[current]??
--outstanding steps:
--check current against each 
--CLOSED[i].pos
--if we have a match, 
--current=closed[i].came_from
--repeat
end

Solution

  • Tables can't be compared unless specifically assigned to eachother (i.e. {a}={b}). So you have to grab and compare the individual values of all the keys of same variable (i.e. x and y). The functions below can do that, returning true if they get a hit. Another more specific method would be to convert the x,y coordinates from 2d to 1d and compare the integers(so with an nxm matrix its x+m*y).

    start={x=0,y=0}
    target={x=33,y=44}
    closed={
        {pos={x=33,y=44},came_from={x=22,y=25}},
        {pos={x=0,y=0},came_from={x=nil,y=nil}},
        {pos={x=22,y=25},came_from={x=0,y=0}}
    }
    path={}
    
    --outline:
    current=target
    function subset(a,b)
        for k,v in pairs(a) do
      if b[k]~=v then return false end
        end
     return true
    end
    function equal(a,b)
     return subset(a,b) and subset(b,a)
    end
    
    while current.x~=start.x and current.y~=start.y do
        --check current against each 
        --closed[i].pos
        --if we have a match, 
        --current=closed[i].came_from
        --repeat
     add(path,current)
        for i=1,#closed do
            if equal(current,closed[i].pos) then
                current=closed[i].came_from
                break
            end
        end
    end
    add(path,start)
    
    
    --expected path={{x=33,y=44},{x=22,y=25},{x=0,y=0}}
    --check:
    for k,v in pairs(path) do
        for k,v in pairs(v) do
        print(k.."="..tostr(v))
        end
    end