Skip to content
This repository was archived by the owner on Apr 3, 2026. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
106 commits
Select commit Hold shift + click to select a range
dde3dcd
poisson distribution class
daphnedemekas Mar 31, 2025
5d7bf9f
update mean distance if bigger than width or height
daphnedemekas Mar 31, 2025
332a15e
varied obstacles
Apr 2, 2025
fcb5b5e
env selector
daphnedemekas Apr 2, 2025
dba1751
Merge branch 'main' of https://github.com/Metta-AI/mettagrid into tra…
daphnedemekas Apr 2, 2025
887b8dc
mettagrid env set
daphnedemekas Apr 3, 2025
7548ec3
remove print statement
daphnedemekas Apr 3, 2025
2673783
Update mettagrid.yaml
daphnedemekas Apr 3, 2025
5557b2e
Delete mettagrid/objects/metta.code-workspace
daphnedemekas Apr 3, 2025
60ebd22
Update mettagrid_env.py
daphnedemekas Apr 3, 2025
085a991
Update mettagrid_env.py
daphnedemekas Apr 3, 2025
cdf4ed4
Update mettagrid_env.py
daphnedemekas Apr 3, 2025
fc0704a
rename poisson
daphnedemekas Apr 3, 2025
8333fe0
while loop for mean distance
daphnedemekas Apr 4, 2025
1517635
Merge branch 'training-suite' of https://github.com/Metta-AI/mettagri…
daphnedemekas Apr 4, 2025
e631aec
varied terrain labyrnths file\
Apr 10, 2025
33b96c6
Delete mettagrid/config/room/cognitive_evals/cylinder.py
daphnedemekas Apr 10, 2025
3e3f795
Delete mettagrid/config/room/obstacle_shapes.py
daphnedemekas Apr 10, 2025
9bbf107
Delete mettagrid/terrain.py
daphnedemekas Apr 10, 2025
feceea1
python file varied terrain changes
daphnedemekas Apr 11, 2025
74096d4
Merge branch 'george-navigation-training' of https://github.com/Metta…
daphnedemekas Apr 11, 2025
ccf3307
blocky diverse terrain python file
Apr 12, 2025
564bac7
new varied terrains
daphnedemekas Apr 12, 2025
8e93f08
update varied terrain
daphnedemekas Apr 12, 2025
9e964fd
update varied terrain
daphnedemekas Apr 12, 2025
caaca1c
varied terrain
daphnedemekas Apr 12, 2025
a315662
speedupg
daphnedemekas Apr 12, 2025
d4b81db
speedupg
daphnedemekas Apr 12, 2025
674b488
less hearts
daphnedemekas Apr 12, 2025
4927a3d
make dense denser
daphnedemekas Apr 12, 2025
30ca27d
merge main
daphnedemekas Apr 14, 2025
ebc3582
merge main
daphnedemekas Apr 14, 2025
e134340
more labyrnthy
daphnedemekas Apr 14, 2025
96f52d7
update labyrinths
daphnedemekas Apr 15, 2025
8ca3060
merge main
daphnedemekas Apr 16, 2025
5a95d75
Update map_from_file.py
daphnedemekas Apr 16, 2025
099cad0
import random
daphnedemekas Apr 16, 2025
e1533c0
import random
daphnedemekas Apr 16, 2025
9d14f31
num hearts
daphnedemekas Apr 16, 2025
c627445
fractal cylinder map gen script
lars-sandved Apr 16, 2025
9ce6f9e
map gen script
lars-sandved Apr 16, 2025
e9ed588
Merge branch 'lars-fractal-cylinders-mettagrid' of https://github.com…
daphnedemekas Apr 16, 2025
b4970ea
download data from s3
daphnedemekas Apr 16, 2025
a6d63f6
change bucketname
daphnedemekas Apr 16, 2025
297e030
try with allow pickle on aws
daphnedemekas Apr 16, 2025
f22c05d
Merge branch 'main' of https://github.com/Metta-AI/mettagrid into geo…
Apr 17, 2025
19fb0cc
Merge branch 'george-navigation-training' of https://github.com/Metta…
Apr 17, 2025
4b2fb6f
update mettagridenvset
daphnedemekas Apr 17, 2025
8d9beb1
Merge branch 'main' into daphne-prioritized-env-replay
daphnedemekas Apr 17, 2025
586dfe2
Delete mettagrid/config/room/fractal_cylinder.py
daphnedemekas Apr 17, 2025
886e9c0
terrain generator with cylinders
Apr 18, 2025
1062e31
Merge branch 'george-navigation-training' of https://github.com/Metta…
Apr 18, 2025
de92a18
Merge branch 'main' of https://github.com/Metta-AI/mettagrid into geo…
Apr 18, 2025
d177d83
update configs
daphnedemekas Apr 18, 2025
fc0699b
Merge branch 'george-navigation-training' of https://github.com/Metta…
Apr 18, 2025
3ff22dd
Merge branch 'main' of https://github.com/Metta-AI/mettagrid into geo…
daphnedemekas Apr 18, 2025
4375a47
Merge branch 'main' of https://github.com/Metta-AI/mettagrid into geo…
daphnedemekas Apr 20, 2025
86089c2
Revert "Move metta_action_handler into action_handler (#107)"
daphnedemekas Apr 20, 2025
54aacac
Merge branch 'revert-107-04-18-moving_metta_action_handler_into_actio…
daphnedemekas Apr 20, 2025
c73ab4a
merge main
daphnedemekas Apr 20, 2025
19d0589
keep current version
daphnedemekas Apr 20, 2025
a56f4ae
Merge branch 'george-navigation-training' of https://github.com/Metta…
Apr 20, 2025
a74695d
update cylinder world
Apr 20, 2025
bc9513d
labyrinth world
Apr 20, 2025
8acdddf
hardcode width and height sampling
daphnedemekas Apr 21, 2025
757fc84
Merge branch 'main' of https://github.com/Metta-AI/mettagrid into geo…
daphnedemekas Apr 21, 2025
069c82e
Update action_handler.pxd
daphnedemekas Apr 21, 2025
69cc3db
Update action_handler.pyx
daphnedemekas Apr 21, 2025
3dad0c9
Update attack.pxd
daphnedemekas Apr 21, 2025
b7abc3e
Update attack.pyx
daphnedemekas Apr 21, 2025
0d023e6
Update change_color.pxd
daphnedemekas Apr 21, 2025
4d353a0
Update change_color.pyx
daphnedemekas Apr 21, 2025
07cc173
Update get_output.pxd
daphnedemekas Apr 21, 2025
fafb76a
Update get_output.pyx
daphnedemekas Apr 21, 2025
f584555
Delete mettagrid/actions/metta_action_handler.pxd
daphnedemekas Apr 21, 2025
2fafc66
Delete mettagrid/actions/metta_action_handler.pyx
daphnedemekas Apr 21, 2025
4dd4c28
Update move.pxd
daphnedemekas Apr 21, 2025
2360b8c
Update move.pyx
daphnedemekas Apr 21, 2025
c397129
Update noop.pxd
daphnedemekas Apr 21, 2025
63fdef2
Update noop.pyx
daphnedemekas Apr 21, 2025
f655f14
Update put_recipe_items.pxd
daphnedemekas Apr 21, 2025
48391ad
Update put_recipe_items.pyx
daphnedemekas Apr 21, 2025
f9984da
Update rotate.pxd
daphnedemekas Apr 21, 2025
30a0e0e
Update rotate.pyx
daphnedemekas Apr 21, 2025
3ca0d04
Update swap.pxd
daphnedemekas Apr 21, 2025
9ebe0f9
Update swap.pyx
daphnedemekas Apr 21, 2025
27a54bc
Update test_basic.py
daphnedemekas Apr 21, 2025
98cb256
Update setup.py
daphnedemekas Apr 21, 2025
1632a16
ruff
daphnedemekas Apr 21, 2025
a2fb866
add generators
daphnedemekas Apr 21, 2025
7f46472
allow option to add generators and sampl eagnets
daphnedemekas Apr 21, 2025
e529f8e
safe loading
daphnedemekas Apr 21, 2025
2759a41
new maps
Apr 22, 2025
c1372bc
Merge branch 'george-navigation-training' of https://github.com/Metta…
Apr 22, 2025
dbb47de
fix width and height
Apr 22, 2025
33c9d37
'corrections'
Apr 22, 2025
182cd90
update mettagrid env format
daphnedemekas Apr 22, 2025
2af32a3
en vset
daphnedemekas Apr 22, 2025
d1e022a
50 hearts
daphnedemekas Apr 22, 2025
436ec30
merge
daphnedemekas Apr 22, 2025
5274347
prioritized multienv
daphnedemekas Apr 22, 2025
d7a494b
updated worlds
Apr 22, 2025
0b92781
new files
Apr 22, 2025
13d3c07
Merge branch 'george-navigation-training' of https://github.com/Metta…
Apr 22, 2025
c3281c2
Merge branch 'george-navigation-training' of https://github.com/Metta…
daphnedemekas Apr 22, 2025
0321969
back to sampling numhearts
daphnedemekas Apr 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
147 changes: 147 additions & 0 deletions mettagrid/config/room/box_world.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
"""
BoxWorld
========

Densely fills the map with rectangular *boxes*:

* Interior rectangle; one side is guaranteed ≥ 8 cells.
* Walls 1‑cell thick.
* A single *entrance* (one gap) sits at a randomly chosen corner.
* A single heart **altar** sits in the *diagonally opposite* corner.
* Boxes are stamped until 10 consecutive placement failures, then agents
are spawned in the remaining open corridors.

Parameters (override in YAML `room:` block if desired):

short_range – inclusive (min, max) for interior short side
elong_range – inclusive (min_add, max_add) added to short → long side
"""

