
    Iih                     L   % S r SSKJr  SSKJr  SSKJrJrJrJ	r	J
r
Jr  \" SS9 " S S	5      5       rS
SS.r\\\4   \S'   \" SS9 " S S5      5       r\" SS9 " S S5      5       rS\	S\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\	S\S \\   S-  S\4S! j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 S\S\	S\\   4S' jr!S\	S\S\\   4S( jr"S\	S)\S*\S\4S+ jr#S\	S\\   4S, jr$S\	S-\S.\S\\   4S/ jr%S\S\	S0\S1\S\\   4
S2 jr&S\SS4S3 jr'S\S\SS4S4 jr(S\S\	S5\S-  S\\   4S6 jr)S\S\	S\S1\S\\   4
S7 jr*S\S\	S8\S1\S\\   4
S9 jr+g):z9Move models and generation/application helpers for Sorry.    )	dataclass   )SorryRulesProfile)SAFETY_LENGTHSorryGameStateSorryPawnStateSorryPlayerStateclockwise_distancenormalize_track_positionT)frozenc                   8    \ rS rSr% Sr\\S'   \\S'   \\S'   Srg)CaptureEvent   z(Records a pawn being sent back to start.captured_player_idcaptured_pawn_indexby_player_id N)	__name__
__module____qualname____firstlineno____doc__str__annotations__int__static_attributes__r       7c:\Users\dbart\PlayPalace11\server\games\sorry\moves.pyr   r      s    2r   r         )r   	   _SLIDE_START_TO_STEPS_BY_OFFSETc                   F    \ rS rSr% Sr\\S'   Sr\S-  \S'   Sr	\\S'   Sr
g)	PawnDestination   z Destination for a pawn movement.zoneNtrack_positionr   
home_stepsr   )r   r   r   r   r   r   r   r'   r   r(   r   r   r   r   r$   r$      s"    *
I!%NC$J%Jr   r$   c                       \ rS rSr% Sr\\S'   \\S'   \\S'   Sr\S-  \S'   Sr	\S-  \S'   Sr
\S-  \S	'   Sr\S-  \S
'   Sr\S-  \S'   Sr\S-  \S'   Srg)	SorryMove(   z$A legal move candidate for a player.	action_id	move_typedescriptionN
pawn_indexstepssecondary_pawn_indexsecondary_stepstarget_player_idtarget_pawn_indexr   )r   r   r   r   r   r   r   r/   r   r0   r1   r2   r3   r4   r   r   r   r   r*   r*   (   sl    .NN!Jd
!E3:'+#*+"&OS4Z&#'cDj'$(sTz(r   r*   player_stater/   Nreturnc                 n    Uc  g US:  d  U[        U R                  5      :  a  g U R                  US-
     $ )Nr   )lenpawns)r5   r/   s     r   	_get_pawnr:   7   s>     A~c,*<*<&==j1n--r   state	player_idc                 @    Uc  g U R                   R                  U5      $ N)player_statesget)r;   r<   s     r   _player_by_idrA   B   s$     ""9--r   pawnr0   c                    US::  a  g UR                   S:X  a  g UR                   S:X  a:  UR                  U-   nU[        ::  a
  [        SUS9$ U[        S-   :X  a	  [        SS9$ g UR                   S:w  d  UR                  c  g [        UR                  U R                  5      nX$::  a   [        S[        UR                  U-   5      S9$ X$-
  nU[        ::  a
  [        SUS9$ U[        S-   :X  a	  [        SS9$ g )	Nr   home	home_path)r&   r(   r   )r&   trackr&   r'   )r&   r(   r   r$   r'   r
   home_entry_trackr   )r5   rB   r0   
next_stepsdistance_to_home_entry	remainings         r   _compute_forward_destinationrL   K   s   
 zyyFyyK__u,
&"
KK**"//yyGt22:/%%
 &3D4G4G%4OP
 	

 .IM!KIFFMA%%F++r   c                     US::  a  g U R                   S:w  d  U R                  c  g [        S[        U R                  U-
  5      S9$ )Nr   rF   rG   )r&   r'   r$   r   )rB   r0   s     r   _compute_backward_destinationrN   t   sK     zyyGt22:/0C0Ce0KL r   ignore_pawn_indexesdestinationrP   c                   U=(       d
    [        5       nU R                   H  nUR                  U;   a  M  UR                  S:X  aZ  UR                  S:X  aH  UR                  b9  [        UR                  5      [        UR                  =(       d    S5      :X  a    gM{  M}  M  UR                  S:X  d  M  UR                  S:X  d  M  UR                  UR                  :X  d  M    g   g)NrF   r   FrE   T)setr9   r/   r&   r'   r   r(   )r5   rQ   rP   ignorerB   s        r    _is_destination_legal_for_playerrU      s     !)CEF""??f$w&		W$''3,T-@-@A+K,F,F,K!LM M 4 % ,yyK'DOO{?U?U,U # r   c                     U R                    Vs/ s H&  nUR                  S:X  d  M  UR                  c  M$  UPM(     sn$ s  snf )NrF   )r9   r&   r'   )r5   rB   s     r   _iter_track_pawnsrW      sI    
 !&&&D99 	$($7$7 	&  s   ???c           
      $   [        SUR                  S9n[        X5      (       d  / $ / nUR                   HU  nUR                  S:w  a  M  UR                  [        SUR                   3SSUR                   S3UR                  S95        MW     U nU$ )NrF   rG   startstart_p
Move pawn z out of start)r,   r-   r.   r/   )r$   start_trackrU   r9   r&   appendr*   r/   )r;   r5   rQ   movesrB   _s         r   _generate_start_movesr`      s     "#//K ,LFF	E""99#DOO#45!((9G??		
 # 	ALr   c                    / nU R                    Hw  n[        XU5      nUc  M  [        U UUR                  1S9(       d  M1  UR	                  [        SU SUR                   3SSUR                   SU 3UR                  US95        My     U$ )NrO   forward_pr[   	 forward r,   r-   r.   r/   r0   r9   rL   rU   r/   r]   r*   r5   r0   r^   rB   rQ   s        r   _generate_forward_movesrh      s      E""2<uM/!% 1

 #E7"T__,=>#((95'J??	
 #& Lr   c                    / nU R                    Hv  n[        X15      nUc  M  [        U UUR                  1S9(       d  M0  UR	                  [        SU SUR                   3SSUR                   SU 3UR                  US95        Mx     U$ )NrO   backwardrc   r[   z
 backward re   )r9   rN   rU   r/   r]   r*   rg   s        r   _generate_backward_movesrk      s      E""3D@/!% 1

 $UG2doo->?$((9E7K??	
 #& Lr   c                    [        U5      nU(       d  / $ / nU H  nU R                  R                  5        H  u  pVXQR                  :X  a  M  [        U5       Hn  nUR	                  [        SUR                   SU SUR                   3SSUR                   SU SUR                   3UR                  UUR                  S95        Mp     M     M     U$ )	Nswap_pr_   rc   swapz
Swap pawn z with  pawn r,   r-   r.   r/   r3   r4   )rW   r?   itemsr<   r]   r*   r/   )r;   r5   	own_trackr^   own_pawnopponent_idopponent_statetargets           r   _generate_swap_movesrw      s     ",/I	E+0+>+>+D+D+F'K444+N;$X%8%8$9;-r&J[J[I\]"(()<)<(=V*m6&2C2C1DF $,#6#6)4*0*;*; < ,G ( Lr   c                 V   UR                    Vs/ s H  o"R                  S:X  d  M  UPM     nnU(       d  / $ / nU H  nU R                  R                  5        H  u  pgXaR                  :X  a  M  [        U5       H  n[        SUR                  S9n	[        UU	UR                  1S9(       d  M4  UR                  [        SUR                   SU SUR                   3SS	UR                   S
U SUR                   3UR                  UUR                  S95        M     M     M     U$ s  snf )NrY   rF   rG   rO   sorry_pr_   rc   sorryr[   z to replace ro   rp   )r9   r&   r?   rq   r<   rW   r$   r'   rU   r/   r]   r*   )
r;   r5   rB   start_pawnsr^   rs   rt   ru   rv   rQ   s
             r   _generate_sorry_movesr|     s:    %1$6$6O$6D))w:N4$6KO	E+0+>+>+D+D+F'K444+N;- #)#8#8 8 )1)<)<(=
 %h&9&9%:!K=6K\K\J]^")()<)<(=\*m6&2C2C1DF $,#6#6)4*0*;*; < ,G  < LG Ps
   D&D&c                    / nU R                    Hw  n[        XU5      nUc  M  [        U UUR                  1S9(       d  M1  UR	                  [        SU SUR                   3SSUR                   SU 3UR                  US95        My     U$ )NrO   	sorry_fwdrc   sorry_fallback_forwardr[   rd   re   rf   rg   s        r   &_generate_sorry_fallback_forward_movesr   ?  s      E""2<uM/!% 1

 %eWBt.?@2((95'J??	
 #& Lr   pawn_apawn_bc                    [        SS5       H  nSU-
  n[        XU5      n[        XU5      nUb  Uc  M(  UR                  UR                  s=:X  a  S:X  a  O  OUR                  UR                  :X  a  Mh  UR                  UR                  s=:X  a  S:X  a  O  OUR                  UR                  :X  a  M  UR
                  UR
                  1n[        XUS9(       d  M  [        XUS9(       d  M    g   g)z8Check if a pair of pawns has at least one valid 7-split.r      rF   rE   rO   TF)rangerL   r&   r'   r(   r/   rU   )r5   r   r   first_stepssecond_stepsdest_adest_brT   s           r   _pair_has_any_valid_splitr   Z  s     Q{;-lKP-lLQ>V^;;&++00V5J5JfNcNc5c;;&++449J9JfN_N_9_##V%6%67/Z`a/Z`a #  r   c                    U R                    Vs/ s H   oR                  S;   d  M  UR                  PM"     nn[        U5      S:  a  / $ / n[	        U5       Hl  u  pEX$S-   S  H\  n[        X5      n[        X5      nUb  Uc  M!  [        XU5      (       d  M4  UR                  [        SU SU 3SSU S	U 3UUS
95        M^     Mn     U$ s  snf )z6Generate one move per valid pawn pair for splitting 7.>   rF   rE      r   Nsplit7_pair_prc   split7_pickzSplit 7 between pawn z
 and pawn )r,   r-   r.   r/   r1   )	r9   r&   r/   r8   	enumerater:   r   r]   r*   )	r5   rB   movabler^   ipawn_a_indexpawn_b_indexr   r   s	            r   _generate_split_seven_movesr   s  s    
 %1$6$6$6D))G]:]$6   7|a	E$W-#EG,L|:F|:F~,\6JJLL -l^2l^L+#8jQ]P^!_+)5 - ." L1s
   CCr   r   c                 p   [        X5      n[        X5      nUb  Uc  / $ / n[        SS5       GH  nSU-
  n[        XU5      n[        XU5      n	Ub  U	c  M)  UR                  U	R                  s=:X  a  S:X  a  O  OUR                  U	R                  :X  a  Mi  UR                  U	R                  s=:X  a  S:X  a  O  OUR
                  U	R
                  :X  a  M  X1n
[        XU
S9(       d  M  [        X	U
S9(       d  M  UR                  [        SU SU SU SU 3S	S
U SU SU SU 3UUUUS95        GM     U$ )z:Generate valid split distributions for a chosen pawn pair.r   r   rF   rE   rO   split7_pr_   rc   split7zPawn z moves z, pawn )r,   r-   r.   r/   r0   r1   r2   )	r:   r   rL   r&   r'   r(   rU   r]   r*   )r5   r   r   r   r   r^   r   r   r   r   rT   s              r   generate_split_options_for_pairr     sP    |2F|2F~	EQ{;-lKP-lLQ>V^;;&++00V5J5JfNcNc5c;;&++449J9JfN_N_9_-/Z`a/Z`a%l^1[ML>QRS_R`a"L> >)N',A (!%1 ,	
 #: Lr   	card_facerulesc                    X#R                  5       ;  a  / $ / nUR                  U5      (       a  UR                  [        X5      5        UR	                  U5       H  nUR                  [        X5      5        M     UR                  U5       H  nUR                  [        X5      5        M     UR                  U5      (       a  UR                  [        U5      5        UR                  U5      (       a  UR                  [        X5      5        UR                  U5      (       aU  [        X5      nUR                  U5        U(       d2  UR                  U5       H  nUR                  [        X5      5        M     [!        US S9$ )z+Generate legal moves for a player and card.c                     U R                   $ r>   )r,   )moves    r   <lambda>&generate_legal_moves.<locals>.<lambda>  s    $..r   )key)
card_facescan_leave_start_with_cardextendr`   forward_steps_for_cardrh   backward_steps_for_cardrk   allows_split_sevenr   allows_swaprw   allows_sorryr|   sorry_fallback_forward_stepsr   sorted)	r;   r5   r   r   r^   forward_stepsbackward_stepssorry_movesfallback_stepss	            r   generate_legal_movesr     s<    ((**	E&&y11*5?@55i@,\IJ A  77	B-lKL C 	**0>?##)%>?)$$+E@[!"'"D"DY"OCLab #P %899r   c                 .    SU l         S U l        SU l        g )NrY   r   )r&   r'   r(   )rB   s    r   _send_pawn_to_startr     s    DIDDOr   c                 D   UR                   U l         UR                   S:X  a  UR                  U l        SU l        g UR                   S:X  a  S U l        UR                  U l        g UR                   S:X  a  S U l        [        S-   U l        g [	        SUR                    35      e)NrF   r   rE   rD   r   zUnsupported destination zone: )r&   r'   r(   r   
ValueError)rB   rQ   s     r   _apply_destinationr     s       DI7")88			[	("%00			V	#"'!+9+:J:J9KLMMr   r'   c           
         Uc  / $ / n[        U5      nU R                  R                  5        H  u  pVXQR                  :X  a  M  UR                   Hx  nUR
                  S:X  d  M  UR                  c  M$  [        UR                  5      U:X  d  M?  [        U5        UR                  [        UUR                  UR                  S95        Mz     M     U$ )NrF   r   r   r   )r   r?   rq   r<   r9   r&   r'   r   r]   r   r/   )r;   r5   r'   events
normalizedother_idother_staterB   s           r   _capture_opponents_on_trackr     s    
 	!#F).9J!&!4!4!:!:!<---%%DyyG#(;(;(G+D,?,?@JN'-MM$/704)5)?)?	 & "= Mr   c           
         UR                   S:w  d  UR                  c  / $ [        UR                  5      nUS-  n[        R	                  U5      nUc  / $ US-  nXqR
                  :H  nUR                  5       n	U	S:X  a  Un
OU(       + n
U
(       d  / $ / n[        XF-   5      n[        US-   5       Vs1 s H  n[        XM-   5      iM     nnU R                  R                  5        H  u  nnUR                   H}  nUUL a  M
  UR                   S:w  d  UR                  c  M)  [        UR                  5      U;   d  MD  [        U5        UR                  [        UUR                  UR                  S95        M     M     Xl        U$ s  snf )NrF      
a5065_corer   r   )r&   r'   r   r"   r@   
seat_indexslide_policy_idr   r?   rq   r9   r   r]   r   r/   r<   )r;   r5   rB   r   rY   side_offsetslide_stepsslide_owner_seatsame_color_slide	policy_idshould_slider   endstepslide_positionsr   r   
other_pawns                     r   _resolve_slide_for_pawnr     s    yyGt22:	$T%8%89E"*K155kBK	{'+B+BB%%'IL ' ,+	!#F
"5#6
7CJOP[^_P_J`aJ`$/=J`Oa!&!4!4!:!:!<+%++JT!')Z-F-F-N'
(A(ABoU#J/ +3,6,A,A%1%;%; , "=  M% bs   /Fr   c                    / nUR                   S:X  a  [        XR                  5      nUb  UR                  S:w  a  [	        S5      e[        SUR                  S9n[        UUUR                  1S9(       d  [	        S5      e[        XV5        UR                  [        XUR                  5      5        UR                  [        XXS5      5        U$ UR                   S;   a  [        XR                  5      nUb  UR                  c  [	        S	5      e[        XUR                  5      nUc  [	        S
5      e[        UUUR                  1S9(       d  [	        S5      e[        XV5        UR                  S:X  a@  UR                  [        XUR                  5      5        UR                  [        XXS5      5        U$ UR                   S:X  a  [        XR                  5      nUb  UR                  c  [	        S5      e[        XRR                  5      nUc  [	        S5      e[        UUUR                  1S9(       d  [	        S5      e[        XV5        UR                  [        XUR                  5      5        UR                  [        XXS5      5        U$ UR                   S:X  a  [        XR                  5      n[!        XR"                  5      nUb  [        XrR$                  5      OSnUb=  Ub:  UR                  S:w  d*  UR                  S:w  d  UR                  b  UR                  c  [	        S5      eUR                  UR                  sUl        Ul        UR                  [        XXS5      5        U$ UR                   S:X  Ga  [        XR                  5      n[!        XR"                  5      nUb  [        XrR$                  5      OSnUb0  Ub-  UR                  S:w  d  UR                  S:w  d  UR                  c  [	        S5      e[        SUR                  S9n[        UUUR                  1S9(       d  [	        S5      e['        U5        [        XV5        UR                  [        XUR                  5      5        UR                  [        XXS5      5        U$ UR                   S:X  GaF  [        XR                  5      n	[        XR(                  5      n
U	b7  U
b4  UR                  b'  UR*                  b  U	R                  U
R                  :X  a  [	        S5      e[        UU	UR                  5      n[        UU
UR*                  5      nUb  Uc  [	        S5      eU	R                  U
R                  1n[        UUUS9(       d  [	        S5      e[        UUUS9(       d  [	        S5      eUR                  UR                  s=:X  a  S:X  a(  O  O%UR                  UR                  :X  a  [	        S5      eUR                  UR                  s=:X  a  S:X  a(  O  O%UR,                  UR,                  :X  a  [	        S5      e[        X5        U	R                  S:X  a@  UR                  [        XU	R                  5      5        UR                  [        XX5      5        [        X5        U
R                  S:X  a@  UR                  [        XU
R                  5      5        UR                  [        XX5      5        U$ [	        SUR                    35      e)zjApply a legal move to mutable game state.

Returns a list of capture events for pawns sent back to start.
rY   NzInvalid start move pawnrF   rG   rO   z Start square blocked by own pawn>   rb   r   zInvalid forward move payloadzForward move is no longer legalz'Forward destination blocked by own pawnrj   zInvalid backward move payloadz Backward move is no longer legalz(Backward destination blocked by own pawnrn   zInvalid swap moverz   zInvalid Sorry movez%Sorry destination blocked by own pawnr   zInvalid split-7 payloadzSplit-7 move is no longer legalz!Primary split destination blockedz#Secondary split destination blockedz)Split-7 cannot stack on same track squarerE   z-Split-7 cannot stack on same home-path squarezUnsupported move type: )r-   r:   r/   r&   r   r$   r\   rU   r   r   r   r'   r   r0   rL   rN   rA   r3   r4   r   r1   r2   r(   )r;   r5   r   r   r   rB   rQ   ru   opponent_pawnprimary	secondaryfirst_destinationsecond_destinationrT   s                 r   
apply_mover   G  s4    "$F~~ 7<499/677%'33
 0!% 1

 ?@@4-1%tGZGZ[\-e4OP~~>>7<4::-;<<2<tzzR>??/!% 1

 FGG4-99MM5e4K^K^_`MM1%tST~~#7<4::-<==3D**E?@@/!% 1

 GHH4-1%tGZGZ[\-e4OP~~7&u.C.CD ) n&<&<= 	 L$yyG#!!W,""*++3011(( 	:]9 	-e4OP~~ 7&u.C.CD ) n&<&<= 	 L$yyG#!!W,++3122%(77
 0!% 1

 DEEM*4-1%tGZGZ[\-e4OP~~!L//:l,E,EF	O zz!##+!!Y%9%996778JJ

 :  

 $(:(B>??$$i&:&:;/ &

 @AA/ &

 BCC""&8&=&=HH!004F4U4UUHII""&8&=&=LL!,,0B0M0MMLMM76<<7"MM5e7KaKabcMM1%wVW99>>W$MM+EAYAYZ MM1%yXY
.t~~.>?
@@r   ),r   dataclassesr   r   r   r;   r   r   r   r	   r
   r   r   r"   dictr   r   r$   r*   r:   r   rA   rL   rN   rS   boolrU   listrW   r`   rh   rk   rw   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>r      s   ? ! $  $   	3 c3h  $   $) ) ).".d
. d...Tz. .&"&
& & t	&R
 t$ ,0	"  SD	
 
0"	." 
)_6" 
)_6" 
)_6" 
)_@''"' 
)_'T" 
)_6"  
	2"	)_>)")) ) 
)_	)X":":"": ": 	":
 
)_":Jn  N
N N 
N$" $J 
,	4//"/ / 	/
 
,/dyAyA"yA yA 	yA
 
,yAr   