mettagrid 0.0.1__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.
Potentially problematic release.
This version of mettagrid might be problematic. Click here for more details.
- mettagrid/__init__.py +0 -0
- mettagrid/actions/__init__.py +0 -0
- mettagrid/actions/actions.pxd +31 -0
- mettagrid/actions/actions.pyx +59 -0
- mettagrid/actions/attack.pxd +6 -0
- mettagrid/actions/attack.pyx +61 -0
- mettagrid/actions/gift.pxd +4 -0
- mettagrid/actions/gift.pyx +24 -0
- mettagrid/actions/move.pxd +4 -0
- mettagrid/actions/move.pyx +31 -0
- mettagrid/actions/rotate.pxd +4 -0
- mettagrid/actions/rotate.pyx +28 -0
- mettagrid/actions/shield.pxd +4 -0
- mettagrid/actions/shield.pyx +26 -0
- mettagrid/actions/use.pxd +4 -0
- mettagrid/actions/use.pyx +66 -0
- mettagrid/config/game_builder.py +101 -0
- mettagrid/config/sample_config.py +27 -0
- mettagrid/mettagrid.pyx +78 -0
- mettagrid/mettagrid_env.py +181 -0
- mettagrid/objects.pxd +197 -0
- mettagrid/objects.pyx +67 -0
- mettagrid/renderer/assets/ore-0.png +0 -0
- mettagrid/renderer/assets/ore-1.png +0 -0
- mettagrid/renderer/assets/ore-2.png +0 -0
- mettagrid/renderer/assets/ore-3.png +0 -0
- mettagrid/renderer/assets/ore-4.png +0 -0
- mettagrid/renderer/assets/ore-5.png +0 -0
- mettagrid/renderer/assets/ore-6.png +0 -0
- mettagrid/renderer/assets/puffer_chars.png +0 -0
- mettagrid/renderer/assets/tiny_galaxy_items.png +0 -0
- mettagrid/renderer/assets/tiny_galaxy_monsters.png +0 -0
- mettagrid/renderer/assets/wall1-0.png +0 -0
- mettagrid/renderer/raylib_client.py +180 -0
- mettagrid-0.0.1.dist-info/LICENSE +21 -0
- mettagrid-0.0.1.dist-info/METADATA +23 -0
- mettagrid-0.0.1.dist-info/RECORD +38 -0
- mettagrid-0.0.1.dist-info/WHEEL +4 -0
mettagrid/__init__.py
ADDED
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
from libc.stdio cimport printf
|
|
3
|
+
from libcpp.string cimport string
|
|
4
|
+
from libcpp.map cimport map
|
|
5
|
+
|
|
6
|
+
from puffergrid.grid_object cimport TypeId, GridObjectId
|
|
7
|
+
from puffergrid.action cimport ActionHandler, ActionArg
|
|
8
|
+
from mettagrid.objects cimport Agent
|
|
9
|
+
|
|
10
|
+
cdef struct StatNames:
|
|
11
|
+
string action
|
|
12
|
+
string action_energy
|
|
13
|
+
map[TypeId, string] target
|
|
14
|
+
map[TypeId, string] target_energy
|
|
15
|
+
|
|
16
|
+
cdef class MettaActionHandler(ActionHandler):
|
|
17
|
+
cdef StatNames _stats
|
|
18
|
+
cdef string action_name
|
|
19
|
+
cdef int action_cost
|
|
20
|
+
|
|
21
|
+
cdef char handle_action(
|
|
22
|
+
self,
|
|
23
|
+
unsigned int actor_id,
|
|
24
|
+
GridObjectId actor_object_id,
|
|
25
|
+
ActionArg arg)
|
|
26
|
+
|
|
27
|
+
cdef char _handle_action(
|
|
28
|
+
self,
|
|
29
|
+
unsigned int actor_id,
|
|
30
|
+
Agent * actor,
|
|
31
|
+
ActionArg arg)
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
|
|
2
|
+
from libc.stdio cimport printf
|
|
3
|
+
|
|
4
|
+
from omegaconf import OmegaConf
|
|
5
|
+
|
|
6
|
+
from puffergrid.grid_object cimport GridObjectId
|
|
7
|
+
from puffergrid.action cimport ActionHandler, ActionArg
|
|
8
|
+
from mettagrid.objects cimport Agent, ObjectTypeNames
|
|
9
|
+
|
|
10
|
+
cdef extern from "<string>" namespace "std":
|
|
11
|
+
string to_string(int val)
|
|
12
|
+
|
|
13
|
+
cdef class MettaActionHandler(ActionHandler):
|
|
14
|
+
def __init__(self, cfg: OmegaConf, action_name, action_cost=0):
|
|
15
|
+
self.action_name = action_name
|
|
16
|
+
|
|
17
|
+
self._stats.action = "action." + action_name
|
|
18
|
+
self._stats.action_energy = "action." + action_name + ".energy"
|
|
19
|
+
|
|
20
|
+
for t, n in enumerate(ObjectTypeNames):
|
|
21
|
+
self._stats.target[t] = self._stats.action + "." + n
|
|
22
|
+
self._stats.target_energy[t] = self._stats.action_energy + "." + n
|
|
23
|
+
|
|
24
|
+
self.action_cost = cfg.cost
|
|
25
|
+
|
|
26
|
+
cdef char handle_action(
|
|
27
|
+
self,
|
|
28
|
+
unsigned int actor_id,
|
|
29
|
+
GridObjectId actor_object_id,
|
|
30
|
+
ActionArg arg):
|
|
31
|
+
|
|
32
|
+
cdef Agent *actor = <Agent*>self.env._grid.object(actor_object_id)
|
|
33
|
+
|
|
34
|
+
if actor.frozen:
|
|
35
|
+
return False
|
|
36
|
+
|
|
37
|
+
if actor.energy < self.action_cost:
|
|
38
|
+
return False
|
|
39
|
+
|
|
40
|
+
actor.energy -= self.action_cost
|
|
41
|
+
self.env._stats.agent_add(actor_id, self._stats.action_energy.c_str(), self.action_cost)
|
|
42
|
+
|
|
43
|
+
cdef char result = self._handle_action(actor_id, actor, arg)
|
|
44
|
+
|
|
45
|
+
if result:
|
|
46
|
+
self.env._stats.agent_incr(actor_id, self._stats.action.c_str())
|
|
47
|
+
|
|
48
|
+
return result
|
|
49
|
+
|
|
50
|
+
cdef char _handle_action(
|
|
51
|
+
self,
|
|
52
|
+
unsigned int actor_id,
|
|
53
|
+
Agent * actor,
|
|
54
|
+
ActionArg arg):
|
|
55
|
+
return False
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
|
|
2
|
+
from libc.stdio cimport printf
|
|
3
|
+
from omegaconf import OmegaConf
|
|
4
|
+
|
|
5
|
+
from puffergrid.grid_object cimport GridLocation, GridObjectId, Orientation, GridObject
|
|
6
|
+
from puffergrid.action cimport ActionHandler, ActionArg
|
|
7
|
+
from mettagrid.objects cimport MettaObject, ObjectType, Usable, Altar, Agent, Events, GridLayer
|
|
8
|
+
from mettagrid.objects cimport Generator, Converter, InventoryItem, ObjectTypeNames, InventoryItemNames
|
|
9
|
+
from mettagrid.actions.actions cimport MettaActionHandler
|
|
10
|
+
|
|
11
|
+
cdef class Attack(MettaActionHandler):
|
|
12
|
+
def __init__(self, cfg: OmegaConf):
|
|
13
|
+
MettaActionHandler.__init__(self, cfg, "attack")
|
|
14
|
+
|
|
15
|
+
cdef char _handle_action(
|
|
16
|
+
self,
|
|
17
|
+
unsigned int actor_id,
|
|
18
|
+
Agent * actor,
|
|
19
|
+
ActionArg arg):
|
|
20
|
+
|
|
21
|
+
if arg > 9 or arg < 1:
|
|
22
|
+
return False
|
|
23
|
+
|
|
24
|
+
cdef short distance = 0
|
|
25
|
+
cdef short offset = 0
|
|
26
|
+
distance = 1 + (arg - 1) // 3
|
|
27
|
+
offset = (arg - 1) % 3 - 1
|
|
28
|
+
|
|
29
|
+
cdef GridLocation target_loc = self.env._grid.relative_location(
|
|
30
|
+
actor.location,
|
|
31
|
+
<Orientation>actor.orientation,
|
|
32
|
+
distance, offset)
|
|
33
|
+
|
|
34
|
+
target_loc.layer = GridLayer.Agent_Layer
|
|
35
|
+
cdef Agent * agent_target = <Agent *>self.env._grid.object_at(target_loc)
|
|
36
|
+
if agent_target:
|
|
37
|
+
self.env._stats.agent_incr(actor_id, self._stats.target[agent_target._type_id].c_str())
|
|
38
|
+
if agent_target.shield and agent_target.energy >= self.damage:
|
|
39
|
+
agent_target.energy -= self.damage
|
|
40
|
+
self.env._stats.agent_add(actor_id, "shield_damage", self.damage)
|
|
41
|
+
else:
|
|
42
|
+
self.env._stats.agent_add(actor_id, "shield_damage", agent_target.energy)
|
|
43
|
+
agent_target.energy = 0
|
|
44
|
+
agent_target.shield = False
|
|
45
|
+
agent_target.frozen = True
|
|
46
|
+
self.env._stats.agent_incr(actor_id, "attack.frozen")
|
|
47
|
+
return True
|
|
48
|
+
|
|
49
|
+
target_loc.layer = GridLayer.Object_Layer
|
|
50
|
+
cdef MettaObject * object_target = <MettaObject *>self.env._grid.object_at(target_loc)
|
|
51
|
+
if object_target:
|
|
52
|
+
self.env._stats.agent_incr(actor_id, self._stats.target[object_target._type_id].c_str())
|
|
53
|
+
object_target.hp -= 1
|
|
54
|
+
self.env._stats.agent_incr(actor_id, "damage." + ObjectTypeNames[object_target._type_id])
|
|
55
|
+
if object_target.hp <= 0:
|
|
56
|
+
self.env._grid.remove_object(object_target)
|
|
57
|
+
self.env._stats.agent_incr(actor_id, "destroyed." + ObjectTypeNames[object_target._type_id])
|
|
58
|
+
|
|
59
|
+
return True
|
|
60
|
+
|
|
61
|
+
return False
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
|
|
2
|
+
from libc.stdio cimport printf
|
|
3
|
+
from omegaconf import OmegaConf
|
|
4
|
+
|
|
5
|
+
from puffergrid.grid_object cimport GridLocation, GridObjectId, Orientation, GridObject
|
|
6
|
+
from puffergrid.action cimport ActionHandler, ActionArg
|
|
7
|
+
from mettagrid.objects cimport MettaObject, ObjectType, Usable, Altar, Agent, Events, GridLayer
|
|
8
|
+
from mettagrid.objects cimport Generator, Converter, InventoryItem, ObjectTypeNames, InventoryItemNames
|
|
9
|
+
from mettagrid.actions.actions cimport MettaActionHandler
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
cdef class Gift(MettaActionHandler):
|
|
13
|
+
def __init__(self, cfg: OmegaConf):
|
|
14
|
+
MettaActionHandler.__init__(self, cfg, "gift")
|
|
15
|
+
|
|
16
|
+
cdef char _handle_action(
|
|
17
|
+
self,
|
|
18
|
+
unsigned int actor_id,
|
|
19
|
+
Agent * actor,
|
|
20
|
+
ActionArg arg):
|
|
21
|
+
return False
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
|
|
2
|
+
from libc.stdio cimport printf
|
|
3
|
+
|
|
4
|
+
from omegaconf import OmegaConf
|
|
5
|
+
|
|
6
|
+
from puffergrid.grid_object cimport GridLocation, GridObjectId, GridObject, Orientation
|
|
7
|
+
from puffergrid.action cimport ActionHandler, ActionArg
|
|
8
|
+
from mettagrid.objects cimport MettaObject, ObjectType, Usable, Altar, Agent, Events, GridLayer
|
|
9
|
+
from mettagrid.objects cimport Generator, Converter, InventoryItem, ObjectTypeNames, InventoryItemNames
|
|
10
|
+
from mettagrid.actions.actions cimport MettaActionHandler
|
|
11
|
+
|
|
12
|
+
cdef class Move(MettaActionHandler):
|
|
13
|
+
def __init__(self, cfg: OmegaConf):
|
|
14
|
+
MettaActionHandler.__init__(self, cfg, "move")
|
|
15
|
+
|
|
16
|
+
cdef char _handle_action(
|
|
17
|
+
self,
|
|
18
|
+
unsigned int actor_id,
|
|
19
|
+
Agent * actor,
|
|
20
|
+
ActionArg arg):
|
|
21
|
+
|
|
22
|
+
cdef unsigned short direction = arg
|
|
23
|
+
if direction >= 2:
|
|
24
|
+
return False
|
|
25
|
+
|
|
26
|
+
cdef Orientation orientation = <Orientation>((actor.orientation + 2*(direction)) % 4)
|
|
27
|
+
cdef GridLocation old_loc = actor.location
|
|
28
|
+
cdef GridLocation new_loc = self.env._grid.relative_location(old_loc, orientation)
|
|
29
|
+
if not self.env._grid.is_empty(new_loc.r, new_loc.c):
|
|
30
|
+
return False
|
|
31
|
+
return self.env._grid.move_object(actor.id, new_loc)
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
from libc.stdio cimport printf
|
|
3
|
+
|
|
4
|
+
from omegaconf import OmegaConf
|
|
5
|
+
|
|
6
|
+
from puffergrid.grid_object cimport GridLocation, GridObjectId, Orientation, GridObject
|
|
7
|
+
from puffergrid.action cimport ActionHandler, ActionArg
|
|
8
|
+
from mettagrid.objects cimport MettaObject, ObjectType, Usable, Altar, Agent, Events, GridLayer
|
|
9
|
+
from mettagrid.objects cimport Generator, Converter, InventoryItem, ObjectTypeNames, InventoryItemNames
|
|
10
|
+
from mettagrid.actions.actions cimport MettaActionHandler
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
cdef class Rotate(MettaActionHandler):
|
|
14
|
+
def __init__(self, cfg: OmegaConf):
|
|
15
|
+
MettaActionHandler.__init__(self, cfg, "rotate")
|
|
16
|
+
|
|
17
|
+
cdef char _handle_action(
|
|
18
|
+
self,
|
|
19
|
+
unsigned int actor_id,
|
|
20
|
+
Agent * actor,
|
|
21
|
+
ActionArg arg):
|
|
22
|
+
|
|
23
|
+
cdef unsigned short orientation = arg
|
|
24
|
+
if orientation >= 4:
|
|
25
|
+
return False
|
|
26
|
+
|
|
27
|
+
actor.orientation = orientation
|
|
28
|
+
return True
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
|
|
2
|
+
from libc.stdio cimport printf
|
|
3
|
+
|
|
4
|
+
from omegaconf import OmegaConf
|
|
5
|
+
|
|
6
|
+
from puffergrid.grid_object cimport GridLocation, GridObjectId, Orientation, GridObject
|
|
7
|
+
from puffergrid.action cimport ActionHandler, ActionArg
|
|
8
|
+
from mettagrid.objects cimport MettaObject, ObjectType, Usable, Altar, Agent, Events, GridLayer
|
|
9
|
+
from mettagrid.objects cimport Generator, Converter, InventoryItem, ObjectTypeNames, InventoryItemNames
|
|
10
|
+
from mettagrid.actions.actions cimport MettaActionHandler
|
|
11
|
+
|
|
12
|
+
cdef class Shield(MettaActionHandler):
|
|
13
|
+
def __init__(self, cfg: OmegaConf):
|
|
14
|
+
MettaActionHandler.__init__(self, cfg, "shield")
|
|
15
|
+
|
|
16
|
+
cdef char _handle_action(
|
|
17
|
+
self,
|
|
18
|
+
unsigned int actor_id,
|
|
19
|
+
Agent * actor,
|
|
20
|
+
ActionArg arg):
|
|
21
|
+
|
|
22
|
+
if actor.shield:
|
|
23
|
+
actor.shield = True
|
|
24
|
+
else:
|
|
25
|
+
actor.shield = False
|
|
26
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
|
|
2
|
+
from libc.stdio cimport printf
|
|
3
|
+
|
|
4
|
+
from omegaconf import OmegaConf
|
|
5
|
+
|
|
6
|
+
from puffergrid.grid_object cimport GridLocation, GridObjectId, Orientation, GridObject
|
|
7
|
+
from puffergrid.action cimport ActionHandler, ActionArg
|
|
8
|
+
from mettagrid.objects cimport MettaObject, ObjectType, Usable, Altar, Agent, Events, GridLayer
|
|
9
|
+
from mettagrid.objects cimport Generator, Converter, InventoryItem, ObjectTypeNames, InventoryItemNames
|
|
10
|
+
from mettagrid.actions.actions cimport MettaActionHandler
|
|
11
|
+
|
|
12
|
+
cdef class Use(MettaActionHandler):
|
|
13
|
+
def __init__(self, cfg: OmegaConf):
|
|
14
|
+
MettaActionHandler.__init__(self, cfg, "use")
|
|
15
|
+
|
|
16
|
+
cdef char _handle_action(
|
|
17
|
+
self,
|
|
18
|
+
unsigned int actor_id,
|
|
19
|
+
Agent * actor,
|
|
20
|
+
ActionArg arg):
|
|
21
|
+
|
|
22
|
+
cdef GridLocation target_loc = self.env._grid.relative_location(
|
|
23
|
+
actor.location,
|
|
24
|
+
<Orientation>actor.orientation
|
|
25
|
+
)
|
|
26
|
+
target_loc.layer = GridLayer.Object_Layer
|
|
27
|
+
cdef MettaObject *target = <MettaObject*>self.env._grid.object_at(target_loc)
|
|
28
|
+
if target == NULL:
|
|
29
|
+
return False
|
|
30
|
+
|
|
31
|
+
if not target.usable(actor):
|
|
32
|
+
return False
|
|
33
|
+
|
|
34
|
+
cdef Usable *usable = <Usable*> target
|
|
35
|
+
actor.energy -= usable.use_cost
|
|
36
|
+
|
|
37
|
+
usable.ready = 0
|
|
38
|
+
self.env._event_manager.schedule_event(Events.Reset, usable.cooldown, usable.id, 0)
|
|
39
|
+
|
|
40
|
+
self.env._stats.agent_incr(actor_id, self._stats.target[target._type_id].c_str())
|
|
41
|
+
self.env._stats.agent_add(actor_id, self._stats.target_energy[target._type_id].c_str(), usable.use_cost + self.action_cost)
|
|
42
|
+
|
|
43
|
+
if target._type_id == ObjectType.AltarT:
|
|
44
|
+
self.env._rewards[actor_id] += 1
|
|
45
|
+
|
|
46
|
+
cdef Generator *generator
|
|
47
|
+
if target._type_id == ObjectType.GeneratorT:
|
|
48
|
+
generator = <Generator*>target
|
|
49
|
+
generator.r1 -= 1
|
|
50
|
+
actor.update_inventory(InventoryItem.r1, 1)
|
|
51
|
+
self.env._stats.agent_incr(actor_id, "r1.gained")
|
|
52
|
+
self.env._stats.game_incr("r1.harvested")
|
|
53
|
+
|
|
54
|
+
cdef Converter *converter
|
|
55
|
+
if target._type_id == ObjectType.ConverterT:
|
|
56
|
+
converter = <Converter*>target
|
|
57
|
+
actor.update_inventory(converter.input_resource, -1)
|
|
58
|
+
self.env._stats.agent_incr(actor_id, InventoryItemNames[converter.input_resource] + ".used")
|
|
59
|
+
|
|
60
|
+
actor.update_inventory(converter.output_resource, 1)
|
|
61
|
+
self.env._stats.agent_incr(actor_id, InventoryItemNames[converter.input_resource] + ".gained")
|
|
62
|
+
|
|
63
|
+
actor.energy += converter.output_energy
|
|
64
|
+
self.env._stats.agent_add(actor_id, "energy.gained", converter.output_energy)
|
|
65
|
+
|
|
66
|
+
return True
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from typing import Dict, List
|
|
2
|
+
import numpy as np
|
|
3
|
+
import yaml
|
|
4
|
+
from omegaconf import OmegaConf
|
|
5
|
+
|
|
6
|
+
class NoAliasDumper(yaml.Dumper):
|
|
7
|
+
def ignore_aliases(self, data):
|
|
8
|
+
return True
|
|
9
|
+
|
|
10
|
+
class MettaGridGameBuilder():
|
|
11
|
+
def __init__(
|
|
12
|
+
self,
|
|
13
|
+
obs_width: int,
|
|
14
|
+
obs_height: int,
|
|
15
|
+
tile_size: int,
|
|
16
|
+
max_steps: int,
|
|
17
|
+
num_agents: int,
|
|
18
|
+
no_energy_steps: int,
|
|
19
|
+
objects,
|
|
20
|
+
actions,
|
|
21
|
+
map):
|
|
22
|
+
|
|
23
|
+
self.obs_width = obs_width
|
|
24
|
+
self.obs_height = obs_height
|
|
25
|
+
self.tile_size = tile_size
|
|
26
|
+
self.num_agents = num_agents
|
|
27
|
+
self.max_steps = max_steps
|
|
28
|
+
|
|
29
|
+
self._symbols = {
|
|
30
|
+
"agent": "A",
|
|
31
|
+
"altar": "a",
|
|
32
|
+
"converter": "c",
|
|
33
|
+
"generator": "g",
|
|
34
|
+
"wall": "w",
|
|
35
|
+
"empty": " ",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
self.no_energy_steps = no_energy_steps
|
|
39
|
+
objects = OmegaConf.create(objects)
|
|
40
|
+
self.object_configs = objects
|
|
41
|
+
actions = OmegaConf.create(actions)
|
|
42
|
+
self.action_configs = actions
|
|
43
|
+
self.map_config = OmegaConf.create(map)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def level(self):
|
|
47
|
+
layout = self.map_config.layout
|
|
48
|
+
|
|
49
|
+
if "rooms" in layout:
|
|
50
|
+
return self.build_map(layout.rooms)
|
|
51
|
+
else:
|
|
52
|
+
return self.build_map(
|
|
53
|
+
[["room"] * layout.rooms_x] * layout.rooms_y)
|
|
54
|
+
|
|
55
|
+
def build_map(self, rooms):
|
|
56
|
+
num_agents = 0
|
|
57
|
+
layers = []
|
|
58
|
+
for layer in rooms:
|
|
59
|
+
rooms = []
|
|
60
|
+
for room_name in layer:
|
|
61
|
+
room_config = self.map_config[room_name]
|
|
62
|
+
rooms.append(self.build_room(room_config, num_agents + 1))
|
|
63
|
+
num_agents += room_config.objects.agent
|
|
64
|
+
layers.append(np.concatenate(rooms, axis=1))
|
|
65
|
+
level = np.concatenate(layers, axis=0)
|
|
66
|
+
assert num_agents == self.num_agents, f"Number of agents in map ({num_agents}) does not match num_agents ({self.num_agents})"
|
|
67
|
+
|
|
68
|
+
footer = np.full((1, level.shape[1]), "W", dtype="U6")
|
|
69
|
+
footer[0, 0] = "q"
|
|
70
|
+
|
|
71
|
+
level = np.concatenate([level, footer], axis=0)
|
|
72
|
+
return level
|
|
73
|
+
|
|
74
|
+
def build_room(self, room_config, starting_agent=1):
|
|
75
|
+
symbols = []
|
|
76
|
+
content_width = room_config.width - 2*room_config.border
|
|
77
|
+
content_height = room_config.height - 2*room_config.border
|
|
78
|
+
area = content_width * content_height
|
|
79
|
+
|
|
80
|
+
for obj_name, count in room_config.objects.items():
|
|
81
|
+
symbol = self._symbols[obj_name]
|
|
82
|
+
if obj_name == "agent":
|
|
83
|
+
symbols.extend([f"{symbol}{i+starting_agent}" for i in range(count)])
|
|
84
|
+
else:
|
|
85
|
+
symbols.extend([symbol] * count)
|
|
86
|
+
|
|
87
|
+
assert(len(symbols) <= area), f"Too many objects in room: {len(symbols)} > {area}"
|
|
88
|
+
symbols.extend(["."] * (area - len(symbols)))
|
|
89
|
+
symbols = np.array(symbols).astype("U8")
|
|
90
|
+
np.random.shuffle(symbols)
|
|
91
|
+
content = symbols.reshape(content_height, content_width)
|
|
92
|
+
room = np.full((room_config.height, room_config.width), "W", dtype="U6")
|
|
93
|
+
room[room_config.border:room_config.border+content_height,
|
|
94
|
+
room_config.border:room_config.border+content_width] = content
|
|
95
|
+
|
|
96
|
+
return room
|
|
97
|
+
|
|
98
|
+
def termination_conditions(self):
|
|
99
|
+
return {
|
|
100
|
+
"Win": [ {"lt": ["game:max_steps", "game:step"]} ],
|
|
101
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
from omegaconf import DictConfig, ListConfig
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def sample_config(value):
|
|
8
|
+
if isinstance(value, int):
|
|
9
|
+
return value
|
|
10
|
+
if isinstance(value, float):
|
|
11
|
+
return value
|
|
12
|
+
if isinstance(value, DictConfig):
|
|
13
|
+
return {
|
|
14
|
+
key: sample_config(value)
|
|
15
|
+
for key, value in value.items()
|
|
16
|
+
}
|
|
17
|
+
if isinstance(value, ListConfig):
|
|
18
|
+
if len(value) == 0:
|
|
19
|
+
return value
|
|
20
|
+
if isinstance(value[0], int):
|
|
21
|
+
assert len(value) == 2, f"Found a list with length != 2 {value}"
|
|
22
|
+
return np.random.randint(value[0], value[1])
|
|
23
|
+
if isinstance(value[0], float):
|
|
24
|
+
assert len(value) == 2, f"Found a list with length != 2 {value}"
|
|
25
|
+
return np.random.uniform(value[0], value[1])
|
|
26
|
+
return value
|
|
27
|
+
return value
|
mettagrid/mettagrid.pyx
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
|
|
2
|
+
from libc.stdio cimport printf
|
|
3
|
+
|
|
4
|
+
import numpy as np
|
|
5
|
+
import gymnasium as gym
|
|
6
|
+
from omegaconf import OmegaConf
|
|
7
|
+
|
|
8
|
+
from puffergrid.grid_env cimport GridEnv
|
|
9
|
+
|
|
10
|
+
from mettagrid.objects cimport ObjectLayers, Agent, ResetHandler, Wall, Generator, Converter, Altar
|
|
11
|
+
from mettagrid.objects cimport MettaObservationEncoder
|
|
12
|
+
from mettagrid.actions.move import Move
|
|
13
|
+
from mettagrid.actions.rotate import Rotate
|
|
14
|
+
from mettagrid.actions.use import Use
|
|
15
|
+
from mettagrid.actions.attack import Attack
|
|
16
|
+
from mettagrid.actions.shield import Shield
|
|
17
|
+
from mettagrid.actions.gift import Gift
|
|
18
|
+
|
|
19
|
+
cdef class MettaGrid(GridEnv):
|
|
20
|
+
cdef:
|
|
21
|
+
object _cfg
|
|
22
|
+
|
|
23
|
+
def __init__(self, cfg: OmegaConf, map: np.ndarray):
|
|
24
|
+
self._cfg = cfg
|
|
25
|
+
|
|
26
|
+
GridEnv.__init__(
|
|
27
|
+
self,
|
|
28
|
+
cfg.num_agents,
|
|
29
|
+
map.shape[1],
|
|
30
|
+
map.shape[0],
|
|
31
|
+
cfg.max_steps,
|
|
32
|
+
dict(ObjectLayers).values(),
|
|
33
|
+
cfg.obs_width, cfg.obs_height,
|
|
34
|
+
MettaObservationEncoder(),
|
|
35
|
+
[
|
|
36
|
+
Move(cfg.actions.move),
|
|
37
|
+
Rotate(cfg.actions.rotate),
|
|
38
|
+
Use(cfg.actions.use),
|
|
39
|
+
Attack(cfg.actions.attack),
|
|
40
|
+
Shield(cfg.actions.shield),
|
|
41
|
+
Gift(cfg.actions.gift),
|
|
42
|
+
],
|
|
43
|
+
[
|
|
44
|
+
ResetHandler()
|
|
45
|
+
]
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
cdef Agent *agent
|
|
50
|
+
for r in range(map.shape[0]):
|
|
51
|
+
for c in range(map.shape[1]):
|
|
52
|
+
if map[r,c] == "W":
|
|
53
|
+
self._grid.add_object(new Wall(r, c, cfg.objects.wall))
|
|
54
|
+
self._stats.game_incr("objects.wall")
|
|
55
|
+
elif map[r,c] == "g":
|
|
56
|
+
self._grid.add_object(new Generator(r, c, cfg.objects.generator))
|
|
57
|
+
self._stats.game_incr("objects.generator")
|
|
58
|
+
elif map[r,c] == "c":
|
|
59
|
+
self._grid.add_object(new Converter(r, c, cfg.objects.converter))
|
|
60
|
+
self._stats.game_incr("objects.converter")
|
|
61
|
+
elif map[r,c] == "a":
|
|
62
|
+
self._grid.add_object(new Altar(r, c, cfg.objects.altar))
|
|
63
|
+
self._stats.game_incr("objects.altar")
|
|
64
|
+
elif map[r,c][0] == "A":
|
|
65
|
+
agent = new Agent(r, c, cfg.objects.agent)
|
|
66
|
+
self._grid.add_object(agent)
|
|
67
|
+
self.add_agent(agent)
|
|
68
|
+
self._stats.game_incr("objects.agent")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def render(self):
|
|
72
|
+
grid = self.render_ascii(["A", "#", "g", "c", "a"])
|
|
73
|
+
for r in grid:
|
|
74
|
+
print("".join(r))
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def action_space(self):
|
|
78
|
+
return gym.spaces.MultiDiscrete((self.num_actions(), 10), dtype=np.uint32)
|