コード例 #1
0
    public void ExecutePathfindingStep()
    {
        Node <Tile> currentNode = openSet.Dequeue();

        if (currentNode == EndNode)
        {
            ConstructPath();
            return;
        }

        closedSet.Add(currentNode);
        foreach (Edge <Tile> neighbouringEdge in currentNode.Edges)
        {
            Node <Tile> neighbor = neighbouringEdge.Node;
            if (closedSet.Contains(neighbor))
            {
                continue;
            }

            float movementCostToNeighbor = neighbor.Data.MovementCost * DistanceBetween(currentNode, neighbor);
            float tentativeGScore        = currentNode.GCost + movementCostToNeighbor;

            if (openSet.Contains(neighbor) && tentativeGScore >= neighbor.GCost)
            {
                continue;
            }

            cameFrom[neighbor] = currentNode;
            neighbor.GCost     = tentativeGScore;
            neighbor.HCost     = CalculateHeuristicCost(neighbor, EndNode);

            openSet.EnqueueOrUpdate(neighbor, neighbor.FCost);
        }
    }
コード例 #2
0
ファイル: QPath_AStar.cs プロジェクト: cyv-cg/FE
        public void DoWork()
        {
            path = new Queue <T>();

            HashSet <T> closedSet = new HashSet <T>();

            PathfindingPriorityQueue <T> openSet = new PathfindingPriorityQueue <T>();

            openSet.Enqueue(startTile, 0);

            Dictionary <T, T> came_from = new Dictionary <T, T>();

            Dictionary <T, float> g_score = new Dictionary <T, float>
            {
                { startTile, 0 }
            };

            Dictionary <T, float> f_score = new Dictionary <T, float>
            {
                { startTile, costEstimateFunc(startTile, endTile) }
            };

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

                if (ReferenceEquals(current, endTile))
                {
                    Reconstruct_path(came_from, current);
                    return;
                }

                closedSet.Add(current);

                foreach (T edge_neighbor in current.GetNeighbors())
                {
                    T neighbor = edge_neighbor;

                    if (closedSet.Contains(neighbor))
                    {
                        continue;
                    }

                    float total_pathfinding_cost_to_neighbor = neighbor.AggregateCostToEnter(g_score[current], current, unit);

                    float tentative_g_score = total_pathfinding_cost_to_neighbor;

                    if (openSet.Contains(neighbor) && tentative_g_score >= g_score[neighbor])
                    {
                        continue;
                    }

                    came_from[neighbor] = current;
                    g_score[neighbor]   = tentative_g_score;
                    f_score[neighbor]   = g_score[neighbor] + costEstimateFunc(neighbor, endTile);

                    openSet.EnqueueOrUpdate(neighbor, f_score[neighbor]);
                }
            }
        }
コード例 #3
0
    public Path_AStar(World world, Tile tileStart, Pathfinder.GoalEvaluator isGoal, Pathfinder.PathfindingHeuristic costEstimate)
    {
        float startTime = Time.realtimeSinceStartup;

        // Set path to empty Queue so that there always is something to check count on
        path = new Queue <Tile>();

        // if tileEnd is null, then we are simply scanning for the nearest objectType.
        // We can do this by ignoring the heuristic component of AStar, which basically
        // just turns this into an over-engineered Dijkstra's algo

        // Check to see if we have a valid tile graph
        if (world.tileGraph == null)
        {
            world.tileGraph = new Path_TileGraph(world);
        }

        // Check to see if we have a valid tile graph
        if (world.roomGraph == null)
        {
            world.roomGraph = new Path_RoomGraph(world);
        }

        // A dictionary of all valid, walkable nodes.
        Dictionary <Tile, Path_Node <Tile> > nodes = world.tileGraph.nodes;

        // Make sure our start/end tiles are in the list of nodes!
        if (nodes.ContainsKey(tileStart) == false)
        {
            UnityDebugger.Debugger.LogError("Path_AStar", "The starting tile isn't in the list of nodes!");

            return;
        }

        Path_Node <Tile> start = nodes[tileStart];

        /*
         * Mostly following this pseusocode:
         * https://en.wikipedia.org/wiki/A*_search_algorithm
         */
        HashSet <Path_Node <Tile> > closedSet = new HashSet <Path_Node <Tile> >();

        /*
         * List<Path_Node<Tile>> openSet = new List<Path_Node<Tile>>();
         *        openSet.Add( start );
         */

        PathfindingPriorityQueue <Path_Node <Tile> > openSet = new PathfindingPriorityQueue <Path_Node <Tile> >();

        openSet.Enqueue(start, 0);

        Dictionary <Path_Node <Tile>, Path_Node <Tile> > came_From = new Dictionary <Path_Node <Tile>, Path_Node <Tile> >();

        Dictionary <Path_Node <Tile>, float> g_score = new Dictionary <Path_Node <Tile>, float>();

        g_score[start] = 0;

        Dictionary <Path_Node <Tile>, float> f_score = new Dictionary <Path_Node <Tile>, float>();

        f_score[start] = costEstimate(start.data);

        while (openSet.Count > 0)
        {
            Path_Node <Tile> current = openSet.Dequeue();

            // Check to see if we are there.
            if (isGoal(current.data))
            {
                Duration = Time.realtimeSinceStartup - startTime;
                Reconstruct_path(came_From, current);
                return;
            }

            closedSet.Add(current);

            foreach (Path_Edge <Tile> edge_neighbor in current.edges)
            {
                Path_Node <Tile> neighbor = edge_neighbor.node;

                if (closedSet.Contains(neighbor))
                {
                    continue; // ignore this already completed neighbor
                }

                float pathfinding_cost_to_neighbor = neighbor.data.PathfindingCost * Dist_between(current, neighbor);

                float tentative_g_score = g_score[current] + pathfinding_cost_to_neighbor;

                if (openSet.Contains(neighbor) && tentative_g_score >= g_score[neighbor])
                {
                    continue;
                }

                came_From[neighbor] = current;
                g_score[neighbor]   = tentative_g_score;
                f_score[neighbor]   = g_score[neighbor] + costEstimate(neighbor.data);

                openSet.EnqueueOrUpdate(neighbor, f_score[neighbor]);
            } // foreach neighbour
        }     // while

        // If we reached here, it means that we've burned through the entire
        // openSet without ever reaching a point where current == goal.
        // This happens when there is no path from start to goal
        // (so there's a wall or missing floor or something).

        // We don't have a failure state, maybe? It's just that the
        // path list will be null.
        Duration = Time.realtimeSinceStartup - startTime;
    }
