Skip to content
Snippets Groups Projects
Commit a6dd302b authored by Nathan Runk's avatar Nathan Runk
Browse files

Made changes to handle room placement for connection events (specifically with page refreshes).

parent e34342f4
No related branches found
No related tags found
1 merge request!4Merging into Master
const socket = io() const socket = io({
query: {
gameId: sessionStorage.getItem("gameId"),
playerId: sessionStorage.getItem("playerId")
}
});
socket.on('gameCode', handleGameCode); // socket.on("unknownCode", handleUnknownCode);
socket.on('unknownCode', handleUnknownCode); // socket.on("tooManyPlayers", handleTooManyPlayers);
socket.on('tooManyPlayers', handleTooManyPlayers);
socket.on('startGame', handleStartGame)
const waitingScreen = document.getElementById('waitingScreen'); const waitingScreen = document.getElementById("waitingScreen");
const homeScreen = document.getElementById('homeScreen'); const homeScreen = document.getElementById("homeScreen");
const newGameBtn = document.getElementById('newGameButton'); const newGameBtn = document.getElementById("newGameButton");
const joinGameBtn = document.getElementById('joinGameButton'); const joinGameBtn = document.getElementById("joinGameButton");
const gameCodeInput = document.getElementById('gameCodeInput'); const gameCodeInput = document.getElementById("gameCodeInput");
const gameCodeDisplay = document.getElementById('gameCodeDisplay'); const gameCodeDisplay = document.getElementById("gameCodeDisplay");
newGameBtn.addEventListener('click', newGame); newGameBtn.addEventListener("click", newGame);
joinGameBtn.addEventListener('click', joinGame); joinGameBtn.addEventListener("click", joinGame);
function newGame() { function newGame() {
socket.emit('newRoom'); socket.emit("new game");
init();
} }
socket.on("game created", (info) => {
sessionStorage.setItem("gameId", info.gameId);
sessionStorage.setItem("playerId", info.playerId);
init(info.gameId);
});
function joinGame() { function joinGame() {
const room = gameCodeInput.value; const gameId = gameCodeInput.value;
if (room != null && room === '') { socket.emit("join game", gameId);
alert("Please enter in a valid code!");
}
else {
socket.emit('joinRoom', room);
init();
}
} }
function init() { socket.on("game joined", (info) => {
homeScreen.style.display = "none"; sessionStorage.setItem("gameId", info.gameId);
waitingScreen.style.display = "block"; sessionStorage.setItem("playerId", info.playerId);
});
// window.location.href = 'index.html' socket.on("start game", () => {
// gameScreen.innerHTML = "This is where we will play!"; window.location.replace("game.html");
} });
function handleGameCode(gameCode) { socket.on("failed to join game", () => {
gameCodeDisplay.innerHTML = gameCode; alert("Failed to join game.");
} });
function handleUnknownCode() { function init(gameId) {
reset(); homeScreen.style.display = "none";
alert('Unknown Game Code') waitingScreen.style.display = "block";
gameCodeDisplay.innerText = gameId;
} }
function handleTooManyPlayers() { // function handleUnknownCode() {
reset(); // reset();
alert('This game is already in progress'); // alert("Unknown game code.");
} // }
// Change client's url path to game board // function handleTooManyPlayers() {
// NEED more concrete approach, changing path kicks sockets out of rooms // reset();
// Either need to dynamically change the page, or pass room code into game board // alert("This game is already in progress.");
function handleStartGame() { // }
window.location.href = 'game.html';
}
function reset() { // function reset() {
gameCodeInput.value = ''; // gameCodeInput.value = "";
homeScreen.style.display = "block"; // homeScreen.style.display = "block";
waitingScreen.style.display = "none"; // waitingScreen.style.display = "none";
} // }
...@@ -123,13 +123,18 @@ ...@@ -123,13 +123,18 @@
} }
let submitButton = document.getElementById("ENTER"); let submitButton = document.getElementById("ENTER");
let socket = io(); const socket = io({
query: {
gameId: sessionStorage.getItem("gameId"),
playerId: sessionStorage.getItem("playerId")
}
});
let correct = false; let correct = false;
let guess = ""; let guess = "";
let guessNum = 0; let guessNum = 0;
let oppGuessNum = 0; let oppGuessNum = 0;
// Calculate score // calculate score
function getScore(guessNum, first) { function getScore(guessNum, first) {
let score = 300 - (50 * (guessNum)); let score = 300 - (50 * (guessNum));
if (first) { if (first) {
...@@ -208,6 +213,10 @@ ...@@ -208,6 +213,10 @@
} }
}); });
const rightLetterRightSpot = "green";
const rightLetterWrongSpot = "yellow";
const wrongLetterWrongSpot = "gray";
socket.on("correct word", (color) => { socket.on("correct word", (color) => {
alert("Correct word!"); alert("Correct word!");
let currentGuess = document.getElementById(`guess-${guessNum++}`); let currentGuess = document.getElementById(`guess-${guessNum++}`);
...@@ -228,7 +237,7 @@ ...@@ -228,7 +237,7 @@
} }
playerScore = getScore(guessNum - 1, playerFirst); playerScore = getScore(guessNum - 1, playerFirst);
let pScore = document.getElementById("p-score"); let pScore = document.getElementById("p-score");
pScore.innerHTML = `SCORE: ${playerScore}`; pScore.innerText = `SCORE: ${playerScore}`;
}); });
// demo of how to change opponent's board // demo of how to change opponent's board
...@@ -252,7 +261,7 @@ ...@@ -252,7 +261,7 @@
oppScore = getScore(oppGuessNum, oppFirst); oppScore = getScore(oppGuessNum, oppFirst);
} }
let oScore = document.getElementById("o-score"); let oScore = document.getElementById("o-score");
oScore.innerHTML = `OPPONENT'S SCORE: ${oppScore}`; oScore.innerText = `OPPONENT'S SCORE: ${oppScore}`;
console.log(oppScore); console.log(oppScore);
}); });
...@@ -263,6 +272,7 @@ ...@@ -263,6 +272,7 @@
for (let [index, letterInput] of currentGuess.childNodes.entries()) { for (let [index, letterInput] of currentGuess.childNodes.entries()) {
letterInput.style.backgroundColor = colors[index]; letterInput.style.backgroundColor = colors[index];
let keyButton = document.getElementById(letterInput.value); let keyButton = document.getElementById(letterInput.value);
// work on keeping each key the correct color
keyButton.style.backgroundColor = colors[index]; keyButton.style.backgroundColor = colors[index];
} }
currentGuess.lastChild.removeAttribute("id"); currentGuess.lastChild.removeAttribute("id");
...@@ -282,7 +292,7 @@ ...@@ -282,7 +292,7 @@
} }
playerScore = getScore(guessNum, playerFirst); playerScore = getScore(guessNum, playerFirst);
let pScore = document.getElementById("p-score"); let pScore = document.getElementById("p-score");
pScore.innerHTML = `SCORE: ${playerScore}`; pScore.innerText = `SCORE: ${playerScore}`;
}); });
socket.on("invalid word", () => { socket.on("invalid word", () => {
......
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>REMAP</title> <title>REMAP</title>
...@@ -17,26 +16,22 @@ ...@@ -17,26 +16,22 @@
transition-duration: 0.4s; transition-duration: 0.4s;
cursor: pointer; cursor: pointer;
} }
.buttons { .buttons {
background-color: white; background-color: white;
flex: 1; flex: 1;
color: black; color: black;
border: 2px solid #4CAF50; border: 2px solid #4CAF50;
} }
.buttons:hover { .buttons:hover {
background-color: #4CAF50; background-color: #4CAF50;
flex: 1; flex: 1;
color: white; color: white;
} }
#waitingScreen { #waitingScreen {
display: none; display: none;
} }
</style> </style>
</head> </head>
<body> <body>
<div id="homeScreen"> <div id="homeScreen">
<h1>REMAP</h1> <h1>REMAP</h1>
...@@ -47,7 +42,6 @@ ...@@ -47,7 +42,6 @@
</div> </div>
<button type="submit" class="button buttons" id="joinGameButton">Join Game</button> <button type="submit" class="button buttons" id="joinGameButton">Join Game</button>
</div> </div>
<div id="waitingScreen"> <div id="waitingScreen">
<div style="display: flex; justify-content: center; margin: 0 auto;"> <div style="display: flex; justify-content: center; margin: 0 auto;">
<h1>Your room code is: <span id="gameCodeDisplay"></span></h1> <h1>Your room code is: <span id="gameCodeDisplay"></span></h1>
...@@ -57,5 +51,4 @@ ...@@ -57,5 +51,4 @@
<script src="/socket.io/socket.io.js"></script> <script src="/socket.io/socket.io.js"></script>
<script src="client.js"></script> <script src="client.js"></script>
</body> </body>
</html> </html>
const pg = require("pg"); const pg = require("pg");
// Import the Express module // import the Express module
const express = require("express"); const express = require("express");
const { join } = require("path"); // create a new instance of Express
// Create a new instance of Express
const app = express(); const app = express();
// https://www.npmjs.com/package/uuid
const { v4: uuidv4 } = require('uuid');
// Set-up a connection between the client and the server // set-up a connection between the client and the server
const http = require("http").Server(app); const http = require("http").Server(app);
const io = require("socket.io")(http); const io = require("socket.io")(http);
// user "public_html directory for static files" // use "public_html" directory for static files
app.use(express.static("public_html")); app.use(express.static("public_html"));
// imports database environment variables // imports database environment variables
...@@ -21,37 +22,26 @@ pool.connect().then(function () { ...@@ -21,37 +22,26 @@ pool.connect().then(function () {
console.log(`Connected to database ${env.database}`); console.log(`Connected to database ${env.database}`);
}); });
// app.get('/', function(req, res) { // global variables to store the rooms and game states
// let path = require("path"); let rooms = new Set();
// res.sendFile(path.resolve('index.html')); let games = {};
// })
// Global variable to store the rooms' objects with id, name, and sockets (players) // function to generate a 5 letter unique game code
const rooms = {}; function generateGameCode() {
let gameCode = "";
// Function to generate a 5 letter unique room code
function generateRoomCode() {
let code = '';
let characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; let characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
let charLength = characters.length let charLength = characters.length;
do {
for (let i = 0; i < 5; i++) { for (let i = 0; i < 5; i++) {
code += characters.charAt(Math.floor(Math.random() * charLength)) gameCode += characters.charAt(Math.floor(Math.random() * charLength));
}
return code;
} }
} while (rooms.has(gameCode));
// Function to connect a socket (player) to a specified room return gameCode;
function connectToRoom(socket, room) { }
// Object that represents a room from the 'rooms' variable
// Let the player join the room with the room id
socket.join(room.id, () => {
// Storing the room id in the sokcet to use later on
socket.roomId = room.id;
});
};
// ---------------Function that assigns new words---------------- // ---------------Function that assigns new words----------------
// Function to assign a unique word to specified room // function to assign a unique word to specified room
async function assignWord(roomName) { async function assignWord(roomName) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let idx = Math.floor(Math.random() * 5758) + 1; let idx = Math.floor(Math.random() * 5758) + 1;
...@@ -79,18 +69,18 @@ async function assignWord(roomName) { ...@@ -79,18 +69,18 @@ async function assignWord(roomName) {
console.log(error); console.log(error);
assignWord(roomName); assignWord(roomName);
}); });
}) });
} }
// Function Call // function call
// assignWord("roomName").then(function (result) { // assignWord("roomName").then(function (result) {
// console.log(result); // console.log(result);
// // Do stuff here ... a.k.a. emit or send etc // // do stuff here ... a.k.a. emit or send etc
// }); // });
// -------------------------------------------------------------- // --------------------------------------------------------------
const answer = "sweet"; // hardcoded for now const answer = "lapse"; // hardcoded for now
// ---- Try this to test the word function - Comment previous line and uncomment the lines beneath // ---- try this to test the word function - Comment previous line and uncomment the lines beneath
// let answer; // let answer;
// assignWord("roomName").then(function (result) { // assignWord("roomName").then(function (result) {
// answer = result; // answer = result;
...@@ -99,55 +89,52 @@ const rightLetterRightSpot = "green"; ...@@ -99,55 +89,52 @@ const rightLetterRightSpot = "green";
const rightLetterWrongSpot = "yellow"; const rightLetterWrongSpot = "yellow";
const wrongLetterWrongSpot = "gray"; const wrongLetterWrongSpot = "gray";
// handle incoming connections from clients
function debugRooms() {
console.log(io.sockets.adapter.rooms);
}
// Handle incoming connections from clients
io.on("connection", socket => { io.on("connection", socket => {
console.log("A user connected with id: " + socket.id); console.log("A user connected with id: " + socket.id);
socket.on('debugRooms', debugRooms); const gameId = socket.handshake.query.gameId;
const playerId = socket.handshake.query.playerId;
socket.on('newRoom', roomName => { socket.on('new game', () => {
// Storing the id, name, and sockets in the room object const gameId = generateGameCode(5);
const room = { rooms.add(gameId);
id: generateRoomCode(5), const game = {
name: roomName, players: []
sockets: []
}; };
rooms[room.id] = room; const playerId = uuidv4();
// Emit the new gameCode with room id game.players.push(playerId);
socket.emit('gameCode', room.id) games[gameId] = game;
// Player joins the new room that they created
connectToRoom(socket, room); io.to(socket.id).emit('game created', {gameId: gameId, playerId: playerId});
console.log("A new game room created with id: " + room.id);
socket.join(gameId);
console.log("A new game room created with id: " + gameId);
}); });
socket.on('joinRoom', roomId => { socket.on('join game', (gameId) => {
if (games.hasOwnProperty(gameId) && games[gameId].players.length === 1) {
const game = games[gameId];
const playerId = uuidv4();
game.players.push(playerId);
const room = rooms[roomId]; io.to(socket.id).emit('game joined', {gameId: gameId, playerId: playerId});
// https://stackoverflow.com/questions/66531331/socket-io-the-room-in-the-rooms-dictionary-is-undefined
// Condition to check if the roomId object is in the sockets socket.join(gameId);
if (io.sockets.adapter.rooms.has(roomId) && io.sockets.adapter.rooms.get(roomId).size == 1) {
// console.log(io.sockets.adapter.rooms); io.in(gameId).emit("start game");
// If it is, allow the socket (player) to join } else {
connectToRoom(socket, room); io.to(socket.id).emit('failed to join game');
console.log(socket.id + " has joined room with id: " + roomId);
// Emit the same gameCode to the new player that joined
socket.emit('gameCode', room.id);
// Tells client to open game board
io.in(room.id).emit('startGame');
}
// Otherwise let the player know the code is invalid or unknown
else {
console.log(socket.id + " tried to join " + roomId + " but the room does not exist.");
socket.emit('unknownCode');
} }
}); });
// handles room placement when clients disconnect and reconnect with a different socket id
if (games.hasOwnProperty(gameId) && games[gameId].players.includes(playerId)) {
socket.join(gameId);
// console.log(io.sockets.adapter.rooms);
}
socket.on("submit word", (word) => { socket.on("submit word", (word) => {
pool.query( pool.query(
`SELECT * FROM words WHERE word = $1`, `SELECT * FROM words WHERE word = $1`,
...@@ -156,8 +143,8 @@ io.on("connection", socket => { ...@@ -156,8 +143,8 @@ io.on("connection", socket => {
if (response.rows.length) { if (response.rows.length) {
let colors = []; let colors = [];
if (word === answer) { if (word === answer) {
socket.emit("correct word", rightLetterRightSpot); io.to(socket.id).emit("correct word", rightLetterRightSpot);
socket.broadcast.emit("update opponent", Array(5).fill(rightLetterRightSpot)); socket.to(gameId).emit("update opponent", Array(5).fill(rightLetterRightSpot));
} else { } else {
for (let i = 0; i < word.length; i++) { for (let i = 0; i < word.length; i++) {
// https://reactgo.com/javascript-variable-regex/ // https://reactgo.com/javascript-variable-regex/
...@@ -182,18 +169,16 @@ io.on("connection", socket => { ...@@ -182,18 +169,16 @@ io.on("connection", socket => {
colors.push(wrongLetterWrongSpot); colors.push(wrongLetterWrongSpot);
} }
} }
socket.emit("incorrect word", colors); io.to(socket.id).emit("incorrect word", colors);
// TEMPORARY socket.to(gameId).emit("update opponent", colors);
socket.broadcast.emit("update opponent", colors);
} }
} else { } else {
socket.emit("invalid word"); io.to(socket.id).emit("invalid word");
} }
}).catch(function (error) { }).catch(function (error) {
console.log(error); console.log(error);
})
}); });
});
}); });
http.listen(3000, function () { http.listen(3000, function () {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment