
    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J	r	  SSK
Jr  SS	K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JrJr  SSKJrJr  SSKJrJ r J!r!  SSK"J#r#  SSK$J%r%  SSK&J'r'  \ " S S\5      5       r(\ " S S\	5      5       r)Sr*Sr+Sr,Sr-Sr.Sr/Sr0Sr1S r2S!r3S"r4\*S#\+S$\,S%\-S&\.S'\/S(\1S)\0S*\2S+\3S,\4S-0r5S8S.\6\7   S/\8S0\7S1\94S2 jjr:S8S/\8S0\7S1\74S3 jjr;S.\6\7   S1\94S4 jr<S.\6\7   S1\6\=\8\7\74      4S5 jr>\\ " S6 S7\\\5      5       5       r?g)9z
Farkle Game Implementation for PlayPalace v11.

Classic dice game: score combinations and don't Farkle!
Push your luck by rolling again or bank your points.
    )	dataclassfield)datetimeN   )GamePlayerGameOptions)register_game   )ActionGuardMixin)RoundBasedGameMixin)Action	ActionSet
Visibility)	BotHelper)
count_dicecount_exact_matcheshas_consecutive_runhas_n_of_a_kind)
GameResultPlayerResult)
BoolOption	IntOptionoption_field)Localization)KeybindState   	bot_thinkc                       \ rS rSr% SrSr\\S'   Sr\\S'   \	" \
S9r\
\   \S'   \	" \
S9r\
\   \S'   S	r\\S
'   Sr\\S'   Sr\\S'   Sr\\S'   Sr\\S'   Srg)FarklePlayer   zPlayer state for Farkle game.r   score
turn_scoredefault_factorycurrent_rollbanked_diceFhas_taken_combor   hot_dice_multiplierhot_dice_chainturns_taken	best_turn N)__name__
__module____qualname____firstlineno____doc__r#   int__annotations__r$   r   listr'   r(   r)   boolr*   r+   r,   r-   __static_attributes__r.       7c:\Users\dbart\PlayPalace11\server\games\farkle\game.pyr!   r!      sq    'E3NJ#D9L$s)9"48Kc8!OT!  NCKIsr9   r!   c                       \ rS rSr% Sr\" \" SSSSSSSS	S
95      r\\	S'   \" \" SSSSSSSS95      r
\\	S'   \" \" SSSSS95      r\\	S'   Srg)FarkleOptions/   zOptions for Farkle game.i  i  r#   zfarkle-set-target-scorezfarkle-enter-target-scorezfarkle-option-changed-targetzfarkle-desc-target-score)defaultmin_valmax_val	value_keylabelprompt
change_msgdescriptiontarget_scorer   i  zfarkle-set-initial-bank-scorezfarkle-enter-initial-bank-scorez(farkle-option-changed-initial-bank-score)r>   r?   r@   rA   rB   rC   rD   initial_bank_scoreFenabledz!farkle-toggle-hot-dice-multiplierz)farkle-option-changed-hot-dice-multiplier)r>   rA   rB   rD   r*   r.   N)r/   r0   r1   r2   r3   r   r   rF   r4   r5   rG   r   r*   r7   r8   r.   r9   r:   r<   r<   /   s    "$+.52		
L#  +14A	

 
 !-5B		
