zkt25/z2/frontend/src/components/GameBoard.jsx
2025-04-03 11:57:59 +02:00

175 lines
5.5 KiB
JavaScript

import React, { useState, useEffect } from 'react';
import Board from './Board';
import './GameBoard.css';
function checkSunkShip(ships, hits) {
const sunkShipsArrays = ships.filter((ship) =>
ship.every((cell) =>
hits.some((hit) => hit.row === cell.row && hit.col === cell.col)
)
);
sunkShipsArrays.forEach((ship) => {
const size = ship.length;
if (size === 4) {
console.log('Battleship (4 cells) is sunk!');
} else if (size === 3) {
console.log('Cruiser (3 cells) is sunk!');
} else if (size === 2) {
console.log('Destroyer (2 cells) is sunk!');
} else if (size === 1) {
console.log('Submarine (1 cell) is sunk!');
}
});
return sunkShipsArrays.flat();
}
function GameBoard({ gameId, player1Name, player2Name, player1Ships, player2Ships, onNewGame }) {
const [currentPlayer, setCurrentPlayer] = useState(1);
const [hitsP1, setHitsP1] = useState([]);
const [missesP1, setMissesP1] = useState([]);
const [hitsP2, setHitsP2] = useState([]);
const [missesP2, setMissesP2] = useState([]);
const [sunkShipsP1, setSunkShipsP1] = useState([]);
const [sunkShipsP2, setSunkShipsP2] = useState([]);
const [winner, setWinner] = useState(null);
useEffect(() => {
console.log('player1Ships:', JSON.stringify(player1Ships, null, 2));
console.log('player2Ships:', JSON.stringify(player2Ships, null, 2));
}, []);
const saveGameResult = async (winnerName, loserName) => {
try {
const resp = await fetch('http://localhost:30000/api/save-result', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
gameId,
winner: winnerName,
loser: loserName,
moves: hitsP1.length + hitsP2.length
})
});
const data = await resp.json();
console.log('Game result saved:', data);
} catch (err) {
console.error('Error saving game result:', err);
}
};
useEffect(() => {
const totalCellsP1 = player1Ships.flat().length;
const totalCellsP2 = player2Ships.flat().length;
if (hitsP1.length === totalCellsP2) {
setWinner(player1Name);
saveGameResult(player1Name, player2Name);
} else if (hitsP2.length === totalCellsP1) {
setWinner(player2Name);
saveGameResult(player2Name, player1Name);
}
}, [hitsP1, hitsP2, player1Ships, player2Ships, player1Name, player2Name]);
useEffect(() => {
const sunkForP1 = checkSunkShip(player1Ships, hitsP2);
const sunkForP2 = checkSunkShip(player2Ships, hitsP1);
setSunkShipsP1(sunkForP1);
setSunkShipsP2(sunkForP2);
}, [hitsP1, hitsP2, player1Ships, player2Ships]);
const handleAttack = (row, col, opponent) => {
if (winner) return;
let alreadyAttacked;
if (opponent === 2) {
alreadyAttacked = [...hitsP1, ...missesP1].some(
(cell) => cell.row === row && cell.col === col
);
} else {
alreadyAttacked = [...hitsP2, ...missesP2].some(
(cell) => cell.row === row && cell.col === col
);
}
if (alreadyAttacked) {
alert('You have already attacked this cell!');
return;
}
let isHit = false;
if (opponent === 2) {
isHit = player2Ships.flat().some((cell) => cell.row === row && cell.col === col);
if (isHit) {
setHitsP1([...hitsP1, { row, col }]);
console.log(`Player1 hit a ship at [${row},${col}] on Player2's board`);
} else {
setMissesP1([...missesP1, { row, col }]);
console.log(`Player1 missed at [${row},${col}] on Player2's board`);
}
} else {
isHit = player1Ships.flat().some((cell) => cell.row === row && cell.col === col);
if (isHit) {
setHitsP2([...hitsP2, { row, col }]);
console.log(`Player2 hit a ship at [${row},${col}] on Player1's board`);
} else {
setMissesP2([...missesP2, { row, col }]);
console.log(`Player2 missed at [${row},${col}] on Player1's board`);
}
}
if (!isHit) {
setCurrentPlayer(currentPlayer === 1 ? 2 : 1);
}
};
return (
<div className="game-board">
{winner ? (
<div className="winner-section">
<h2>Winner: {winner}!</h2>
<button className="new-game-button" onClick={onNewGame}>Start New Game</button>
</div>
) : (
<h2 className="turn-title">Current turn: {currentPlayer === 1 ? player1Name : player2Name}</h2>
)}
<div className="boards-container">
<div className="board-wrapper">
<h3>{player1Name}'s Board</h3>
<Board
boardSize={10}
ships={player1Ships.flat()}
hits={hitsP2}
misses={missesP2}
sunkShips={sunkShipsP1}
onCellClick={
currentPlayer === 2 ? (r, c) => handleAttack(r, c, 1) : null
}
hideShips={true}
/>
</div>
<div className="board-wrapper">
<h3>{player2Name}'s Board</h3>
<Board
boardSize={10}
ships={player2Ships.flat()}
hits={hitsP1}
misses={missesP1}
sunkShips={sunkShipsP2}
onCellClick={
currentPlayer === 1 ? (r, c) => handleAttack(r, c, 2) : null
}
hideShips={true}
/>
</div>
</div>
</div>
);
}
export default GameBoard;