示例#1
0
 public static Vector2Int[] GetPath(Vector2Int start, Vector2Int goal, CanTravelDelegate canTravelDelegate, int infiniteLoopLimit) => GetPath(start, goal, canTravelDelegate, DefaultCalculateTravelCostDelegate, infiniteLoopLimit);
示例#2
0
        public static Vector2Int[] GetPath(Vector2Int start, Vector2Int goal, CanTravelDelegate canTravelDelegate, CalculateTravelCostDelegate calculateTravelCostDelegate, int infiniteLoopLimit)
        {
            Vector2Int[] bestPath = new Vector2Int[0];

            HashSet <Vector2IntAsAStarNode> open   = new HashSet <Vector2IntAsAStarNode>();
            HashSet <Vector2IntAsAStarNode> closed = new HashSet <Vector2IntAsAStarNode>();

            open.Add(new Vector2IntAsAStarNode
            {
                coord    = start,
                previous = null,
                f        = 0,
                g        = 0,
                h        = 0,
            });

            int counter = 0;

            while (open.Count > 0)
            {
                counter++;

                if (infiniteLoopLimit >= 0 && counter > infiniteLoopLimit)
                {
                    throw new Exception("Vector2IntPathFinder - infinite loop detected");
                }

                List <Vector2IntAsAStarNode> openAsList = new List <Vector2IntAsAStarNode>(open);
                openAsList.Sort((Vector2IntAsAStarNode a, Vector2IntAsAStarNode b) =>
                {
                    return(a.f.CompareTo(b.f));
                });

                // set the current node to the node with the least f
                Vector2IntAsAStarNode currentNode = openAsList[0];

                closed.Add(openAsList[0]);
                open.Remove(currentNode);

                if (currentNode.coord.Equals(goal)) // remember to use .Equals() instead of == becuase these are not the same object
                {
                    bestPath = currentNode.ToPath();
                    break;
                }

                List <Vector2Int> potentialNextCoords = new List <Vector2Int>();
                if (canTravelDelegate(currentNode.coord + Vector2Int.up))
                {
                    potentialNextCoords.Add(currentNode.coord + Vector2Int.up);
                }
                if (canTravelDelegate(currentNode.coord + Vector2Int.down))
                {
                    potentialNextCoords.Add(currentNode.coord + Vector2Int.down);
                }
                if (canTravelDelegate(currentNode.coord + Vector2Int.left))
                {
                    potentialNextCoords.Add(currentNode.coord + Vector2Int.left);
                }
                if (canTravelDelegate(currentNode.coord + Vector2Int.right))
                {
                    potentialNextCoords.Add(currentNode.coord + Vector2Int.right);
                }

                foreach (Vector2Int coord in potentialNextCoords)
                {
                    Vector2IntAsAStarNode childNode = new Vector2IntAsAStarNode();
                    childNode.coord    = coord;
                    childNode.previous = currentNode;
                    childNode.g        = currentNode.g + 1;
                    childNode.h        = (coord - goal).ManhattanDistance();
                    childNode.f        = childNode.g + childNode.h + calculateTravelCostDelegate(coord);

                    // check if we've visited this coord but now we have a better path to it
                    bool alreadyVisited = false;
                    foreach (Vector2IntAsAStarNode openNode in open)
                    {
                        if (!openNode.coord.Equals(coord))
                        {
                            continue;
                        }

                        if (openNode.f <= childNode.f)
                        {
                            continue;
                        }

                        openNode.g        = childNode.g;
                        openNode.h        = childNode.h;
                        openNode.f        = childNode.f;
                        openNode.previous = childNode.previous;
                        alreadyVisited    = true;
                    }

                    foreach (Vector2IntAsAStarNode closedNode in closed)
                    {
                        if (closedNode.coord.Equals(coord))
                        {
                            alreadyVisited = true;
                            break;
                        }
                    }

                    if (!alreadyVisited)
                    {
                        open.Add(childNode);
                    }
                }
            }

            return(bestPath);
        }
示例#3
0
 public static Vector2Int[] GetPath(Vector2Int start, Vector2Int goal, CanTravelDelegate canTravelDelegate) => GetPath(start, goal, canTravelDelegate, DefaultCalculateTravelCostDelegate, -1);