public void BalanceHomelandYields(HomelandData homelandData) { YieldSummary currentYield = YieldSummary.Empty; foreach (var cell in homelandData.Cells) { currentYield += YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs); } float weightedCellCount = homelandData.LandCells.Count() * homelandData.YieldAndResources.LandWeight + homelandData.WaterCells.Count() * homelandData.YieldAndResources.WaterWeight; float minFood = homelandData.YieldAndResources.MinFoodPerCell * weightedCellCount; float minProduction = homelandData.YieldAndResources.MinProductionPerCell * weightedCellCount; BringYieldTypeToMin( YieldType.Food, minFood, homelandData, ref currentYield ); BringYieldTypeToMin( YieldType.Production, minProduction, homelandData, ref currentYield ); float minScore = homelandData.YieldAndResources.MinScorePerCell * weightedCellCount; float maxScore = homelandData.YieldAndResources.MaxScorePerCell * weightedCellCount; KeepScoreWithinBounds(homelandData, minScore, maxScore); }
private List <IResourceDefinition> GetLuxuriesForWholeHomeland( HomelandData homelandData, out Dictionary <IResourceDefinition, int> weightOfResources ) { var startingRegionWeights = homelandData.StartingData.GetResourceWeights(); var otherRegionsByWeight = homelandData.OtherRegionData.Select( regionData => regionData.GetResourceWeights() ); weightOfResources = new Dictionary <IResourceDefinition, int>(); foreach (var resource in startingRegionWeights.Keys) { if (resource.Type != ResourceType.Luxury || startingRegionWeights[resource] <= 0) { continue; } var otherRegionWeights = otherRegionsByWeight.Select( resourceWeight => resourceWeight.ContainsKey(resource) ? resourceWeight[resource] : 0 ); if (otherRegionWeights.Max() > 0) { weightOfResources[resource] = startingRegionWeights[resource] + otherRegionWeights.Sum(); } } return(weightOfResources.Keys.ToList()); }
public void DistributeYieldAndResources(HomelandData homelandData, IMapTemplate mapTemplate) { LuxuryDistributor.DistributeLuxuriesAcrossHomeland(homelandData); StrategicDistributor.DistributeStrategicsAcrossHomeland(homelandData); HomelandBalancer.BalanceHomelandYields(homelandData); }
public void GenerateTopologyAndEcology(HomelandData homelandData, IMapTemplate mapTemplate) { var regions = homelandData.OtherRegions.ToList(); regions.Add(homelandData.StartingRegion); int riveredCells = 0; foreach (var region in regions) { var regionData = homelandData.GetDataOfRegion(region); RegionGenerator.GenerateTopology(region, regionData.Topology); RegionGenerator.PaintTerrain(region, regionData.Biome); riveredCells += Mathf.CeilToInt(region.LandCells.Count * regionData.Biome.RiverPercentage * 0.01f); } var allLandCells = regions.SelectMany(region => region.LandCells); var allWaterCells = regions.SelectMany(region => region.WaterCells); RiverGenerator.CreateRivers(allLandCells, allWaterCells, riveredCells); RegionGenerator.AssignFloodPlains(allLandCells); foreach (var region in regions) { var regionData = homelandData.GetDataOfRegion(region); VegetationPainter.PaintVegetation(region, regionData.Biome); } }
public void DistributeStrategicsAcrossHomeland(HomelandData homelandData) { int nodesLeft = Mathf.CeilToInt(homelandData.YieldAndResources.StrategicNodesPerCell * homelandData.Cells.Count()); int copiesLeft = Mathf.CeilToInt(homelandData.YieldAndResources.StrategicCopiesPerCell * homelandData.Cells.Count()); var validStrategics = new List <IResourceDefinition>(StrategicResources); var resourceWeightsByRegion = new Dictionary <MapRegion, Dictionary <IResourceDefinition, int> >(); foreach (var region in homelandData.AllRegions) { resourceWeightsByRegion[region] = homelandData.GetDataOfRegion(region).GetResourceWeights(); } var regions = homelandData.AllRegions.ToList(); int iterations = regions.Count * 10; while (nodesLeft > 0 && copiesLeft > 0 && iterations-- > 0) { if (regions.Count == 0) { regions.AddRange(homelandData.AllRegions); } var region = regions.Random(); regions.Remove(region); var resourceWeights = resourceWeightsByRegion[region]; var strategic = ResourceRandomSampler.SampleElementsFromSet( validStrategics, 1, resource => resourceWeights.ContainsKey(resource) ? resourceWeights[resource] : 0 ).FirstOrDefault(); if (strategic == null) { continue; } var location = CellRandomSampler.SampleElementsFromSet( region.Cells, 1, cell => ResourceRestrictionCanon.GetPlacementWeightOnCell(strategic, cell) ).FirstOrDefault(); if (location != null && NodeFactory.CanBuildNode(location, strategic)) { int copies = StrategicCopiesLogic.GetWeightedRandomCopies(); copies = Math.Min(copies, copiesLeft); NodeFactory.BuildNode(location, strategic, copies); nodesLeft--; copiesLeft -= copies; } } }
private List <IResourceDefinition> GetLuxuriesForStartingRegion( HomelandData homelandData, out Dictionary <IResourceDefinition, int> weightOfResources ) { weightOfResources = homelandData.StartingData.GetResourceWeights(); var retval = weightOfResources.Keys.Where(resource => resource.Type == ResourceType.Luxury).ToList(); return(retval); }
public void DistributeLuxuriesAcrossHomeland(HomelandData homelandData) { Dictionary <IResourceDefinition, int> weightForStarting; Dictionary <IResourceDefinition, int> weightForOthers; Dictionary <IResourceDefinition, int> weightForWhole; List <IResourceDefinition> luxuriesForStarting = GetLuxuriesForStartingRegion(homelandData, out weightForStarting); List <IResourceDefinition> luxuriesForOthers = GetLuxuriesForOtherRegions(homelandData, out weightForOthers); List <IResourceDefinition> luxuriesForWhole = GetLuxuriesForWholeHomeland(homelandData, out weightForWhole); var luxuriesAlreadyChosen = new HashSet <IResourceDefinition>(); foreach (var luxuryData in homelandData.LuxuryResources) { if (luxuryData.ConstrainedToStarting) { DistributeLuxuryAcrossSingleRegion( homelandData.StartingRegion, luxuryData.StartingCount, luxuriesForStarting, weightForStarting, luxuriesAlreadyChosen ); } else if (luxuryData.ConstrainedToOthers) { DistributeLuxuryAcrossMultipleRegions( homelandData.OtherRegions, luxuryData.OtherCount, luxuriesForOthers, weightForOthers, luxuriesAlreadyChosen ); } else { if (!TryDistributeLuxuryAcrossSingleAndMultipleRegions( homelandData.StartingRegion, homelandData.OtherRegions, luxuryData.StartingCount, luxuryData.OtherCount, luxuriesForWhole, weightForWhole, luxuriesAlreadyChosen )) { DistributeLuxuryAcrossSingleRegion( homelandData.StartingRegion, luxuryData.StartingCount, luxuriesForStarting, weightForStarting, luxuriesAlreadyChosen ); DistributeLuxuryAcrossMultipleRegions( homelandData.OtherRegions, luxuryData.OtherCount, luxuriesForOthers, weightForOthers, luxuriesAlreadyChosen ); } } } }
private void KeepScoreWithinBounds(HomelandData homelandData, float minScore, float maxScore) { var currentScore = homelandData.Cells.Select(cell => CellScorer.GetScoreOfCell(cell)).Sum(); float scoreChange; var strategyWeightsByRegion = new Dictionary <MapRegion, Dictionary <IBalanceStrategy, int> >(); foreach (var region in homelandData.AllRegions) { strategyWeightsByRegion[region] = homelandData.GetDataOfRegion(region).GetBalanceStrategyWeights(); } int iterations = homelandData.AllRegions.Count() * 50; var regions = homelandData.AllRegions.ToList(); while ((currentScore < minScore || currentScore > maxScore) && iterations-- > 0) { if (regions.Count == 0) { regions.AddRange(homelandData.AllRegions); } var region = regions.Random(); regions.Remove(region); var regionData = homelandData.GetDataOfRegion(region); var strategyToAttempt = GetStrategy(strategyWeightsByRegion[region]); if (strategyToAttempt == null) { break; } if (currentScore < minScore && strategyToAttempt.TryIncreaseScore(region, regionData, out scoreChange)) { currentScore += scoreChange; } if (currentScore > maxScore && strategyToAttempt.TryDecreaseScore(region, regionData, out scoreChange)) { currentScore -= scoreChange; } } }
private void BringYieldTypeToMin( YieldType type, float minYield, HomelandData homelandData, ref YieldSummary currentYield ) { float yieldDeficit = minYield - currentYield[type]; var strategyWeightsByRegion = new Dictionary <MapRegion, Dictionary <IBalanceStrategy, int> >(); foreach (var region in homelandData.AllRegions) { strategyWeightsByRegion[region] = homelandData.GetDataOfRegion(region).GetBalanceStrategyWeights(); } int iterations = homelandData.AllRegions.Count() * 10; List <MapRegion> regions = homelandData.AllRegions.ToList(); while (yieldDeficit > 0 && iterations-- > 0) { if (regions.Count == 0) { regions = homelandData.AllRegions.ToList(); } var region = regions.Random(); regions.Remove(region); var strategyWeights = strategyWeightsByRegion[region]; var strategy = GetStrategy(strategyWeights); YieldSummary yieldAdded; if (strategy.TryIncreaseYield(region, homelandData.GetDataOfRegion(region), type, out yieldAdded)) { yieldDeficit -= yieldAdded[type]; currentYield += yieldAdded; } } if (currentYield[type] < minYield) { Debug.LogWarningFormat("Failed to bring yield type {0} to min yield {1}", type, minYield); } }
private List <IResourceDefinition> GetLuxuriesForOtherRegions( HomelandData homelandData, out Dictionary <IResourceDefinition, int> weightOfResources ) { weightOfResources = new Dictionary <IResourceDefinition, int>(); foreach (var regionData in homelandData.OtherRegionData) { var resourceWeights = regionData.GetResourceWeights(); foreach (var luxury in resourceWeights.Keys.Where(resource => resource.Type == ResourceType.Luxury)) { int globalPriority; weightOfResources.TryGetValue(luxury, out globalPriority); globalPriority += resourceWeights[luxury]; weightOfResources[luxury] = globalPriority; } } return(weightOfResources.Keys.ToList()); }