Exemplo n.º 1
0
        public RegionData GetRegionData(MapRegion archipelagoRegion)
        {
            int regionIndex = ArchipelagoRegions.IndexOf(archipelagoRegion);

            if (regionIndex < 0)
            {
                throw new InvalidOperationException("The given region is not an archipelago region in this ocean");
            }

            return(ArchipelagoRegionData[regionIndex]);
        }
Exemplo n.º 2
0
        private void PaintArcticTerrain(
            MapRegion region, IRegionBiomeTemplate template, HashSet <IHexCell> unassignedLandCells
            )
        {
            var unassignedByPolarDistance = new List <IHexCell>(unassignedLandCells);

            unassignedByPolarDistance.Sort(PolarDistanceComparer);

            int snowCellCount   = Mathf.RoundToInt(template.SnowPercentage * region.LandCells.Count * 0.01f);
            int tundraCellCount = Mathf.RoundToInt(template.TundraPercentage * region.LandCells.Count * 0.01f);

            for (int i = 0; i < snowCellCount; i++)
            {
                if (unassignedByPolarDistance.Any())
                {
                    var candidate = unassignedByPolarDistance.Last();

                    if (ModLogic.CanChangeTerrainOfCell(candidate, CellTerrain.Snow))
                    {
                        ModLogic.ChangeTerrainOfCell(candidate, CellTerrain.Snow);
                        unassignedLandCells.Remove(candidate);
                    }

                    unassignedLandCells.Remove(candidate);
                    unassignedByPolarDistance.RemoveAt(unassignedByPolarDistance.Count - 1);
                }
                else
                {
                    break;
                }
            }

            for (int i = 0; i < tundraCellCount; i++)
            {
                if (unassignedByPolarDistance.Any())
                {
                    var candidate = unassignedByPolarDistance.Last();

                    if (ModLogic.CanChangeTerrainOfCell(candidate, CellTerrain.Tundra))
                    {
                        ModLogic.ChangeTerrainOfCell(candidate, CellTerrain.Tundra);
                        unassignedLandCells.Remove(candidate);
                    }

                    unassignedByPolarDistance.RemoveAt(unassignedByPolarDistance.Count - 1);
                }
                else
                {
                    break;
                }
            }
        }
Exemplo n.º 3
0
        public void PaintTerrain(MapRegion region, IRegionBiomeTemplate template)
        {
            var unassignedLandCells = new HashSet <IHexCell>(region.LandCells);

            PaintArcticTerrain(region, template, unassignedLandCells);
            PaintOtherTerrains(region, template, unassignedLandCells);
            AssignLandOrphans(region, template, unassignedLandCells);

            foreach (var cell in region.WaterCells)
            {
                ModLogic.ChangeTerrainOfCell(cell, CellTerrain.ShallowWater);
            }
        }
        public bool TryIncreaseScore(MapRegion region, RegionData regionData, out float scoreAdded)
        {
            YieldSummary yieldAdded;

            if (TryIncreaseYield(region, regionData, YieldType.Food, out yieldAdded))
            {
                scoreAdded = MapScorer.GetScoreOfYield(yieldAdded);
                return(true);
            }
            else
            {
                scoreAdded = 0f;
                return(false);
            }
        }
Exemplo n.º 5
0
 private Func <IResourceDefinition, int> GetResourceSelectionWeightFunction(
     MapRegion region, RegionData regionData
     )
 {
     return(delegate(IResourceDefinition resource) {
         if (region.Cells.Any(cell => ResourceRestrictionCanon.IsResourceValidOnCell(resource, cell)))
         {
             return regionData.GetWeightOfResource(resource);
         }
         else
         {
             return 0;
         }
     });
 }