コード例 #4
0
ファイル: Path_AStar.cs プロジェクト: walru5/ProjectPorcupine
    public Path_AStar(World world, Tile tileStart, Tile tileEnd, string objectType = null, int desiredAmount = 0, bool canTakeFromStockpile = false, bool lookingForFurn = false)
    {
        // if tileEnd is null, then we are simply scanning for the nearest objectType.
        // We can do this by ignoring the heuristic component of AStar, which basically
        // just turns this into an over-engineered Dijkstra's algo

        // Check to see if we have a valid tile graph
        if (world.tileGraph == null)
        {
            world.tileGraph = new Path_TileGraph(world);
        }

        // A dictionary of all valid, walkable nodes.
        Dictionary <Tile, Path_Node <Tile> > nodes = world.tileGraph.nodes;

        // Make sure our start/end tiles are in the list of nodes!
        if (nodes.ContainsKey(tileStart) == false)
        {
            Debug.ULogErrorChannel("Path_AStar", "The starting tile isn't in the list of nodes!");

            return;
        }

        Path_Node <Tile> start = nodes[tileStart];

        // if tileEnd is null, then we are simply looking for an inventory object
        // so just set goal to null.
        Path_Node <Tile> goal = null;

        if (tileEnd != null)
        {
            if (nodes.ContainsKey(tileEnd) == false)
            {
                Debug.ULogErrorChannel("Path_AStar", "The ending tile isn't in the list of nodes!");
                return;
            }

            goal = nodes[tileEnd];
        }

        /*
         * Mostly following this pseusocode:
         * https://en.wikipedia.org/wiki/A*_search_algorithm
         */
        HashSet <Path_Node <Tile> > closedSet = new HashSet <Path_Node <Tile> >();

        /*
         * List<Path_Node<Tile>> openSet = new List<Path_Node<Tile>>();
         *        openSet.Add( start );
         */

        PathfindingPriorityQueue <Path_Node <Tile> > openSet = new PathfindingPriorityQueue <Path_Node <Tile> >();

        openSet.Enqueue(start, 0);

        Dictionary <Path_Node <Tile>, Path_Node <Tile> > came_From = new Dictionary <Path_Node <Tile>, Path_Node <Tile> >();

        Dictionary <Path_Node <Tile>, float> g_score = new Dictionary <Path_Node <Tile>, float>();

        g_score[start] = 0;

        Dictionary <Path_Node <Tile>, float> f_score = new Dictionary <Path_Node <Tile>, float>();

        f_score[start] = Heuristic_cost_estimate(start, goal);

        while (openSet.Count > 0)
        {
            Path_Node <Tile> current = openSet.Dequeue();

            // If we have a POSITIONAL goal, check to see if we are there.
            if (goal != null)
            {
                if (current == goal)
                {
                    Reconstruct_path(came_From, current);
                    return;
                }
            }
            else
            {
                // We don't have a POSITIONAL goal, we're just trying to find
                // some kind of inventory or furniture.  Have we reached it?
                if (current.data.Inventory != null && current.data.Inventory.objectType == objectType && lookingForFurn == false && current.data.Inventory.locked == false)
                {
                    // Type is correct and we are allowed to pick it up
                    if (canTakeFromStockpile || current.data.Furniture == null || current.data.Furniture.IsStockpile() == false)
                    {
                        // Stockpile status is fine
                        Reconstruct_path(came_From, current);
                        return;
                    }
                }

                if (current.data.Furniture != null && current.data.Furniture.ObjectType == objectType && lookingForFurn)
                {
                    // Type is correct
                    Reconstruct_path(came_From, current);
                    return;
                }
            }

            closedSet.Add(current);

            foreach (Path_Edge <Tile> edge_neighbor in current.edges)
            {
                Path_Node <Tile> neighbor = edge_neighbor.node;

                if (closedSet.Contains(neighbor))
                {
                    continue; // ignore this already completed neighbor
                }

                float movement_cost_to_neighbor = neighbor.data.MovementCost * Dist_between(current, neighbor);

                float tentative_g_score = g_score[current] + movement_cost_to_neighbor;

                if (openSet.Contains(neighbor) && tentative_g_score >= g_score[neighbor])
                {
                    continue;
                }

                came_From[neighbor] = current;
                g_score[neighbor]   = tentative_g_score;
                f_score[neighbor]   = g_score[neighbor] + Heuristic_cost_estimate(neighbor, goal);

                openSet.EnqueueOrUpdate(neighbor, f_score[neighbor]);
            } // foreach neighbour
        }     // while

        // If we reached here, it means that we've burned through the entire
        // openSet without ever reaching a point where current == goal.
        // This happens when there is no path from start to goal
        // (so there's a wall or missing floor or something).

        // We don't have a failure state, maybe? It's just that the
        // path list will be null.
    }
