{ this.state.message }
{(this.state.pickName || !game.name) && }
@@ -934,7 +978,7 @@ class Table extends React.Component {
{ game && game.turn && game.turn.color !== game.color &&
(game.state === 'initial-placement' || game.state === 'normal') &&
-
+ (!game.player || !game.player.mustDiscard) &&
}
{ game && game.showCards &&
diff --git a/client/src/assets/man-robber.png b/client/src/assets/man-robber.png
new file mode 100755
index 0000000..52d2b7d
Binary files /dev/null and b/client/src/assets/man-robber.png differ
diff --git a/client/src/assets/woman-robber.png b/client/src/assets/woman-robber.png
new file mode 100755
index 0000000..007a774
Binary files /dev/null and b/client/src/assets/woman-robber.png differ
diff --git a/server/routes/games.js b/server/routes/games.js
index 075a573..e539491 100755
--- a/server/routes/games.js
+++ b/server/routes/games.js
@@ -291,7 +291,11 @@ const distributeResources = (game, roll) => {
for (let i = 0; i < game.pipOrder.length; i++) {
let index = game.pipOrder[i];
if (assetData.pips[index].roll === roll) {
- tiles.push(i);
+ if (game.robber === i) {
+ addChatMessage(game, null, `That pesky Robber stole resources!`);
+ } else {
+ tiles.push(i);
+ }
}
}
@@ -350,10 +354,40 @@ const processRoll = (game, dice) => {
game.turn.roll = game.dice[0] + game.dice[1];
if (game.turn.roll === 7) {
addChatMessage(game, null, `ROBBER! ROBBER! ROBBER!`);
+ for (let id in game.sessions) {
+ const player = game.sessions[id].player;
+ if (player) {
+ let discard = player.stone + player.wheat + player.brick + player.wood + player.sheep;
+ if (discard > 7) {
+ discard = Math.floor(discard / 2);
+
+ player.mustDiscard = discard;
+ addChatMessage(game, null, `${game.sessions[id].name} must discard ${discard} resource cards.`);
+ } else {
+ delete player.mustDiscard;
+ }
+ }
+ }
+ /*
+ if you roll a 7, no one receives any resource cards.
+ instead, every player who has more than 7 resource cards must select
+ half (rounded down) of their
+ resource cards and return them to the bank.
+ then you muyst move the robber:
+ 1. you must move the robber immediately to the number token of any other
+ terrain ohex or to the desert hex,
+ 2. you then steal 1 (random) resourcde card from an opponent who has a settlement or city
+ adjacent to the target terrain hex. the player who is robbed holds their resource cards
+ face down. you then take 1 card at random. if the target hex is adjacent to 2 or
+ more player's settlements or cities, you choose which one you want to steal from.
+ If the production number for the hex containing the robber is rolled, the owners of
+ adjacent settlements and citieis do not receive resourcres. The robber prevents it.
+ */
} else {
distributeResources(game, game.turn.roll);
}
}
+
const getPlayer = (game, color) => {
if (!game) {
return {
@@ -846,6 +880,34 @@ router.put("/:id/:action/:value?", async (req, res) => {
addChatMessage(game, null, `It is ${next}'s turn.`);
}
break;
+ case 'place-robber':
+ if (game.state !== 'normal' && game.turn.roll !== 7) {
+ error = `You cannot place robber unless 7 was rolled!`;
+ break;
+ }
+ if (game.turn.name !== name) {
+ error = `You cannot place the robber when it isn't your turn.`;
+ break;
+ }
+ for (let color in game.players) {
+ if (game.players[color].status === 'Not active') {
+ continue;
+ }
+ if (game.players[color].mustDiscard > 0) {
+ error = `You cannot place the robber until everyone has discarded!`;
+ break;
+ }
+ }
+ const robber = parseInt(value);
+ if (game.robber === robber) {
+ error = `You must move the robber to a new location!`;
+ break;
+ }
+ game.robber = robber;
+ game.turn.placedRobber = true;
+ addChatMessage(game, session, `Robber has been moved!`);
+ addChatMessage(game, null, 'TODO: Look up which players are on tile, then allow robber-roller to select which player to steal from.');
+ break;
case 'place-settlement':
if (game.state !== 'initial-placement' && game.state !== 'normal') {
error = `You cannot place an item unless the game is active.`;
@@ -979,6 +1041,33 @@ router.put("/:id/:action/:value?", async (req, res) => {
case 'place-city':
error = `City placement not yet implemented!`;
break;
+ case 'discard':
+ if (game.turn.roll !== 7) {
+ error = `You can only discard due to the Robber!`;
+ break;
+ }
+ const discards = req.body, player = session.player;
+ let sum = 0;
+ for (let type in discards) {
+ if (player[type] < parseInt(discards[type])) {
+ error = `You have requested to discard more ${type} than you have.`
+ break;
+ }
+ sum += parseInt(discards[type]);
+ }
+ if (sum > player.mustDiscard) {
+ error = `You have requested to discard more cards than you are allowed!`;
+ break;
+ }
+ for (let type in discards) {
+ player[type] -= parseInt(discards[type]);
+ player.mustDiscard -= parseInt(discards[type])
+ }
+ addChatMessage(game, null, `${session.name} discarded ${sum} resource cards.`);
+ if (player.mustDiscard) {
+ addChatMessage(game, null, `${session.name} must discard ${player.mustDiscard} more cards.`);
+ }
+ break;
case "state":
const state = value;
if (!state) {
@@ -1048,6 +1137,28 @@ const sendGame = async (req, res, game, error) => {
}
game.active = active;
+ /* If the current turn is a robber placement, and everyone has
+ * discarded, set the limits for where the robber can be placed */
+ if (game.turn.roll === 7) {
+ let move = true;
+ for (let color in game.players) {
+ const discard = game.players[color].mustDiscard;
+ if (discard) {
+ move = false;
+ }
+ }
+ if (move && !game.turn.placedRobber) {
+ game.turn.actions = [ 'place-robber' ];
+ game.turn.limits = { pips: [] };
+ for (let i = 0; i < 19; i++) {
+ if (i === game.robber) {
+ continue;
+ }
+ game.turn.limits.pips.push(i);
+ }
+ }
+ }
+
/* Update the session lastActive clock */
let session;
if (req.session) {
@@ -1117,6 +1228,14 @@ const resetGame = (game) => {
roads: []
};
+ for (let key in game.players) {
+ game.players[key].wheat =
+ game.players[key].sheep =
+ game.players[key].stone =
+ game.players[key].brick =
+ game.players[key].wood = 0;
+ }
+
for (let i = 0; i < layout.corners.length; i++) {
game.placements.corners[i] = {
color: undefined,
@@ -1247,6 +1366,7 @@ const shuffleBoard = (game) => {
* the target pip value to the currently incremeneting
* pip value. */
if (game.tiles[game.tileOrder[target]].type === 'desert') {
+ game.robber = target;
game.pipOrder[target] = 18;
} else {
game.pipOrder[target] = p++;