public Regions PickStartingRegions(Map map, Regions availableOptions)
        {
            int numberToPick = availableOptions.Count > GameSettings.StartingRegions ? GameSettings.StartingRegions : availableOptions.Count;

            var selectedRegions = new Regions();

            // Sgt. Stupid picks random regions from the ones he was provided.
            availableOptions.OrderBy(x => _random.Next()).Take(numberToPick)
                .ToList()
                .ForEach(selectedRegions.Add);

            return selectedRegions;
        }
        public Regions PickStartingRegions(Map map, Regions availableOptions)
        {
            int numberToPick = availableOptions.Count > 6 ? 6 : availableOptions.Count;

            IEnumerable<RegionScore<StartRegion>> scores = _calc.CalculateStartRegions(map);

            var pickList = new Regions();

            pickList.AddRange(scores
                .OrderByCumulativeScore()
                .Where(r => availableOptions.Contains(r.Region))
                .Select(r => r.Region)
                .Take(numberToPick));

            return pickList;
        }
        public IEnumerable<ArmyPlacement> PlaceArmies(Map map)
        {
            var armyPlacements = new List<ArmyPlacement>();

            // Sgt. Stupid dumps everybody to the first region we own that's on a battle front.  No battlefront, means you won the game, but dump them on anything then.
            Region firstRegion =
                map.Regions.FirstOrDefault(r => r.Owner == BotPlayer && r.BoardingUncontrolled.Any()) ??
                map.Regions.First(r => r.Owner == BotPlayer);

            firstRegion.Armies += BotPlayer.DeployableArmies;
            armyPlacements.Add(new ArmyPlacement(firstRegion, BotPlayer.DeployableArmies));

            BotPlayer.DeployableArmies = 0;

            return armyPlacements;
        }
        public IEnumerable<AttackTransfer> AttackTransfer(Map map)
        {
            var moves = new List<AttackTransfer>();

            // Sgt Stupid does not transfer.  He just attacks, attacks, attacks!!!!
            foreach (Region ourRegion in map.Regions.OwnedBy(BotPlayer))
            {
                foreach (Region uncontrolled in ourRegion.BoardingUncontrolled)
                {
                    // If Sgt Stupid's region has a neighbor that's not his, kick their ass if they're out gunned.
                    if (ourRegion.ArmyRatio(uncontrolled) >= 1.5)
                    {
                        moves.Add(new AttackTransfer(ourRegion, uncontrolled, ourRegion.MaxAttackTransfer));
                        break;
                    }
                }
            }

            return moves;
        }
        public IEnumerable<RegionScore<StartRegion>> CalculateStartRegions(Map map)
        {
            var scores = new List<RegionScore<StartRegion>>();

            foreach (Region region in map.Regions)
            {
                var calc = new RegionScore<StartRegion>(region, new StartRegion());

                calc.Scores.SuperRegionScore = 1/(double) region.SuperRegion.Regions.Count*5;
                calc.Scores.DefensibilityScore = 1/(double) region.Neighbors.Count;
                calc.Scores.BorderRegionScore = region.IsBorderRegion ? .2 : 0;

                if (region.IsBorderRegion)
                    calc.Scores.ChokepointScore = 1/(double) region.SuperRegion.BorderRegions.Count();
                else
                    calc.Scores.ChokepointScore = 0;

                scores.Add(calc);
            }

            return scores;
        }
        //public IEnumerable<AttackTransfer> AttackTransfer(Map map)
        //{
        //    throw new NotImplementedException();
        //}
        public IEnumerable<AttackTransfer> AttackTransfer(Map map)
        {
            List<Region> ourRegions = map.Regions.OwnedBy(BotPlayer).ToList();
            var moves = new List<AttackTransfer>();

            foreach (Region ourRegion in ourRegions)
            {
                foreach (Region uncontrolled in ourRegion.BoardingUncontrolled)
                {
                    // If Sgt Stupid's region has a neighbor that's not his, kick their ass if they're out gunned.
                    if (ourRegion.ArmyRatio(uncontrolled) >= 1.5)
                    {
                        moves.Add(new AttackTransfer(ourRegion, uncontrolled, ourRegion.MaxAttackTransfer));
                        break;
                    }
                }
            }

            // Transfer armies from sheltered regions to the closest battlefront
            foreach (Region sheltered in ourRegions.Sheltered().Where(r => r.Armies > GameSettings.MinimumArmies))
            {

                List<Region> shortestPath = null;

                foreach (Region battleFront in ourRegions.OrderByDescending(r => r.BoardingEnemyArmies))
                {
                    var path = map.Regions.ShortestPath(sheltered, battleFront, BotPlayer).ToList();

                    if (path.Any() && (shortestPath == null || path.Count() < shortestPath.Count()))
                        shortestPath = path;
                }

                if (shortestPath != null && shortestPath.Any())
                    moves.Add(new AttackTransfer(sheltered, shortestPath[0], sheltered.Armies - GameSettings.MinimumArmies));
            }

            return moves;
        }
        public IEnumerable<RegionScore<Deployment>> CalculateDeployments(Map map, Player targetPlayer)
        {
            var scores = new List<RegionScore<Deployment>>();

            foreach (Region region in map.Regions.OwnedBy(targetPlayer))
            {
                var calc = new RegionScore<Deployment>(region, new Deployment());

                calc.Scores.HostilityScore = region.BoardingEnemyArmies * .1;
                calc.Scores.ExpansionScore = region.BoardingUncontrolled.Any() ? 1/(double) region.BoardingUncontrolled.Count() : 0;

                // Only give superregions a weight if we don't own it.  Expansive strategy for now.
                if (region.SuperRegion.Owner != targetPlayer)
                {
                    calc.Scores.SuperRegionScore = region.SuperRegion.Regions.OwnedBy(targetPlayer).Count() /
                                                   (double) region.SuperRegion.Regions.Count() * 1.5;
                }

                scores.Add(calc);
            }

            return scores;
        }
        public IEnumerable<ArmyPlacement> PlaceArmies(Map map)
        {
            var placements = new List<ArmyPlacement>();

            IEnumerable<RegionScore<Deployment>> top3 =
                _calc.CalculateDeployments(map, BotPlayer)
                .OrderByDescending(s => s.Scores.CumulativeScore)
                .Take(3)
                .ToList();

            // Only deal with the top 3 placements
            double top3TotalScore = top3.Sum(s => s.Scores.CumulativeScore);

            // Total number of deployable armies.  For calculating army allocation percentages.
            int deployableArmies = BotPlayer.DeployableArmies;

            foreach (RegionScore<Deployment> deployment in top3)
            {
                // Deploy armies based on their score % of the total.
                var armies = (int)Math.Floor((deployment.Scores.CumulativeScore/top3TotalScore) * deployableArmies);

                BotPlayer.DeployableArmies -= armies;

                placements.Add(new ArmyPlacement(deployment.Region, armies));
            }

            // Cleanup
            if (BotPlayer.DeployableArmies != 0)
            {
                placements[0].Armies += BotPlayer.DeployableArmies;
                BotPlayer.DeployableArmies = 0;
            }

            return placements;
        }
 public IEnumerable<RegionScore<Desirability>> CalculateDesirability(Map map, Player targetPlayer)
 {
     throw new NotImplementedException();
 }