diff --git a/Game.js b/Game.js index 2556ba0..04402aa 100644 --- a/Game.js +++ b/Game.js @@ -58,6 +58,18 @@ class Game { } return w; } + + validBoards() { + this.room.players.forEach((player) => { + player.pieces.forEach((piece) => { + for (let i = piece.startPos.x; i <= piece.endPos.x; i++) { + for (let j = piece.startPos.y; j <= piece.endPos.y; j++) { + player.grid.cases[i][j].isShip = true; + } + } + }); + }); + } } module.exports = { diff --git a/app.js b/app.js index 1569c8b..33c4ab1 100644 --- a/app.js +++ b/app.js @@ -5,30 +5,43 @@ const { io } = require(`${__dirname}/index.js`); let room; let game; +let players = []; io.on("connection", (socket) => { + /* TODO : handle disconnection + socket.on("disconnect", (reason) => { + if (game.room.players.length === 2) { + game.endGame(); + delete game.room; + } + console.debug(game); + }); + */ + + socket.on("first connection", (socketId, callback) => { + let player = new Player(socketId); + players.push(player); + callback({ + player: player, + }); + }); + socket.on("Hello", (callback) => { callback({ Hello: "World", }); }); - socket.on("room creation", (socketId) => { - let player = new Player(socketId); - player.grid.cases[2][2].isShip = true; - player.grid.cases[3][2].isShip = true; + socket.on("room creation", (player) => { room = new Room(); room.addPlayer(player); }); - socket.on("ask for room", (socketId) => { - if (room.players.length === 1) { - let player = new Player(socketId); - player.grid.cases[2][2].isShip = true; - room.addPlayer(player); - game = new Game(room); - game.start(); - } + socket.on("ask for room", (player) => { + room.addPlayer(player); + game = new Game(room); + game.validBoards(); + game.start(); }); socket.on("play", (move) => { diff --git a/businesses/Case.js b/businesses/Case.js index 713a71f..dce4741 100644 --- a/businesses/Case.js +++ b/businesses/Case.js @@ -2,6 +2,7 @@ class Case { constructor() { this.isShip = false; this.isPlayed = false; + this.piece = ""; } } diff --git a/businesses/Piece.js b/businesses/Piece.js new file mode 100644 index 0000000..f48888e --- /dev/null +++ b/businesses/Piece.js @@ -0,0 +1,16 @@ +const uuid = require("uuid"); + +class Piece { + constructor(size, startPos, endPos) { + this.id = uuid.v4(); + this.size = size; + this.startPos = startPos; + this.endPos = endPos; + this.vertical = true; + this.isSelected = false; + } +} + +module.exports = { + Piece, +}; diff --git a/businesses/Player.js b/businesses/Player.js index 050e507..ff5cf30 100644 --- a/businesses/Player.js +++ b/businesses/Player.js @@ -1,11 +1,24 @@ const uuid = require("uuid"); const { Grid } = require("./Grid.js"); +const { Piece } = require("./Piece.js"); class Player { constructor(socketId) { this.id = uuid.v4(); this.socketId = socketId; this.grid = new Grid(); + this.pieces = []; + this.pieces.push(new Piece(1, { x: 0, y: 0 }, { x: 0, y: 0 })); + this.pieces.push(new Piece(2, { x: 2, y: 2 }, { x: 2, y: 3 })); + + this.pieces.forEach((piece) => { + for (let i = piece.startPos.x; i <= piece.endPos.x; i++) { + for (let j = piece.startPos.y; j <= piece.endPos.y; j++) { + this.grid.cases[i][j].isShip = true; + this.grid.cases[i][j].piece = piece; + } + } + }); } } diff --git a/public/assets/style.css b/public/assets/style.css index c57f4a3..ee38811 100644 --- a/public/assets/style.css +++ b/public/assets/style.css @@ -1,6 +1,7 @@ #game { display: flex; flex-direction: row; + gap: 10px; } .hidden-element { diff --git a/public/index.html b/public/index.html index 4f8590a..973baf8 100644 --- a/public/index.html +++ b/public/index.html @@ -18,11 +18,25 @@ -
- - +
+
+ +
+ +
+
+ + +

You have to play

Hit !

WIN !

diff --git a/public/scripts/game.js b/public/scripts/game.js index f10f9b4..ccc6d0e 100644 --- a/public/scripts/game.js +++ b/public/scripts/game.js @@ -7,10 +7,37 @@ const ennemyCanvas = document.getElementById("ennemy_board"); const ennemyCtx = ennemyCanvas.getContext("2d"); const CASE_SIZE = 30; +let selectedPiece = ""; export function drawGrid(player) { + ownCtx.clearRect(0, 0, ownCanvas.height, ownCanvas.width); + ownCtx.strokeStyle = "black"; + player.pieces.forEach((piece) => { + for (let i = piece.startPos.x; i <= piece.endPos.x; i++) { + for (let j = piece.startPos.y; j <= piece.endPos.y; j++) { + if (piece.isSelected) { + ownCtx.fillStyle = "#F88379"; + ownCtx.fillRect( + i * CASE_SIZE + 1, + j * CASE_SIZE + 1, + CASE_SIZE - 1, + CASE_SIZE - 1, + ); + } else { + ownCtx.fillStyle = "#A9A9A9"; + ownCtx.fillRect( + i * CASE_SIZE + 1, + j * CASE_SIZE + 1, + CASE_SIZE - 1, + CASE_SIZE - 1, + ); + } + } + } + }); + for (let i = 0; i < player.grid.cases.length; i++) { for (let j = 0; j < player.grid.cases.length; j++) { ownCtx.strokeRect( @@ -20,16 +47,6 @@ export function drawGrid(player) { CASE_SIZE, ); - if (player.grid.cases[i][j].isShip) { - ownCtx.fillStyle = "#A9A9A9"; - ownCtx.fillRect( - i * CASE_SIZE + 1, - j * CASE_SIZE + 1, - CASE_SIZE - 1, - CASE_SIZE - 1, - ); - } - if (player.grid.cases[i][j].isPlayed) { const centerX = CASE_SIZE / 2 + i * CASE_SIZE; const centerY = CASE_SIZE / 2 + j * CASE_SIZE; @@ -104,6 +121,189 @@ function clickPlay(event) { sendMove(play); } +function validMoove(player, piece, movement) { + let isValid = true; + player.pieces.forEach((p) => { + if (p.id === piece.id) { + if (movement.type === "move") { + if (p.vertical && movement.selectedCase.row + p.size > 10) + isValid = false; + if (!p.vertical && movement.selectedCase.col + p.size > 10) + isValid = false; + + let colMin, colMax, rowMin, rowMax; + + if (p.vertical) { + colMin = + movement.selectedCase.col - 1 < 0 + ? 0 + : movement.selectedCase.col - 1; + colMax = + movement.selectedCase.col + 1 > 9 + ? 9 + : movement.selectedCase.col + 1; + rowMin = + movement.selectedCase.row - 1 < 0 + ? 0 + : movement.selectedCase.row - 1; + rowMax = + movement.selectedCase.row + p.size > 9 + ? 9 + : movement.selectedCase.row + p.size; + } else { + colMin = + movement.selectedCase.col - 1 < 0 + ? 0 + : movement.selectedCase.col - 1; + colMax = + movement.selectedCase.col + p.size > 9 + ? 9 + : movement.selectedCase.col + p.size; + rowMin = + movement.selectedCase.row - 1 < 0 + ? 0 + : movement.selectedCase.row - 1; + rowMax = + movement.selectedCase.row + 1 > 9 + ? 9 + : movement.selectedCase.row + 1; + } + + for (let i = colMin; i <= colMax; i++) { + for (let j = rowMin; j <= rowMax; j++) { + if ( + player.grid.cases[i][j].isShip && + player.grid.cases[i][j].piece.id !== p.id + ) + isValid = false; + } + } + } else { + if (p.vertical && movement.selectedCase.x + p.size > 10) + isValid = false; + if (!p.vertical && movement.selectedCase.y + p.size > 10) + isValid = false; + } + } + }); + return isValid; +} + +function clickNewCase(player, piece) { + const clickNewCasehandler = function (event) { + let selectedCase = getCursorPosition(ownCanvas, event); + player.pieces.forEach((p) => { + if ( + p.id === piece.id && + p.isSelected && + validMoove(player, piece, { type: "move", selectedCase: selectedCase }) + ) { + for (let i = p.startPos.x; i <= p.endPos.x; i++) { + for (let j = p.startPos.y; j <= p.endPos.y; j++) { + player.grid.cases[i][j].piece = ""; + player.grid.cases[i][j].isShip = false; + } + } + p.startPos = { x: selectedCase.col, y: selectedCase.row }; + if (p.vertical) { + p.endPos = { + x: selectedCase.col, + y: selectedCase.row + piece.size - 1, + }; + } else { + p.endPos = { + x: selectedCase.col + piece.size - 1, + y: selectedCase.row, + }; + } + for (let i = p.startPos.x; i <= p.endPos.x; i++) { + for (let j = p.startPos.y; j <= p.endPos.y; j++) { + player.grid.cases[i][j].piece = p; + player.grid.cases[i][j].isShip = true; + } + } + } + drawGrid(player); + }); + }; + + return clickNewCasehandler; +} + +function rotatePiece(player, piece) { + const handler = function (event) { + event.preventDefault(); + + player.pieces.forEach((p) => { + if ( + p.id === piece.id && + p.isSelected && + validMoove(player, piece, { + type: "rotation", + selectedCase: p.startPos, + }) + ) { + for (let i = p.startPos.x; i <= p.endPos.x; i++) { + for (let j = p.startPos.y; j <= p.endPos.y; j++) { + player.grid.cases[i][j].piece = ""; + player.grid.cases[i][j].isShip = false; + } + } + if (p.vertical) { + p.endPos = { x: p.startPos.x + p.size - 1, y: p.startPos.y }; + p.vertical = false; + } else { + p.endPos = { x: p.startPos.x, y: p.startPos.y + p.size - 1 }; + p.vertical = true; + } + + for (let i = p.startPos.x; i <= p.endPos.x; i++) { + for (let j = p.startPos.y; j <= p.endPos.y; j++) { + player.grid.cases[i][j].piece = p; + player.grid.cases[i][j].isShip = true; + } + } + } + }); + drawGrid(player); + }; + + return handler; +} + +function clickChoose(player) { + const clickHandler = function (event) { + let selectedCase = getCursorPosition(ownCanvas, event); + if (player.grid.cases[selectedCase.col][selectedCase.row].isShip) { + const rotate_button = document.querySelector("#rotate"); + rotate_button.classList.remove("hidden-element"); + + let piece = player.grid.cases[selectedCase.col][selectedCase.row].piece; + let oldPieceId = selectedPiece.id; + player.pieces.forEach((p) => { + if (p.id === oldPieceId) { + p.isSelected = false; + } + if (p.id === piece.id) { + selectedPiece = p; + p.isSelected = true; + } + }); + + drawGrid(player); + + rotate_button.addEventListener("click", rotatePiece(player, piece)); + ownCanvas.addEventListener("mousedown", clickNewCase(player, piece)); + } + }; + + return clickHandler; +} + export function play() { ennemyCanvas.addEventListener("mousedown", clickPlay); } + +export function selectPiece(player) { + ownCanvas.addEventListener("mousedown", clickChoose(player)); +} diff --git a/public/scripts/index.js b/public/scripts/index.js index 5b53f93..83cbf6c 100644 --- a/public/scripts/index.js +++ b/public/scripts/index.js @@ -1,22 +1,36 @@ -import { drawGrid, drawEnnemyGrid, play } from "./game.js"; +import { drawGrid, drawEnnemyGrid, play, selectPiece } from "./game.js"; export const socket = io(); +function startConnection() { + socket.emit("first connection", socket.id, (response) => { + drawGrid(response.player); + selectPiece(response.player); + + document + .querySelector("#start") + .addEventListener("click", onCreateRoom(response.player)); + document + .querySelector("#join") + .addEventListener("click", onJoinRoom(response.player)); + }); +} + socket.on("start game", (game) => { - const gameCard = document.querySelector("#game"); + const ennemyBoard = document.querySelector("#ennemy_board"); - gameCard.classList.remove("hidden-element"); + ennemyBoard.classList.remove("hidden-element"); drawBoards(game); }); socket.on("end game", () => { console.log("end game"); - const game = document.querySelector("#game"); + const ennemyBoard = document.querySelector("#ennemy_board"); const loader = document.querySelector("#loader"); loader.classList.remove("hidden-element"); - game.classList.add("hidden-element"); + ennemyBoard.classList.add("hidden-element"); }); socket.on("play", () => { @@ -62,23 +76,28 @@ export function sendMove(move) { notification.classList.add("hidden-element"); } -const onCreateRoom = function (event) { - event.preventDefault(); +function onCreateRoom(player) { + const handler = function (event) { + event.preventDefault(); + const loader = document.querySelector("#loader"); + loader.classList.add("hidden-element"); - const loader = document.querySelector("#loader"); - loader.classList.add("hidden-element"); + socket.emit("room creation", player); + }; - socket.emit("room creation", socket.id); -}; + return handler; +} -const onJoinRoom = function (event) { - event.preventDefault(); +function onJoinRoom(player) { + const handler = function (event) { + event.preventDefault(); + const loader = document.querySelector("#loader"); + loader.classList.add("hidden-element"); - const loader = document.querySelector("#loader"); - loader.classList.add("hidden-element"); + socket.emit("ask for room", player); + }; - socket.emit("ask for room", socket.id); -}; + return handler; +} -document.querySelector("#start").addEventListener("click", onCreateRoom); -document.querySelector("#join").addEventListener("click", onJoinRoom); +setTimeout(startConnection, 100);