diff --git a/server.js b/server.js index 73a678e2d71d0598283395814009f5417b7ca5a7..9d7540e423e40d7ad81a9f8e801bffc7d69e4f92 100644 --- a/server.js +++ b/server.js @@ -15,73 +15,129 @@ app.use(express.static('public')); io.on('connection', (socket) => { console.log('A user connected:', socket.id); - socket.on('createRoom', () => { + // Create a room + socket.on('createRoom', (playerName) => { const roomCode = Math.random().toString(36).substring(2, 7).toUpperCase(); - rooms[roomCode] = { players: [], questions: [] }; + rooms[roomCode] = { + players: {}, + settings: null, + questions: [] + }; + + rooms[roomCode].players[socket.id] = { name: playerName, score: 0 }; + socket.join(roomCode); socket.emit('roomCreated', roomCode); - console.log(`Room created with code ${roomCode}`); + console.log(`Room created with code ${roomCode} by ${playerName}`); }); - socket.on('joinRoom', (roomCode) => { - if (rooms[roomCode]) { - socket.join(roomCode); - socket.emit('roomJoined'); - console.log(`User ${socket.id} joined room ${roomCode}`); + // Join a room +socket.on('joinRoom', ({ roomCode, playerName, playerId }) => { + const room = rooms[roomCode]; + + if (room) { + let player = Object.values(room.players).find(p => p.id === playerId); + + if (player) { + player.socketId = socket.id; + console.log(`${playerName} rejoined room ${roomCode}`); + } else { + room.players[socket.id] = { id: playerId, name: playerName, score: 0 }; + console.log(`${playerName} joined room ${roomCode}`); + } + + socket.join(roomCode); + socket.emit('roomJoined'); } else { - socket.emit('error', 'Room not found'); + socket.emit('error', 'Room not found'); } - }); +}); - socket.on('startGame', ({ roomCode, category, difficulty }) => { - fetchQuestions(category, difficulty).then((questions) => { - if (!questions || questions.length === 0) { - socket.emit('error', 'Failed to load questions'); - return; - } - rooms[roomCode].questions = questions; - io.in(roomCode).emit('newQuestion', questions[0]); - }); + + socket.on('gameSettings', ({ roomCode, category, difficulty, numQuestions }) => { + if (rooms[roomCode]) { + rooms[roomCode].settings = { category, difficulty, numQuestions }; + fetchQuestions(category, difficulty, numQuestions).then((questions) => { + if (!questions || questions.length === 0) { + io.to(roomCode).emit('error', 'Failed to load questions'); + return; + } + + rooms[roomCode].questions = questions; + io.to(roomCode).emit('startGameWithSettings', { category, difficulty, numQuestions }); + sendNextQuestion(roomCode); + }); + } }); - socket.on('submitAnswer', (data) => { - const room = rooms[data.roomCode]; - + socket.on('submitAnswer', ({ roomCode, answer }) => { + const room = rooms[roomCode]; if (!room || !room.questions || room.questions.length === 0) { socket.emit('error', 'No questions available'); return; } - - const question = room.questions[0]; - const correct = question.correctAnswer === data.answer; - socket.emit('answerResult', { correct, correctAnswer: question.correctAnswer }); + + const currentQuestion = room.questions[0]; + const correct = currentQuestion.correctAnswer === answer; + if (correct) { + room.players[socket.id].score += 1; + } + + socket.emit('answerResult', { correct, correctAnswer: currentQuestion.correctAnswer }); }); socket.on('nextQuestion', (roomCode) => { + sendNextQuestion(roomCode); + }); + + function sendNextQuestion(roomCode) { const room = rooms[roomCode]; - if (room && room.questions.length > 0) { room.questions.shift(); if (room.questions.length > 0) { - io.in(roomCode).emit('newQuestion', room.questions[0]); + io.to(roomCode).emit('newQuestion', room.questions[0]); } else { - io.in(roomCode).emit('gameOver'); + determineWinner(roomCode); } - } else { - io.in(roomCode).emit('gameOver'); } - }); + } + + function determineWinner(roomCode) { + const room = rooms[roomCode]; + if (!room) return; + + const players = Object.entries(room.players); + const winner = players.reduce((topPlayer, [id, player]) => { + return player.score > topPlayer.score ? player : topPlayer; + }, { name: 'No one', score: 0 }); + + io.to(roomCode).emit('gameOver', { + winner: { name: winner.name, score: winner.score }, + scores: Object.values(room.players).map(player => ({ + name: player.name, + score: player.score + })) + }); + + delete rooms[roomCode]; + } socket.on('disconnect', () => { console.log('User disconnected:', socket.id); + for (const roomCode of Object.keys(rooms)) { + if (rooms[roomCode].players[socket.id]) { + delete rooms[roomCode].players[socket.id]; + console.log(`User ${socket.id} removed from room ${roomCode}`); + } + } }); }); -function fetchQuestions(category, difficulty) { +function fetchQuestions(category, difficulty, numQuestions) { return axios.get(`https://opentdb.com/api.php`, { params: { - amount: 5, + amount: numQuestions, category, difficulty, type: 'multiple', @@ -89,11 +145,8 @@ function fetchQuestions(category, difficulty) { }) .then((response) => { return response.data.results.map((q) => { - let options = [q.correct_answer]; - for (let incorrect of q.incorrect_answers) { - options.push(incorrect); - } - options = shuffleArray(options); + let options = [q.correct_answer, ...q.incorrect_answers]; + options = shuffleArray(options); return { question: q.question, options: options, @@ -116,3 +169,4 @@ function shuffleArray(array) { } server.listen(PORT, () => console.log(`Server is running on http://localhost:${PORT}`)); +