I have been working on my first ever attempt at 2D Pathfinding (Still fairly new to gamedev) using the A* Algorithm as detailed here - http://www.policyalmanac.org/games/aStarTutorial.htm
For the most part it seems to be working correctly and as intended. However upon attempting to wrap my path around a building in the map, a stack overflow is caused in ClosedList (The List storing coordinates of the path). Upon further investigation it would appear that at some point in the path the algorithm is switching back and forth between two tiles and I cannot seem to work out why.
Any help or nudges in the right direction would be greatly appreciated.
The code probably isn’t the best way to do things but this is my first attempt so apologies if it offends anyone ![]()
void CheckSquare(Vector2 Start, Vector2 End)
{
//Check for Invalid Start/End Points
if (Start == End ||
grid.PTileArray[(int)Start.x, (int)Start.y].CurrentType.Passable == 0 ||
grid.PTileArray[(int)End.x, (int)End.y].CurrentType.Passable == 0)
{
return;
}
//Check which adjacent tiles are passable
if (grid.PTileArray[(int)Start.x - 1, (int)Start.y].CurrentType.Passable == 1)
{
OpenList.Add(new Vector2(Start.x - 1, Start.y)); //LEFT
gValues.Add(10);
}
if (grid.PTileArray[(int)Start.x - 1, (int)Start.y + 1].CurrentType.Passable == 1)
{
OpenList.Add(new Vector2(Start.x - 1, Start.y + 1)); //TOP LEFT
gValues.Add(14);
}
if (grid.PTileArray[(int)Start.x, (int)Start.y + 1].CurrentType.Passable == 1)
{
OpenList.Add(new Vector2(Start.x, Start.y + 1)); //TOP
gValues.Add(10);
}
if (grid.PTileArray[(int)Start.x + 1, (int)Start.y + 1].CurrentType.Passable == 1)
{
OpenList.Add(new Vector2(Start.x + 1, Start.y + 1)); //TOP RIGHT
gValues.Add(14);
}
if (grid.PTileArray[(int)Start.x + 1, (int)Start.y].CurrentType.Passable == 1)
{
OpenList.Add(new Vector2(Start.x + 1, Start.y)); //RIGHT
gValues.Add(10);
}
if (grid.PTileArray[(int)Start.x + 1, (int)Start.y - 1].CurrentType.Passable == 1)
{
OpenList.Add(new Vector2(Start.x + 1, Start.y - 1)); //BOTTOM RIGHT
gValues.Add(14);
}
if (grid.PTileArray[(int)Start.x, (int)Start.y - 1].CurrentType.Passable == 1)
{
OpenList.Add(new Vector2(Start.x, Start.y - 1)); //BOTTOM
gValues.Add(10);
}
if (grid.PTileArray[(int)Start.x - 1, (int)Start.y - 1].CurrentType.Passable == 1)
{
OpenList.Add(new Vector2(Start.x - 1, Start.y - 1)); //BOTTOM LEFT
gValues.Add(14);
}
//Remove the parent from the Possible choices
for (int n = 0; n < OpenList.Count; n++)
{
if (OpenList[n] == ClosedList[ClosedList.Count - 1])
{
OpenList.RemoveAt(n);
}
}
//Calculate H Values
for (int n = 0; n < OpenList.Count; n++)
{
float x = Mathf.Abs(End.x - OpenList[n].x);
float y = Mathf.Abs(End.y - OpenList[n].y);
float final = 10 * (x + y);
hValues.Add((int)final);
}
//Calculate F Values
int lowest = 10000;
int reference = 0;
for (int n = 0; n < OpenList.Count; n++)
{
int g = gValues[n];
int h = hValues[n];
int final = g + h;
fValues.Add(final);
if (fValues[n] < lowest)
{
lowest = fValues[n];
reference = n;
}
}
//Add the square with the lowest F Value to the closed list as part of the path
ClosedList.Add(OpenList[reference]);
//Clear Lists
OpenList.Clear();
gValues.Clear();
hValues.Clear();
fValues.Clear();
//If the final Location in ClosedList is not the end then continue
if (ClosedList[ClosedList.Count - 1] != End)
CheckSquare(ClosedList[ClosedList.Count - 1], End);
}
