miniworld-maze 1.3.1__py3-none-any.whl → 1.4.0__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 miniworld-maze might be problematic. Click here for more details.

@@ -25,7 +25,7 @@ if "PYGLET_HEADLESS" not in os.environ:
25
25
  "Automatically set PYGLET_HEADLESS=1 for headless rendering. "
26
26
  "Set PYGLET_HEADLESS=0 before importing miniworld_maze to override this behavior.",
27
27
  UserWarning,
28
- stacklevel=2
28
+ stacklevel=2,
29
29
  )
30
30
 
31
31
  from .core import ObservationLevel
@@ -33,10 +33,6 @@ from .environments.nine_rooms import NineRooms
33
33
  from .environments.spiral_nine_rooms import SpiralNineRooms
34
34
  from .environments.twenty_five_rooms import TwentyFiveRooms
35
35
 
36
- # Import factory to register environments
37
- from .environments import factory # noqa: F401
38
-
39
- __version__ = "1.1.0"
40
36
  __all__ = [
41
37
  "NineRooms",
42
38
  "SpiralNineRooms",
@@ -60,6 +60,7 @@ DEFAULT_WARMUP_STEPS: Final[int] = 10
60
60
  # TEXTURE THEMES
61
61
  # ========================
62
62
 
63
+
63
64
  class TextureThemes:
64
65
  """Pre-defined texture themes for different environments."""
65
66
 
@@ -116,7 +117,6 @@ class TextureThemes:
116
117
  ]
117
118
 
118
119
 
119
-
120
120
  # ========================
121
121
  # RENDERING CONSTANTS
122
122
  # ========================
@@ -9,29 +9,71 @@ import gymnasium as gym
9
9
  import numpy as np
10
10
  import pyglet
11
11
  from gymnasium import spaces
12
- from pyglet.gl import *
13
-
14
- from ..observation_types import ObservationLevel
15
- from .entities import *
16
- from .math import *
17
- from .objmesh import *
18
- from .occlusion_queries import OcclusionQueryManager
19
- from .opengl import *
20
- from .params import DEFAULT_PARAMS
21
- from .random import RandGen
22
- from .room import Room
12
+ from pyglet.gl import (
13
+ glEnable,
14
+ glDeleteLists,
15
+ glNewList,
16
+ glLightfv,
17
+ glShadeModel,
18
+ glColorMaterial,
19
+ glCallList,
20
+ glClearColor,
21
+ glClearDepth,
22
+ glClear,
23
+ glMatrixMode,
24
+ glLoadIdentity,
25
+ glOrtho,
26
+ glLoadMatrixf,
27
+ glDisable,
28
+ glBindFramebuffer,
29
+ glFlush,
30
+ glEndList,
31
+ gluPerspective,
32
+ gluLookAt,
33
+ GL_DEPTH_TEST,
34
+ GL_CULL_FACE,
35
+ GL_COMPILE,
36
+ GL_LIGHT0,
37
+ GL_POSITION,
38
+ GL_AMBIENT,
39
+ GL_DIFFUSE,
40
+ GL_SMOOTH,
41
+ GL_FRONT_AND_BACK,
42
+ GL_AMBIENT_AND_DIFFUSE,
43
+ GL_LIGHTING,
44
+ GL_COLOR_MATERIAL,
45
+ GL_COLOR_BUFFER_BIT,
46
+ GL_DEPTH_BUFFER_BIT,
47
+ GL_PROJECTION,
48
+ GL_MODELVIEW,
49
+ GL_TEXTURE_2D,
50
+ GL_FRAMEBUFFER,
51
+ GLubyte,
52
+ GLfloat,
53
+ )
54
+
55
+ from miniworld_maze.core.observation_types import ObservationLevel
56
+ from miniworld_maze.core.miniworld_gymnasium.entities import Entity, Agent
57
+ from miniworld_maze.core.miniworld_gymnasium.math import Y_VEC, intersect_circle_segs
58
+ from miniworld_maze.core.miniworld_gymnasium.occlusion_queries import (
59
+ OcclusionQueryManager,
60
+ )
61
+ from miniworld_maze.core.miniworld_gymnasium.opengl import Texture, FrameBuffer, drawBox
62
+ from miniworld_maze.core.miniworld_gymnasium.params import DEFAULT_PARAMS
63
+ from miniworld_maze.core.miniworld_gymnasium.random import RandGen
64
+ from miniworld_maze.core.miniworld_gymnasium.room import Room
23
65
 
24
66
  # Optional architectural improvements
25
67
  try:
