Exemplo n.º 1
0
 /// <summary>
 ///     Ctor for the A* search. It requires a searchMap from the level, a world vector start and end,
 ///     and a heuristic strategy object.
 /// </summary>
 /// <param name="seeker">The entity looking for the path</param>
 /// <param name="start">A vector2 to the starting location. Must be in worldspace</param>
 /// <param name="end">A vector2 to the ending location. Must be in worldspace</param>
 /// <param name="heuristic">A heurstic strategy object</param>
 public SearchAStar(MovingObject seeker, Vector2 start, Vector2 end, PathHeuristic heuristic)
 {
     _seeker    = seeker;
     _start     = start;
     _end       = end;
     _heuristic = heuristic;
 }
Exemplo n.º 2
0
    //A* pathfinding for faults
    public static List<IntVector2> GetPath(IntVector2 start, IntVector2 goal, List<IntVector2> nodes)
    {
        List<PathHeuristic> openList = new List<PathHeuristic> ();
        List<PathHeuristic> closedList = new List<PathHeuristic> ();

        PathHeuristic currentTile = new PathHeuristic(start);

        float startFuncTime = Time.realtimeSinceStartup;

        do {
            //Get the best fault using heuristics
            if(openList.Count>0){
                PathHeuristic lowestFTile = null;
                foreach(PathHeuristic tile in openList){
                    if(lowestFTile==null){
                        lowestFTile = tile;
                    }
                    else if(tile.score<lowestFTile.score){
                        lowestFTile = tile;
                    }
                    if(lowestFTile.tileIndex==goal){
                        lowestFTile = tile;
                        break;
                    }
                }
                currentTile = lowestFTile;
            }

            //Put the currentTile in closedList and remove from open
            closedList.Add(currentTile);
            openList.Remove(currentTile);

            //If the current is at the end
            if(currentTile.tileIndex == goal){
                List<IntVector2> pathList = new List<IntVector2>();

                while(currentTile.parent!=null){
                    //Add parent to the pathlist
                    pathList.Add(currentTile.tileIndex);
                    currentTile = currentTile.parent;
                }
                pathList.Add(start);
                pathList.Reverse();

                float time = (Time.realtimeSinceStartup-startFuncTime)*100;

                return pathList;
            }

            //Set adjacent list up
            List<IntVector2> adjacentList = GetAdjacentNodes(currentTile.tileIndex, nodes);

            foreach(IntVector2 adjacent in adjacentList){
                //If adjacent is in closed list, skip
                bool adjacentInClosed = false;
                foreach(PathHeuristic tile in closedList){
                    if(tile.tileIndex == adjacent){
                        adjacentInClosed = true;
                    }
                }

                if(adjacentInClosed){
                    continue;
                }

                //If not in open list, add it
                bool adjacentInOpen = false;
                foreach(PathHeuristic tile in openList){
                    if(tile.tileIndex == adjacent){
                        adjacentInOpen = true;
                    }
                }
                //Add to open list
                if(!adjacentInOpen){
                    PathHeuristic newTile = new PathHeuristic(adjacent, currentTile);
                    //Score
                    newTile.SetScore((int)(IntVector2.Distance(adjacent,goal)*10));
                    openList.Add(newTile);
                }
            }
        } while(openList.Count>0);
        //Unable to find a path between the start-goal
        return null;
    }
Exemplo n.º 3
0
 static int GetParentCount(PathHeuristic _tile)
 {
     PathHeuristic tile = _tile;
     int parentCount = 0;
     while (tile.parent!=null) {
         tile = tile.parent;
         parentCount++;
     }
     return parentCount;
 }
Exemplo n.º 4
0
 public PathHeuristic(IntVector2 _tileIndex, PathHeuristic _parent = null)
 {
     tileIndex = _tileIndex;
     parent = _parent;
 }
Exemplo n.º 5
0
    /// <summary>
    /// Search a path with custom AStar algorithm
    /// (Path class is used to explore the grid)
    /// </summary>
    /// <param name="_Start">Tile to start from</param>
    /// <param name="_End">Tile to reach</param>
    /// <param name="_ChronoInfos">Struct with times value to evaluate performance</param>
    /// <param name="_MaxSeconds">Max time allowed to search a solution. If value is negative, no time limit applied</param>
    /// <returns>the shortest path from start tile to end tile if it exists, null otherwise</returns>
    public static Path AStarCustomBasic(Tile _Start, Tile _End, out ChronoInfos _ChronoInfos, float _MaxSeconds)
    {
        StartChrono();

        if (_Start == null || !_Start.IsAccessible || _End == null || !_End.IsAccessible)
        {
            _ChronoInfos = ChronoInfos.InfosNone;
            return(null);
        }

        List <PathHeuristic> openList = new List <PathHeuristic>(50)
        {
            new PathHeuristic(_Start, Tile.GetManhattanDistance(_Start, _End))
        };
        HashSet <Tile> closeHashSet = new HashSet <Tile>();
        CustomComparer <PathHeuristic> phComparer = new CustomComparer <PathHeuristic>(false);

        while (openList.Count > 0)
        {
            if (_MaxSeconds > 0 && chrono.Elapsed.TotalSeconds > _MaxSeconds)
            {
                _ChronoInfos = StopChrono(_Start, _End, false);
                return(null);
            }

            PathHeuristic pathToExtend = openList.Last();

            removeFromOpenChrono -= chrono.ElapsedMilliseconds;
            openList.RemoveAt(openList.Count - 1);
            removeFromOpenChrono += chrono.ElapsedMilliseconds;

            Tile tileToExtend = pathToExtend.LastStep;
            if (tileToExtend == _End)
            {
                _ChronoInfos = StopChrono(_Start, _End, true);
                return(pathToExtend);
            }

            if (closeHashSet.Contains(tileToExtend))
            {
                continue;
            }

            closeHashSet.Add(tileToExtend);

            foreachNeighborsChrono -= chrono.ElapsedMilliseconds;
            for (int i = 0; i < tileToExtend.Neighbors.Count; i++)
            {
                Tile neighbor = tileToExtend.Neighbors[i];
                if (!neighbor.IsAccessible)
                {
                    continue;
                }

                searchInCloseListChrono -= chrono.ElapsedMilliseconds;
                if (closeHashSet.Contains(neighbor))
                {
                    continue;
                }
                searchInCloseListChrono += chrono.ElapsedMilliseconds;

                clonePathChrono -= chrono.ElapsedMilliseconds;
                PathHeuristic extendedPath = new PathHeuristic(pathToExtend);
                clonePathChrono += chrono.ElapsedMilliseconds;

                extendPathChrono -= chrono.ElapsedMilliseconds;
                extendedPath.AddStep(neighbor, Tile.GetManhattanDistance(neighbor, _End));
                extendPathChrono += chrono.ElapsedMilliseconds;

                searchInsertionChrono -= chrono.ElapsedMilliseconds;
                int indexInsertion = openList.BinarySearch(extendedPath, phComparer);
                if (indexInsertion < 0)
                {
                    indexInsertion = ~indexInsertion;
                }
                searchInsertionChrono += chrono.ElapsedMilliseconds;

                insertToOpenListChrono -= chrono.ElapsedMilliseconds;
                openList.Insert(indexInsertion, extendedPath);
                insertToOpenListChrono += chrono.ElapsedMilliseconds;
            }
            foreachNeighborsChrono += chrono.ElapsedMilliseconds;
        }

        _ChronoInfos = StopChrono(_Start, _End, false);
        return(null);
    }