0👍
Although you seem to suggest that your algorithm works, but too slow, it actually has at least one blocking error:
-
for (let node in toChecknext)
: this will iterate the indexes of the array, not the values. Yet you treat those values as nodes, which will lead to undesired behaviour. Change to:for (let node of toChecknext)
There are other, non-breaking issues as well:
-
if (grid[ny][nx].prev !== [])
will always be true, because a newly created array can never be the same object as an already existing object. I gues you first tried with=== []
, then found it was alwaysfalse
, and then just toggled it. Instead initialiseprev
asnull
and just check whetherprev
is a truthy value. Also just referencenode
instead ofgrid[ny][nx]
, which really is the same object (see more about that in another bullet point further down this list):this.prev = null; // in Node constructor /* ... */ if (node.prev)
-
toChecknext
is never cleared. It should, otherwise the algorithm will be doing unnecessary work. Whenever you have copied the contents oftoChecknext
tothis.toCheck
, you should emptytoChecknext
so that you will not be verifying nodes that are already visited. So after the copy, add:toChecknext.length = 0;
-
There is no provision for the case where there is no path. The algorithm will get into an infinite loop. On the condition you did the previous correction, also add this block before the
else
:} else if (toChecknext.length == 0) { this.output = []; return []; // No solution!
-
The path
pathnodes
lacks the end node. So initialise it with:let pathnodes = [currentNode];
-
The path
pathnodexy
actually is reversed, as it lists coordinates from the end to the beginning. So do this:this.output = pathnodexy.reverse();
-
In the case the start node is the end node, you
return
the path, but in all other cases you do not return it, but set a property. This is inconsistent. So in theelse
case do this:this.output = [start];
and outside of the
if..else
block do:return this.output;
-
It is overkill to do things like
this.grid[node.y][node.x].id
, which really isnode.id
. You have this happening at several places in your code. Another example iscurrentNode.x !== startNode.x || currentNode.y !== startNode.y
, which can be justcurrentNode != startNode
. There are other cases, which I will not list all… -
It is of no use to pass
this.grid
tofindNeighbours
and then havefindNeighbours
return it. Any mutation you did on thatgrid
argument will be directly onthis.grid
.grid
is a reference to the same asthis.grid
. So just remove that parameter, and have the function work withthis.grid
instead ofgrid
, and just return the neighbour list. -
Don’t use
try { ... } catch { null }
, as you risk to miss out on errors you did not expect.
There is much more to improve in this code, but with these adjustments it should run in a reasonable time.