Exemplo n.º 6
0
        public HomelandData(
            MapRegion startingRegion, RegionData startingData,
            List <MapRegion> otherRegions, List <RegionData> otherRegionData,
            IEnumerable <LuxuryResourceData> luxuryResources,
            IYieldAndResourcesTemplate yieldData
            )
        {
            StartingRegion = startingRegion;
            StartingData   = startingData;

            _otherRegions    = otherRegions;
            _otherRegionData = otherRegionData;

            LuxuryResources   = luxuryResources;
            YieldAndResources = yieldData;
        }
        private Func <IHexCell, int> GetOasisCandidateWeightFunction(MapRegion region)
        {
            return(delegate(IHexCell cell) {
                if (OasisCandidateFilter(cell, region))
                {
                    int nearbyOases = Grid.GetCellsInRadius(cell, 2).Where(nearby => nearby.Feature == CellFeature.Oasis).Count();
                    int nearbyNonDesert = Grid.GetCellsInRadius(cell, 2).Where(nearby => nearby.Terrain != CellTerrain.Desert).Count();

                    return Math.Max(1, 1000 - nearbyOases * NearbyOasisAvoidance - nearbyNonDesert * NearbyNonDesertAvoidance);
                }
                else
                {
                    return 0;
                }
            });
        }
        private bool OasisCandidateFilter(IHexCell cell, MapRegion region)
        {
            if (cell.Terrain == CellTerrain.Desert && ModLogic.CanChangeFeatureOfCell(cell, CellFeature.Oasis))
            {
                bool surroundedByLand = Grid.GetNeighbors(cell).All(
                    neighbor => !neighbor.Terrain.IsWater()
                    );

                bool hasResourceNode = NodePositionCanon.GetPossessionsOfOwner(cell).Any();

                return(surroundedByLand && !hasResourceNode);
            }
            else
            {
                return(false);
            }
        }
        public IRegionBiomeTemplate GetBiomeForLandRegion(MapRegion landRegion, IMapTemplate mapTemplate)
        {
            float regionTemperature   = GetRegionTemperature(landRegion);
            float regionPrecipitation = GetRegionPrecipitation(landRegion);


            var templatesByPriority = new List <IRegionBiomeTemplate>(mapTemplate.RegionBiomes);
            var templatePriority    = new Dictionary <IRegionBiomeTemplate, float>();

            foreach (var regionTemplate in templatesByPriority)
            {
                templatePriority[regionTemplate] = GetBiomePriority(regionTemplate, regionTemperature, regionPrecipitation);
            }

            templatesByPriority.Sort((a, b) => templatePriority[a].CompareTo(templatePriority[b]));

            return(templatesByPriority.First());
        }
Exemplo n.º 10
0
        public bool TryIncreaseYield(
            MapRegion region, RegionData regionData, YieldType type, out YieldSummary yieldAdded
            )
        {
            var availableResources = BonusResourcesWithYield[type].ToList();

            while (availableResources.Count > 0)
            {
                var chosenResource = ResourceRandomSampler.SampleElementsFromSet(
                    availableResources, 1, GetResourceSelectionWeightFunction(region, regionData)
                    ).FirstOrDefault();

                if (chosenResource == null)
                {
                    break;
                }

                var cell = CellRandomSampler.SampleElementsFromSet(
                    region.Cells, 1, GetCellPlacementWeightFunction(chosenResource)
                    ).FirstOrDefault();

                if (cell != null)
                {
                    var oldYield = YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs);

                    int copies = chosenResource.Type == ResourceType.Strategic
                               ? StrategicCopiesLogic.GetWeightedRandomCopies()
                               : 0;

                    ResourceNodeFactory.BuildNode(cell, chosenResource, copies);

                    yieldAdded = YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs) - oldYield;
                    return(true);
                }
                else
                {
                    availableResources.Remove(chosenResource);
                }
            }

            yieldAdded = YieldSummary.Empty;
            return(false);
        }
Exemplo n.º 11
0
        public bool TryIncreaseScore(
            MapRegion region, RegionData regionData, out float scoreAdded
            )
        {
            var candidateResources = new List <IResourceDefinition>(ScoreIncreasingCandidates);

            while (candidateResources.Any())
            {
                var chosenResource = ResourceRandomSampler.SampleElementsFromSet(
                    candidateResources, 1, GetResourceSelectionWeightFunction(region, regionData)
                    ).FirstOrDefault();

                if (chosenResource == null)
                {
                    break;
                }

                var cell = CellRandomSampler.SampleElementsFromSet(
                    region.Cells, 1, GetCellPlacementWeightFunction(chosenResource)
                    ).FirstOrDefault();

                if (cell != null)
                {
                    float oldScore = CellScorer.GetScoreOfCell(cell);

                    int copies = chosenResource.Type == ResourceType.Strategic
                               ? StrategicCopiesLogic.GetWeightedRandomCopies()
                               : 0;

                    ResourceNodeFactory.BuildNode(cell, chosenResource, copies);

                    scoreAdded = CellScorer.GetScoreOfCell(cell) - oldScore;
                    return(true);
                }
                else
                {
                    candidateResources.Remove(chosenResource);
                }
            }

            scoreAdded = 0f;
            return(false);
        }
