
    h&                        S r SSKJr  SSKJrJr  SSKrSSKr	SSK
JrJr  SSKJr  S/r " S S\	R                   \	R"                  R$                  5      rg)	z\Implementation of Atari 2600 Preprocessing following the guidelines of Machado et al., 2018.    )annotations)AnySupportsFloatN)WrapperActTypeWrapperObsType)BoxAtariPreprocessingc                      \ rS rSrSr       S               SS jjr\S 5       r    SS jrSSS.     SS jjr	S	 r
S
rg)r	      a  Implements the common preprocessing techniques for Atari environments (excluding frame stacking).

For frame stacking use :class:`gymnasium.wrappers.FrameStackObservation`.
No vector version of the wrapper exists

This class follows the guidelines in Machado et al. (2018),
"Revisiting the Arcade Learning Environment: Evaluation Protocols and Open Problems for General Agents".

Specifically, the following preprocess stages applies to the atari environment:

- Noop Reset: Obtains the initial state by taking a random number of no-ops on reset, default max 30 no-ops.
- Frame skipping: The number of frames skipped between steps, 4 by default.
- Max-pooling: Pools over the most recent two observations from the frame skips.
- Termination signal when a life is lost: When the agent losses a life during the environment, then the environment is terminated.
    Turned off by default. Not recommended by Machado et al. (2018).
- Resize to a square image: Resizes the atari environment original observation shape from 210x180 to 84x84 by default.
- Grayscale observation: Makes the observation greyscale, enabled by default.
- Grayscale new axis: Extends the last channel of the observation such that the image is 3-dimensional, not enabled by default.
- Scale observation: Whether to scale the observation between [0, 1) or [0, 255), not scaled by default.

Example:
    >>> import gymnasium as gym
    >>> import ale_py
    >>> gym.register_envs(ale_py)
    >>> env = gym.make("ALE/Pong-v5", frameskip=1)
    >>> env = AtariPreprocessing(
    ...     env,
    ...     noop_max=10, frame_skip=4, terminal_on_life_loss=True,
    ...     screen_size=84, grayscale_obs=False, grayscale_newaxis=False
    ... )

