@@ -113,55 +113,57 @@ def __init__(
113113 self .num_envs = len (rom_paths )
114114 self .batch_size = self .num_envs if batch_size == 0 else batch_size
115115
116- # Set up the observation space based on grayscale or RGB format
117- self .grayscale = grayscale
118- obs_shape = (stack_num , img_height , img_width )
119- if not grayscale :
120- obs_shape += (3 ,)
121- self .single_observation_space = Box (
122- shape = obs_shape , low = 0 , high = 255 , dtype = np .uint8
123- )
124-
125116 self .autoreset_mode = AutoresetMode (autoreset_mode )
126117 self .metadata ["autoreset_mode" ] = self .autoreset_mode
127118
128- self .observation_space = gymnasium .vector .utils .batch_space (
129- self .single_observation_space , self .batch_size
119+ # Set up the observation space
120+ self .grayscale = grayscale
121+ self .single_observation_space , self .observation_space = self ._setup_obs (
122+ stack_num , img_height , img_width
130123 )
131124
132- # Set up the action space to use continuous or discrete actions
125+ # Set up the action space
133126 self .full_action_space = full_action_space
134127 self .continuous = continuous
135128 self .continuous_action_threshold = continuous_action_threshold
129+ self .single_action_space , self .action_space = (
130+ self ._setup_continuous_action ()
131+ if self .continuous
132+ else self ._setup_discrete_action ()
133+ )
134+ self .is_xla_registered = False
135+
136+ def _setup_obs (self , stack_num : int , img_height : int , img_width : int ) -> tuple :
137+ obs_shape = (stack_num , img_height , img_width )
138+ if not self .grayscale :
139+ obs_shape += (3 ,)
140+ single = Box (shape = obs_shape , low = 0 , high = 255 , dtype = np .uint8 )
141+ return single , gymnasium .vector .utils .batch_space (single , self .batch_size )
142+
143+ def _setup_continuous_action (self ) -> tuple :
136144 self .map_action_idx = np .zeros ((3 , 3 , 2 ), dtype = np .int32 )
137145 for h in (- 1 , 0 , 1 ):
138146 for v in (- 1 , 0 , 1 ):
139147 for f in (0 , 1 ):
140148 action = AtariEnv .map_action_idx (h , v , bool (f )).value
141149 self .map_action_idx [h + 1 , v + 1 , f ] = action
142-
143- if self .continuous :
144- # Actions are radius, theta, and fire, where first two are the parameters of polar coordinates.
145- self .single_action_space = Box (
146- low = np .array ([0.0 , - np .pi , 0.0 ]).astype (np .float32 ),
147- high = np .array ([1.0 , np .pi , 1.0 ]).astype (np .float32 ),
148- dtype = np .float32 ,
149- shape = (3 ,),
150- )
151- self .action_space = gymnasium .vector .utils .batch_space (
152- self .single_action_space , self .batch_size
153- )
154- else :
155- self .single_action_space = (
156- None if self .full_action_space is None else Discrete (16 )
157- )
158- # Note: we expose the action space for all games instead of filtering up to the batch size,
159- # the user will need the full list to determine the action size for each environment.
160- self .action_space = MultiDiscrete (
161- np .array ([len (s ) for s in self .ale .get_action_sets ()], dtype = np .int64 )
162- )
163-
164- self .is_xla_registered = False
150+ # Actions are radius, theta, and fire, where first two are the parameters of polar coordinates.
151+ single = Box (
152+ low = np .array ([0.0 , - np .pi , 0.0 ]).astype (np .float32 ),
153+ high = np .array ([1.0 , np .pi , 1.0 ]).astype (np .float32 ),
154+ dtype = np .float32 ,
155+ shape = (3 ,),
156+ )
157+ return single , gymnasium .vector .utils .batch_space (single , self .batch_size )
158+
159+ def _setup_discrete_action (self ) -> tuple :
160+ single = None if self .full_action_space is None else Discrete (16 )
161+ # Note: we expose the action space for all games instead of filtering up to the batch size,
162+ # the user will need the full list to determine the action size for each environment.
163+ action_space = MultiDiscrete (
164+ np .array ([len (s ) for s in self .ale .get_action_sets ()], dtype = np .int64 )
165+ )
166+ return single , action_space
165167
166168 def reset (
167169 self ,
0 commit comments