Beispiel #1
0
    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;
    }
Beispiel #2
0
    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;
    }
Beispiel #3
0
    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;
    }