cogames 0.3.59.post1.dev2__py3-none-any.whl → 0.3.65__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cogames/cli/client.py +12 -0
- cogames/cli/leaderboard.py +40 -0
- cogames/cli/mission.py +31 -34
- cogames/cli/submit.py +1 -1
- cogames/cogs_vs_clips/clips.py +86 -0
- cogames/cogs_vs_clips/cog.py +14 -7
- cogames/cogs_vs_clips/cogsguard_tutorial.py +10 -11
- cogames/cogs_vs_clips/config.py +38 -0
- cogames/cogs_vs_clips/{cogs_vs_clips_mapgen.md → docs/cogs_vs_clips_mapgen.md} +6 -7
- cogames/cogs_vs_clips/evals/README.md +4 -4
- cogames/cogs_vs_clips/evals/cogsguard_evals.py +96 -0
- cogames/cogs_vs_clips/evals/diagnostic_evals.py +13 -100
- cogames/cogs_vs_clips/evals/difficulty_variants.py +9 -18
- cogames/cogs_vs_clips/evals/integrated_evals.py +8 -60
- cogames/cogs_vs_clips/evals/spanning_evals.py +48 -54
- cogames/cogs_vs_clips/mission.py +65 -277
- cogames/cogs_vs_clips/missions.py +16 -24
- cogames/cogs_vs_clips/sites.py +35 -25
- cogames/cogs_vs_clips/stations.py +33 -82
- cogames/cogs_vs_clips/team.py +44 -0
- cogames/cogs_vs_clips/{procedural.py → terrain.py} +12 -6
- cogames/cogs_vs_clips/variants.py +41 -118
- cogames/core.py +87 -0
- cogames/main.py +5 -1
- cogames/maps/evals/eval_balanced_spread.map +7 -3
- cogames/maps/evals/eval_clip_oxygen.map +7 -3
- cogames/maps/evals/eval_collect_resources.map +7 -3
- cogames/maps/evals/eval_collect_resources_hard.map +7 -3
- cogames/maps/evals/eval_collect_resources_medium.map +7 -3
- cogames/maps/evals/eval_divide_and_conquer.map +7 -3
- cogames/maps/evals/eval_energy_starved.map +7 -3
- cogames/maps/evals/eval_multi_coordinated_collect_hard.map +7 -3
- cogames/maps/evals/eval_oxygen_bottleneck.map +7 -3
- cogames/maps/evals/eval_single_use_world.map +7 -3
- cogames/maps/evals/extractor_hub_100x100.map +7 -3
- cogames/maps/evals/extractor_hub_30x30.map +7 -3
- cogames/maps/evals/extractor_hub_50x50.map +7 -3
- cogames/maps/evals/extractor_hub_70x70.map +7 -3
- cogames/maps/evals/extractor_hub_80x80.map +7 -3
- cogames/verbose.py +2 -2
- {cogames-0.3.59.post1.dev2.dist-info → cogames-0.3.65.dist-info}/METADATA +19 -3
- {cogames-0.3.59.post1.dev2.dist-info → cogames-0.3.65.dist-info}/RECORD +46 -44
- cogames/cogs_vs_clips/cogsguard_reward_variants.py +0 -138
- cogames/cogs_vs_clips/mission_utils.py +0 -19
- cogames/cogs_vs_clips/tutorial_missions.py +0 -25
- {cogames-0.3.59.post1.dev2.dist-info → cogames-0.3.65.dist-info}/WHEEL +0 -0
- {cogames-0.3.59.post1.dev2.dist-info → cogames-0.3.65.dist-info}/entry_points.txt +0 -0
- {cogames-0.3.59.post1.dev2.dist-info → cogames-0.3.65.dist-info}/licenses/LICENSE +0 -0
- {cogames-0.3.59.post1.dev2.dist-info → cogames-0.3.65.dist-info}/top_level.txt +0 -0
|
@@ -1,95 +1,74 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, override
|
|
2
4
|
|
|
3
5
|
from cogames.cogs_vs_clips.evals.difficulty_variants import DIFFICULTY_VARIANTS
|
|
4
|
-
from cogames.cogs_vs_clips.
|
|
5
|
-
from cogames.
|
|
6
|
-
from mettagrid.config.action_config import VibeTransfer
|
|
7
|
-
from mettagrid.config.game_value import stat
|
|
8
|
-
from mettagrid.config.reward_config import reward
|
|
6
|
+
from cogames.cogs_vs_clips.terrain import BaseHubVariant, MachinaArenaVariant
|
|
7
|
+
from cogames.core import CoGameMissionVariant
|
|
9
8
|
from mettagrid.map_builder.map_builder import MapBuilderConfig
|
|
10
9
|
from mettagrid.mapgen.mapgen import MapGen
|
|
11
10
|
from mettagrid.mapgen.scenes.base_hub import DEFAULT_EXTRACTORS as HUB_EXTRACTORS
|
|
12
11
|
from mettagrid.mapgen.scenes.building_distributions import DistributionConfig, DistributionType
|
|
13
12
|
|
|
13
|
+
if TYPE_CHECKING:
|
|
14
|
+
from cogames.cogs_vs_clips.mission import CvCMission
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class NumCogsVariant(CoGameMissionVariant):
|
|
18
|
+
name: str = "num_cogs"
|
|
19
|
+
description: str = "Set the number of cogs for the mission."
|
|
20
|
+
num_cogs: int
|
|
14
21
|
|
|
15
|
-
|
|
22
|
+
@override
|
|
23
|
+
def modify_mission(self, mission: CvCMission) -> None:
|
|
24
|
+
if self.num_cogs < mission.site.min_cogs or self.num_cogs > mission.site.max_cogs:
|
|
25
|
+
raise ValueError(
|
|
26
|
+
f"Invalid number of cogs for {mission.site.name}: {self.num_cogs}. "
|
|
27
|
+
+ f"Must be between {mission.site.min_cogs} and {mission.site.max_cogs}"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
mission.num_cogs = self.num_cogs
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class DarkSideVariant(CoGameMissionVariant):
|
|
16
34
|
name: str = "dark_side"
|
|
17
35
|
description: str = "You're on the dark side of the asteroid. You recharge slower."
|
|
18
36
|
|
|
19
37
|
@override
|
|
20
|
-
def modify_mission(self, mission):
|
|
21
|
-
assert isinstance(mission, Mission)
|
|
38
|
+
def modify_mission(self, mission: CvCMission) -> None:
|
|
22
39
|
mission.cog.energy_regen = 0
|
|
23
40
|
|
|
24
41
|
|
|
25
|
-
class SuperChargedVariant(
|
|
42
|
+
class SuperChargedVariant(CoGameMissionVariant):
|
|
26
43
|
name: str = "super_charged"
|
|
27
44
|
description: str = "The sun is shining on you. You recharge faster."
|
|
28
45
|
|
|
29
46
|
@override
|
|
30
|
-
def modify_mission(self, mission):
|
|
31
|
-
assert isinstance(mission, Mission)
|
|
47
|
+
def modify_mission(self, mission: CvCMission) -> None:
|
|
32
48
|
mission.cog.energy_regen += 2
|
|
33
49
|
|
|
34
50
|
|
|
35
|
-
class
|
|
36
|
-
name: str = "rough_terrain"
|
|
37
|
-
description: str = "The terrain is rough. Moving is more energy intensive."
|
|
38
|
-
|
|
39
|
-
@override
|
|
40
|
-
def modify_mission(self, mission):
|
|
41
|
-
assert isinstance(mission, Mission)
|
|
42
|
-
mission.cog.move_energy_cost += 2
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class PackRatVariant(MissionVariant):
|
|
46
|
-
name: str = "pack_rat"
|
|
47
|
-
description: str = "Raise heart, cargo, energy, and gear caps to 255."
|
|
48
|
-
|
|
49
|
-
@override
|
|
50
|
-
def modify_mission(self, mission):
|
|
51
|
-
assert isinstance(mission, Mission)
|
|
52
|
-
mission.cog.heart_limit = max(mission.cog.heart_limit, 255)
|
|
53
|
-
mission.cog.energy_limit = max(mission.cog.energy_limit, 255)
|
|
54
|
-
mission.cog.cargo_limit = max(mission.cog.cargo_limit, 255)
|
|
55
|
-
mission.cog.gear_limit = max(mission.cog.gear_limit, 255)
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
class EnergizedVariant(MissionVariant):
|
|
51
|
+
class EnergizedVariant(CoGameMissionVariant):
|
|
59
52
|
name: str = "energized"
|
|
60
53
|
description: str = "Max energy and full regen so agents never run dry."
|
|
61
54
|
|
|
62
55
|
@override
|
|
63
|
-
def modify_mission(self, mission):
|
|
64
|
-
assert isinstance(mission, Mission)
|
|
56
|
+
def modify_mission(self, mission: CvCMission) -> None:
|
|
65
57
|
mission.cog.energy_limit = max(mission.cog.energy_limit, 255)
|
|
66
58
|
mission.cog.energy_regen = mission.cog.energy_limit
|
|
67
59
|
|
|
68
60
|
|
|
69
|
-
class
|
|
70
|
-
name: str = "compass"
|
|
71
|
-
description: str = "Enable compass observation."
|
|
72
|
-
|
|
73
|
-
@override
|
|
74
|
-
def modify_env(self, mission, env):
|
|
75
|
-
env.game.obs.global_obs.compass = True
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
class Small50Variant(MissionVariant):
|
|
61
|
+
class Small50Variant(CoGameMissionVariant):
|
|
79
62
|
name: str = "small_50"
|
|
80
63
|
description: str = "Set map size to 50x50 for quick runs."
|
|
81
64
|
|
|
82
65
|
def modify_env(self, mission, env) -> None:
|
|
83
66
|
map_builder = env.game.map_builder
|
|
84
|
-
# Only set width/height if instance is a SceneConfig, not a MapBuilderConfig
|
|
85
|
-
# When instance is a MapBuilderConfig, width and height must be None
|
|
86
67
|
if isinstance(map_builder, MapGen.Config) and isinstance(map_builder.instance, MapBuilderConfig):
|
|
87
|
-
# Skip setting width/height for MapBuilderConfig instances
|
|
88
68
|
return
|
|
89
69
|
env.game.map_builder = map_builder.model_copy(update={"width": 50, "height": 50})
|
|
90
70
|
|
|
91
71
|
|
|
92
|
-
# Biome variants (weather) for procedural maps
|
|
93
72
|
class DesertVariant(MachinaArenaVariant):
|
|
94
73
|
name: str = "desert"
|
|
95
74
|
description: str = "The desert sands make navigation challenging."
|
|
@@ -117,7 +96,6 @@ class CityVariant(MachinaArenaVariant):
|
|
|
117
96
|
def modify_node(self, node):
|
|
118
97
|
node.biome_weights = {"city": 1.0, "caves": 0.0, "desert": 0.0, "forest": 0.0}
|
|
119
98
|
node.base_biome = "city"
|
|
120
|
-
# Fill almost the entire map with the city layer
|
|
121
99
|
node.density_scale = 1.0
|
|
122
100
|
node.biome_count = 1
|
|
123
101
|
node.max_biome_zone_fraction = 0.95
|
|
@@ -140,32 +118,29 @@ class DistantResourcesVariant(MachinaArenaVariant):
|
|
|
140
118
|
|
|
141
119
|
@override
|
|
142
120
|
def modify_node(self, node):
|
|
143
|
-
# Bias buildings toward the map edges using bimodal clusters centered at
|
|
144
121
|
node.building_coverage = 0.01
|
|
145
122
|
|
|
146
123
|
vertical_edges = DistributionConfig(
|
|
147
124
|
type=DistributionType.BIMODAL,
|
|
148
|
-
center1_x=0.92,
|
|
125
|
+
center1_x=0.92,
|
|
149
126
|
center1_y=0.08,
|
|
150
|
-
center2_x=0.08,
|
|
127
|
+
center2_x=0.08,
|
|
151
128
|
center2_y=0.92,
|
|
152
129
|
cluster_std=0.18,
|
|
153
130
|
)
|
|
154
131
|
horizontal_edges = DistributionConfig(
|
|
155
132
|
type=DistributionType.BIMODAL,
|
|
156
|
-
center1_x=0.08,
|
|
133
|
+
center1_x=0.08,
|
|
157
134
|
center1_y=0.08,
|
|
158
|
-
center2_x=0.92,
|
|
135
|
+
center2_x=0.92,
|
|
159
136
|
center2_y=0.92,
|
|
160
137
|
cluster_std=0.18,
|
|
161
138
|
)
|
|
162
139
|
|
|
163
|
-
# Apply edge-biased distributions to extractors; other buildings follow the global distribution
|
|
164
140
|
names = list(self.building_names)
|
|
165
141
|
node.building_distributions = {
|
|
166
142
|
name: (vertical_edges if i % 2 == 0 else horizontal_edges) for i, name in enumerate(names)
|
|
167
143
|
}
|
|
168
|
-
# Fallback for any unspecified building types
|
|
169
144
|
node.distribution = DistributionConfig(type=DistributionType.UNIFORM)
|
|
170
145
|
|
|
171
146
|
|
|
@@ -180,10 +155,10 @@ class QuadrantBuildingsVariant(MachinaArenaVariant):
|
|
|
180
155
|
|
|
181
156
|
names = list(node.building_names or self.building_names)
|
|
182
157
|
centers = [
|
|
183
|
-
(0.25, 0.25),
|
|
184
|
-
(0.75, 0.25),
|
|
185
|
-
(0.25, 0.75),
|
|
186
|
-
(0.75, 0.75),
|
|
158
|
+
(0.25, 0.25),
|
|
159
|
+
(0.75, 0.25),
|
|
160
|
+
(0.25, 0.75),
|
|
161
|
+
(0.75, 0.75),
|
|
187
162
|
]
|
|
188
163
|
dists: dict[str, DistributionConfig] = {}
|
|
189
164
|
for i, name in enumerate(names):
|
|
@@ -206,8 +181,6 @@ class SingleResourceUniformVariant(MachinaArenaVariant):
|
|
|
206
181
|
|
|
207
182
|
@override
|
|
208
183
|
def modify_node(self, node):
|
|
209
|
-
# Resolve resource to a concrete building name
|
|
210
|
-
# Restrict building set to only the chosen building and enforce uniform distribution
|
|
211
184
|
node.building_names = [self.building_name]
|
|
212
185
|
node.building_weights = {self.building_name: 1.0}
|
|
213
186
|
node.building_distributions = None
|
|
@@ -217,12 +190,10 @@ class SingleResourceUniformVariant(MachinaArenaVariant):
|
|
|
217
190
|
class EmptyBaseVariant(BaseHubVariant):
|
|
218
191
|
name: str = "empty_base"
|
|
219
192
|
description: str = "Base hub with extractors removed from the four corners."
|
|
220
|
-
# Extractor object names to remove, e.g., ["oxygen_extractor"]
|
|
221
193
|
missing: list[str] = list(HUB_EXTRACTORS)
|
|
222
194
|
|
|
223
195
|
@override
|
|
224
196
|
def modify_node(self, node):
|
|
225
|
-
# Use the default extractor order and blank out any that are missing
|
|
226
197
|
missing_set = set(self.missing or [])
|
|
227
198
|
corner_objects = [name if name not in missing_set else "" for name in HUB_EXTRACTORS]
|
|
228
199
|
node.corner_objects = corner_objects
|
|
@@ -230,8 +201,6 @@ class EmptyBaseVariant(BaseHubVariant):
|
|
|
230
201
|
|
|
231
202
|
|
|
232
203
|
class BalancedCornersVariant(MachinaArenaVariant):
|
|
233
|
-
"""Enable corner balancing to ensure fair spawn distances."""
|
|
234
|
-
|
|
235
204
|
name: str = "balanced_corners"
|
|
236
205
|
description: str = "Balance path distances from center to corners for fair spawns."
|
|
237
206
|
balance_tolerance: float = 1.5
|
|
@@ -244,65 +213,19 @@ class BalancedCornersVariant(MachinaArenaVariant):
|
|
|
244
213
|
node.max_balance_shortcuts = self.max_balance_shortcuts
|
|
245
214
|
|
|
246
215
|
|
|
247
|
-
|
|
248
|
-
name: str = "trader"
|
|
249
|
-
description: str = "Agents can trade resources with each other."
|
|
250
|
-
|
|
251
|
-
@override
|
|
252
|
-
def modify_env(self, mission, env):
|
|
253
|
-
# Define vibe transfers for trading resources (actor gives, target receives)
|
|
254
|
-
trade_transfers = [
|
|
255
|
-
VibeTransfer(vibe="carbon_a", target={"carbon": 1}, actor={"carbon": -1}),
|
|
256
|
-
VibeTransfer(vibe="carbon_b", target={"carbon": 10}, actor={"carbon": -10}),
|
|
257
|
-
VibeTransfer(vibe="oxygen_a", target={"oxygen": 1}, actor={"oxygen": -1}),
|
|
258
|
-
VibeTransfer(vibe="oxygen_b", target={"oxygen": 10}, actor={"oxygen": -10}),
|
|
259
|
-
VibeTransfer(vibe="germanium_a", target={"germanium": 1}, actor={"germanium": -1}),
|
|
260
|
-
VibeTransfer(vibe="germanium_b", target={"germanium": 4}, actor={"germanium": -4}),
|
|
261
|
-
VibeTransfer(vibe="silicon_a", target={"silicon": 10}, actor={"silicon": -10}),
|
|
262
|
-
VibeTransfer(vibe="silicon_b", target={"silicon": 50}, actor={"silicon": -50}),
|
|
263
|
-
VibeTransfer(vibe="heart_a", target={"heart": 1}, actor={"heart": -1}),
|
|
264
|
-
VibeTransfer(vibe="heart_b", target={"heart": 4}, actor={"heart": -4}),
|
|
265
|
-
]
|
|
266
|
-
# Enable transfer action with these vibes
|
|
267
|
-
env.game.actions.transfer.enabled = True
|
|
268
|
-
env.game.actions.transfer.vibe_transfers.extend(trade_transfers)
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
class SharedRewardsVariant(MissionVariant):
|
|
272
|
-
name: str = "shared_rewards"
|
|
273
|
-
description: str = "Rewards for deposited hearts are shared among all agents."
|
|
274
|
-
|
|
275
|
-
@override
|
|
276
|
-
def modify_env(self, mission, env):
|
|
277
|
-
num_cogs = mission.num_cogs if mission.num_cogs is not None else mission.site.min_cogs
|
|
278
|
-
env.game.agent.rewards["chest_heart_deposited_by_agent"] = reward(
|
|
279
|
-
stat("chest.heart.deposited_by_agent"), weight=0
|
|
280
|
-
)
|
|
281
|
-
env.game.agent.rewards["chest_heart_amount"] = reward(stat("chest.heart.amount"), weight=1 / num_cogs)
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
# TODO - validate that all variant names are unique
|
|
285
|
-
VARIANTS: list[MissionVariant] = [
|
|
216
|
+
VARIANTS: list[CoGameMissionVariant] = [
|
|
286
217
|
CavesVariant(),
|
|
287
218
|
CityVariant(),
|
|
288
|
-
CompassVariant(),
|
|
289
219
|
DarkSideVariant(),
|
|
290
220
|
DesertVariant(),
|
|
291
221
|
EmptyBaseVariant(),
|
|
292
222
|
EnergizedVariant(),
|
|
293
223
|
ForestVariant(),
|
|
294
|
-
PackRatVariant(),
|
|
295
224
|
QuadrantBuildingsVariant(),
|
|
296
|
-
RoughTerrainVariant(),
|
|
297
|
-
SharedRewardsVariant(),
|
|
298
225
|
SingleResourceUniformVariant(),
|
|
299
226
|
Small50Variant(),
|
|
300
227
|
SuperChargedVariant(),
|
|
301
|
-
TraderVariant(),
|
|
302
228
|
*DIFFICULTY_VARIANTS,
|
|
303
229
|
]
|
|
304
230
|
|
|
305
|
-
|
|
306
|
-
HIDDEN_VARIANTS: list[MissionVariant] = [
|
|
307
|
-
# Example: ExperimentalVariant(), # keep empty by default
|
|
308
|
-
]
|
|
231
|
+
HIDDEN_VARIANTS: list[CoGameMissionVariant] = []
|
cogames/core.py
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
"""Core base classes for CoGame missions and variants."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from abc import ABC
|
|
6
|
+
from typing import TypeVar
|
|
7
|
+
|
|
8
|
+
from pydantic import Field
|
|
9
|
+
from typing_extensions import Self
|
|
10
|
+
|
|
11
|
+
from mettagrid.base_config import Config
|
|
12
|
+
from mettagrid.config.mettagrid_config import MettaGridConfig
|
|
13
|
+
from mettagrid.map_builder.map_builder import AnyMapBuilderConfig
|
|
14
|
+
|
|
15
|
+
# Type variable for mission types
|
|
16
|
+
TMission = TypeVar("TMission", bound="CoGameMission")
|
|
17
|
+
|
|
18
|
+
MAP_MISSION_DELIMITER = "."
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class CoGameMissionVariant(Config, ABC):
|
|
22
|
+
# Note: we could derive the name from the class name automatically, but it would make it
|
|
23
|
+
# harder to find the variant source code based on CLI interactions.
|
|
24
|
+
name: str
|
|
25
|
+
description: str = Field(default="")
|
|
26
|
+
|
|
27
|
+
def modify_mission(self, mission: CoGameMission) -> None:
|
|
28
|
+
# Override this method to modify the mission.
|
|
29
|
+
# Variants are allowed to modify the mission in-place - it's guaranteed to be a one-time only instance.
|
|
30
|
+
pass
|
|
31
|
+
|
|
32
|
+
def modify_env(self, mission: CoGameMission, env: MettaGridConfig) -> None:
|
|
33
|
+
# Override this method to modify the produced environment.
|
|
34
|
+
# Variants are allowed to modify the environment in-place.
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
def compat(self, mission: CoGameMission) -> bool:
|
|
38
|
+
"""Check if this variant is compatible with the given mission.
|
|
39
|
+
|
|
40
|
+
Returns True if the variant can be safely applied to the mission.
|
|
41
|
+
Override this method to add compatibility checks.
|
|
42
|
+
"""
|
|
43
|
+
return True
|
|
44
|
+
|
|
45
|
+
def apply(self, mission: TMission) -> TMission:
|
|
46
|
+
mission = mission.model_copy(deep=True)
|
|
47
|
+
mission.variants.append(self)
|
|
48
|
+
self.modify_mission(mission)
|
|
49
|
+
return mission
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class CoGameSite(Config):
|
|
53
|
+
name: str
|
|
54
|
+
description: str
|
|
55
|
+
map_builder: AnyMapBuilderConfig
|
|
56
|
+
|
|
57
|
+
min_cogs: int = Field(default=1, ge=1)
|
|
58
|
+
max_cogs: int = Field(default=1000, ge=1)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class CoGameMission(Config, ABC):
|
|
62
|
+
"""Base class for Mission configurations with common fields and methods."""
|
|
63
|
+
|
|
64
|
+
name: str
|
|
65
|
+
description: str
|
|
66
|
+
site: CoGameSite
|
|
67
|
+
num_cogs: int | None = None
|
|
68
|
+
|
|
69
|
+
# Variants are applied to the mission immediately, and to its env when make_env is called
|
|
70
|
+
variants: list[CoGameMissionVariant] = Field(default_factory=list)
|
|
71
|
+
|
|
72
|
+
max_steps: int = Field(default=10000)
|
|
73
|
+
|
|
74
|
+
def __init__(self, **kwargs):
|
|
75
|
+
super().__init__(**kwargs)
|
|
76
|
+
# Can't call `variant.apply` here because it will create a new mission instance
|
|
77
|
+
for variant in self.variants:
|
|
78
|
+
variant.modify_mission(self)
|
|
79
|
+
|
|
80
|
+
def with_variants(self, variants: list[CoGameMissionVariant]) -> Self:
|
|
81
|
+
mission = self
|
|
82
|
+
for variant in variants:
|
|
83
|
+
mission = variant.apply(mission)
|
|
84
|
+
return mission
|
|
85
|
+
|
|
86
|
+
def full_name(self) -> str:
|
|
87
|
+
return f"{self.site.name}{MAP_MISSION_DELIMITER}{self.name}"
|
cogames/main.py
CHANGED
|
@@ -109,13 +109,17 @@ def _register_policies() -> None:
|
|
|
109
109
|
discover_and_register_policies()
|
|
110
110
|
|
|
111
111
|
|
|
112
|
+
def _register_policies_callback() -> None:
|
|
113
|
+
_register_policies()
|
|
114
|
+
|
|
115
|
+
|
|
112
116
|
app = typer.Typer(
|
|
113
117
|
help="CoGames - Multi-agent cooperative and competitive games",
|
|
114
118
|
context_settings={"help_option_names": ["-h", "--help"]},
|
|
115
119
|
no_args_is_help=True,
|
|
116
120
|
rich_markup_mode="rich",
|
|
117
121
|
pretty_exceptions_show_locals=False,
|
|
118
|
-
callback=
|
|
122
|
+
callback=_register_policies_callback,
|
|
119
123
|
)
|
|
120
124
|
|
|
121
125
|
tutorial_app = typer.Typer(
|
|
@@ -15,9 +15,9 @@ map_data: |-
|
|
|
15
15
|
#.....####.C....O......................#
|
|
16
16
|
#C.......#.......................G.....#
|
|
17
17
|
#......C.#.....###.....###.............#
|
|
18
|
-
#........#.....#O
|
|
19
|
-
|
|
20
|
-
#.....#.....G
|
|
18
|
+
#........#.....#O...m...G#...........O.#
|
|
19
|
+
#.....#........#...a=r...#......#......#
|
|
20
|
+
#.....#.....G.......t...........##.....#
|
|
21
21
|
#....C#.............&....S.......##....#
|
|
22
22
|
#.....#.............@@@@@@@@......#....#
|
|
23
23
|
#.....#....C...........................#
|
|
@@ -51,3 +51,7 @@ char_to_map_name:
|
|
|
51
51
|
"@": agent.agent
|
|
52
52
|
"&": hub
|
|
53
53
|
"=": chest
|
|
54
|
+
"a": aligner_station
|
|
55
|
+
"r": scrambler_station
|
|
56
|
+
"m": miner_station
|
|
57
|
+
"t": scout_station
|
|
@@ -15,9 +15,9 @@ map_data: |-
|
|
|
15
15
|
#.....####.............................#
|
|
16
16
|
#........#.............................#
|
|
17
17
|
#........#.....###.....###.............#
|
|
18
|
-
#........#.....#O
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
#........#.....#O...m...G#.............#
|
|
19
|
+
#.....#........#...a=r...#......#......#
|
|
20
|
+
#.....#.............t...........##.....#
|
|
21
21
|
#.....#.............&............##....#
|
|
22
22
|
#.....#.............@@@@@@@@......#....#
|
|
23
23
|
#.....#........S.......................#
|
|
@@ -53,3 +53,7 @@ char_to_map_name:
|
|
|
53
53
|
"=": chest
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
"a": aligner_station
|
|
57
|
+
"r": scrambler_station
|
|
58
|
+
"m": miner_station
|
|
59
|
+
"t": scout_station
|
|
@@ -15,9 +15,9 @@ map_data: |-
|
|
|
15
15
|
#.....####...........C.................#
|
|
16
16
|
#....S...#........................O....#
|
|
17
17
|
#........#.....###.....###.............#
|
|
18
|
-
#........#.....#O
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
#........#.....#O...m...G#.............#
|
|
19
|
+
#.....#........#.@.a=r.@.#......#......#
|
|
20
|
+
#.....#.............t..@........##.....#
|
|
21
21
|
#.....#...C......@..&............##....#
|
|
22
22
|
#.....#.............@..@..........#....#
|
|
23
23
|
#.....#..........@.......@.............#
|
|
@@ -53,3 +53,7 @@ char_to_map_name:
|
|
|
53
53
|
"=": chest
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
"a": aligner_station
|
|
57
|
+
"r": scrambler_station
|
|
58
|
+
"m": miner_station
|
|
59
|
+
"t": scout_station
|
|
@@ -15,9 +15,9 @@ map_data: |-
|
|
|
15
15
|
#.....####.............................#
|
|
16
16
|
#........#.............................#
|
|
17
17
|
#........#.....###.....###.............#
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
#........#.....#....m....#.............#
|
|
19
|
+
#.....#........#...a=r...#......#......#
|
|
20
|
+
#.....#.............t...........##.....#
|
|
21
21
|
#.....#.............&............##....#
|
|
22
22
|
#.....#.............@@@@@@@@......#....#
|
|
23
23
|
#.....#................................#
|
|
@@ -53,3 +53,7 @@ char_to_map_name:
|
|
|
53
53
|
"=": chest
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
"a": aligner_station
|
|
57
|
+
"r": scrambler_station
|
|
58
|
+
"m": miner_station
|
|
59
|
+
"t": scout_station
|
|
@@ -15,9 +15,9 @@ map_data: |-
|
|
|
15
15
|
#.....####.............................#
|
|
16
16
|
#........#.............................#
|
|
17
17
|
#........#.....###.....###...........G.#
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
#.....#......C
|
|
18
|
+
#........#.....#....m....#.............#
|
|
19
|
+
#.....#........#...a=r...#......#......#
|
|
20
|
+
#.....#......C......t...........##.....#
|
|
21
21
|
#.....#.............&............##....#
|
|
22
22
|
#.....#.............@@@@@@@@......#....#
|
|
23
23
|
#.....#................................#
|
|
@@ -53,3 +53,7 @@ char_to_map_name:
|
|
|
53
53
|
"=": chest
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
"a": aligner_station
|
|
57
|
+
"r": scrambler_station
|
|
58
|
+
"m": miner_station
|
|
59
|
+
"t": scout_station
|
|
@@ -15,9 +15,9 @@ map_data: |-
|
|
|
15
15
|
#.....####.............................#
|
|
16
16
|
#........#.............................#
|
|
17
17
|
#........#.....###.....###.............#
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
#........#.....#....m....#.............#
|
|
19
|
+
#.....#........#...a=r...#......#......#
|
|
20
|
+
#.....#.............t...........##.....#
|
|
21
21
|
#.....#.............&............##....#
|
|
22
22
|
#.....#.............@@@@@@@@......#....#
|
|
23
23
|
#.....#................................#
|
|
@@ -51,3 +51,7 @@ char_to_map_name:
|
|
|
51
51
|
"@": agent.agent
|
|
52
52
|
"&": hub
|
|
53
53
|
"=": chest
|
|
54
|
+
"a": aligner_station
|
|
55
|
+
"r": scrambler_station
|
|
56
|
+
"m": miner_station
|
|
57
|
+
"t": scout_station
|
|
@@ -15,9 +15,9 @@ map_data: |-
|
|
|
15
15
|
#.....####.............................#
|
|
16
16
|
#...S....#........................S....#
|
|
17
17
|
#........#.....###.....###.............#
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
#........#.....#....m....#.............#
|
|
19
|
+
#.....#........#...a=r...#......#......#
|
|
20
|
+
#.....#.............t...........##.....#
|
|
21
21
|
#.....#...O.........&............##....#
|
|
22
22
|
#.....#.............@@@@@@@@......#....#
|
|
23
23
|
#.....#................................#
|
|
@@ -51,3 +51,7 @@ char_to_map_name:
|
|
|
51
51
|
"@": agent.agent
|
|
52
52
|
"&": hub
|
|
53
53
|
"=": chest
|
|
54
|
+
"a": aligner_station
|
|
55
|
+
"r": scrambler_station
|
|
56
|
+
"m": miner_station
|
|
57
|
+
"t": scout_station
|
|
@@ -15,9 +15,9 @@ map_data: |-
|
|
|
15
15
|
#.....####.............................#
|
|
16
16
|
#........#.............................#
|
|
17
17
|
#........#.....###.....###.............#
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
#........#.....#....m....#.............#
|
|
19
|
+
#.....#........#...a=r...#......#......#
|
|
20
|
+
#.....#.............t...........##.....#
|
|
21
21
|
#.....#.............&....@.......##....#
|
|
22
22
|
#.....#.............@.............#....#
|
|
23
23
|
#.....#.........@.......@..............#
|
|
@@ -54,3 +54,7 @@ char_to_map_name:
|
|
|
54
54
|
|
|
55
55
|
|
|
56
56
|
|
|
57
|
+
"a": aligner_station
|
|
58
|
+
"r": scrambler_station
|
|
59
|
+
"m": miner_station
|
|
60
|
+
"t": scout_station
|
|
@@ -15,9 +15,9 @@ map_data: |-
|
|
|
15
15
|
#.....####.............................#
|
|
16
16
|
#........#.............................#
|
|
17
17
|
#........#.....###.....###.............#
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
#........#.....#....m...G#.............#
|
|
19
|
+
#.....#........#...a=r...#......#......#
|
|
20
|
+
#.....#.............t...........##.....#
|
|
21
21
|
#.....#.............&............##....#
|
|
22
22
|
#.....#.............@@@@@@@@......#....#
|
|
23
23
|
#.....#................................#
|
|
@@ -53,3 +53,7 @@ char_to_map_name:
|
|
|
53
53
|
"=": chest
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
"a": aligner_station
|
|
57
|
+
"r": scrambler_station
|
|
58
|
+
"m": miner_station
|
|
59
|
+
"t": scout_station
|
|
@@ -15,9 +15,9 @@ map_data: |-
|
|
|
15
15
|
#.....####.C....O......................#
|
|
16
16
|
#C.......#.......................G.....#
|
|
17
17
|
#......C.#.....###.....###.............#
|
|
18
|
-
#........#.....#O
|
|
19
|
-
|
|
20
|
-
#.....#.....G
|
|
18
|
+
#........#.....#O...m...G#...........O.#
|
|
19
|
+
#.....#........#...a=r...#......#......#
|
|
20
|
+
#.....#.....G.......t...........##.....#
|
|
21
21
|
#....C#.............&....S.......##....#
|
|
22
22
|
#.....#.............@@@@@@@@......#....#
|
|
23
23
|
#.....#................................#
|
|
@@ -53,3 +53,7 @@ char_to_map_name:
|
|
|
53
53
|
"=": chest
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
"a": aligner_station
|
|
57
|
+
"r": scrambler_station
|
|
58
|
+
"m": miner_station
|
|
59
|
+
"t": scout_station
|
|
@@ -55,10 +55,10 @@ map_data: |-
|
|
|
55
55
|
#####............###............#...###.....#.........@.........#...#.......#.....#..###...##...#.##...#######
|
|
56
56
|
########..#..###.##.#.#.....#.S....#.##..##.......................#.#....#..#.G.......##.#####.###.....#######
|
|
57
57
|
######........##......#..#..#......#.#.....#........@.&.@........##...##.#.##.........##....#..##.#....#######
|
|
58
|
-
#####....##.C
|
|
58
|
+
#####....##.C.#........###..#.#...##.###..#...........m..........#...#......##......C.####...#.#..#.....######
|
|
59
59
|
######...#........#...........#.......#..####.........@.........#.#..#..####.#........####.....##.......######
|
|
60
|
-
#######.........#..##.G
|
|
61
|
-
|
|
60
|
+
#######.........#..##.G.#...#.####....#.....#........a=r........#..##..#####......+.#...#.##..##....S...######
|
|
61
|
+
########.#.##..#...##.....###.###.......##..#.........t.........#.......#....#............#.............######
|
|
62
62
|
#######.#######....##..#.######.....##..##..#...................####..G.##.....##...###..#..###....#..########
|
|
63
63
|
######......#....#..#.####.###..###....####.#...................#####...##.##.##...##.....#######.#..#########
|
|
64
64
|
#####.....O...O.....#.###...##.##.....#..####...................#...#...#####...#..##.##....#..####..##..#####
|
|
@@ -121,3 +121,7 @@ char_to_map_name:
|
|
|
121
121
|
"S": silicon_extractor
|
|
122
122
|
"O": oxygen_extractor
|
|
123
123
|
"C": carbon_extractor
|
|
124
|
+
"a": aligner_station
|
|
125
|
+
"r": scrambler_station
|
|
126
|
+
"m": miner_station
|
|
127
|
+
"t": scout_station
|
|
@@ -20,10 +20,10 @@ map_data: |-
|
|
|
20
20
|
########.#......@..@....@....#....######
|
|
21
21
|
########........................+..#####
|
|
22
22
|
######...........@.&.@.............#####
|
|
23
|
-
|
|
23
|
+
######..#..........m...............#####
|
|
24
24
|
#####..###......@..@.@.......###..######
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
#####..###........a=r........##..#######
|
|
26
|
+
#####..###.........t.........#..########
|
|
27
27
|
#####...##...................#..########
|
|
28
28
|
######..##...................#.#########
|
|
29
29
|
#######..#...................#.....#####
|
|
@@ -51,3 +51,7 @@ char_to_map_name:
|
|
|
51
51
|
"S": silicon_extractor
|
|
52
52
|
"O": oxygen_extractor
|
|
53
53
|
"C": carbon_extractor
|
|
54
|
+
"a": aligner_station
|
|
55
|
+
"r": scrambler_station
|
|
56
|
+
"m": miner_station
|
|
57
|
+
"t": scout_station
|
|
@@ -30,10 +30,10 @@ map_data: |-
|
|
|
30
30
|
#####...#....#.....#..@......@.....@...#.#..#.......########
|
|
31
31
|
#####.....#.............................##..##.....#########
|
|
32
32
|
#####..........#...........@.&.@..............##.###########
|
|
33
|
-
######..##.G
|
|
33
|
+
######..##.G..###............m...........C....##.###########
|
|
34
34
|
######.###.....##..#.....@...@.........#..........#...######
|
|
35
|
-
#####..##....G
|
|
36
|
-
|
|
35
|
+
#####..##....G.....#........a=r........#........##.....#####
|
|
36
|
+
#####..#...........#.........t.........#........##.....#####
|
|
37
37
|
#####...#.....#....#...................#......#..#.O..######
|
|
38
38
|
#####....####.##...#...................#..............######
|
|
39
39
|
#####....##........#...................#..............######
|
|
@@ -71,3 +71,7 @@ char_to_map_name:
|
|
|
71
71
|
"S": silicon_extractor
|
|
72
72
|
"O": oxygen_extractor
|
|
73
73
|
"C": carbon_extractor
|
|
74
|
+
"a": aligner_station
|
|
75
|
+
"r": scrambler_station
|
|
76
|
+
"m": miner_station
|
|
77
|
+
"t": scout_station
|