From dac755cad0294dac71bddc30a1f19e35b4e8370e Mon Sep 17 00:00:00 2001 From: James Ketrenos Date: Sat, 12 Mar 2022 15:30:03 -0800 Subject: [PATCH] Use "resources" instead of "haveResources" Updated client to use private instead of player Signed-off-by: James Ketrenos --- client/src/Actions.js | 36 ++-- client/src/Activities.js | 11 -- client/src/Board.js | 50 +----- client/src/GameOrder.js | 17 +- client/src/Trade.js | 4 +- server/routes/games.js | 363 ++++++++++++++++++++++----------------- 6 files changed, 225 insertions(+), 256 deletions(-) diff --git a/client/src/Actions.js b/client/src/Actions.js index 708d295..df99fe8 100644 --- a/client/src/Actions.js +++ b/client/src/Actions.js @@ -1,52 +1,42 @@ import React, { useState, useEffect, useContext, useRef, useMemo } from "react"; -import "./Actions.css"; import Paper from '@material-ui/core/Paper'; import Button from '@material-ui/core/Button'; -import { PlayerName } from './PlayerName.js'; +import equal from "fast-deep-equal"; +import "./Actions.css"; +import { PlayerName } from './PlayerName.js'; import { GlobalContext } from "./GlobalContext.js"; const Actions = () => { const { ws, gameId, name } = useContext(GlobalContext); const [state, setState] = useState('lobby'); const [color, setColor] = useState(undefined); - const [player, setPlayer] = useState(undefined); - const [players, setPlayers] = useState(undefined); + const [priv, setPriv] = useState(undefined); const [turn, setTurn] = useState({}); const [active, setActive] = useState(0); const [edit, setEdit] = useState(name); const fields = useMemo(() => [ - 'state', 'turn', 'player', 'active', 'color' + 'state', 'turn', 'private', 'active', 'color' ], []); const onWsMessage = (event) => { const data = JSON.parse(event.data); switch (data.type) { case 'game-update': + if ('private' in data.update && !equal(data.update.private, priv)) { + setPriv(data.update.private); + } if ('state' in data.update && data.update.state !== state) { setState(data.update.state); } if ('color' in data.update && data.update.color !== color) { setColor(data.update.color); - if (players && color in players) { - setPlayer(players[color]); - } else if (player) { - setPlayer(undefined); - } } if ('name' in data.update && data.update.name !== edit) { setEdit(data.update.name); } - if ('players' in data.update) { - setPlayers(data.update.players); - if (color in data.update.players) { - setPlayer(data.update.players[color]); - } else if (player) { - setPlayer(undefined); - } - } - if ('turn' in data.update) { + if ('turn' in data.update && !equal(data.update.turn, turn)) { setTurn(data.update.turn); } if ('active' in data.update && data.update.active !== active) { @@ -143,14 +133,14 @@ const Actions = () => { const inLobby = state === 'lobby', inGame = state === 'normal', inGameOrder = state === 'game-order', - hasGameOrderRolled = (player && player.orderRoll) ? true : false, + hasGameOrderRolled = (priv && priv.orderRoll) ? true : false, hasRolled = (turn && turn.roll) ? true : false, isTurn = (turn && turn.color === color) ? true : false, robberActions = (turn && turn.robberInAction), - haveResources = player ? player.haveResources : false, + haveResources = priv ? priv.resources !== 0 : false, placement = (state === 'initial-placement' || (turn && turn.active === 'road-building')), placeRoad = placement && turn && turn.actions && turn.actions.indexOf('place-road') !== -1; - + return ( { edit === "" && } @@ -169,7 +159,7 @@ const Actions = () => { } onClick={rollClick}>Roll Dice - { turn && turn.roll === 7 && player && player.mustDiscard > 0 && + { turn && turn.roll === 7 && priv && priv.mustDiscard > 0 && } diff --git a/client/src/Activities.js b/client/src/Activities.js index 7a281d3..4a7a438 100644 --- a/client/src/Activities.js +++ b/client/src/Activities.js @@ -46,7 +46,6 @@ const Activities = () => { const [activities, setActivities] = useState([]); const [turn, setTurn] = useState(); const [color, setColor] = useState(); - const [player, setPlayer] = useState(undefined); const [players, setPlayers] = useState({}); const [timestamp, setTimestamp] = useState(0); const [state, setState] = useState(''); @@ -99,11 +98,6 @@ const Activities = () => { if ('players' in data.update && !equal(data.update.players, players)) { setPlayers(data.update.players); - if ((color in data.update.players) - && !equal(player, data.update.players[color])) { - setPlayer(data.update.players[color]); - requestUpdate('turn'); - } } if ('timestamp' in data.update && data.update.timestamp !== timestamp) { @@ -111,11 +105,6 @@ const Activities = () => { } if ('color' in data.update && data.update.color !== color) { setColor(data.update.color); - if (players && (data.update.color in players) - && !equal(player, players[data.update.color])) { - setPlayer(player); - requestUpdate('turn'); - } } break; default: diff --git a/client/src/Board.js b/client/src/Board.js index 375e61a..3a486da 100644 --- a/client/src/Board.js +++ b/client/src/Board.js @@ -51,54 +51,6 @@ const Board = () => { 'placements', 'turn', 'state', 'color', 'longestRoadLength' ], []); - /* Placements is a structure of roads and corners arrays - * indicating what is stored at each of the locations - * - * Corners consist of a type and color - * Roads consist of a color, and longestRoad - * - * See games.js resetGame, placeRoad, placeSettlement, placeCity, - * and calculateRoadLengths - * - * Returns: true === differences, false === same - */ - const comparePlacements = (A, B) => { - if (!A && !B) { - return false; /* same */ - } - if ((A && !B) - || (!A && B)) { - return true; - } - - if ((A.roads.length !== B.roads.length) - || (A.corners.length !== B.corners.length)) { - return true; - } - - /* Roads compare color and longestRoad */ - for (let i = 0; i < A.roads.length; i++) { - if (A.roads[i].color !== B.roads[i].color) { - return true; - } - if (A.roads[i].longestRoad !== B.roads[i].longestRoad) { - return true; - } - } - - /* Corners compare type and color */ - for (let i = 0; i < A.corners.length; i++) { - if (A.corners[i].type !== B.corners[i].type) { - return true; - } - if (A.corners[i].color !== B.corners[i].color) { - return true; - } - } - - return false; /* same */ - }; - const onWsMessage = (event) => { const data = JSON.parse(event.data); switch (data.type) { @@ -132,7 +84,7 @@ const Board = () => { } } - if ('placement' in data.update) { + if ('placements' in data.update) { if (!equal(data.update.placements, placements)) { console.log(`board - placements`, data.update.placements); setPlacements(data.update.placements); diff --git a/client/src/GameOrder.js b/client/src/GameOrder.js index b874eee..dd0200f 100644 --- a/client/src/GameOrder.js +++ b/client/src/GameOrder.js @@ -1,7 +1,8 @@ import React, { useState, useEffect, useContext, useRef, useMemo } from "react"; -import "./Actions.css"; import Paper from '@material-ui/core/Paper'; import Button from '@material-ui/core/Button'; +import equal from "fast-deep-equal"; + import { Dice } from "./Dice.js"; import { PlayerColor } from "./PlayerColor.js"; @@ -11,25 +12,23 @@ import { GlobalContext } from "./GlobalContext.js"; const GameOrder = () => { const { ws } = useContext(GlobalContext); - const [player, setPlayer] = useState(undefined); const [players, setPlayers] = useState({}); + const [color, setColor] = useState(undefined); const fields = useMemo(() => [ - 'player', 'players' + 'players', 'color' ], []); - const color = player ? player.color : undefined; - const onWsMessage = (event) => { const data = JSON.parse(event.data); switch (data.type) { case 'game-update': console.log(`GameOrder game-update: `, data.update); - if ('player' in data.update) { - setPlayer(data.update.player); - } - if ('players' in data.update) { + if ('players' in data.update && !equal(players, data.update.players)) { setPlayers(data.update.players); } + if ('color' in data.update && data.update.color !== color) { + setColor(data.update.color); + } break; default: break; diff --git a/client/src/Trade.js b/client/src/Trade.js index 7c59242..e7fb9f7 100644 --- a/client/src/Trade.js +++ b/client/src/Trade.js @@ -458,11 +458,11 @@ const Trade = ({table}) => {
{ players }
- { !player.haveResources && You have no resources to participate in this trade. } + { player.resources === 0 && You have no resources to participate in this trade. } - { player.haveResources && + { player.resources !== 0 &&
Get
Give
Have
{ transfers } diff --git a/server/routes/games.js b/server/routes/games.js index 6c63aa3..85346fa 100755 --- a/server/routes/games.js +++ b/server/routes/games.js @@ -202,7 +202,7 @@ const processGameOrder = (game, player, dice) => { name: players[0].name, color: players[0].color }; - placeSettlement(game, getValidCorners(game)); + getValidSettlementPlacements(game, getValidCorners(game)); addActivity(game, null, `${game.robberName} Robber Robinson entered the scene as the nefarious robber!`); addChatMessage(game, null, `Initial settlement placement has started!`); addChatMessage(game, null, `It is ${game.turn.name}'s turn to place a settlement.`);4 @@ -318,6 +318,7 @@ const distributeResources = (game, roll) => { if (color !== 'robber') { session = sessionFromColor(game, color); session.player[type] += entry[type]; + session.player.resources += entry[type]; message.push(`${entry[type]} ${type}`); } else { robberSteal(game, color, type); @@ -414,6 +415,7 @@ const newPlayer = (color) => { points: 0, status: "Not active", lastActive: 0, + resources: 0, order: 0, stone: 0, wheat: 0, @@ -654,7 +656,7 @@ const adminActions = (game, action, value) => { return `There are no valid locations for ${game.turn.name} to place a settlement.`; } game.turn.free = true; - placeSettlement(game, corners); + getValidSettlementPlacements(game, corners); addChatMessage(game, null, `Admin gave a settlment to ${game.turn.name}. ` + `They must now place the settlement.`); break; @@ -665,6 +667,7 @@ const adminActions = (game, action, value) => { case 'brick': const count = parseInt(card); session.player[type] += count; + session.resources += count; addChatMessage(game, null, `Admin gave ${count} ${type} to ${game.turn.name}.`); break; default: @@ -1627,7 +1630,7 @@ const placeCity = (game, limits) => { game.turn.limits = { corners: limits }; } -const placeSettlement = (game, limits) => { +const getValidSettlementPlacements = (game, limits) => { game.turn.actions = [ 'place-settlement' ]; game.turn.limits = { corners: limits }; } @@ -1799,14 +1802,18 @@ const trade = (game, session, { offer, value }) => { offer.gets.forEach(item => { if (target.name !== 'The bank') { target[item.type] -= item.count; + target.resources -= item.count; } player[item.type] += item.count; + player.resources += item.count; }); offer.gives.forEach(item => { if (target.name !== 'The bank') { target[item.type] += item.count; + target.resources += item.count; } player[item.type] -= item.count; + player.resources -= item.count; }); const from = (offer.name === 'The bank') ? 'the bank' : offer.name; @@ -1933,7 +1940,7 @@ const stealResource = (game, session, value) => { debugChat(game, 'Before steal'); - if (cards.length === 0) { + if (cards.length === 0) { addChatMessage(game, session, `${victim.name} ` + `did not have any cards for ${session.name} to steal.`); @@ -1943,7 +1950,9 @@ const stealResource = (game, session, value) => { let index = Math.floor(Math.random() * cards.length), type = cards[index]; victim[type]--; - session.player[type]++ + victim.resources--; + session.player[type]++; + session.player.resources++; game.turn.actions = []; game.turn.limits = {}; addChatMessage(game, session, @@ -1988,6 +1997,10 @@ const buyDevelopment = (game, session, value) => { player.stone--; player.wheat--; player.sheep--; + player.resources = 0; + [ 'wheat', 'brick', 'sheep', 'stone', 'wood' ].forEach(resource => { + player.resources += player[resource]; + }); debugChat(game, 'After development purchase'); card = game.developmentCards.pop(); card.turn = game.turns; @@ -2104,6 +2117,131 @@ const playCard = (game, session, { card }) => { } } +const placeSettlement = (game, session, value) => { + const player = session.player; + if (game.state !== 'initial-placement' && game.state !== 'normal') { + return `You cannot place an item unless the game is active.`; + } + if (session.color !== game.turn.color) { + return `It is not your turn! It is ${game.turn.name}'s turn.`; + } + index = parseInt(value); + if (game.placements.corners[index] === undefined) { + return `You have requested to place a settlement illegally!`; + } + /* If this is not a valid road in the turn limits, discard it */ + if (game.turn && game.turn.limits && game.turn.limits.corners && game.turn.limits.corners.indexOf(index) === -1) { + return `You tried to cheat! You should not try to break the rules.`; + } + corner = game.placements.corners[index]; + if (corner.color) { + return `This location already has a settlement belonging to ${game.players[corner.color].name}!`; + } + + if (!player.banks) { + player.banks = []; + } + + if (game.state === 'normal') { + if (!game.turn.free) { + if (player.brick < 1 || player.wood < 1 || player.wheat < 1 || player.sheep < 1) { + return `You have insufficient resources to build a settlement.`; + } + } + + if (player.settlements < 1) { + return `You have already built all of your settlements.`; + } + + player.settlements--; + + if (!game.turn.free) { + addChatMessage(game, session, `${session.name} spent 1 brick, 1 wood, 1 sheep, 1 wheat to purchase a settlement.`) + player.brick--; + player.wood--; + player.wheat--; + player.sheep--; + player.resources = 0; + [ 'wheat', 'brick', 'sheep', 'stone', 'wood' ].forEach(resource => { + player.resources += player[resource]; + }); + } + delete game.turn.free; + + corner.color = session.color; + corner.type = 'settlement'; + let bankType = undefined; + + if (layout.corners[index].banks.length) { + layout.corners[index].banks.forEach(bank => { + const border = game.borderOrder[Math.floor(bank / 3)], + type = game.borders[border][bank % 3]; + console.log(`${session.id}: Bank ${bank} = ${type}`); + if (!type) { + console.log(`${session.id}: Bank ${bank}`) + return; + } + bankType = (type === 'bank') + ? '3 of anything for 1 resource' + : `2 ${type} for 1 resource`; + if (player.banks.indexOf(type) === -1) { + player.banks.push(type); + } + }); + } + game.turn.actions = []; + game.turn.limits = {}; + if (bankType) { + addActivity(game, session, + `${session.name} placed a settlement by a maritime bank that trades ${bankType}.`); + } else { + addActivity(game, session, `${session.name} placed a settlement.`); + } + calculateRoadLengths(game, session); + } else if (game.state === 'initial-placement') { + if (game.direction && game.direction === 'backward') { + session.initialSettlement = index; + } + corner.color = session.color; + corner.type = 'settlement'; + let bankType = undefined; + if (layout.corners[index].banks.length) { + layout.corners[index].banks.forEach(bank => { + const border = game.borderOrder[Math.floor(bank / 3)], + type = game.borders[border][bank % 3]; + console.log(`${session.id}: Bank ${bank} = ${type}`); + if (!type) { + return; + } + bankType = (type === 'bank') + ? '3 of anything for 1 resource' + : `2 ${type} for 1 resource`; + if (player.banks.indexOf(type) === -1) { + player.banks.push(type); + } + }); + } + player.settlements--; + if (bankType) { + addActivity(game, session, + `${session.name} placed a settlement by a maritime bank that trades ${bankType}. ` + + `Next, they need to place a road.`); + } else { + addActivity(game, session, `${name} placed a settlement. ` + + `Next, they need to place a road.`); + } + placeRoad(game, layout.corners[index].roads); + } + + sendUpdateToPlayers(game, { + placements: game.placements, + turn: game.turn, + }); + sendUpdateToPlayer(session, { + private: game.player + }); +} + const asdf = () => { const game = 0, session = 0; switch (game) { @@ -2179,6 +2317,7 @@ const asdf = () => { if (player[type]) { gave.push(`${player.name} gave ${player[type]} ${type}`); session.player[type] += player[type]; + session.resources += player[type]; total += player[type]; player[type] = 0; } @@ -2195,6 +2334,7 @@ const asdf = () => { case 'year-of-plenty': cards.forEach(type => { session.player[type]++; + session.player.resources++; }); addChatMessage(game, session, `${session.name} player Year of Plenty.` + `They chose to receive ${display.join(', ')} from the bank.`); @@ -2236,132 +2376,10 @@ const asdf = () => { error = `There are no valid locations for you to place a settlement.`; break; } - placeSettlement(game, corners); + getValidSettlementPlacements(game, corners); addActivity(game, session, `${game.turn.name} is considering placing a settlement.`); break; - case 'place-settlement': - if (game.state !== 'initial-placement' && game.state !== 'normal') { - error = `You cannot place an item unless the game is active.`; - break; - } - if (session.color !== game.turn.color) { - error = `It is not your turn! It is ${game.turn.name}'s turn.`; - break; - } - index = parseInt(value); - if (game.placements.corners[index] === undefined) { - error = `You have requested to place a settlement illegally!`; - break; - } - /* If this is not a valid road in the turn limits, discard it */ - if (game.turn && game.turn.limits && game.turn.limits.corners && game.turn.limits.corners.indexOf(index) === -1) { - error = `You tried to cheat! You should not try to break the rules.`; - break; - } - corner = game.placements.corners[index]; - if (corner.color) { - error = `This location already has a settlement belonging to ${game.players[corner.color].name}!`; - break; - } - - if (!player.banks) { - player.banks = []; - } - - if (game.state === 'normal') { - if (!game.turn.free) { - if (player.brick < 1 || player.wood < 1 || player.wheat < 1 || player.sheep < 1) { - error = `You have insufficient resources to build a settlement.`; - break; - } - } - - if (player.settlements < 1) { - error = `You have already built all of your settlements.`; - break; - } - debugChat(game, 'Before settlement purchase'); - player.settlements--; - - if (!game.turn.free) { - addChatMessage(game, session, `${session.name} spent 1 brick, 1 wood, 1 sheep, 1 wheat to purchase a settlement.`) - player.brick--; - player.wood--; - player.wheat--; - player.sheep--; - } - delete game.turn.free; - debugChat(game, 'After settlement purchase'); - - corner.color = session.color; - corner.type = 'settlement'; - let bankType = undefined; - - if (layout.corners[index].banks.length) { - layout.corners[index].banks.forEach(bank => { - const border = game.borderOrder[Math.floor(bank / 3)], - type = game.borders[border][bank % 3]; - console.log(`Bank ${bank} = ${type}`); - if (!type) { - console.log(`Bank ${bank}`) - return; - } - bankType = (type === 'bank') - ? '3 of anything for 1 resource' - : `2 ${type} for 1 resource`; - if (player.banks.indexOf(type) === -1) { - player.banks.push(type); - } - }); - } - game.turn.actions = []; - game.turn.limits = {}; - if (bankType) { - addActivity(game, session, - `${name} placed a settlement by a maritime bank that trades ${bankType}.`); - } else { - addActivity(game, session, `${name} placed a settlement.`); - } - calculateRoadLengths(game, session); - } else if (game.state === 'initial-placement') { - if (game.direction && game.direction === 'backward') { - session.initialSettlement = index; - } - corner.color = session.color; - corner.type = 'settlement'; - let bankType = undefined; - if (layout.corners[index].banks.length) { - layout.corners[index].banks.forEach(bank => { - console.log(game.borderOrder); - console.log(game.borders); - const border = game.borderOrder[Math.floor(bank / 3)], - type = game.borders[border][bank % 3]; - console.log(`Bank ${bank} = ${type}`); - if (!type) { - return; - } - bankType = (type === 'bank') - ? '3 of anything for 1 resource' - : `2 ${type} for 1 resource`; - if (player.banks.indexOf(type) === -1) { - player.banks.push(type); - } - }); - } - player.settlements--; - if (bankType) { - addActivity(game, session, - `${name} placed a settlement by a maritime bank that trades ${bankType}. ` + - `Next, they need to place a road.`); - } else { - addActivity(game, session, `${name} placed a settlement. ` + - `Next, they need to place a road.`); - } - placeRoad(game, layout.corners[index].roads); - } - break; - case 'buy-city': if (game.state !== 'normal') { error = `You cannot purchase a city unless the game is active.`; @@ -2447,6 +2465,10 @@ const asdf = () => { addChatMessage(game, session, `${session.name} spent 2 wheat, 3 stone to upgrade to a city.`) player.wheat -= 2; player.stone -= 3; + player.resources = 0; + [ 'wheat', 'brick', 'sheep', 'stone', 'wood' ].forEach(resource => { + player.resources += player[resource]; + }); } delete game.turn.free; @@ -2535,7 +2557,11 @@ const asdf = () => { if (!game.turn.free) { addChatMessage(game, session, `${name} spent 1 brick, 1 wood to purchase a road.`) player.brick--; - player.wood--; + player.wood--; + player.resources = 0; + [ 'wheat', 'brick', 'sheep', 'stone', 'wood' ].forEach(resource => { + player.resources += player[resource]; + }); } debugChat(game, 'After road purchase'); @@ -2590,7 +2616,7 @@ const asdf = () => { name: next, color: getColorFromName(game, next) }; - placeSettlement(game, getValidCorners(game)); + getValidSettlementPlacements(game, getValidCorners(game)); calculateRoadLengths(game, session); addChatMessage(game, null, `It is ${next}'s turn to place a settlement.`); } else { @@ -2623,6 +2649,7 @@ const asdf = () => { let message = []; for (let type in receives) { player[type] += receives[type]; + player.resources += receives[type]; message.push(`${receives[type]} ${type}`); } addChatMessage(game, session, `${session.name} receives ${message.join(', ')}.`); @@ -2653,8 +2680,10 @@ const asdf = () => { break; } for (let type in discards) { - player[type] -= parseInt(discards[type]); - player.mustDiscard -= parseInt(discards[type]) + const count = parseInt(discards[type]); + player[type] -= count; + player.mustDiscard -= count; + player.resources -= count; } addChatMessage(game, null, `${session.name} discarded ${sum} resource cards.`); if (player.mustDiscard) { @@ -3002,6 +3031,24 @@ router.ws("/ws/:id", (ws, req) => { }); }); +const getFilteredPlayers = (game) => { + const filtered = {}; + for (let color in game.players) { + const player = Object.assign({}, game.players[color]); + filtered[color] = player; + if (player.status === 'Not active') { + continue; + } + player.resources = 0; + [ 'wheat', 'brick', 'sheep', 'stone', 'wood' ].forEach(resource => { + player.resources += player[resource]; + delete player[resource]; + }); + delete player.development; + } + return filtered; +}; + const wsConnect = async (ws, req) => { const { id } = req.params; const gameId = id; @@ -3179,6 +3226,10 @@ const wsConnect = async (ws, req) => { update = {}; data.fields.forEach((field) => { switch (field) { + case 'player': + sendWarning(session, `'player' is not a valid item. use 'private' instead`); + update.player = undefined; + break; case 'id': case 'chat': case 'startTime': @@ -3191,8 +3242,11 @@ const wsConnect = async (ws, req) => { case 'unselected': update.unselected = getFilteredUnselected(game); break; + case 'private': + update.private = session.player; + break; case 'players': - update.players = game.players; + update.players = getFilteredPlayers(game); break; case 'color': console.log(`${session.id}: -> Returning color as ${session.color} for ${getName(session)}`); @@ -3343,14 +3397,6 @@ const debugChat = (game, preamble) => { const sendGameToSession = (session, reducedSessions, game, reducedGame, error, res) => { const player = session.player ? session.player : undefined; - if (player) { - player.haveResources = player.wheat > 0 || - player.brick > 0 || - player.sheep > 0 || - player.stone > 0 || - player.wood > 0; - } - /* Strip out data that should not be shared with players */ delete reducedGame.developmentCards; @@ -3577,14 +3623,6 @@ const getFilteredGameForPlayer = (game, session) => { const player = session.player ? session.player : undefined; - if (player) { - player.haveResources = player.wheat > 0 || - player.brick > 0 || - player.sheep > 0 || - player.stone > 0 || - player.wood > 0; - } - /* Strip out data that should not be shared with players */ delete reducedGame.developmentCards; @@ -3653,11 +3691,6 @@ const resetGame = (game) => { longestRoad: undefined }); - /* Reset all player data */ - for (let color in game.players) { - clearPlayer(game.players[color]); - } - /* Populate the game corner and road placement data as cleared */ for (let i = 0; i < layout.corners.length; i++) { game.placements.corners[i] = { @@ -3673,6 +3706,14 @@ const resetGame = (game) => { }; } + /* Put the robber back on the Desert */ + for (let i = 0; i < game.pipOrder.length; i++) { + if (game.pipOrder[i] === 18) { + game.robber = i; + break; + } + } + /* Populate the game development cards with a fresh deck */ for (let i = 1; i <= 14; i++) { game.developmentCards.push({ @@ -3694,6 +3735,11 @@ const resetGame = (game) => { })); shuffleArray(game.developmentCards); + + /* Reset all player data */ + for (let color in game.players) { + clearPlayer(game.players[color]); + } /* Ensure sessions are connected to player objects */ for (let key in game.sessions) { @@ -3702,14 +3748,7 @@ const resetGame = (game) => { session.player = game.players[session.color]; session.player.status = 'Active'; session.player.lastActive = Date.now(); - } - } - - /* Put the robber back on the Desert */ - for (let i = 0; i < game.pipOrder.length; i++) { - if (game.pipOrder[i] === 18) { - game.robber = i; - break; + session.player.live = session.live; } } }