
    Ii              	         S r SSKJr  SSKJrJr  SSKJr  SSK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  SSKJr  SSK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K(J)r)  SSK*J+r+J,r,  SSK-J.r/  \	(       a  SSK*J0r0  Sr1Sr2Sr3SS/r4Sr5Sr6S r7S!r8S"r9S#r:Sr;Sr<Sr=Sr>/ S$Qr?/ S%Qr@S&S'S(S)S%.rAS*S+/rBS,S-S..rCS/S0/rD\ " S1 S2\5      5       rE\ " S3 S4\5      5       rF\ " S5 S6\5      5       rG\;4S>S7 jjrH              S?S8 jrI      S@S9 jrJ        SAS: jrK      SBS; jrL\\ " S< S=\\%\5      5       5       rMg)CzX
Battleship Game Implementation for PlayPalace v11.

Classic naval combat on a 2D grid.
    )annotations)	dataclassfield)datetimeN)TYPE_CHECKING)DataClassJSONMixin   )GamePlayerGameOptions)register_game   )Action	ActionSet
Visibility)	BotHelper)
GameResultPlayerResult)GridGameMixin
GridCursor)
MenuOption
BoolOptionoption_field)PokerTurnTimer)TurnTimerMixin)Localization)KeybindState)MenuItemEscapeBehavior   )	bot_think)Userzgame_battleship/fire.oggzgame_battleship/miss.oggzgame_battleship/hit.oggzgame_battleship/sunk1.oggzgame_battleship/sunk2.oggzgame_battleship/place.oggzgame_battleship/deploy_done.oggzgame_pig/wingame.oggzgame_pig/lose.oggzgame_battleship/mus.ogg   ))carrier   )
battleship   )	destroyerr   )	submariner   )patrolr	   )681012zbattleship-grid-6x6zbattleship-grid-8x8zbattleship-grid-10x10zbattleship-grid-12x12automanualzbattleship-placement-autozbattleship-placement-manual)r/   r0   
horizontalverticalc                      \ rS rSr% SrS\S'   S\S'   SrS\S'   SrS\S	'   S
rS\S'   Sr	S\S'   \
SS j5       rSS jrSrg)ShipZ   z"A ship placed on a player's board.strtype_keyintsizer   rowcolTboolr1   hitsc                4    U R                   U R                  :  $ Nr=   r9   )selfs    ;c:\Users\dbart\PlayPalace11\server\games\battleship\game.pysunk	Ship.sunke   s    yyDII%%    c                   / n[        U R                  5       Hj  nU R                  (       a,  UR                  U R                  U R
                  U-   45        M@  UR                  U R                  U-   U R
                  45        Ml     U$ )z2Return all (row, col) cells occupied by this ship.)ranger9   r1   appendr:   r;   )rA   resultis      rB   cells
Ship.cellsi   sb    tyy!AtxxA67txx!|TXX67	 "
 rE    N)returnr<   )rN   zlist[tuple[int, int]])__name__