from typing import List, Optional, Tuple

import numpy as np
from mettagrid.config.room.room import Room


class BoxWorld(Room):
STYLE_PARAMETERS = {"box_world": {"hearts_count": 0}}

# ------------------------------------------------------------------ #
# Init
# ------------------------------------------------------------------ #
def __init__(
self,
width: int = 120,
height: int = 120,
agents: int | dict = 0,
short_range: Tuple[int, int] = (4, 6), # interior short side
elong_range: Tuple[int, int] = (4, 8), # + add to short → long
seed: Optional[int] = 42,
border_width: int = 2,
border_object: str = "wall",
):
super().__init__(border_width=border_width, border_object=border_object)
self._rng = np.random.default_rng(seed)
self._width, self._height = np.random.randint(40,100), np.random.randint(40,100)
self._agents = agents
self._occ = np.zeros((height, width), dtype=bool)
self.short_min, self.short_max = short_range
self.elong_min, self.elong_max = elong_range

# ------------------------------------------------------------------ #
# Public build
# ------------------------------------------------------------------ #
def _build(self):
grid = np.full((self._height, self._width), "empty", dtype=object)
fails = 0
while fails < 10: # pack until space gone
if self._place_box(grid, clearance=1):
fails = 0
else:
fails += 1
return self._place_agents(grid)

