mettagrid 0.1.0__py3-none-any.whl → 0.1.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.
Files changed (83) hide show
  1. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/actions/actions.cpython-311-darwin.so +0 -0
  2. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/actions/attack.cpython-311-darwin.so +0 -0
  3. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/actions/attack_nearest.cpython-311-darwin.so +0 -0
  4. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/actions/change_color.cpython-311-darwin.so +0 -0
  5. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/actions/get_output.cpython-311-darwin.so +0 -0
  6. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/actions/move.cpython-311-darwin.so +0 -0
  7. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/actions/noop.cpython-311-darwin.so +0 -0
  8. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/actions/put_recipe_items.cpython-311-darwin.so +0 -0
  9. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/actions/rotate.cpython-311-darwin.so +0 -0
  10. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/actions/swap.cpython-311-darwin.so +0 -0
  11. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/grid_env.cpython-311-darwin.so +0 -0
  12. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/mettagrid_c.cpython-311-darwin.so +0 -0
  13. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/agent.cpython-311-darwin.so +0 -0
  14. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/altar.cpython-311-darwin.so +0 -0
  15. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/armory.cpython-311-darwin.so +0 -0
  16. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/constants.cpython-311-darwin.so +0 -0
  17. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/converter.cpython-311-darwin.so +0 -0
  18. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/factory.cpython-311-darwin.so +0 -0
  19. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/generator.cpython-311-darwin.so +0 -0
  20. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/lab.cpython-311-darwin.so +0 -0
  21. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/lasery.cpython-311-darwin.so +0 -0
  22. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/metta_object.cpython-311-darwin.so +0 -0
  23. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/mine.cpython-311-darwin.so +0 -0
  24. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/production_handler.cpython-311-darwin.so +0 -0
  25. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/objects/wall.cpython-311-darwin.so +0 -0
  26. build/lib.macosx-11.0-arm64-cpython-311/mettagrid/observation_encoder.cpython-311-darwin.so +0 -0
  27. build/mettagrid/actions/swap.cpp +85 -48
  28. build/mettagrid/grid_env.cpp +899 -768
  29. build/mettagrid/mettagrid.cpp +709 -468
  30. build/mettagrid/objects/agent.hpp +4 -0
  31. build/mettagrid/objects/constants.hpp +19 -10
  32. build/mettagrid/objects/converter.hpp +5 -1
  33. build/mettagrid/objects/generator.hpp +4 -0
  34. build/mettagrid/objects/metta_object.hpp +5 -1
  35. build/mettagrid/objects/mine.hpp +6 -0
  36. build/mettagrid/objects/wall.hpp +10 -0
  37. mettagrid/actions/actions.cpython-311-darwin.so +0 -0
  38. mettagrid/actions/attack.cpython-311-darwin.so +0 -0
  39. mettagrid/actions/attack_nearest.cpython-311-darwin.so +0 -0
  40. mettagrid/actions/change_color.cpython-311-darwin.so +0 -0
  41. mettagrid/actions/get_output.cpython-311-darwin.so +0 -0
  42. mettagrid/actions/move.cpython-311-darwin.so +0 -0
  43. mettagrid/actions/noop.cpython-311-darwin.so +0 -0
  44. mettagrid/actions/put_recipe_items.cpython-311-darwin.so +0 -0
  45. mettagrid/actions/rotate.cpython-311-darwin.so +0 -0
  46. mettagrid/actions/swap.cpython-311-darwin.so +0 -0
  47. mettagrid/actions/swap.pyx +9 -3
  48. mettagrid/config/config.py +14 -48
  49. mettagrid/grid_env.cpython-311-darwin.so +0 -0
  50. mettagrid/grid_env.pyx +4 -0
  51. mettagrid/mettagrid.pyx +14 -5
  52. mettagrid/mettagrid_c.cpython-311-darwin.so +0 -0
  53. mettagrid/mettagrid_env.py +57 -8
  54. mettagrid/objects/agent.cpython-311-darwin.so +0 -0
  55. mettagrid/objects/agent.hpp +4 -0
  56. mettagrid/objects/altar.cpython-311-darwin.so +0 -0
  57. mettagrid/objects/armory.cpython-311-darwin.so +0 -0
  58. mettagrid/objects/constants.cpython-311-darwin.so +0 -0
  59. mettagrid/objects/constants.hpp +19 -10
  60. mettagrid/objects/converter.cpython-311-darwin.so +0 -0
  61. mettagrid/objects/converter.hpp +5 -1
  62. mettagrid/objects/factory.cpython-311-darwin.so +0 -0
  63. mettagrid/objects/generator.cpython-311-darwin.so +0 -0
  64. mettagrid/objects/generator.hpp +4 -0
  65. mettagrid/objects/lab.cpython-311-darwin.so +0 -0
  66. mettagrid/objects/lasery.cpython-311-darwin.so +0 -0
  67. mettagrid/objects/metta_object.cpython-311-darwin.so +0 -0
  68. mettagrid/objects/metta_object.hpp +5 -1
  69. mettagrid/objects/metta_object.pxd +1 -0
  70. mettagrid/objects/mine.cpython-311-darwin.so +0 -0
  71. mettagrid/objects/mine.hpp +6 -0
  72. mettagrid/objects/production_handler.cpython-311-darwin.so +0 -0
  73. mettagrid/objects/wall.cpython-311-darwin.so +0 -0
  74. mettagrid/objects/wall.hpp +10 -0
  75. mettagrid/observation_encoder.cpython-311-darwin.so +0 -0
  76. mettagrid/renderer/raylib/object_render.py +2 -2
  77. mettagrid/renderer/raylib/raylib_renderer.py +1 -3
  78. {mettagrid-0.1.0.dist-info → mettagrid-0.1.1.dist-info}/METADATA +1 -1
  79. {mettagrid-0.1.0.dist-info → mettagrid-0.1.1.dist-info}/RECORD +83 -83
  80. tests/benchmark_env_perf.py +0 -3
  81. tests/test_basic.py +3 -0
  82. {mettagrid-0.1.0.dist-info → mettagrid-0.1.1.dist-info}/LICENSE +0 -0
  83. {mettagrid-0.1.0.dist-info → mettagrid-0.1.1.dist-info}/WHEEL +0 -0
