コード例 #1
0
 public static Stack <Point> findPath(Point startPoint, Point endPoint, isAtEnd endPointFunction, GameLocation location, int limit = -1)
 {
     if (Interlocked.Increment(ref _counter) != 1)
     {
         throw new Exception();
     }
     try
     {
         bool endPointIsFarmer = endPoint.X == Game1.player.getTileX() && endPoint.Y == Game1.player.getTileY();
         _openList.Clear();
         _closedList.Clear();
         var           openList   = _openList;
         HashSet <int> closedList = _closedList;
         int           iterations = 0;
         openList.Enqueue(new PathNode(startPoint.X, startPoint.Y, 0, null), Math.Abs(endPoint.X - startPoint.X) + Math.Abs(endPoint.Y - startPoint.Y));
         int        layerWidth       = location.map.Layers[0].LayerWidth;
         int        layerHeight      = location.map.Layers[0].LayerHeight;
         Character  character        = Game1.player;
         List <int> searchDirections = SearchDirections(startPoint, endPoint);
         while (!openList.IsEmpty())
         {
             PathNode currentNode = openList.Dequeue();
             if (endPointFunction(currentNode, endPoint, location, character))
             {
                 return(reconstructPath(currentNode));
             }
             closedList.Add(currentNode.id);
             int ng = (byte)(currentNode.g + 1);
             foreach (int i in searchDirections)
             {
                 int nx  = currentNode.x + Directions[i, 0];
                 int ny  = currentNode.y + Directions[i, 1];
                 int nid = PathNode.ComputeHash(nx, ny);
                 if (!closedList.Contains(nid))
                 {
                     bool isWalkable = isTileWalkable(location, nx, ny);
                     bool isEndPoint = nx == endPoint.X && ny == endPoint.Y;
                     bool isOffMap   = nx < 0 || ny < 0 || nx >= layerWidth || ny >= layerHeight;
                     if ((!isEndPoint && isOffMap) || !isWalkable)
                     {
                         closedList.Add(nid);
                     }
                     else
                     {
                         PathNode neighbor = new(nx, ny, currentNode);
                         neighbor.g = (byte)(currentNode.g + 1);
                         float f = ng + (Math.Abs(endPoint.X - nx) + Math.Abs(endPoint.Y - ny));
                         closedList.Add(nid);
                         openList.Enqueue(neighbor, f);
                     }
                 }
             }
             iterations++;
             if (limit >= 0)
             {
                 if (iterations >= limit)
                 {
                     return(null);
                 }
             }
         }
         return(null);
     }
     finally
     {
         if (Interlocked.Decrement(ref _counter) != 0)
         {
             throw new Exception();
         }
     }
 }