public IEnumerator ComputePathAsync(IPathNode startNode, IPathNode endNode) { FindingParams findingParams = new FindingParams() { startNode = startNode, endNode = endNode, computedPath = new LinkedList <IPathNode>() }; return(ComputePathCoroutine(findingParams)); }
public LinkedList<IPathNode> ComputePath(IPathNode startNode, IPathNode endNode) { FindingParams findingParams = new FindingParams() { startNode = startNode, endNode = endNode, computedPath = new LinkedList<IPathNode>() }; IEnumerator coroutine = ComputePathCoroutine(findingParams); while (coroutine.MoveNext()); return findingParams.computedPath; }
public LinkedList <IPathNode> ComputePath(IPathNode startNode, IPathNode endNode) { FindingParams findingParams = new FindingParams() { startNode = startNode, endNode = endNode, computedPath = new LinkedList <IPathNode>() }; IEnumerator coroutine = ComputePathCoroutine(findingParams); while (coroutine.MoveNext()) { ; } return(findingParams.computedPath); }
public IEnumerator ComputePathCoroutine(FindingParams findingParams) { //NOTE: curTicks will be different for each call. // if openTicks == curTicks, it means the node in in openList, same for closeList and closeTicks. // this is faster than reset a bool isInOpenList for all nodes before next call to this method int curTicks = (int)(Time.realtimeSinceStartup * 1000); IsComputing = true; if (findingParams.startNode == findingParams.endNode) { findingParams.computedPath.AddLast(findingParams.startNode); } else { //1) Add the starting square (or node) to the open list. m_closeList.Clear(); m_openList.Clear(); m_openList.AddLast(findingParams.startNode); findingParams.startNode.openTicks = curTicks; //2) Repeat the following: LinkedListNode <IPathNode> curNode; int iterations = 0; int iterChunkCounter = k_IterationsPerProcessChunk; do { ++iterations; --iterChunkCounter; if (iterChunkCounter == 0) { iterChunkCounter = k_IterationsPerProcessChunk; yield return(null); } //a) Look for the lowest F cost square on the open list. We refer to this as the current square. //curNode = m_vOpen.First(c => c.Score == m_vOpen.Min(c2 => c2.Score)); curNode = null; for (LinkedListNode <IPathNode> pathNode = m_openList.First; pathNode != null; pathNode = pathNode.Next) { if (curNode == null || pathNode.Value.Score < curNode.Value.Score) { curNode = pathNode; } } //b) Switch it to the closed list. m_openList.Remove(curNode); curNode.Value.openTicks = 0; m_closeList.AddLast(curNode); curNode.Value.closeTicks = curTicks; //c) For each of the 8 squares adjacent to this current square … for (int i = 0; i < curNode.Value.GetNeighborCount(); ++i) { //If it is not walkable or if it is on the closed list, ignore it. Otherwise do the following. IPathNode neigborNode = curNode.Value.GetNeighbor(i); float movingCost = curNode.Value.GetNeigborMovingCost(i); if ( neigborNode.closeTicks != curTicks && // if closeList does not contains node movingCost != k_InfiniteCostValue && neigborNode.IsPassable() ) { //If it isn’t on the open list, add it to the open list. Make the current square the parent of this square. Record the F, G, and H costs of the square. float newCost = curNode.Value.Cost + movingCost; if (neigborNode.openTicks != curTicks) // if openList does not contains node { m_openList.AddLast(neigborNode); neigborNode.openTicks = curTicks; neigborNode.ParentNode = curNode.Value; neigborNode.Cost = newCost; neigborNode.Score = neigborNode.Cost + neigborNode.GetHeuristic(); if (neigborNode == findingParams.endNode) { curNode.Value = neigborNode; m_openList.Clear(); // force to exit while break; } } //If it is on the open list already, check to see if this path to that square is better, using G cost as the measure. A lower G cost means that this is a better path. else if (newCost < neigborNode.Cost) { //If so, change the parent of the square to the current square, and recalculate the G and F scores of the square. neigborNode.ParentNode = curNode.Value; neigborNode.Cost = newCost; neigborNode.Score = neigborNode.Cost + neigborNode.GetHeuristic(); } } } }while (m_openList.Count > 0 && (MaxIterations <= 0 || iterations < MaxIterations)); //Debug.Log("iterations: " + iterations); if (iterations >= MaxIterations) { Debug.LogWarning("Info: max iterations reached before finding path solution. MaxIterations is set to " + MaxIterations); } //d) Stop when you: //Add the target square to the closed list, in which case the path has been found (see note below), or //Fail to find the target square, and the open list is empty. In this case, there is no path. if (curNode.Value == findingParams.endNode) { //3) Save the path. Working backwards from the target square, go from each square to its parent square until you reach the starting square. That is your path. findingParams.computedPath.AddLast(curNode.Value); do { curNode.Value = curNode.Value.ParentNode; findingParams.computedPath.AddLast(curNode.Value); }while (curNode.Value != findingParams.startNode); } } IsComputing = false; yield return(findingParams); }
public IEnumerator ComputePathAsync(IPathNode startNode, IPathNode endNode) { FindingParams findingParams = new FindingParams() { startNode = startNode, endNode = endNode, computedPath = new LinkedList<IPathNode>() }; return ComputePathCoroutine(findingParams); }