Beispiel #1
0
        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);
        }
Beispiel #2
0
        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());
        }
Beispiel #3
0
        public void DistributeYieldAndResources(HomelandData homelandData, IMapTemplate mapTemplate)
        {
            LuxuryDistributor.DistributeLuxuriesAcrossHomeland(homelandData);
            StrategicDistributor.DistributeStrategicsAcrossHomeland(homelandData);

            HomelandBalancer.BalanceHomelandYields(homelandData);
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
        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;
                }
            }
        }
Beispiel #6
0
        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);
        }
Beispiel #7
0
        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
                            );
                    }
                }
            }
        }
Beispiel #8
0
        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;
                }
            }
        }
Beispiel #9
0
        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);
            }
        }
Beispiel #10
0
        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());
        }