예제 #1
0
        public static Stack <Point> FindPathOnFarm(Point startPoint, Point endPoint, GameLocation location, int limit)
        {
            Dictionary <Vector2, int> weight_map = new Dictionary <Vector2, int>();
            PriorityQueue             openList   = new PriorityQueue();
            HashSet <int>             closedList = new HashSet <int>();
            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));
            PathNode previousNode = (PathNode)openList.Peek();
            int      layerWidth   = location.map.Layers[0].LayerWidth;
            int      layerHeight  = location.map.Layers[0].LayerHeight;

            while (!openList.IsEmpty())
            {
                PathNode currentNode = openList.Dequeue();
                if (currentNode.x == endPoint.X && currentNode.y == endPoint.Y)
                {
                    return(reconstructPath(currentNode));
                }
                closedList.Add(currentNode.id);
                for (int i = 0; i < 4; i++)
                {
                    int neighbor_tile_x = currentNode.x + Directions[i, 0];
                    int neighbor_tile_y = currentNode.y + Directions[i, 1];
                    int nid             = PathNode.ComputeHash(neighbor_tile_x, neighbor_tile_y);
                    if (closedList.Contains(nid))
                    {
                        continue;
                    }
                    PathNode neighbor = new PathNode(neighbor_tile_x, neighbor_tile_y, currentNode);
                    neighbor.g = (byte)(currentNode.g + 1);
                    if ((neighbor.x == endPoint.X && neighbor.y == endPoint.Y) || (neighbor.x >= 0 && neighbor.y >= 0 && neighbor.x < layerWidth && neighbor.y < layerHeight && !IsPositionImpassableOnFarm(location, neighbor.x, neighbor.y)))
                    {
                        int f = neighbor.g + GetFarmTileWeight(location, neighbor.x, neighbor.y, weight_map) + (Math.Abs(endPoint.X - neighbor.x) + Math.Abs(endPoint.Y - neighbor.y));
                        if (previousNode.x - currentNode.x == currentNode.x - neighbor_tile_x && previousNode.y - currentNode.y == currentNode.y - neighbor_tile_y)
                        {
                            f -= 25;
                        }
                        if (!openList.Contains(neighbor, f))
                        {
                            openList.Enqueue(neighbor, f);
                        }
                    }
                }
                previousNode = currentNode;
                iterations++;
                if (iterations >= limit)
                {
                    return(null);
                }
            }
            return(null);
        }
        public static Stack <Point> findPathForNPCSchedules(Point startPoint, Point endPoint, GameLocation location, int limit)
        {
            PriorityQueue openList   = new PriorityQueue();
            HashSet <int> closedList = new HashSet <int>();
            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));
            PathNode previousNode = (PathNode)openList.Peek();
            int      layerWidth   = location.map.Layers[0].LayerWidth;
            int      layerHeight  = location.map.Layers[0].LayerHeight;

            while (!openList.IsEmpty())
            {
                PathNode currentNode = openList.Dequeue();
                if (currentNode.x == endPoint.X && currentNode.y == endPoint.Y)
                {
                    return(reconstructPath(currentNode));
                }
                closedList.Add(currentNode.id);
                for (int i = 0; i < 4; i++)
                {
                    int neighbor_tile_x = currentNode.x + Directions[i, 0];
                    int neighbor_tile_y = currentNode.y + Directions[i, 1];
                    int nid             = PathNode.ComputeHash(neighbor_tile_x, neighbor_tile_y);
                    if (closedList.Contains(nid))
                    {
                        continue;
                    }
                    PathNode neighbor = new PathNode(neighbor_tile_x, neighbor_tile_y, currentNode);
                    neighbor.g = (byte)(currentNode.g + 1);
                    if ((neighbor.x == endPoint.X && neighbor.y == endPoint.Y) || (neighbor.x >= 0 && neighbor.y >= 0 && neighbor.x < layerWidth && neighbor.y < layerHeight && !isPositionImpassableForNPCSchedule(location, neighbor.x, neighbor.y)))
                    {
                        int f = neighbor.g + getPreferenceValueForTerrainType(location, neighbor.x, neighbor.y) + (Math.Abs(endPoint.X - neighbor.x) + Math.Abs(endPoint.Y - neighbor.y) + (((neighbor.x == currentNode.x && neighbor.x == previousNode.x) || (neighbor.y == currentNode.y && neighbor.y == previousNode.y)) ? (-2) : 0));
                        if (!openList.Contains(neighbor, f))
                        {
                            openList.Enqueue(neighbor, f);
                        }
                    }
                }
                previousNode = currentNode;
                iterations++;
                if (iterations >= limit)
                {
                    return(null);
                }
            }
            return(null);
        }
 public static Stack <Point> findPath(Point startPoint, Point endPoint, isAtEnd endPointFunction, GameLocation location, Character character, int limit)
 {
     if (Interlocked.Increment(ref _counter) != 1)
     {
         throw new Exception();
     }
     try
     {
         _openList.Clear();
         _closedList.Clear();
         PriorityQueue 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;
         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);
             for (int i = 0; i < 4; i++)
             {
                 int nx  = currentNode.x + Directions[i, 0];
                 int ny  = currentNode.y + Directions[i, 1];
                 int nid = PathNode.ComputeHash(nx, ny);
                 if (!closedList.Contains(nid))
                 {
                     if ((nx != endPoint.X || ny != endPoint.Y) && (nx < 0 || ny < 0 || nx >= layerWidth || ny >= layerHeight))
                     {
                         closedList.Add(nid);
                     }
                     else
                     {
                         PathNode neighbor = new PathNode(nx, ny, currentNode);
                         neighbor.g = (byte)(currentNode.g + 1);
                         if (location.isCollidingPosition(new Rectangle(neighbor.x * 64 + 1, neighbor.y * 64 + 1, 62, 62), Game1.viewport, character is Farmer, 0, glider: false, character, pathfinding: true))
                         {
                             closedList.Add(nid);
                         }
                         else
                         {
                             int f = ng + (Math.Abs(endPoint.X - nx) + Math.Abs(endPoint.Y - ny));
                             closedList.Add(nid);
                             openList.Enqueue(neighbor, f);
                         }
                     }
                 }
             }
             iterations++;
             if (iterations >= limit)
             {
                 return(null);
             }
         }
         return(null);
     }
     finally
     {
         if (Interlocked.Decrement(ref _counter) != 0)
         {
             throw new Exception();
         }
     }
 }