Esempio n. 1
0
        /// <summary>
        /// Finds the shortest path from [fleeing] to [chasing] using the AStar algorithm.
        /// </summary>
        /// <param name="start">The node to fleeing at.</param>
        /// <param name="end">The node to chasing at.</param>
        /// <param name="map">The map.</param>
        /// <returns>The path as a list of nodes.</returns>
        public static List<Node> FindPathTo(Node start, Node end, Map map)
        {
            // Create lists
            var path = new List<Node>();
            _open = new List<Node>();
            _closed = new List<Node>();

            // Create fleeing node
            var tempStart = start;
            tempStart.CameFrom = null;
            tempStart.GScore = 0;
            tempStart.FScore = tempStart.GScore + tempStart.DistanceTo(end);
            AddToOpenList(tempStart);

            // While open is not empty...
            while (_open.Count > 0)
            {
                var current = _open[0];

                // If we found the goal ...
                if (current.Equals(end))
                {
                    // ... Create the path.
                    path =  ReconstructPath(current);
                    break;
                }

                _open.Remove(current);
                AddToClosedList(current);

                // For all neighbour nodes
                foreach (var neighbour in map.NeighbourNodes(current))
                {
                    if (neighbour.Closed) continue;

                    // Calculate scores.
                    var tentativeGScore = current.GScore + neighbour.Cost;
                    var tentativeFScore = tentativeGScore + neighbour.DistanceTo(end);

                    // If the neighbour is in the closed list and the tentativeFScore is higher
                    // than the neighbour's, skip it.
                    if (_closed.Contains(neighbour)
                        && tentativeFScore >= _closed[_closed.IndexOf(neighbour)].FScore)
                    {
                        continue;
                    }

                    // If the neighbour is not in the open list, add it.
                    if (!_open.Contains(neighbour)
                        && map.WithinMap(neighbour))
                    {
                        neighbour.CameFrom = current;
                        neighbour.GScore = tentativeGScore;
                        neighbour.FScore = tentativeFScore;

                        AddToOpenList(neighbour);
                        continue;
                    }

                    // If the neighbour is in the open list, modify it.
                    if (_open.Contains(neighbour)
                        && map.WithinMap(neighbour))
                    {
                        var indexOfNeighbour = _open.IndexOf(neighbour);

                        if (tentativeFScore < _open[indexOfNeighbour].FScore)
                        {
                            _open[indexOfNeighbour].CameFrom = current;
                            _open[indexOfNeighbour].GScore = tentativeGScore;
                            _open[indexOfNeighbour].FScore = tentativeFScore;
                        }
                    }
                }
            }

            return path;
        }
Esempio n. 2
0
        /// <summary>
        /// Simple way to avoid the target.
        /// </summary>
        /// <param name="target">The target to avoid.</param>
        /// <param name="map">The map that the agent is traveling on.</param>
        public void Avoid(Agent target, Map map)
        {
            var iterations = 0;
            int newX = X, newY = Y;

            var targetNode = map[target.X, target.Y];
            var currentDist = map[X, Y].DistanceTo(targetNode);

            // Only 10 steps are needed.
            while (iterations < 20)
            {
                var neighbours = map.NeighbourNodes(map[newX, newY]);

                // Check which neighbour node that leads furthest away from the target.
                foreach (Node neighbour in neighbours)
                {
                    if (neighbour.Closed) continue;

                    var tempDist = neighbour.DistanceTo(targetNode);

                    if (tempDist > currentDist)
                    {
                        currentDist = tempDist;
                        var optimalNeighbour = neighbours.IndexOf(neighbour);

                        newX = neighbours[optimalNeighbour].X;
                        newY = neighbours[optimalNeighbour].Y;
                    }
                }

                iterations++;
            }

            // Find the path to the target location.
            Path = AStar.FindPathTo(map[X, Y], map[newX, newY], map);
            Move();
        }