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));
 }
        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));
 }
        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 static double RankPlanet(ReadOnlyPlanetData planet)
 {
     return(planet.Power * planet.ProductionRate);
 }
        private bool IsVisible(ReadOnlyMap map, ReadOnlyPlanetData source, ReadOnlyPlanetData destination)
        {
            var distance = map.CalculateDistance(source.Position, destination.Position);

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