
    Ii?                         S r SSKJrJr  SSKJr  SSKrSSKJrJr  SSK	J
r
  SS	KJrJrJr  SS
KJr  SSKJrJr  SSKJr  SSKJr  \ " S S\5      5       r\\
 " S S\5      5       5       rg)zg
Snakes and Ladders Game Implementation for PlayPalace.

Classic board game where players race to 100.
    )	dataclassfield)datetimeN   )GamePlayer)register_game   )Action	ActionSet
Visibility)	BotHelper)
GameResultPlayerResult)Localization)KeybindStatec                   6    \ rS rSr% SrSr\\S'   Sr\	\S'   Sr
g)	SnakesPlayer   z$Player state for Snakes and Ladders.   positionFfinished N)__name__
__module____qualname____firstlineno____doc__r   int__annotations__r   bool__static_attributes__r       Ac:\Users\dbart\PlayPalace11\server\games\snakesandladders\game.pyr   r      s    .HcHdr#   r   c                     ^  \ rS rSr% Sr\" \S9r\\   \	S'   Sr
SrSrSSS	S
SSSSSS.	rSSSSSSSSSSS.
r\S\4S j5       r\S\4S j5       r\S\4S j5       r\S\4S j5       r\S\4S  j5       rSDS!\S"\S#\S\4S$ jjrSES& jrSFSGS' jjrS(\S\4S) jrS(\S\S%-  4S* jrS(\S\4S+ jr S(S,S\4U 4S- jjr!S(S,S\4U 4S. jjr"S(\S\4U 4S/ jjr#S(\S\4S0 jr$S(\S\S%-  4S1 jr%SEU 4S2 jjr&S(\S3\SS%4S4 jr'S(\S3\SS%4S5 jr(S6\S7\)SS%4S8 jr*SHS9\S:\SS%4S; jjr+SES< jr,SEU 4S= jjr-S(\S\S%-  4S> jr.S\/4S? jr0S@\/SA\S\\   4SB jr1SCr2U =r3$ )ISnakesAndLaddersGame   z
Snakes and Ladders.

Race to square 100. Ladders move you up, Snakes move you down.
Exact roll required to win (bounce back rule).
)default_factoryplayersd   r
   &         *   T   ,   C   [   )	r      	      r'   $   3   G   P            5      <      I   K   N   )
   /   1   8   >   @   W   ]   _   b   returnc                     g)NzSnakes and Laddersr   clss    r$   get_nameSnakesAndLaddersGame.get_name4   s    #r#   c                     g)Nsnakesandladdersr   rP   s    r$   get_typeSnakesAndLaddersGame.get_type8   s    !r#   c                     g)Nzcategory-board-gamesr   rP   s    r$   get_category!SnakesAndLaddersGame.get_category<   s    %r#   c                     g)Nr   r   rP   s    r$   get_min_players$SnakesAndLaddersGame.get_min_players@       r#   c                     g)Nr3   r   rP   s    r$   get_max_players$SnakesAndLaddersGame.get_max_playersD   r^   r#   	player_idnameis_botc                     [        XUS9$ )N)idrc   rd   )r   )selfrb   rc   rd   s       r$   create_player"SnakesAndLaddersGame.create_playerH   s    yFCCr#   Nc                    SU l         SU l        U R                   H  nSUl        SUl        M     U R                  U R                  5       5        U R                  S5        U R                  S5        U R                  5         g)zCalled when the game starts.playingTr   Fzgame_pig/mus.oggzgame-snakesandladders-descN)
statusgame_activer)   r   r   set_turn_playersget_active_players
play_musicbroadcast_l_start_turn)rg   ps     r$   on_startSnakesAndLaddersGame.on_startK   sr     AAJAJ 
 	d5578 	*+56r#   c                 B   U R                   nU(       d  gU R                  U5      nU(       a-  [        UR                  SS5      (       a  UR	                  S5        U R                  SUR                  UR                  S9  UR                  (       a*  [        R                  " U[        R                  " SS5      S	9  Ub(  U R                  US
S9  X:w  a  U R                  U5        ggU R                   H+  nXB:X  a  U R                  US
S9  M  U R                  U5        M-     g)zStart the current player's turn.