Exemplo n.º 12
0
        public RegionData GetDataOfRegion(MapRegion region)
        {
            if (region == StartingRegion)
            {
                return(StartingData);
            }
            else
            {
                int index = OtherRegions.IndexOf(region);

                if (index >= 0)
                {
                    return(OtherRegionData[index]);
                }
                else
                {
                    throw new InvalidOperationException("No data exists for the argued region");
                }
            }
        }
Exemplo n.º 13
0
        public bool TryDecreaseScore(MapRegion region, RegionData regionData, out float scoreRemoved)
        {
            var removeJungleCandidates = region.Cells.Where(DecreaseScoreFilter);

            if (removeJungleCandidates.Any())
            {
                var oldJungle = removeJungleCandidates.Random();

                var oldScore = CellScorer.GetScoreOfCell(oldJungle);

                ModLogic.ChangeVegetationOfCell(oldJungle, CellVegetation.None);

                scoreRemoved = oldScore - CellScorer.GetScoreOfCell(oldJungle);
                return(true);
            }
            else
            {
                scoreRemoved = 0f;
                return(false);
            }
        }
Exemplo n.º 14
0
        public bool TryIncreaseScore(MapRegion region, RegionData regionData, out float scoreAdded)
        {
            var addJungleCandidates = region.Cells.Where(IncreaseScoreFilter);

            if (addJungleCandidates.Any())
            {
                var newJungle = addJungleCandidates.Random();

                var oldScore = CellScorer.GetScoreOfCell(newJungle);

                ModLogic.ChangeVegetationOfCell(newJungle, CellVegetation.Jungle);

                scoreAdded = CellScorer.GetScoreOfCell(newJungle) - oldScore;
                return(true);
            }
            else
            {
                scoreAdded = 0f;
                return(false);
            }
        }
Exemplo n.º 15
0
        public void PlaceStartingUnitsInRegion(
            MapRegion region, ICivilization owner, IMapTemplate mapTemplate
            )
        {
            if (owner.Template.IsBarbaric)
            {
                return;
            }

            var centralLocation = GetBestStartingCell(region);

            if (centralLocation == null)
            {
                throw new InvalidOperationException("Failed to find an appropriate central location");
            }

            UnitFactory.BuildUnit(centralLocation, mapTemplate.StartingUnits[0], owner);

            for (int i = 1; i < mapTemplate.StartingUnits.Count; i++)
            {
                var unitTemplate = mapTemplate.StartingUnits[i];

                var location = Grid.GetCellsInRadius(centralLocation, 2).Where(
                    cell => !UnitPositionCanon.GetPossessionsOfOwner(cell).Any() &&
                    UnitFactory.CanBuildUnit(cell, unitTemplate, owner) &&
                    cell != null
                    ).FirstOrDefault();

                if (location == null)
                {
                    throw new InvalidOperationException(
                              string.Format("Failed to place starting unit {0} for civ {1}", unitTemplate, owner)
                              );
                }
                else
                {
                    UnitFactory.BuildUnit(location, unitTemplate, owner);
                }
            }
        }
Exemplo n.º 16
0
        private void CarveArchipelagoesFromOcean(
            IEnumerable <MapSection> shallowOceanSections, List <MapSection> midOceanSections,
            IEnumerable <MapSection> deepOceanSections, IOceanTemplate oceanTemplate, GridPartition partition,
            IMapTemplate mapTemplate, out List <MapRegion> emptyOceanRegions,
            out List <MapRegion> archipelagoRegions, out List <RegionData> archipelagoRegionData
            )
        {
            int landSectionCount = Mathf.RoundToInt(oceanTemplate.DeepOceanLandPercentage * 0.01f * deepOceanSections.Count());

            var deepOceanLand = MapSectionRandomSampler.SampleElementsFromSet(
                deepOceanSections, landSectionCount, GetArchipelagoWeightFunction(mapTemplate)
                ).ToList();

            var deepOceanWater = deepOceanSections.Except(deepOceanLand).ToList();

            List <MapSection> emptyDeepOcean;

            GetArchipelagoesFromLandAndWater(
                deepOceanLand, deepOceanWater, midOceanSections, oceanTemplate,
                partition, out archipelagoRegions, out emptyDeepOcean
                );

            var emptyOceanCells = shallowOceanSections.Concat(midOceanSections).Concat(emptyDeepOcean);

            var emptyOcean = new MapRegion(
                new List <IHexCell>(),
                emptyOceanCells.SelectMany(section => section.Cells).ToList()
                );

            emptyOceanRegions = new List <MapRegion>()
            {
                emptyOcean
            };

            archipelagoRegionData = archipelagoRegions.Select(region => new RegionData(
                                                                  TemplateSelectionLogic.GetBiomeForLandRegion(region, mapTemplate),
                                                                  TemplateSelectionLogic.GetTopologyForLandRegion(region, mapTemplate),
                                                                  AvailableBalanceStrategies
                                                                  )).ToList();
        }
