
    Ii                     J    S r SSKJrJr  \(       a  SSKJrJr   " S S5      rg)a  Bot helper for managing AI player actions.

This is a stateless helper that operates on serialized Player fields:
- player.bot_think_ticks: Ticks until bot can act
- player.bot_pending_action: Action to execute when ready
- player.bot_target: Game-specific target value
    )TYPE_CHECKINGCallable   )GamePlayerc            
       .   \ rS rSrSrSr\ SSSS\S-  S\S	   S-  S
S4S jj5       r	\SSS	S\S-  S
S4S jj5       r
\SS	S\S-  S
S4S j5       r\SS	S
\S-  4S j5       r\SS	S\/ \S-  4   S\\/S4   S
\4S j5       r\SSSS\S
S4S jj5       rSrg)	BotHelper   zStateless helper for managing bot AI in games.

All bot state is stored on Player fields for serialization. This helper
provides utility methods for manipulating that state.

Usage:
    BotHelper.on_tick(self)
    BotHelper.jolt_bots(game, ticks=10)
   Ngamer   ticksplayersr   returnc                     Ub  UO[         R                  nUb  UOU R                  nU H#  nUR                  (       d  M  X5l        SUl        M%     g)z
Make bots pause before they can act.

Args:
    game: The game instance.
    ticks: How many ticks to pause. Uses DEFAULT_THINK_TICKS if None.
    players: Specific players to jolt. All bots in game if None.
N)r	   DEFAULT_THINK_TICKSr   is_botbot_think_ticksbot_pending_action)r   r   r   pause_tickstarget_playersplayers         ;c:\Users\dbart\PlayPalace11\server\game_utils\bot_helper.py	jolt_botsBotHelper.jolt_bots   sG      %0ei6S6S$+$7T\\$F}}})4&,0) %    r   c                 l    U R                   (       a#  Ub  UO[        R                  nX l        SU l        gg)zJolt a single bot.N)r   r	   r   r   r   )r   r   r   s      r   jolt_botBotHelper.jolt_bot1   s0     ==#(#4%):W:WK%0"(,F% r   targetc                     Xl         g)z%Set a game-specific target for a bot.N
bot_target)r   r   s     r   
set_targetBotHelper.set_target9   s
     #r   c                     U R                   $ )z'Get the game-specific target for a bot.r!   )r   s    r   
get_targetBotHelper.get_target>   s        r   botthink_fn
execute_fnc                     U R                   S:  a  U =R                   S-  sl         gU R                  (       a  U R                  nSU l        U" U5        gU" 5       nU(       a  X0l        gg)a  
Process a single bot's action cycle: think -> pending -> execute.

This encapsulates the common pattern for bot action handling:
1. Count down think ticks if bot is still "thinking"
2. Execute pending action if one exists
3. Otherwise, call think function to decide what to do

Args:
    bot: The bot player to process.
    think_fn: A callable that returns an action_id (or None if no action).
    execute_fn: A callable that takes an action_id and executes it.

Returns:
    True if the bot took an action (executed or set pending), False if still thinking.

Example usage:
    BotHelper.process_bot_action(
        bot=player,
        think_fn=lambda: self.bot_think(player),
        execute_fn=lambda action_id: self.execute_action(player, action_id),
    )
r      FNT)r   r   )r(   r)   r*   	action_ids       r   process_bot_actionBotHelper.process_bot_actionC   sg    < "1$ !!..I%)C"y! J	%."r   debugc                 B   U R                   (       a  U R                  S:w  a  gU R                  nU(       aD  [        SU(       a  UR                  OS SU(       a  UR
                  OS SU R                   35        U(       a  UR
                  (       d  gUR                  S:  a  U=R                  S-  sl        gUR                  (       a%  UR                  nSUl        U R                  X#5        g[        U S5      (       a   U R                  U5      nU(       a  X2l        ggg)	zO
Process bot actions for a tick.

Call this from your game's on_tick() method.
playingNz[BotHelper] current=z	, is_bot=z, turn_index=r   r,   	bot_think)game_activestatuscurrent_playerprintnamer   
turn_indexr   r   execute_actionhasattrr3   )r   r0   currentr-   s       r   on_tickBotHelper.on_tickt   s    4;;)#; %%&ww||D&IelSZSaSarvRw  xE  FJ  FU  FU  EV  W gnn ""Q&##q(# %%22I)-G&3 4%%w/I-6*  &r    )NN)N)F)__name__
__module____qualname____firstlineno____doc__r   staticmethodintlistr   r   r#   r&   r   strboolr.   r=   __static_attributes__r?   r   r   r	   r	      sK    QU11 4Z19=h$9N1	1 1& - -#* - - - #8 #S4Z #D # # !8 !d
 ! ! ..2sTz>*. cUD[). 
	. .` #7f #7T #7d #7 #7r   r	   N)rD   typingr   r   
games.baser   r   r	   r?   r   r   <module>rM      s!    +)I7 I7r   