
    hiE                        % S r SSKrSSKrSSKJrJr  SSKrSSKJr	  SSKr
SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SS	KJrJrJr  SS
KJrJr  SSKJr  SSKJr  \R>                  r \\!S'   \"S\#\$4   r%\	RL                  " / SQ5      r' " S S\5      r(S r)S r*S r+S r,S r-S r.S r/S r0S r1S r2S r3S r4S r5\Rl                   " S S 5      5       r7 " S! S"\\(\R>                  \$\8\9\%\74   5      r: " S# S$\\5      r;\<S%:X  at   \" \;" S&S'95      r=\=R}                  5       u  r?r@\A" \?\@5        S(rB\B(       d:  \$" \C" S)5      5      rD\=R                  \D5      u  r?rFrBrGr@\A" \?\F\B\G\@5        \B(       d  M:  \H" 5         gg)*zjThis module provides a Blackjack functional environment and Gymnasium environment wrapper BlackJackJaxEnv.    N)
NamedTuple	TypeAlias)struct)random)spaces)FunctionalJaxEnv)DependencyNotInstalled)ActTypeFuncEnv	StateType)EzPickleseeding)AutoresetMode)HumanRenderingPRNGKeyTypezpygame.Surface)                        	   
   r   r   r   c                   t    \ rS rSr% Sr\R                  \S'   \R                  \S'   \\S'   \\S'   \\S'   Sr	g	)
