Ejemplo n.º 1
0
 /// <summary>
 /// If neighbour has line of sight to currents parent and skipping current is cheaper, skips current node and sets neighbour cost / parent depending on whether current is used
 /// </summary>
 /// <param name="current"></param>
 /// <param name="neighbour"></param>
 /// <param name="settings"></param>
 /// <param name="openNodes"></param>
 private static void UpdateNode(Node current, Node neighbour, PathfindingSettings settings, BucketList <Node> openNodes)
 {
     if (LineOfSight(current.parent, neighbour))
     {
         var costSkippingCurrent = current.parent.cost + settings.CostIncrease(current.parent.pos, neighbour.pos);
         if (costSkippingCurrent < neighbour.cost)
         {
             if (openNodes.Contains(neighbour))
             {
                 openNodes.Remove(neighbour);
             }
             neighbour.cost   = costSkippingCurrent;
             neighbour.parent = current.parent;
             openNodes.Add(neighbour);
         }
     }
     else
     {
         var costUsingCurrent = current.cost + settings.CostIncrease(current.pos, neighbour.pos);
         if (costUsingCurrent < neighbour.cost)
         {
             if (openNodes.Contains(neighbour))
             {
                 openNodes.Remove(neighbour);
             }
             neighbour.cost   = costUsingCurrent;
             neighbour.parent = current;
             openNodes.Add(neighbour);
         }
     }
 }
Ejemplo n.º 2
0
        /// <summary>
        /// Loads a level from file and initializes the world from its data then returns the level name.
        /// </summary>
        /// <param name="_loadFile">Full file path to level xml save file.</param>
        public string Load(string _loadFile)
        {
            //Debug.Log("Loading level from file: " + _loadFile);
            var levelName = "unknown";

            Current.Clear();

            using (var xmlReader = XmlReader.Create(_loadFile))
            {
                while (xmlReader.Read())
                {
                    if (xmlReader.IsStartElement())
                    {
                        switch (xmlReader.Name)
                        {
                        case "LevelName":
                            xmlReader.Read();
                            levelName = xmlReader.Value;
                            break;

                        case "LevelPlayerSpawn":
                            var px = int.Parse(xmlReader["X"]);
                            var py = int.Parse(xmlReader["Y"]);
                            GameObject.FindGameObjectWithTag("PlayerSpawn").transform.position = new Vector2(px, py);
                            break;

                        case "LevelAISpawn":
                            var aiX = int.Parse(xmlReader["X"]);
                            var aiY = int.Parse(xmlReader["Y"]);
                            GameObject.FindGameObjectWithTag("AISpawn").transform.position = new Vector2(aiX, aiY);
                            break;

                        case "PathfindingSettings":
                            PathfindingSettings.SetHeuristicFromID(int.Parse(xmlReader["Heuristic"]));
                            PathfindingSettings.FallJumpLinkMaxDist = int.Parse(xmlReader["FallJumpLinkDistance"]);
                            break;

                        case "Tile":
                            var x    = int.Parse(xmlReader["TileX"]);
                            var y    = int.Parse(xmlReader["TileY"]);
                            var type = Tile.GetTypeFromString(xmlReader["TileType"]);
                            Current.Tiles[x, y].Type = type;
                            break;
                        }
                    }
                }
            }

            PlatformCount = GetTileCountOfType(TileType.Platform);
            OnWorldModifyFinishCallback();
            //Debug.Log("Finished loading level: " + levelName);
            return(levelName);
        }
