import React, { useState, useEffect, useContext, useRef, useMemo, useCallback } from "react"; import equal from "fast-deep-equal"; import Paper from "@mui/material/Paper"; import Button from "@mui/material/Button"; import "./Winner.css"; import { Resource } from "./Resource"; import { PlayerColor } from "./PlayerColor"; import { GlobalContext } from "./GlobalContext"; interface WinnerProps { winnerDismissed: boolean; setWinnerDismissed: (dismissed: boolean) => void; } /* eslint-disable @typescript-eslint/no-explicit-any */ const Winner: React.FC = ({ winnerDismissed, setWinnerDismissed }) => { const { lastJsonMessage, sendJsonMessage } = useContext(GlobalContext); const [winner, setWinner] = useState(undefined); const [state, setState] = useState(undefined); const fields = useMemo(() => ["winner", "state"], []); useEffect(() => { if (!lastJsonMessage) { return; } const data = lastJsonMessage; switch (data.type) { case "game-update": console.log(`winner - game update`, data.update); if ("winner" in data.update && !equal(data.update.winner, winner)) { setWinner(data.update.winner); } if ("state" in data.update && data.update.state !== state) { if (data.update.state !== "winner") { setWinner(undefined); } setWinnerDismissed(false); setState(data.update.state); } break; default: break; } }, [lastJsonMessage, winner, state, setWinnerDismissed]); useEffect(() => { if (!sendJsonMessage) { return; } sendJsonMessage({ type: "get", fields, }); }, [sendJsonMessage, fields]); const quitClicked = useCallback(() => { if (!winnerDismissed) { setWinnerDismissed(true); sendJsonMessage({ type: "goto-lobby", }); } }, [sendJsonMessage, winnerDismissed, setWinnerDismissed]); if (!winner || winnerDismissed) { return <>; } let losers = []; for (const key in winner.players) { if (key === winner.color || winner.players[key].status === "Not active") { continue; } losers.push(winner.players[key]); } const turnCount = Math.floor(winner.turns / (losers.length + 1)); losers = losers.map((player: any) => { const averageSeconds = Math.floor(player.totalTime / turnCount / 1000), average = `${Math.floor(averageSeconds / 60)}m:${averageSeconds % 60}s`; return (
{player.name} finished with {player.points} victory points. {Number(player.potential) !== 0 && ( <> They had {player.potential} unplayed Victory Point card(s). )} Their average turn time was {average}.
); }); let robber; let max = 0; let playerStolen: any = {}; const stats = winner.stolen; for (const player in stats) { if (player === "total" || player === "player") { continue; } if (player === "robber") { robber = <>; for (const type in stats.robber.stole) { if (type === "total") { continue; } const count = stats.robber.stole[type]; robber = ( <> {robber} ); } robber = (
Throughout the game, the robber blocked {stats.robber.stole.total} resources:
{robber}
); continue; } if (stats[player].stolen.total < max) { continue; } if (stats[player].stolen.total > max) { max = stats[player].stolen.total; playerStolen = { robber: stats[player].stolen.robber, player: stats[player].stolen.player, element: <>, }; } let stolen; for (const type in stats[player].stolen) { if (["total", "robber", "player"].indexOf(type) !== -1) { continue; } if (!stolen) { stolen = <>; } const count = stats[player].stolen[type]; stolen = ( <> {stolen} ); } if (stolen) { playerStolen.element = (
{winner.players[player].name}
{stolen}
); } } if (!robber) { robber =
The robber never blocked any resources from anyone!
; } const averageSeconds = Math.floor(winner.totalTime / turnCount / 1000), average = `${Math.floor(averageSeconds / 60)}m:${averageSeconds % 60}s`; const seconds = winner.elapsedTime / 1000, h = Math.floor(seconds / (60 * 60)), m = Math.floor((seconds % (60 * 60)) / 60), s = Math.floor((seconds % (60 * 60)) % 60); const totalTime = `${h}h:${m}m:${s}s`; const vpType: string[] = ["market", "university", "library", "palace"]; const selectedVpType = vpType[Math.floor(vpType.length * Math.random())]; return (
{winner.name} has won with {winner.points} victory points!
Congratulations, {winner.name}!
{winner.name} won the game with {winner.points} Victory Points after {turnCount} game turns. {Number(winner.potential) !== 0 && ( <> They had {winner.potential} unplayed Victory Point card(s). )} Their average turn time was {average}.
{losers}
The game took {totalTime}.
{robber} {max !== 0 && ( <>
The robber stole {playerStolen.robber} and other players stole {playerStolen.player} resources from:
{playerStolen.element}
)}
); }; export { Winner };