// internal function to find path, don't use this one from outside private static List <Node> _ImpFindPath(Griddef grid, Point startPos, Point targetPos) { Node startNode = grid.nodes[startPos.x, startPos.y]; Node targetNode = grid.nodes[targetPos.x, targetPos.y]; List <Node> openSet = new List <Node>(); HashSet <Node> closedSet = new HashSet <Node>(); openSet.Add(startNode); while (openSet.Count > 0) { Node currentNode = openSet[0]; for (int i = 1; i < openSet.Count; i++) { if (openSet[i].fCost < currentNode.fCost || openSet[i].fCost == currentNode.fCost && openSet[i].hCost < currentNode.hCost) { currentNode = openSet[i]; } } openSet.Remove(currentNode); closedSet.Add(currentNode); if (currentNode == targetNode) { return(RetracePath(grid, startNode, targetNode)); } foreach (Node neighbour in grid.GetNeighbours(currentNode)) { if (!neighbour.walkable || closedSet.Contains(neighbour)) { continue; } int newMovementCostToNeighbour = currentNode.gCost + GetDistance(currentNode, neighbour) * (int)(10.0f * neighbour.penalty); if (newMovementCostToNeighbour < neighbour.gCost || !openSet.Contains(neighbour)) { neighbour.gCost = newMovementCostToNeighbour; neighbour.hCost = GetDistance(neighbour, targetNode); neighbour.parent = currentNode; if (!openSet.Contains(neighbour)) { openSet.Add(neighbour); } } } } return(null); }
private static List <Node> RetracePath(Griddef grid, Node startNode, Node endNode) { List <Node> path = new List <Node>(); Node currentNode = endNode; while (currentNode != startNode) { path.Add(currentNode); currentNode = currentNode.parent; } path.Reverse(); return(path); }
public static List <Point> FindPath(Griddef grid, Point startPos, Point targetPos) { // find path List <Node> nodes_path = _ImpFindPath(grid, startPos, targetPos); // convert to a list of points and return List <Point> ret = new List <Point>(); if (nodes_path != null) { foreach (Node node in nodes_path) { ret.Add(new Point(node.gridX, node.gridY)); } } return(ret); }