
    Ii                        S r SSKJrJr  SSKrSrSrS/S-  rS\S'   S\S	'   S
\S'   S\S'   S\S'   S\S'   S\S'   S\S'   \ " S S5      5       r\ " S S5      5       r	S\
S\4S jrS\
S\
4S jrS\	S\
S\4S jrS\	S\
S\4S jrS\	S\
S\SS4S jrS\	S\
S\SS4S jrS\	S \S\
S-  4S! jrS\	S \S\4S" jrS\	S\\   4S# jrS\	S\\   4S$ jrS\	S\
S\4S% jrS\	S\
S\4S& jrS \S\
S\4S' jrS(\S\
S\4S) jrS2S*\R8                  S-  S\\\4   4S+ jjrS3S,\S\	4S- jjrS\	S.\
S\4S/ jr S\	S.\
S\4S0 jr!S\	S.\
S\4S1 jr"g)4z)Serializable state models for Backgammon.    )	dataclassfieldN                                 c                   p    \ rS rSr% Sr\" S S9r\\   \	S'   Sr
\\	S'   Sr\\	S'   Sr\\	S	'   Sr\\	S
'   Srg)BackgammonBoardState   z:Board representation: signed integers per point + bar/off.c                       [        [        5      $ N)listINITIAL_BOARD     <c:\Users\dbart\PlayPalace11\server\games\backgammon\state.py<lambda>BackgammonBoardState.<lambda>   s	    d=6Ir   default_factorypointsr   bar_red	bar_whiteoff_red	off_whiter   N)__name__
__module____qualname____firstlineno____doc__r   r!   r   int__annotations__r"   r#   r$   r%   __static_attributes__r   r   r   r   r      sA    D.IJFDIJGSIsGSIsr   r   c                   N   \ rS rSr% Sr\" \S9r\\S'   \" \	S9r
\	\   \S'   \" \	S9r\	\   \S'   Sr\\S'   S	r\\S
'   Sr\S-  \S'   \" \	S9r\	\   \S'   Sr\\S'   Sr\\S'   Sr\\S'   Sr\\S'   Sr\\S'   Sr\\S'   Sr\\S'   Sr\\S'   Sr\\S'   Sr\\S'   Sr\\S'   Srg)BackgammonGameState$   z-Serializable game-level state for Backgammon.r   boarddice	dice_usedpre_roll
turn_phaseredcurrent_colorNselected_sourcemoves_this_turn   
cube_value 
cube_ownermatch_lengthr   	score_redscore_whiteFis_crawfordcrawford_usedgame_numberTopening_rollopening_die_redopening_die_whiter   ) r&   r'   r(   r)   r*   r   r   r1   r,   r   r2   r+   r3   boolr5   strr7   r8   r9   dictr;   r=   r>   r?   r@   rA   rB   rC   rD   rE   rF   r-   r   r   r   r/   r/   $   s    7"'8L"MEMD1D$s)1!$7ItDz7 J M3"&OS4Z&"'"=OT$Z= JJ L#IsKKM4K L$OSsr   r/   colorreturnc                     U S:X  a  S$ S$ )z Return +1 for red, -1 for white.r6   r:   r   rJ   s    r   
color_signrO   B   s    1&B&r   c                     U S:X  a  S$ S$ )zReturn the other color.r6   whiter   rN   s    r   opponent_colorrR   G   s    un7/%/r   statec                 f    US:X  a  U R                   R                  $ U R                   R                  $ )zGet bar count for a color.r6   r1   r"   r#   rS   rJ   s     r   	bar_countrW   L   '    "'5.5;;Kekk6K6KKr   c                 f    US:X  a  U R                   R                  $ U R                   R                  $ )z Get borne off count for a color.r6   r1   r$   r%   rV   s     r   	off_countr[   Q   rX   r   countc                 R    US:X  a  X R                   l        gX R                   l        g)zSet bar count for a color.r6   NrU   rS   rJ   r\   s      r   set_barr_   V       ~# %r   c                 R    US:X  a  X R                   l        gX R                   l        g)z Set borne off count for a color.r6   NrZ   r^   s      r   set_offrb   ^   r`   r   	point_idxc                 R    U R                   R                  U   nUS:  a  gUS:  a  gg)z.Return color owning a point, or None if empty.r   r6   rQ   N)r1   r!   )rS   rc   vals      r   point_ownerrf   f   s-    
++

