/// <summary> /// Used for A* /// </summary> /// <param name="start"></param> /// <param name="end"></param> /// <returns></returns> public float CalculateTotal(qpNode start, qpNode end) { _h = CalculateH(end); if (_parent != null) { _g = CalculateG(_parent) + _parent.GetG(); } else { _g = 1; } _total = _g + _h; return(_total); }
/// <summary> /// Performs an A* algorithm /// </summary> /// <param name="start">Starting node</param> /// <param name="end">Destination Node</param> /// <returns>The fastest path from start node to the end node</returns> protected List <qpNode> AStar(qpNode start, qpNode end) { Debug.Log("astar from " + start.GetCoordinate() + " to " + end.GetCoordinate()); List <qpNode> path = new List <qpNode>(); //will hold the final path bool complete = (end == null || start == null) ? true : false; //Regulates the main while loop of the algorithm List <qpNode> closedList = new List <qpNode>(); //Closed list for the best candidates. List <qpNode> openList = new List <qpNode>(); //Open list for all candidates(A home for all). qpNode candidate = start; //The current node candidate which is being analyzed in the algorithm. openList.Add(start); //Start node is added to the openlist if (start == null || end == null) { return(null); //algoritmen cannot be executed if either start or end node are null. } int astarSteps = 0; while (openList.Count > 0 && !complete) //ALGORITHM STARTS HERE. { astarSteps++; if (candidate == end) //If current candidate is end, the algorithm has been completed and the path can be build. { DestinationNode = end; complete = true; bool pathComplete = false; qpNode node = end; while (!pathComplete) { path.Add(node); if (node == start) { pathComplete = true; } node = node.GetParent(); } } List <qpNode> allNodes = (DiagonalMovement ? candidate.Contacts : candidate.NonDiagonalContacts); List <qpNode> potentialNodes = new List <qpNode>(); foreach (qpNode n in allNodes) { if (n.traverseable) { potentialNodes.Add(n); } } foreach (qpNode n in potentialNodes) { bool inClosed = closedList.Contains(n); bool inOpen = openList.Contains(n); //Mark candidate as parent if not in open nor closed. if (!inClosed && !inOpen) { n.SetParent(candidate); openList.Add(n); } //But if in open, then calculate which is the better parent: Candidate or current parent. else if (inOpen) { float math2 = n.GetParent().GetG(); float math1 = candidate.GetG(); if (math2 > math1) { //candidate is the better parent as it has a lower combined g value. n.SetParent(candidate); } } } //Calculate h, g and total if (openList.Count == 0) { break; } openList.RemoveAt(0); if (openList.Count == 0) { break; } //the below one-lined for loop,if conditional and method call updates all nodes in openlist. for (int i = 0; i < openList.Count; i++) { openList[i].CalculateTotal(start, end); } openList.Sort(delegate(qpNode node1, qpNode node2) { return(node1.GetTotal().CompareTo(node2.GetTotal())); }); candidate = openList[0]; closedList.Add(candidate); } Debug.Log("astar completed in " + astarSteps + " steps. Path found:" + complete); path.Reverse(); return(path); }