26
- from .entity_manager import EntityManager
27
- from .rendering_engine import RenderingEngine
68
+ from miniworld_maze.core.miniworld_gymnasium.entity_manager import EntityManager
69
+ from miniworld_maze.core.miniworld_gymnasium.rendering_engine import RenderingEngine
28
70
 
29
71
  ARCHITECTURAL_IMPROVEMENTS_AVAILABLE = True
30
72
  except ImportError:
31
73
  RenderingEngine = None
32
74
  EntityManager = None
33
75
  ARCHITECTURAL_IMPROVEMENTS_AVAILABLE = False
34
- from ..constants import (
76
+ from miniworld_maze.core.constants import (
35
77
  CARRY_POSITION_OFFSET,
36
78
  DEFAULT_DISPLAY_WIDTH,
37
79
  DEFAULT_WINDOW_HEIGHT,
@@ -47,6 +89,7 @@ from ..constants import (
47
89
  ORTHOGRAPHIC_DEPTH_RANGE,
48
90
  PICKUP_RADIUS_MULTIPLIER,
49
91
  PICKUP_REACH_MULTIPLIER,
92
+ POMDP_VIEW_RADIUS,
50
93
  PORTAL_CONNECTION_TOLERANCE,
51
94
  TEXT_LABEL_WIDTH,
52
95
  TEXT_MARGIN_X,
@@ -363,8 +406,6 @@ class UnifiedMiniWorldEnv(gym.Env):
363
406
  render_agent: Whether to render the agent in the observation.
364
407
  If None, uses default behavior based on observation level.
365
408
  """
366
- # Import ObservationLevel here to avoid circular imports
367
- from ..observation_types import ObservationLevel
368
409
 
369
410
  if observation_level == ObservationLevel.TOP_DOWN_PARTIAL:
370
411
  if self.agent_mode == "empty":
@@ -1039,9 +1080,6 @@ class UnifiedMiniWorldEnv(gym.Env):
1039
1080
  def _calculate_scene_extents(self, POMDP):
1040
1081
  """Calculate scene extents for rendering."""
1041
1082
  if POMDP:
1042
- # Import constants for POMDP view radius
1043
- from ..constants import POMDP_VIEW_RADIUS
1044
-
1045
1083
  agent_x, _, agent_z = self.agent.pos
1046
1084
  min_x = agent_x - POMDP_VIEW_RADIUS
1047
1085
  max_x = agent_x + POMDP_VIEW_RADIUS
@@ -1287,9 +1325,6 @@ class UnifiedMiniWorldEnv(gym.Env):
1287
1325
  if view == "agent":
1288
1326
  img = self.render_obs(self.vis_fb)
1289
1327
  else:
1290
- # Import ObservationLevel here to avoid circular imports
1291
- from ..observation_types import ObservationLevel
1292
-
1293
1328
  if self.obs_level == ObservationLevel.TOP_DOWN_PARTIAL:
1294
1329
  img = self.render_top_view(self.vis_fb, POMDP=True)
1295
1330
  else:
@@ -1,9 +1,13 @@
1
1
  """Nine Rooms environment implementations."""
2
2
 
3
- from .base_grid_rooms import GridRoomsEnvironment
4
- from .nine_rooms import NineRooms
5
- from .spiral_nine_rooms import SpiralNineRooms
6
- from .twenty_five_rooms import TwentyFiveRooms
3
+ from miniworld_maze.environments.base_grid_rooms import GridRoomsEnvironment
4
+ from miniworld_maze.environments.nine_rooms import NineRooms
5
+ from miniworld_maze.environments.spiral_nine_rooms import SpiralNineRooms
6
+ from miniworld_maze.environments.twenty_five_rooms import TwentyFiveRooms
7
+
8
+ from gymnasium.envs.registration import register
9
+ from miniworld_maze.core import ObservationLevel
10
+ from miniworld_maze.core.constants import FACTORY_DOOR_SIZE, FACTORY_ROOM_SIZE
7
11
 
8
12
  __all__ = [
9
13
  "GridRoomsEnvironment",
@@ -11,3 +15,40 @@ __all__ = [
11
15
  "SpiralNineRooms",
12
16
  "TwentyFiveRooms",
13
17
  ]
18
+
19
+ # Register environment variants with factory defaults matching the original wrapper
20
+ register(
21
+ id="NineRooms-v0",
22
+ entry_point="miniworld_maze.environments.nine_rooms:NineRooms",
23
+ max_episode_steps=1000,
24
+ kwargs={
25
+ "room_size": FACTORY_ROOM_SIZE,
26
+ "door_size": FACTORY_DOOR_SIZE,
27
+ "obs_level": ObservationLevel.TOP_DOWN_PARTIAL,
28
+ "agent_mode": None, # becomes "empty" by default
29
+ },
30
+ )
31
+
32
+ register(
33
+ id="SpiralNineRooms-v0",
34
+ entry_point="miniworld_maze.environments.spiral_nine_rooms:SpiralNineRooms",
35
+ max_episode_steps=1000,
36
+ kwargs={
37
+ "room_size": FACTORY_ROOM_SIZE,
38
+ "door_size": FACTORY_DOOR_SIZE,
39
+ "obs_level": ObservationLevel.TOP_DOWN_PARTIAL,
40
+ "agent_mode": None,
41
+ },
42
+ )
43
+
44
+ register(
45
+ id="TwentyFiveRooms-v0",
46
+ entry_point="miniworld_maze.environments.twenty_five_rooms:TwentyFiveRooms",
47
+ max_episode_steps=1000,
48
+ kwargs={
49
+ "room_size": FACTORY_ROOM_SIZE,
50
+ "door_size": FACTORY_DOOR_SIZE,
51
+ "obs_level": ObservationLevel.TOP_DOWN_PARTIAL,
52
+ "agent_mode": None,
53
+ },
54
+ )
@@ -230,17 +230,20 @@ class GridRoomsEnvironment(UnifiedMiniWorldEnv):
230
230
  obs, reward, terminated, truncated, info = super().step(action)
231
231
 
232
232
  # Check if goal is achieved
233
- if self._is_goal_achieved():
233
+ goal_achieved = self._is_goal_achieved()
234
+ if goal_achieved:
234
235
  terminated = True
235
236
  reward = 1.0 # Positive reward for achieving goal
236
237
 
238
+ # Add success indicator to info dictionary
239
+ info["success"] = 1.0 if goal_achieved else 0.0
240
+
237
241
  # Add agent and goal positions to info dictionary
238
242
  agent_pos = self.agent.pos
239
243
  info["agent_position"] = np.array([agent_pos[0], agent_pos[2]]) # x, z
240
244
 
241
- if hasattr(self, "_current_goal_position"):
242
- goal_pos = self._current_goal_position
243
- info["goal_position"] = np.array([goal_pos[0], goal_pos[2]]) # x, z
245
+ goal_pos = self._current_goal_position
246
+ info["goal_position"] = np.array([goal_pos[0], goal_pos[2]]) # x, z
244
247
 
245
248
  # Return observation as dict
246
249
  obs_dict = self._build_observation_dict(obs)
@@ -261,6 +264,8 @@ class GridRoomsEnvironment(UnifiedMiniWorldEnv):
261
264
  # Call parent reset
262
265
  obs, info = super().reset(seed=seed, options=options, pos=pos)
263
266
 
267
+ info["success"] = 0.0
268
+
264
269
  # Generate goal
265
270
  self.desired_goal = self._get_goal()
266
271
 
@@ -268,9 +273,8 @@ class GridRoomsEnvironment(UnifiedMiniWorldEnv):
268
273
  agent_pos = self.agent.pos
269
274
  info["agent_position"] = np.array([agent_pos[0], agent_pos[2]]) # x, z
270
275
 
271
- if hasattr(self, "_current_goal_position"):
272
- goal_pos = self._current_goal_position
273
- info["goal_position"] = np.array([goal_pos[0], goal_pos[2]]) # x, z
276
+ goal_pos = self._current_goal_position
277
+ info["goal_position"] = np.array([goal_pos[0], goal_pos[2]]) # x, z
274
278
 
275
279
  # Return observation as dict with desired_goal and achieved_goal
276
280
  obs_dict = self._build_observation_dict(obs)
@@ -377,22 +381,24 @@ class GridRoomsEnvironment(UnifiedMiniWorldEnv):
377
381
  goal_positions.append([[center_x, 0.0, center_z]])
378
382
  else:
379
383
  # Two goals per room: center-left and center-right
380
- goal_positions.append([
381
- [center_x - 1.0, 0.0, center_z], # left goal
382
- [center_x + 1.0, 0.0, center_z], # right goal
383
- ])
384
+ goal_positions.append(
385
+ [
386
+ [center_x - 1.0, 0.0, center_z], # left goal
387
+ [center_x + 1.0, 0.0, center_z], # right goal
388
+ ]
389
+ )
384
390
  return goal_positions
385
391
 
386
392
  def get_extent(self, padding: float = 1.0) -> Tuple[float, float, float, float]:
387
393
  """
388
394
  Get the scene extent for use with matplotlib imshow.
389
-
390
- Returns the scene bounds with padding in the format expected by
395
+
396
+ Returns the scene bounds with padding in the format expected by
391
397
  matplotlib's imshow(extent=...) parameter: (left, right, bottom, top).
392
-
398
+
393
399
  Args:
394
400
  padding: Padding to add around environment bounds (default: 1.0)
395
-
401
+
396
402
  Returns:
397
403
  Tuple[float, float, float, float]: (min_x, max_x, min_z, max_z) with padding
398
404
  """
@@ -400,7 +406,7 @@ class GridRoomsEnvironment(UnifiedMiniWorldEnv):
400
406
  self.min_x - padding,
401
407
  self.max_x + padding,
402
408
  self.min_z - padding,
403
- self.max_z + padding
409
+ self.max_z + padding,
404
410
  )
405
411
 
406
412
  def _build_observation_dict(self, obs: np.ndarray) -> dict:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: miniworld-maze
3
- Version: 1.3.1
3
+ Version: 1.4.0
4
4
  Summary: Multi-room maze environments from the DrStrategy paper. Provides NineRooms-v0, SpiralNineRooms-v0, and TwentyFiveRooms-v0 gymnasium environments.
5
5
  Keywords: reinforcement-learning,environment,gymnasium,multi-room-maze,drstrategy,maze-navigation,partial-observability,3d-environments
6
6
  Author: Tim Joseph
@@ -1,6 +1,6 @@
1
- miniworld_maze/__init__.py,sha256=Dfq3558bJ5kgxDZxPxvlHu1531zfBhtiDfKbVL_4zCE,1430
1
+ miniworld_maze/__init__.py,sha256=gbc4Bqlu9HiqbIIZEQ-3mcuceaoKR9al7Ekl6KhSUtk,1318
2
2
  miniworld_maze/core/__init__.py,sha256=5BA4WKXQjrG55TNaEid2JGrnf1KQniJZ1HhRqovM1Q0,293
3
- miniworld_maze/core/constants.py,sha256=UXqmuvsT9ww1GljW74lWPPP9XxVmvti-8JfM_RBSoWQ,4314
3
+ miniworld_maze/core/constants.py,sha256=IjU4t7Nhlm8EOHQ8KVA351oOmTrR0R76M0kgmUXoo1Y,4314
4
4
  miniworld_maze/core/miniworld_gymnasium/README.md,sha256=kkZgkRKBdgixpot3uHuiBFlRIKRFIVBVfXwu68XTEv0,74
5
5
  miniworld_maze/core/miniworld_gymnasium/__init__.py,sha256=ALOqr4SCVk9I9bmxyoU0Du8LUPE_57jIyZuV4QhOcBc,159
6
6
  miniworld_maze/core/miniworld_gymnasium/base_env.py,sha256=K2L5r4gG2k4fEknFqRJ7f-b2S0Uj5QhanS-MLi6ncVc,1927
@@ -260,18 +260,16 @@ miniworld_maze/core/miniworld_gymnasium/textures/white_1.png,sha256=wRrgs92I_Ids
260
260
  miniworld_maze/core/miniworld_gymnasium/textures/wood_1.png,sha256=XRZyIN34HFo14olbxRcsHGrzCAFqUlowc6nLR22IFBE,184713
261
261
  miniworld_maze/core/miniworld_gymnasium/textures/wood_2.png,sha256=qSDHB-ZO11JJLQuiQse-0edpbuTg1YO-eIBhdTvNUhc,93121
262
262
  miniworld_maze/core/miniworld_gymnasium/textures/wood_planks_1.png,sha256=E4SNN1s4yOtkLfZFQy905eip6KvDWnnPUrpS82FxMAg,847259
263
- miniworld_maze/core/miniworld_gymnasium/unified_env.py,sha256=_xkznGIzXQpZOULgK-XFZaXZbhsouEupByf-4cfZLZc,46607
263
+ miniworld_maze/core/miniworld_gymnasium/unified_env.py,sha256=XWKKic2KGRJ4vTrN5D9VNt6Qaglvo-t8wtIKsh6KSDo,47424
264
264
  miniworld_maze/core/miniworld_gymnasium/utils.py,sha256=9cfpg4qYz-Esxvu8nTMPFJc-Tl0TRxTrX6cfg0YuK_o,1007
265
265
  miniworld_maze/core/miniworld_gymnasium/wrappers.py,sha256=cD0nGSJYNU96zoWv63aEiKd986POhtHfGGEpNpRL5ec,122
266
266
  miniworld_maze/core/observation_types.py,sha256=Co8mEIXzIgk0MLx6tqeBd1EE0PuZOL1gbZwobiEde08,1316
267
- miniworld_maze/environments/__init__.py,sha256=DKld5MQU7x9eNL6BlxIettA44bCiIn2zIpYECDCNxoQ,331
268
- miniworld_maze/environments/base_grid_rooms.py,sha256=--tm6t9cHn444xJX9N3Md-4YApK38a2dQi7mnggevbI,14885
269
- miniworld_maze/environments/factory.py,sha256=Zk26JawsMgSLMgvSnQxFhQCD8yMH76HgqFtogzWFfqY,1333
267
+ miniworld_maze/environments/__init__.py,sha256=KPmY72EA2Q0Xyuy75MZ7RZjJ4SUjlg4QvGR0WXu--78,1717
268
+ miniworld_maze/environments/base_grid_rooms.py,sha256=zlHEw_hlG9hoqrZWUN-QacS0vq8vvNW1U_h2j4RGHFk,14972
270
269
  miniworld_maze/environments/nine_rooms.py,sha256=Ct96cKtSt1_nLNI5RBUhwqdNUQq1rHfBJ3aB5Igbdow,1794
271
270
  miniworld_maze/environments/spiral_nine_rooms.py,sha256=a_pUuv-ghez8h76Z7YsHkQoLXsQ-w9azKLjEjO4uKmA,1749
272
271
  miniworld_maze/environments/twenty_five_rooms.py,sha256=MewKPDHDilscQGTT3aGRrSHvo4uFgHHAOrnJMrHaezQ,2598
273
- miniworld_maze/tools/__init__.py,sha256=XiReXrJIcBKvDVyPZrKPq1mckJs0_WC7q_RmdXXcKHs,55
274
272
  miniworld_maze/utils.py,sha256=HTOkfRq72oOC844gVXjWMH1ox7wdSxfCS6oTrWBw05Q,7523
275
- miniworld_maze-1.3.1.dist-info/WHEEL,sha256=NHRAbdxxzyL9K3IO2LjmlNqKSyPZnKv2BD16YYVKo18,79
276
- miniworld_maze-1.3.1.dist-info/METADATA,sha256=P-TEotub0dhvLm08sS1HWkRQWqF3HDzXOlUpVEPyPQs,9657
277
- miniworld_maze-1.3.1.dist-info/RECORD,,
273
+ miniworld_maze-1.4.0.dist-info/WHEEL,sha256=Jb20R3Ili4n9P1fcwuLup21eQ5r9WXhs4_qy7VTrgPI,79
274
+ miniworld_maze-1.4.0.dist-info/METADATA,sha256=rBLhLTs-PyS6I8tEji41pAEt1MDuUh9ymNfoyMyX8kM,9657
275
+ miniworld_maze-1.4.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: uv 0.8.14
2
+ Generator: uv 0.8.15
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,42 +0,0 @@
1
- """Gymnasium environment registrations for Nine Rooms environment variants."""
2
-
3
- from gymnasium.envs.registration import register
4
- from ..core import ObservationLevel
5
- from ..core.constants import FACTORY_DOOR_SIZE, FACTORY_ROOM_SIZE
6
-
7
- # Register environment variants with factory defaults matching the original wrapper
8
- register(
9
- id="NineRooms-v0",
10
- entry_point="miniworld_maze.environments.nine_rooms:NineRooms",
11
- max_episode_steps=1000,
12
- kwargs={
13
- "room_size": FACTORY_ROOM_SIZE,
14
- "door_size": FACTORY_DOOR_SIZE,
15
- "obs_level": ObservationLevel.TOP_DOWN_PARTIAL,
16
- "agent_mode": None, # becomes "empty" by default
17
- },
18
- )
19
-
20
- register(
21
- id="SpiralNineRooms-v0",
22
- entry_point="miniworld_maze.environments.spiral_nine_rooms:SpiralNineRooms",
23
- max_episode_steps=1000,
24
- kwargs={
25
- "room_size": FACTORY_ROOM_SIZE,
26
- "door_size": FACTORY_DOOR_SIZE,
27
- "obs_level": ObservationLevel.TOP_DOWN_PARTIAL,
28
- "agent_mode": None,
29
- },
30
- )
31
-
32
- register(
33
- id="TwentyFiveRooms-v0",
34
- entry_point="miniworld_maze.environments.twenty_five_rooms:TwentyFiveRooms",
35
- max_episode_steps=1000,
36
- kwargs={
37
- "room_size": FACTORY_ROOM_SIZE,
38
- "door_size": FACTORY_DOOR_SIZE,
39
- "obs_level": ObservationLevel.TOP_DOWN_PARTIAL,
40
- "agent_mode": None,
41
- },
42
- )
@@ -1,3 +0,0 @@
1
- """Tools for Nine Rooms environments."""
2
-
3
- __all__ = []