///<summary>Creates a node at the input position and movement cost of 1</summary> public Node(Position position) { _postition = position; _parent = null; _movementCost = 1; _vistable = true; }
///<summary>Adds the input node into the closed list</summary> ///<param name="node">Node to add to the closed list</param> public void Add(Node node) { _closedNodeList.Add(node); #if Debug Console.WriteLine("Added node at " + node.Postition.ToString() + " to closed list"); #endif }
///<summary>Creates a node at the input position and the inputed movement cost</summary> public Node(Position position, double movementCost) { _postition = position; _parent = null; _movementCost = movementCost; _vistable = true; }
///<summary>Adds the input node to the heap</summary> ///<param name="node">Node to add to the open list</param> public void Add(Node node) { _openNodes.Add(node); #if Debug Console.WriteLine("Added node at " + node.Postition.ToString() + " to open list"); #endif }
///<summary>Tests to see if the input node is on the map</summary> ///<param name="node">Node to check if it is on the map</param> ///<returns>Returns true if the node is on the map. Returns false if it is not on the map</returns> public bool Contains(Node node) { if (node.Postition.X >= _xNodes || node.Postition.Y >= _yNodes || node.Postition.X < 0 || node.Postition.Y < 0) { return false; } return true; }
///<summary>Tests to see if the input node is in the closed list</summary> ///<param name="node">Node to test if the node exists in the closed list</param> ///<returns>Returns true if the node is in the closed list. Returns false if the node is not in the closed list.</returns> public bool Contains(Node node) { for (int i = 0; i < _closedNodeList.Count; i++) { if (node == _closedNodeList[i]) { return true; } } return false; }
///<summary>Tests to see if the input node is in the open list</summary> ///<param name="node">Node to test if the node exists in the open list</param> ///<returns>Returns true if the node is in the open list. Returns false if the node is not in the open list.</returns> public bool Contains(Node node) { for (int i = 0; i < _openNodes.Count; i++) { if (node == _openNodes[i]) { return true; } } return false; }
///<summary>Removes the input node from the open list if it exists</summary> ///<param name="node">Node to remove from the open list</param> public void Remove(Node node) { for (int i = 0; i < _openNodes.Count; i++) { if (node == _openNodes[i]) { _openNodes.RemoveAllCopies(_openNodes[i]); } } #if Debug Console.WriteLine("Removed node at " + node.Postition.ToString() + " from the open list"); #endif }
///<summary>Instantiates the AStar class with a starting node, ending node, and a map. Ensures the starting and ending nodes are on the map and visitable</summary> ///<param name="startingNode">Beginning of the path</param> ///<param name="next">Node to find a path to from the starting node</param> public AStar(Node startingNode, Node endingNode, Map map) { if (!startingNode.Vistable) { throw new Exception("Can't start on an unvistable node"); } if (!endingNode.Vistable) { throw new Exception("Can't end on an unvistable node"); } if (!map.Contains(startingNode)) { throw new Exception("Starting node not on the map"); } if (!map.Contains(endingNode)) { throw new Exception("Ending node not on the map"); } _startingNode = startingNode; _endingNode = endingNode; _map = map; }
///<summary>Finds all of nodes on the map up, down, left, or right of the input node</summary> ///<param name="node">Node to adjacent to</param> ///<returns>Returns a list of adjacent nodes</returns> public List<Node> GetAdjacentNodes(Node node) { List<Node> adjacentNodes = new List<Node>(); int x = node.Postition.X; int y = node.Postition.Y; if (x != 0) { adjacentNodes.Add(_nodeMap[x - 1, y]); } if (y != 0) { adjacentNodes.Add(_nodeMap[x, y - 1]); } if (x != _xNodes - 1) { adjacentNodes.Add(_nodeMap[x + 1, y]); } if (y != _yNodes - 1) { adjacentNodes.Add(_nodeMap[x, y + 1]); } return adjacentNodes; }
///<summary>Creates a path from the ending node to its first parent</summary> /// <param name="endingNode">Ending node to trace a path using its parents</param> ///<returns>Returns a path from the starting node to the ending node</returns> private Path retracePath(Node endingNode) { Path path = new Path(); path.AppendNode(endingNode); while (endingNode.Parent != null) { endingNode = endingNode.Parent; path.AppendNode(endingNode); } path.ReversePath(); return path; }
///<summary>Estimates the movement cost from input node to the ending node. Uses the Manhatten method and a cross product tie breaker to estimate movement cost.</summary> ///<param name="node">Node used to estimate the cost from the node to the ending position</param> ///<returns>Returns the estimated movement cost from the input node to the endingnode as a double</returns> private double h(Node node) { double dx1 = node.Postition.X - _endingNode.Postition.X; double dy1 = node.Postition.Y - _endingNode.Postition.Y; double dx2 = _startingNode.Postition.X - _endingNode.Postition.X; double dy2 = _startingNode.Postition.Y - _endingNode.Postition.Y; double h = node.MovementCost * (Math.Abs(dx1) + Math.Abs(dy1)); //Crossproduct tiebreak for path smoothness double cross = Math.Abs(dx1 * dy2 - dx2 * dy1); return h + cross * 0.01; }
///<summary>Appends the next node to the end of the current node's parent list and calculates the movement cost from the next node and all of its parents</summary> ///<param name="current">Node used to backtrack from to find the known movement cost</param> ///<param name="next">Node to append to the end of the current node's parent list</param> ///<returns>Returns the movement cost as a double of next node appended to current and all current's parents</returns> private double g(Node current, Node next) { next.Parent = current; return g(current); }
///<summary>Calculates the movement cost from input node and all of its parents</summary> ///<param name="node">Node used to backtrack from to find the known movement cost</param> ///<returns>Returns the movement cost as a double of the input node and all its parents</returns> private double g(Node node) { double cost = node.MovementCost; while (node.Parent != null) { node = node.Parent; cost += node.MovementCost; } return cost; }
///<summary>Approximates the movement cost from the starting to ending node passing through the input node</summary> /// <param name="node">Node used to estimate the cost from the starting position to the ending position passing through the node</param> /// <returns>Returns the estimated movement cost from the starting node to the ending node as a double</returns> private double f(Node node) { return g(node) + h(node); }
///<summary>Adds the input node to the end of the path</summary> ///<param name="node">Number of nodes in the x direction of the map</param> public void AppendNode(Node node) { _path.Add(node); }