1+ import { Player } from './Player.js' ;
2+ import {
3+ FLEET ,
4+ renderBoard ,
5+ renderTracker ,
6+ renderSetupBoard ,
7+ renderFleet ,
8+ setStatus ,
9+ setDragState ,
10+ } from './UI.js' ;
11+
12+ // ─── DOM References ───────────────────────────────────────────────────────────
13+ const setupPanel = document . getElementById ( 'setup-panel' ) ;
14+ const gameArea = document . getElementById ( 'game-area' ) ;
15+ const statusText = document . getElementById ( 'status-text' ) ;
16+
17+ const setupBoardEl = document . getElementById ( 'setup-board' ) ;
18+ const fleetEl = document . getElementById ( 'fleet' ) ;
19+ const rotateBtn = document . getElementById ( 'btn-rotate' ) ;
20+ const randomBtn = document . getElementById ( 'btn-random' ) ;
21+ const startBtn = document . getElementById ( 'btn-start' ) ;
22+
23+ const playerBoardEl = document . getElementById ( 'player-board' ) ;
24+ const enemyBoardEl = document . getElementById ( 'enemy-board' ) ;
25+ const playerTracker = document . getElementById ( 'player-tracker' ) ;
26+ const enemyTracker = document . getElementById ( 'enemy-tracker' ) ;
27+ const restartBtn = document . getElementById ( 'btn-restart' ) ;
28+
29+ // ─── State ────────────────────────────────────────────────────────────────────
30+ let human , computer ;
31+ let isVertical = false ;
32+ let remainingFleet = [ ] ;
33+ let gameActive = false ;
34+
35+ // ─── Setup ────────────────────────────────────────────────────────────────────
36+ function initSetup ( ) {
37+ human = new Player ( 'human' ) ;
38+ computer = new Player ( 'computer' ) ;
39+ isVertical = false ;
40+ remainingFleet = [ ...FLEET ] ;
41+ gameActive = false ;
42+
43+ rotateBtn . textContent = '↔ Horizontal' ;
44+ setupPanel . classList . remove ( 'hidden' ) ;
45+ gameArea . classList . add ( 'hidden' ) ;
46+
47+ setStatus ( statusText , 'Colocá tus barcos arrastrándolos al tablero' ) ;
48+ refreshSetup ( ) ;
49+ computer . placeShipsRandomly ( FLEET . map ( ( [ l ] ) => l ) ) ;
50+ }
51+
52+ function refreshSetup ( ) {
53+ renderSetupBoard ( setupBoardEl , human . gameboard , ( row , col , length , vertical ) => {
54+ const placed = human . gameboard . placeShip ( row , col , length , vertical ) ;
55+ if ( placed ) {
56+ const idx = remainingFleet . findIndex ( ( [ l ] ) => l === length ) ;
57+ if ( idx !== - 1 ) remainingFleet . splice ( idx , 1 ) ;
58+ refreshSetup ( ) ;
59+ }
60+ } ) ;
61+
62+ renderFleet ( fleetEl , remainingFleet , ( length , name ) => {
63+ setStatus ( statusText , `Arrastrando: ${ name } (${ length } casillas)` ) ;
64+ } , isVertical ) ;
65+
66+ const allPlaced = remainingFleet . length === 0 ;
67+ startBtn . disabled = ! allPlaced ;
68+ startBtn . style . opacity = allPlaced ? '1' : '0.5' ;
69+
70+ if ( allPlaced ) {
71+ setStatus ( statusText , '¡Todo listo! Presioná "Iniciar Batalla"' ) ;
72+ }
73+ }
74+
75+ // Rotate: toggle isVertical y re-renderizar la flota
76+ rotateBtn . addEventListener ( 'click' , ( ) => {
77+ isVertical = ! isVertical ;
78+ rotateBtn . textContent = isVertical ? '↕ Vertical' : '↔ Horizontal' ;
79+ refreshSetup ( ) ;
80+ } ) ;
81+
82+ randomBtn . addEventListener ( 'click' , ( ) => {
83+ human . placeShipsRandomly ( FLEET . map ( ( [ l ] ) => l ) ) ;
84+ remainingFleet = [ ] ;
85+ refreshSetup ( ) ;
86+ } ) ;
87+
88+ startBtn . addEventListener ( 'click' , ( ) => {
89+ if ( remainingFleet . length > 0 ) return ;
90+ startGame ( ) ;
91+ } ) ;
92+
93+ // ─── Game ─────────────────────────────────────────────────────────────────────
94+ function startGame ( ) {
95+ setupPanel . classList . add ( 'hidden' ) ;
96+ gameArea . classList . remove ( 'hidden' ) ;
97+ gameActive = true ;
98+ setStatus ( statusText , '¡Tu turno! Atacá el tablero enemigo' ) ;
99+ refreshGame ( ) ;
100+ }
101+
102+ function refreshGame ( ) {
103+ renderBoard ( playerBoardEl , human . gameboard , { isEnemy : false } ) ;
104+ renderBoard ( enemyBoardEl , computer . gameboard , {
105+ isEnemy : true ,
106+ onAttack : handlePlayerAttack ,
107+ } ) ;
108+ renderTracker ( playerTracker , human . gameboard . ships ) ;
109+ renderTracker ( enemyTracker , computer . gameboard . ships ) ;
110+ }
111+
112+ function handlePlayerAttack ( row , col ) {
113+ if ( ! gameActive ) return ;
114+ if ( computer . gameboard . isAttacked ( row , col ) ) return ;
115+
116+ computer . gameboard . receiveAttack ( row , col ) ;
117+
118+ if ( computer . gameboard . allSunk ( ) ) {
119+ gameActive = false ;
120+ refreshGame ( ) ;
121+ setStatus ( statusText , '🎉 ¡Ganaste! Hundiste toda la flota enemiga' ) ;
122+ return ;
123+ }
124+
125+ const hitShip = computer . gameboard . grid [ row ] [ col ] ?. ship ;
126+ if ( hitShip ?. isSunk ( ) ) {
127+ setStatus ( statusText , '💥 ¡Hundiste un barco enemigo! Tu turno de nuevo' ) ;
128+ } else if ( computer . gameboard . isHit ( row , col ) ) {
129+ setStatus ( statusText , '🔥 ¡Impacto! Seguí atacando' ) ;
130+ } else {
131+ setStatus ( statusText , '💧 Agua... turno del enemigo' ) ;
132+ }
133+
134+ refreshGame ( ) ;
135+ setTimeout ( computerTurn , 750 ) ;
136+ }
137+
138+ function computerTurn ( ) {
139+ if ( ! gameActive ) return ;
140+
141+ const move = computer . makeComputerMove ( human . gameboard ) ;
142+ if ( ! move ) return ;
143+
144+ const [ row , col ] = move ;
145+
146+ if ( human . gameboard . allSunk ( ) ) {
147+ gameActive = false ;
148+ refreshGame ( ) ;
149+ setStatus ( statusText , '💀 ¡Perdiste! El enemigo hundió toda tu flota' ) ;
150+ return ;
151+ }
152+
153+ const hitShip = human . gameboard . grid [ row ] [ col ] ?. ship ;
154+ if ( hitShip ?. isSunk ( ) ) {
155+ setStatus ( statusText , '😱 ¡El enemigo hundió uno de tus barcos! Tu turno' ) ;
156+ } else if ( human . gameboard . isHit ( row , col ) ) {
157+ setStatus ( statusText , '😬 ¡Te impactaron! Tu turno' ) ;
158+ } else {
159+ setStatus ( statusText , '😮💨 El enemigo falló. ¡Tu turno!' ) ;
160+ }
161+
162+ refreshGame ( ) ;
163+ }
164+
165+ restartBtn . addEventListener ( 'click' , initSetup ) ;
166+
167+ // ─── Boot ─────────────────────────────────────────────────────────────────────
168+ initSetup ( ) ;
0 commit comments