예제 #1
0
파일: PlayerBot.cs 프로젝트: qoter/GameBot
 private static bool IsLocationForAttack(LevelView levelView, Location location)
 {
     return(GetCountMonstersOnAttackRange(levelView, location) > 0 &&
            levelView.Field[location] != CellType.Wall &&
            levelView.Field[location] != CellType.Trap &&
            !levelView.GetItemAt(location).HasValue);
 }
예제 #2
0
        private int CalculateInfluence(Location location)
        {
            if (levelView.Field.IsOutOfRange(location))
            {
                return(-1);
            }

            var cellType = Field[location];

            if (cellType == CellType.Wall ||
                cellType == CellType.Trap ||
                cellType == CellType.Exit ||
                levelView.GetItemAt(location).HasValue)
            {
                return(-1);
            }

            if (levelView.GetHealthPackAt(location).HasValue)
            {
                return(1 + CalculateMonstersInfluence(location, monsterInfluenceSeed));
            }

            var seedForMonsters = levelView.Monsters.Count() == 1 ? arenaFighterInfluenceSeed : monsterInfluenceSeed;

            return(CalculeateBaseInfluence(location) + CalculateMonstersInfluence(location, seedForMonsters));
        }
예제 #3
0
파일: PathFinder.cs 프로젝트: qoter/GameBot
        private static bool IsPassable(Location location, LevelView levelView)
        {
            var isObject = levelView.GetHealthPackAt(location).HasValue ||
                           levelView.GetMonsterAt(location).HasValue ||
                           levelView.GetItemAt(location).HasValue;

            var isEmpty = levelView.Field[location] == CellType.Empty ||
                          levelView.Field[location] == CellType.PlayerStart;

            return(!isObject && isEmpty);
        }
예제 #4
0
        public static bool IsStepValid(this Location to, LevelView view)
        {
            if (to.X < 0 || to.X >= view.Field.Width ||
                to.Y < 0 || to.Y >= view.Field.Height)
            {
                return(false);
            }

            return(view.Field[to] != CellType.Trap &&
                   view.Field[to] != CellType.Wall &&
                   view.Field[to] != CellType.Exit &&
                   !view.GetMonsterAt(to).HasValue &&
                   !view.GetItemAt(to).HasValue);
        }
예제 #5
0
        private bool TryGetBestStepToItem(LevelView level, out Location locationToStep)
        {
            locationToStep = FindByDijkstra(level, IsToConsider, GetCost);

            return(locationToStep != default(Location));

            bool IsToConsider(Location location)
            {
                level.Player.TryGetEquippedItem(out var item);

                return(level.GetItemAt(location).HasValue&&
                       level.GetItemAt(location).AttackBonus > item.AttackBonus &&
                       level.GetItemAt(location).DefenceBonus > item.DefenceBonus);
            }

            int GetCost(Location location)
            {
                if (level.Field[location] == CellType.Wall ||
                    level.Field[location] == CellType.Trap ||
                    level.GetMonsterAt(location).HasValue)
                {
                    return(100);
                }

                if (level.GetItemAt(location).HasValue)
                {
                    level.Player.TryGetEquippedItem(out var item);

                    if (level.GetItemAt(location).AttackBonus > item.AttackBonus &&
                        level.GetItemAt(location).DefenceBonus > item.DefenceBonus)
                    {
                        return(0);
                    }

                    return(100);
                }

                if (level.Field[location] == CellType.Exit)
                {
                    return(0);
                }

                if (level.Field[location] == CellType.Empty || level.Field[location] == CellType.PlayerStart)
                {
                    return(10 - GetNeighbours(location, NeighbourType.Eight)
                           .Count(x => level.Field[x] == CellType.Trap ||
                                  level.Field[x] == CellType.Wall));
                }

                if (level.Field[location] == CellType.Hidden)
                {
                    return(10);
                }

                throw new ArgumentOutOfRangeException(nameof(location));
            }
        }
예제 #6
0
        public static IEnumerable <Location> BFS(LevelView levelView, Func <Location, bool> isTarget,
                                                 bool acceptPickup = false)
        {
            var queue = new Queue <Location>();
            var start = levelView.Player.Location;

            queue.Enqueue(start);

            var visited = new HashSet <Location> {
                start
            };
            var pred = new Dictionary <Location, Location>();

            while (queue.Any())
            {
                var current = queue.Dequeue();
                if (isTarget(current))
                {
                    return(RevertPath(levelView, current, pred));
                }

                foreach (var offset in Offset.StepOffsets)
                {
                    var next = current + offset;

                    if (!visited.Contains(next) && (levelView.Field[next] > CellType.Trap))
                    {
                        if (levelView.GetHealthPackAt(next).HasValue || levelView.GetItemAt(next).HasValue)
                        {
                            if (!acceptPickup)
                            {
                                continue;
                            }
                        }
                        queue.Enqueue(next);
                        visited.Add(next);
                        pred[next] = current;
                    }
                }
            }
            var path = RevertPath(levelView, levelView.Player.Location, pred);

            if (!path.Any())
            {
                path = BFS(levelView, isTarget, true);
            }

            return(path);
        }
예제 #7
0
        private bool TryGetBestStepToHealth(LevelView level, out Location locationToStep)
        {
            locationToStep = FindByDijkstra(level, IsToConsider, GetCost);

            return(locationToStep != default(Location));

            bool IsToConsider(Location location)
            {
                return(level.GetHealthPackAt(location).HasValue ||
                       location == _exit && _exit != default(Location) ||
                       GetNeighbours(location, NeighbourType.Four)
                       .Any(y => level.Field[y] == CellType.Hidden && _hiddenYet.Contains(y)));
            }

            int GetCost(Location location)
            {
                if (level.Field[location] == CellType.Wall ||
                    level.Field[location] == CellType.Trap ||
                    level.GetMonsterAt(location).HasValue ||
                    level.GetItemAt(location).HasValue)
                {
                    return(100);
                }

                if (level.Field[location] == CellType.Exit ||
                    level.GetHealthPackAt(location).HasValue)
                {
                    return(0);
                }

                if (level.Field[location] == CellType.Empty || level.Field[location] == CellType.PlayerStart)
                {
                    return(10 - GetNeighbours(location, NeighbourType.Eight)
                           .Count(x => level.Field[x] == CellType.Trap ||
                                  level.Field[x] == CellType.Wall));
                }

                if (level.Field[location] == CellType.Hidden)
                {
                    return(10);
                }

                throw new ArgumentOutOfRangeException(nameof(location));
            }
        }
예제 #8
0
        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));
        }
예제 #9
0
파일: PlayerBot.cs 프로젝트: qoter/GameBot
        private static Turn ExecuteFindMonster(LevelView levelView)
        {
            var pathToMonster = PathFinder.FindShortestPath(levelView, levelView.Player.Location,
                                                            location => IsLocationForAttack(levelView, location));

            if (pathToMonster != null)
            {
                return(PathFinder.GetFirstTurn(pathToMonster));
            }
            var pathToHealthOrItem = PathFinder.FindShortestPath(levelView, levelView.Player.Location,
                                                                 location => levelView.GetHealthPackAt(location).HasValue || levelView.GetItemAt(location).HasValue);

            return(PathFinder.GetFirstTurn(pathToHealthOrItem));
        }