/// <summary> /// Return a list of tuples (IAgent, float), where float is the period in seconds at which the agent should be executed. /// </summary> public World Create() { Contract.Requires(this.Size.X > 0, "size.X must be positive"); Contract.Requires(this.Size.Y > 0, "size.Y must be positive"); WorldRules rules = this.WorldRulesFactory.Create(this.Random); var terrainMap = this.TerrainGenerator.GenerateTerrainMap(rules, this.Size); var zoneMap = new ArrayMap <int>(this.Size, rules.Zones[Zones.Empty]); var buildingMap = new ArrayMap <int>(this.Size, MapTypes.NoBuilding); Maps maps = new Maps(this.Size); terrainMap.RegisterTerrain(maps); zoneMap.RegisterZone(maps); buildingMap.RegisterBuilding(maps); var buildings = new AnonymousEntities(MapTypes.Building); foreach (var buildingComponents in rules.BuildingComponents.Values) { buildings.Extend(buildingComponents); } return(new World(maps, buildings, rules, new Ticker(), new RoadGraph(zoneMap, rules.Zones[Zones.Road]))); }
public static void RegisterBuilidingModelResourceProductionComponent(WorldRules worldRules) { Contract.Requires(worldRules != null); var buildingResourceProduction = new TypedComponents <BuildingResourceProduction[]>( BuildingModelResourceProductionComponent, () => System.Array.Empty <BuildingResourceProduction>()); var buildingModelsInitializer = new BuildingModelsInitializer(worldRules.BuildingModels, buildingResourceProduction); var resources = worldRules.Resources; int maxDistance = 16; buildingModelsInitializer.Set( Farm, new BuildingResourceProduction(resources[Resources.Food], 1, maxDistance), new BuildingResourceProduction(resources[Resources.Population], -1, maxDistance)); buildingModelsInitializer.Set( House, new BuildingResourceProduction(resources[Resources.Food], -2, maxDistance), new BuildingResourceProduction(resources[Resources.Population], 4, maxDistance)); buildingModelsInitializer.Set( ConvenienceStore, new BuildingResourceProduction(resources[Resources.Food], -5, maxDistance), new BuildingResourceProduction(resources[Resources.Population], -4, maxDistance)); worldRules.BuildingModels.Extend(buildingResourceProduction); }
public static void RegisterBuildingComponent(WorldRules worldRules) { Contract.Requires(worldRules != null); TypedComponents <int> typedComponents = new TypedComponents <int>(Component, worldRules.Random.Next); worldRules.BuildingComponents.Add(typedComponents.Name, typedComponents); }
public World(Maps maps, AnonymousEntities buildings, WorldRules rules, Ticker ticker, IGraph <Vector> transportGraph) { this.maps = maps; this.Buildings = buildings; this.Rules = rules; this.ticker = ticker; this.transportGraph = transportGraph; }
public static void RegisterDefaults(WorldRules worldRules) { Contract.Requires(worldRules != null); worldRules.ToolBrushes[Pen.Name] = Pen; worldRules.ToolBrushes[Manatthan.Name] = Manatthan; worldRules.ToolBrushes[Rectangle.Name] = Rectangle; }
/// <summary> /// The transport link of each building. /// The transport link is the position on the map where all path finding related to the building starts and ends. /// </summary> public static void RegisterBuildingTransportLink(WorldRules worldRules) { Contract.Requires(worldRules != null); var connectionsComponent = new TypedComponents <Vector?>(TransportLinkComponent, () => null); worldRules.BuildingComponents.Add(connectionsComponent.Name, connectionsComponent); }
/// <summary> /// The connections of each building. /// The connection refers to a building id. /// Connections are bi-directional, in other words, if a building A has a connection to a building B, then building B must have a connection to building A. /// Building connections are used to satisfy the building supply chain. /// For example, a building with a model "house" consuming "food" will need to be connected to a building with a model producing "food" such as a "farm". /// There can be multiple connections for the same resource, until the constraint is satisfied, considering that resource productions have associated quantities. /// </summary> public static void RegisterBuildingConnections(WorldRules worldRules) { Contract.Requires(worldRules != null); var connectionsComponent = new TypedComponents <ISet <int> >(ConnectionsComponent, () => new HashSet <int>()); worldRules.BuildingComponents.Add(connectionsComponent.Name, connectionsComponent); }
/// <summary> /// The building model of each building, such a house, or a shop. /// Much of the building attributes are defined in the model. /// This is an implementation of the flywheel design pattern. /// </summary> public static void RegisterBuildingModelComponent(WorldRules worldRules) { Contract.Requires(worldRules != null); var buildingModelComponent = new TypedComponents <int>(BuildingModelComponent, () => BuildingModels.NoModel); worldRules.BuildingComponents.Add(buildingModelComponent.Name, buildingModelComponent); }
/// <summary> /// The location of each building. /// </summary> public static void RegisterBuildingLocation(WorldRules worldRules) { Contract.Requires(worldRules != null); var connectionsComponent = new TypedComponents <Vector>(LocationComponent, () => new Vector(-1, -1)); worldRules.BuildingComponents.Add(connectionsComponent.Name, connectionsComponent); }
public static void RegisterDefaults(WorldRules worldRules) { Contract.Requires(worldRules != null); NamedEntities resources = worldRules.Resources; resources.Register(Population); resources.Register(Food); }
public static void RegisterDefaults(WorldRules worldRules) { Contract.Requires(worldRules != null); NamedEntities terrains = worldRules.Terrains; terrains.Register(Land); terrains.Register(Water); }
public static void RegisterDefaults(WorldRules worldRules) { Contract.Requires(worldRules != null); NamedEntities buildingModels = worldRules.BuildingModels; buildingModels.Register(Farm); buildingModels.Register(House); buildingModels.Register(ConvenienceStore); }
/// <summary> /// A zone component to define legal terrains corresponding to each zone. By default, the only legal terrain is Land. /// </summary> public static void RegisterZonableTerrainsComponent(WorldRules worldRules) { Contract.Requires(worldRules != null); var zones = worldRules.Zones; var terrains = worldRules.Terrains; ZonableOnlyOn zonableOnlyOnLand = new ZonableOnlyOn(terrains[Terrains.Land]); TypedComponents <IZonableTerrain> zonableTerrains = new TypedComponents <IZonableTerrain>(ZonableTerrains, () => zonableOnlyOnLand); zonableTerrains[zones[Zones.Empty]] = new AlwaysZonable(); zones.Extend(zonableTerrains); }
public static void RegisterManuallyZonableComponent(WorldRules worldRules) { Contract.Requires(worldRules != null); NamedEntities zones = worldRules.Zones; var manuallyZonable = new TypedComponents <bool>(ManuallyZonable, () => false); manuallyZonable[zones[Zones.Commercial]] = true; manuallyZonable[zones[Zones.Farmland]] = true; manuallyZonable[zones[Zones.Residential]] = true; manuallyZonable[zones[Zones.Road]] = true; zones.Extend(manuallyZonable); }
public static void RegisterDefaults(WorldRules worldRules) { Contract.Requires(worldRules != null); NamedEntities zones = worldRules.Zones; zones.Register(Empty); zones.Register(Commercial); zones.Register(Farmland); zones.Register(Residential); zones.Register(Road); }
public WorldRules Create(Random random) { Contract.Requires(this.ConfigProvider != null); Contract.Requires(this.WorldRulesCustomizer != null); WorldRules wr = new WorldRules(random) { ConfigProvider = this.ConfigProvider, }; this.WorldRulesCustomizer(wr); return(wr); }
public static void RegisterBuildingModelZoneComponent(WorldRules worldRules) { Contract.Requires(worldRules != null); var buildingModelZoneComponent = new TypedComponents <int>(BuildingModelZoneComponent, () => - 1); var buildingModels = worldRules.BuildingModels; var zones = worldRules.Zones; buildingModelZoneComponent[buildingModels[Farm]] = zones[Zones.Farmland]; buildingModelZoneComponent[buildingModels[House]] = zones[Zones.Residential]; buildingModelZoneComponent[buildingModels[ConvenienceStore]] = zones[Zones.Commercial]; worldRules.BuildingModels.Extend(buildingModelZoneComponent); }
/// <summary> /// The default building model for each zone. This is used as estimate when computing how empty zones will develop. /// </summary> public static void RegisterZonesDefaultBuildingModel(WorldRules worldRules) { Contract.Requires(worldRules != null); var zones = worldRules.Zones; var buildingModels = worldRules.BuildingModels; TypedComponents <int> defaultBuildingModels = new TypedComponents <int>(DefaultBuildingModel, () => BuildingModels.NoModel); defaultBuildingModels[zones[Zones.Farmland]] = buildingModels[BuildingModels.Farm]; defaultBuildingModels[zones[Zones.Residential]] = buildingModels[BuildingModels.House]; defaultBuildingModels[zones[Zones.Commercial]] = buildingModels[BuildingModels.ConvenienceStore]; zones.Extend(defaultBuildingModels); }
public static void RegisterDefaults(WorldRules worldRules) { Contract.Requires(worldRules != null); var zones = worldRules.Zones; worldRules.ToolBehaviors[Zoner] = zoneName => { var zone = zones.GetNamedEntity(zoneName); if (!zones.GetTypedComponents <bool>(Zones.ManuallyZonable).IsMarked(zone.Id)) { throw new ArgumentException(zone.Name); } return(new Zoner(zone)); }; }
public static void ConfigureBuildingConstructorAgent(WorldRules worldRules) { Contract.Requires(worldRules != null); EmptyLocationVoter emptyLocation = EmptyLocationVoter.GetInstance(); StochasticVoter stochastic = new StochasticVoter(worldRules.Random); worldRules.ConfigProvider.RegisterConfigUpdateListener <double>("tiledev.rate", rate => { Contract.Requires(rate >= 0.0 && rate <= 1.0); stochastic.DevelopmentRate = rate; }); var buildingTransportLinkFinder = new BuildingTransportLinkFinder(); worldRules.OnNewWorldListener += buildingTransportLinkFinder.OnNewWorld; worldRules.ConfigProvider.RegisterConfigUpdateListener <int>("transport_location.max_distance", maxDistance => { Contract.Requires(maxDistance > 0); buildingTransportLinkFinder.MaxDistance = maxDistance; }); var buildingConnectionFinder = new BuildingConnectionFinder(CreatePathFinder(), new RandomResourceProvider(buildingTransportLinkFinder)); worldRules.OnNewWorldListener += buildingConnectionFinder.OnNewWorld; var buildingResource = new BuildingResourceVoter(buildingConnectionFinder, buildingTransportLinkFinder); CombinedBuildingDevelopmentVoter combinedTileDevelopmentVoter = new CombinedBuildingDevelopmentVoter(emptyLocation, stochastic, buildingResource); BuildingConstructorVoter buildingConstructionVoter = new BuildingConstructorVoter(combinedTileDevelopmentVoter, new ZoneBuildingModels()); worldRules.OnNewWorldListener += w => buildingConstructionVoter.OnNewWorld(w); var zoneDeveloper = new BuildingConstructor(buildingConstructionVoter); worldRules.Agents[zoneDeveloper.Name] = new ScheduledAgent(zoneDeveloper, 1.0f); }