Exemplo n.º 17
0
        public bool TryIncreaseYield(
            MapRegion region, RegionData regionData, YieldType type, out YieldSummary yieldAdded
            )
        {
            if (type != YieldType.Food)
            {
                yieldAdded = YieldSummary.Empty;
                return(false);
            }

            var candidates = region.Cells.Where(GetLakeCandidateFilter(region));

            if (candidates.Any())
            {
                var newLake = candidates.Random();

                var oldYields = new Dictionary <IHexCell, YieldSummary>();

                foreach (var cell in Grid.GetCellsInRadius(newLake, 1))
                {
                    oldYields[cell] = YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs);
                }

                ModLogic.ChangeTerrainOfCell(newLake, CellTerrain.FreshWater);

                yieldAdded = YieldSummary.Empty;
                foreach (var cell in oldYields.Keys)
                {
                    yieldAdded += YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs) - oldYields[cell];
                }

                return(true);
            }
            else
            {
                yieldAdded = YieldSummary.Empty;
                return(false);
            }
        }
Exemplo n.º 18
0
        private bool TryDistributeLuxuryAcrossSingleAndMultipleRegions(
            MapRegion singleRegion, IEnumerable <MapRegion> multipleRegions, int singleNodeCount,
            int multipleNodeCount, List <IResourceDefinition> validLuxuries,
            Dictionary <IResourceDefinition, int> weightForResources,
            HashSet <IResourceDefinition> luxuriesAlreadyChosen
            )
        {
            while (validLuxuries.Any())
            {
                var candidate = ResourceRandomSampler.SampleElementsFromSet(
                    validLuxuries, 1, luxury => weightForResources[luxury]
                    ).FirstOrDefault();
                validLuxuries.Remove(candidate);

                if (luxuriesAlreadyChosen.Contains(candidate))
                {
                    continue;
                }

                var validSingleCells = singleRegion.Cells.Where(
                    cell => ResourceRestrictionCanon.IsResourceValidOnCell(candidate, cell)
                    );

                var validMultipleCells = multipleRegions.SelectMany(region => region.Cells).Where(
                    cell => ResourceRestrictionCanon.IsResourceValidOnCell(candidate, cell)
                    );

                if (validSingleCells.Count() >= singleNodeCount && validMultipleCells.Count() >= multipleNodeCount)
                {
                    DistributeResource(candidate, validSingleCells, singleNodeCount);
                    DistributeResource(candidate, validMultipleCells, multipleNodeCount);
                    luxuriesAlreadyChosen.Add(candidate);
                    return(true);
                }
            }

            return(false);
        }
Exemplo n.º 19
0
        private void PaintOtherTerrains(
            MapRegion region, IRegionBiomeTemplate template, HashSet <IHexCell> unassignedLandCells
            )
        {
            var terrainsToPaint = new List <CellTerrain>()
            {
                CellTerrain.Grassland, CellTerrain.Plains, CellTerrain.Desert
            };

            var percentageOfTerrains = new Dictionary <CellTerrain, int>()
            {
                { CellTerrain.Grassland, template.GrasslandPercentage },
                { CellTerrain.Plains, template.PlainsPercentage },
                { CellTerrain.Desert, template.DesertPercentage },
            };

            int landToPaintCount = unassignedLandCells.Count;

            foreach (var terrain in terrainsToPaint)
            {
                var weightFunction = GetWeightFunction(terrain);

                int terrainCount = Mathf.RoundToInt(percentageOfTerrains[terrain] * 0.01f * landToPaintCount);
                terrainCount = Math.Min(terrainCount, unassignedLandCells.Count);

                var changeCandidatesDescending = new List <IHexCell>(unassignedLandCells);

                changeCandidatesDescending.Sort((first, second) => weightFunction(second).CompareTo(weightFunction(first)));

                for (int i = 0; i < terrainCount; i++)
                {
                    var cellToChange = changeCandidatesDescending[i];

                    ModLogic.ChangeTerrainOfCell(cellToChange, terrain);
                    unassignedLandCells.Remove(cellToChange);
                }
            }
        }
        public bool TryDecreaseScore(MapRegion region, RegionData regionData, out float scoreRemoved)
        {
            var allCandidates = region.LandCells.Where(CandidateFilter).ToList();

            allCandidates.Sort(CandidateComparer);

            var bestCandidate = allCandidates.FirstOrDefault();

            if (bestCandidate != null)
            {
                var oldScore = CellScorer.GetScoreOfCell(bestCandidate);

                ModLogic.ChangeShapeOfCell(bestCandidate, CellShape.Mountains);

                scoreRemoved = oldScore - CellScorer.GetScoreOfCell(bestCandidate);
                return(true);
            }
            else
            {
                scoreRemoved = 0f;
                return(false);
            }
        }
        public bool TryIncreaseYield(
            MapRegion region, RegionData regionData, YieldType type, out YieldSummary yieldAdded
            )
        {
            yieldAdded = YieldSummary.Empty;
            if (type != YieldType.Food && type != YieldType.Gold)
            {
                return(false);
            }

            var newOasis = CellRandomSampler.SampleElementsFromSet(
                region.LandCells, 1, GetOasisCandidateWeightFunction(region)
                ).FirstOrDefault();

            if (newOasis == null)
            {
                return(false);
            }

            var oldYields = new Dictionary <IHexCell, YieldSummary>();

            foreach (var cell in Grid.GetCellsInRadius(newOasis, 1))
            {
                oldYields[cell] = YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs);
            }

            ModLogic.ChangeFeatureOfCell(newOasis, CellFeature.Oasis);

            yieldAdded = YieldSummary.Empty;
            foreach (var cell in oldYields.Keys)
            {
                yieldAdded += YieldEstimator.GetYieldEstimateForCell(cell, TechCanon.AvailableTechs) - oldYields[cell];
            }

            return(true);
        }
