I wrote this A* Shortest Path algorithm using a Priority Queue which works when I map nodes a certain way, but not when I do it another way. Here is the base code for the algorithm:
My heuristic is the distance from the node to the goal node.
-- Example node = {v = "N0", c = {}}
-- v is the node value, also the name
-- c is the children/neighbors of the node in a table
function aStarSearch(start, goal)
local queue = {}
local visited = {}
local function testVisited(node)
for i,v in pairs(visited) do
if v == node then
return true
end
end
return false
end
start.d = 0
table.insert(queue, start)
local current = nil
while #queue > 0 do
current = queue[1]
table.remove(queue, 1)
if not testVisited(current) then
table.insert(visited, current)
print(current.v, goal.v)
if current.v == goal.v then
table.insert(path, current)
return path
end
local neighbors = current.c
for i,v in pairs(neighbors) do
if not testVisited(v) then
local predictedDistance = (parts[v.v].Position - parts[goal.v].Position).magnitude
local neighborDistance = (parts[current.v].Position - parts[v.v].Position).magnitude
local totalDistance = (parts[current.v].Position - parts[start.v].Position).magnitude + neighborDistance + predictedDistance
if predictedDistance < totalDistance then
--print(current.v, v.v)
if #current.c > 0 then
table.insert(path, current)
end
table.insert(queue, v)
end
end
end
end
end
end
The current way it get's the shortest path is by adding nodes to a path variable here:
if predictedDistance < totalDistance then
--print(current.v, v.v)
if #current.c > 0 then
table.insert(path, current)
end
table.insert(queue, v)
end
This works for when no node has the same neighbor as any other node, or in visual form, this:
I already know the issue with this is that if it takes a wrong path and has to backtrack, it has already added the wrong nodes to the path variable.
This happens 95% of the time when I add loops:
This is how I map the nodes initially:
for i = 1,10 do
local newNode = createNode("N"..i, {})
if i == 1 then
addChild(findNode(start.v), newNode)
else
addChild(findNode(lastNode.v), newNode)
local r = math.random(1,2)
if r == 1 then
lastNode = newNode
end
end
end
And if I want to add loops I do this:
for i,v in pairs(nodes) do
local r = math.random(1,4)
local n = math.random(1,10)
while n == i do
n = math.random(1,10)
end
addChild(findNode(v.v), nodes[n])
end
So in short my question is, how do I return the CORRECT path and not include any nodes that perhaps ended in a dead end, or were wrong for another way? Perhaps the way I wrote the algorithm is incorrect, which it very well might be since this is my first A* algorithm, so if you see any weird things I do please point them out.

3 comments
dam
this might take a day to answer
You just wrote math.random() with two parameter, math.random() uses 3 parameters, math.random(startvalue endvalue, breakvalue)