# ------------------------------------------------------------------ #
# Box helpers
# ------------------------------------------------------------------ #
def _place_box(self, grid, clearance: int) -> bool:
pattern = self._generate_box()
return self._place_region(grid, pattern, clearance)

def _generate_box(self) -> np.ndarray:
# --- choose interior dimensions -------------------------------- #
short = int(self._rng.integers(self.short_min, self.short_max + 1))
long_add = int(self._rng.integers(self.elong_min, self.elong_max + 1))
long_side = max(short + long_add, 8) # ensure ≥ 8 somewhere

horiz = self._rng.random() < 0.5
h_int, w_int = (short, long_side) if horiz else (long_side, short)

h, w = h_int + 2, w_int + 2 # +2 for walls
pat = np.full((h, w), "wall", dtype=object)
pat[1:-1, 1:-1] = "empty"

# pick entrance corner, altar opposite
corners = [(1, 1), (1, w - 2), (h - 2, 1), (h - 2, w - 2)]
entrance = corners[self._rng.integers(4)]
altar = corners[(corners.index(entrance) + 2) % 4]
er, ec = entrance

pat[altar] = "altar"

# carve a single gap adjacent to the entrance corner
gaps = []
if er == 1: gaps.append((0, ec)) # top wall
if er == h - 2: gaps.append((h - 1, ec)) # bottom wall
if ec == 1: gaps.append((er, 0)) # left wall
if ec == w - 2: gaps.append((er, w - 1)) # right wall
gap = gaps[self._rng.integers(len(gaps))]
pat[gap] = "empty"
return pat

# ------------------------------------------------------------------ #
# Agent placement
# ------------------------------------------------------------------ #
def _place_agents(self, grid):
tags = (
["agent.agent"] * self._agents
if isinstance(self._agents, int)
else ["agent." + n for n, k in self._agents.items() for _ in range(k)]
)
for t in tags:
pos = self._rand_empty()
if pos:
grid[pos] = t
self._occ[pos] = True
return grid

