Esempio n. 1
0
    // Annoyingly, C# doesn't have Priority Queues...
    IEnumerator UCS(Breadcrumb root, Breadcrumb goal)
    {
        List <Breadcrumb> expanded = new List <Breadcrumb>();

        // Organizes by Breadcrumb heuristic. The lower the number, the higher the priority
        PriorityQueue <Breadcrumb> pq = new PriorityQueue <Breadcrumb>();

        pq.Enqueue(root);

        Breadcrumb current = root;

        // Go through the nodes on the map
        while (pq.Count() > 0)
        {
            current = pq.Dequeue();
            // Each time we visit a node, leave a breadcrub
            transform.position = current.transform.position;
            current.SetColor(Color.blue);
            numSteps++;
            yield return(new WaitForSeconds((float)stepSpeed / 1000));

            // If we found the goal we're done
            if (current == goal)
            {
                print("Found Goal");
                break;
            }

            if (!expanded.Contains(current))
            {
                expanded.Add(current);

                // Look at north, south, east, and west nodes. Diagonals are optional
                for (int x = 0; x < numDirections; x++)
                {
                    Breadcrumb neighbor = CheckNode(current, (Direction)x);

                    if (neighbor != null && !expanded.Contains(neighbor) && neighbor != current && !pq.Contains(neighbor))
                    {
                        pq.Enqueue(neighbor);

                        yield return(new WaitForSeconds((float)stepSpeed / 1000));
                    }
                }
            }
        }

        searching = false;
        yield return(null);
    }
Esempio n. 2
0
    IEnumerator DFS(Breadcrumb root, Breadcrumb goal)
    {
        List <Breadcrumb>  expanded = new List <Breadcrumb>();
        Stack <Breadcrumb> s        = new Stack <Breadcrumb>();

        s.Push(root);

        Breadcrumb current = root;

        // Go through the nodes on the map
        while (s.Count > 0)
        {
            current = s.Pop();

            // Each time we visit a node, leave a breadcrub
            transform.position = current.transform.position;
            current.SetColor(Color.blue);
            numSteps++;
            yield return(new WaitForSeconds((float)stepSpeed / 1000));

            // If we found the goal we're done
            if (current.ID == goal.ID)
            {
                print("Found Goal");
                break;
            }

            if (!expanded.Contains(current))
            {
                expanded.Add(current);

                // Look at north, south, east, and west nodes. Diagonals are optional
                for (int x = 0; x < numDirections; x++)
                {
                    Breadcrumb neighbor = CheckNode(current, (Direction)x);

                    if (neighbor != null && !expanded.Contains(neighbor) && neighbor != current && !s.Contains(neighbor))
                    {
                        s.Push(neighbor);

                        yield return(new WaitForSeconds((float)stepSpeed / 1000));
                    }
                }
            }
        }

        searching = false;
        yield return(null);
    }
Esempio n. 3
0
    IEnumerator Astar(Breadcrumb root, Breadcrumb goal, bool consistentHeuristic)
    {
        // The set of nodes already evaluated.
        // Don't used expanded if the heuristic is MONOTONIC/CONSISTENT (see Wikipedia)
        // Basically, if the shortest path between two neighboring nodes is always the direct path between those nodes
        // then the heuristic is consistent. There isn't another path that goes through more nodes but has a smaller heuristic
        List <Breadcrumb>          expanded = new List <Breadcrumb>();
        PriorityQueue <Breadcrumb> pq       = new PriorityQueue <Breadcrumb>();

        pq.Enqueue(root);

        // For each node, which node it can most efficiently be reached from.
        Dictionary <Breadcrumb, Breadcrumb> cameFrom = new Dictionary <Breadcrumb, Breadcrumb>();

        // For each node, the cost of getting from the start node to that node.
        Dictionary <Breadcrumb, float> fromStartHeuristic = new Dictionary <Breadcrumb, float>();

        fromStartHeuristic[root] = 0;   // The cost of going from start to start is zero.

        // For each node, the total cost of getting from the start node to the goal by passing by that node. That value is partly known, partly heuristic.
        Dictionary <Breadcrumb, float> estimatedHeuristic = new Dictionary <Breadcrumb, float>();

        estimatedHeuristic[root] = root.heuristic;

        Breadcrumb current = null;

        while (pq.Count() > 0)
        {
            current = pq.Dequeue();

            transform.position = current.transform.position;
            current.SetColor(Color.blue);
            numSteps++;
            yield return(new WaitForSeconds((float)stepSpeed / 1000));

            if (current.ID == goal.ID)
            {
                print("Found Goal");
                break;
            }

            if (!expanded.Contains(current))
            {
                expanded.Add(current);

                // Check neighbors
                for (int x = 0; x < numDirections; x++)
                {
                    Breadcrumb neighbor = CheckNode(current, (Direction)x);

                    if (neighbor != null && neighbor != current)
                    {
                        // If it has consistent heuristics, then we have to check if we've already expanded the node
                        if (consistentHeuristic)
                        {
                            if (!expanded.Contains(neighbor))
                            {
                                float temp_gScore = fromStartHeuristic[current] + (current.heuristic - neighbor.heuristic);

                                if (!pq.Contains(neighbor)) // Discover a new node
                                {
                                    pq.Enqueue(neighbor);
                                }
                                else if (temp_gScore >= fromStartHeuristic[neighbor])
                                {
                                    continue;       // This is not a better path.
                                }
                                // This path is the best until now. Record it!
                                cameFrom[neighbor]           = current;
                                fromStartHeuristic[neighbor] = temp_gScore;
                                estimatedHeuristic[neighbor] = fromStartHeuristic[neighbor] + neighbor.heuristic;
                            }
                        }
                        // Otherwise, we don't need/don't want to check if we've already expanded the node, so let's check it
                        else
                        {
                            float tentative_gScore = fromStartHeuristic[current] + (current.heuristic - neighbor.heuristic);

                            if (!pq.Contains(neighbor)) // Discover a new node
                            {
                                pq.Enqueue(neighbor);
                            }
                            else if (tentative_gScore >= fromStartHeuristic[neighbor])
                            {
                                continue;               // This is not a better path.
                            }
                            // This path is the best until now. Record it!
                            cameFrom[neighbor]           = current;
                            fromStartHeuristic[neighbor] = tentative_gScore;
                            estimatedHeuristic[neighbor] = fromStartHeuristic[neighbor] + neighbor.heuristic;
                        }

                        yield return(new WaitForSeconds((float)stepSpeed / 1000));
                    }
                }
            }
        }

        searching = false;
        yield return(null);
    }