diff --git a/client/src/Winner.css b/client/src/Winner.css
index 605fa35..760897e 100644
--- a/client/src/Winner.css
+++ b/client/src/Winner.css
@@ -80,3 +80,19 @@
text-align: center;
line-height: 1.5rem;
}
+
+.Winner .ThiefStole {
+
+}
+
+.Winner .PlayerStolen {
+ display: flex;
+ align-items: center;
+
+}
+
+.Winner .PlayerStolenList {
+ display: flex;
+ flex-wrap: wrap;
+ flex-direction: row;
+}
\ No newline at end of file
diff --git a/client/src/Winner.js b/client/src/Winner.js
index ccba456..8a8436d 100644
--- a/client/src/Winner.js
+++ b/client/src/Winner.js
@@ -88,24 +88,60 @@ const Winner = ({ winnerDismissed, setWinnerDismissed }) => {
;
});
- let robber = <>>;
+ let robber;
+ let max = 0;
- if (winner.robberStole) {
- let stolen = <>>;
- for (let type in winner.stolen) {
- const resource = winner.stolen[type];
- if (typeof resource === 'object') { /* player colors are also in 'game.stolen' */
+ let playerStolen = [];
+ const stats = winner.stolen;
+ for (let player in stats) {
+ 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 stole
{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 = [];
+ }
+
+ let stolen;
+ for (let type in stats[player].stolen) {
+ if (type === 'total') {
continue;
}
+ if (!stolen) {
+ stolen = <>>;
+ }
+ const count = stats[player].stolen[type];
stolen = <>{stolen}
-
+
>;
}
- robber =
- Throughout the game, the robber stole
{winner.robberStole} resources:
-
{stolen}
-
;
- } else {
+ if (stolen) {
+ playerStolen.push(
+
{winner.players[player].name}
+ {stolen}
+ );
+ }
+ }
+
+ if (!robber) {
robber = The robber never stole any resources from anyone!
;
}
@@ -138,6 +174,12 @@ const Winner = ({ winnerDismissed, setWinnerDismissed }) => {
{ losers }
The game took {totalTime}.
{ robber }
+ { max !== 0 && <>
+ Player{ playerStolen.length === 1 ? '' : 's'} that had the most ({max}) resources stolen by the thief or other players:
+
+ { playerStolen }
+
+ > }
diff --git a/server/routes/games.js b/server/routes/games.js
index 1c1876a..8b2eaeb 100755
--- a/server/routes/games.js
+++ b/server/routes/games.js
@@ -285,14 +285,15 @@ const distributeResources = (game, roll) => {
tiles.forEach(tile => {
let shuffle = game.tileOrder[tile.index];
const resource = game.tiles[shuffle];
- console.log(tile.index, resource);
layout.tiles[tile.index].corners.forEach(cornerIndex => {
const active = game.placements.corners[cornerIndex];
if (active && active.color) {
+ const count = active.type === 'settlement' ? 1 : 2;
if (!tile.robber) {
- receives[active.color][resource.type] += active.type === 'settlement' ? 1 : 2;
+ receives[active.color][resource.type] += count;
} else {
- receives.robber[resource.type] += active.type === 'settlement' ? 1 : 2;
+ trackTheft(game, active.color, robber, resource.type, count);
+ receives.robber[resource.type] += count;
}
}
})
@@ -316,7 +317,7 @@ const distributeResources = (game, roll) => {
session.player.resources += entry[type];
message.push(`${entry[type]} ${type}`);
} else {
- robberSteal(game, color, type, entry[type]);
+
robber.push(`${entry[type]} ${type}`);
}
}
@@ -510,6 +511,7 @@ const loadGame = async (id) => {
console.log(`${info}: Creating backup of games/${id}`);
await writeFile(`games/${id}.bk`, JSON.stringify(game));
} catch (error) {
+ console.log(`Load or parse error from games/${id}:`, error);
console.log(`Attempting to load backup from games/${id}.bk`);
game = await readFile(`games/${id}.bk`)
.catch(() => {
@@ -518,7 +520,7 @@ const loadGame = async (id) => {
if (game) {
try {
game = JSON.parse(game);
- console.log(`Restoring backup to games/${id}`);
+ console.log(`Saving backup to games/${id}`);
await writeFile(`games/${id}`, JSON.stringify(game, null, 2));
} catch (error) {
console.error(error);
@@ -2055,6 +2057,8 @@ const stealResource = (game, session, color) => {
session.player.resources++;
game.turn.actions = [];
game.turn.limits = {};
+ trackTheft(game, victim.color, session.color, type, 1);
+
addChatMessage(game, session,
`${session.name} randomly stole 1 ${type} from ` +
`${victim.name}.`);
@@ -3320,7 +3324,6 @@ const calculatePoints = (game, update) => {
console.log(`${info}: ${message}`);
update.winner = Object.assign({}, player, {
state: 'winner',
- robberStole: game.robberStole,
stolen: game.stolen,
chat: game.chat,
turns: game.turns,
@@ -3944,22 +3947,71 @@ const getFilteredGameForPlayer = (game, session) => {
});
}
-const robberSteal = (game, color, type, count) => {
- if (!game.stolen) {
- game.stolen = {};
+/* Example:
+"stolen": {
+ "robber": {
+ "stole": {
+ "total": 5,
+ "wheat": 2,
+ "wood": 1,
+ "sheep": 2
+ }
+ },
+ "O": {
+ "stolen": {
+ "total": 2,
+ "wheat": 2
+ },
+ "stole": {
+ "total": 2,
+ "brick": 2
+ }
+ },
+ "W": {
+ "stolen": {
+ "total": 4,
+ "brick": 2,
+ "wood": 1,
+ "sheep": 2
+ },
+ "stole": {
+ "total": 3,
+ "brick": 2,
+ "wheat": 1
+ }
}
- if (!(color in game.stolen)) {
- game.stolen[color] = {};
+}
+*/
+const trackTheft = (game, from, to, type, count) => {
+ const stats = game.stolen;
+
+ /* Initialize the stole / stolen structures */
+ [ to, from ].forEach(player => {
+ if (!(player in stats)) {
+ stats[player] = {
+ stole: { /* the resources this player stole */
+ total: 0
+ },
+ stolen: { /* the resources stolen from this player */
+ total: 0
+ }
+ };
+ }
+ });
+
+ /* Initialize 'type' field in structures */
+ if (!(type in stats[from].stole)) {
+ games.stolen[from].stole[type] = 0;
}
- if (!(type in game.stolen)) {
- game.stolen[type] = 0;
+ if (!(type in stats[to].stole)) {
+ games.stole[to].stolen[type] = 0;
}
- if (!(type in game.stolen[color])) {
- game.stolen[color][type] = 0;
- }
- game.robberStole = game.robberStole += count;
- game.stolen[type] += count;
- game.stolen[color][type] += count;
+
+ /* Update counts */
+ stats[from].stolen.total += count;
+ stats[from].stolen[type] += count;
+ stats[to].stole.total += count;
+ stats[to].stole[type] += count;
}
const resetGame = (game) => {
@@ -3986,8 +4038,12 @@ const resetGame = (game) => {
tileOrder: game.tileOrder,
signature: game.signature,
players: game.players,
- stolen: {},
- robberStole: 0,
+ stolen: {
+ robber: {
+ stole: 0
+ },
+ total: 0
+ },
longestRoad: '',
longestRoadLength: 0,
largestArmy: '',