Exemplo n.º 22
0
        private Comparison <IHexCell> GetScoreComparisonFunction(MapRegion region)
        {
            var cellScores   = new Dictionary <IHexCell, float>();
            var cellsInRange = new Dictionary <IHexCell, IHexCell[]>();

            foreach (var cell in region.Cells)
            {
                cellScores[cell] = CellScorer.GetScoreOfCell(cell);

                cellsInRange[cell] = Grid.GetCellsInRadius(cell, CityConfig.MaxBorderRange)
                                     .Where(nearby => region.Cells.Contains(nearby))
                                     .ToArray();
            }

            var cityPlacementScore = new Dictionary <IHexCell, float>();

            return(delegate(IHexCell cellOne, IHexCell cellTwo) {
                float cellOneScore, cellTwoScore;

                if (!cityPlacementScore.TryGetValue(cellOne, out cellOneScore))
                {
                    cellOneScore = cellsInRange[cellOne].Select(neighbor => cellScores[neighbor]).Sum();

                    cityPlacementScore[cellOne] = cellOneScore;
                }

                if (!cityPlacementScore.TryGetValue(cellTwo, out cellTwoScore))
                {
                    cellTwoScore = cellsInRange[cellTwo].Select(neighbor => cellScores[neighbor]).Sum();

                    cityPlacementScore[cellTwo] = cellTwoScore;
                }

                return cellTwoScore.CompareTo(cellOneScore);
            });
        }
 public bool TryIncreaseScore(MapRegion region, RegionData regionData, out float scoreAdded)
 {
     scoreAdded = 0f;
     return(false);
 }
 public bool TryIncreaseYield(MapRegion region, RegionData regionData, YieldType type, out YieldSummary yieldAdded)
 {
     yieldAdded = YieldSummary.Empty;
     return(false);
 }
 private float GetRegionTemperature(MapRegion region)
 {
     return(region.LandCells.Sum(cell => CellClimateLogic.GetTemperatureOfCell(cell)) / region.LandCells.Count);
 }
 private float GetRegionPrecipitation(MapRegion region)
 {
     return(region.LandCells.Sum(cell => CellClimateLogic.GetPrecipitationOfCell(cell)) / region.LandCells.Count);
 }
 public bool TryDecreaseScore(MapRegion region, RegionData regionData, out float scoreRemoved)
 {
     scoreRemoved = 0;
     return(false);
 }
Exemplo n.º 28
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
                       ));
        }
Exemplo n.º 29
0
        private float GetScorePerCell(MapRegion region)
        {
            var cellsByScore = region.Cells.Select(cell => CellScorer.GetScoreOfCell(cell));

            return(cellsByScore.Aggregate((current, next) => current + next) / region.Cells.Count);
        }
 public IRegionTopologyTemplate GetTopologyForLandRegion(MapRegion region, IMapTemplate mapTemplate)
 {
     return(mapTemplate.RegionTopologies.Random());
 }