
    Ii                     L   % S r SSKJrJr  SSKrSrSrSrSrSr	\
\S4   \S	'   S
r\
\S4   \S'   \ " S S5      5       rS\\   4S jrS\S\\   4S jr\ " S S5      5       r\ " S S5      5       r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\\   4S jrS-S\\   S \R4                  S-  SS4S! jjr S-S"\S \R4                  S-  S\S-  4S# jjrS"\SS4S$ jrS"\S\\\\
\\4      4   4S% jr\S&S'SS(.S)\\   S\S*\ S+\ S \R4                  S-  S\4S, jjr!g).z6Serializable state models and board helpers for Sorry.    )	dataclassfieldN<         )r         -   .SEAT_START_TRACKS)1234578101112sorry
CARD_FACESc                   T    \ rS rSr% Sr\\S'   Sr\\S'   Sr	\S-  \S'   Sr
\\S	'   S
rg)SorryPawnState   z&State for one pawn on the Sorry board.
pawn_indexstartzoneNtrack_positionr   
home_steps )__name__
__module____qualname____firstlineno____doc__int__annotations__r   strr   r   __static_attributes__r        7c:\Users\dbart\PlayPalace11\server\games\sorry\state.pyr   r      s,    0OD#!%NC$J%Jr*   r   returnc                  `    [        [        5       V s/ s H  n [        U S-   S9PM     sn $ s  sn f )z(Create default pawn states for a player.   r   )rangePAWNS_PER_PLAYERr   )is    r+   create_default_pawnsr3   &   s+    6;<L6MN6MNa!e,6MNNNs   +pawns_per_playerc                 X    [        U 5       Vs/ s H  n[        US-   S9PM     sn$ s  snf )z8Create pawn states for the requested profile pawn count.r.   r/   )r0   r   )r4   r2   s     r+   create_pawns_for_countr6   +   s+    6;<L6MN6MNa!e,6MNNNs   'c                   ^    \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \" \	S9r
\\   \S'   S	rg
)SorryPlayerState0   z(Serializable board state for one player.	player_id
seat_indexstart_trackhome_entry_trackdefault_factorypawnsr    N)r!   r"   r#   r$   r%   r(   r'   r&   r   r3   r@   listr   r)   r    r*   r+   r8   r8   0   s0    2NO"'8L"ME4Mr*   r8   c                       \ rS rSr% Sr\" \S9r\\   \	S'   \" \
S9r\
\\4   \	S'   \" \S9r\\   \	S'   \" \S9r\\   \	S'   Sr\S-  \	S	'   S
r\\	S'   Sr\\	S'   Sr\S-  \	S'   Sr\S-  \	S'   Srg)SorryGameState;   z(Serializable game-level state for Sorry.r>   player_orderplayer_states	draw_pilediscard_pileNcurrent_carddraw
turn_phaser.   turn_numbersplit_pawn_asplit_pawn_br    )r!   r"   r#   r$   r%   r   rA   rE   r(   r'   dictrF   r8   rG   rH   rI   rK   rL   r&   rM   rN   r)   r    r*   r+   rC   rC   ;   s    2#D9L$s)916t1LM4--.L 6ItCy6#D9L$s)9#L#*#JK#L#*##L#*#r*   rC   positionc                     U [         -  $ )z0Normalize a track position to 0..TRACK_LENGTH-1.)TRACK_LENGTH)rP   s    r+   normalize_track_positionrS   J   s    l""r*   r;   c                 "    [         U [        -     $ )z+Get track entry position for a player seat.)r   MAX_PLAYERS)r;   s    r+   get_start_track_for_seatrV   O   s    Z+566r*   c                 4    [        U 5      n[        US-
  5      $ )z<Get track square just before entering this seat's home path.r.   )rV   rS   )r;   r<   s     r+   get_home_entry_track_for_seatrX   T   s    *:6K#K!O44r*   r   endc                     [        X-
  5      $ )z;Compute clockwise steps from one track position to another.)rS   )r   rY   s     r+   clockwise_distancer[   Z   s    #CK00r*   c                  N    / n [          H  nU R                  U/S-  5        M     U $ )zBBuild classic deck composition used by the current baseline rules.r   )r   extend)deckcards     r+   build_default_draw_piler`   _   s(    DTFQJ Kr*   cardsrngc                 Z    Uc  [         R                  " U 5        gUR                  U 5        g)zShuffle card list in place.N)randomshuffle)ra   rb   s     r+   shuffle_cardsrf   g   s"    
{uKKr*   statec                    U R                   (       dB  U R                  (       a1  U R                  SS U l         / U l        [        U R                   U5        U R                   (       d  gU R                   R                  5       nX l        U$ )z?Draw next card, reshuffling discard into draw pile when needed.N)rG   rH   rf   poprI   )rg   rb   r_   s      r+   draw_next_cardrj   o   sb    
 ??u11,,Q/eoos+???? DKr*   c                 x    U R                   c  gU R                  R                  U R                   5        SU l         g)z>Move current card to discard pile and clear current card slot.N)rI   rH   append)rg   s    r+   discard_current_cardrm      s3    !	e001Er*   c                 6   0 nU R                   R                  5        Hx  u  p#UR                   Hc  nUR                  S:w  d  UR                  c  M"  [        UR                  5      nUR                  U/ 5      R                  X$R                  45        Me     Mz     U$ )z4Return mapping of track position to occupying pawns.track)	rF   itemsr@   r   r   rS   
setdefaultrl   r   )rg   	occupancyr:   player_statepawnposs         r+   get_track_occupancyrv      s     35I#(#6#6#<#<#>	 &&DyyG#t':':'B*4+>+>?C  b)00)__1MN	 ' $? r*   FT)r4   faster_setup_one_pawn_outshuffle_deckrb   
player_idsrw   rx   c          
         [        U 5      [        :  a  [        S5      eUS:  a  [        S5      e0 nU SS n[        U5       Ht  u  px[	        U5      n	[        U5      n
[        UUU	U
[        U5      S9nU(       a8  UR                  (       a'  SUR                  S   l	        XR                  S   l
        XU'   Mv     [        5       nU(       a  [        X5        [        UUUS9$ )	z0Build initial serializable state for a new game.z Sorry supports at most 4 playersr.   z+Sorry requires at least one pawn per playerN)r:   r;   r<   r=   r@   ro   r   )rE   rF   rG   )lenrU   
ValueError	enumeraterV   rX   r8   r6   r@   r   r   r`   rf   rC   )ry   r4   rw   rx   rb   rF   ordered_player_idsr;   r:   r<   r=   rs   rG   s                r+   build_initial_game_stater      s     :$;<<!FGG13M#A!*+=!>
.z:8D'!#-()9:
 %););)0Lq!&3>q!0#/i  "? ()Ii%'# r*   )N)"r%   dataclassesr   r   rd   rR   SAFETY_LENGTHr1   rU   r   tupler&   r'   r   r(   r   rA   r3   r6   r8   rC   rS   rV   rX   r[   r`   Randomrf   rj   rm   rO   rv   boolr   r    r*   r+   <module>r      s   < (   %4 5c? 4
E#s(O    Od>2 O
OS OT.5I O
 N N N $ $ $#s #s #
7 7 7
5c 5c 51c 1 1 1
c c )=   !%		 	4Z  4 	#tE#s(O$
$%" -&+ $'S	' '  $	'
 ' 
	' 'r*   