public override IEnumerator Search(List <Node> nodes, int size, Node start, Node goal, int framesPerSecond) { IsSearching = true; Debug.LogFormat("Searching path using A* algorythm"); bool hasPath = false; bool[,] visited = new bool[size, size]; cameFrom = new Dictionary <Node, Node> (); List <NodeDistance> frontier = new List <NodeDistance> (); Node current = new Node(); float pathLength; frontier.Add(new NodeDistance(start, 0 + Mathf.Abs(Vector2.Distance(start.pos, goal.pos)))); cameFrom[start] = null; visited[(int)start.pos.x, (int)start.pos.y] = true; while (frontier.Count > 0) { current = frontier[0].node; pathLength = frontier[0].distance - Mathf.Abs(Vector2.Distance(current.pos, goal.pos)); frontier.RemoveAt(0); UIUpdate(frontier.Count, pathLength, Mathf.Abs(Vector2.Distance(current.pos, goal.pos)) + pathLength); //visualize path to current GraphSearcher.VisualizePath(cameFrom, current, start); yield return(new WaitForSeconds(1f / framesPerSecond)); if (current == goal) { hasPath = true; break; } //get the maxNodes nodes closest to the objective and keep them. for (int i = 0; i < current.links.Count; i++) { Node neighbour = current.links[i]; if (!visited[(int)neighbour.pos.x, (int)neighbour.pos.y]) { visited[(int)neighbour.pos.x, (int)neighbour.pos.y] = true; cameFrom[neighbour] = current; float totalDistance = pathLength + Mathf.Abs(Vector2.Distance(neighbour.pos, current.pos)) + Mathf.Abs(Vector2.Distance(neighbour.pos, goal.pos)); frontier.Add(new NodeDistance(neighbour, totalDistance)); UIIncrementEnqueuings(); } frontier.Sort(); } } SearchComplete(hasPath); yield break; }
public override IEnumerator Search(List <Node> nodes, int size, Node start, Node goal, int framesPerSecond) { IsSearching = true; Debug.Log("Searching path using Breadth First Search algorythm."); bool hasPath = false; bool[,] visited = new bool[size, size]; cameFrom = new Dictionary <Node, Node> (); Queue <Node> frontier = new Queue <Node> (); Node current = new Node(); frontier.Enqueue(start); cameFrom[start] = null; visited[(int)start.pos.x, (int)start.pos.y] = true; while (frontier.Count > 0) { current = frontier.Dequeue(); UIUpdate(frontier.Count, CalculatePathLength(start, current)); //visualize path to current GraphSearcher.VisualizePath(cameFrom, current, start); yield return(new WaitForSeconds(1f / framesPerSecond)); if (current == goal) { hasPath = true; break; } for (int i = 0; i < current.links.Count; i++) { Node neighbour = current.links[i]; if (neighbour == current) { Debug.LogErrorFormat("node {0} has link to itself.", current); } if (!visited[(int)neighbour.pos.x, (int)neighbour.pos.y]) { visited[(int)neighbour.pos.x, (int)neighbour.pos.y] = true; cameFrom[neighbour] = current; frontier.Enqueue(neighbour); UIIncrementEnqueuings(); } } } SearchComplete(hasPath); yield break; }
public override IEnumerator Search(List <Node> nodes, int size, Node start, Node goal, int framesPerSecond) { IsSearching = true; Debug.Log("Searching path using Hill Climbing algorythm."); bool hasPath = false; bool[,] visited = new bool[size, size]; cameFrom = new Dictionary <Node, Node> (); Stack <Node> frontier = new Stack <Node> (); Node current = new Node(); frontier.Push(start); cameFrom[start] = null; while (frontier.Count > 0) { current = frontier.Pop(); UIUpdate(frontier.Count, CalculatePathLength(start, current)); //visualize path to current GraphSearcher.VisualizePath(cameFrom, current, start); yield return(new WaitForSeconds(1f / framesPerSecond)); if (current == goal) { hasPath = true; break; } float closestDistance = Vector2.Distance(current.pos, goal.pos); Node closestNeighbour = null; for (int i = 0; i < current.links.Count; i++) { Node neighbour = current.links[i]; // test shortest path float neighbourDist = Vector2.Distance(neighbour.pos, goal.pos); if (neighbourDist < closestDistance || closestDistance == float.MaxValue) { closestNeighbour = neighbour; closestDistance = neighbourDist; } } // extend path if (closestNeighbour != null) { if (!visited[(int)closestNeighbour.pos.x, (int)closestNeighbour.pos.y]) { visited[(int)closestNeighbour.pos.x, (int)closestNeighbour.pos.y] = true; cameFrom[closestNeighbour] = current; frontier.Push(closestNeighbour); UIIncrementEnqueuings(); } } else { Debug.LogFormat("Stuck in local maxima. node {0}", current.ID); } } SearchComplete(hasPath); yield break; }