private ExpansionWeightFunction GetExpansionWeightFunction(
            GridPartition partition, IMapTemplate template
            )
        {
            var middleCell = Grid.GetCellAtOffset(Grid.CellCountX / 2, Grid.CellCountZ / 2);

            return(delegate(MapSection section, List <MapSection> chunk) {
                if (IsWithinHardBorder(section.CentroidCell, template))
                {
                    return 0;
                }

                int borderAvoidanceWeight = GetBorderAvoidanceWeight(section.CentroidCell, template);

                int neighborsInContinent = partition.GetNeighbors(section).Intersect(chunk).Count();
                int neighborsInContinentWeight = neighborsInContinent * template.NeighborsInContinentWeight;

                int distanceFromSeedCentroid = Grid.GetDistance(chunk[0].CentroidCell, section.CentroidCell);
                int distanceFromSeedCentroidWeight = distanceFromSeedCentroid * template.DistanceFromSeedCentroidWeight;

                int distanceFromMapCenter = Grid.GetDistance(section.CentroidCell, middleCell) * template.DistanceFromMapCenterWeight;

                int weight = 1 + Math.Max(
                    0, neighborsInContinentWeight + distanceFromSeedCentroidWeight + borderAvoidanceWeight + distanceFromMapCenter
                    );

                return weight;
            });
        }
示例#2
0
        public int GetDistanceToCell(IHexCell cell)
        {
            int shorestDistance = int.MaxValue;

            foreach (var cellInRegion in cells)
            {
                shorestDistance = Math.Min(Grid.GetDistance(cell, cellInRegion), shorestDistance);
            }

            return(shorestDistance);
        }
示例#3
0
        public bool IsCellValidForCity(IHexCell cell)
        {
            if (CellPossessionCanon.GetOwnerOfPossession(cell) != null)
            {
                return(false);
            }

            if (cell.Terrain.IsWater())
            {
                return(false);
            }

            if (cell.Feature != CellFeature.None)
            {
                return(false);
            }

            foreach (var city in CityFactory.AllCities)
            {
                var cityLocation = CityLocationCanon.GetOwnerOfPossession(city);

                if (HexGrid.GetDistance(cell, cityLocation) < Config.MinimumSeparation)
                {
                    return(false);
                }
            }

            return(true);
        }
        public Func <IHexCell, int> GetWanderWeightFunction(IUnit unit, InfluenceMaps maps)
        {
            var unitLocation = UnitPositionCanon.GetOwnerOfPossession(unit);

            return(delegate(IHexCell cell) {
                if (cell == unitLocation || !UnitPositionCanon.CanPlaceUnitAtLocation(unit, cell, false))
                {
                    return 0;
                }
                else
                {
                    float fromDistance = Grid.GetDistance(cell, unitLocation) * BarbarianConfig.WanderSelectionWeight_Distance;
                    float fromAllies = -maps.AllyPresence [cell.Index] * BarbarianConfig.WanderSelectionWeight_Allies;
                    float fromEnemies = -maps.EnemyPresence[cell.Index] * BarbarianConfig.WanderSelectionWeight_Enemies;

                    return Math.Max(0, Mathf.RoundToInt(fromDistance + fromAllies + fromEnemies));
                }
            });
        }
示例#5
0
        public Func <IHexCell, float> GetPillageUtilityFunction(IUnit unit, InfluenceMaps maps)
        {
            var unitLocation = UnitPositionCanon.GetOwnerOfPossession(unit);

            return(delegate(IHexCell cell) {
                float divisor = Grid.GetDistance(unitLocation, cell) + 1;

                return Mathf.Clamp01(maps.PillagingValue[cell.Index] * BarbarianConfig.PillageUtilityCoefficient / divisor);
            });
        }
示例#6
0
 private Func <IHexCell, bool> GetRiverEndpointFilter(
     IEnumerable <IHexCell> waterCells, IHexCell start, int maxRiverLength
     )
 {
     return(delegate(IHexCell cell) {
         return cell != start &&
         !IsWater(cell, waterCells) &&
         !RiverCanon.HasRiver(cell) &&
         Grid.GetDistance(cell, start) <= maxRiverLength;
     });
 }
        /// <inheritdoc/>
        public bool IsCellAvailable(ICity city, IHexCell cell)
        {
            if (city == null)
            {
                throw new ArgumentNullException("city");
            }
            else if (cell == null)
            {
                throw new ArgumentNullException("cell");
            }

            var cityLocation = CityLocationCanon.GetOwnerOfPossession(city);

            bool isUnowned              = PossessionCanon.GetOwnerOfPossession(cell) == null;
            bool isWithinRange          = HexGrid.GetDistance(cityLocation, cell) <= Config.MaxBorderRange;
            bool isNeighborOfPossession = HexGrid.GetNeighbors(cell).Exists(neighbor => PossessionCanon.GetOwnerOfPossession(neighbor) == city);

            return(isUnowned && isWithinRange && isNeighborOfPossession);
        }
示例#8
0
        private ICity GetNearestDomesticCity(IHexCell location, ICivilization domesticCiv)
        {
            int   shortestDistance = int.MaxValue;
            ICity nearestCity      = null;

            foreach (var domesticCity in CityPossessionCanon.GetPossessionsOfOwner(domesticCiv))
            {
                var cityLocation = CityLocationCanon.GetOwnerOfPossession(domesticCity);

                int distanceTo = Grid.GetDistance(location, cityLocation);

                if (distanceTo < shortestDistance)
                {
                    nearestCity      = domesticCity;
                    shortestDistance = distanceTo;
                }
            }

            return(nearestCity);
        }
        private CrawlingWeightFunction GetTreeCrawlingCostFunction(
            CellVegetation treeType, IRegionBiomeTemplate template
            )
        {
            return(delegate(IHexCell cell, IHexCell seed, IEnumerable <IHexCell> acceptedCells) {
                if (cell.Vegetation == CellVegetation.Marsh || cell.Feature != CellFeature.None ||
                    !ModLogic.CanChangeVegetationOfCell(cell, treeType)
                    )
                {
                    return -1;
                }
                else
                {
                    int terrainCost = template.GetTreePlacementCostForTerrain(cell.Terrain);
                    int shapeCost = template.GetTreePlacementCostForShape(cell.Shape);
                    int distanceCost = Grid.GetDistance(seed, cell);

                    return terrainCost + shapeCost + distanceCost;
                }
            });
        }
        private MapSection GetStartingSection(
            HashSet <MapSection> unassignedSections, IEnumerable <MapSection> startingSections,
            int minSeparation, IMapTemplate mapTemplate
            )
        {
            var candidates = new List <MapSection>();

            foreach (var unassignedSection in unassignedSections)
            {
                if (unassignedSection.Cells.Count == 0 || IsWithinSoftBorder(unassignedSection.CentroidCell, mapTemplate))
                {
                    continue;
                }

                bool unassignedIsValid = true;
                foreach (var startingSection in startingSections)
                {
                    if (Grid.GetDistance(unassignedSection.CentroidCell, startingSection.CentroidCell) < minSeparation)
                    {
                        unassignedIsValid = false;
                        break;
                    }
                }

                if (unassignedIsValid)
                {
                    candidates.Add(unassignedSection);
                }
            }

            if (candidates.Count == 0)
            {
                throw new InvalidOperationException("Failed to acquire a valid starting location");
            }
            else
            {
                return(candidates.Random());
            }
        }