AdventOfCode/AdventOfCode.Core/Shared/A-Star/AStarGrid.cs

55 lines
1.8 KiB
C#

namespace AdventOfCode.Core.Shared.A_Star
{
public class AStarGrid<T>(T[] data) : Grid<T>(data) where T : AStarNode
{
public int TileMoveCost { get; set; }
public int MinimalSteps(T start, T destination)
{
List<T> openNodes = [start];
List<T> closedNodes = [];
while(openNodes.Count != 0)
{
// get the lowest F-cost node
T current = openNodes.OrderBy(n => n.FCost).First();
openNodes.Remove(current);
closedNodes.Add(current);
if (current == destination)
{
//done
return 1;
}
var neighbors = GetNeighbors(current, false)
.Where(n => current.CanMoveTo(current));
// calc costs
foreach(T neighbor in neighbors)
{
long g = current.GCost + GetMoveCost(current, neighbor);
long h = neighbor.GetManhattanDistance(destination) * GetMoveCost(current, neighbor);
long f = g + h;
int openNodeIndex = openNodes.IndexOf(neighbor),
closedNodeIndex = closedNodes.IndexOf(neighbor);
if (openNodeIndex > 0 && openNodes[openNodeIndex].FCost > f)
{
openNodes[openNodeIndex].ParentNode = neighbor;
openNodes[openNodeIndex].GCost = g;
openNodes[openNodeIndex].HCost = h;
}
openNodes.Add(neighbor);
}
}
return -1;
}
public virtual int GetMoveCost(T current, T neighbor) => TileMoveCost;
}
}