Args:
    previous_player: The player whose turn just ended. Only that player
        and the new current player need menu rebuilds. Pass None to
        rebuild all players (e.g. on game start).
Nplay_turn_soundTzgame_pig/turn.oggzsnakes-turnplayerr   r   (   )ticksr   )r   )current_playerget_usergetattrpreferences
play_soundrq   rc   r   rd   r   jolt_botrandomrandintrebuild_player_menur)   )rg   previous_playerry   userrs   s        r$   rr    SnakesAndLaddersGame._start_turn_   s     $$ }}V$GD,,.?FFOO/0v{{V__U ==vV^^B-CD & $$Va$8(((9 ) \\;,,Q,;,,Q/	 "r#   ry   c           
          [        SS9nU R                  U5      nU(       a  UR                  OSnUR                  [	        S[
        R                  " US5      SSSS	95        U$ )
Nturn)rc   enrollzsnakes-roll_action_roll_is_roll_enabled_is_roll_hiddenrf   labelhandler
is_enabled	is_hidden)r   r}   localeaddr   r   get)rg   ry   
action_setr   r   s        r$   create_turn_action_set+SnakesAndLaddersGame.create_turn_action_set   s_    F+
}}V$ $$"&&v}=&-+	
 r#   c                 l    U R                   S:w  a  gU R                  (       a  gU R                  U:w  a  gg )Nrk   action-not-playingzaction-game-in-progresszaction-not-your-turn)rl   is_animatingr|   rg   ry   s     r$   r   %SnakesAndLaddersGame._is_roll_enabled   s1    ;;)#',&()r#   c                     U R                   S:w  a  [        R                  $ U R                  U:w  a  [        R                  $ [        R                  $ Nrk   )rl   r   HIDDENr|   VISIBLEr   s     r$   r   $SnakesAndLaddersGame._is_roll_hidden   s@    ;;)#$$$&($$$!!!r#   r   c                    > U R                  U5      nU(       a!  [        USS5      S:X  a  [        R                  $ [        TU ]  U5      $ )Nclient_type web)r}   r~   r   r   super_is_whos_at_table_hiddenrg   ry   r   	__class__s      r$   r   -SnakesAndLaddersGame._is_whos_at_table_hidden   s@    }}V$GD-4=%%%w/77r#   c                    > U R                  U5      nU(       aA  [        USS5      S:X  a0  U R                  S:X  a  [        R                  $ [        R
                  $ [        TU ]  U5      $ )Nr   r   r   rk   )r}   r~   rl   r   r   r   r   _is_whose_turn_hiddenr   s      r$   r   *SnakesAndLaddersGame._is_whose_turn_hidden   sX    }}V$GD-4={{i'!)))$$$w,V44r#   c           
      b  > [         TU ]  U5      nU R                  U5      nU(       a  UR                  OSnUR	                  [        S[        R                  " US5      SSSS95        SUR                  ;   a7  UR                  R                  S5        UR                  R                  SS5        U$ )	z(Add Check Positions to standard actions.r   check_positionszcheck-positions_action_check_positions_is_check_positions_enabled_is_check_positions_hiddenr   r   )r   create_standard_action_setr}   r   r   r   r   r   _orderremoveinsert)rg   ry   r   r   r   r   s        r$   r   /SnakesAndLaddersGame.create_standard_action_set   s    W7?
}}V$ $$ 	$"&&v/@A186	
 
 1 11$$%67$$Q(9:r#   c                 b    U R                   S:w  a  [        R                  $ [        R                  $ )z/Show check positions for everyone when playing.rk   )rl   r   r   r   r   s     r$   r   /SnakesAndLaddersGame._is_check_positions_hidden   s&    ;;)#$$$!!!r#   c                 &    U R                   S:w  a  gg)z9Check positions is only available while a game is active.rk   r   N)rl   r   s     r$   r   0SnakesAndLaddersGame._is_check_positions_enabled   s    ;;)#'r#   c                    > [         TU ]  5         U R                  SSS/[        R                  S9  U R                  SSS/[        R                  S9  U R                  SSS/[        R                  S	S
9  g )Nrz	Roll dicer   )statespaceczCheck positionsr   T)r   include_spectators)r   setup_keybindsdefine_keybindr   ACTIVErg   r   s    r$   r   #SnakesAndLaddersGame.setup_keybinds   sw     Cvhl>Q>QRG[6(,BUBUV%%# 	 	
r#   	action_idc                 L   U R                  U5      nU(       d  g/ nU R                  5        H/  nUnUR                  UR                   SUR                   35        M1     [
        R                  " UR                  S5      nUR                  U SSR                  U5       35        g)z"Announce current player positions.N zsnakes-positions-headerz, )