@@ -93,6 +93,10 @@ public:
93
93
  this->current_resource_reward = new_reward;
94
94
  }
95
95
 
96
+ virtual bool swappable() const override {
97
+ return this->frozen;
98
+ }
99
+
96
100
  virtual void obs(ObsType* obs, const std::vector<unsigned int> &offsets) const override {
97
101
  obs[offsets[0]] = 1;
98
102
  obs[offsets[1]] = group;
@@ -33,18 +33,22 @@ enum ObjectType {
33
33
  };
34
34
 
35
35
  enum InventoryItem {
36
- ore = 0,
37
- battery = 1,
38
- heart = 2,
39
- armor = 3,
40
- laser = 4,
41
- blueprint = 5,
42
- InventoryCount = 6
36
+ ore_red = 0,
37
+ ore_blue =1,
38
+ ore_green = 2,
39
+ battery = 3,
40
+ heart = 4,
41
+ armor = 5,
42
+ laser = 6,
43
+ blueprint = 7,
44
+ InventoryCount = 8
43
45
  };
44
46
 
45
47
  // These should be const, but we run into type inference issues with cython
46
48
  std::vector<std::string> InventoryItemNames = {
47
- "ore",
49
+ "ore.red",
50
+ "ore.blue",
51
+ "ore.green",
48
52
  "battery",
49
53
  "heart",
50
54
  "armor",
@@ -55,8 +59,13 @@ std::vector<std::string> InventoryItemNames = {
55
59
  std::vector<std::string> ObjectTypeNames = {
56
60
  "agent",
57
61
  "wall",
58
- "mine",
59
- "generator",
62
+ "block",
63
+ "mine.red",
64
+ "mine.blue",
65
+ "mine.green",
66
+ "generator.red",
67
+ "generator.blue",
68
+ "generator.green",
60
69
  "altar",
61
70
  "armory",
62
71
  "lasery",
@@ -62,6 +62,7 @@ public:
62
62
  unsigned char cooldown; // Time to wait after producing before starting again
63
63
  bool converting; // Currently in production phase
64
64
  bool cooling_down; // Currently in cooldown phase
65
+ unsigned char color;
65
66
  EventManager *event_manager;
66
67
 
67
68
  Converter(GridCoord r, GridCoord c, ObjectConfig cfg, TypeId type_id) {
@@ -77,6 +78,7 @@ public:
77
78
  this->max_output = cfg["max_output"];
78
79
  this->conversion_ticks = cfg["conversion_ticks"];
79
80
  this->cooldown = cfg["cooldown"];
81
+ this->color = cfg.count("color") ? cfg["color"] : 0;
80
82
  this->converting = false;
81
83
  this->cooling_down = false;
82
84
 
@@ -130,7 +132,8 @@ public:
130
132
  void obs(ObsType *obs, const std::vector<unsigned int> &offsets) const override {
131
133
  obs[offsets[0]] = 1;
132
134
  obs[offsets[1]] = this->hp;
133
- obs[offsets[2]] = this->converting || this->cooling_down;
135
+ obs[offsets[2]] = this->color;
136
+ obs[offsets[3]] = this->converting || this->cooling_down;
134
137
  for (unsigned int i = 0; i < InventoryItem::InventoryCount; i++) {
135
138
  obs[offsets[3] + i] = this->inventory[i];
136
139
  }
@@ -143,6 +146,7 @@ public:
143
146
  // we expect converters to be hard coded.
144
147
  names.push_back("converter");
145
148
  names.push_back("hp");
149
+ names.push_back("color");
146
150
  names.push_back("converting");
147
151
  for (unsigned int i = 0; i < InventoryItem::InventoryCount; i++) {
148
152
  names.push_back("inv:" + InventoryItemNames[i]);
@@ -12,6 +12,10 @@ class Generator : public Converter {
12
12
  public:
13
13
  Generator(GridCoord r, GridCoord c, ObjectConfig cfg) : Converter(r, c, cfg, ObjectType::GeneratorT) {}
14
14
 
15
+ void obs(ObsType *obs, const std::vector<unsigned int> &offsets) const override {
16
+ Converter::obs(obs, offsets);
17
+ }
18
+
15
19
  static std::vector<std::string> feature_names() {
16
20
  auto names = Converter::feature_names();
17
21
  names[0] = "generator";
@@ -15,7 +15,11 @@ public:
15
15
  this->hp = cfg["hp"];
16
16
  }
17
17
 
18
- virtual bool has_inventory() {
18
+ virtual bool has_inventory() { // TODO: make const
19
+ return false;
20
+ }
21
+
22
+ virtual bool swappable() const {
19
23
  return false;
20
24
  }
21
25
  };
@@ -10,8 +10,13 @@
10
10
 
11
11
  class Mine : public Converter {
12
12
  public:
13
+
13
14
  Mine(GridCoord r, GridCoord c, ObjectConfig cfg) : Converter(r, c, cfg, ObjectType::MineT) {}
14
15
 
16
+ void obs(ObsType *obs, const std::vector<unsigned int> &offsets) const override {
17
+ Converter::obs(obs, offsets);
18
+ }
19
+
15
20
  static std::vector<std::string> feature_names() {
16
21
  auto names = Converter::feature_names();
17
22
  names[0] = "mine";
@@ -19,4 +24,5 @@ public:
19
24
  }
20
25
  };
21
26
 
27
+
22
28
  #endif
@@ -6,24 +6,34 @@
6
6
  #include "../grid_object.hpp"
7
7
  #include "constants.hpp"
8
8
  #include "metta_object.hpp"
9
+
9
10
  class Wall : public MettaObject {
10
11
  public:
12
+ bool _swappable;
13
+
11
14
  Wall(GridCoord r, GridCoord c, ObjectConfig cfg) {
12
15
  GridObject::init(ObjectType::WallT, GridLocation(r, c, GridLayer::Object_Layer));
13
16
  MettaObject::init_mo(cfg);
17
+ this->_swappable = cfg["swappable"];
14
18
  }
15
19
 
16
20
  virtual void obs(ObsType *obs, const std::vector<unsigned int> &offsets) const override {
17
21
  obs[offsets[0]] = 1;
18
22
  obs[offsets[1]] = this->hp;
23
+ obs[offsets[2]] = this->_swappable;
19
24
  }
20
25
 
21
26
  static std::vector<std::string> feature_names() {
22
27
  std::vector<std::string> names;
23
28
  names.push_back("wall");
24
29
  names.push_back("hp");
30
+ names.push_back("swappable");
25
31
  return names;
26
32
  }
33
+
34
+ virtual bool swappable() const override {
35
+ return this->_swappable;
36
+ }
27
37
  };
28
38
 
29
39
  #endif
@@ -9,6 +9,8 @@ from mettagrid.objects.agent cimport Agent
9
9
  from mettagrid.grid_object cimport GridLocation, GridObjectId, Orientation, GridObject
10
10
  from mettagrid.action cimport ActionHandler, ActionArg
11
11
  from mettagrid.actions.actions cimport MettaActionHandler
12
+ from mettagrid.objects.metta_object cimport MettaObject
13
+ from mettagrid.objects.constants cimport GridLayer
12
14
 
13
15
  cdef class Swap(MettaActionHandler):
14
16
  def __init__(self, cfg: OmegaConf):
@@ -25,13 +27,17 @@ cdef class Swap(MettaActionHandler):
25
27
 
26
28
  cdef GridLocation target_loc = self.env._grid.relative_location(
27
29
  actor.location,
28
- <Orientation>actor.orientation
30
+ <Orientation>actor.orientation
29
31
  )
30
- cdef Agent *target = <Agent*>self.env._grid.object_at(target_loc)
32
+ cdef MettaObject *target
33
+ target = <MettaObject*>self.env._grid.object_at(target_loc)
34
+ if target == NULL:
35
+ target_loc.layer = GridLayer.Object_Layer
36
+ target = <MettaObject*>self.env._grid.object_at(target_loc)
31
37
  if target == NULL:
32
38
  return False
33
39
 
34
- if not target.frozen:
40
+ if not target.swappable():
35
41
  return False
36
42
 
37
43
  self.env._grid.swap_objects(actor.id, target.id)
@@ -10,36 +10,28 @@ import warnings
10
10
 
11
11
  warnings.warn("This config.py file is deprecated", DeprecationWarning)
12
12
 
13
- def seed_everything(seed, torch_deterministic):
14
- random.seed(seed)
15
- np.random.seed(seed)
16
- if seed is not None:
17
- torch.manual_seed(seed)
18
- torch.backends.cudnn.deterministic = torch_deterministic
19
-
20
13
  def uniform(min_val, max_val, center, *, _root_):
21
- sampling = _root_.get("sampling", 0)
14
+ sampling = _root_["sampling"]
22
15
  if sampling == 0:
23
16
  return center
24
- else:
25
17
 
26
- center = (max_val + min_val) // 2
27
- # Calculate the available range on both sides of the center
28
- left_range = center - min_val
29
- right_range = max_val - center
18
+ center = (max_val + min_val) // 2
19
+ # Calculate the available range on both sides of the center
20
+ left_range = center - min_val
21
+ right_range = max_val - center
30
22
 
31
- # Scale the ranges based on the sampling parameter
32
- scaled_left = min(left_range, sampling * left_range)
33
- scaled_right = min(right_range, sampling * right_range)
23
+ # Scale the ranges based on the sampling parameter
24
+ scaled_left = min(left_range, sampling * left_range)
25
+ scaled_right = min(right_range, sampling * right_range)
34
26
 
35
- # Generate a random value within the scaled range
36
- val = np.random.uniform(center - scaled_left, center + scaled_right)
27
+ # Generate a random value within the scaled range
28
+ val = np.random.uniform(center - scaled_left, center + scaled_right)
37
29
 
38
- # Clip to ensure we stay within [min_val, max_val]
39
- val = np.clip(val, min_val, max_val)
30
+ # Clip to ensure we stay within [min_val, max_val]
31
+ val = np.clip(val, min_val, max_val)
40
32
 
41
- # Return integer if the original values were integers
42
- return int(round(val)) if isinstance(center, int) else val
33
+ # Return integer if the original values were integers
34
+ return int(round(val)) if isinstance(center, int) else val
43
35
 
44
36
  def choose(*args):
45
37
  return random.choice(args)
@@ -53,29 +45,3 @@ def sub(a, b):
53
45
  def make_odd(a):
54
46
  return max(3, a // 2 * 2 + 1)
55
47
 
56
- def setup_omega_conf():
57
- OmegaConf.register_new_resolver("div", div, replace=True)
58
- OmegaConf.register_new_resolver("uniform", uniform, replace=True)
59
- OmegaConf.register_new_resolver("sub", sub, replace=True)
60
- OmegaConf.register_new_resolver("make_odd", make_odd, replace=True)
61
- OmegaConf.register_new_resolver("choose", choose, replace=True)
62
-
63
- def setup_metta_environment(cfg):
64
- # Set environment variables to run without display
65
- os.environ['GLFW_PLATFORM'] = 'osmesa' # Use OSMesa as the GLFW backend
66
- os.environ['SDL_VIDEODRIVER'] = 'dummy'
67
- os.environ['MPLBACKEND'] = 'Agg'
68
- os.environ['PYGAME_HIDE_SUPPORT_PROMPT'] = '1'
69
- os.environ['DISPLAY'] = ''
70
-
71
- # Suppress deprecation warnings
72
- warnings.filterwarnings('ignore', category=DeprecationWarning)
73
- warnings.filterwarnings('ignore', category=DeprecationWarning, module='pkg_resources')
74
- warnings.filterwarnings('ignore', category=DeprecationWarning, module='pygame.pkgdata')
75
-
76
- setup_omega_conf()
77
- # print(OmegaConf.to_yaml(cfg))
78
- traceback.install(show_locals=False)
79
- seed_everything(cfg.seed, cfg.torch_deterministic)
80
- os.makedirs(cfg.run_dir, exist_ok=True)
81
- signal.signal(signal.SIGINT, lambda sig, frame: os._exit(0))
Binary file
mettagrid/grid_env.pyx CHANGED
@@ -16,6 +16,7 @@ from mettagrid.grid_object cimport (
16
16
  )
17
17
  from mettagrid.observation_encoder cimport ObservationEncoder, ObsType
18
18
  from mettagrid.objects.production_handler cimport ProductionHandler, CoolDownHandler
19
+ from mettagrid.objects.constants cimport ObjectTypeNames
19
20
 
20
21
  # Constants
21
22
  obs_np_type = np.uint8
@@ -309,3 +310,6 @@ cdef class GridEnv:
309
310
 
310
311
  def action_success(self):
311
312
  return self._action_success
313
+
314
+ def object_type_names(self):
315
+ return ObjectTypeNames
mettagrid/mettagrid.pyx CHANGED
@@ -114,11 +114,20 @@ cdef class MettaGrid(GridEnv):
114
114
  wall = new Wall(r, c, cfg.objects.wall)
115
115
  self._grid.add_object(wall)
116
116
  self._stats.incr(b"objects.wall")
117
-
118
- elif map[r,c] == "mine":
119
- converter = new Mine(r, c, cfg.objects.mine)
120
- elif map[r,c] == "generator":
121
- converter = new Generator(r, c, cfg.objects.generator)
117
+ elif map[r,c] == "block":
118
+ block = new Wall(r, c, cfg.objects.block)
119
+ self._grid.add_object(block)
120
+ self._stats.incr(b"objects.block")
121
+ elif map[r,c].startswith("mine"):
122
+ m = map[r,c]
123
+ if "." not in m:
124
+ m = "mine.red"
125
+ converter = new Mine(r, c, cfg.objects[m])
126
+ elif map[r,c].startswith("generator"):
127
+ m = map[r,c]
128
+ if "." not in m:
129
+ m = "generator.red"
130
+ converter = new Generator(r, c, cfg.objects[m])
122
131
  elif map[r,c] == "altar":
123
132
  converter = new Altar(r, c, cfg.objects.altar)
124
133
  elif map[r,c] == "armory":
Binary file
@@ -1,20 +1,22 @@
1
1
  import copy
2
+ import random
2
3
  from typing import Any, Dict
3
4
 
4
5
  import gymnasium as gym
5
6
  import hydra
6
7
  import numpy as np
7
- from mettagrid.config.config import setup_omega_conf
8
+ from torch import sub
9
+ from mettagrid.config.config import make_odd
8
10
  import pufferlib
9
11
  from omegaconf import OmegaConf, DictConfig
10
12
 
11
13
  from mettagrid.mettagrid_c import MettaGrid # pylint: disable=E0611
12
-
13
-
14
+ from mettagrid.config import config
15
+ from util.config import config_from_path
14
16
  class MettaGridEnv(pufferlib.PufferEnv, gym.Env):
15
17
  def __init__(self, env_cfg: DictConfig, render_mode: str, buf=None, **kwargs):
16
18
  self._render_mode = render_mode
17
- self._cfg = env_cfg
19
+ self._cfg_template = env_cfg
18
20
  self.make_env()
19
21
  self.should_reset = False
20
22
  self._renderer = None
@@ -22,8 +24,10 @@ class MettaGridEnv(pufferlib.PufferEnv, gym.Env):
22
24
  super().__init__(buf)
23
25
 
24
26
  def make_env(self):
25
- self._env_cfg = copy.deepcopy(self._cfg)
27
+ self._env_cfg = OmegaConf.create(copy.deepcopy(self._cfg_template))
28
+
26
29
  OmegaConf.resolve(self._env_cfg)
30
+
27
31
  self._map_builder = hydra.utils.instantiate(self._env_cfg.game.map_builder)
28
32
  env_map = self._map_builder.build()
29
33
  map_agents = np.count_nonzero(np.char.startswith(env_map, "agent"))
@@ -59,7 +63,7 @@ class MettaGridEnv(pufferlib.PufferEnv, gym.Env):
59
63
  self.actions[:] = np.array(actions).astype(np.uint32)
60
64
  self._c_env.step(self.actions)
61
65
 
62
- if self._cfg.normalize_rewards:
66
+ if self._env_cfg.normalize_rewards:
63
67
  self.rewards -= self.rewards.mean()
64
68
 
65
69
  infos = {}
@@ -157,12 +161,57 @@ class MettaGridEnv(pufferlib.PufferEnv, gym.Env):
157
161
  def action_success(self):
158
162
  return np.asarray(self._c_env.action_success())
159
163
 
164
+ def object_type_names(self):
165
+ return self._c_env.object_type_names()
166
+
160
167
  def close(self):
161
168
  pass
162
169
 
163
170
 
164
171
  def make_env_from_cfg(cfg_path: str, *args, **kwargs):
165
- setup_omega_conf()
166
- cfg = OmegaConf.load(cfg_path)
172
+ cfg = config_from_path(cfg_path)
167
173
  env = MettaGridEnv(cfg, *args, **kwargs)
168
174
  return env
175
+
176
+
177
+ def oc_uniform(min_val, max_val, center, *, _root_):
178
+ sampling = _root_.get("sampling", 0)
179
+ if sampling == 0:
180
+ return center
181
+ else:
182
+
183
+ center = (max_val + min_val) // 2
184
+ # Calculate the available range on both sides of the center
185
+ left_range = center - min_val
186
+ right_range = max_val - center
187
+
188
+ # Scale the ranges based on the sampling parameter
189
+ scaled_left = min(left_range, sampling * left_range)
190
+ scaled_right = min(right_range, sampling * right_range)
191
+
192
+ # Generate a random value within the scaled range
193
+ val = np.random.uniform(center - scaled_left, center + scaled_right)
194
+
195
+ # Clip to ensure we stay within [min_val, max_val]
196
+ val = np.clip(val, min_val, max_val)
197
+
198
+ # Return integer if the original values were integers
199
+ return int(round(val)) if isinstance(center, int) else val
200
+
201
+ def oc_choose(*args):
202
+ return random.choice(args)
203
+
204
+ def oc_div(a, b):
205
+ return a // b
206
+
207
+ def oc_sub(a, b):
208
+ return a - b
209
+
210
+ def oc_make_odd(a):
211
+ return max(3, a // 2 * 2 + 1)
212
+
213
+ OmegaConf.register_new_resolver("div", oc_div, replace=True)
214
+ OmegaConf.register_new_resolver("uniform", oc_uniform, replace=True)
215
+ OmegaConf.register_new_resolver("sub", oc_sub, replace=True)
216
+ OmegaConf.register_new_resolver("make_odd", oc_make_odd, replace=True)
217
+ OmegaConf.register_new_resolver("choose", oc_choose, replace=True)
@@ -93,6 +93,10 @@ public:
93
93
  this->current_resource_reward = new_reward;
94
94
  }
95
95
 
96
+ virtual bool swappable() const override {
97
+ return this->frozen;
98
+ }
99
+
96
100
  virtual void obs(ObsType* obs, const std::vector<unsigned int> &offsets) const override {
97
101
  obs[offsets[0]] = 1;
98
102
  obs[offsets[1]] = group;
@@ -33,18 +33,22 @@ enum ObjectType {
33
33
  };
34
34
 
35
35
  enum InventoryItem {
36
- ore = 0,
37
- battery = 1,
38
- heart = 2,
39
- armor = 3,
40
- laser = 4,
41
- blueprint = 5,
42
- InventoryCount = 6
36
+ ore_red = 0,
37
+ ore_blue =1,
38
+ ore_green = 2,
39
+ battery = 3,
40
+ heart = 4,
41
+ armor = 5,
42
+ laser = 6,
43
+ blueprint = 7,
44
+ InventoryCount = 8
43
45
  };
44
46
 
45
47
  // These should be const, but we run into type inference issues with cython
46
48
  std::vector<std::string> InventoryItemNames = {
47
- "ore",
49
+ "ore.red",
50
+ "ore.blue",
51
+ "ore.green",
48
52
  "battery",
49
53
  "heart",
50
54
  "armor",
@@ -55,8 +59,13 @@ std::vector<std::string> InventoryItemNames = {
55
59
  std::vector<std::string> ObjectTypeNames = {
56
60
  "agent",
57
61
  "wall",
58
- "mine",
59
- "generator",
62
+ "block",
63
+ "mine.red",
64
+ "mine.blue",
65
+ "mine.green",
66
+ "generator.red",
67
+ "generator.blue",
68
+ "generator.green",
60
69
  "altar",
61
70
  "armory",
62
71
  "lasery",
@@ -62,6 +62,7 @@ public:
62
62
  unsigned char cooldown; // Time to wait after producing before starting again
63
63
  bool converting; // Currently in production phase
64
64
  bool cooling_down; // Currently in cooldown phase
65
+ unsigned char color;
65
66
  EventManager *event_manager;
66
67
 
67
68
  Converter(GridCoord r, GridCoord c, ObjectConfig cfg, TypeId type_id) {
@@ -77,6 +78,7 @@ public:
77
78
  this->max_output = cfg["max_output"];
78
79
  this->conversion_ticks = cfg["conversion_ticks"];
79
80
  this->cooldown = cfg["cooldown"];
81
+ this->color = cfg.count("color") ? cfg["color"] : 0;
80
82
  this->converting = false;
81
83
  this->cooling_down = false;
82
84
 
@@ -130,7 +132,8 @@ public:
130
132
  void obs(ObsType *obs, const std::vector<unsigned int> &offsets) const override {
131
133
  obs[offsets[0]] = 1;
132
134
  obs[offsets[1]] = this->hp;
133
- obs[offsets[2]] = this->converting || this->cooling_down;
135
+ obs[offsets[2]] = this->color;
136
+ obs[offsets[3]] = this->converting || this->cooling_down;
134
137
  for (unsigned int i = 0; i < InventoryItem::InventoryCount; i++) {
135
138
  obs[offsets[3] + i] = this->inventory[i];
136
139
  }
@@ -143,6 +146,7 @@ public:
143
146
  // we expect converters to be hard coded.
144
147
  names.push_back("converter");
145
148
  names.push_back("hp");
149
+ names.push_back("color");
146
150
  names.push_back("converting");
147
151
  for (unsigned int i = 0; i < InventoryItem::InventoryCount; i++) {
148
152
  names.push_back("inv:" + InventoryItemNames[i]);
@@ -12,6 +12,10 @@ class Generator : public Converter {
12
12
  public:
13
13
  Generator(GridCoord r, GridCoord c, ObjectConfig cfg) : Converter(r, c, cfg, ObjectType::GeneratorT) {}
14
14
 
15
+ void obs(ObsType *obs, const std::vector<unsigned int> &offsets) const override {
16
+ Converter::obs(obs, offsets);
17
+ }
18
+
15
19
  static std::vector<std::string> feature_names() {
16
20
  auto names = Converter::feature_names();
17
21
  names[0] = "generator";
Binary file
@@ -15,7 +15,11 @@ public:
15
15
  this->hp = cfg["hp"];
16
16
  }
17
17
 
18
- virtual bool has_inventory() {
18
+ virtual bool has_inventory() { // TODO: make const
19
+ return false;
20
+ }
21
+
22
+ virtual bool swappable() const {
19
23
  return false;
20
24
  }
21
25
  };
@@ -9,3 +9,4 @@ cdef extern from "metta_object.hpp":
9
9
  unsigned int hp
10
10
  void init_mo(ObjectConfig cfg)
11
11
  bint has_inventory()
12
+ bint swappable()
@@ -10,8 +10,13 @@
10
10
 
11
11
  class Mine : public Converter {
12
12
  public:
13
+
13
14
  Mine(GridCoord r, GridCoord c, ObjectConfig cfg) : Converter(r, c, cfg, ObjectType::MineT) {}
14
15
 
16
+ void obs(ObsType *obs, const std::vector<unsigned int> &offsets) const override {
17
+ Converter::obs(obs, offsets);
18
+ }
19
+
15
20
  static std::vector<std::string> feature_names() {
16
21
  auto names = Converter::feature_names();
17
22
  names[0] = "mine";
@@ -19,4 +24,5 @@ public:
19
24
  }
20
25
  };
21
26
 
27
+
22
28
  #endif