private void DrawForbiddenLine(
            HashSet <MapSection> unassignedSections, HashSet <MapSection> forbiddenSections,
            GridPartition partition, IMapTemplate mapTemplate
            )
        {
            int lineXCoord = Mathf.RoundToInt(Grid.CellCountX * UnityEngine.Random.Range(
                                                  mapTemplate.ContinentSeparationLineXMin, mapTemplate.ContinentSeparationLineXMax
                                                  ));

            IHexCell startCell = Grid.GetCellAtCoordinates(HexCoordinates.FromOffsetCoordinates(lineXCoord, 0));
            IHexCell endCell   = Grid.GetCellAtCoordinates(HexCoordinates.FromOffsetCoordinates(lineXCoord, Grid.CellCountZ - 1));

            var cellLine = Grid.GetCellsInLine(startCell, endCell);

            var sectionsOnLine = cellLine.Select(cell => partition.GetSectionOfCell(cell)).Distinct();

            var sectionsToForbid = sectionsOnLine.SelectMany(section => partition.GetNeighbors(section))
                                   .Concat(sectionsOnLine).Distinct();

            foreach (var section in sectionsToForbid)
            {
                unassignedSections.Remove(section);
                forbiddenSections.Add(section);
            }
        }
        private bool TryExpandChunk(
            List <MapSection> chunk, HashSet <MapSection> unassignedSections,
            GridPartition partition, IMapTemplate mapTemplate,
            ExpansionWeightFunction weightFunction, bool mustBeContiguous
            )
        {
            expansionCandidates.Clear();

            foreach (MapSection section in chunk)
            {
                nearbySections.Clear();

                sectionsWithinDistance.Clear();

                if (mustBeContiguous)
                {
                    foreach (var adjacentSection in partition.GetNeighbors(section))
                    {
                        if (unassignedSections.Contains(adjacentSection))
                        {
                            nearbySections.Add(adjacentSection);
                        }
                    }
                }
                else
                {
                    foreach (IHexCell nearbyCell in Grid.GetCellsInRadius(section.CentroidCell, mapTemplate.HomelandExpansionMaxCentroidSeparation))
                    {
                        MapSection sectionOfCell = partition.GetSectionOfCell(nearbyCell);

                        if (unassignedSections.Contains(sectionOfCell))
                        {
                            sectionsWithinDistance.Add(sectionOfCell);
                        }
                    }

                    var sectionsSurroundedByUnassigned = sectionsWithinDistance.Where(
                        nearby => partition.GetNeighbors(nearby).Count(neighbor => !unassignedSections.Contains(neighbor)) <= 0
                        );

                    if (sectionsSurroundedByUnassigned.Any())
                    {
                        foreach (var surroundedSection in sectionsSurroundedByUnassigned)
                        {
                            nearbySections.Add(surroundedSection);
                        }
                    }
                    else
                    {
                        foreach (var sectionWithin in sectionsWithinDistance)
                        {
                            nearbySections.Add(sectionWithin);
                        }
                    }
                }

                foreach (var nearby in nearbySections)
                {
                    expansionCandidates.Add(nearby);
                }
            }

            if (expansionCandidates.Count > 0)
            {
                var newSection = MapSectionRandomSampler.SampleElementsFromSet(
                    expansionCandidates, 1, section => weightFunction(section, chunk)
                    ).FirstOrDefault();

                if (newSection != null)
                {
                    unassignedSections.Remove(newSection);
                    chunk.Add(newSection);
                    return(true);
                }
            }

            return(false);
        }
Пример #3
0
        public HomelandData GetHomelandData(
            ICivilization civ, List <MapSection> landSections, List <MapSection> waterSections,
            GridPartition partition, IHomelandTemplate homelandTemplate, IMapTemplate mapTemplate
            )
        {
            var landChunks  = new List <List <MapSection> >();
            var waterChunks = new List <List <MapSection> >();

            IHexCell seedCentroid = landSections[0].CentroidCell;

            var startingLandSections =
                Grid.GetCellsInRadius(seedCentroid, homelandTemplate.StartingRegionRadius)
                .Select(cell => partition.GetSectionOfCell(cell))
                .Distinct()
                .Intersect(landSections);

            var startingWaterSections =
                Grid.GetCellsInRadius(seedCentroid, homelandTemplate.StartingRegionRadius)
                .Select(cell => partition.GetSectionOfCell(cell))
                .Distinct()
                .Intersect(waterSections);

            var startingRegion = new MapRegion(
                startingLandSections.SelectMany(section => section.Cells).ToList(),
                startingWaterSections.SelectMany(section => section.Cells).ToList()
                );

            foreach (var cell in startingRegion.Cells)
            {
                cell.SetMapData(1f);
            }

            var unassignedLand  = landSections.Except(startingLandSections);
            var unassignedWater = waterSections.Except(startingWaterSections);

            DivideSectionsIntoRectangularChunks(
                unassignedLand, unassignedWater, homelandTemplate.RegionCount,
                out landChunks, out waterChunks
                );

            var regions = new List <MapRegion>();

            regions.Add(startingRegion);

            for (int i = 0; i < landChunks.Count; i++)
            {
                var region = new MapRegion(
                    landChunks [i].SelectMany(section => section.Cells).ToList(),
                    waterChunks[i].SelectMany(section => section.Cells).ToList()
                    );

                regions.Add(region);
            }

            var startingData = new RegionData(
                TemplateSelectionLogic.GetBiomeForLandRegion(startingRegion, mapTemplate),
                TemplateSelectionLogic.GetTopologyForLandRegion(startingRegion, mapTemplate),
                AvailableBalanceStrategies
                );

            var otherRegions = regions.Where(region => region != startingRegion).ToList();

            var otherData = otherRegions.Select(region => new RegionData(
                                                    TemplateSelectionLogic.GetBiomeForLandRegion(region, mapTemplate),
                                                    TemplateSelectionLogic.GetTopologyForLandRegion(region, mapTemplate),
                                                    AvailableBalanceStrategies
                                                    )).ToList();

            return(new HomelandData(
                       startingRegion, startingData, otherRegions, otherData,
                       homelandTemplate.LuxuryResourceData, homelandTemplate.YieldAndResources
                       ));
        }