! r9   r<   single_1single_5three_of_kindfour_of_kindfive_of_kindsix_of_kindsmall_straightlarge_straightthree_pairsdouble_triplets
full_housezgame_farkle/point10.oggzgame_farkle/singles5.oggzgame_farkle/3kind.oggzgame_farkle/4kind.oggzgame_farkle/5kind.oggzgame_farkle/6kind.oggzgame_farkle/largestraight.oggzgame_farkle/smallstraight.oggzgame_farkle/3pairs.oggzgame_farkle/doubletriplets.oggzgame_farkle/fullhouse.oggdice
combo_typenumberreturnc                   ^ [        U 5      mU[        :X  a  TS   S:  $ U[        :X  a  TS   S:  $ U[        :X  a  [	        TSUS9$ U[
        :X  a  [	        TSUS9$ U[        :X  a  [	        TSUS9$ U[        :X  a  [	        TSUS9$ U[        :X  a  [        TSSSSS9$ U[        :X  a  [        TSSSS	9$ U[        :X  a  [        U 5      S:w  a  g
[        TS5      S:H  $ U[        :X  a  [        U 5      S:w  a  g
[        TS5      S:H  $ U[        :X  aY  [        U 5      S:w  a  g
[!        U4S j[#        SS5       5       5      n[!        U4S j[#        SS5       5       5      nU=(       a    U$ g
)z-Check if dice contain a specific combination.r      r   )value      Tlength	min_value	max_valuerequire_uniquer^   r_   r`   Fr   c              3   4   >#    U  H  nTU   S :H  v   M     g7f)r[   Nr.   .0icountss     r:   	<genexpr>"has_combination.<locals>.<genexpr>        ;{!vayA~{      c              3   4   >#    U  H  nTU   S :H  v   M     g7f)r   Nr.   rd   s     r:   rh   ri      rj   rk   )r   COMBO_SINGLE_1COMBO_SINGLE_5COMBO_THREE_OF_KINDr   COMBO_FOUR_OF_KINDCOMBO_FIVE_OF_KINDCOMBO_SIX_OF_KINDCOMBO_LARGE_STRAIGHTr   COMBO_SMALL_STRAIGHTCOMBO_THREE_PAIRSlenr   COMBO_DOUBLE_TRIPLETSCOMBO_FULL_HOUSEanyrange)rT   rU   rV   has_quadhas_pairrg   s        @r:   has_combinationr~   q   ss   F^#ayA~	~	%ayA~	*	*vq77	)	)vq77	)	)vq77	(	(vq77	+	+"6!qA^bcc	+	+"6!qANN	(	(t9>"61-22	,	,t9>"61-22	'	't9>;uQ{;;;uQ{;;$H$r9   c                 V   U [         :X  a  gU [        :X  a  gU [        :X  a  US:X  a  S$ US-  $ U [        :X  a  US:X  a  S$ US-  $ U [        :X  a  US:X  a  S$ US-  $ U [
        :X  a  US:X  a  S	$ US
-  $ U [        :X  a  gU [        :X  a  gU [        :X  a  gU [        :X  a  gU [        :X  a  gg)z"Get point value for a combination.
   rY   r   d         i  (   i   P         r   rn   ro   rp   rq   rr   rs   ru   rt   rv   rx   ry   )rU   rV   s     r:   get_combination_pointsr      s    ^#	~	%	*	*ks2v{2	)	)ks2v{2	)	)ks2v{2	(	(ks2v{2	+	+	+	+	(	(	,	,	'	'r9   c                    U (       d  g[        U 5      nUR                  SS5      S:  d  UR                  SS5      S:  a  g[        US5      (       a  g[        U 5      S:X  a  [	        USSSSS9(       a  g[        U 5      S:  a  [	        USSSS	9(       a  g[        U 5      S:X  a  [        US
5      S:X  a  g[        U 5      S:X  a  [        US5      S
:X  a  gg)zFCheck if dice contain any scoring combinations (for farkle detection).Fr   r   rY   Tr   r\   r]   rb   r   )r   getr   rw   r   r   )rT   rg   s     r:   has_scoring_dicer      s    F zz!Q!vzz!Q/!3 vq!! 4yA~-qA4  4yA~-fQ!WXY 4yA~-fa8A= 4yA~-fa8A=r9   c                    / nU (       d  U$ [        U 5      n[        SS5       HB  n[        U [        U5      (       d  M  [	        [        U5      nUR                  [        X445        MD     [        SS5       HB  n[        U [        U5      (       d  M  [	        [        U5      nUR                  [        X445        MD     [        SS5       HB  n[        U [        U5      (       d  M  [	        [        U5      nUR                  [        X445        MD     [        U [        5      (       a'  [	        [        5      nUR                  [        SU45        [        U [        5      (       a'  [	        [        5      nUR                  [        SU45        [        U [        5      (       a'  [	        [        5      nUR                  [        SU45        [        U [        5      (       a'  [	        [        5      nUR                  [        SU45        [        U [        5      (       a'  [	        [        5      nUR                  [        SU45        [        SS5       HB  n[        U [        U5      (       d  M  [	        [        U5      nUR                  [        X445        MD     US   S:  a'  [	        [        5      nUR                  [        SU45        US   S:  a'  [	        [        5      nUR                  [        SU45        UR!                  S SS9  U$ )zNGet all available scoring combinations as (combo_type, number, points) tuples.r   rl   r   rY   c                     U S   $ Nr   r.   )xs    r:   <lambda>,get_available_combinations.<locals>.<lambda>  s    AaDr9   Tkeyreverse)r   r{   r~   rs   r   appendrr   rq   rt   ru   rx   ry   rv   rp   rn   ro   sort)rT   combinationsrg   numpointss        r:   get_available_combinationsr      s   LF Q{4!2C88+,=sCF!2C @A  Q{4!3S99+,>DF!3S AB  Q{4!3S99+,>DF!3S AB  t122'(<=11f=> t122'(<=11f=> t233'(=>2Av>? t-..'(89-q&9: t.//'(9:.6:; Q{4!4c::+,?EF!4c BC  ay1}'7^Q78 ay1}'7^Q78 .$7r9   c            
       r  ^  \ rS rSr% SrSr\" \S9r\\	   \
S'   \" \S9r\\
S'   \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\S\\   4S j5       rS<S\S\S\S\	4S jjrS\	S\4S jrS=U 4S jjrS\S\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\!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\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S4S( jr,S\S\SS4S) jr-S\	S\S\SS4S* jr.S+\S\4S, jr/S\S\SS4S- jr0S\S\SS4S. jr1S=S/ jr2S=S0 jr3S=S1 jr4S=U 4S2 jjr5S\	S\S-  4S3 jr6S=S4 jr7S\84S5 jr9S6\8S\S\\   4S7 jr:S>S8\S9\SS4S: jjr;S;r<U =r=$ )?
FarkleGamei   a  
Farkle dice game.

Players take turns rolling 6 dice and selecting scoring combinations.
After each selection, they can roll remaining dice or bank their points.
Rolling dice with no scoring combinations (Farkle!) loses all turn points.
First player to reach the target score wins.
Nr%   playersoptionsrW   c                     g)NFarkler.   clss    r:   get_nameFarkleGame.get_name1      r9   c                     g)Nfarkler.   r   s    r:   get_typeFarkleGame.get_type5  r   r9   c                     g)Nzcategory-dice-gamesr.   r   s    r:   get_categoryFarkleGame.get_category9  s    $r9   c                     gr   r.   r   s    r:   get_min_playersFarkleGame.get_min_players=  s    r9   c                     g)Nr   r.   r   s    r:   get_max_playersFarkleGame.get_max_playersA  s    r9   c                 "    SSSSSSS.SS	S
SS./$ )Navg_points_per_turnz&player_stats.{player_name}.total_scorez&player_stats.{player_name}.turns_takensumavgr   )id	numeratordenominator	aggregateformatdecimalsbest_single_turnz$player_stats.{player_name}.best_turnmaxr#   )r   pathr   r   r.   r   s    r:   get_leaderboard_types FarkleGame.get_leaderboard_typesE  s8     ,EG" )>"!	
 	
r9   	player_idnameis_botc                 &    [        UUUSS/ / SSSS9
$ )z/Create a new player with Farkle-specific state.r   Fr   )
r   r   r   r#   r$   r'   r(   r)   r*   r+   )r!   )selfr   r   r   s       r:   create_playerFarkleGame.create_playerX  s-    ! !
 	
r9   playerc                 `   U R                  U5      nU(       a  UR                  OSn[        SS9nUR                  [	        S[
        R                  " USSS9SS	S
SS95        UR                  [	        S[
        R                  " USSS9SSSSS95        UR                  [	        SSSSSS95        U$ )z(Create the turn action set for a player.enturn)r   rollfarkle-rollr\   count_action_roll_is_roll_enabled_is_roll_hidden_get_roll_label)r   rB   handler
is_enabled	is_hidden	get_labelbankfarkle-bankr   r   _action_bank_is_bank_enabled_is_bank_hidden_get_bank_labelcheck_turn_scoreCheck turn score_action_check_turn_score_is_check_turn_score_enabled_is_check_turn_score_hidden)r   rB   r   r   r   )get_userlocaler   addr   r   r   )r   r   userr   
action_sets        r:   create_turn_action_set!FarkleGame.create_turn_action_setg  s    }}V$ $$F+
 	"&&v}AF&-++		
 	"&&v}QG&-++		
 	%(297	
 r9   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9  g)z!Define all keybinds for the game.rz	Roll dicer   )statebzBank pointsr   cr   r   N)supersetup_keybindsdefine_keybindr   ACTIVEr   	__class__s    r:   r   FarkleGame.setup_keybinds  su      	Cvhl>Q>QRC@S@ST#&8%9ATAT 	 	
r9   r   rU   rV   r   c                    U[         :X  a  [        R                  " USUS9$ U[        :X  a  [        R                  " USUS9$ U[        :X  a  [        R                  " USX4S9$ U[
        :X  a  [        R                  " USX4S9$ U[        :X  a  [        R                  " USX4S9$ U[        :X  a  [        R                  " USX4S9$ U[        :X  a  [        R                  " US	US9$ U[        :X  a  [        R                  " US
US9$ U[        :X  a  [        R                  " USUS9$ U[        :X  a  [        R                  " USUS9$ U[        :X  a  [        R                  " USUS9$ U SU S3$ )z2Get the localized label for a scoring combination.zfarkle-take-single-oner   zfarkle-take-single-fivezfarkle-take-three-kind)rV   r   zfarkle-take-four-kindzfarkle-take-five-kindzfarkle-take-six-kindzfarkle-take-small-straightzfarkle-take-large-straightzfarkle-take-three-pairszfarkle-take-double-tripletszfarkle-take-full-housez for z points)rn   r   r   ro   rp   rq   rr   rs   ru   rt   rv   rx   ry   )r   r   rU   rV   r   s        r:   _get_combo_labelFarkleGame._get_combo_label  sk   '##F,DVTT>)##F,EfUU..##F,DVcc--##F,CFbb--##F,CFbb,,##F,B6aa//##F,HQWXX//##F,HQWXX,,##F,EfUU00##F,IRXYY++##F,DVTTU6('22r9   c                     U[         :X  a  gU[        :X  a  gU[        :X  a  SU S3$ U[        :X  a  SU S3$ U[        :X  a  SU S3$ U[
        :X  a  SU S3$ U[        :X  a  gU[        :X  a  g	U[        :X  a  g
U[        :X  a  gU[        :X  a  gU$ )zJGet the English name for a combo (for announcements). Matches v10 exactly.zSingle 1zSingle 5zThree szFour zFive zSix zSmall StraightzLarge StraightzThree pairszDouble tripletsz
Full houser   )r   rU   rV   s      r:   _get_combo_nameFarkleGame._get_combo_name  s    '>)..F81%%--6(!$$--6(!$$,,&##//#//#,, 00$++r9   c           
         U R                  US5      nU(       d  gU R                  U5      nU(       a  UR                  OSnUR                  R	                  5        Vs/ s H  oUR                  S5      (       d  M  UPM     nnU H  nUR                  U	 M     [        UR                  5      nUR                  R                  5         U Ho  u  pn
SU SU	 3nU
[        SUR                  5      -  nU R                  XHX5      n[        UUSSS	S
S9UR                  U'   UR                  R                  U5        Mq     S H/  nXRR                  ;   d  M  UR                  R                  U5        M1     gs  snf )zhUpdate scoring actions based on current roll.

Scoring actions are placed BEFORE roll/bank in the menu.
r   Nr   score__r   _action_take_combo_is_scoring_action_enabled_is_scoring_action_hiddenF)r   rB   r   r   r   show_in_actions_menu)r   r   r   )get_action_setr   r   _actionskeys
startswithr   r'   _orderclearr   r*   r   r   r   )r   r   turn_setr   r   	action_idold_actionscombosrU   rV   r   display_pointsrB   s                r:   update_scoring_actions!FarkleGame.update_scoring_actions  se   
 &&vv6}}V$ $$ (0'8'8'='='?
'?)CWCWX`CaI'? 	 
 %I!!), % ,F,?,?@ 	 +1&J AfX6I#c!V-G-G&HHN))&fUE+1,75%*,Hi( OO""9- +1  >I---&&y1 >;
s   E2:E2c                     U R                  U5      nU(       a  U$ Un[        UR                  5      S:H  =(       d    UR                  nU(       d  gg)z Check if roll action is enabled.r   zfarkle-must-take-comboN)guard_turn_action_enabledrw   r'   r)   )r   r   errorfarkle_playercan_rolls        r:   r   FarkleGame._is_roll_enabled  sH    ..v6L&,}112a7X=;X;X+r9   c                 z    Un[        UR                  5      S:H  =(       d    UR                  nU R                  XS9$ )zCheck if roll action is hidden.r   extra_condition)rw   r'   r)   turn_action_visibility)r   r   r  r  s       r:   r   FarkleGame._is_roll_hidden  s;    &,}112a7X=;X;X**6*LLr9   r  c                     U R                  U5      nU(       a  UR                  OSnUnU R                  U5      n[        R                  " USUS9$ )z"Get dynamic label for roll action.r   r   r   )r   r   _get_roll_dice_countr   r   )r   r   r  r   r   r  num_dices          r:   r   FarkleGame._get_roll_label  sG    }}V$ $$&,,,];XFFr9   c                     U R                  U5      nU(       a  U$ UnUR                  S:  =(       a9    [        UR                  5      S:H  =(       d    [	        UR                  5      (       + nU(       d  gg)z Check if bank action is enabled.r   zfarkle-cannot-bankN)r  r$   rw   r'   r   )r   r   r  r  can_banks        r:   r   FarkleGame._is_bank_enabled  si    ..v6L&, ++a/ 
**+q0d8HIcIc8d4d 	 'r9   c                     UnUR                   S:  =(       a9    [        UR                  5      S:H  =(       d    [        UR                  5      (       + nU R	                  XS9$ )zCheck if bank action is hidden.r   r  )r$   rw   r'   r   r  )r   r   r  r$  s       r:   r   FarkleGame._is_bank_hidden*  s\    &, ++a/ 
**+q0d8HIcIc8d4d 	 **6*LLr9   c                     U R                  U5      nU(       a  UR                  OSnUn[        R                  " USUR                  S9$ )z"Get dynamic label for bank action.r   r   r   )r   r   r   r   r$   )r   r   r  r   r   r  s         r:   r   FarkleGame._get_bank_label2  s=    }}V$ $$&,m>V>VWWr9   c                 "    U R                  5       $ )z,Check if check turn score action is enabled.)guard_game_activer   r   s     r:   r   'FarkleGame._is_check_turn_score_enabled9  s    %%''r9   c                 "    [         R                  $ )z;Check turn score is always hidden from menu (keybind only).)r   HIDDENr,  s     r:   r   &FarkleGame._is_check_turn_score_hidden=  s       r9   c                 $    U R                  U5      $ )zWCheck if a scoring action is enabled (scoring actions are only created when available).)r  r,  s     r:   r  %FarkleGame._is_scoring_action_enabledA  s    --f55r9   c                 $    U R                  U5      $ )z$Check if a scoring action is hidden.)r  r,  s     r:   r  $FarkleGame._is_scoring_action_hiddenE  s    **622r9   c                     [        UR                  5      S:  a  [        UR                  5      $ S[        UR                  5      -
  nUS:X  a  SnU$ )z+Get the number of dice that will be rolled.r   r\   )rw   r'   r(   )r   r   r!  s      r:   r   FarkleGame._get_roll_dice_countI  sL    v""#a'v**++3v1122H1}Or9   c           	      $   Un[        UR                  5      S:X  a(  S[        UR                  5      -
  nUS:X  a	  / Ul        SnO[        UR                  5      nU R                  USSUS9  U R	                  S5        [
        R                  " U[        R                  " SS5      S	9  [        [        U5       Vs/ s H  n[        R                  " S
S5      PM     sn5      Ul        SR                  S UR                   5       5      nU R                  SUS9  [        UR                  5      (       dv  U R	                  S5        U R                  USSUR                  S9  U=R                  S
-  sl        SUl        / Ul        / Ul        S
Ul        SUl        U R%                  5         gSUl        U R)                  U5        [+        UR                  5      nU(       a   US   u  pnSU SU	 3n
U R-                  X:S9  gU R/                  U5        gs  snf )zHandle roll action.r   r\   zfarkle-you-rollzfarkle-rollsr   zgame_pig/roll.oggr   r   ticksr   z, c              3   8   #    U  H  n[        U5      v   M     g 7fN)str)re   ds     r:   rh   *FarkleGame._action_roll.<locals>.<genexpr>m  s     H-GSVV-Gs   zfarkle-roll-result)rT   zgame_farkle/farkle.oggzfarkle-you-farklezfarkle-farkler   NFr  r  )selection_id)rw   r'   r(   broadcast_personal_l
play_soundr   jolt_botrandomrandintsortedr{   joinbroadcast_lr   r$   r,   r*   r+   end_turnr)   r  r   update_player_menurebuild_player_menu)r   r   r  r  r!  r  dice_strr  rU   rV   r?  s              r:   r   FarkleGame._action_rollS  s   &, }))*a/3}8899H1},.)=556H!!&*;^S[!\+, 	6B)?@ &,+0?;?aV^^Aq!?;&
"
 99H]-G-GHH-H=   : :;;OO45%%+_]E]E] &  %%*%'(M$)+M&(*M%01M-+,M(MMO ).% 	##M2 ,M,F,FG$*1I!J#J<q9L##M#M$$]3I <s   8!Hc                    Un[         R                  " U[        R                  " SS5      S9  UR	                  SS5      S   nUR                  S5      (       a
  [        nSnGOUR                  S5      (       a
  [        nSnGOUR                  S	5      (       a%  [        n[        UR	                  S5      S
   5      nGOKUR                  S5      (       a%  [        n[        UR	                  S5      S
   5      nGOUR                  S5      (       a$  [        n[        UR	                  S5      S
   5      nOUR                  S5      (       a$  [        n[        UR	                  S5      S
   5      nOUR                  S5      (       a	  [        nSnO}UR                  S5      (       a	  [        nSnO^UR                  S5      (       a	  [        nSnO?UR                  S5      (       a	  [         nSnO UR                  S5      (       a	  ["        nSnOg[%        UR&                  XV5      (       d#  U R)                  U5        U R+                  U5        g[-        XV5      nU[/        SUR0                  5      -  nU R3                  XV5      n	U R5                  X5U5        U=R6                  U-  sl        U R9                  S5        U[:        ;   a  U R=                  [:        U   SS9  U R?                  USSXS9  [A        URB                  5      S:X  a  [A        UR&                  5      S:X  a  U RE                  S5        U RF                  R0                  (       as  U=RH                  S-  sl$        U RK                  URH                  5      n
U R9                  SU
S9  U=R0                  S-  sl        U RM                  SUR0                   3S S!9  OU R9                  S5        S"Ul'        U R)                  U5        U R+                  U5        g)#z$Handle taking a scoring combination.      r8  r  r   rI   rJ   rY   rK   rL   rM   rN   rO   r   rP   rQ   rR   rS   Nzgame_farkle/takepoint.oggr   )delay_tickszfarkle-you-take-combozfarkle-takes-combo)combor   r\   zfarkle-hot-dicezgame_farkle/hotdice.ogg)pitchzHot Dice Multiplier table)bufferT)(r   rB  rC  rD  splitr
  rn   ro   rp   r4   rq   rr   rs   ru   rt   rv   rx   ry   r~   r'   r  rJ  r   r   r*   r   _remove_combo_dicer$   rA  COMBO_SOUNDSschedule_soundr@  rw   r(   rG  r   r+   _get_hot_dice_pitch	broadcastr)   )r   r   r  r  partsrU   rV   base_pointsr   
combo_namerS  s              r:   r  FarkleGame._action_take_combo  sz   &, 	62)>? Q'* J'''JFj))'JFo..,JS)"-.Fn--+JS)"-.Fn--+JS)"-.Fm,,*JS)"-.F.//-JF.//-JFm,,*JF/00.JFl++)JF }99:NN''6$$]3,Z@s1m&G&GHH))*=
 	6B 	  F*  	34%Z 8aH 	!!+-A 	" 	

 }(()Q.3}7Q7Q3RVW3W./||//,,1,001M1MN 9G11Q61*=+L+L*MN"  
  9: )-% 	##M2  /r9   c                   ^ [        UR                  5      mU[        :X  a7  UR                  R                  S5        UR                  R                  S5        g	U[        :X  a7  UR                  R                  S5        UR                  R                  S5        g	U[        :X  aI  [        S5       H9  nUR                  R                  U5        UR                  R                  U5        M;     g	U[        :X  aI  [        S5       H9  nUR                  R                  U5        UR                  R                  U5        M;     g	U[        :X  aI  [        S5       H9  nUR                  R                  U5        UR                  R                  U5        M;     g	U[        :X  aI  [        S5       H9  nUR                  R                  U5        UR                  R                  U5        M;     g	U[        :X  a-  UR                  R                  UR                  5        / Ul        g	U[        :X  a  [        UR                  5      m[        U4S j[        SS5       5       5      nU(       a  / SQnO/ SQnU H9  nUR                  R                  U5        UR                  R                  U5        M;     g	U[         ["        [$        4;   a-  UR                  R                  UR                  5        / Ul        g	g	)
z8Remove dice from current_roll for the given combination.r   rY   r   r[   r\   c              3   4   >#    U  H  nTU   S :  v   M     g7f)r   Nr.   rd   s     r:   rh   0FarkleGame._remove_combo_dice.<locals>.<genexpr>  s     >+Q&)q.+rk   )r   r   r   r[   rY   )r   r   r[   rY   r\   N)r   r'   rn   remover(   r   ro   rp   r{   rq   rr   rs   rt   extendru   allrv   rx   ry   )	r   r   rU   rV   r  has_1_5neededr   rg   s	           @r:   rW  FarkleGame._remove_combo_dice  sQ   F//0'&&q)%%a(>)&&q)%%a(..1X##**62""))&1  --1X##**62""))&1  --1X##**62""))&1  ,,1X##**62""))&1  //%%f&9&9:"$F// 3 34F>%1+>>G((##**3/""))#.  !
 
 %%f&9&9:"$F
r9   r+   c                 n    US::  a  gUS-
  n[        SSUS-  -  -  5      n[        S[        SU5      5      $ )zCGet pitch for hot-dice sound, raising by semitones after the first.r   r   r   rO  r   2   )roundminr   )r   r+   semitone_stepsrS  s       r:   rZ  FarkleGame._get_hot_dice_pitch1  sE    Q (!+cQ>B#67893B''r9   c                 R   UnU R                  U5      nUR                  S:X  aj  U R                  R                  S:  aP  UR                  U R                  R                  :  a,  U(       a$  UR                  SU R                  R                  S9  gU=R                  S-  sl        UR                  UR                  :  a  UR                  Ul        U=R                  UR                  -  sl        U R                  R                  UR                  UR                  5        U R                  S[        R                  " SS5       S35        U R                  US	S
UR                  UR                  S9  SUl        / Ul        / Ul        SUl        SUl        SUl        U R)                  5         g)zHandle bank action.r   z!farkle-minimum-initial-bank-scorer#   Nr   zgame_farkle/bankr   z.oggzfarkle-you-bankzfarkle-banks)r   totalF)r   r#   r   rG   r$   speak_lr,   r-   _team_manageradd_to_team_scorer   rA  rC  rD  r@  r'   r(   r)   r*   r+   rH  )r   r   r  r  r   s        r:   r   FarkleGame._action_bank;  ss   &,}}V$ 1$//!3((4<<+J+JJ7,,99    	!!Q&!##m&=&==&3&>&>M# 	}777 	,,V[[-:R:RS*6>>!Q+?*@EF!! ++%% 	" 	
 $% %'"$&!(-%,-)'($r9   c                     U R                   nU R                  U5      nU(       d  gU(       a(  UnUR                  SUR                  UR                  S9  gUR                  S5        g)zHandle check turn score action.Nzfarkle-turn-score)r   r   zfarkle-no-turn)current_playerr   rr  r   r$   )r   r   r  currentr   farkle_currents         r:   r   #FarkleGame._action_check_turn_scorek  s_    %%}}V$+2NLL#||%00  
 %&r9   c                 j    UnSUl         SUl        / Ul        / Ul        SUl        SUl        SUl        g Nr   Fr   )r#   r$   r'   r(   r)   r*   r+   )r   r   farkle_ps      r:   _reset_player_for_game!FarkleGame._reset_player_for_game{  s>    !' "!#( '($"#r9   c                 ~    UnSUl         / Ul        / Ul        SUl        SUl        SUl        U R                  U5        g r|  )r$   r'   r(   r)   r*   r+   r  )r   r   r  s      r:   _reset_player_for_turn!FarkleGame._reset_player_for_turn  sE    &,#$ %'"$&!(-%,-)'($##M2r9   c                 V    UR                   (       a  [        R                  " US5        g g )Nr   )r   r   
set_targetr,  s     r:   _setup_bot_for_turnFarkleGame._setup_bot_for_turn  s    ==  + r9   c                 r   > [         TU ]  5         U R                  (       d  g[        R                  " U 5        g)z6Called every tick. Handle bot AI and scheduled sounds.N)r   on_tickgame_activer   r   s    r:   r  FarkleGame.on_tick  s'    $r9   c                     [        X5      $ r;  r   r,  s     r:   r   FarkleGame.bot_think  s    &&r9   c                    U R                  5       n/ nSnU Ho  nUnUR                  U R                  R                  :  d  M+  UR                  U:  a  U/nUR                  nML  UR                  U:X  d  M^  UR	                  U5        Mq     [        U5      S:X  aF  U R                  S5        US   nU R                  US   SSUR                  S9  U R                  5         g[        U5      S:  a  U Vs/ s H  owR                  PM     nnU R                   HO  nU R                  U5      n	U	(       d  M  [        R                  " U	R                  U5      n
U	R                  SU
SS	9  MQ     U Vs/ s H  owR                  PM     nnU H  nUR                  U;  d  M  S
Ul        M     U R#                  5         gU R#                  5         gs  snf s  snf )zHandle end of a round.r   r   zgame_pig/win.oggzfarkle-you-winzfarkle-winnerrp  zfarkle-winners-tierT  )r   rU  TN)get_active_playersr#   r   rF   r   rw   rA  r@  finish_gamer   r   r   r   format_list_andr   rr  is_spectator_start_round)r   active_playerswinners
high_scorepr}  winner_farklewnamesr   	names_strwinner_namess               r:   _on_round_endFarkleGame._on_round_end  s    002
A%&H~~!:!::>>J. cG!)J^^z1NN1%   w<1OO./*1!*M%%
,o]EXEX &  \A%,-WVVWE-\\}}Q'4 , < <T[[% PILL!5yQXLY	 " -44GqFFGL4#66-%)AN $   . 5s   2G,Gc                    [        U R                  5       S SS9n0 n0 nU HM  nUnUR                  X$R                  '   UR                  UR
                  UR                  S.X4R                  '   MO     U(       a  US   OSnUn[        U R                  5       [        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U(       a  UR                  OSU(       a  UR                  OSUUU R                   U R"                  R$                  S
.S9$ s  snf )z0Build the game result with Farkle-specific data.c                     U R                   $ r;  rp  )r  s    r:   r   .FarkleGame.build_game_result.<locals>.<lambda>  s    !''r9   Tr   )r,   r-   total_scorer   Nis_virtual_botF)r   player_namer   r  )winner_namewinner_scorefinal_scoresplayer_statsrounds_playedrF   )	game_type	timestampduration_ticksplayer_resultscustom_data)rE  r  r#   r   r,   r-   r   r   r   now	isoformatsound_scheduler_tickr   r   r   getattrrk  r   rF   )r   sorted_playersr  r  r  r}  winnerr  s           r:   build_game_resultFarkleGame.build_game_result  sE   ##%!
 A%&H#+>>L '33%//'~~$L    '5"$&,mmolln..044 002 3A dd !88#*1.>#F	 3 /5v{{$7D 3 3! , ,!% $ 9 9
 	
s   ?E%resultc                    [         R                  " US5      /nUR                  R                  S0 5      n[        UR	                  5       S5       H7  u  nu  pg[         R                  " USUS9nUR                  U SU SU 35        M9     U$ )z&Format the end screen for Farkle game.zgame-final-scoresr  r   zgame-pointsr   z. z: )r   r   r  	enumerateitemsr   )	r   r  r   linesr  rf   r   r#   
points_strs	            r:   format_end_screenFarkleGame.format_end_screen  s    !!&*=>?))--nbA ),*<*<*> BA}%))&-uMJLLA3bb56 !C r9   jolt_minjolt_maxc                 v    [         R                  " U [        R                  " X5      S9  U R	                  5         g)zEnd the current player's turn.r8  N)r   	jolt_botsrC  rD  _on_turn_end)r   r  r  s      r:   rH  FarkleGame.end_turn  s'    Dx(JKr9   r.   )F)rW   N)r      )>r/   r0   r1   r2   r3   round_start_soundr   r6   r   r!   r5   r<   r   classmethodr<  r   r   r   r4   r   r   dictr   r7   r   r   r   r   r   r   r  r   r   r   r   r   r   r   r   r   r   r  r  r   r   r  rW  rZ  r   r   r~  r  r  r  r   r  r   r  r  rH  r8   __classcell__)r   s   @r:   r   r      s    "'"=GT,="=AG]A      %S % %       
d4j 
 
$
s 
# 
t 
P\ 
*\ *i *X	
3s 3 3S 3RU 3Z] 34# s s 4,2\ ,2d ,2d	v 	#* 	Mf M MGf G G Gv #* Mf M MXf X X X(6 (cDj (!& !Z !6 6C$J 63 3: 3< C :46 :4c :4d :4x^0 ^0C ^0D ^0@@% @%3 @%PS @%X\ @%D(# (# (.6 .c .d .`'v '# '$ ' $3, ' 't ') V,
: ,
\	
 	C 	DI 	 S $  r9   r   )r   )@r3   dataclassesr   r   r   rC  baser   r   r	   registryr
   game_utils.action_guard_mixinr   !game_utils.round_based_game_mixinr   game_utils.actionsr   r   r   game_utils.bot_helperr   game_utils.dicer   r   r   r   game_utils.game_resultr   r   game_utils.optionsr   r   r   messages.localizationr   server.core.ui.keybindsr   botr   r!   r<   rn   ro   rp   rq   rr   rs   ru   rt   rv   rx   ry   rX  r6   r4   r<  r7   r~   r   r   tupler   r   r.   r9   r:   <module>r     s   )   , , $ = D ? ? .  ? E E 1 0  6   !K ! !J % # # ! ' ' ! )   -.0//.99/;1#$s) # #c #$ #Ls C  6!49 ! !HGT#Y G4c3m8L3M GT d!#6 d  dr9   