namespace AdventOfCode.Core.Shared.A_Star { public class AStarGrid(T[] data) : Grid(data) where T : AStarNode { public int TileMoveCost { get; set; } public int MinimalSteps(T start, T destination) { List openNodes = [start]; List 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; } }