예제 #1
0
파일: Map.cs 프로젝트: FantinBibas/ggj2018
    public Path NavigateTo(Vector3Int from, Vector3Int to)
    {
        if (!HasNodeAt(from) || !HasNodeAt(to))
        {
            return(null);
        }
        List <PathfindingNode> nodes   = new List <PathfindingNode>();
        PathfindingNode        current = new PathfindingNode(from);
        PathfindingNode        toNode  = new PathfindingNode(to);

        for (int x = 0; x < Width; x += 1)
        {
            for (int y = 0; y < Height; y += 1)
            {
                if (!_nodes[x, y])
                {
                    continue;
                }
                PathfindingNode node = new PathfindingNode(x, y);
                nodes.Add(node);
                node.FScore = node.Heuristic(toNode);
                if (node.Equals(from))
                {
                    current = node;
                }
                if (node.Equals(to))
                {
                    toNode = node;
                }
            }
        }
        current.GScore = 0;
        List <PathfindingNode> closedSet = new List <PathfindingNode>();
        List <PathfindingNode> openSet   = new List <PathfindingNode> {
            current
        };

        while (openSet.Count > 0)
        {
            current = openSet.OrderBy(n => n.FScore).First();
            if (current.Equals(to))
            {
                return(current.ConstructPath());
            }
            openSet.Remove(current);
            closedSet.Add(current);
            foreach (PathfindingNode node in nodes.Where(n => n.IsNeighboor(current)))
            {
                if (closedSet.Contains(node))
                {
                    continue;
                }
                if (!openSet.Contains(node))
                {
                    openSet.Add(node);
                }
                int tentativeGScore = current.GScore + 1;
                if (tentativeGScore > AStarLimit)
                {
                    return(null);
                }
                if (tentativeGScore >= node.GScore)
                {
                    continue;
                }
                node.GScore = tentativeGScore;
                node.FScore = node.GScore + node.Heuristic(toNode);
                if (current.From != null)
                {
                    node.FScore += current.To(current.From).Equals(node.To(current)) ? 0 : 4;
                }
                node.From = current;
            }
        }
        return(null);
    }