Change logs:
 * Added in gym v0.12.2 (gym #1455)
c	                L   [         R                  R                  R                  U UUUUUUUS9  [         R                  R                  X5         SSKn	US:  d   e[        U[        5      (       a  US:  dE  [        U[        5      (       a&  [        U5      S:X  a  [        S U 5       5      (       d
   SU 35       eUS:  a&  [        UR                  S	S5      S:w  a  [!        S
5      eUS:  d   eX l        US:  a#  UR                  R%                  5       S   S:X  d   eX0l        [        U[        5      (       a  UOXD4U l        XPl        X`l        Xpl        Xl        [        UR2                  [4        5      (       d   eU(       az  [6        R8                  " UR2                  R:                  SS [6        R<                  S9[6        R8                  " UR2                  R:                  SS [6        R<                  S9/U l        Os[6        R8                  " UR2                  R:                  [6        R<                  S9[6        R8                  " UR2                  R:                  [6        R<                  S9/U l        SU l         SU l!        U(       a  SS[6        RD                  4OSS[6        R<                  4u  pnU R(                  S   U R(                  S   U(       a  SOS4nU(       a  U(       d  USS n[5        XXS9U l        g! [         a     [         R                  R                  S5      ef = f)ag  Wrapper for Atari 2600 preprocessing.

Args:
    env (Env): The environment to apply the preprocessing
    noop_max (int): For No-op reset, the max number no-ops actions are taken at reset, to turn off, set to 0.
    frame_skip (int): The number of frames between new observation the agents observations effecting the frequency at which the agent experiences the game.
    screen_size (int | tuple[int, int]): resize Atari frame.
    terminal_on_life_loss (bool): `if True`, then :meth:`step()` returns `terminated=True` whenever a
        life is lost.
    grayscale_obs (bool): if True, then gray scale observation is returned, otherwise, RGB observation
        is returned.
    grayscale_newaxis (bool): `if True and grayscale_obs=True`, then a channel axis is added to
        grayscale observations to make them 3-dimensional.
    scale_obs (bool): if True, then observation normalized in range [0,1) is returned. It also limits memory
        optimization benefits of FrameStack Wrapper.

Raises:
    DependencyNotInstalled: opencv-python package not installed
    ValueError: Disable frame-skipping in the original env
)noop_max
frame_skipscreen_sizeterminal_on_life_lossgrayscale_obsgrayscale_newaxis	scale_obsr   Nzgopencv-python package not installed, run `pip install "gymnasium[other]"` to get dependencies for atari   c              3  Z   #    U  H!  n[        U[        5      =(       a    US :  v   M#     g7f)r   N)
isinstanceint).0sizes     `/home/james-whalen/.local/lib/python3.13/site-packages/gymnasium/wrappers/atari_preprocessing.py	<genexpr>.AtariPreprocessing.__init__.<locals>.<genexpr>k   s#     O;4JtS)6dQh6;s   )+z3Expect the `screen_size` to be positive, actually:    
_frameskipzsDisable frame-skipping in the original env. Otherwise, more than one frame-skip will happen as through this wrapperNOOPdtypeF      )lowhighshaper!   )#gymutilsRecordConstructorArgs__init__Wrappercv2ImportErrorerrorDependencyNotInstalledr   r   tuplelenallgetattr	unwrapped
ValueErrorr   get_action_meaningsr   r   r   r   r   r   observation_spacer   npemptyr'   uint8
obs_bufferlives	game_overfloat32)selfenvr   r   r   r   r   r   r   r-   _low_high_dtype_shapes                 r   r+   AtariPreprocessing.__init__5   s   > 			''00!#"7'/ 	1 		
 	T'	 A~~;,,q{E**K A%O;OOO	O AN		O 

 >gcmm\4HAM F  1}} a<==446q9VCCC$ +u-- + 	
 &;"*!2" #//5555..44Ra8I..44Ra8IDO ..44BHHE..44BHHEDO
 
4=q!RZZ0AsBHHCUV""1%t'7'7':ATUV!2CR[F!$!Vg  	))22y 	s   K9 9*L#c                B    U R                   R                  R                  $ )z:Make ale as a class property to avoid serialization error.)rA   r5   ale)r@   s    r   rH   AtariPreprocessing.ale   s     xx!!%%%    c                f   SSS0 4u  p#pE[        U R                  5       GH|  nU R                  R                  U5      u  pxp4nX(-  nX0l        U R
                  (       a=  U R                  R                  5       n	U=(       d    XR                  :  nX0l        Xl        U(       d  U(       a    OX`R                  S-
  :X  af  U R                  (       a*  U R                  R                  U R                  S   5        M  U R                  R                  U R                  S   5        GM  X`R                  S-
  :X  d  GM  U R                  (       a+  U R                  R                  U R                  S   5        GMT  U R                  R                  U R                  S   5        GM     U R                  5       X#XE4$ )z2Applies the preprocessing for an :meth:`env.step`.g        Fr   r   r   )ranger   rA   stepr>   r   rH   r=   r   getScreenGrayscaler<   getScreenRGB_get_obs)
r@   actiontotal_reward
terminated	truncatedinfot_reward	new_livess
             r   rM   AtariPreprocessing.step   s=    58r4I1)t'A59XX]]65J2Azd"L'N)) HHNN,	'A9zz+A
!+&
YOOa''%%HH//0BCHH))$//!*<=oo))%%HH//0BCHH))$//!*<=- (. }})IIrJ   Nseedoptionsc                  U R                   R                  XS9u  p4U R                  S:  a=  U R                   R                  R                  R                  SU R                  S-   5      OSn[        U5       H^  nU R                   R                  S5      u    p6pxUR                  U5        U(       d	  U(       d  MC  U R                   R                  XS9u  p4M`     U R                  R                  5       U l
        U R                  (       a)  U R                  R                  U R                  S   5        O(U R                  R                  U R                  S   5        U R                  S   R                  S5        U R!                  5       U4$ )z+Resets the environment using preprocessing.r[   r   r   )rA   resetr   r5   	np_randomintegersrL   rM   updaterH   r=   r   rN   r<   rO   fillrP   )	r@   r\   r]   rW   
reset_infonoopsrS   rT   	step_infos	            r   r_   AtariPreprocessing.reset   s,   
 DB }}q  HH((11!T]]Q5FG 	
 uA59XX]]15E2Aqii(YY $D J:	  XX^^%
HH''(:;HH!!$//!"45"}}
**rJ   c                0   U R                   S:  a=  [        R                  " U R                  S   U R                  S   U R                  S   S9  SS KnUR                  U R                  S   U R                  UR                  S9nU R                  (       a'  [        R                  " U[        R                  S9S-  nO#[        R                  " U[        R                  S9nU R                  (       a&  U R                  (       a  [        R                  " USS9nU$ )	Nr   r   )out)interpolationr    g     o@r$   )axis)r   r9   maximumr<   r-   resizer   
INTER_AREAr   asarrayr?   r;   r   r   expand_dims)r@   r-   obss      r   rP   AtariPreprocessing._get_obs   s    ??QJJtq)4??1+=4??STCUVjjOOA..  
 >>**S

3e;C**S1C$"8"8..2.C
rJ   )r   r>   r   r   r=   r   r<   r8   r   r   r   )      T   FTFF)rA   zgym.Envr   r   r   r   r   zint | tuple[int, int]r   boolr   rv   r   rv   r   rv   )rQ   r   returnz@tuple[WrapperObsType, SupportsFloat, bool, bool, dict[str, Any]])r\   z
int | Noner]   zdict[str, Any] | Nonerw   z%tuple[WrapperObsType, dict[str, Any]])__name__
__module____qualname____firstlineno____doc__r+   propertyrH   rM   r_   rP   __static_attributes__ rJ   r   r	   r	      s    !L -/&+""'`W`W `W 	`W
 +`W  $`W `W  `W `WD & &J$J	IJ@ %)4+!+3H+	.+6rJ   )r|   
__future__r   typingr   r   numpyr9   	gymnasiumr(   gymnasium.corer   r   gymnasium.spacesr   __all__r,   r)   r*   r	   r   rJ   r   <module>r      sB    b " %   9    
 Xcii&E&E XrJ   