# ------------------------------------------------------------------ #
# Generic helpers (same as LabyrinthWorld)
# ------------------------------------------------------------------ #
def _place_region(self, grid, pat, clearance: int) -> bool:
ph, pw = pat.shape
for r, c in self._free_windows((ph + 2 * clearance, pw + 2 * clearance)):
grid[r + clearance : r + clearance + ph,
c + clearance : c + clearance + pw] = pat
self._occ[r : r + ph + 2 * clearance,
c : c + pw + 2 * clearance] = True
return True
return False

def _free_windows(self, shape) -> List[Tuple[int, int]]:
h, w = shape
H, W = self._occ.shape
if h > H or w > W:
return []
view = np.lib.stride_tricks.as_strided(
self._occ, (H - h + 1, W - w + 1, h, w), self._occ.strides * 2
)
coords = np.argwhere(view.sum(axis=(2, 3)) == 0)
self._rng.shuffle(coords)
return [tuple(t) for t in coords]

def _rand_empty(self):
empties = np.flatnonzero(~self._occ)
return None if empties.size == 0 else tuple(
np.unravel_index(self._rng.integers(empties.size), self._occ.shape)
)
126 changes: 126 additions & 0 deletions mettagrid/config/room/cubicle_world.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
"""
CubicleWorld
=============

Creates a cubicle of full‑length walls: vertical lines from top‑to‑bottom and
horizontal lines from left‑to‑right. Interior rectangles of empty space are the
“cubicles.” Door‑sized openings are carved in each interior wall.

The outermost perimeter is always a solid wall, ensuring the arena is fully enclosed.

Episode‑time random sampling
----------------------------
* env_width, env_height ← uniform int samples from width_range / height_range
* gap_x, gap_y ← uniform int samples from gap_range (4‑14)

Wall coordinates:
vertical walls at 0, gap_x+1, 2*(gap_x+1), …, width‑1
horizontal walls at 0, gap_y+1, 2*(gap_y+1), …, height‑1
"""

from __future__ import annotations
from typing import Sequence
import numpy as np
from mettagrid.config.room.room import Room



class CubicleWorld(Room):
STYLE_PARAMETERS = {"cubicle": {"hearts_count": 0}}

def __init__(
self,
width_range: Sequence[int] = (120, 320),
height_range: Sequence[int] = (120, 320),
gap_range: Sequence[int] = (4, 14),
altars_count: int = 50,
agents: int | dict = 20,
seed: int | None = 42,
border_object: str = "wall",
border_width: int = 6
):
"""
Initialize a CubicleWorld environment.
"""
super().__init__(border_width = border_width, border_object=border_object)
rng = np.random.default_rng(seed)

self.width = np.random.randint(width_range[0], width_range[1])
self.height = np.random.randint(height_range[0], height_range[1])
self.gap_x = np.random.randint(gap_range[0], gap_range[1])
self.gap_y = np.random.randint(gap_range[0], gap_range[1])

self.altars_count = altars_count
self._agents = agents
self._rng = rng

# --------------------------------------------------------------- #
def _build(self):
grid = self._generate_grid()
self._place_altars(grid)
self._place_agents(grid)
return grid

# --------------------------------------------------------------- #
def _generate_grid(self) -> np.ndarray:
H, W = self.height, self.width
grid = np.full((H, W), "empty", dtype=object)

# Draw vertical full‑height walls
col = 0
while col < W:
grid[:, col] = "wall"
col += self.gap_x + 1

# Draw horizontal full‑width walls
row = 0
while row < H:
grid[row, :] = "wall"
row += self.gap_y + 1

# Carve door‑sized breaks in every interior wall
# Vertical walls: skip borders (col == 0 or col == W‑1)
for col in range(self.gap_x + 1, W - 1, self.gap_x + 1):
for row_start in range(0, H, self.gap_y + 1):
if row_start + self.gap_y < H:
door_row = row_start + 1 + self._rng.integers(self.gap_y)
grid[door_row, col] = "empty"

# Horizontal walls: skip borders (row == 0 or row == H‑1)
for row in range(self.gap_y + 1, H - 1, self.gap_y + 1):
for col_start in range(0, W, self.gap_x + 1):
if col_start + self.gap_x < W:
door_col = col_start + 1 + self._rng.integers(self.gap_x)
grid[row, door_col] = "empty"

# Ensure the outer perimeter is a solid wall
grid[0, :] = "wall"
grid[-1, :] = "wall"
grid[:, 0] = "wall"
grid[:, -1] = "wall"

