
    hC                        S SK Jr  S SKJr  S SKJr  S SKJr  S SKr	S SK
rS SK
JrJrJr  S SKJr  S SKJr  S S	KJr  S rS
rSrSr/ SQ/ SQS.rSS jr S       SS jjr " S S\5      rg)    )annotations)closing)StringIO)pathN)Envspacesutils)categorical_sample)DependencyNotInstalled)seeding         )SFFFFHFHFFFHHFFG)SFFFFFFFFFFFFFFFFFFHFFFFFFFFFHFFr   FHHFFFHFFHFFHFHFFFFHFFFG)4x48x8c                h   / [        5       p2UR                  S5        U(       a  UR                  5       u  pEXE4U;  am  UR                  XE45        / SQnU HQ  u  pxXG-   n	XX-   n
U	S:  d  X:  d  U
S:  d  X:  a  M%  X	   U
   S:X  a    gX	   U
   S:w  d  M?  UR                  X45        MS     U(       a  M  g)N)r   r   ))r   r   )r   r   )r   )r   r   r   GTHF)setappendpopadd)boardmax_sizefrontier
discoveredrc
directionsxyr_newc_news              ]/home/james-whalen/.local/lib/python3.13/site-packages/gymnasium/envs/toy_text/frozen_lake.pyis_validr1   %   s    sujOOF
||~v#NNA6";J"19 1UQY%BS<&#-<&#-OOUN3 # (     c                (   Sn/ n[         R                  " U5      u  pVU(       dI  [        SU5      nUR                  SS/X 4USU-
  /S9nSUS   S'   SUS	   S	'   [	        X@5      nU(       d  MI  U Vs/ s H  nS
R                  U5      PM     sn$ s  snf )a  Generates a random valid map (one that has a path from start to goal)

Args:
    size: size of each side of the grid
    p: probability that a tile is frozen
    seed: optional seed to ensure the generation of reproducible maps

Returns:
    A random valid map
Fr   Fr    )pSr   r   r    )r   	np_randomminchoicer1   join)sizer5   seedvalidr%   r8   _r,   s           r0   generate_random_mapr@   9   s     EE$$T*LI1I  #sd\aQZ Hab	"% e !&&1BGGAJ&&&s   1Bc                     ^  \ rS rSrSr/ SQSS.r      S           SS jjrS rSSS	.   SU 4S
 jjjrS r	S r