Ejemplo n.º 3
0
        public static AlgorithmSolution Find(PathfindingSettings settings, int mapWidth, int mapHeight, IEnumerable <Point> obstacles)
        {
            var observer  = new AlgorithmObserverFactory();
            var start     = new Point(settings.FromX, settings.FromY);
            var goal      = new Point(settings.GoalX, settings.GoalY);
            var boundary  = new Rectangle(0, 0, mapWidth, mapHeight);
            var unit      = 1;
            var queryable = HeuristicSearch.Use(settings.Algorithm, start, goal, (step, i) => step.GetFourDirections(unit), null, observer);
            var solution  = ApplyHeuristicFunction(queryable.Except(obstacles).Where(boundary.Contains), settings.Heuristics);

            return(new AlgorithmSolution()
            {
                Details = observer.Details,
                Solution = solution.ToArray(),
                NumberOfEstimatedNodes = observer.Estimated.Count,
            });
        }
        public ResponseBody <AlgorithmSolution> Find([FromBody] PathfindingRequestBody body)
        {
            var settings = body.ToSettings();

            if (!PathfindingSettings.CheckIfValid(settings))
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return(new ResponseBody <AlgorithmSolution>()
                {
                    Errors = new[] { ResponseError.InvalidFromAndGoalSettings }
                });
            }
            try
            {
                var result = AlgorithmCore.Find(settings, body.Map);

                return(new ResponseBody <AlgorithmSolution>()
                {
                    Data = result
                });
            }
            catch (InvalidOperationException)
            {
                Response.StatusCode = (int)HttpStatusCode.BadRequest;
                return(new ResponseBody <AlgorithmSolution>()
                {
                });
            }
            catch (Exception)
            {
                Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                return(new ResponseBody <AlgorithmSolution>()
                {
                });
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Tries to find a path from start to goal node using settings
        /// </summary>
        /// <param name="start">Start node</param>
        /// <param name="goal">Goal node</param>
        /// <param name="settings">PathfindingSettings (which heuristics to use etc)</param>
        /// <param name="isoLevel">Determines which nodes are considered walkable (iso value > this)</param>
        /// <param name="openNodes">Nodes that were still open after algorithm finished</param>
        /// <param name="closedNodes">Nodes that were fully explored after algorithm finished</param>
        /// <param name="maxIterations">Max number of loop iterations, prevents infinite loops</param>
        /// <param name="nodeCount">Approximate total node count, determines start capacity of path stack</param>
        /// <returns></returns>
        public static Stack <Vector3> FindPath(Node start, Node goal, PathfindingSettings settings, float isoLevel, out BucketList <Node> openNodes, out HashSet <Node> closedNodes, int maxIterations = 50000, int nodeCount = 1000)
        {
            NodesGenerator.CostHeuristicBalance = settings.greediness;
            int neighbourChecks = 0;

            int numIterations = 0;

            //euclidean distance from start to end
            float distance = Vector3.Distance(start.pos, goal.pos);

            //full length of path
            float pathLength = 0;

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();

            if (settings.benchmark)
            {
                sw.Start();
            }

            var             startCapacity = nodeCount / 100;
            Stack <Vector3> path          = new Stack <Vector3>(startCapacity);

            openNodes = new BucketList <Node>(distance / 100, Mathf.Min(settings.Heuristic(start.pos, goal.pos) * settings.greediness, settings.CostIncrease(start.pos, goal.pos) * (1 - settings.greediness)));
            //openNodes = new MinHeap<Node>(startCapacity * 10);

            closedNodes = new HashSet <Node>();

            Node current = null;

            start.cost      = 0;
            start.parent    = start;
            start.heuristic = settings.Heuristic(start.pos, goal.pos);
            openNodes.Add(start);
            while (openNodes.Count != 0 && !closedNodes.Contains(goal))
            {
                if (++numIterations == maxIterations)
                {
                    break;
                }

                current = openNodes.ExtractMin();

                closedNodes.Add(current);

                foreach (var neighbour in current.neighbours)
                {
                    neighbourChecks++;
                    if (neighbour.isoValue <= isoLevel)
                    {
                        continue;
                    }
                    if (closedNodes.Contains(neighbour))
                    {
                        continue;
                    }
                    var newCost = current.cost + settings.CostIncrease(current.pos, neighbour.pos);
                    if (openNodes.Contains(neighbour))
                    {
                        if (newCost >= neighbour.cost)
                        {
                            continue;
                        }
                        openNodes.Remove(neighbour);
                    }
                    neighbour.parent    = current;
                    neighbour.heuristic = settings.Heuristic(neighbour.pos, goal.pos);
                    neighbour.cost      = newCost;

                    openNodes.Add(neighbour);
                }
            }

            if (!closedNodes.Contains(goal))
            {
                Debug.Log("no goal, " + numIterations + " iterations, closed: " + closedNodes.Count + ", opened: " + openNodes.Count);
                return(path);
            }

            path.Push(goal.pos);
            Node temp = goal.parent;

            while (temp != null)
            {
                pathLength += Vector3.Distance(path.Peek(), temp.pos);
                path.Push(temp.pos);
                if (temp == start)
                {
                    break;
                }
                temp = temp.parent;
            }

            if (settings.benchmark)
            {
                sw.Stop();
                Debug.Log("A*, Heuristic: " + settings.heuristic + ", Cost increase: " + settings.costIncrease + ", Path length: " + pathLength * 100 / distance + "%, ms: " + sw.Elapsed.TotalMilliseconds + ", closed: " + closedNodes.Count + ", opened: " + openNodes.Count + ", Neighbour checks: " + neighbourChecks);
            }

            return(path);
        }
Ejemplo n.º 6
0
 public static AlgorithmSolution Find(PathfindingSettings settings, int[][] map)
 {
     return(Find(settings, map.Max(row => row.Length), map.Length, GetAllObstacles(map)));
 }