import React, { useState, useEffect, useContext, useRef, useMemo, useCallback } from "react"; import equal from "fast-deep-equal"; import Paper from '@material-ui/core/Paper'; import Button from '@material-ui/core/Button'; import "./Winner.css"; import {Resource} from './Resource.js'; import {PlayerColor} from './PlayerColor.js'; import { GlobalContext } from "./GlobalContext.js"; const Winner = ({ winnerDismissed, setWinnerDismissed }) => { const { ws } = useContext(GlobalContext); const [winner, setWinner] = useState(undefined); const [state, setState] = useState(undefined); const fields = useMemo(() => [ 'winner', 'state' ], []); const onWsMessage = (event) => { const data = JSON.parse(event.data); 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; } }; const refWsMessage = useRef(onWsMessage); useEffect(() => { refWsMessage.current = onWsMessage; }); useEffect(() => { if (!ws) { return; } const cbMessage = e => refWsMessage.current(e); ws.addEventListener('message', cbMessage); return () => { ws.removeEventListener('message', cbMessage); } }, [ws, refWsMessage]); useEffect(() => { if (!ws) { return; } ws.send(JSON.stringify({ type: 'get', fields })); }, [ws, fields]); const quitClicked = useCallback((event) => { if (!winnerDismissed) { setWinnerDismissed(true); ws.send(JSON.stringify({ type: 'goto-lobby' })); } }, [ws, winnerDismissed, setWinnerDismissed]); if (!winner || winnerDismissed) { return <>; } let losers = []; for (let 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 => { 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 = {}; const stats = winner.stolen; for (let player in stats) { if (player === 'total' || player === 'player') { continue; } if (player === 'robber') { robber = <>; for (let 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 (let 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`; let vpType = ['market', 'university', 'library', 'palace']; vpType = 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 };