__module____qualname____firstlineno____doc____annotations__r:   r;   r1   r=   propertyrC   rK   __static_attributes__rM   rE   rB   r4   r4   Z   sK    ,M
ICLCLJD#M& &rE   r4   c                      \ rS rSr% Sr\" \S9rS\S'   \" \S9r	S\S'   \" \S9r
S\S'   S	rS
\S'   SrS\S'   SrS\S'   S	rS
\S'   S	rS
\S'   Srg)BattleshipPlayert   z5Player with own board, shot tracking, and ship fleet.default_factorylist[list[int]]	own_board
shot_board
list[Ship]shipsr   r8   ships_placedFr<   deploy_readyTviewing_owntotal_shots
total_hitsrM   N)rO   rP   rQ   rR   rS   r   listr]   rT   r^   r`   ra   rb   rc   rd   re   rV   rM   rE   rB   rX   rX   t   sf    ? "'t!<I<"'"=J=d3E:3L#L$KKJrE   rX   c                      \ rS rSr% \" \" \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SS95      rS\	S'   \" \" / SQSSSSSS S!S"S#S.S$S95      rS	\	S%'   S&rg')(BattleshipOptions   r-   r9   zbattleship-set-grid-sizezbattleship-select-grid-sizez#battleship-option-changed-grid-sizezbattleship-desc-grid-size)choicesdefault	value_keylabelprompt
change_msgchoice_labelsdescriptionr6   	grid_sizer/   modezbattleship-set-placement-modez battleship-select-placement-modez(battleship-option-changed-placement-modezbattleship-desc-placement-modeplacement_modeFenabledzbattleship-set-replay-on-hitz'battleship-option-changed-replay-on-hitzbattleship-desc-replay-on-hit)rk   rl   rm   ro   rq   r<   replay_on_hit)0304560rw   secondszbattleship-set-turn-timerzbattleship-select-turn-timerz$battleship-option-changed-turn-timerzbattleship-timer-offzbattleship-timer-30zbattleship-timer-45zbattleship-timer-60zbattleship-desc-turn-timer
turn_timerrM   N)rO   rP   rQ   rR   r   r   GRID_SIZE_CHOICESGRID_SIZE_LABELSrr   rT   PLACEMENT_CHOICESPLACEMENT_LABELSrt   r   rv   r|   rV   rM   rE   rB   rh   rh      s    !%,0<*3		
Is  '%15A*8		
NC  '0@7	
M4  #+-1=++++	 5	
J rE   rh   c                J    [        U 5       Vs/ s H  o!/U -  PM
     sn$ s  snf r?   )rG   )r9   fill_s      rB   _make_boardr      s"    #(;/;aFTM;///s    c                    [        U5       HF  nU(       a  UOX&-   nU(       a  X6-   OUnUS:  d  Xu:  d  US:  d  X:  a    gX   U   [        :w  d  MF    g   g)z4Check if a ship can be placed at the given position.r   FT)rG   
CELL_EMPTY)	boardr9   r:   r;   r1   rr   rJ   rcs	            rB   _can_place_shipr      sV     4[C37!CGsq5ANa!eq~8A;*$  rE   c                L    UR                  5        H  u  p#[        X   U'   M     g)zMark ship cells on the board.N)rK   	CELL_SHIP)r   shipr   r   s       rB   _place_ship_on_boardr      s!    
 

 rE   c           
        / nU H  u  pESn[        S5       H  n[        R                  " SS/5      nU(       a4  [        R                  " SUS-
  5      n	[        R                  " SX-
  5      n
O3[        R                  " SX-
  5      n	[        R                  " SUS-
  5      n
[	        XXX5      (       d  M  [        UUU	U
US9n[        X5        UR                  U5        Sn  O   U(       a  M  [        SU S35      e   U$ )	z7Randomly place all ships. Returns list of placed Ships.Fi  Tr   r    r7   r9   r:   r;   r1   zCould not place z after 1000 attempts)	rG   randomchoicerandintr   r4   r   rH   RuntimeError)r   rr   fleetr`   r7   r9   placedr   r1   r:   r;   r   s               rB   _random_place_fleetr      s     EtAe}5JnnQ	A6nnQ	(89nnQ	(89nnQ	A6uCjLL%) %U1T"' ( v!1(;OPQQ/  0 LrE   c                n    U R                  5        H!  nUR                  UR                  :w  d  M  Us  $    g)zGet the other player.N)get_active_playersid)gameplayerps      rB   _get_opponentr     s1    
 $$&44699H ' rE   c                  <  ^  \ rS rSr% \" \S9rS\S'   \" \S9r	S\S'   Sr
S\S	'   SrS\S
'   \" \S9rS\S'   \" \S9rS\S'   \" \S9rS\S'   \" \S9rS\S'   SrS\S'   SrS\S'   SrS\S'   \" \S9rS\S'   \" \S9rS\S'   \" \S9rS\S'   \" \S9rS\S'   S rS\S!'   S"rS\S#'   S"rS\S$'   SrS\S%'   \SaS& j5       r\SaS' j5       r\SaS( j5       r \SbS) j5       r!\SbS* j5       r"\ScS+ j5       r# Sd       SeS, jjr$SfU 4S- jjr%SgS. jr&ShU 4S/ jjr'SiS0 jr(SjU 4S1 jjr)SkU 4S2 jjr* Sl     SmU 4S3 jjjr+SjU 4S4 jjr,SkS5 jr-SkS6 jr.SnU 4S7 jjr/SjS8 jr0SjS9 jr1SjS: jr2SjS; jr3SjS< jr4          SoS= jr5SpS> jr6        SqS? jr7        SrS@ jr8        SsSA jr9      StSB jr:SjSC jr;        SsSD jr<        SsSE jr=SjSF jr>        SuSG jr?SvSH jr@SwSI jrASjSJ jrB    SxSK jrCSySL jrD      SzSM jrES{SN jrFS|SO jrG      SzSP jrHS{SQ jrIS|SR jrJ      SzSS jrKS{ST jrLS|SU jrMS}U 4SV jjrNS}U 4SW jjrOSjU 4SX jjrPS~SY jrQSSZ jrR      SS[ jrSSS\ jrTSjS] jrU            SS^ jrV          SS_ jrWS`rXU =rY$ )BattleshipGamei  rZ   zlist[BattleshipPlayer]playersrh   options
   r8   	grid_rows	grid_colszdict[str, GridCursor]grid_cursors	list[str]grid_row_labelsgrid_col_labelsr   timerFr<   _timer_warning_played	deployingr6   phaser   deploy_wait_tickszdict[str, int]placing_ship_indexzdict[str, bool]placing_orientation_pendingplacing_rowplacing_col shot_pending_player_idshot_pending_rowshot_pending_colshot_pending_ticksc                    g)N
BattleshiprM   clss    rB   get_nameBattleshipGame.get_name7      rE   c                    g)Nr&   rM   r   s    rB   get_typeBattleshipGame.get_type;  r   rE   c                    g)Nzcategory-playauralrM   r   s    rB   get_categoryBattleshipGame.get_category?  s    #rE   c                    gNr	   rM   r   s    rB   get_min_playersBattleshipGame.get_min_playersC      rE   c                    gr   rM   r   s    rB   get_max_playersBattleshipGame.get_max_playersG  r   rE   c                
    / SQ$ )N)winsratinggames_playedrM   r   s    rB   get_supported_leaderboards)BattleshipGame.get_supported_leaderboardsK  s    11rE   c                    [        XUS9$ )N)r   nameis_bot)rX   )rA   	player_idr   r   s       rB   create_playerBattleshipGame.create_playerO  s      9GGrE   c                F   > / nUR                  [        TU ]	  5       5        U$ r?   )extendsuperprestart_validate)rA   errors	__class__s     rB   r    BattleshipGame.prestart_validateW  s!    /1eg/12rE   c                   U R                  U5      nU(       a  UR                  OSn[        SS9nU R                  U5       H  nUR	                  U5        M     U R                  5        H  nUR	                  U5        M     U$ )Nenturn)r   )get_userlocaler   build_grid_actionsaddbuild_grid_nav_actions)rA   r   userr   
action_setactions         rB   create_turn_action_set%BattleshipGame.create_turn_action_set`  ss    }}V$ $$F+
 --f5FNN6" 6 113FNN6" 4 rE   c           
       > [         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        UR	                  [        S[        R                  " US	5      S
SSS95        UR	                  [        S[        R                  " US5      SSSS95        U R                  X#5        U$ )Nr   toggle_viewzbattleship-toggle-view_action_toggle_view_is_toggle_view_enabled_is_toggle_view_hidden)r   rm   handler
is_enabled	is_hidden
read_fleetzbattleship-read-fleet_action_read_fleet_is_read_fleet_enabled_is_read_fleet_hiddenread_enemy_fleetzbattleship-read-enemy-fleet_action_read_enemy_fleet_is_read_enemy_fleet_enabled_is_read_enemy_fleet_hidden)	r   create_standard_action_setr   r   r   r   r   get_apply_standard_action_order)rA   r   r   r   r   r   s        rB   r   )BattleshipGame.create_standard_action_seto  s    W7?
}}V$ $$ 	 "&&v/GH-42	
 	"&&v/FG,31	
 	%"&&v/LM297	
 	))*;rE   c                   / SQnUR                    Vs/ s H  oDU;  d  M
  UPM     snU Vs/ s H  oAR                  U5      (       d  M  UPM     sn-   Ul         U(       ar  [        USS5      S:X  a`  / SQnUR                    Vs/ s H  oDU;  d  M
  UPM     nnU H,  nUR                  U5      (       d  M  UR                  U5        M.     Xal         g g g s  snf s  snf s  snf )N)r   r   r   client_typer   web)r   r   r   check_scores
