| 
					
				 | 
			
			
				@@ -5,8 +5,8 @@ import numpy as np 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from gym import error, spaces, utils 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 from gym.utils import seeding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-# Size in pixels of a cell in the full-scale human view 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-CELL_PIXELS = 32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+# Size in pixels of a tile in the full-scale human view 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+TILE_PIXELS = 32 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 # Map of color names to RGB values 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 COLORS = { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -106,6 +106,44 @@ class WorldObj: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """Method to trigger/toggle an action this object performs""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return False 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def encode(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """Encode the a description of this object as a 3-tuple of integers""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return (OBJECT_TO_IDX[self.type], COLOR_TO_IDX[self.color], 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def decode(type_idx, color_idx, state): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """Create an object from a 3-tuple state description""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        obj_type = IDX_TO_OBJECT[type_idx] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        color = IDX_TO_COLOR[color_idx] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if obj_type == 'empty' or obj_type == 'unseen': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return None 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # State, 0: open, 1: closed, 2: locked 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        is_open = state == 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        is_locked = state == 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if obj_type == 'wall': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            v = Wall(color) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif obj_type == 'floor': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            v = Floor(color) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif obj_type == 'ball': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            v = Ball(color) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif obj_type == 'key': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            v = Key(color) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif obj_type == 'box': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            v = Box(color) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif obj_type == 'door': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            v = Door(color, is_open, is_locked) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif obj_type == 'goal': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            v = Goal() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif obj_type == 'lava': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            v = Lava() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            assert False, "unknown object type in decode '%s'" % objType 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return v 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def render(self, r): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """Draw this object with the given renderer""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         raise NotImplementedError 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -126,9 +164,9 @@ class Goal(WorldObj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def render(self, r): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._set_color(r) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.drawPolygon([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (0          , CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS, CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS,           0), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (0          , TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS, TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS,           0), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             (0          ,           0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -149,9 +187,9 @@ class Floor(WorldObj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.setLineColor(100, 100, 100, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.setColor(*c/2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.drawPolygon([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (1          , CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS, CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS,           1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (1          , TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS, TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS,           1), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             (1          ,           1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -167,9 +205,9 @@ class Lava(WorldObj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.setLineColor(*orange) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.setColor(*orange) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.drawPolygon([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (0          , CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS, CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS, 0), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (0          , TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS, TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS, 0), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             (0          , 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -177,27 +215,27 @@ class Lava(WorldObj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.setLineColor(0, 0, 0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.drawPolyline([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.1 * CELL_PIXELS, .3 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.3 * CELL_PIXELS, .4 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.5 * CELL_PIXELS, .3 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.7 * CELL_PIXELS, .4 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.9 * CELL_PIXELS, .3 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.1 * TILE_PIXELS, .3 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.3 * TILE_PIXELS, .4 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.5 * TILE_PIXELS, .3 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.7 * TILE_PIXELS, .4 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.9 * TILE_PIXELS, .3 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.drawPolyline([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.1 * CELL_PIXELS, .5 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.3 * CELL_PIXELS, .6 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.5 * CELL_PIXELS, .5 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.7 * CELL_PIXELS, .6 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.9 * CELL_PIXELS, .5 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.1 * TILE_PIXELS, .5 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.3 * TILE_PIXELS, .6 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.5 * TILE_PIXELS, .5 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.7 * TILE_PIXELS, .6 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.9 * TILE_PIXELS, .5 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.drawPolyline([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.1 * CELL_PIXELS, .7 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.3 * CELL_PIXELS, .8 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.5 * CELL_PIXELS, .7 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.7 * CELL_PIXELS, .8 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (.9 * CELL_PIXELS, .7 * CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.1 * TILE_PIXELS, .7 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.3 * TILE_PIXELS, .8 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.5 * TILE_PIXELS, .7 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.7 * TILE_PIXELS, .8 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (.9 * TILE_PIXELS, .7 * TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class Wall(WorldObj): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -210,9 +248,9 @@ class Wall(WorldObj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def render(self, r): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._set_color(r) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.drawPolygon([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (0          , CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS, CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS,           0), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (0          , TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS, TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS,           0), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             (0          ,           0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -241,6 +279,19 @@ class Door(WorldObj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.is_open = not self.is_open 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def encode(self): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        """Encode the a description of this object as a 3-tuple of integers""" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        # State, 0: open, 1: closed, 2: locked 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if self.is_open: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            state = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif self.is_locked: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            state = 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elif not self.is_open: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            state = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return (OBJECT_TO_IDX[self.type], COLOR_TO_IDX[self.color], state) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def render(self, r): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         c = COLORS[self.color] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.setLineColor(c[0], c[1], c[2]) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -248,37 +299,37 @@ class Door(WorldObj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if self.is_open: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             r.drawPolygon([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                (CELL_PIXELS-2, CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                (CELL_PIXELS  , CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                (CELL_PIXELS  ,           0), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                (CELL_PIXELS-2,           0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                (TILE_PIXELS-2, TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                (TILE_PIXELS  , TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                (TILE_PIXELS  ,           0), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                (TILE_PIXELS-2,           0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.drawPolygon([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (0          , CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS, CELL_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS,           0), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (0          , TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS, TILE_PIXELS), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS,           0), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             (0          ,           0) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.drawPolygon([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (2            , CELL_PIXELS-2), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS-2, CELL_PIXELS-2), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS-2,           2), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (2            , TILE_PIXELS-2), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS-2, TILE_PIXELS-2), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS-2,           2), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             (2            ,           2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if self.is_locked: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             # Draw key slot 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             r.drawLine( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                CELL_PIXELS * 0.55, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                CELL_PIXELS * 0.5, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                CELL_PIXELS * 0.75, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                CELL_PIXELS * 0.5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                TILE_PIXELS * 0.55, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                TILE_PIXELS * 0.5, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                TILE_PIXELS * 0.75, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                TILE_PIXELS * 0.5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             # Draw door handle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            r.drawCircle(CELL_PIXELS * 0.75, CELL_PIXELS * 0.5, 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            r.drawCircle(TILE_PIXELS * 0.75, TILE_PIXELS * 0.5, 2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class Key(WorldObj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def __init__(self, color='blue'): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -326,7 +377,7 @@ class Ball(WorldObj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def render(self, r): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self._set_color(r) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        r.drawCircle(CELL_PIXELS * 0.5, CELL_PIXELS * 0.5, 10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        r.drawCircle(TILE_PIXELS * 0.5, TILE_PIXELS * 0.5, 10) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class Box(WorldObj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     def __init__(self, color, contains=None): 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -343,17 +394,17 @@ class Box(WorldObj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.setLineWidth(2) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.drawPolygon([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (4            , CELL_PIXELS-4), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS-4, CELL_PIXELS-4), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (CELL_PIXELS-4,             4), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (4            , TILE_PIXELS-4), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS-4, TILE_PIXELS-4), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (TILE_PIXELS-4,             4), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             (4            ,             4) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.drawLine( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            CELL_PIXELS / 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            CELL_PIXELS - 4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            CELL_PIXELS / 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            TILE_PIXELS / 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            TILE_PIXELS - 4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            TILE_PIXELS / 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.setLineWidth(1) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -363,6 +414,27 @@ class Box(WorldObj): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         env.grid.set(*pos, self.contains) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return True 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+def render_tile( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    obj, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    agent_dir=None, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    highlight=False, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    tile_size=TILE_PIXELS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Render a tile and cache the result 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 class Grid: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     Represent a grid and operations on it 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -479,14 +551,14 @@ class Grid: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         assert r.height == self.height * tile_size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Total grid size at native scale 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        widthPx = self.width * CELL_PIXELS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        heightPx = self.height * CELL_PIXELS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        widthPx = self.width * TILE_PIXELS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        heightPx = self.height * TILE_PIXELS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.push() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Internally, we draw at the "large" full-grid resolution, but we 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # use the renderer to scale back to the desired size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        r.scale(tile_size / CELL_PIXELS, tile_size / CELL_PIXELS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        r.scale(tile_size / TILE_PIXELS, tile_size / TILE_PIXELS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Draw the background of the in-world cells black 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.fillRect( 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -500,10 +572,10 @@ class Grid: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Draw grid lines 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.setLineColor(100, 100, 100) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         for rowIdx in range(0, self.height): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            y = CELL_PIXELS * rowIdx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            y = TILE_PIXELS * rowIdx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             r.drawLine(0, y, widthPx, y) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         for colIdx in range(0, self.width): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            x = CELL_PIXELS * colIdx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x = TILE_PIXELS * colIdx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             r.drawLine(x, 0, x, heightPx) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Render the grid 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -513,7 +585,7 @@ class Grid: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if cell == None: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 r.push() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                r.translate(i * CELL_PIXELS, j * CELL_PIXELS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                r.translate(i * TILE_PIXELS, j * TILE_PIXELS) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 cell.render(r) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 r.pop() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -528,6 +600,7 @@ class Grid: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             vis_mask = np.ones((self.width, self.height), dtype=bool) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         array = np.zeros((self.width, self.height, 3), dtype='uint8') 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         for i in range(self.width): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for j in range(self.height): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 if vis_mask[i, j]: 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -537,17 +610,9 @@ class Grid: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         array[i, j, 0] = OBJECT_TO_IDX['empty'] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         array[i, j, 1] = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                         array[i, j, 2] = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        # State, 0: open, 1: closed, 2: locked 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        state = 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if hasattr(v, 'is_open') and not v.is_open: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            state = 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        if hasattr(v, 'is_locked') and v.is_locked: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            state = 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        array[i, j, 0] = OBJECT_TO_IDX[v.type] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        array[i, j, 1] = COLOR_TO_IDX[v.color] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        array[i, j, 2] = state 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        array[i, j, :] = v.encode() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return array 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -563,37 +628,8 @@ class Grid: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         grid = Grid(width, height) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         for i in range(width): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             for j in range(height): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                typeIdx, colorIdx, state = array[i, j] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if typeIdx == OBJECT_TO_IDX['unseen'] or \ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        typeIdx == OBJECT_TO_IDX['empty']: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    continue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                objType = IDX_TO_OBJECT[typeIdx] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                color = IDX_TO_COLOR[colorIdx] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                # State, 0: open, 1: closed, 2: locked 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                is_open = state == 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                is_locked = state == 2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if objType == 'wall': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    v = Wall(color) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                elif objType == 'floor': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    v = Floor(color) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                elif objType == 'ball': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    v = Ball(color) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                elif objType == 'key': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    v = Key(color) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                elif objType == 'box': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    v = Box(color) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                elif objType == 'door': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    v = Door(color, is_open, is_locked) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                elif objType == 'goal': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    v = Goal() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                elif objType == 'lava': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    v = Lava() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                else: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    assert False, "unknown obj type in decode '%s'" % objType 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                type_idx, color_idx, state = array[i, j] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                v = WorldObj.decode(type_idx, color_idx, state) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 grid.set(i, j, v) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return grid 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1229,7 +1265,7 @@ class MiniGridEnv(gym.Env): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return obs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    def get_obs_render(self, obs, tile_size=CELL_PIXELS//2, mode='pixmap'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def get_obs_render(self, obs, tile_size=TILE_PIXELS//2, mode='pixmap'): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Render an agent observation for visualization 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1251,12 +1287,12 @@ class MiniGridEnv(gym.Env): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         grid.render(r, tile_size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Draw the agent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ratio = tile_size / CELL_PIXELS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ratio = tile_size / TILE_PIXELS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.push() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.scale(ratio, ratio) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.translate( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            CELL_PIXELS * (0.5 + self.agent_view_size // 2), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            CELL_PIXELS * (self.agent_view_size - 0.5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            TILE_PIXELS * (0.5 + self.agent_view_size // 2), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            TILE_PIXELS * (self.agent_view_size - 0.5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.rotate(3 * 90) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.setLineColor(255, 0, 0) 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1276,7 +1312,7 @@ class MiniGridEnv(gym.Env): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return r.getPixmap() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return r 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    def render(self, mode='human', close=False, highlight=True, tile_size=CELL_PIXELS): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    def render(self, mode='human', close=False, highlight=True, tile_size=TILE_PIXELS): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         Render the whole-grid human view 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         """ 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1305,12 +1341,12 @@ class MiniGridEnv(gym.Env): 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         self.grid.render(r, tile_size) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         # Draw the agent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ratio = tile_size / CELL_PIXELS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ratio = tile_size / TILE_PIXELS 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.push() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.scale(ratio, ratio) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.translate( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            CELL_PIXELS * (self.agent_pos[0] + 0.5), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            CELL_PIXELS * (self.agent_pos[1] + 0.5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            TILE_PIXELS * (self.agent_pos[0] + 0.5), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            TILE_PIXELS * (self.agent_pos[1] + 0.5) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         ) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.rotate(self.agent_dir * 90) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         r.setLineColor(255, 0, 0) 
			 |