const games = new Map(); let currentGameID = 0; // Bisca deck configuration const suits = ["hearts", "diamonds", "clubs", "spades"]; const cards = [ { face: "A", value: 11, points: 11 }, { face: "7", value: 10, points: 10 }, { face: "K", value: 4, points: 4 }, { face: "J", value: 3, points: 3 }, { face: "Q", value: 2, points: 2 }, { face: "6", value: 0, points: 0 }, { face: "5", value: 0, points: 0 }, { face: "4", value: 0, points: 0 }, { face: "3", value: 0, points: 0 }, { face: "2", value: 0, points: 0 }, ]; const createDeck = () => { const deck = []; suits.forEach((suit) => { cards.forEach((card) => { deck.push({ ...card, suit }); }); }); return deck; }; const shuffleDeck = (deck) => { const shuffled = [...deck]; for (let i = shuffled.length - 1; i > 0; i--) { const j = Math.floor(Math.random() * (i + 1)); [shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]; } return shuffled; }; const dealCards = (deck, cardsPerPlayer = 3) => { const player1Hand = deck.slice(0, cardsPerPlayer); const player2Hand = deck.slice(cardsPerPlayer, cardsPerPlayer * 2); const trumpCard = deck.pop(); return { player1Hand, player2Hand, trumpCard, remainingDeck: deck, }; }; export const createGame = (type, host) => { const gameID = currentGameID++; const game = { match_id: gameID, type: type, player1_user_id: host.id, player2_user_id: null, is_draw: false, winner_user_id: null, loser_user_id: null, status: "pending", began_at: null, ended_at: null, player1_points: 0, player2_points: 0, // Game-specific state player1_hand: [], player2_hand: [], trump_card: null, trump_suit: null, current_trick: [], current_player: null, round_number: 0, }; games.set(gameID, game); return game; }; export const joinGame = (gameID, player2) => { const game = games.get(gameID); game.player2_user_id = player2.id; game.status = "playing"; game.began_at = new Date(); const cardCount = parseInt(game.type, 10); if (![3, 9].includes(cardCount)) { throw new Error("Unsupported game type"); } // Initialize game state const deck = shuffleDeck(createDeck()); const { player1Hand, player2Hand, trumpCard, remainingDeck } = dealCards( deck, cardCount ); game.player1_hand = player1Hand; game.player2_hand = player2Hand; game.trump_card = trumpCard; game.trump_suit = trumpCard.suit; game.remaining_deck = remainingDeck; game.current_player = game.player1_user_id; // Player 1 starts return game; }; export const playCard = (gameID, playerID, cardIndex) => { const game = games.get(gameID); if (game.current_player !== playerID) { throw new Error("Not this player's turn"); } const isPlayer1 = playerID === game.player1_user_id; const playerHand = isPlayer1 ? game.player1_hand : game.player2_hand; const playedCard = playerHand.splice(cardIndex, 1)[0]; game.current_trick.push({ playerID, card: playedCard }); if (game.current_trick.length === 2) { resolveTrick(game); } else { game.current_player = isPlayer1 ? game.player2_user_id : game.player1_user_id; } return game; }; const resolveTrick = (game) => { const [first, second] = game.current_trick; let winner; if (first.card.suit === second.card.suit) { winner = first.card.value > second.card.value ? first : second; } else if (second.card.suit === game.trump_suit) { winner = second; } else { winner = first; // First card wins if no trump and different suits } const points = first.card.points + second.card.points; winner.playerID === game.player1_user_id ? (game.player1_points += points) : (game.player2_points += points); if (deck.length > 0) { const winnerHand = winner.playerID === game.player1_user_id ? game.player1_hand : game.player2_hand; loserHand = winner.playerID === game.player1_user_id ? game.player2_hand : game.player1_hand; winnerHand.push(game.deck.shift()); if (game.deck.length > 0) { loserHand.push(game.deck.shift()); } } game.current_trick = []; game.current_player = winner.playerID; game.round_number += 1; if (game.player1_hand.length === 0 && game.player2_hand.length === 0) { endGame(game); } }; const endGame = (game) => { game.status = "ended"; game.ended_at = new Date(); if (game.player1_points > game.player2_points) { game.winner_user_id = game.player1_user_id; game.loser_user_id = game.player2_user_id; } else if (game.player2_points > game.player1_points) { game.winner_user_id = game.player2_user_id; game.loser_user_id = game.player1_user_id; } else { game.is_draw = true; } }; export const getGame = (gameID) => games.get(gameID); export const getAllGames = () => Array.from(games.values());