diff --git a/public/game.html b/public/game.html index b4df495090fe60f38dab6b2c600b29355ad94195..7da9a4ea7cae852161bdf117cb96bb11c087bbab 100644 --- a/public/game.html +++ b/public/game.html @@ -31,5 +31,9 @@ </div> <script src="/public/gameClient.js"></script> + <div id="gameInfo"> + <span id="snakeCoords">Coords: (0, 0)</span> + <span id="snakeSize">Size: 1</span> + </div> </body> </html> diff --git a/public/gameClient.js b/public/gameClient.js index f686b7f7c87715f0a645ca0fc8b4a7f258631277..9093c046ce44f6c74cea692137a808f7dc720611 100644 --- a/public/gameClient.js +++ b/public/gameClient.js @@ -32,6 +32,14 @@ let gameBoardHandler = (event) => { widthStep = width / board[0].length; heightStep = height / board.length; + let coordsDiv = document.getElementById("snakeCoords"); + let sizeDiv = document.getElementById("snakeSize"); + + if (event.headPosition && event.bodySize) { + coordsDiv.innerText = `Coords: (${event.headPosition.x}, ${event.headPosition.y})`; + sizeDiv.innerText = `Size: ${event.bodySize}`; + } + for (let i = 0; i < board.length; i++) { for (let j = 0; j < board[i].length; j++) { if (board[i][j].type === 0) { @@ -137,6 +145,15 @@ socket.addEventListener("message", (event) => { messages.appendChild(messageElement); updateNumberPlayers(msg.numPlayers); + } else if (msg.type === "restart") { + const messages = document.getElementById("chatOutput"); + const messageElement = document.createElement("div"); + messageElement.innerText = `Player ${msg.pid} is the WINNER!`; + messages.appendChild(messageElement); + setTimeout(() => { + //Redirect back to lobby after 10 seconds + window.location = window.location; + }, 10000); } } catch (e) { console.log(e.message); diff --git a/src/game/game.js b/src/game/game.js index b06b15aa6f86ccb314e0ec8b6f53a26165e8abe0..1f81b419aed4ded5413a79babd17b0902b3650ce 100644 --- a/src/game/game.js +++ b/src/game/game.js @@ -305,15 +305,18 @@ module.exports = { let width = 11; let height = 11; - let head = null; + let bodySize = 0; + for (var i = 0; i < updatedBoard.length; i++) { for (var j = 0; j < updatedBoard[i].length; j++) { let cell = updatedBoard[i][j]; if (cell.type === cellTypes.PLAYERHEAD && cell.pid === pid) { - console.log("MY Player head found at: ", cell.x, cell.y); head = cell; } + if (cell.type === cellTypes.PLAYERBODY && cell.pid === pid) { + bodySize++; + } } } @@ -343,6 +346,11 @@ module.exports = { playerView.push(row); } - return playerView; + // Return the view along with head position and body size + return { + view: playerView, + headPosition: { x: head.x, y: head.y }, + bodySize: bodySize + 1, // Include head in body size + }; }, }; diff --git a/src/models/WebSocketModel.js b/src/models/WebSocketModel.js index c73bd4e69ee8d46d92270ebb6cdaed32fee2fde5..637128bec34ac6f3c324579a6c6ef7db9abddee6 100644 --- a/src/models/WebSocketModel.js +++ b/src/models/WebSocketModel.js @@ -41,6 +41,27 @@ class WebSocketModel { } } + const alivePlayers = this.games[game].players.filter( + (player) => !player.spectating, + ); + + if (alivePlayers.length === 1) { + const winner = alivePlayers[0].pid; + + for (let conn of this.games[game].players) { + conn.connection.send( + JSON.stringify({ + type: "restart", + pid: winner, + }), + ); + } + + this.resetGame(game); + + return; + } + for (let conn of this.games[game].players) { let playerView = null; if (conn.spectating) { @@ -57,7 +78,9 @@ class WebSocketModel { conn.connection.send( JSON.stringify({ type: "gameBoard", - data: playerView, + data: playerView.view, + headPosition: playerView.headPosition, + bodySize: playerView.bodySize, }), ); } @@ -67,7 +90,7 @@ class WebSocketModel { this.connections = []; this.games = {}; this.sockserver = new WebSocketServer({ port: 3001 }); - this.createGame("game1", "public"); + this.createGame("game1", "public", 25); this.createGame("game2", "public"); this.createGame("game3", "public"); this.onConnection(); @@ -85,9 +108,9 @@ class WebSocketModel { return publicGames; } - createGame(gameId, gameType) { + createGame(gameId, gameType, size = 100) { this.games[gameId] = { - gameBoard: gameModule.createGameBoard(100, 100), + gameBoard: gameModule.createGameBoard(size, size), players: [], type: gameType, started: false, @@ -98,6 +121,16 @@ class WebSocketModel { this.createInterval(gameId); } + resetGame(gameId) { + this.games[gameId].gameBoard = gameModule.createGameBoard(100, 100); + this.games[gameId].players = []; + this.games[gameId].started = false; + this.games[gameId].readyPlayers = 0; + this.games[gameId].borderCounter = 0; + this.games[gameId].numPlayers = 0; + this.games[gameId].elapsedTime = 0; + } + moveHandler(connection, message) { console.log("Received move: " + message.data); let movement = message.data; @@ -109,28 +142,51 @@ class WebSocketModel { for (var j = 0; j < gameBoard[0].length; j++) { if (gameBoard[i][j].type === 1 && gameBoard[i][j].pid === pid) { console.log("Updating direction to: " + movement); + + let currentDirection = gameBoard[i][j].direction; + let newDirection = currentDirection; + switch (movement) { case "up": - gameBoard[i][j].direction = 0; + if (currentDirection !== 2) newDirection = 0; // Cannot move up if going down break; case "right": - gameBoard[i][j].direction = 1; - cell.direction = 1; + if (currentDirection !== 3) newDirection = 1; // Cannot move right if going left break; case "down": - gameBoard[i][j].direction = 2; + if (currentDirection !== 0) newDirection = 2; // Cannot move down if going up break; case "left": - gameBoard[i][j].direction = 3; + if (currentDirection !== 1) newDirection = 3; // Cannot move left if going right break; } - console.log("New direction set to: " + gameBoard[i][j].direction); + if (newDirection !== currentDirection) { + console.log("Updating direction to: " + movement); + gameBoard[i][j].direction = newDirection; + } return; } } } } + arbitrateConnections(gameId) { + console.log( + "this.games[gameId].players.length: ", + this.games[gameId].players.length, + ); + for (let i = 0; i < this.games[gameId].players.length; i++) { + if (this.games[gameId].players[i].connection === undefined) { + delete this.games[gameId].players[i]; + console.log("Client has disconnected!"); + } + } + console.log( + "this.games[gameId].players.length: ", + this.games[gameId].players.length, + ); + } + onConnection() { this.sockserver.on("connection", (connection) => { console.log("New client connected!"); @@ -139,6 +195,8 @@ class WebSocketModel { let roomId = connection.protocol; + //this.arbitrateConnections(roomId); + if ( !this.games[roomId].started && this.games[roomId].players.length < 10 @@ -228,7 +286,7 @@ class WebSocketModel { for (let conn of this.games[roomId].players) { if (conn.connection !== connection) conn.connection.send( - JSON.stringify({ type: "playerReady", data: message.data }), + JSON.stringify({ type: "playerReady", pid: message.pid }), ); } this.games[roomId].readyPlayers++;