whose_turnwhos_at_table)_order
get_actiongetattrrH   )rA   r   r   
custom_idsaidtarget_order	new_orders          rB   r   +BattleshipGame._apply_standard_action_order  s    F
,6,=,=W,=SJAVS,=W%[
%C)>)>s)CC:[
 

 GD-4=L )3(9(9U(9=T(9IU#((--$$S) $ !* >4 X [
 Vs!   	CCC	C	CCc                  > [         TU ]  5         U R                  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 )NvzToggle viewr   )statefz
Read fleetr   ezRead enemy fleetr   )r   setup_keybindssetup_grid_keybindsdefine_keybindr   ACTIVE)rA   r   s    rB   r  BattleshipGame.setup_keybinds  s       "O%%	 	 	
 	N%%	 	 	
 	 %%	 	 	
rE   c                h   > U R                  U5        U R                  U5        [        TU ]  U5        g r?   )_sync_turn_actions_sync_standard_actionsr   rebuild_player_menurA   r   r   s     rB   r  "BattleshipGame.rebuild_player_menu  s,    '##F+#F+rE   c                d   > U R                  U5        U R                  U5        [        TU ]  XS9  g )N)selection_id)r  r  r   update_player_menu)rA   r   r!  r   s      rB   r"  !BattleshipGame.update_player_menu  s1    
 	'##F+"6"ErE   c                   > U R                    H%  nU R                  U5        U R                  U5        M'     [        TU ]  5         g r?   )r   r  r  r   rebuild_all_menusr  s     rB   r%   BattleshipGame.rebuild_all_menus  s:    llF##F+''/ # 	!#rE   c                j    U R                  US5      nU(       d  gU R                  U5      nU(       d  gg)z*Keep turn actions in sync with game phase.r   N)get_action_set_as_bp)rA   r   turn_setbps       rB   r  !BattleshipGame._sync_turn_actions  s3    &&vv6[[  rE   c                x    U R                  US5      nU(       d  g U R                  X R                  U5      5        g )Nstandard)r(  r   r   )rA   r   standard_sets      rB   r  %BattleshipGame._sync_standard_actions  s1    **6:>)),f8MNrE   c                  > UR                  S5      nUR                  SS5      nUS:X  a  U R                  R                  UR                  S5        U R	                  U5      nU(       d  U R                  U5        gUS:X  d  U(       d+  SU R                  UR                  '   U R                  U5        gUS:H  nU R                  XV5        g[        TU ]%  X5        g)	z&Handle orientation sub-menu selection.menu_idr!  r   orient_menuN_cancelFr1   )