コード例 #5
0
ファイル: Path_AStar.cs プロジェクト: cesarrac/LDJam40
    public Path_AStar(Area area, Tile startTile, Tile endTile)
    {
        //if (world.path_graph == null)
        //    world.path_graph = new Path_TileGraph(world);

        if (area.path_graph == null)
            area.path_graph = new Path_TileGraph(area);

        // A dictionary of Walkable Nodes (just a reference to path_graph.nodes)
        Dictionary<Tile, Path_Node<Tile>> nodes = area.path_graph.nodes;

        if (nodes.ContainsKey(startTile) == false)
        {
            Debug.LogError("PathAStar could not find starting tile in path graph!");
            return;
        }

        // Set the starting tile's node
        Path_Node<Tile> start = nodes[startTile];

        // If end tile is null, keep this goal null
        Path_Node<Tile> goal = null;
        if (endTile != null)
        {
            if (nodes.ContainsKey(endTile) == false)
            {
               // Debug.LogError("PathAStar could not find end tile in path graph!");
                return;
            }

            goal = nodes[endTile];
        }

        // Nodes already verified
        List<Path_Node<Tile>> ClosedSet = new List<Path_Node<Tile>>();

        //List<Path_Node<Tile>> OpenSet = new List<Path_Node<Tile>>();
        //OpenSet.Add( start );

        // Nodes being verified
        PathfindingPriorityQueue<Path_Node<Tile>> OpenSet = new PathfindingPriorityQueue<Path_Node<Tile>>();
        OpenSet.Enqueue(start, 0);

        // Nodes we just came from
        Dictionary<Path_Node<Tile>, Path_Node<Tile>> Came_From = new Dictionary<Path_Node<Tile>, Path_Node<Tile>>();

        Dictionary<Path_Node<Tile>, float> g_score = new Dictionary<Path_Node<Tile>, float>();
        // Set default values to Infinity (so all nodes have a score in the Map)
        foreach (Path_Node<Tile> n in nodes.Values)
        {
            g_score[n] = Mathf.Infinity;
        }
        g_score[ start ] = 0;

        Dictionary<Path_Node<Tile>, float> f_score = new Dictionary<Path_Node<Tile>, float>();
        // Set default values to Infinity (so all nodes have a score in the Map)
        foreach (Path_Node<Tile> n in nodes.Values)
        {
            f_score[n] = Mathf.Infinity;
        }
        f_score[ start ] = HeuristicCostEstimate(start, goal);

        while(OpenSet.Count > 0)
        {
            Path_Node<Tile> current = OpenSet.Dequeue();

            if (goal != null)
            {
                if (current == goal)
                {
                    ReconstructPath(Came_From, current);
                    return;
                }
            }
            else
            {
                // TODO: goal is null, meaning the goal is to walk on a tile that contains some THING on it
            }

            ClosedSet.Add(current);

            foreach(Path_Edge<Tile> edge_neighbor in current.edges)
            {
                Path_Node<Tile> neighbor = edge_neighbor.node;

                if (ClosedSet.Contains(neighbor))
                    continue; // Ignore this already verified node

                float tentative_g_score = g_score[current] + DistBetween(current, neighbor);

                // Check this Node (neighbor) has not been check yet
                if (OpenSet.Contains(neighbor) && tentative_g_score >= g_score[neighbor])
                    continue;

                Came_From[neighbor] = current;
                g_score[neighbor] = tentative_g_score;
                f_score[neighbor] = g_score[neighbor] + HeuristicCostEstimate(neighbor, goal);

                if (OpenSet.Contains(neighbor) == false)
                    OpenSet.Enqueue(neighbor, f_score[neighbor]);
                else
                    OpenSet.UpdatePriority(neighbor, f_score[neighbor]);
            }
        }

        // No Path from Start to Goal was found if we reach here
        return;
    }