const { GameEngine } = require('../game/GameEngine'); const { buildStarterDeck, STARTER_DECKS, ALL_CARDS, CARD_DB } = require('../cards'); class GameManager { constructor() { this.rooms = new Map(); this.playerRooms = new Map(); this.games = new Map(); } createRoom(hostId, hostName, roomName) { const roomId = `room_${Date.now()}_${Math.random().toString(36).slice(2, 6)}`; const room = { id: roomId, name: roomName || `${hostName}'s Game`, hostId, players: [{ id: hostId, name: hostName, deck: null, ready: false }], status: 'waiting', gameId: null, maxPlayers: 2, }; this.rooms.set(roomId, room); this.playerRooms.set(hostId, roomId); return room; } joinRoom(roomId, playerId, playerName) { const room = this.rooms.get(roomId); if (!room) return { error: 'Room not found' }; if (room.status !== 'waiting') return { error: 'Game already in progress' }; if (room.players.length >= room.maxPlayers) return { error: 'Room is full' }; if (room.players.find((p) => p.id === playerId)) return { error: 'Already in room' }; room.players.push({ id: playerId, name: playerName, deck: null, ready: false }); this.playerRooms.set(playerId, roomId); return { success: true, room }; } leaveRoom(playerId) { const roomId = this.playerRooms.get(playerId); if (!roomId) return { error: 'Not in a room' }; const room = this.rooms.get(roomId); if (!room) { this.playerRooms.delete(playerId); return { error: 'Room not found' }; } room.players = room.players.filter((p) => p.id !== playerId); this.playerRooms.delete(playerId); if (room.players.length === 0) { this.rooms.delete(roomId); if (room.gameId) this.games.delete(room.gameId); return { success: true, roomDeleted: true, roomId }; } if (room.hostId === playerId) { room.hostId = room.players[0].id; } return { success: true, room }; } selectDeck(playerId, deckColor) { const roomId = this.playerRooms.get(playerId); if (!roomId) return { error: 'Not in a room' }; const room = this.rooms.get(roomId); if (!room) return { error: 'Room not found' }; const player = room.players.find((p) => p.id === playerId); if (!player) return { error: 'Player not in room' }; if (!STARTER_DECKS[deckColor]) return { error: 'Invalid deck color' }; player.deck = deckColor; player.ready = true; return { success: true, room }; } selectCustomDeck(playerId, cardIds) { const roomId = this.playerRooms.get(playerId); if (!roomId) return { error: 'Not in a room' }; const room = this.rooms.get(roomId); if (!room) return { error: 'Room not found' }; const player = room.players.find((p) => p.id === playerId); if (!player) return { error: 'Player not in room' }; if (cardIds.length < 40) return { error: 'Deck must have at least 40 cards' }; if (cardIds.length > 60) return { error: 'Deck cannot exceed 60 cards' }; for (const cid of cardIds) { if (!CARD_DB[cid]) return { error: `Invalid card id: ${cid}` }; } const nonLandCounts = {}; for (const cid of cardIds) { const card = CARD_DB[cid]; if (card.type !== 'land' || card.subtype !== 'basic') { nonLandCounts[cid] = (nonLandCounts[cid] || 0) + 1; if (nonLandCounts[cid] > 4) { return { error: `Cannot have more than 4 copies of ${card.name}` }; } } } player.deck = cardIds; player.customDeck = true; player.ready = true; return { success: true, room }; } startGame(roomId) { const room = this.rooms.get(roomId); if (!room) return { error: 'Room not found' }; if (room.players.length < 2) return { error: 'Need at least 2 players' }; if (!room.players.every((p) => p.ready)) return { error: 'Not all players are ready' }; const p1 = room.players[0]; const p2 = room.players[1]; const deck1 = p1.customDeck ? p1.deck : buildStarterDeck(p1.deck); const deck2 = p2.customDeck ? p2.deck : buildStarterDeck(p2.deck); const engine = new GameEngine(p1.id, p2.id, deck1, deck2); const initialState = engine.startGame(); room.status = 'playing'; room.gameId = engine.id; this.games.set(engine.id, engine); return { success: true, gameId: engine.id, state: initialState }; } getGame(gameId) { return this.games.get(gameId); } handleGameAction(gameId, playerId, action) { const engine = this.games.get(gameId); if (!engine) return { error: 'Game not found' }; return engine.handleAction(playerId, action); } getGameState(gameId, playerId) { const engine = this.games.get(gameId); if (!engine) return null; return engine.getState(playerId); } getRooms() { const roomList = []; for (const room of this.rooms.values()) { roomList.push({ id: room.id, name: room.name, playerCount: room.players.length, maxPlayers: room.maxPlayers, status: room.status, host: room.players.find((p) => p.id === room.hostId)?.name || 'Unknown', }); } return roomList; } getRoomDetails(roomId) { return this.rooms.get(roomId) || null; } getCardList() { return ALL_CARDS; } getStarterDecks() { return STARTER_DECKS; } } module.exports = { GameManager };