r   _pending_actionspopr   r)  r  r   _try_place_shipr   _handle_menu_event)rA   r   eventr2  r!  r+  r1   r   s          rB   r8  !BattleshipGame._handle_menu_event  s    ))I&yy4m#!!%%fii6V$B((0y(:?007((,%5J  0"61rE   c                   [        U R                  R                  5      nXl        Xl        SU l        U R                  5         SU l        U R                  5        Hg  nU R                  U5      nU(       d  M  [        U5      Ul        [        U5      Ul        / Ul        SUl        SUl        SUl        SUl        SUl        Mi     U R'                  5         U R                  5        H  nU R)                  US5        U R+                  U5      nU(       d  M/  U R,                  R/                  UR0                  / 5      nUR3                  SU5        XPR,                  UR0                  '   M     U R                  R4                  S:X  a  U R7                  5         OYU R                  5        H5  nSU R8                  UR0                  '   SU R:                  UR0                  '   M7     U R=                  5         U R?                  5         g )NplayingTr   Fr   r/   ) r8   r   rr   r   r   status_sync_table_statusgame_activer   r)  r   r]   r^   r`   ra   rb   rc   rd   re   
_init_gridremove_action_setr   player_action_setsr   r   insertrt   _auto_deploy_allr   r   _announce_deploy_phaser%  )rA   r9   r   r+  r*  setss         rB   on_startBattleshipGame.on_start  s   4<<))*! --/FV$Br*40 +D 1"#"'!%!" ! 0 	 --/F""662226:Hx..22699bAAx(59''		2 0 <<&&&0!!# 11356''		2>C00; 4 '') rE   c                :   [        U R                  R                  5      nU R                  5        HX  nU R	                  U5      nU(       d  M  [        UR                  U[        5      Ul        [        [        5      Ul
        SUl        MZ     U R                  5         g)z4Auto-place ships for all players, then start battle.TN)r8   r   rr   r   r)  r   r]   FLEETr`   lenra   rb   _start_battle)rA   r9   r   r+  s       rB   rD  BattleshipGame._auto_deploy_all5  sq    4<<))*--/FV$B*2<<uEBH!%jBO"BO 0 	rE   c           
     &   U R                  5        H}  nU R                  U5      nU R                  U5      nU(       a  U(       d  M5  [        S   u  pEUR	                  SS[
        R                  " UR                  SU 35      [        U5      S9  M     g)z(Tell each player to start placing ships.r   zbattleship-deploy-startr   battleship-ship-r   r9   N)	r   r)  r   rJ  speak_lr   r   r   r6   )rA   r   r+  r   ship_key	ship_sizes         rB   rE  %BattleshipGame._announce_deploy_phaseA  s    --/FV$B==(DT"'(HLL)!%%dkk5EhZ3PQ^	   0rE   c                   SU l         U R                  5        H$  nU R                  U5      nU(       d  M  SUl        M&     U R	                  U R                  5       5        U R                  [        5        U R                  SSS9  U R                  5         U R                  5         U R                  5         U R                  5         g)z,Transition from deploying to battling phase.battlingFzbattleship-battle-starttablebufferN)r   r   r)  rc   set_turn_players
play_musicSOUND_MUSICbroadcast_lannounce_turn_maybe_start_timer
_jolt_botsr%  rA   r   r+  s      rB   rL  BattleshipGame._start_battleP  s    
--/FV$Br!& 0 	d5578$27C! rE   c                     [        U R                  R                  5      nUS:  a  U R                  5         g g ! [        [        4 a    Sn N,f = f)Nr   )r8   r   r|   
ValueErrorAttributeErrorstart_turn_timer)rA   r{   s     rB   r_  !BattleshipGame._maybe_start_timer`  sP    	$,,112G Q;!!#  N+ 	G	s   9 AAc                   U R                  U5      nU R                  X5      nU(       a  XR                  :  d  X R                  :  a  U$ UR                  (       d  U$ U R
                  S:X  a[  UR                  U   U   nU[        :X  a)  U R                  XQX$5      n[        R                  " USUUS9$ [        R                  " USUS9$ UR                  (       Ga  UR                  U   U   n[        X5      n	[        n
U	(       a  U	R                  U   U   n
U
[        :X  aj  U R                  XQX$5      nU R                  XQU5      nU(       a(  UR                   (       a  [        R                  " USUUS9$ [        R                  " USUUS9$ U
["        :X  a  [        R                  " USUS9$ U[        :X  a)  U R                  XQX$5      n[        R                  " US	UUS9$ [        R                  " USUS9$ UR                  U   U   nU[        :X  a  [        X5      n	U	(       ae  U R                  XU5      nU(       aL  UR                   (       a;  [        R                  " US
UR$                   35      n[        R                  " USUUS9$ [        R                  " USUS9$ U["        :X  a  [        R                  " USUS9$ [        R                  " USUS9$ )z5Return cell description based on phase and view mode.r   zbattleship-cell-ship-placed)coordr   zbattleship-cell-emptyri  zbattleship-cell-own-sunkzbattleship-cell-own-hitzbattleship-cell-own-misszbattleship-cell-own-shiprO  zbattleship-cell-sunkzbattleship-cell-hitzbattleship-cell-misszbattleship-cell-unknown)r)  _grid_cell_coordinater   r   r]   r   r   _ship_name_atr   r   rc   r   r   r^   CELL_HIT_find_ship_atrC   	CELL_MISSr7   )rA   r:   r;   r   r   r+  ri  cell	ship_nameopponentopponent_shotr   s               rB   get_cell_labelBattleshipGame.get_cell_labell  s    [[ **34SNN*c^^.CL||L::$<<$S)Dy  ..rD	#''1"	   ##'  >>><<$S)D$T.H&M ( 3 3C 8 =( ..rD	))"37DII'++2#&	  $''-"	  	)#''. 
 y  ..rD	#''."	   ##'  ==%c*Dx(2--hSAD		$0$4$4".t}}o>%	  ,//"2"'!*	   $'') 
 y #''* 
  ##) rE   c                    U R                  U5      nU(       d  gU R                  S:X  a  U R                  XBU5        gU R                  S:X  a  U R                  XBU5        gg)z%Handle cell selection based on phase.Nr   rV  )r)  r   _on_deploy_select_on_battle_selectrA   r   r:   r;   r+  s        rB   on_grid_selectBattleshipGame.on_grid_select  sS    [[ ::$""2C0ZZ:%""2C0 &rE   c                    U R                   S:w  a  gX R                  :  d  X0R                  :  a  gUR                  (       a  gU R	                  U5      nU(       d  gU R
                  S:X  a  UR                  (       a  gg g )Nr<  action-not-playingzaction-not-availableaction-spectatorr   zbattleship-deploy-complete)r=  r   r   is_spectatorr)  r   rb   ry  s        rB   is_grid_cell_enabled#BattleshipGame.is_grid_cell_enabled  sg     ;;)#'.. C>>$9)%[[ )::$3 rE   c                    U R                   S:w  a  [        R                  $ X R                  :  d  X0R                  :  a  [        R                  $ [        R
                  $ )Nr<  )r=  r   HIDDENr   r   VISIBLE)rA   r   r:   r;   s       rB   is_grid_cell_hidden"BattleshipGame.is_grid_cell_hidden  sG     ;;)#$$$.. C>>$9$$$!!!rE   c           	        UR                   (       a  gU R                  U5      nU(       d  gU R                  R                  UR                  S5      nU[        [        5      :  a  gX R                  UR                  '   X0R                  UR                  '   SU R                  UR                  '   [        U   u  pgU R                  X#5      nUR                  SS[        R                  " UR                  SU 35      U[        U5      S9  SU R                  UR                  '   [        R                  " UR                  S	5      n	[        R                  " UR                  S
5      n
[        R                  " UR                  S5      n[!        U	SS9[!        U
SS9[!        USS9/nUR#                  SUS[$        R&                  S9  g)z(Handle cell selection during deployment.Nr   Tzbattleship-choose-orientationr   rO  )r   ri  r9   orient_placementzbattleship-orient-horizontalzbattleship-orient-verticalcancelr1   )textr   r2   r4  r3  )multiletterescape_behavior)rb   r   r   r   r   rK  rJ  r   r   r   rk  rQ  r   r   r6   r5  r   	show_menur   SELECT_LAST)rA   r+  r:   r;   r   ship_idxrR  rS  ri  h_labelv_labelcancel_labelitemss                rB   rw   BattleshipGame._on_deploy_select  s    ??}}R **..ruua8s5z! #&"%26((/#Ho**34+!!$++1A(/LMY 	 	
 (:bee$""4;;0NO""4;;0LM#''X>'l3'j1,95

 	*66	 	 	
 	rE   c           
     x   U R                  U5      nU(       d  gU R                  R                  UR                  S5      nU[	        [
        5      :  a  gU R                  R                  UR                  S5      nU R                  R                  UR                  S5      n[
        U   u  px[        U R                  R                  5      n	[        UR                  XXbU	5      (       d  U R                  XV5      n
U(       a  SOSnUR                  SS[        R                  " UR                   SU 35      U
[        R                  " UR                   U5      S9  S	U R"                  UR                  '   U R%                  U5        g['        UUUUUS
9n[)        UR                  U5        UR*                  R-                  U5        U=R.                  S-  sl        S	U R"                  UR                  '   UR1                  [2        5        U R                  XV5      n
U(       a  SOSnUR                  SS[        R                  " UR                   SU 35      U
[        R                  " UR                   U5      S9  US-   nXR                  UR                  '   U[	        [
        5      :  aI  [
        U   u  pUR                  SS[        R                  " UR                   SU 35      [5        U5      S9  O>SUl        UR1                  [8        5        UR                  SS5        U R;                  5         U R%                  U5        g)z<Try to place ship at stored position with given orientation.Nr   zbattleship-horizontalzbattleship-verticalzbattleship-cannot-placer   rO  )r   ri  orientationFr   r    zbattleship-ship-placedzbattleship-place-next-shiprP  Tzbattleship-deploy-done)r   r   r   r   rK  rJ  r   r   r8   r   rr   r   r]   rk  rQ  r   r   r   r  r4   r   r`   rH   ra   
play_soundSOUND_PLACEr6   rb   SOUND_DEPLOY_DONE_check_all_deployed)rA   r+  r1   r   r  r:   r;   rR  rS  r9   ri  orientation_keyr   next_idxnext_key	next_sizes                   rB   r7  BattleshipGame._try_place_ship@  s    }}R **..ruua8s5z!""255!,""255!,#Ho4<<))*r||YSdSS..s8E9C5I^OLL)!%%dkk5EhZ3PQ(,,T[[/J   7<D,,RUU3$$R( !
 	R\\40

127((/$**345?1EZ$!!$++1A(/LM$((oF 	 	
 a<)1&c%j "'/HLL,!%%dkk5EhZ3PQ^	   #BOOO-.LL16:$$&  $rE   c                    U R                  5        H.  nU R                  U5      nU(       a  UR                  (       a  M.    g   SU l        g)z-Check if all players have finished deploying.N(   )r   r)  rb   r   ra  s      rB   r  "BattleshipGame._check_all_deployed  s;    --/FV$BR___ 0
 "$rE   c                n   U R                   S:  a  gU R                  U:w  a  gUR                  (       a+  U R                  U5      nU(       a  UR	                  SS5        gUR
                  U   U   [        :w  a+  U R                  U5      nU(       a  UR	                  SS5        gU R                  XU5        g)z)Handle firing a shot during battle phase.r   Nzbattleship-switch-to-shotsr   zbattleship-already-shot)r   current_playerrc   r   rQ  r^   r   
_fire_shot)rA   r+  r:   r;   r   s        rB   rx   BattleshipGame._on_battle_select  s     ""Q&"$>>==$D96B ==c"j0==$D6?%rE   c                    [        X5      nU(       d  gU=R                  S-  sl        U R                  [        5        UR                  U l        X l        X0l        [        U l	        g)zBInitiate a shot: play fire sound and queue the result after delay.Nr    )
r   rd   r  
SOUND_FIREr   r   r   r   FIRE_DELAY_TICKSr   )rA   r+  r:   r;   rr  s        rB   r  BattleshipGame._fire_shot  sP     !*
!
# ')ee# # #"2rE   c           	     v   U R                  U R                  U R                  5      5      nU(       d  gU R                  nU R                  n[        X5      nU(       d  gU R                  X#5      nUR                  U   U   [        :X  Ga1  [        UR                  U   U'   U=R                  S-  sl        U R                  XBU5      nU(       a  U=R                  S-  sl        U R                  [        5        U(       GaJ  UR                   (       Ga8  U R#                  [$        R&                  " [(        5      SS9  U R*                   H  nU R-                  U5      nU(       d  M  [.        R0                  " UR2                  SUR4                   35      n	UR6                  UR6                  :X  a  UR9                  SSU	S9  Mx  UR6                  UR6                  :X  a  UR9                  S	SUR:                  U	S
9  M  UR9                  SSUR:                  UR:                  U	S9  M     U R=                  U5      (       a  U R?                  U5        gOU RA                  UUSSSUS9  U RC                  5         U RD                  RF                  (       a1  U RI                  5         U RK                  5         U RM                  5         gO?[N        UR                  U   U'   U R                  [P        5        U RA                  UUSSSUS9  U RC                  5         U RS                  5         U RI                  5         U RK                  5         g)z8Resolve a pending shot after the fire delay has elapsed.Nr    r	   )delay_ticksrO  zbattleship-sunk-selfr   )r   zbattleship-sunk-target)r   r   zbattleship-sunk-spectator)r   targetr   zbattleship-hit-selfzbattleship-hit-targetzbattleship-hit-spectatorrj  zbattleship-miss-selfzbattleship-miss-targetzbattleship-miss-spectator)*r)  get_player_by_idr   r   r   r   rk  r]   r   rm  r^   re   rn  r=   r  	SOUND_HITrC   schedule_soundr   r   
SOUND_SUNKr   r   r   r   r   r7   r   rQ  r   _all_ships_sunk_handle_victory_speak_perspectivestop_turn_timerr   rv   r_  r`  r%  ro  
SOUND_MISSadvance_turn)
rA   r+  r:   r;   rr  ri  hit_shipr   urq  s
             rB   _resolve_shotBattleshipGame._resolve_shot  s   [[!!$"="=>
 #### ***34c"3'94&.BMM#s#MMQM ))(=H"OOI&HMMM##FMM*$=1#MAa(A  , 0 0*8+<+<*=>!I ttruu}		"8&y	Q,		4"#%77!*	 "  		7"#%77#+==!* " % &6 ''11((, 2 '')+. (    " ||))'')!&&(	 * '0BMM#s#OOJ'##&(+ $  	!rE   c                \    UR                    H  nX#4UR                  5       ;   d  M  Us  $    g)z'Find the ship occupying the given cell.N)r`   rK   )rA   r   r:   r;   r   s        rB   rn  BattleshipGame._find_ship_at,  s,     LLDzTZZ\) ! rE   c                :    [        S UR                   5       5      $ )Nc              3  8   #    U  H  oR                   v   M     g 7fr?   rC   ).0r   s     rB   	<genexpr>1BattleshipGame._all_ships_sunk.<locals>.<genexpr>9  s     699s   )allr`   rA   r   s     rB   r  BattleshipGame._all_ships_sunk8  s    6666rE   c                l   [        X5      nU(       a  UR                  OSnU R                   H  nU R                  U5      nU(       d  M  UR                  UR                  :X  a)  UR                  SS5        UR                  [        5        M`  U(       aL  UR                  UR                  :X  a2  UR                  SSUR                  S9  UR                  [        5        M  UR                  SSUR                  US9  UR                  [        5        M     U R                  5         U R                  5         g)	z8Handle game over when a player sinks all opponent ships.r   zbattleship-victory-selfr   zbattleship-victory-targetr   zbattleship-victory-spectatorr   r  N)r   r   r   r   r   rQ  r  	SOUND_WIN
SOUND_LOSEr  finish_game)rA   winnerloser
loser_namer   r  s         rB   r  BattleshipGame._handle_victory;  s    d+#(UZZb
Aa Attvyy 		3V<Y'144588+		/!;;  
 Z(		2!;;%	   Z(+ . 	rE   c                ~   U R                   nU(       d  gU R                  U5      nU(       d  gSUl        U R                  U5      nU(       aQ  Uu  pEU R	                  U5      nU(       a"  U R                  XE5      nUR                  SSUS9  U R                  X$U5        gU R                  5         U R                  5         g)z4Auto-fire at a random valid cell when timer expires.NFzbattleship-timeout-firer   rj  )
r  r)  rc   _random_valid_targetr   rk  rQ  r  r  r_  )rA   currentr+  r  r:   r;   r   ri  s           rB   _on_turn_timeoutBattleshipGame._on_turn_timeout^  s    %%[[!  **2.HC==$D223<6eLOOBS)##%rE   c                "   [        U R                  R                  5      n[        U5       VVs/ s H4  n[        U5        H!  oAR                  U   U   [
        :X  d  M  X44PM#     M6     nnnU(       a  [        R                  " U5      $ S$ s  snnf )zPick a random un-shot cell.N)r8   r   rr   rG   r^   r   r   r   )rA   r+  r9   r   r   
candidatess         rB   r  #BattleshipGame._random_valid_targetw  sz    
 4<<))*!$K
'qtAa@PQR@SWa@aFQFFK 	 
 -7v}}Z(@D@
s   ,BBc                D   [        U R                  R                  5      n[        U5      Ul        [        UR                  U[        5      Ul        [        [        5      Ul	        SUl
        [        [        5      U R                  UR                  '   U R                  5         g)z&Auto-place all ships for a bot player.TN)r8   r   rr   r   r]   r   rJ  r`   rK  ra   rb   r   r   r  )rA   r+  r9   s      rB   _bot_auto_deployBattleshipGame._bot_auto_deploy  sl    4<<))*"4(&r||T5Ae*),U&  "rE   c                   U R                  U5      nU(       d  g UR                  (       + Ul        U R                  U5      nU(       a  UR                  (       a  UR                  SS5        OUR                  SS5        U R	                  U5      nU R                  UR                  UR                  X4R                  5      nUR                  USS9  U R                  U5        g )Nzbattleship-view-ownr   zbattleship-view-shotsrW  rX  )r)  rc   r   rQ  _get_cursorrt  r:   r;   r   speakr"  )rA   r   	action_idr+  r   cursorrm   s          rB   r   "BattleshipGame._action_toggle_view  s    
 [[ ^^+}}V$~~2F;4f=%%b)F''

FJJKKPEJJuWJ-#rE   c                l    U R                   S:w  a  gUR                  (       a  gU R                  S:X  a  gg Nr<  r}  r~  r   zbattleship-deploy-in-progressr=  r  r   r  s     rB   r   &BattleshipGame._is_toggle_view_enabled  /    ;;)#'%::$2rE   c                6   U R                   S:w  d  UR                  (       a  [        R                  $ U R                  S:X  a  [        R                  $ U R                  U5      nU(       a!  [        USS5      S:X  a  [        R                  $ [        R                  $ Nr<  r   r  r   r  )r=  r  r   r  r   r   r
  r  rA   r   r   s      rB   r   %BattleshipGame._is_toggle_view_hidden  ss    ;;)#v':':$$$::$$$$}}V$GD-4=%%%   rE   c           	        U R                  U5      nU(       d  g U R                  U5      nU(       d  g [        R                  " UR                  S5      /nUR
                   H  n[        R                  " UR                  SUR                   35      nUR                  (       a"  [        R                  " UR                  S5      nOyUR                  S:  aH  [        R                  " UR                  S[        UR                  5      [        UR                  5      S9nO![        R                  " UR                  S5      nUR                  U SU 35        M     U R                  X55        g )	Nzbattleship-fleet-headerrO  zbattleship-status-sunkr   zbattleship-status-damagedr@   zbattleship-status-intactz: )r)  r   r   r   r   r`   r7   rC   r=   r6   r9   rH   
status_box)	rA   r   r  r+  r   linesr   rq  r=  s	            rB   r   !BattleshipGame._action_read_fleet  s   
 [[ }}V$!!$++/HIJHHD$((8H6XYIyy%))$++7OPQ%))KK/TYYTYY	 &))$++7QRLLI;b12  	"rE   c                J    U R                   S:w  a  gUR                  (       a  gg )Nr<  r}  r~  )r=  r  r  s     rB   r   %BattleshipGame._is_read_fleet_enabled  s     ;;)#'%rE   c                    U R                   S:w  d  UR                  (       a  [        R                  $ U R	                  U5      nU(       a!  [        USS5      S:X  a  [        R                  $ [        R                  $ )Nr<  r  r   r  )r=  r  r   r  r   r
  r  r  s      rB   r   $BattleshipGame._is_read_fleet_hidden  s[    ;;)#v':':$$$}}V$GD-4=%%%   rE   c                T   U R                  U5      nU R                  U5      nU(       d  g S nU(       a  [        X5      nO$U R                  5       n[	        U5      S:  a  US   nU(       d  g [
        R                  " UR                  S5      /n[        S UR                   5       5      n[	        UR                  5      n	UR                  [
        R                  " UR                  S[        U5      [        U	5      S95        UR                   H  n
U
R                  (       d  M  [
        R                  " UR                  SU
R                   35      nUR                  [
        R                  " UR                  SU[        U
R                  5      S	95        M     U R                  X5        g )
Nr	   r    zbattleship-enemy-fleet-headerc              3  J   #    U  H  oR                   (       d  M  S v   M     g7fr    Nr  r  ss     rB   r  :BattleshipGame._action_read_enemy_fleet.<locals>.<genexpr>  s     =NqffN   #	#zbattleship-enemy-fleet-summary)rC   totalrO  zbattleship-enemy-ship-sunkrP  )r)  r   r   r   rK  r   r   r   sumr`   rH   r6   rC   r7   r9   r  )rA   r   r  r+  r   rr  activer  
sunk_countr  r   rq  s               rB   r   'BattleshipGame._action_read_enemy_fleet  sS   
 [[ }}V$ $T.H ,,.F6{a!!9!!$++/NOP=HNN==
HNN#0_%j		
 NNDyyy(,,KK&t}}o6	  $$4& ^	 # 	&rE   c                l    U R                   S:w  a  gUR                  (       a  gU R                  S:X  a  gg r  r  r  s     rB   r   +BattleshipGame._is_read_enemy_fleet_enabled  r  rE   c                6   U R                   S:w  d  U R                  S:X  a  [        R                  $ UR                  (       a  [        R                  $ U R                  U5      nU(       a!  [        USS5      S:X  a  [        R                  $ [        R                  $ r  )r=  r   r   r  r  r   r
  r  r  s      rB   r   *BattleshipGame._is_read_enemy_fleet_hidden&  ss    ;;)#tzz['@$$$$$$}}V$GD-4=%%%   rE   c                   > U R                  U5      nU(       a!  [        USS5      S:X  a  [        R                  $ [        TU ]  U5      $ )Nr  r   r  )r   r
  r   r  r   _is_whos_at_table_hiddenrA   r   r   r   s      rB   r  'BattleshipGame._is_whos_at_table_hidden4  s@    }}V$GD-4=%%%w/77rE   c                   > U R                  U5      nU(       a1  [        USS5      S:X  a   U R                  S:X  a  [        R                  $ [
        TU ]  U5      $ )Nr  r   r  r<  )r   r
  r=  r   r  r   _is_whose_turn_hiddenr  s      rB   r  $BattleshipGame._is_whose_turn_hidden:  sL    }}V$GD-4=$++QZBZ%%%w,V44rE   c                  > [         TU ]  5         U R                  5         U R                  (       d  g U R                  S:  a6  U =R                  S-  sl        U R                  S:X  a  U R                  5         g U R                  S:X  ai  U R                  5        HT  nU R                  U5      nU(       d  M  UR                  (       d  M0  UR                  (       a  MC  U R                  U5        MV     g U R                  S:  a6  U =R                  S-  sl        U R                  S:X  a  U R                  5         g U R                  S:X  a  U R                  5         [        R                  " U 5        g )Nr   r    r   rV  )r   on_tickprocess_scheduled_soundsr?  r   rL  r   r   r)  r   rb   r  r   r  on_tick_turn_timerr   )rA   r   r+  r   s      rB   r  BattleshipGame.on_tickD  s"   %%' !!A%""a'"%%*""$ ::$113[[(2")))BOOO))"- 4  ""Q&##q(#&&!+""$ ::###% 	$rE   c                    [        X5      $ r?   )
_bot_thinkr  s     rB   r!   BattleshipGame.bot_thinkl  s    $''rE   c                b   U R                  5       nS nU HK  nU R                  U5      nU(       d  M  [        X5      nU(       d  M1  U R                  U5      (       d  MI  Un  O   U(       a  UR                  /O/ nUU(       a  UR
                  OS S.nU H~  nU R                  U5      nU(       d  M  UR                  XtR
                   S3'   UR                  XtR
                   S3'   [        S UR                   5       5      XtR
                   S3'   M     [        U R                  5       [        R                  " 5       R                  5       U R                  U Vs/ s HD  n[!        UR                  UR
                  UR"                  =(       a    UR$                  (       + S9PMF     snUS9$ s  snf )N)
winner_idswinner_name_shots_hitsc              3  J   #    U  H  oR                   (       d  M  S v   M     g7fr  r  r  s     rB   r  3BattleshipGame.build_game_result.<locals>.<genexpr>  s     5TAVVaar  _ships_lost)r   player_namer   )	game_type	timestampduration_ticksplayer_resultscustom_data)r   r)  r   r  r   r   rd   re   r  r`   r   r   r   now	isoformatsound_scheduler_tickr   r   replaced_human)rA   r  r  r   r+  rr  r  customs           rB   build_game_result BattleshipGame.build_game_results  sr   ((*AQBr(28 4 4X > >F  %+fii[
$*06;;d

 AQBr-/^^''&)*,.MM''%()255T5T2T''+./  mmolln..044    A dd !88<A,<,<(<
   
 	
s   AF,c                   / nUR                   R                  S5      nU(       a%  UR                  [        R                  " USUS95        UR                   H  nUR                   R                  UR
                   S3S5      nUR                   R                  UR
                   S3S5      nUS:  a  Xv-  S-  OSnUR                  [        R                  " USUR
                  [        U5      [        U5      US	 S
95        M     U$ )Nr  zbattleship-winner-liner  r  r   r  d   zbattleship-stats-linez.0f)r   shotsr=   accuracy)r  r   rH   r   r  r  r6   )	rA   rI   r   r  r  prr)  r=   r*  s	            rB   format_end_screen BattleshipGame.format_end_screen  s    
 ((,,];LL  ,& ''B&&**bnn-=V+DaHE%%))R^^,<E*BAFD/4qys*aHLL  +>>e*T (~		 ( rE   c                2    [        U[        5      (       a  U$ g r?   )
isinstancerX   r  s     rB   r)  BattleshipGame._as_bp  s    f.//MrE   c                    U R                  5        H@  nUR                  (       d  M  [        R                  " U[        R
                  " SS5      S9  MB     g)z,Add a 2-5 second thinking delay to all bots.r  r(  )ticksN)r   r   r   jolt_botr   r   r  s     rB   r`  BattleshipGame._jolt_bots  s9    --/F}}}""6C1HI 0rE   c                   U R                    H  nU R                  U5      nU(       d  M  UR                  UR                  :X  a  UR                  " US40 UD6  MM  UR                  UR                  :X  a-  UR                  " US4UR                  UR                  S.UD6  M  UR                  " US4UR                  UR                  S.UD6  M     g)z9Send a personalized TTS message to each player/spectator.r   r  N)r   r   r   rQ  r   )	rA   shooterrr  key_self
key_targetkey_spectatorkwargsr   r  s	            rB   r  !BattleshipGame._speak_perspective  s     Aa Attwzz!		(F5f5$		 #<<#==	
  		! #<<#==	
  rE   c                    U R                  XU5      nU(       a$  [        R                  " USUR                   35      $ [        R                  " US5      $ )z5Get the localized name of the ship at the given cell.rO  zbattleship-ship-unknown)rn  r   r   r7   )rA   r+  r:   r;   r   r   s         rB   rl  BattleshipGame._ship_name_at  sL     !!"3/##F.>t}}o,NOO(ABBrE   )
r   r?  r   r   r   r   r   r   r   r=  )rN   r6   )rN   r8   )rN   r   )F)r   r6   r   r6   r   r<   rN   rX   )rN   zlist[str | tuple[str, dict]])r   rX   rN   r   )r   r   rN   r   )r   r   r   z'User | None'rN   None)rN   r>  )r   r   rN   r>  r?   )r   r   r!  
str | NonerN   r>  )r   r   r9  dictrN   r>  )
r:   r8   r;   r8   r   'Player'r   r6   rN   r6   )r   rA  r:   r8   r;   r8   rN   r>  )r   rA  r:   r8   r;   r8   rN   r?  )r   rA  r:   r8   r;   r8   rN   r   )r+  rX   r:   r8   r;   r8   rN   r>  )r+  rX   r1   r<   rN   r>  )r   rX   r:   r8   r;   r8   rN   zShip | None)r   rX   rN   r<   )r  rX   rN   r>  )r+  rX   rN   ztuple[int, int] | None)r+  rX   rN   r>  )r   rA  r  r6   rN   r>  )r   rA  rN   r?  )r   rA  rN   r   )r   r   rN   r   )r   rX   rN   r?  )rN   r   )rI   r   r   r6   rN   r   )r   rA  rN   BattleshipPlayer | None)r6  rX   rr  rX   r7  r6   r8  r6   r9  r6   rN   r>  )
r+  rX   r:   r8   r;   r8   r   r6   rN   r6   )ZrO   rP   rQ   rR   r   rf   r   rT   rh   r   r   r   r@  r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   classmethodr   r   r   r   r   r   r   r   r   r   r   r  r  r"  r%  r  r  r8  rG  rD  rE  rL  r_  rt  rz  r  r  rw  r7  r  rx  r  r  rn  r  r  r  r  r  r   r   r   r   r   r   r   r   r   r  r  r  r!   r%  r,  r)  r`  r  rl  rV   __classcell__)r   s   @rB   r   r     s&    ',D&AG#A!&7H!IGI IsIs*/*EL'E!&t!<OY<!&t!<OY< ".AE>A"'4' E3s */t)DD383NN"'"=K="'"=K= #%C$cc     $ $     2 2 	HH H 	H
 
H'R*0
4, $(FF !F 
	F F$O24+!Z
! $kk k 	k
 k 
kZ	1  	
 
2
"
" 
" 	
"
 

" 11 1 	1
 
1fK%K% K% 
	K%Z$&& & 	&
 
&433 3 	3
 
3(bH
 
 
 	

 

7F&2	A	A 
 	A#$$ $ 
	$*!## # 
	#8!0'0' 0' 
	0'd!85" P(%
N  
	F
J! # 	
   
BCC C 	C
 C 
C CrE   r   )r9   r8   r   r8   rN   r\   )r   r\   r9   r8   r:   r8   r;   r8   r1   r<   rr   r8   rN   r<   )r   r\   r   r4   rN   r>  )r   r\   rr   r8   r   zlist[tuple[str, int]]rN   r_   )r   z'BattleshipGame'r   rX   rN   rB  )NrS   
__future__r   dataclassesr   r   r   r   typingr   mashumaro.mixins.jsonr   baser
   r   r   registryr   game_utils.actionsr   r   r   game_utils.bot_helperr   game_utils.game_resultr   r   game_utils.grid_mixinr   r   game_utils.optionsr   r   r   game_utils.poker_timerr   game_utils.turn_timer_mixinr   messages.localizationr   server.core.ui.keybindsr   server.core.users.baser   r   botr!   r  r"   r  r  r  r  r  r  r  r  r\  r  r   r   ro  rm  rJ  r}   r~   r   r   ORIENTATION_CHOICESr4   rX   rh   r   r   r   r   r   r   rM   rE   rB   <module>rW     s0   # (     4 , , $ ? ? . > > F F 4 9 1 0 ; (+ (
'
%	
 *5 "	 
'   
			 + 		
!
!	  X& '+ 
 $Z0    2 v   2 2 2t (2 0
 
 
	
   
&  
  
  ! 	D
   
aC]ND aC  aCrE   