# Occupancy mask for placement
self._occ = np.zeros((H, W), dtype=bool)
return grid

# --------------------------------------------------------------- #
def _place_altars(self, grid: np.ndarray):
empties = list(zip(*np.where(grid == "empty")))
self._rng.shuffle(empties)
for pos in empties[: self.altars_count]:
grid[pos] = "altar"
self._occ[pos] = True

def _place_agents(self, grid: np.ndarray):
# build tag list
if isinstance(self._agents, int):
tags = ["agent.agent"] * self._agents
else:
tags = ["agent." + t for t, n in self._agents.items() for _ in range(n)]

empties = np.flatnonzero((grid == "empty") & (~self._occ))
self._rng.shuffle(empties)
for tag, idx in zip(tags, empties):
pos = tuple(np.unravel_index(idx, grid.shape))
grid[pos] = tag
self._occ[pos] = True
111 changes: 111 additions & 0 deletions mettagrid/config/room/cubicle_world_uniform.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
"""
CubicleUniformWorld
===================

Variant of *CubicleWorld* in which every interior wall has a single door
**exactly at the midpoint** of the wall segment, producing perfectly aligned
corridors between adjacent cubicles.
"""

from __future__ import annotations
from typing import Sequence
import numpy as np

from mettagrid.config.room.room import Room


class CubicleUniformWorld(Room):
STYLE_PARAMETERS = {"cubicle_uniform": {"hearts_count": 0}}

# ------------------------------------------------------------------ #
def __init__(
self,
width_range: Sequence[int] = (120, 320),
height_range: Sequence[int] = (120, 320),
gap_range: Sequence[int] = (4, 14),
altars_count: int = 50,
agents: int | dict = 20,
seed: int | None = 42,
border_object: str = "wall",
):
super().__init__(border_object=border_object)
rng = np.random.default_rng(seed)

self.width = rng.integers(width_range[0], width_range[1])
self.height = rng.integers(height_range[0], height_range[1])
self.gap_x = rng.integers(gap_range[0], gap_range[1])
self.gap_y = rng.integers(gap_range[0], gap_range[1])

self.altars_count = altars_count
self._agents = agents
self._rng = rng

# ------------------------------------------------------------------ #
def _build(self):
grid = self._generate_grid()
self._place_altars(grid)
self._place_agents(grid)
return grid

# ------------------------------------------------------------------ #
def _generate_grid(self) -> np.ndarray:
"""Create the cubicle lattice with centred doors."""
H, W = self.height, self.width
grid = np.full((H, W), "empty", dtype=object)

# Draw vertical full‑height walls
col = 0
while col < W:
grid[:, col] = "wall"
col += self.gap_x + 1

# Draw horizontal full‑width walls
row = 0
while row < H:
grid[row, :] = "wall"
row += self.gap_y + 1

# Carve centred doors in vertical walls (skip outer perimeter)
for col in range(self.gap_x + 1, W - 1, self.gap_x + 1):
row_start = 0
while row_start + self.gap_y < H:
door_row = row_start + 1 + self.gap_y // 2
grid[door_row, col] = "empty"
row_start += self.gap_y + 1

# Carve centred doors in horizontal walls
for row in range(self.gap_y + 1, H - 1, self.gap_y + 1):
col_start = 0
while col_start + self.gap_x < W:
door_col = col_start + 1 + self.gap_x // 2
grid[row, door_col] = "empty"
col_start += self.gap_x + 1

# Ensure solid outer perimeter
grid[0, :] = grid[-1, :] = "wall"
grid[:, 0] = grid[:, -1] = "wall"

# Occupancy mask
self._occ = np.zeros((H, W), dtype=bool)
return grid

# ------------------------------------------------------------------ #
def _place_altars(self, grid: np.ndarray):
empties = list(zip(*np.where(grid == "empty")))
self._rng.shuffle(empties)
for pos in empties[: self.altars_count]:
grid[pos] = "altar"
self._occ[pos] = True

def _place_agents(self, grid: np.ndarray):
tags = (
["agent.agent"] * self._agents
if isinstance(self._agents, int)
else ["agent." + t for t, n in self._agents.items() for _ in range(n)]
)
empties = np.flatnonzero((grid == "empty") & (~self._occ))
self._rng.shuffle(empties)
for tag, idx in zip(tags, empties):
pos = tuple(np.unravel_index(idx, grid.shape))
grid[pos] = tag
self._occ[pos] = True
Loading