feature/api-admin-policies #78
@@ -0,0 +1,192 @@
|
|||||||
|
class BiscaGame {
|
||||||
|
constructor(id, type, player1, player2) {
|
||||||
|
this.id = id;
|
||||||
|
this.type = type;
|
||||||
|
this.deck = [];
|
||||||
|
this.trumpCard = null;
|
||||||
|
this.trumpSuit = null;
|
||||||
|
|
||||||
|
this.table = {
|
||||||
|
playerCard: null,
|
||||||
|
opponentCard: null,
|
||||||
|
firstPlayerId: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.currentTurn = null;
|
||||||
|
this.status = "pending";
|
||||||
|
|
||||||
|
this.players = {
|
||||||
|
[player1.id]: {
|
||||||
|
id: player1.id,
|
||||||
|
name: player1.name,
|
||||||
|
hand: [],
|
||||||
|
points: 0,
|
||||||
|
tricks: 0,
|
||||||
|
},
|
||||||
|
[player2.id]: {
|
||||||
|
id: player2.id,
|
||||||
|
name: player2.name,
|
||||||
|
hand: [],
|
||||||
|
points: 0,
|
||||||
|
tricks: 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
init() {
|
||||||
|
this.deck = this.createDeck();
|
||||||
|
const lastCard = this.deck.pop();
|
||||||
|
this.trumpCard = lastCard;
|
||||||
|
this.trumpSuit = lastCard.suit;
|
||||||
|
|
||||||
|
this.dealInitialCards();
|
||||||
|
|
||||||
|
this.currentTurn = Object.keys(this.players)[0];
|
||||||
|
this.status = "playing";
|
||||||
|
}
|
||||||
|
|
||||||
|
createDeck() {
|
||||||
|
const suits = ["c", "e", "o", "p"];
|
||||||
|
const ranks = [1, 2, 3, 4, 5, 6, 7, 11, 12, 13];
|
||||||
|
let deck = [];
|
||||||
|
for (const suit of suits) {
|
||||||
|
for (const rank of ranks) {
|
||||||
|
deck.push({
|
||||||
|
id: `${suit}-${rank}`,
|
||||||
|
suit,
|
||||||
|
rank,
|
||||||
|
strength: this.getStrength(rank),
|
||||||
|
points: this.getPoints(rank),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deck.sort(() => Math.random() - 0.5); // Baralhar
|
||||||
|
}
|
||||||
|
|
||||||
|
dealInitialCards() {
|
||||||
|
const cardsToDeal = this.type == 9 ? 9 : 3;
|
||||||
|
const pIds = Object.keys(this.players);
|
||||||
|
for (let i = 0; i < cardsToDeal; i++) {
|
||||||
|
pIds.forEach((id) => this.drawCard(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawCard(userId) {
|
||||||
|
if (this.deck.length > 0) {
|
||||||
|
this.players[userId].hand.push(this.deck.pop());
|
||||||
|
} else if (this.trumpCard) {
|
||||||
|
this.players[userId].hand.push(this.trumpCard);
|
||||||
|
this.trumpCard = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
playCard(userId, cardId) {
|
||||||
|
if (this.currentTurn != userId) return { error: "Não é a tua vez!" };
|
||||||
|
|
||||||
|
const player = this.players[userId];
|
||||||
|
const cardIndex = player.hand.findIndex((c) => c.id === cardId);
|
||||||
|
|
||||||
|
if (cardIndex === -1) return { error: "Não tens essa carta!" };
|
||||||
|
|
||||||
|
const card = player.hand[cardIndex];
|
||||||
|
|
||||||
|
player.hand.splice(cardIndex, 1); // Remove da mão (Server-side)
|
||||||
|
|
||||||
|
if (!this.table.playerCard) {
|
||||||
|
this.table.playerCard = card;
|
||||||
|
this.table.firstPlayerId = userId;
|
||||||
|
this.currentTurn = this.getOpponentId(userId); // Passa a vez
|
||||||
|
return { action: "next_turn" };
|
||||||
|
} else {
|
||||||
|
this.table.opponentCard = card;
|
||||||
|
return this.resolveTrick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resolveTrick() {
|
||||||
|
const p1Id = this.table.firstPlayerId;
|
||||||
|
const p2Id = this.getOpponentId(p1Id);
|
||||||
|
const card1 = this.table.playerCard;
|
||||||
|
const card2 = this.table.opponentCard;
|
||||||
|
|
||||||
|
let winnerId = p2Id;
|
||||||
|
let p1Wins = false;
|
||||||
|
|
||||||
|
if (card2.suit === this.trumpSuit && card1.suit !== this.trumpSuit)
|
||||||
|
p1Wins = false;
|
||||||
|
else if (card1.suit === this.trumpSuit && card2.suit !== this.trumpSuit)
|
||||||
|
p1Wins = true;
|
||||||
|
else if (card1.suit === card2.suit)
|
||||||
|
p1Wins = card1.strength > card2.strength;
|
||||||
|
else p1Wins = true;
|
||||||
|
|
||||||
|
winnerId = p1Wins ? p1Id : p2Id;
|
||||||
|
|
||||||
|
const points = card1.points + card2.points;
|
||||||
|
this.players[winnerId].points += points;
|
||||||
|
this.players[winnerId].tricks += 1;
|
||||||
|
this.currentTurn = winnerId;
|
||||||
|
|
||||||
|
if (this.type == 3) {
|
||||||
|
this.drawCard(winnerId);
|
||||||
|
this.drawCard(this.getOpponentId(winnerId));
|
||||||
|
}
|
||||||
|
|
||||||
|
const trickResult = { winnerId, points, cards: [card1, card2] };
|
||||||
|
|
||||||
|
this.table = { playerCard: null, opponentCard: null, firstPlayerId: null };
|
||||||
|
|
||||||
|
if (this.players[winnerId].hand.length === 0) {
|
||||||
|
this.status = "finished";
|
||||||
|
return { action: "game_ended", trickResult, winnerId };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { action: "trick_resolved", trickResult };
|
||||||
|
}
|
||||||
|
|
||||||
|
getStateForPlayer(userId) {
|
||||||
|
const oppId = this.getOpponentId(userId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: this.id,
|
||||||
|
trumpCard: this.trumpCard,
|
||||||
|
trumpSuit: this.trumpSuit,
|
||||||
|
deckCount: this.deck.length + (this.trumpCard ? 1 : 0),
|
||||||
|
currentTurn: this.currentTurn,
|
||||||
|
table: this.table,
|
||||||
|
|
||||||
|
hand: this.players[userId].hand,
|
||||||
|
points: this.players[userId].points,
|
||||||
|
|
||||||
|
opponent: {
|
||||||
|
points: this.players[oppId].points,
|
||||||
|
cardCount: this.players[oppId].hand.length,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
getOpponentId(id) {
|
||||||
|
return Object.keys(this.players).find((pid) => pid != id);
|
||||||
|
}
|
||||||
|
getPoints(r) {
|
||||||
|
const p = { 1: 11, 7: 10, 13: 4, 11: 3, 12: 2 };
|
||||||
|
return p[r] || 0;
|
||||||
|
}
|
||||||
|
getStrength(r) {
|
||||||
|
const s = {
|
||||||
|
1: 10,
|
||||||
|
7: 9,
|
||||||
|
13: 8,
|
||||||
|
11: 7,
|
||||||
|
12: 6,
|
||||||
|
6: 5,
|
||||||
|
5: 4,
|
||||||
|
4: 3,
|
||||||
|
3: 2,
|
||||||
|
2: 1,
|
||||||
|
};
|
||||||
|
return s[r] || 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = BiscaGame;
|
||||||
+137
-13
@@ -1,19 +1,143 @@
|
|||||||
import axios from "axios";
|
const axios = require("axios");
|
||||||
import { getUser } from "../state/connection.js";
|
const { getGame, createGame } = require("../state/game");
|
||||||
import { createGame, joinGame, playCard, getGame } from "../state/game.js";
|
const { getUser } = require("../state/connection");
|
||||||
|
|
||||||
const API_URL = process.env.API_URL || "http://localhost:8000/api";
|
const API_URL = "http://localhost:8000/api/v1";
|
||||||
|
|
||||||
export const handleGameEvents = (io, socket) => {
|
module.exports = (io, socket) => {
|
||||||
socket.on("create-game", async (data) => {
|
// --- EVENTO: ENTRAR NO JOGO (Validado pela tabela GAMES) ---
|
||||||
try {
|
socket.on("join-game", async ({ gameId }) => {
|
||||||
const user = getUser(socket.id);
|
const user = getUser(socket.id);
|
||||||
const game = createGame(data.type, user);
|
|
||||||
socket.join(`game_${game.match_id}`);
|
|
||||||
|
|
||||||
} catch (error) {
|
if (!user) {
|
||||||
console.error("Error creating game:", error);
|
socket.emit("error", { message: "Não autenticado." });
|
||||||
socket.emit("error", { message: "Failed to create game." });
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[Socket] User ${user.id} a tentar entrar no Game ${gameId}`);
|
||||||
|
|
||||||
|
// 1. Verificar se o jogo já está na memória do Node
|
||||||
|
let game = getGame(gameId);
|
||||||
|
|
||||||
|
// 2. Se NÃO existe na memória, vamos buscá-lo ao Laravel
|
||||||
|
if (!game) {
|
||||||
|
try {
|
||||||
|
// Token para autenticação no Laravel
|
||||||
|
const token = socket.handshake.auth.token;
|
||||||
|
|
||||||
|
// CHAMADA À API GAMES
|
||||||
|
const response = await axios.get(`${API_URL}/games/${gameId}`, {
|
||||||
|
headers: { Authorization: token },
|
||||||
|
});
|
||||||
|
|
||||||
|
const gameData = response.data.data;
|
||||||
|
|
||||||
|
// Validação: O user pertence a este jogo?
|
||||||
|
if (
|
||||||
|
gameData.player1_user_id != user.id &&
|
||||||
|
gameData.player2_user_id != user.id
|
||||||
|
) {
|
||||||
|
socket.emit("error", { message: "Não pertences a este jogo!" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validação: O jogo já acabou?
|
||||||
|
if (gameData.status === "Ended") {
|
||||||
|
socket.emit("error", { message: "Este jogo já terminou." });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`[Laravel] Game ${gameId} validado. A iniciar lógica...`);
|
||||||
|
|
||||||
|
// Preparar jogadores
|
||||||
|
// Nota: O endpoint 'games/{id}' deve retornar info básica dos users ou pelo menos os IDs.
|
||||||
|
// Se não vier o nome, usamos um placeholder ou o nome do user atual se coincidir.
|
||||||
|
|
||||||
|
const p1Name =
|
||||||
|
gameData.player1 && gameData.player1.name
|
||||||
|
? gameData.player1.name
|
||||||
|
: "Player 1";
|
||||||
|
const p2Name =
|
||||||
|
gameData.player2 && gameData.player2.name
|
||||||
|
? gameData.player2.name
|
||||||
|
: "Player 2";
|
||||||
|
|
||||||
|
const p1 = { id: gameData.player1_user_id, name: p1Name };
|
||||||
|
const p2 = { id: gameData.player2_user_id, name: p2Name };
|
||||||
|
|
||||||
|
// Tipo de jogo ('3' ou '9')
|
||||||
|
const type = gameData.type == "9" ? 9 : 3;
|
||||||
|
|
||||||
|
// CRIAR O JOGO NA MEMÓRIA
|
||||||
|
game = createGame(gameId, type, p1, p2);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
`[Erro Laravel] Falha ao buscar Game ${gameId}:`,
|
||||||
|
error.message
|
||||||
|
);
|
||||||
|
// Dica: Se der 404, o jogo não existe na BD
|
||||||
|
socket.emit("error", { message: "Erro ao buscar dados do jogo." });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Juntar o socket à sala do jogo
|
||||||
|
socket.join(`game_${gameId}`);
|
||||||
|
|
||||||
|
// 4. Enviar o estado do jogo ao jogador
|
||||||
|
if (game.players[user.id]) {
|
||||||
|
// Envia apenas o que este jogador pode ver (esconde mão do adversário)
|
||||||
|
const gameState = game.getStateForPlayer(user.id);
|
||||||
|
socket.emit("game-state", gameState);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- EVENTO: JOGAR CARTA ---
|
||||||
|
socket.on("play-card", ({ gameId, cardId }) => {
|
||||||
|
const user = getUser(socket.id);
|
||||||
|
const game = getGame(gameId);
|
||||||
|
|
||||||
|
if (!game || !user) return;
|
||||||
|
|
||||||
|
// 1. Processar jogada
|
||||||
|
const result = game.playCard(user.id, cardId);
|
||||||
|
|
||||||
|
if (result.error) {
|
||||||
|
socket.emit("game-error", { message: result.error });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const roomName = `game_${gameId}`;
|
||||||
|
|
||||||
|
// 2. Atualizar estado visual (Solução rápida: Forçar refresh nos clientes)
|
||||||
|
// O ideal é iterar os sockets da sala e enviar 'game-state' personalizado a cada um
|
||||||
|
const socketsInRoom = io.sockets.adapter.rooms.get(roomName);
|
||||||
|
if (socketsInRoom) {
|
||||||
|
for (const socketId of socketsInRoom) {
|
||||||
|
const s = io.sockets.sockets.get(socketId);
|
||||||
|
// Precisamos saber qual User ID pertence a este socket para enviar o estado certo
|
||||||
|
// Assumindo que o teu getUser(socketId) funciona:
|
||||||
|
const u = getUser(socketId);
|
||||||
|
if (u && game.players[u.id]) {
|
||||||
|
s.emit("game-state", game.getStateForPlayer(u.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Eventos de Animação (Vaza / Fim de Jogo)
|
||||||
|
if (result.action === "trick_resolved") {
|
||||||
|
io.to(roomName).emit("trick-end", result.trickResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.action === "game_ended") {
|
||||||
|
io.to(roomName).emit("game-over", { winnerId: result.winnerId });
|
||||||
|
|
||||||
|
// AQUI: Salvar o resultado na BD 'GAMES'
|
||||||
|
// axios.put(`${API_URL}/games/${gameId}`, {
|
||||||
|
// status: 'Ended',
|
||||||
|
// winner_user_id: result.winnerId,
|
||||||
|
// ...pontos...
|
||||||
|
// });
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
+40
-177
@@ -1,186 +1,49 @@
|
|||||||
const games = new Map();
|
// websockets/state/game.js
|
||||||
let currentGameID = 0;
|
|
||||||
|
|
||||||
// Bisca deck configuration
|
// Importamos a classe que criaste no Passo 1
|
||||||
const suits = ["hearts", "diamonds", "clubs", "spades"];
|
const BiscaGame = require('../classes/BiscaGame');
|
||||||
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 = () => {
|
// Aqui guardamos todos os jogos a decorrer na memória RAM do servidor
|
||||||
const deck = [];
|
// Chave: ID do jogo (matchId) -> Valor: Instância do Jogo (O objeto com o baralho, mãos, etc)
|
||||||
suits.forEach((suit) => {
|
const activeGames = new Map();
|
||||||
cards.forEach((card) => {
|
|
||||||
deck.push({ ...card, suit });
|
/**
|
||||||
});
|
* Cria um novo jogo, guarda-o na memória e retorna-o.
|
||||||
});
|
*/
|
||||||
return deck;
|
const createGame = (id, type, player1, player2) => {
|
||||||
|
// 1. Instanciar a classe (Criar o jogo com as regras)
|
||||||
|
const game = new BiscaGame(id, type, player1, player2);
|
||||||
|
|
||||||
|
// 2. Preparar o jogo (Baralhar, dar cartas iniciais)
|
||||||
|
game.init();
|
||||||
|
|
||||||
|
// 3. Guardar no "Armazém" para não se perder
|
||||||
|
activeGames.set(id, game);
|
||||||
|
|
||||||
|
console.log(`[Game State] Jogo criado: ${id} (Tipo: ${type})`);
|
||||||
|
return game;
|
||||||
};
|
};
|
||||||
|
|
||||||
const shuffleDeck = (deck) => {
|
/**
|
||||||
const shuffled = [...deck];
|
* Busca um jogo existente pelo ID.
|
||||||
for (let i = shuffled.length - 1; i > 0; i--) {
|
* Usado sempre que um jogador envia uma carta, para sabermos a qual jogo pertence.
|
||||||
const j = Math.floor(Math.random() * (i + 1));
|
*/
|
||||||
[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]];
|
const getGame = (id) => {
|
||||||
}
|
return activeGames.get(id);
|
||||||
return shuffled;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const dealCards = (deck, cardsPerPlayer = 3) => {
|
/**
|
||||||
const player1Hand = deck.slice(0, cardsPerPlayer);
|
* Remove o jogo da memória.
|
||||||
const player2Hand = deck.slice(cardsPerPlayer, cardsPerPlayer * 2);
|
* Usado quando o jogo acaba para libertar RAM.
|
||||||
const trumpCard = deck.pop();
|
*/
|
||||||
return {
|
const removeGame = (id) => {
|
||||||
player1Hand,
|
activeGames.delete(id);
|
||||||
player2Hand,
|
console.log(`[Game State] Jogo removido: ${id}`);
|
||||||
trumpCard,
|
|
||||||
remainingDeck: deck,
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const createGame = (type, host) => {
|
// Exportamos estas funções para serem usadas no ficheiro de eventos
|
||||||
const gameID = currentGameID++;
|
module.exports = {
|
||||||
const game = {
|
createGame,
|
||||||
match_id: gameID,
|
getGame,
|
||||||
type: type,
|
removeGame
|
||||||
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());
|
|
||||||
|
|||||||
Reference in New Issue
Block a user