Watch window unable to exlpore tables more than 3 levels deep?
Consider the following screenshot: <a href="http://img352.imageshack.us/img352/9507/image1fa4.png" target="_blank">http://img352.imageshack.us/img352/9507/image1fa4.png</a>
The first item in the watch window is the_maze.nodes[1], and the second is the_maze expanded to look at the nodes table. The first way shows the members of the_maze.nodes[1], while the second reports the_maze.nodes[1] as {}. Also note that the_maze.nodes[1].maze.nodes is reported as an empty table {}, however the_maze.nodes[1].maze == the_maze, therefore the nodes table cannot be empty.
The code in question:<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->function maze()
node"B"(0, 0) B"BJ" node"J"(2, 0) R"JN" node"N"(4, 0)
Y"BI" R"BD" Y"DJ" Y"JK" B"JL" B"LN" Y"NP"
node"I"(0, 1) Y"ID" node"D"(1, 1) R"DK" node"K"(2, 1) R"KL" node"L"(3, 1) Y"LP" node"P"(4, 1)
R"IT" B"DT" R"TK" R"RK" B"KR" Y"LR" B"RP"
B"IC" node"T"(1, 2) finish"G"(2, 2) node"R"(3, 2) R"PS"
R"CT" Y"AT" B"TH" R"HR" Y"RE" Y"RS"
node"C"(0, 3) B"CA" node"A"(1, 3) R"AH" node"H"(2, 3) Y"HE" node"E"(3, 3) B"ES" node"S"(4, 3)
Y"CV" B"AV" R"AM" B"HM" B"EM" R"EF" B"SF"
node"V"(0, 4) R"VM" node"M"(2, 4) Y"MF" node"F"(4, 4)
R"M*"
start"*"(2, 5)
end
local function getnode(n, m)
m = m or maze
return m[n] or m.nodes[n] or n
end
do
local maze_fn = maze
maze = function()
local the_maze = {
nodes = {},
edges = {
red = {},
yellow = {},
brown = {},
},
}
local function add_node(name, x, y, special)
local node = {
maze = the_maze,
name = name,
x = x,
y = y,
idx = #the_maze.nodes + 1,
edges = {
red = {},
yellow = {},
brown = {},
},
}
if special then
node[special] = true
the_maze[special] = node
end
the_maze.nodes[node.idx] = node
the_maze.nodes[node.name] = node
end
local function add_edge(colour, nodes)
local set = the_maze.edges[colour]
local edge = {
maze = the_maze,
name = nodes,
colour = colour,
idx = #set + 1,
from = nodes:sub(1, 1),
to = nodes:sub(2, 2),
}
edge.cost = 1
set[edge.idx] = edge
set[edge.name] = edge
end
local f_env = {
node = function(name) return function(x, y) add_node(name, x, y ) end end,
start = function(name) return function(x, y) add_node(name, x, y, "start" ) end end,
finish = function(name) return function(x, y) add_node(name, x, y, "finish") end end,
Y = function(names) add_edge("yellow", names) end,
R = function(names) add_edge("red" , names) end,
B = function(names) add_edge("brown" , names) end,
}
setfenv(maze_fn, f_env)()
for colour, edges in pairs(the_maze.edges) do
for _, edge in ipairs(edges) do
edge.from = getnode(edge.from, the_maze)
edge.to = getnode(edge.to, the_maze)
edge.from.edges[edge.colour][edge] = edge.to
edge.to .edges[edge.colour][edge] = edge.from
end
end
return the_maze
end
end
maze = maze()
local function pathfind_compare(p1, p2)
return p1.cost < p2.cost
end
function solve(sequence)
print("Solving for " .. table.concat(sequence, ", ") .. " ...")
local queue = { {node = getnode"start", phase = 0, previous = nil, cost = 0} }
local closed = setmetatable({}, {__index = function(t, k) local v = {}; t[k] = v; return v end})
while queue[1] do
local path = queue[1]
table.remove(queue, 1)
if not closed[path.node][path.phase] then
closed[path.node][path.phase] = true
if path.node.finish then
print "Route found: ..."
return true
end
local next_phase = (path.phase + 1) % #sequence
for edge, node in pairs(path.node.edges[sequence[next_phase + 1]]) do
if not closed[node][next_phase] then
queue[#queue+1] = {node = node, phase = next_phase, previous = path, cost = path.cost + edge.cost}
end
end
table.sort(queue, pathfind_compare)
end
end
print "No route found"
return false
end
solve {"red", "yellow"}
solve {"red", "yellow", "brown"}
solve {"red", "brown", "yellow"}<!--c2--></div><!--ec2-->Code is being debugged in a Lua 5.1.3 command line interpreter compiled from source.
The first item in the watch window is the_maze.nodes[1], and the second is the_maze expanded to look at the nodes table. The first way shows the members of the_maze.nodes[1], while the second reports the_maze.nodes[1] as {}. Also note that the_maze.nodes[1].maze.nodes is reported as an empty table {}, however the_maze.nodes[1].maze == the_maze, therefore the nodes table cannot be empty.
The code in question:<!--c1--><div class='codetop'>CODE</div><div class='codemain'><!--ec1-->function maze()
node"B"(0, 0) B"BJ" node"J"(2, 0) R"JN" node"N"(4, 0)
Y"BI" R"BD" Y"DJ" Y"JK" B"JL" B"LN" Y"NP"
node"I"(0, 1) Y"ID" node"D"(1, 1) R"DK" node"K"(2, 1) R"KL" node"L"(3, 1) Y"LP" node"P"(4, 1)
R"IT" B"DT" R"TK" R"RK" B"KR" Y"LR" B"RP"
B"IC" node"T"(1, 2) finish"G"(2, 2) node"R"(3, 2) R"PS"
R"CT" Y"AT" B"TH" R"HR" Y"RE" Y"RS"
node"C"(0, 3) B"CA" node"A"(1, 3) R"AH" node"H"(2, 3) Y"HE" node"E"(3, 3) B"ES" node"S"(4, 3)
Y"CV" B"AV" R"AM" B"HM" B"EM" R"EF" B"SF"
node"V"(0, 4) R"VM" node"M"(2, 4) Y"MF" node"F"(4, 4)
R"M*"
start"*"(2, 5)
end
local function getnode(n, m)
m = m or maze
return m[n] or m.nodes[n] or n
end
do
local maze_fn = maze
maze = function()
local the_maze = {
nodes = {},
edges = {
red = {},
yellow = {},
brown = {},
},
}
local function add_node(name, x, y, special)
local node = {
maze = the_maze,
name = name,
x = x,
y = y,
idx = #the_maze.nodes + 1,
edges = {
red = {},
yellow = {},
brown = {},
},
}
if special then
node[special] = true
the_maze[special] = node
end
the_maze.nodes[node.idx] = node
the_maze.nodes[node.name] = node
end
local function add_edge(colour, nodes)
local set = the_maze.edges[colour]
local edge = {
maze = the_maze,
name = nodes,
colour = colour,
idx = #set + 1,
from = nodes:sub(1, 1),
to = nodes:sub(2, 2),
}
edge.cost = 1
set[edge.idx] = edge
set[edge.name] = edge
end
local f_env = {
node = function(name) return function(x, y) add_node(name, x, y ) end end,
start = function(name) return function(x, y) add_node(name, x, y, "start" ) end end,
finish = function(name) return function(x, y) add_node(name, x, y, "finish") end end,
Y = function(names) add_edge("yellow", names) end,
R = function(names) add_edge("red" , names) end,
B = function(names) add_edge("brown" , names) end,
}
setfenv(maze_fn, f_env)()
for colour, edges in pairs(the_maze.edges) do
for _, edge in ipairs(edges) do
edge.from = getnode(edge.from, the_maze)
edge.to = getnode(edge.to, the_maze)
edge.from.edges[edge.colour][edge] = edge.to
edge.to .edges[edge.colour][edge] = edge.from
end
end
return the_maze
end
end
maze = maze()
local function pathfind_compare(p1, p2)
return p1.cost < p2.cost
end
function solve(sequence)
print("Solving for " .. table.concat(sequence, ", ") .. " ...")
local queue = { {node = getnode"start", phase = 0, previous = nil, cost = 0} }
local closed = setmetatable({}, {__index = function(t, k) local v = {}; t[k] = v; return v end})
while queue[1] do
local path = queue[1]
table.remove(queue, 1)
if not closed[path.node][path.phase] then
closed[path.node][path.phase] = true
if path.node.finish then
print "Route found: ..."
return true
end
local next_phase = (path.phase + 1) % #sequence
for edge, node in pairs(path.node.edges[sequence[next_phase + 1]]) do
if not closed[node][next_phase] then
queue[#queue+1] = {node = node, phase = next_phase, previous = path, cost = path.cost + edge.cost}
end
end
table.sort(queue, pathfind_compare)
end
end
print "No route found"
return false
end
solve {"red", "yellow"}
solve {"red", "yellow", "brown"}
solve {"red", "brown", "yellow"}<!--c2--></div><!--ec2-->Code is being debugged in a Lua 5.1.3 command line interpreter compiled from source.
Comments