private IEnumerable <BarbarianTribeConfiguration> AddBarbarianTribesToRegion(ConfigurationRegion region, int barbarianTribesToCreate) { var maxTries = barbarianTribesToCreate * 25; // The maximum number of valid point generation attempts var i = 0; var ipGroups = region.CityIps.GroupBy(cityIp => cityIp / (CITY_IP_PER_BARB_LVL * 2)) .Select(group => new { GroupIp = group.Key, CityIps = group.ToList() }) .OrderByDescending(group => group.GroupIp) .ToArray(); while (maxTries > 0 && i < barbarianTribesToCreate) { var position = region.GetRandomPosition(); if (!IsLocationAvailable(position)) { maxTries--; continue; } int cityIp; if (i < ipGroups.Length && ipGroups[i].CityIps.Count > 0) { cityIp = ipGroups[i].CityIps.First(); ipGroups[i].CityIps.RemoveAt(0); } else { cityIp = ipGroups.SelectMany(group => @group.CityIps).FirstOrDefault(); } byte level; // Make sure non-empty regions have at least 1 low level barb if (region.CityIps.Count > 0 && i + 1 == barbarianTribesToCreate && region.BarbLevels.All(barbLevel => barbLevel < 2 || barbLevel > 4)) { level = (byte)Config.Random.Next(2, 5); } // If we are generating for a specific city else if (cityIp > 0) { // Returns a random barb level within a 5 level range. // The range is determined by the provided city_ip. // E.g., a city with 150 ip will result in barb lvl 4-8. level = (byte)((cityIp / CITY_IP_PER_BARB_LVL).Clamp(1, 6) + Config.Random.Next(0, 5)); } // Pick a random one if we already have a low level and we are generating the free barb else { level = (byte)Config.Random.Next(2, 11); } level = level.Clamp((byte)1, (byte)10); region.BarbLevels.Add(level); yield return(new BarbarianTribeConfiguration(level, position)); i++; } }
private int GetBarbarianTribesToGenerate(ConfigurationRegion region) { var cityCount = region.CityIps.Count; var barbCount = region.BarbLevels.Count; var neededSpawns = MIN_BARBS_PER_REGION; // Start with min amount neededSpawns += cityCount; // Add another barb for each city neededSpawns = Math.Min(neededSpawns, MAX_BARBS_PER_REGION); // Cap result neededSpawns -= barbCount; // Subtract existing barbs from result neededSpawns = Math.Max(0, neededSpawns); // Keep result at 0 or higher return(neededSpawns); }
private ConfigurationRegion GenerateRegion(Position regionPosition, List <IBarbarianTribe> existingBarbarianTribes) { var region = new ConfigurationRegion(regionPosition); foreach (var barbarianTribe in existingBarbarianTribes .Where(barbarianTribe => region.IsWithinRegion(barbarianTribe.PrimaryPosition))) { region.BarbLevels.Add(barbarianTribe.Lvl); } // We are not locking cities here but all we are accessing is the primary position and the value // which are never null foreach (var city in cityManager.AllCities().Where(city => region.IsWithinRegion(city.PrimaryPosition))) { region.CityIps.Add(city.Value); } return(region); }