EnvState   zBA named tuple which contains the full state of the blackjack game.dealer_handplayer_handdealer_cardsplayer_cardsdone N)
__name__
__module____qualname____firstlineno____doc__jaxArray__annotations__int__static_attributes__r$       Z/home/james-whalen/.local/lib/python3.13/site-packages/gymnasium/envs/tabular/blackjack.pyr   r      s*    L
Ir/   r   c                 `    X:  R                  [        5      X:  R                  [        5      -
  $ )z)Returns 1 if a > b, otherwise returns -1.)astyper-   )abs     r0   cmpr5   '   s#    E>>#!%!444r/   c                     [         R                  " U 5      S   n [         R                  " U [        SS9nUS   R	                  [
        5      U 4$ )z(Draws a randowm card (with replacement).r   )r   )shape)r   splitchoicedeckr2   r-   )keyr9   s     r0   random_cardr<   ,   sA    
,,s
A
C]]3D1F!9C #%%r/   c                     [        U 5      u  p UR                  S   R                  U5      n[        U 5      u  p UR                  S   R                  U5      nX4$ )z*Draws a starting hand of two random cards.r   r   r<   atset)r;   handnew_cards      r0   	draw_handrC   4   sN    $MH771:>>(#D$MH771:>>(#D9r/   c                 f    [        U 5      u  p0UR                  U   R                  U5      nXUS-   4$ )z'Draws a new card and adds it to a hand.r   r>   )r;   rA   indexrB   s       r0   	draw_cardrF   =   s5    $MH775>h'Deair/   c                     [         R                  " [         R                  " U S:H  5      [         R                  " U 5      S-   S:*  5      $ )z(Checks to se if a hand has a usable ace.r   r      )jnplogical_andanysumrA   s    r0   
usable_acerN   D   s2    ??377419-swwt}r/AR/GHHr/   c                     U u  pUR                   nUR                  nUR                  nUR                  n[	        X$U5      u  p'nUS-   n	[        UUUU	SS9U4$ )zAThis function is called if the player has decided to take a card.r   r   r   r    r!   r"   r#   )r   r    r!   r"   rF   r   )
	env_statestater;   r   r    r!   r"   new_player_hand_new_player_cardss
             r0   takerV   I   sy    JE##K##K%%L%%L',GC!#a'
 	#'%)	
 		 	r/   c                 $    [        U S   5      S:  $ )z;This function determines if the dealer should stop drawing.r      sum_handvals    r0   dealer_stopr]   a   s    CFb  r/   c                     [        U 6 $ )zWrapper function for draw_card.)rF   r[   s    r0   draw_card_wrapperr_   f   s    c?r/   c                     U u  pUR                   nUR                  nUR                  nUR                  n[        R
                  R                  [        [        X#U45      u  p#n[        UUUUSS9U4$ )zThis function is called if the player has decided to not take a card.

Calling this function ends the active portion
of the game and turns control over to the dealer.
r   rP   )
r   r    r!   r"   r*   lax
while_loopr]   r_   r   )rQ   rR   r;   r   r    r!   r"   s          r0   notakerc   k   s     JE##K##K%%L%%L%(WW%7%7	<(&"Cl 	##%%	
 		 	r/   c                 L    [         R                  " U 5      S[        U 5      -  -   $ )z#Returns the total points in a hand.r   )rI   rL   rN   rM   s    r0   rZ   rZ      s    774=BD!1122r/   c                     [        U 5      S:  $ )z*Returns whether or not the hand is a bust.rH   rY   rM   s    r0   is_bustrf      s    D>Br/   c                 X    [         R                  " [        U 5      5      [        U 5      -  $ )z*Returns the score for a hand(0 if a bust).)rI   logical_notrf   rZ   rM   s    r0   scoreri      s    OOGDM*htn<<r/   c           	          [         R                  " [         R                  " [         R                  " U 5      S:H  [         R                  " U S:H  5      S:  5      [         R                  " U S:H  5      S:  5      $ )z+Returns if the hand is a natural blackjack.r   r   r   r   )rI   rJ   count_nonzerorM   s    r0   
is_naturalrl      sa    ??d#q(3+<+<TQY+G!+K	
 
		42:	&	*	 r/   c                   6    \ rS rSr% SrSr\\S'   Sr\\S'   Sr	g)	BlackJackParams   z-Parameters for the jax Blackjack environment.FnaturalTsutton_and_bartor$   N)
r%   r&   r'   r(   r)   rp   boolr,   rq   r.   r$   r/   r0   rn   rn      s    7GT!d!r/   rn   c                   b   \ rS rSrSr\R                  " S5      r\R                  " \	R                  " / SQ5      \	R                  " / SQ5      S\	R                  S9rS/S	\R                  S
.r\4S\S\\R(                  -  S\S\S\4
S jjr\4S\S\S\4S jjr\4S\S\S\S\R(                  4S jjr\4S\S\S\S\R(                  4S jjr\4S\S\S\S\S\S\R(                  4S jjr S S\S\S\4S jjr\4S\S\S\S\\\	R@                  4   4S jjr!\4S\S\SS4S jjr"S\4S jr#Sr$g)!BlackjackFunctional   a}	  Blackjack is a card game where the goal is to beat the dealer by obtaining cards that sum to closer to 21 (without going over 21) than the dealers cards.

### Description
Card Values:

- Face cards (Jack, Queen, King) have a point value of 10.
- Aces can either count as 11 (called a 'usable ace') or 1.
- Numerical cards (2-9) have a value equal to their number.

This game is played with an infinite deck (or with replacement).
The game starts with the dealer having one face up and one face down card,
while the player has two face up cards.

The player can request additional cards (hit, action=1) until they decide to stop (stick, action=0)
or exceed 21 (bust, immediate loss).
After the player sticks, the dealer reveals their facedown card, and draws
until their sum is 17 or greater.  If the dealer goes bust, the player wins.
If neither the player nor the dealer busts, the outcome (win, lose, draw) is
decided by whose sum is closer to 21.

### Action Space
There are two actions: stick (0), and hit (1).

### Observation Space
The observation consists of a 3-tuple containing: the player's current sum,
the value of the dealer's one showing card (1-10 where 1 is ace),
and whether the player holds a usable ace (0 or 1).

This environment corresponds to the version of the blackjack problem
described in Example 5.1 in Reinforcement Learning: An Introduction
by Sutton and Barto (http://incompleteideas.net/book/the-book-2nd.html).

### Rewards
- win game: +1
- lose game: -1
- draw game: 0
- win game with natural blackjack:

    +1.5 (if <a href="#nat">natural</a> is True)

    +1 (if <a href="#nat">natural</a> is False)

### Arguments

```
gym.make('Jax-Blackjack-v0', natural=False, sutton_and_barto=False)
```

<a id="nat">`natural=False`</a>: Whether to give an additional reward for
starting with a natural blackjack, i.e. starting with an ace and ten (sum is 21).

<a id="sutton_and_barto">`sutton_and_barto=False`</a>: Whether to follow the exact rules outlined in the book by
Sutton and Barto. If `sutton_and_barto` is `True`, the keyword argument `natural` will be ignored.
If the player achieves a natural blackjack and the dealer does not, the player
will win (i.e. get a reward of +1). The reverse rule does not apply.
If both the player and the dealer get a natural, it will be a draw (i.e. reward 0).

### Version History
* v0: Initial version release (0.0.0), adapted from original gym blackjack v1
r   )r   r   r   )       r   )r   )lowhighr7   dtype	rgb_arrayr   )render_modes
render_fpszautoreseet-moderR   actionr;   paramsreturnc                 .   [         R                  R                  U[        [        X45      nUu  pcUR
                  nUR                  nUR                  n	UR                  n
[        U5      U-  [        R                  " U5      S-  -   n[        UUU	U
US9nU$ )z6The blackjack environment's state transition function.r   rP   )r*   ra   condrV   rc   r   r    r!   r"   rf   rI   rh   r   )selfrR   r~   r;   r   rQ   
hand_stater   r    r!   r"   r#   	new_states                r0   
transitionBlackjackFunctional.transition   s     GGLLv|D	#
 ,, ,,!..!.. $v-3??63Ja2OP##%%
	 r/   rngc                     [         R                  " S5      n[         R                  " S5      n[        X5      u  p1[        X5      u  pASnSn[        UUUUSS9nU$ )z(Blackjack initial observataion function.rH   r   r   rP   )rI   zerosrC   r   )r   r   r   r    r   r!   r"   rR   s           r0   initialBlackjackFunctional.initial  sb     iimiim$S6$S6##%%
 r/   c                     [         R                  " [        UR                  5      UR                  S   [        UR                  5      S-  /[        R                  S9$ )zBlackjack observation.r   g      ?)rz   )rI   arrayrZ   r    r   rN   npint32r   rR   r   r   s       r0   observationBlackjackFunctional.observation)  sR     yy**+!!!$5,,-3
 ((
 	
r/   c                      UR                   S:  $ )z=Determines if a particular Blackjack observation is terminal.r   )r#   r   s       r0   terminalBlackjackFunctional.terminal9  s     

ar/   
next_statec                 p   UnUR                   nUR                  nS[        U5      S-  U-  -   [        R                  " U5      [        [        U5      [        U5      5      -  -   nUR                  (       aS  UR                  (       dB  [        R                  " [        U5      US:H  5      n	U[        R                  " U	5      -  SU	-  -   nUR                  (       a\  [        R                  " [        U5      [        R                  " [        U5      5      5      n	U[        R                  " U	5      -  SU	-  -   nU$ )zCalculates reward from a state.g        r         ?)r   r    rf   rI   rh   r5   ri   rp   rq   rJ   rl   )
r   rR   r~   r   r   r   r   r    reward	conditions
             r0   r   BlackjackFunctional.rewardB  s    '''' {#b(613'3u[/A5CU+VVX 	 >>&"9"9
;(?&A+OIcooi883?JF
 "";'K9P)QI cooi881y=HFr/   screen_widthscreen_heightc                     SSK n[        R                  " S5      S   n/ SQnUR                  U5      nUR                  / SQ5      nUR                  5         UR                  X45      nXU4$ ! [         a    [        S5      ef = f)z Returns an initial render state.r   NGpygame is not installed, run `pip install "gymnasium[classic_control]"`)CDHS)JQK)pygameImportErrorr	   r   	np_randomr9   initSurface)	r   r   r   r   r   suitsdealer_top_card_suitdealer_top_card_value_strscreens	            r0   render_initBlackjackFunctional.render_initf  s    	 "1%$"zz%0$'JJ$?! =>2FFF  	(Y 	s   A- -Brender_statec           
      &  ^^ ^!  SSK m!Uu  pEnU R                  US5      u  pxn	Su  pUS-  m[	        TS-  S-  5      m US-  nS	nS
nUS:X  a  SnO(US:X  a  UnO[        [        R                  " U5      5      nUR                  U5        U!4S jnU!4S jnU" [        R                  R                  SS5      US-  5      nUR                  S[        U5      -   SU5      nUR                  UX45      nUU U!4S jnU" U" [        R                  R                  SU U S35      5      5      nUR                  UU
S-  T -
  US-  -
  UR                  U-   45      nU" U" [        R                  R                  SS5      5      5      nUR                  UU
S-  US-  -   UR                  U-   45        UR                  SSU5      nUR                  UUUR                  SU-  -   45      nU" [        R                  R                  SS5      US-  5      nUR                  [        U5      SU5      nUR                  UU
S-  UR                  5       S-  -
  UR                  U-   45      nU	(       aN  UR                  SSU5      nUR                  UU
S-  UR                  5       S-  -
  UR                  US-  -   45        U[         R"                  " [         R$                  " T!R&                  R)                  U5      5      SS94$ ! [         a    [        S5      ef = f) zRenders an image from a state.r   Nz@pygame is not installed, run `pip install "gymnasium[toy_text]"`iX  i  r            )r   c   $   )   r   r   r   Ar   c                 >  > [         R                  R                  [        5      n[         R                  R	                  US5      n[         R                  R	                  US5      nTR
                  R                  [         R                  R	                  X5      5      nU$ Nz..toy_text)ospathdirname__file__joinimageload)r   cwdr   r   s      r0   	get_image3BlackjackFunctional.render_image.<locals>.get_image  sc    ''//(+C'',,sD)C'',,sJ/CLL%%bggll3&=>ELr/   c                 @  > [         R                  R                  [        5      n[         R                  R	                  US5      n[         R                  R	                  US5      nTR
                  R                  [         R                  R	                  X 5      U5      nU$ r   )r   r   r   r   r   fontFont)r   sizer   r   r   s       r0   get_font2BlackjackFunctional.render_image.<locals>.get_font  se    ''//(+C'',,sD)C'',,sJ/C;;##BGGLL$;TBDKr/   r   zMinecraft.ttf   zDealer: Tc                 @   > TR                   R                  U TT45      $ N)	transformscale)card_imgcard_img_heightcard_img_widthr   s    r0   scale_card_img8BlackjackFunctional.render_image.<locals>.scale_card_img  s!    ##))(^_4UVVr/   imgz.pngr   zCard.pngPlayerr   r   z
usable ace)r   r   r   )axes)r   r   r	   r   r-   strmathfloorfillr   r   r   renderblitbottom	get_widthr   	transposer   	surfarraypixels3d)"r   rR   r   r   r   r   r   
player_sumdealer_card_valuerN   r   r   spacingbg_colorwhitedisplay_card_valuer   r   
small_fontdealer_textdealer_text_rectr   dealer_card_imgdealer_card_recthidden_card_imgplayer_textplayer_text_rect
large_fontplayer_sum_textplayer_sum_text_rectusable_ace_textr   r   r   s"                                  @@@r0   render_image BlackjackFunctional.render_image{  sN   	
 CO?+?484D4DUD4Q1
z&.#'1,_s2S892%!!$"$!:!$TZZ0A%B!CH		 GGLL1=B3F

 !''.//u
 ";;{W4FG	W )+,-?,@E
 ";;!N2W\A '''1
 )277<<z3R)ST!GqL0 '''1	
 !''$>!;;'#3#:#:S7]#JK
 bggll6?C]VWEWX
$++C
OT5I%{{!O$=$=$?1$DD '''1 
 (//dEJOKK A%(A(A(Cq(HH(//'Q,> R\\HHV%%..v67i
 
 	
E  	(R 	s   K: :LNc                      SSK nUR                  R	                  5         UR	                  5         g! [         a  n[        S5      UeSnAff = f)zCloses the render state.r   Nr   )r   r   r	   displayquit)r   r   r   r   es        r0   render_close BlackjackFunctional.render_close  sJ    	
 	  	(Y	s   1 
AAAc                     [        S0 UD6$ )zGet the default params.r$   )rn   )r   kwargss     r0   get_default_params&BlackjackFunctional.get_default_params  s    (((r/   r$   r   )%r%   r&   r'   r(   r)   r   Discreteaction_spaceBoxr   r   r   observation_spacer   	NEXT_STEPmetadatarn   r   r-   r*   r+   r   r   r   r   r   r
   r   RenderStateTyper   r   tuplendarrayr   r  r  r.   r$   r/   r0   rt   rt      s   ;z ??1%L

HHYbhh{&;4rxx
 %(22H #2 cii 	
   
> ;J(7	2 #2	

 
  	

 

( #2	      	 
 
  #2"" " 	"
 "  " 
"J =@GG69G	G2 #2	m
m
 &m
  	m

 


*	+m
` HW+5D	)o )r/   rt   c                   L   ^  \ rS rSrSrS/SSS.rSS\S-  4U 4S	 jjjrS
rU =r	$ )BlackJackJaxEnvi  z9A Gymnasium Env wrapper for the functional blackjack env.r{   2   T)r|   r}   r*   Nrender_modec                    > [         R                  " U 4SU0UD6  [        S0 UD6nUR                  [        R
                  5        [        TU ]  UU R                  US9  g)z5Initializes Gym wrapper for blackjack functional env.r  )r  r  Nr$   )r   __init__rt   r   r*   jitsuperr  )r   r  r  env	__class__s       r0   r  BlackJackJaxEnv.__init__  sW    $BKB6B!+F+cgg]]# 	 	
r/   r$   r   )
r%   r&   r'   r(   r)   r  r   r  r.   __classcell__)r  s   @r0   r  r    s)    C!,RMH

C$J 

 

r/   r  __main__r{   )r  FzPlease input an action
)Ir)   r   r   typingr   r   r*   	jax.numpynumpyrI   r   flaxr   r   	gymnasiumr   !gymnasium.envs.functional_jax_envr   gymnasium.errorr	   !gymnasium.experimental.functionalr
   r   r   gymnasium.utilsr   r   gymnasium.vectorr   gymnasium.wrappersr   r+   r   r,   r  r   r-   r  r   r:   r   r5   r<   rC   rF   rN   rV   r]   r_   rc   rZ   rf   ri   rl   	dataclassrn   floatrr   rt   r  r%   r  resetobsinfoprintr   inputr~   stepr   	truncatedexitr$   r/   r0   <module>r2     s   p  	 ( 
      > 2 I I - * - Y "(#s23 yy<=z 5
& I
0!

<3

=
 " " "O)HciieT?OSTO)d

& 
. z [A
BC		IC	#tHU56714&1A.VXy$c68Y5 h
 	F! r/   