Skip to content

Commit

Permalink
Add unique room ID generation and waiting player management to Tic Ta…
Browse files Browse the repository at this point in the history
…c Toe logic
  • Loading branch information
Xanthium7 committed Jan 1, 2025
1 parent 6212b7f commit 771c3f3
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 50 deletions.
16 changes: 15 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"version": "1.0.0",
"main": "server.js",
"scripts": {

"start": "node server.js",
"dev": "nodemon server.js"
},
Expand All @@ -14,6 +13,7 @@
"dependencies": {
"@azure/web-pubsub-socket.io": "^1.1.0",
"dotenv": "^16.4.7",
"socket.io": "^4.8.1"
"socket.io": "^4.8.1",
"uuid": "^11.0.3"
}
}
145 changes: 98 additions & 47 deletions ticTacToe.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,88 @@
const { v4: uuidv4 } = require("uuid"); // For generating unique room IDs

// Initialize a waiting queue
if (!module.exports.waitingPlayers) {
module.exports.waitingPlayers = {};
}

module.exports = function (io, socket) {
const { roomId, playername } = socket.handshake.query;

if (!io.games) {
io.games = {};
}

if (!io.games[roomId]) {
io.games[roomId] = {
players: {},
board: Array(9).fill(null),
currentTurn: null,
winner: null,
};
}
const game = io.games[roomId];

//adding the player part
game.players[socket.id] = {
id: socket.id,
name: playername || "hehe",
symbol: null, // 'X' or 'O'
};

const playerCount = Object.keys(game.players).length;
if (playerCount === 1) {
game.players[socket.id].symbol = "X";
game.currentTurn = socket.id;
socket.emit("gameStart", {
symbol: "X",
board: game.board,
currentTurn: game.currentTurn,
});
} else if (playerCount === 2) {
game.players[socket.id].symbol = "O";
// notify both players
io.to(roomId).emit("gameStart", {
symbol: "O",
board: game.board,
currentTurn: game.currentTurn,
});
} else {
socket.emit("gameFull");
}
// Handle startTicTacToe event
socket.on("startTicTacToe", () => {
if (!module.exports.waitingPlayers[roomId]) {
// No player waiting, mark this socket as waiting
module.exports.waitingPlayers[roomId] = socket.id;
socket.emit("waitingForPlayer");
} else {
// Found a waiting player, pair them
const waitingSocketId = module.exports.waitingPlayers[roomId];
delete module.exports.waitingPlayers[roomId];

// Create a unique game room id
const gameRoomId = uuidv4();
// Join both sockets to the game room
socket.join(gameRoomId);
const waitingSocket = io.sockets.sockets.get(waitingSocketId);
if (waitingSocket) {
waitingSocket.join(gameRoomId);

// Initialize game state
io.games[gameRoomId] = {
players: {},
board: Array(9).fill(null),
currentTurn: null,
winner: null,
};

// Assign symbols
io.games[gameRoomId].players[waitingSocketId] = {
id: waitingSocketId,
name: playername || "Player",
symbol: "X",
};
io.games[gameRoomId].players[socket.id] = {
id: socket.id,
name: playername || "Player",
symbol: "O",
};

// Set current turn
io.games[gameRoomId].currentTurn = waitingSocketId;

// Emit gameStart to both players with roomId
waitingSocket.emit("gameStart", {
symbol: "X",
board: io.games[gameRoomId].board,
currentTurn: io.games[gameRoomId].currentTurn,
roomId: gameRoomId,
});
socket.emit("gameStart", {
symbol: "O",
board: io.games[gameRoomId].board,
currentTurn: io.games[gameRoomId].currentTurn,
roomId: gameRoomId,
});
} else {
// Waiting socket was disconnected before pairing
socket.emit("waitingForPlayer");
}
}
});

// Handle player's move
socket.on("makeMove", (data) => {
const { index, roomId } = data;
const game = io.games[roomId];
if (!game) {
socket.emit("invalidMove", "Game not found.");
return;
}

socket.on("makeMove", (index) => {
if (game.winner) {
socket.emit("invalidMove", "Game has already been won.");
return;
Expand Down Expand Up @@ -108,15 +147,27 @@ module.exports = function (io, socket) {

// Handle disconnection
socket.on("disconnect", () => {
delete game.players[socket.id];
io.to(roomId).emit("playerDisconnected", socket.id);

// Reset game if a player disconnects
game.board = Array(9).fill(null);
game.currentTurn = null;
game.winner = null;
// Remove from waiting players if in waiting
if (module.exports.waitingPlayers[roomId] === socket.id) {
delete module.exports.waitingPlayers[roomId];
}

// Notify remaining players
io.to(roomId).emit("gameReset", { board: game.board });
// Find all games this socket is in
for (const gameRoomId in io.games) {
const game = io.games[gameRoomId];
if (game.players[socket.id]) {
delete game.players[socket.id];
io.to(gameRoomId).emit("playerDisconnected", socket.id);

// Reset game
game.board = Array(9).fill(null);
game.currentTurn = null;
game.winner = null;

// Notify remaining players
io.to(gameRoomId).emit("gameReset", { board: game.board });
break;
}
}
});
};

0 comments on commit 771c3f3

Please sign in to comment.