const roomController = require('./room'); const SONGS = [ { id: 1, title: "Black Steam", artist: "Carrot Quest GmbH", coverUrl: "https://mir-s3-cdn-cf.behance.net/project_modules/1400/fe529a64193929.5aca8500ba9ab.jpg" }, {id: 2, title: "Sunset Dreams", artist: "Ocean Waves", coverUrl: "https://place-hold.it/500x500/"}, {id: 3, title: "Neon Nights", artist: "Electric Avenue", coverUrl: "https://place-hold.it/500x500/"}, {id: 4, title: "Mountain Echo", artist: "Wild Terrain", coverUrl: "https://place-hold.it/500x500/"}, {id: 5, title: "Urban Jungle", artist: "City Dwellers", coverUrl: "https://place-hold.it/500x500/"}, {id: 6, title: "Cosmic Journey", artist: "Stargazers", coverUrl: "https://place-hold.it/500x500/"} ]; const gameStates = {}; const initializeGameState = (roomId) => { if (!gameStates[roomId]) { gameStates[roomId] = { round: 0, phase: 'waiting', roles: {}, selectedSong: null, scores: {}, songOptions: [], guessResults: {}, currentComposer: null, roundStartTime: null, phaseTimeLimit: { composing: 30, guessing: 30 }, lastFrequency: 440, }; const users = roomController.getRoomUsers(roomId); users.forEach(user => { gameStates[roomId].scores[user.id] = 0; }); } return gameStates[roomId]; }; const startNewRound = (roomId) => { const gameState = gameStates[roomId]; if (!gameState) return false; const users = roomController.getRoomUsers(roomId); if (users.length < 2) return false; gameState.round += 1; gameState.phase = 'composing'; gameState.guessResults = {}; gameState.roundStartTime = Date.now(); gameState.roles = {}; gameState.currentComposer = determineNextComposer(roomId, gameState, users); users.forEach(user => { gameState.roles[user.id] = user.id === gameState.currentComposer ? 'composer' : 'guesser'; }); selectSongAndOptions(gameState); return true; }; const determineNextComposer = (roomId, gameState, users) => { if (gameState.round === 1 || !gameState.currentComposer) { return users[Math.floor(Math.random() * users.length)].id; } const currentIndex = users.findIndex(user => user.id === gameState.currentComposer); if (currentIndex === -1) { return users[Math.floor(Math.random() * users.length)].id; } return users[(currentIndex + 1) % users.length].id; }; const selectSongAndOptions = (gameState) => { gameState.selectedSong = SONGS[Math.floor(Math.random() * SONGS.length)]; const songOptions = [...SONGS].sort(() => Math.random() - 0.5).slice(0, 5); if (!songOptions.includes(gameState.selectedSong)) { songOptions[Math.floor(Math.random() * songOptions.length)] = gameState.selectedSong; } gameState.songOptions = songOptions; }; const getTimeRemaining = (roomId) => { const gameState = gameStates[roomId]; if (!gameState || !gameState.roundStartTime) return 0; const phaseDuration = gameState.phaseTimeLimit[gameState.phase] * 1000; const timeElapsed = Date.now() - gameState.roundStartTime; const timeRemaining = Math.max(0, phaseDuration - timeElapsed); return Math.ceil(timeRemaining / 1000); }; const advancePhase = (roomId) => { const gameState = gameStates[roomId]; if (!gameState) { console.error(`Cannot advance phase: no game state for room ${roomId}`); return false; } const currentPhase = gameState.phase; console.log(`Advancing phase for room ${roomId} from ${currentPhase}`); if (currentPhase === 'composing') { gameState.phase = 'guessing'; gameState.roundStartTime = Date.now(); console.log(`Room ${roomId} advanced to guessing phase`); return { phase: 'guessing' }; } else if (currentPhase === 'guessing') { gameState.phase = 'results'; console.log(`Room ${roomId} advanced to results phase`); return { phase: 'results' }; } else if (currentPhase === 'results') { console.log(`Room ${roomId} starting new round from results phase`); return startNewRound(roomId); } console.warn(`Cannot advance from unknown phase "${currentPhase}" in room ${roomId}`); return false; }; const updateFrequency = (roomId, frequency) => { if (!gameStates[roomId]) return false; gameStates[roomId].lastFrequency = frequency; return true; }; const submitGuess = (roomId, userId, songId) => { const gameState = gameStates[roomId]; if (!gameState || gameState.phase !== 'guessing' || gameState.roles[userId] !== 'guesser') { return false; } const isCorrect = gameState.selectedSong.id === parseInt(songId); const points = isCorrect ? 10 : 0; gameState.guessResults[userId] = {songId, isCorrect, points}; if (isCorrect) { gameState.scores[userId] = (gameState.scores[userId] || 0) + points; } return { isCorrect, correctSong: gameState.selectedSong, points }; }; const getCurrentFrequency = (roomId) => gameStates[roomId]?.lastFrequency || 440; const getRoles = (roomId) => gameStates[roomId]?.roles || {}; const getUserRole = (roomId, userId) => gameStates[roomId]?.roles[userId] || null; const getSongOptions = (roomId) => gameStates[roomId]?.songOptions || []; const getSelectedSong = (roomId) => gameStates[roomId]?.selectedSong || null; const getRoundResults = (roomId) => { const gameState = gameStates[roomId]; if (!gameState) return {round: 0, scores: {}, guessResults: {}, selectedSong: null}; return { round: gameState.round, selectedSong: gameState.selectedSong, guessResults: gameState.guessResults, scores: gameState.scores }; }; const cleanupGameState = (roomId) => { delete gameStates[roomId]; }; const getCurrentComposer = (roomId) => gameStates[roomId]?.currentComposer || null; const getGameState = (roomId) => { return gameStates[roomId] || null; }; module.exports = { initializeGameState, startNewRound, getTimeRemaining, advancePhase, updateFrequency, getCurrentFrequency, submitGuess, getRoundResults, getRoles, getUserRole, getSongOptions, getSelectedSong, cleanupGameState, getCurrentComposer, getGameState };