private int ShouldLaunchShips(ReadOnlyMap map, ReadOnlyPlanetData source, ReadOnlyPlanetData destination)
 {
     if (!IsVisible(map, source, destination))
     {
         return(0);
     }
     return(source.OwnerId == destination.OwnerId
         ? ShouldLaunchReinforcementShips(map, source, destination)
         : ShouldLaunchAttackShips(map, source, destination));
 }
        public List <FleetData> ChooseFleetsToLaunch(Guid userId, ReadOnlyMap map)
        {
            if (map == null)
            {
                throw new ArgumentNullException(nameof(map));
            }
            if (!map.Any())
            {
                return(new List <FleetData>());
            }
            var planetComparer = new PropertyComparer <ReadOnlyPlanetData, string>(x => x.Name);
            var myPlanets      = map
                                 .Where(x => x.OwnerId == userId)
                                 .ToHashSet(planetComparer);
            var allPlanets = map
                             .ToHashSet(planetComparer);

            if (myPlanets.Count == 0)
            {
                return(new List <FleetData>());
            }
            var topPlanet   = allPlanets.OrderByDescending(RankPlanet).First();
            var myTopPlanet = myPlanets.OrderByDescending(RankPlanet).First();
            var candidates  = myPlanets
                              .AsParallel()
                              .SelectMany(source =>
            {
                var otherPlanets = allPlanets
                                   .Except(new[] { source }, planetComparer);
                return(GetCandidates(map, source, otherPlanets, myTopPlanet, topPlanet));
            })
                              .OrderByDescending(Rank)
                              .ToList();
            var sentShips = new Dictionary <string, int>();
            var fleets    = new List <FleetData>();

            foreach (var candidate in candidates)
            {
                var sent = sentShips.GetOrCreateDefault(candidate.Source.Name);
                if (candidate.Ships + sent > candidate.Source.Ships)
                {
                    continue;
                }
                fleets.Add(new FleetData
                {
                    From  = candidate.Source.Position,
                    To    = candidate.Destination.Position,
                    Ships = candidate.Ships
                });
                sentShips[candidate.Source.Name] += candidate.Ships;
            }
            return(fleets);
        }
        private int ShouldLaunchReinforcementShips(ReadOnlyMap map, ReadOnlyPlanetData source,
                                                   ReadOnlyPlanetData destination)
        {
            var stupidPower  = (1 - source.Power) * (1 - _options.ClevernessFactor);
            var powerRatio   = (source.Power + stupidPower) / destination.Power;
            var shouldLaunch = powerRatio < 1;

            if (!shouldLaunch)
            {
                return(0);
            }
            var ships = (int)Math.Floor(source.Ships * _options.RiskFactor);

            return(ships);
        }
 private IEnumerable <Candidate> GetCandidates(
     ReadOnlyMap map,
     ReadOnlyPlanetData source,
     IEnumerable <ReadOnlyPlanetData> otherPlanets,
     ReadOnlyPlanetData myTopPlanet,
     ReadOnlyPlanetData topPlanet)
 {
     return(otherPlanets
            .Select(destination => new Candidate
     {
         Source = source,
         Destination = destination,
         Ships = ShouldLaunchShips(map, source, destination),
         MyTopPlanet = myTopPlanet,
         TopPlanet = topPlanet
     })
            .Where(fleet => fleet.Ships > 0));
 }
Ejemplo n.º 5
0
        public List <FleetData> ChooseFleetsToLaunch(Guid userId, ReadOnlyMap map)
        {
            var myPlanets    = map.Where(x => x.OwnerId == userId).ToHashSet(_planetComparer);
            var otherPlanets = map.Except(myPlanets, _planetComparer).ToList();

            if (otherPlanets.Count == 0)
            {
                return(new List <FleetData>());
            }
            var fleets = myPlanets
                         .Select(source => new FleetData
            {
                From  = source.Position,
                To    = otherPlanets[_random.Next(0, otherPlanets.Count)].Position,
                Ships = source.Ships
            })
                         .ToList();

            return(fleets);
        }
        private int ShouldLaunchAttackShips(ReadOnlyMap map, ReadOnlyPlanetData source, ReadOnlyPlanetData destination)
        {
            var distance           = map.CalculateDistance(source.Position, destination.Position);
            var enemyExpectedPower = (destination.Ships + destination.ProductionRate * distance) * destination.Power;
            var requiredShips      = (int)Math.Ceiling(enemyExpectedPower / source.Power * _options.ClevernessFactor);
            var enoughShips        = source.Ships >= requiredShips;

            if (!enoughShips)
            {
                return(0);
            }
            var difference = source.Ships - requiredShips;

            if (difference == 0)
            {
                return(requiredShips);
            }
            var addition = (int)Math.Floor(difference - _options.RiskFactor * difference);

            return(requiredShips + addition);
        }
        private bool IsVisible(ReadOnlyMap map, ReadOnlyPlanetData source, ReadOnlyPlanetData destination)
        {
            var distance = map.CalculateDistance(source.Position, destination.Position);

            return(distance < map.MaxDistance * _options.VisionFactor);
        }