
    Ii$                         S r SSKJrJr  \(       a  SSK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
KJr   " S S5      rg)z5Mixin providing game result handling and persistence.    )TYPE_CHECKINGAny   )Player)User   )
GameResultPlayerResult)RatingHelper)Localization)MenuItemc                       \ rS rSrSrSS\SS4S jjr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\
\
\	      4S jrS\SS4S jrS\
\	   SS4S jrSrg)GameResultMixin   aC  Build, persist, and display game results.

Expected Game attributes:
    game_active: bool.
    status: str.
    players: list[Player].
    sound_scheduler_tick: int.
    _table: Table or server reference.
    get_user(player) -> User | None.
    get_type() -> str.
    get_active_players() -> list[Player].
    destroy().
show_end_screenreturnNc                    SU l         SU l        U R                  5       nX l        U R	                  U5        U(       a  U R                  U5        [        S U R                   5       5      nU(       d  U R                  5         gg)a\  Mark the game as finished, persist result, and optionally show end screen.

Call this instead of setting status directly to ensure proper cleanup.
If no humans remain, the table is automatically destroyed.

Args:
    show_end_screen: Whether to show the end screen (default True).
                     Set to False if you want to show it manually.
Ffinishedc              3   j   #    U  H)  oR                   (       + =(       d    [        US S5      v   M+     g7f)is_virtual_botFN)is_botgetattr).0ps     Bc:\Users\dbart\PlayPalace11\server\game_utils\game_result_mixin.py	<genexpr>.GameResultMixin.finish_game.<locals>.<genexpr>5   s)     cVbQRXXL4De)LLVbs   13N)	game_activestatusbuild_game_result_last_game_result_persist_result_show_end_screenanyplayersdestroy)selfr   result
has_humanss       r   finish_gameGameResultMixin.finish_game   st     !  '')!'V$ !!&) cVZVbVbcc
LLN     c                 >   SSK J n  [        U R                  5       UR                  5       R	                  5       U R
                  U R                  5        Vs/ s H8  n[        UR                  UR                  UR                  [        USS5      S9PM:     sn0 S9$ s  snf )zBuild the game result. Override in subclasses for custom data.

Returns:
    A GameResult with game-specific data in custom_data.
r   )datetimer   F)	player_idplayer_namer   r   )	game_type	timestampduration_ticksplayer_resultscustom_data)r.   r	   get_typenow	isoformatsound_scheduler_tickget_active_playersr
   idnamer   r   )r'   r.   r   s      r   r    !GameResultMixin.build_game_result9   s     	&mmolln..044 002 3A dd !88#*1.>#F	 3 
 	
s   ?Br(   localec                     [         R                  " US5      /nUR                   H  nUR                  UR                  5        M      U$ )zFormat the end screen lines from a game result. Override for custom display.

Args:
    result: The game result to format
    locale: The locale to use for localization

Returns:
    List of lines to display on the end screen
z	game-over)r   getr4   appendr0   )r'   r(   r>   linesr   s        r   format_end_screen!GameResultMixin.format_end_screenQ   s>     !!&+67&&ALL' 'r,   c                     UR                  5       (       d  gU R                  (       a-  U R                  R                  U5        U R                  U5        gg)z;Persist the game result to the database and update ratings.N)has_human_players_tablesave_game_result_update_ratings)r'   r(   s     r   r"   GameResultMixin._persist_resulta   sB     ''));;KK((0  ( r,   c                 ,   U R                   (       a  U R                   R                  (       d  g[        U R                   R                  U R                  5       5      nU R	                  U5      nU(       a  [        U5      S:  a  gUR                  U5        g)z+Update player ratings based on game result.Nr   )rG   _dbr   r6   get_rankings_for_ratinglenupdate_ratings)r'   r(   rating_helperrankingss       r   rI   GameResultMixin._update_ratingsl   sc    {{$++//$T[[__dmmoF //73x=1, 	$$X.r,   c                    UR                   R                  S5      nUR                   Vs/ s H(  o3R                  (       a  UR                  (       d  M&  UPM*     nnU(       d  / $ U(       a]  Sn/ nU H<  nUR
                  U:X  a  UR                  nM!  UR                  UR                  5        M>     U(       a  U(       a  U/U/$ U//$ U Vs/ s H  o3R                  PM     sn/$ s  snf s  snf )a  Get player rankings for rating update. Override for custom ranking logic.

Returns a list of player ID groups ordered by placement.
First group = 1st place, second = 2nd place, etc.
Players in same group = tie for that position.

Default: Winner first, everyone else tied for second.
winner_nameN)r5   r@   r4   r   r   r0   r/   rA   )r'   r(   rT   r   human_players	winner_idotherss          r   rM   'GameResultMixin.get_rankings_for_rating|   s     ((,,];$*$9$9^$9qQM]M]$9^IIF"==K/ !IMM!++.	 # &K00"}$ '44mm455) _( 5s   %C%C%C*c           	      d   U R                    H  nU R                  U5      nU(       d  M  U R                  XR                  5      nU Vs/ s H  n[	        USS9PM     nnUR                  [	        [        R                  " UR                  S5      SS95        UR                  SUSS9  M     gs  snf )	z;Show the end screen to all players using structured result.
score_linetextr;   zgame-over-leave
leave_game	game_overFmultiletterN)	r%   get_userrC   r>   r   rA   r   r@   	show_menu)r'   r(   playeruserrB   lineitemss          r   r#    GameResultMixin._show_end_screen   s    llF==(Dt..v{{CJOP%$t=%PX<+;+;DKKIZ+[`lmn{EuE # Qs   	B-score_linesc           	          U R                    HH  nU R                  U5      nU(       d  M  U Vs/ s H  n[        USS9PM     nnUR                  SUSS9  MJ     gs  snf )aA  Show the game end menu to all players.

DEPRECATED: Use finish_game() with build_game_result() and format_end_screen()
instead. This method is kept for backwards compatibility during migration.

Args:
    score_lines: List of score lines to display
                 (e.g., ["Final Scores:", "1. Alice: 100 points", ...])
rZ   r[   r^   Fr_   N)r%   ra   r   rb   )r'   rh   rc   rd   re   rf   s         r   show_game_end_menu"GameResultMixin.show_game_end_menu   sX     llF==(DtJUV+$t=+V{EuE	 # Ws   A)r!   r   r   )T)__name__
__module____qualname____firstlineno____doc__boolr*   r	   r    strlistrC   r"   rI   rM   r#   rj   __static_attributes__ r,   r   r   r      s    4 4 6
: 
0
 C DI  	)j 	)T 	)/j /T / 6j 6T$s)_ 6B	Fz 	Fd 	FFd3i FD Fr,   r   N)rp   typingr   r   
games.baser   server.core.users.baser   game_resultr	   r
   stats_helpersr   messages.localizationr   r   r   ru   r,   r   <module>r|      s.    ; %#+ 1 ' 0 +gF gFr,   