
    Ii"                        S r SSKJr  SSKJr  SSKJrJr  \(       a  SSKJ	r	J
r
  SS	S
SS\S-  4S jr  S)S\\   S\\   S\S\\   S\S\S\\\   \\   \4   4S jjrS\\\      S\\   S\S\\\   \\   \4   4S jrS\\   S\\   S\\   S\4S jrS\\   S\4S jrS\\   S\\   S\S\\   S\S\S\S\\\   \\   \4   4S jrSS	S\S
SS\4S jrS\S \S\4S! jrSS	S\S
SS\4S" jrSS	S\S
SS \S\S\4S# jrSS	S\S\\\      S \S\4
S$ jrS\\   S \S\4S% jrS\\   S&\\   S \S\4S' jrS\\   S \S\4S( jrg)*zD
Bot AI for Scopa game.

Handles bot decision making for card play.
    )TYPE_CHECKING   )Card   )find_capturesselect_best_capture)	ScopaGameScopaPlayergamer	   playerr
   returnNc                     UR                   (       d  gSn[        S5      nUR                    H  n[        XU5      nXS:  d  M  UnUnM     U(       a  SUR                   3$ g)z
Bot AI decision making.

Args:
    game: The Scopa game instance.
    player: The bot player making a decision.

Returns:
    Action ID to execute, or None if no action available.
Nz-inf
play_card_)handfloatevaluate_cardid)r   r   	best_card
best_scorecardscores         5c:\Users\dbart\PlayPalace11\server\games\scopa\bot.py	bot_thinkr      sa     ;; IvJd&1JI	  ILL>**    tableremaining_handescobacards_playeddepth	max_depthc           
          XE:  d  U(       d  / / S4$ / n/ nSnU HQ  n	[        X	R                  U5      n
U
(       a  [        XU	5      u  pnO[        U UUUU	UU5      u  pnX:  d  MK  UnUnUnMS     XgU4$ )a  
Recursively find the best combo chain starting from current state.

Returns the sequence of cards to play and what gets captured at the end.

Args:
    table: Current table cards (simulated).
    remaining_hand: Cards still in hand.
    escoba: Whether escoba rules apply.
    cards_played: Cards played so far in this combo chain.
    depth: Current recursion depth.
    max_depth: Maximum depth to search.

Returns:
    Tuple of (cards_to_play, cards_captured, score).
        )r   rank_evaluate_combo_completion_explore_combo_chain)r   r   r   r   r   r    best_sequencebest_capturedr   r   capturessequencecapturedr   s                 r   find_best_combo_chainr+   -   s    0 B} "M "MJ 		6:(B8[_(`%H(<)%H J$M$M% ( *55r   r(   r   c                     [        U 5      nU Vs1 s H  oDR                  iM     nnU Vs/ s H  oDR                  U;   d  M  UPM     nnU(       d  / / S4$ [        X6U5      nX/-   X74$ s  snf s  snf )Nr"   )r   r   _score_combo_completion)r(   r   r   best_capturec
played_setcaptured_from_combor   s           r   r$   r$   c   su     'x0L ,-1$$J-&2Ilddj6H1lIB}#L|TE6!<77 .Is   A)A.A.r.   r1   c                     S[        U 5      S-  -   nU[        U5      S-  -  nU[        U5      S-  -  nU[        U 5      -  nU$ )N         r   )len_score_combo_captured_cards)r.   r1   r   r   s       r   r-   r-   p   sV    
 \"Q&&E	S$%))E	S""E	(66ELr   captured_cardsc                     SnU  HV  nUR                   S:X  a  US-  nUR                  S:X  a  US-  nUR                  S:X  d  M?  UR                   S:X  d  MQ  US-  nMX     U$ )Nr"   r         r   r4   suitr#   )r8   r   r   s      r   r7   r7   |   s^    E99>QJE99>QJE99>dii1nQJE  Lr   c                     X/-   nU Vs/ s H   oR                   UR                   :w  d  M  UPM"     n	nX4/-   n
[        XyX*US-   U5      $ s  snf )Nr   )r   r+   )r   r   r   r   r   r   r    	new_tabler/   new_hand
new_playeds              r   r%   r%      sS     I)=>aTTTWW_>H=&J f%RS)U^__ >s
   A	A	c                    U R                   R                  nUR                   Vs/ s H   oDR                  UR                  :w  d  M  UPM"     nnU(       d  gU R                  U/-   n[        UUUU/S[        [        U5      S5      S9u  pxn	U(       a6  [        U5      n
[        U R                  5       5      nSU
S-
  US-
  -  -  nX-  n	U	$ s  snf )u  
Check if playing this card sets up a capture combo chain.

Handles multi-card combos like:
- Table: 2, Hand: 3, 5, 10
- Play 3 → table: 2, 3
- Play 5 → table: 2, 3, 5 (sum = 10)
- Play 10 → captures 2, 3, 5!

Args:
    game: The Scopa game instance.
    card: The card being considered for play.
    player: The bot player.

Returns:
    Bonus score if combo potential exists.
r"   r      )r   r   r    gffffff?r   )	optionsr   r   r   table_cardsr+   minr6   get_active_players)r   r   r   r   r/   other_cardssimulated_tabler)   r*   r   chain_lengthnum_playersrisk_factors                r   check_combo_potentialrM      s    $ \\  F$kk=kTTTWW_1kK= &&$/O !6Vc+&*!H 8} $1134|a/K!ODEL9 >s   C
C
inversec                     U R                   S::  a!  SSU R                   -
  S-  -   nU(       d  U$ U* $ SU R                   S-
  S-  -
  nU(       d  U$ U* $ )aZ  
Evaluate card for playing on empty table in escoba mode.

Cards with value <= 4 cannot be captured alone (15 - 4 = 11 > max rank 10),
preventing opponent from both capturing AND sweeping.

Args:
    card: The card being considered.
    inverse: If True, inverse scopa rules apply.

Returns:
    Score bonus/penalty for this card on empty table.
rC      r4   r:   r   )r#   )r   rN   safety_bonusrisk_penaltys       r   evaluate_escoba_empty_tablerT      s_     yyA~ Q]a//#*|== dii!mq00#*|==r   c                     U R                   R                  nU R                   R                  n[        U R                  UR
                  U5      nU(       d  [        XX#U5      $ [        XXS5      $ )z
Evaluate a card for bot play.

Args:
    game: The Scopa game instance.
    card: The card to evaluate.
    player: The bot player.

Returns:
    Score for this card (higher is better).
)rD   inverse_scopar   r   rE   r#   _score_non_capture_score_capture)r   r   r   rN   r   r(   s         r   r   r      sY     ll((G\\  FT--tyy&AH!$fvFF$h88r   c                     U(       a  SUR                   S-  -
  OSUR                   S-  -   nU[        XU5      -  nU(       a'  [        U R                  5      S:X  a  U[	        X5      -  nU$ )N
   g      ?r   )r#   rM   r6   rE   rT   )r   r   r   rN   r   r   s         r   rW   rW      sc     '.B$))c/"2S3IE	"4v66E#d&&'1,,T;;Lr   c                     [        U5      n[        XC5      nU[        X@R                  U5      -  nU[	        XC5      -  nU$ )N)r   _score_capture_size_score_scoparE   _score_capture_cards)r   r   r(   rN   r.   r   s         r   rX   rX     sD     'x0L6E	\,(8(8'BBE	!,88ELr   c                 <    [        U 5      nU(       a  U* S-  $ US-  $ )NrZ   r6   )r.   rN   num_captureds      r   r]   r]     s%    |$L!(L=2?lR.??r   rE   c                     [        U 5      nU[        U5      :H  =(       a    [        U5      S:  nU(       d  gU(       a  S$ S$ )Nr   r"   id   ra   )r.   rE   rN   rb   is_scopas        r   r^   r^     s=    |$Ls;//HC4Dq4HH4##r   c                 (   SnU  H  nUR                   S:X  a  X!(       a  SOS-  nUR                  S:X  a  UR                   S:X  a  X!(       a  SOS-  nUR                  S:X  a  X!(       a  SOS	-  nUR                  S
;   d  M|  X!(       a  SOS-  nM     U$ )Nr"   r   r[   r4   r;   rQ      r   )r      r:   r<   )r.   rN   r   r   s       r   r_   r_     s    E99>7R)E99>dii1nGS+E99>7R)E997R)E  Lr   )r   rC   )__doc__typingr   game_utils.cardsr   capturer   r   r   r	   r
   strr   listboolinttupler   r+   r$   r-   r7   r%   rM   rT   r   rW   rX   r]   r^   r_    r   r   <module>ru      s   ! $ 7,K  3: D 36:36J36 36 t*	36
 36 36 4:tDz5()36l
84:
8.24j
8@D
8
4:tDz5()
8	t*	d	 t*	 			T
 	u 	`:`J` ` t*	`
 ` ` ` 4:tDz5()`/ /4 / /SX /d>d >T >e >49 94 9 95 9.
!+8CGQU

!-1$t*-=HL
@d4j @4 @E @
$tDz $T
 $T $V[ $tDz D U r   