コード例 #1
0
ファイル: PlayerBot.cs プロジェクト: qoter/GameBot
        private Turn CollectHealth(LevelView levelView)
        {
            if (levelView.Player.Health > HighHealthLimit || !levelView.HealthPacks.Any())
            {
                automaton.PopAction();
                return(automaton.CurrentAction.Invoke(levelView));
            }

            var influenceMap        = InfluenceMap.CreateForm(levelView);
            var pathToNearestHealth = PathFinder.FindShortestPathWithInfluenceMap(levelView, influenceMap, levelView.Player.Location, loc => levelView.GetHealthPackAt(loc).HasValue);

            return(PathFinder.GetFirstTurn(pathToNearestHealth));
        }
コード例 #2
0
ファイル: Algorithm.cs プロジェクト: snoward/Roguelike
        public static IEnumerable <Location> Dijkstra(LevelView levelView, Func <Location, bool> isTarget)
        {
            var costs   = new InfluenceMap(levelView);
            var current = levelView.Player.Location;
            var dist    = new Dictionary <Location, int> {
                [current] = 0
            };
            var prev      = new Dictionary <Location, Location>();
            var notOpened = new HashSet <Location> {
                current
            };

            for (var y = 0; y < levelView.Field.Height; y++)
            {
                for (var x = 0; x < levelView.Field.Width; x++)
                {
                    var location = new Location(x, y);
                    var cellType = levelView.Field[location];
                    if ((cellType == CellType.Empty || cellType == CellType.PlayerStart) && (location != current) &&
                        !levelView.GetItemAt(location).HasValue)
                    {
                        notOpened.Add(location);
                        dist[location] = int.MaxValue;
                    }
                }
            }
            while (notOpened.Any())
            {
                var toOpen    = default(Location);
                var bestPrice = int.MaxValue;
                foreach (var node in notOpened)
                {
                    if (dist.ContainsKey(node) && (dist[node] < bestPrice))
                    {
                        bestPrice = dist[node];
                        toOpen    = node;
                    }
                }
                notOpened.Remove(toOpen);

                if (isTarget(toOpen))
                {
                    return(RevertPath(levelView, toOpen, prev));
                }

                foreach (var stepOffset in Offset.StepOffsets)
                {
                    var neighbour = toOpen + stepOffset;
                    if (!notOpened.Contains(neighbour))
                    {
                        continue;
                    }
                    var alt = dist[toOpen] + costs[neighbour];
                    if (alt < dist[neighbour])
                    {
                        dist[neighbour] = alt;
                        prev[neighbour] = toOpen;
                    }
                }
            }
            return(RevertPath(levelView, current, prev));
        }
コード例 #3
0
ファイル: PathFinder.cs プロジェクト: qoter/GameBot
        public static List <Location> FindShortestPathWithInfluenceMap(LevelView levelView, InfluenceMap influenceMap, Location from, Func <Location, bool> isTarget)
        {
            var notOpened = new SortedSet <LocationWithPriority>();
            var distances = new Dictionary <Location, int>();
            var previous  = new Dictionary <Location, Location> {
                [from] = default(Location)
            };

            foreach (var location in levelView.Field.GetAllLocations())
            {
                if ((IsPassable(location, levelView) || isTarget(location)) && location != from)
                {
                    distances[location] = int.MaxValue;
                    notOpened.Add(new LocationWithPriority(location, int.MaxValue));
                }
            }

            distances[from] = 0;
            notOpened.Add(new LocationWithPriority(from, 0));

            while (notOpened.Any())
            {
                var toOpen = notOpened.Min;
                notOpened.Remove(toOpen);

                if (toOpen.Priority == int.MaxValue)
                {
                    return(null);
                }
                if (isTarget(toOpen.Location))
                {
                    return(CreatePath(from, toOpen.Location, previous));
                }

                foreach (var adjacentLocation in GetAdjacentLocations(toOpen.Location, levelView).Where(l => IsPassable(l, levelView) || isTarget(l)))
                {
                    var currentDistance = toOpen.Priority + influenceMap[adjacentLocation];
                    if (!previous.ContainsKey(adjacentLocation) || currentDistance < distances[adjacentLocation])
                    {
                        notOpened.Remove(new LocationWithPriority(adjacentLocation, distances[adjacentLocation]));
                        distances[adjacentLocation] = currentDistance;
                        notOpened.Add(new LocationWithPriority(adjacentLocation, currentDistance));
                        previous[adjacentLocation] = toOpen.Location;
                    }
                }
            }
            return(null);
        }