const express = require('express'); const cors = require('cors'); const mysql = require('mysql2/promise'); const app = express(); app.use(cors()); app.use(express.json()); (async () => { console.log("Initializing database connection..."); try { const pool = await mysql.createPool({ host: process.env.DB_HOST || 'localhost', user: process.env.DB_USER || 'root', password: process.env.DB_PASSWORD || 'somepassword', database: process.env.DB_NAME || 'battleship', waitForConnections: true, connectionLimit: 10, queueLimit: 0 }); console.log("Successfully connected to MySQL!"); const conn = await pool.getConnection(); const [rows] = await conn.query("SELECT VERSION() AS mysql_version"); console.log(`MySQL Version: ${rows[0].mysql_version}`); conn.release(); console.log("Checking or creating tables..."); await pool.execute(` CREATE TABLE IF NOT EXISTS games ( id INT AUTO_INCREMENT PRIMARY KEY, player1 VARCHAR(255), player2 VARCHAR(255), player1_ships JSON, player2_ships JSON, current_turn INT DEFAULT 1, game_state JSON NOT NULL ) `); console.log("Table 'games' is ready!"); await pool.execute(` CREATE TABLE IF NOT EXISTS game_results ( id INT AUTO_INCREMENT PRIMARY KEY, game_id INT, winner VARCHAR(255), loser VARCHAR(255), moves INT ) `); console.log("Table 'game_results' is ready!"); app.get('/api/results', async (req, res) => { try { const [results] = await pool.execute('SELECT * FROM game_results ORDER BY id DESC'); res.json({ results }); } catch (err) { console.error("Error fetching results:", err); res.status(500).json({ error: "Database error" }); } }); app.post('/api/new-game', async (req, res) => { const { player1, player2 } = req.body; if (!player1 || !player2) { console.warn("Missing player names in request."); return res.status(400).json({ error: 'Player names required' }); } const gameState = { boardSize: 5, hits: [], misses: [], gameOver: false }; try { console.log(`Creating new game for ${player1} vs ${player2}...`); const [result] = await pool.execute( 'INSERT INTO games (player1, player2, game_state) VALUES (?, ?, ?)', [player1, player2, JSON.stringify(gameState)] ); console.log(`Game created with ID: ${result.insertId}`); res.json({ gameId: result.insertId, message: 'Game created' }); } catch (err) { console.error('Error creating game:', err); res.status(500).json({ error: 'Database error' }); } }); app.post('/api/place-ships', async (req, res) => { const { gameId, player, ships } = req.body; if (!gameId || !player || !ships) { console.warn("Missing parameters for placing ships."); return res.status(400).json({ error: 'Missing parameters' }); } try { console.log(`Placing ships for player ${player} in game ID: ${gameId}...`); const [rows] = await pool.execute('SELECT * FROM games WHERE id = ?', [gameId]); if (rows.length === 0) { console.warn(`Game with ID ${gameId} not found.`); return res.status(404).json({ error: 'Game not found' }); } let updateField = player === 1 ? 'player1_ships' : 'player2_ships'; await pool.execute(`UPDATE games SET ${updateField} = ? WHERE id = ?`, [JSON.stringify(ships), gameId]); console.log(`Ships placed for player ${player} in game ID: ${gameId}`); res.json({ message: `Ships placed for player ${player}` }); } catch (err) { console.error('Error placing ships:', err); res.status(500).json({ error: 'Database error' }); } }); // 🎯 Атака app.post('/api/attack', async (req, res) => { const { gameId, row, col, player } = req.body; if (!gameId || typeof row === 'undefined' || typeof col === 'undefined' || !player) { console.warn("Missing attack parameters in request."); return res.status(400).json({ error: 'Missing parameters' }); } try { console.log(`Player ${player} attacks (${row}, ${col}) in game ID: ${gameId}`); const [rows] = await pool.execute('SELECT * FROM games WHERE id = ?', [gameId]); if (rows.length === 0) { console.warn(`Game with ID ${gameId} not found.`); return res.status(404).json({ error: 'Game not found' }); } let game = rows[0]; let state = JSON.parse(game.game_state); let opponentShips = player === 1 ? JSON.parse(game.player2_ships || "[]") : JSON.parse(game.player1_ships || "[]"); const hit = opponentShips.some(ship => ship.row === row && ship.col === col); if (hit) { console.log(`HIT! Player ${player} hit an opponent's ship at (${row}, ${col})`); state.hits.push({ row, col }); if (state.hits.length === opponentShips.length) { state.gameOver = true; console.log(`Player ${player} has won the game!`); } } else { console.log(`MISS! Player ${player} attacked (${row}, ${col}) but missed.`); state.misses.push({ row, col }); } state.current_turn = player === 1 ? 2 : 1; await pool.execute('UPDATE games SET game_state = ? WHERE id = ?', [JSON.stringify(state), gameId]); res.json({ hit, state }); } catch (err) { console.error("Attack error:", err); res.status(500).json({ error: 'Database error' }); } }); app.post('/api/save-result', async (req, res) => { const { gameId, winner, loser, moves } = req.body; if (!gameId || !winner || !loser || !moves) { console.warn("Missing game result parameters."); return res.status(400).json({ error: 'Missing parameters' }); } try { console.log(`Saving result: Winner - ${winner}, Loser - ${loser}, Moves - ${moves}`); await pool.execute( `INSERT INTO game_results (game_id, winner, loser, moves) VALUES (?, ?, ?, ?)`, [gameId, winner, loser, moves] ); console.log(`Game result saved for game ID ${gameId}`); res.json({ message: "Game result saved" }); } catch (err) { console.error("Error saving game result:", err); res.status(500).json({ error: "Database error" }); } }); const port = 4000; app.listen(port, () => { console.log(`Backend started on port ${port}`); }); } catch (err) { console.error("Database connection failed!", err); } })();