r}   ro   appendrc   r   r   r   r   speakjoin)rg   ry   r   r   speech_partsrs   spheaders           r$   r   ,SnakesAndLaddersGame._action_check_positions   s    }}V$ ((*A B166(!BKK= 9: +
 !!$++/HI

fXQtyy6789r#   c                 \   UnSU l         [        R                  " SS5      nU R                  5         U R	                  SUR
                  US9  SnSnUR                  nXt-   nU R                  UUUU R                  S9n	U R                  S	UR                  US
.U	S9  U	S-  n	Un
XR                  :  aP  XR                  -
  nU R                  U-
  n
U R                  SU	S9  U R                  SUR                  U
S
.U	S9  U	S-  n	U
nSnXR                  :X  a  SnOXR                  ;   a{  U R                  U   n[        R                  " SU R                  5      nU R                  SU S3U	S9  U R                  SUR                  XS.U	S9  UnU	S-  n	XR                  :X  a  SnOTXR                  ;   aE  U R                  U   nU R                  SU	S9  U R                  SUR                  UUS.U	S9  UnU	S-  n	U(       a  U R                  SSUR                  0U	S9  gU R                  S0 U	S-   S9  g)z*Handle roll action with sequential events.Tr   r:   zsnakes-roll-result)ry   r      r3   )start_delay_ticksstep_interval_ticksvariant_countmove)rb   pos)delay_ticksr   zgame_snakes/bounce.oggbounceFzgame_snakes/ladderz.oggladder)rb   startend   zgame_snakes/snake.oggsnake   winrb   end_turn   N)r   r   r   play_standard_dice_roll_soundrq   rc   r   'schedule_standard_token_movement_soundsNUM_STEP_SOUNDSschedule_eventrf   WINNING_SQUAREschedule_soundLADDERSNUM_LADDER_SOUNDSSNAKES)rg   ry   r   snakes_playerr   step_delay_startstep_intervalold_posintermediate_pos
next_delayfinal_pre_interaction_pos	overshoot	final_posis_wintopladder_varianttails                    r$   r   !SnakesAndLaddersGame._action_roll   s   &,  ~~a#**,-fkkM   (("> AA. -..	 B 

 	&))4DES] 	 	
 	a
 %5!111(+>+>>I(,(;(;i(G%  8jQ$ii0IJ&    !OJ
 .	+++F,,&,,y)C $^^At/E/EFN"4^4DD IWab$ii)H&    I"J///++%;;y)D  7ZP$ii)DI&    I"J VYY'?ZX
BJNKr#   
event_typedatac                    UR                  S5      nU(       a  U R                  U5      OSnUS:X  a/  U(       a'  US   nXTl        U R                  SUR                  US9  ggUS:X  a/  U(       a'  US   nXTl        U R                  SUR                  US9  ggUS	:X  a4  U(       a,  US
   nUS   nXtl        U R                  SUR                  XgS9  ggUS:X  a4  U(       a,  US
   nUS   nXtl        U R                  SUR                  XgS9  ggUS:X  a  U(       a  U R                  U5        ggUS:X  a  SU l        U R                  5         gg)zHandle a scheduled game event.rb   Nr   r   zsnakes-moverx   r   zsnakes-bouncer   r   r   zsnakes-ladder)ry   r   r   r   zsnakes-snaker   r   F)r   get_player_by_idr   rq   rc   _handle_winr   r   )rg   r   r   rb   ry   new_posr   r   s           r$   on_game_event"SnakesAndLaddersGame.on_game_evente  sX   HH[)	5>&&y1Du+")  v{{W U 
 8#u+")  w W 
 8#W5k"%  E [	  7"W5k"%  5 Z	  5   (  :% %DMMO &r#   winnerdelayc                     SUl         Xl        U R                  S5        U R                  SUR                  S9  U R                  5         g)zHandle win condition.Tzgame_pig/win.oggz
snakes-win)ry   N)r   r  r   rq   rc   finish_game)rg   r  r  s      r$   r    SnakesAndLaddersGame._handle_win  s@     	*+fkk:r#   c                     U R                   nU R                  U R                  -   [        U R                  5      -  U l        U R                  US9  g)zAdvance turn.)r   N)r|   
turn_indexturn_directionlenturn_player_idsrr   )rg   previouss     r$   r   SnakesAndLaddersGame.end_turn  sD    &&??T-@-@@CH\H\D]]2r#   c                    > [         TU ]  5         U R                  5         U R                  S:X  a  [        R                  " U 5        g g r   )r   on_tickprocess_scheduled_eventsrl   r   r   s    r$   r  SnakesAndLaddersGame.on_tick  s8    %%';;)#d# $r#   c                     g)zBot always rolls.r   r   r   s     r$   	bot_thinkSnakesAndLaddersGame.bot_think  s    r#   c                    [        U SS5      n[        U R                  5       S SS9nU R                   Vs0 s H  o3R                  UR
                  _M     nn[        U R                  5       [        R                  " 5       R                  5       U R                  U Vs/ s H,  n[        UR                  UR                  UR                  S9PM.     snU(       a  UR                  OSUS.S9$ s  snf s  snf )	zBuild standard game result.r  Nc                 2    U R                   U R                  4$ N)r   r   )rs   s    r$   <lambda>8SnakesAndLaddersGame.build_game_result.<locals>.<lambda>  s    1::qzz2r#   T)keyreverse)rb   player_namerd   )winner_namefinal_positions)	game_type	timestampduration_ticksplayer_resultscustom_data)r~   sortedro   r)   rc   r   r   rV   r   now	isoformatsound_scheduler_tickr   rf   rd   )rg   r  sorted_playersrs   r   s        r$   build_game_result&SnakesAndLaddersGame.build_game_result  s    x.  ##%2
 8<||D|!661::-|Dmmolln..044 ('A qttQ'
 /5v{{$#2
 	
 Es    C,3C1resultr   c                 &   [         R                  " US5      /n[        UR                  S5       H^  u  pEUR                  S   R                  UR
                  S5      nUR                  [         R                  " USXER
                  US95        M`     U$ )Nzgame-final-scoresr   r   r   zsnakes-end-score)rankry   r   )r   r   	enumerater$  r%  r  r   )rg   r-  r   linesip_resultr   s          r$   format_end_screen&SnakesAndLaddersGame.format_end_screen  s    !!&*=>? %V%:%:A>KA$$%67;;H<P<PRSTCLL  .Q?S?S^a ? r#   )rm   r   rl   r
  r  )F)rN   Nr  )r   zSnakesPlayer | NonerN   N)r   )4r   r   r   r   r   r   listr)   r   r    r   r   r   r   r   classmethodstrrR   rV   rY   r   r\   r`   r!   rh   rt   rr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   dictr  r   r   r  r  r   r+  r4  r"   __classcell__)r   s   @r$   r&   r&      s    #("=GT,= N O PSTGQSY[\F$ $ $ " " " &S & &      Ds D# Dt DP\ D()0V\ i "v #* "f " "8x 8J 85H 5 5 I 2" "J "& S4Z 

:f : : :$cL6 cLc cLd cLJ% %4 %D %N	, 	s 	4 	3$ t 
: 
8
 C DI  r#   r&   )r   dataclassesr   r   r   r   baser   r   registryr	   game_utils.actionsr   r   r   game_utils.bot_helperr   game_utils.game_resultr   r   messages.localizationr   server.core.ui.keybindsr   r   r&   r   r#   r$   <module>rC     sn    )    $ ? ? . > 1 0 6   r4 r  rr#   