\S 5       rS rS rSrU =r$ )FrozenLakeEnvT   aA  
 Frozen lake involves crossing a frozen lake from start to goal without falling into any holes
 by walking over the frozen lake.
 The player may not always move in the intended direction due to the slippery nature of the frozen lake.

 ## Description
 The game starts with the player at location `[0,0]` of the frozen lake grid world with the
 goal located at far extent of the world e.g. `[3,3]` for the 4x4 environment.

 Holes in the ice are distributed in set locations when using a pre-determined map
 or in random locations when a random map is generated.
 Randomly generated worlds will always have a path to the goal.

 The player makes moves until they reach the goal or fall in a hole.

 The lake is slippery (unless disabled) so the player may move perpendicular
 to the intended direction sometimes (see `is_slippery` in Argument section).

 Elf and stool from [https://franuka.itch.io/rpg-snow-tileset](https://franuka.itch.io/rpg-snow-tileset).
 All other assets by Mel Tillery [http://www.cyaneus.com/](http://www.cyaneus.com/).

 ## Action Space
 The action shape is `(1,)` in the range `{0, 3}` indicating
 which direction to move the player.

 - 0: Move left
 - 1: Move down
 - 2: Move right
 - 3: Move up

 ## Observation Space
 The observation is a value representing the player's current position as
 `current_row * ncols + current_col` (where both the row and col start at 0).
 Therefore, the observation is returned as an integer.

 For example, the goal position in the 4x4 map can be calculated as follows: 3 * 4 + 3 = 15.
 The number of possible observations is dependent on the size of the map.

 ## Starting State
 The episode starts with the player in state `[0]` (location [0, 0]).

 ## Rewards

 Default reward schedule:
 - Reach goal: +1
 - Reach hole: 0
 - Reach frozen: 0

 See `reward_schedule` for reward customization in the Argument section.

 ## Episode End
 The episode ends if the following happens:

 - Termination:
     1. The player moves into a hole.
     2. The player reaches the goal at `max(nrow) * max(ncol) - 1` (location `[max(nrow)-1, max(ncol)-1]`).

 - Truncation (using the time_limit wrapper):
     1. The length of the episode is 100 for FrozenLake4x4, 200 for FrozenLake8x8.

 ## Information

 `step()` and `reset()` return a dict with the following keys:
 - `p`: transition probability for the state which will be impacted by the `is_slippery` parameter.

 ## Arguments

 FrozenLake has five parameters:
 ```python
 import gymnasium as gym
 gym.make(
     'FrozenLake-v1',
     desc=None,
     map_name="4x4",
     is_slippery=True,
     success_rate=1.0/3.0,
     reward_schedule=(1, 0, 0)
 )
 ```

 * `desc=None`: Used to specify maps non-preloaded maps.
     If `desc=None` then `map_name` will be used. If both `desc` and `map_name` are
     `None` a random 8x8 map with 80% of locations frozen will be generated.

     To Specify a custom map - `desc=["SFFF", "FHFH", "FFFH", "HFFG"]`
     The tile letters denote:
     - "S" for Start tile
     - "G" for Goal tile
     - "F" for frozen tile
     - "H" for a tile with a hole

     A random generated map can be specified by calling the function `generate_random_map`.
     ```
     from gymnasium.envs.toy_text.frozen_lake import generate_random_map

     gym.make('FrozenLake-v1', desc=generate_random_map(size=8))
     ```

 * `map_name="4x4"` - Helps load two predefined map names (`4x4` and `8x8`)
     ```
     "4x4":[
         "SFFF",
         "FHFH",
         "FFFH",
         "HFFG"
     ]

     "8x8": [
         "SFFFFFFF",
         "FFFFFFFF",
         "FFFHFFFF",
         "FFFFFHFF",
         "FFFHFFFF",
         "FHHFFFHF",
         "FHFFHFHF",
         "FFFHFFFG",
     ]
     ```

* `is_slippery=True`: If true the player will move in intended direction with probability specified by the
     `success_rate` else will move in either perpendicular direction with equal probability in both directions.

     For example, if action is left, `is_slippery` is True, and `success_rate` is 1/3, then:
     - P(move left)=1/3
     - P(move up)=1/3
     - P(move down)=1/3

     If action is up, `is_slippery` is True, and `success_rate` is 3/4, then:
     - P(move up)=3/4
     - P(move left)=1/8
     - P(move right)=1/8

* `success_rate=1.0/3.0`: Used to specify the probability of moving in the intended direction when is_slippery=True

* `reward_schedule=(1, 0, 0)`: Used to specify reward amounts for reaching certain tiles.
     The indices correspond to: Reach Goal, Reach Hole, Reach Frozen (includes Start), Respectively

 ## Version History
 * v1: Bug fixes to rewards (v1.3, added reward customization)
 * v0: Initial version release

)humanansi	rgb_array   )render_modes
render_fpsNc                  ^^^^^^ Tc  Uc  [        5       mOTc	  [        U   m[        R                  " TSS9=U l        mTR
                  =u  U l        U l        u  mm[        T5      [        T5      4U l
        SnTT-  n[        R                  " TS:H  5      R                  S5      R                  5       U l        U =R                  U R                  R                  5       -  sl        [!        U5       V	V
s0 s H  o[!        U5       V
s0 s H  o/ _M     sn
_M!     sn
n	U l        SU-
  S-  nU4S jmUU4S	 jmUUUU4S
 jn[!        T5       H  n[!        T5       H  nT" X5      n	[!        S5       H  n
U R"                  U	   U
   nTX4   nUS;   a  UR%                  SU	SS45        M8  U(       a=  U
S-
  S-  XS-   S-  4 H'  nUR%                  UU
:X  a  UOU/U" XU5      Q75        M)     M|  UR%                  S/U" XU
5      Q75        M     M     M     [&        R(                  " U5      U l        [&        R(                  " U5      U l        Xl        [        ST-  S5      [        ST-  S5      4U l        U R0                  S   U R                  -  U R0                  S   U R                  -  4U l        S U l        S U l        S U l        S U l        S U l        S U l        S U l         S U l!        g s  sn
f s  sn
n	f )Nr*   )dtyperG      Sfloat64g      ?g       @c                   > U T-  U-   $ )N )rowcolncols     r0   to_s$FrozenLakeEnv.__init__.<locals>.to_s  s    :##r2   c                   > U[         :X  a  [        US-
  S5      nX4$ U[        :X  a  [        U S-   TS-
  5      n X4$ U[        :X  a  [        US-   TS-
  5      nX4$ U[
        :X  a  [        U S-
  S5      n X4$ )Nr   r   )LEFTmaxDOWNr9   RIGHTUP)rP   rQ   arR   nrows      r0   inc#FrozenLakeEnv.__init__.<locals>.inc  s    Dy#'1o : d#'4!8,
 :	 e#'4!8, : b#'1o:r2   c                   > T
" XU5      u  p4T" X45      nT	X44   n[        U5      S;   nTSR                  US;   a  UOS5         nXXU4$ )N   GHs   GHF   F)bytesindex)rP   rQ   actionnew_rownew_col	new_state
new_letter
terminatedrewarddescr]   reward_schedulerS   s            r0   update_probability_matrix9FrozenLakeEnv.__init__.<locals>.update_probability_matrix  sd    "3V4GW.Ig./Jz*e3J$:+?ZTJF j00r2   r`   r   Tr   @   i   )"r@   MAPSnpasarrayrk   shaper\   rR   r9   rW   reward_rangearrayastyperavelinitial_state_distribsumrangePr"   r   Discreteobservation_spaceaction_spacerender_modewindow_size	cell_sizewindow_surfaceclockhole_imgcracked_hole_imgice_img
elf_imagesgoal_img	start_img)selfr   rk   map_nameis_slipperysuccess_raterl   nAnSsr[   	fail_raterm   rP   rQ   liletterbr]   rR   r\   rS   s     `   `           @@@@r0   __init__FrozenLakeEnv.__init__   s    <H,&(D\>D::d#66	D,0JJ6	49ztT 133GHD[%'XXddl%;%B%B9%M%S%S%U"""d&@&@&D&D&FF"9>rCAU2Y/YeY//C<'3.		$			1 	1 ;CT{NqA1B!#(^F		31d"34&'(1uk11uk%B "		89QI%&)B3Q)O%&!" &C IIs&T-FsQR-S&TU " # ( "(!4"OOB/&  T	3/R$Y1DEQ499,Q499,
 #
 $E 0Cs   6K0	K+K0+K0c                   U R                   U R                     U   n[        U Vs/ s H  o3S   PM	     snU R                  5      nX$   u  pVpsX`l        Xl        U R
                  S:X  a  U R                  5         [        U5      XsSSU04$ s  snf )Nr   rD   Fprob)r{   r   r
   r8   
lastactionr   renderint)r   r[   transitionstir5   r   r)   s           r0   stepFrozenLakeEnv.stepD  s    ffTVVnQ'k:k!k:DNNK ^
aw&KKM1vqUVQK//  ;s   B
)r=   optionsc                  > [         TU ]  US9  [        U R                  U R                  5      U l        S U l        U R                  S:X  a  U R                  5         [        U R
                  5      SS04$ )N)r=   rD   r   r   )
superresetr
   rx   r8   r   r   r   r   r   )r   r=   r   	__class__s      r0   r   FrozenLakeEnv.resetP  s`     	4 #D$>$>Ow&KKM466{VQK''r2   c                    U R                   cG  U R                  c   e[        R                  R	                  SU R                  R
                   S35        g U R                   S:X  a  U R                  5       $ U R                  U R                   5      $ )NzYou are calling render method without specifying any render mode. You can specify the render_mode at initialization, e.g. gym.make("z", render_mode="rgb_array")rE   )r   specgymloggerwarnid_render_text_render_gui)r   s    r0   r   FrozenLakeEnv.render^  s    #99(((JJOO""&)),,/JL
 v%$$&&##D$4$455r2   c                v    SS K nU R                  c  UR	                  5         US:X  a`  UR
                  R	                  5         UR
                  R                  S5        UR
                  R                  U R                  5      U l        O&US:X  a   UR                  U R                  5      U l        U R                  c   S5       eU R                  c  UR                  R                  5       U l
        U R                  cs  [        R                  " [        R                   " ["        5      S5      nUR$                  R'                  UR(                  R+                  U5      U R,                  5      U l        U R.                  cs  [        R                  " [        R                   " ["        5      S5      nUR$                  R'                  UR(                  R+                  U5      U R,                  5      U l        U R0                  cs  [        R                  " [        R                   " ["        5      S	5      nUR$                  R'                  UR(                  R+                  U5      U R,                  5      U l        U R2                  cs  [        R                  " [        R                   " ["        5      S
5      nUR$                  R'                  UR(                  R+                  U5      U R,                  5      U l        U R4                  cs  [        R                  " [        R                   " ["        5      S5      nUR$                  R'                  UR(                  R+                  U5      U R,                  5      U l        U R6                  Gc  [        R                  " [        R                   " ["        5      S5      [        R                  " [        R                   " ["        5      S5      [        R                  " [        R                   " ["        5      S5      [        R                  " [        R                   " ["        5      S5      /nU Vs/ s HB  nUR$                  R'                  UR(                  R+                  U5      U R,                  5      PMD     snU l        U R8                  R;                  5       n[=        U[>        5      (       d
   SU 35       e[A        U RB                  5       GH8  n[A        U RD                  5       GH  n	XR,                  S   -  XR,                  S   -  4n
/ U
QU R,                  Q7nU R                  RG                  U R0                  U
5        Xx   U	   S:X  a'  U R                  RG                  U R                  U
5        OcXx   U	   S:X  a'  U R                  RG                  U R2                  U
5        O1Xx   U	   S:X  a&  U R                  RG                  U R4                  U
5        URH                  RK                  U R                  SUS5        GM     GM;     U RL                  U RD                  -  U RL                  U RD                  -  pXR,                  S   -  XR,                  S   -  4nU RN                  b  U RN                  OSnU R6                  U   nX|   U   S:X  a'  U R                  RG                  U R.                  U5        OU R                  RG                  UU5        US:X  a]  URP                  RS                  5         UR
                  RU                  5         U R                  RW                  U RX                  S   5        g US:X  aL  [Z        R\                  " [Z        R^                  " UR`                  Rc                  U R                  5      5      SS9$ g ! [         a  n[        S5      UeS nAff = fs  snf )Nr   z@pygame is not installed, run `pip install "gymnasium[toy-text]"`rD   zFrozen LakerF   z;Something went wrong with pygame. This should never happen.zimg/hole.pngzimg/cracked_hole.pngzimg/ice.pngzimg/goal.pngzimg/stool.pngzimg/elf_left.pngzimg/elf_down.pngzimg/elf_right.pngzimg/elf_up.pngz'desc should be a list or an array, got r      H   GrL   )         rI   )r   r   r   )axes)2pygameImportErrorr   r   initdisplayset_captionset_moder   Surfacer   timeClockr   r   r;   dirname__file__	transformscaleimageloadr   r   r   r   r   r   rk   tolist
isinstancelistrz   r\   rR   blitdrawrectr   r   eventpumpupdatetickmetadatarq   	transposeru   	surfarraypixels3d)r   moder   e	file_nameelfsf_namerk   r-   r,   posr   bot_rowbot_col	cell_rectlast_actionelf_imgs                    r0   r   FrozenLakeEnv._render_guim  s   	 &KKMw##%**=9&,nn&=&=d>N>N&O#$&,nnT5E5E&F# +	IH	I+ ::**,DJ== 		$,,x"8.II",,22!!),dnnDM   (		$,,x"8:PQI$*$4$4$:$:!!),dnn%D! <<		$,,x"8-HI!++11!!),dnnDL == 		$,,x"8.II",,22!!),dnnDM >>!		$,,x"8/JI#--33!!),dnnDN ??"		$,,x02DE		$,,x02DE		$,,x02EF		$,,x02BC	D #"F   &&v||'8'8'@$..Q"DO
 yy!$%%W)PQUPV'WW%tyy!A499%>>!,,a..2C.CD..t~~.##((s;71:%'',,T]]C@WQZ4''',,T]]C@WQZ4''',,T^^SA  !4!4otQO & "   66TYY.0B~~a00'NN1<M2MN	)-)Ddoo!//+.=!T)$$T%:%:IF$$Wi87?LLNN!!#JJOODMM,78[ <<))2243F3FGHy  !u  	(R	js   ^ ;A	^6
^3"^..^3c                Z    U S   US   -
  S-  nU S   US   -
  S-  nU S   U-   U S   U-   4$ )Nr   r   r   r   rO   )big_rect
small_dimsoffset_woffset_hs       r0   _center_small_rect FrozenLakeEnv._center_small_rect  sR    QK*Q-/14QK*Q-/14QK("QK("
 	
r2   c           
        U R                   R                  5       n[        5       nU R                  U R                  -  U R                  U R                  -  pCU VVs/ s H#  oU Vs/ s H  ofR                  S5      PM     snPM%     nnn[        R                  " X   U   SSS9X   U'   U R                  b%  UR                  S/ SQU R                      S35        OUR                  S5        UR                  SR                  S	 U 5       5      S-   5        [        U5         UR                  5       sS S S 5        $ s  snf s  snnf ! , (       d  f       g = f)
Nzutf-8redT)	highlightz  ()LeftDownRightUpz)

c              3  D   #    U  H  nS R                  U5      v   M     g7f)r7   N)r;   ).0lines     r0   	<genexpr>-FrozenLakeEnv._render_text.<locals>.<genexpr>  s     ?$$$s    )rk   r   r   r   rR   decoder	   colorizer   writer;   r   getvalue)r   rk   outfilerP   rQ   r   r*   s          r0   r   FrozenLakeEnv._render_text  s   yy!*66TYY&(:S>BCddD1Dq'"D1dC	#N	#??&MMC ? PQQTUVMM$dii?$??$FGW##%  2C s$   	D?$D:>D? E:D?
Ec                |    U R                   b/  SS KnUR                  R                  5         UR                  5         g g )Nr   )r   r   r   quit)r   r   s     r0   closeFrozenLakeEnv.close  s/    *NN!KKM	 +r2   )r{   r~   r   r   r   rk   r   r   r   r   rx   r   rR   r\   r}   r   rt   r   r   r   r   )NNr   TgUUUUUU?)r   r   r   )r   z
str | Nonerk   	list[str]r   strr   boolr   floatrl   ztuple[int, int, int])r=   
int | Noner   zdict | None)__name__
__module____qualname____firstlineno____doc__r   r   r   r   r   r   staticmethodr   r   r   __static_attributes____classcell__)r   s   @r0   rB   rB   T   s    M` 7H #' '09YY Y 	Y
 Y Y .Yv
0  #	( ( 	( (6`D 
 
&  r2   rB   )r%   zlist[list[str]]r&   r   returnr   )   g?N)r<   r   r5   r  r=   r  r  r   )
__future__r   
contextlibr   ior   osr   numpyrq   	gymnasiumr   r   r   r	   gymnasium.envs.toy_text.utilsr
   gymnasium.errorr   gymnasium.utilsr   rV   rX   rY   rZ   rp   r1   r@   rB   rO   r2   r0   <module>r     s    "      ( ( < 2 # 		 ,	 * 7;'
'')3''6YC Yr2   