Y
'C
Qw	qr   c                 F    [        U R                  R                  U   5      $ )z)Return absolute checker count on a point.)absr1   r!   )rS   rc   s     r   point_countri   p   s    u{{!!),--r   c                     [        U R                  U R                  5       VVs/ s H  u  pU(       a  M  UPM     snn$ s  snnf )z!Return list of unused die values.)zipr2   r3   )rS   duseds      r   remaining_dicern   u   s/     U__=J='!TA=JJJs   ??c                 <    [        [        [        U 5      5      5      $ )z'Return sorted unique unused die values.)sortedsetrn   )rS   s    r   remaining_dice_uniquerr   z   s    #nU+,--r   c                     [        U5      n[        X5      nUS:  a  g[        [        5       HD  nU R                  R
                  U   nXR-  S:  d  M&  US:X  a  US:  a    gUS:X  d  M<  US:  d  MD    g   g)zHCheck if all checkers are in the home board (points 1-6 for that color).r   Fr6   r	   rQ   r   T)rO   rW   range
NUM_POINTSr1   r!   )rS   rJ   signon_barire   s         r   all_checkers_in_homery      st    eDu$Fz :kk  #:>~!a%AF  r   c                    Sn[        U5      n[        [        5       HM  nU R                  R                  U   nXS-  S:  d  M&  [        U5      nUS:X  a  X&US-   -  -  nMC  X&SU-
  -  -  nMO     U[        X5      S-  -  nU$ )z Calculate pip count for a color.r   r6   r:   r   r   )rO   rt   ru   r1   r!   rh   rW   )rS   rJ   totalrv   rx   re   r\   s          r   	pip_countr|      s    EeD:kk  #:>HE~ !a%( "q&))  
Yu$r))ELr   c                 "    US:X  a  U S-   $ SU -
  $ )zConvert internal index to player-facing point number.

Red sees index 0 as point 1, index 23 as point 24.
White sees index 23 as point 1, index 0 as point 24.
r6   r:   r   r   )rc   rJ   s     r   point_number_for_playerr~      s     ~1}I~r   	point_numc                 "    US:X  a  U S-
  $ SU -
  $ )z5Convert player-facing point number to internal index.r6   r:   r   r   )r   rJ   s     r   player_point_to_indexr      s    ~1}I~r   rngc                 h    U =(       d    [         nUR                  SS5      UR                  SS5      4$ )zRoll two dice.r:      )randomrandint)r   rs     r   	roll_dicer      s*    vAIIaOQYYq!_--r   r>   c                 >    [        [        [        [        5      S9U S9$ )z.Build initial state for a new backgammon game.)r!   )r1   r>   )r/   r   r   r   )r>   s    r   build_initial_game_stater      s    "$}*=>! r   loser_colorc                     [        X5      S:H  $ )z=Check if the loser has been gammoned (no checkers borne off).r   )r[   rS   r   s     r   	is_gammonr      s    U(A--r   c                 >   [        X5      (       d  g[        X5      S:  a  g[        U5      nUS:X  a6  [        SS5       H%  nU R                  R
                  U   U-  S:  d  M%    g   g[        SS5       H%  nU R                  R
                  U   U-  S:  d  M%    g   g)zCheck if the loser has been backgammoned.

Backgammon: loser has no checkers off AND has checkers on the bar
or in the winner's home board.
Fr   Tr6   r   r   r   )r   rW   rO   rt   r1   r!   )rS   r   rv   rx   s       r   is_backgammonr      s     U(($q(k"Der2A{{!!!$t+a/   q!A{{!!!$t+a/  r   c                 H    [        X5      (       a  g[        X5      (       a  gg)z=Calculate game multiplier (1=single, 2=gammon, 3=backgammon).r   r   r:   )r   r   r   s     r   game_multiplierr      s!    U(($$r   r   )r:   )#r*   dataclassesr   r   r   ru   CHECKERS_PER_PLAYERr   r   r/   rH   r+   rO   rR   rW   r[   r_   rb   rf   ri   r   rn   rr   rG   ry   r|   r~   r   Randomtupler   r   r   r   r   r   r   r   <module>r      s   / (  
 
 bb b a a a b b b       :'c 'c '
0# 0# 0
L( L L L
L( L L L
&& &s &3 &4 &&& &s &3 &4 &* s sTz .* .s .s .
K- K$s) K
.!4 .c .
 3 C D $(   *	s 	3 	3 	S   .6==4' .5c? .3 7J .( .s .t .
, 3 4 2. S S r   