diff --git a/client/src/Board.js b/client/src/Board.js
index df8aeea..4f29aab 100755
--- a/client/src/Board.js
+++ b/client/src/Board.js
@@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react";
import "./Board.css";
import history from "./history.js";
import Paper from '@material-ui/core/Paper';
+import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
import List from '@material-ui/core/List';
import ListItem from '@material-ui/core/ListItem';
@@ -286,6 +287,24 @@ const Chat = ({ game, promoteGameState }) => {
);
}
+const Action = ({ game, promoteGameState }) => {
+ const actionClick = (event) => {
+ this.setGameState("active").then((state) => {
+ game.state = state;
+ });
+ };
+
+ return (
+ <>
+ { game.state == 'lobby' &&
+
+
+
+ }
+ >
+ );
+}
+
/* This needs to take in a mechanism to declare the
* player's active item in the game */
const Players = ({ game, promoteGameState }) => {
@@ -403,7 +422,10 @@ class Board extends React.Component {
this.randomize = this.randomize.bind(this);
this.throwDice = this.throwDice.bind(this);
this.promoteGameState = this.promoteGameState.bind(this);
+ this.resetGameLoad = this.resetGameLoad.bind(this);
this.loadGame = this.loadGame.bind(this);
+ this.rollDice = this.rollDice.bind(this);
+ this.setGameState = this.setGameState.bind(this);
this.mouse = { x: 0, y: 0 };
this.radius = 0.317;
@@ -426,6 +448,39 @@ class Board extends React.Component {
this.id = (props.router && props.router.params.id) ? props.router.params.id : 0;
}
+ rollDice() {
+ if (this.loadTimer) {
+ window.clearTimeout(this.loadTimer);
+ this.loadTimer = null;
+ }
+
+ return window.fetch(`${base}/api/v1/games/${this.state.game.id}/roll`, {
+ method: "PUT",
+ cache: 'no-cache',
+ credentials: 'same-origin',
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ }).then((res) => {
+ if (res.status > 400) {
+ console.log(res);
+ throw new Error(`Unable to roll dice`);
+ }
+ return res.json();
+ }).then((game) => {
+ console.log (`Dice rolled!`);
+ console.log(game.dice);
+ this.game = game;
+ this.setState({ game: { ...this.state.game, dice: game.dice }} );
+ }).catch((error) => {
+ console.error(error);
+ alert(error);
+ }).then(() => {
+ this.resetGameLoad();
+ return this.game.dice;
+ });
+ }
+
loadGame() {
if (this.loadTimer) {
window.clearTimeout(this.loadTimer);
@@ -433,7 +488,7 @@ class Board extends React.Component {
}
if (this.state.game) {
- // return;
+ //return;
}
window.fetch(`${base}/api/v1/games/${this.state.game.id}`, {
@@ -456,10 +511,18 @@ class Board extends React.Component {
console.error(error);
alert(error);
}).then(() => {
- this.loadTimer = window.setTimeout(this.loadGame, 1000);
+ this.resetGameLoad();
});
}
+ resetGameLoad() {
+ if (this.loadTimer) {
+ window.clearTimeout(this.loadTimer);
+ this.loadTimer = 0;
+ }
+ this.loadTimer = window.setTimeout(this.loadGame, 1000);
+ }
+
promoteGameState(change) {
console.log("Requesting state change: ", change);
@@ -489,7 +552,7 @@ class Board extends React.Component {
console.error(error);
alert(error);
}).then(() => {
- this.loadTimer = window.setTimeout(this.loadGame, 1000);
+ this.resetGameLoad();
});
}
@@ -517,49 +580,92 @@ class Board extends React.Component {
}
}
- throwDice() {
- for (let i = 0; i < 2; i++) {
- dice[i] = {
- pips: Math.ceil(Math.random() * 6),
- angle: Math.random() * Math.PI * 2,
- jitter: (Math.random() - 0.5) * diceSize * 0.125
- }
+ setGameState(state) {
+ if (this.loadTimer) {
+ window.clearTimeout(this.loadTimer);
+ this.loadTimer = null;
}
- window.requestAnimationFrame(this.drawFrame);
- const sum = dice[0].pips + dice[1].pips;
- if (sum === 7) { /* Robber! */
- if (this.state.total > 7) {
- let half = Math.ceil(this.state.total * 0.5);
- this.setState({ total: this.state.total - half});
- while (half) {
- switch (Math.floor(Math.random() * 5)) {
- case 0: if (this.state.wood) { this.setState({ wood: this.state.wood - 1}); half--; } break;
- case 1: if (this.state.sheep) { this.setState({ sheep: this.state.sheep - 1}); half--; } break;
- case 2: if (this.state.stone) { this.setState({ stone: this.state.stone - 1}); half--; } break;
- case 3: if (this.state.brick) { this.setState({ brick: this.state.brick - 1}); half--; } break;
- case 4:
- default: if (this.state.wheat) { this.setState({ wheat: this.state.wheat - 1}); half--; } break;
+ return window.fetch(`${base}/api/v1/games/${this.state.game.id}/state/${state}`, {
+ method: "PUT",
+ cache: 'no-cache',
+ credentials: 'same-origin',
+ headers: {
+ 'Content-Type': 'application/json'
+ }
+ }).then((res) => {
+ if (res.status > 400) {
+ console.log(res);
+ throw new Error(`Unable to set state to ${state}`);
+ }
+ return res.json();
+ }).then((game) => {
+ console.log (`Game state set to ${game.state}!`);
+ this.game = game;
+ this.setState({ game: { ...this.state.game, state: game.state }} );
+ }).catch((error) => {
+ console.error(error);
+ alert(error);
+ }).then(() => {
+ this.resetGameLoad();
+ return this.game.state;
+ });
+ }
+
+ throwDice() {
+ dice[0].pips = dice[1].pips = 0;
+
+ return this.rollDice().then((roll) => {
+ roll.forEach((value, index) => {
+ dice[index] = {
+ pips: value,
+ angle: Math.random() * Math.PI * 2,
+ jitter: (Math.random() - 0.5) * diceSize * 0.125
+ };
+ });
+
+ window.requestAnimationFrame(this.drawFrame);
+
+ if (this.game.state == 'lobby') {
+ return;
+ }
+
+ const sum = dice[0].pips + dice[1].pips;
+ if (sum === 7) { /* Robber! */
+ if (this.state.total > 7) {
+ let half = Math.ceil(this.state.total * 0.5);
+ this.setState({ total: this.state.total - half});
+ while (half) {
+ switch (Math.floor(Math.random() * 5)) {
+ case 0: if (this.state.wood) { this.setState({ wood: this.state.wood - 1}); half--; } break;
+ case 1: if (this.state.sheep) { this.setState({ sheep: this.state.sheep - 1}); half--; } break;
+ case 2: if (this.state.stone) { this.setState({ stone: this.state.stone - 1}); half--; } break;
+ case 3: if (this.state.brick) { this.setState({ brick: this.state.brick - 1}); half--; } break;
+ case 4:
+ default: if (this.state.wheat) { this.setState({ wheat: this.state.wheat - 1}); half--; } break;
+ }
}
}
+ } else {
+ this.tiles.forEach((tile) => {
+ if (tile.pip.roll !== sum) {
+ return;
+ }
+ this.setState({ [tile.type]: this.state[tile.type] + 1});
+ this.setState({ total: this.state.total + 1 });
+ });
}
- } else {
- this.tiles.forEach((tile) => {
- if (tile.pip.roll !== sum) {
- return;
- }
- this.setState({ [tile.type]: this.state[tile.type] + 1});
- this.setState({ total: this.state.total + 1 });
- });
- }
- this.setState({
- total: this.state.total,
- wood: this.state.wood,
- sheep: this.state.sheep,
- stone: this.state.stone,
- brick: this.state.brick,
- wheat: this.state.wheat
+ this.setState({
+ total: this.state.total,
+ wood: this.state.wood,
+ sheep: this.state.sheep,
+ stone: this.state.stone,
+ brick: this.state.brick,
+ wheat: this.state.wheat
+ });
+ }).catch((error) => {
+ console.error(error);
});
}
@@ -760,17 +866,20 @@ class Board extends React.Component {
ctx.fillStyle = "rgba(128, 128, 0, 0.125)";
ctx.strokeStyle = "rgba(255, 255, 0, 0.5)";
- const roll = dice[0].pips + dice[1].pips;
- if (roll) this.tiles.forEach((tile) => {
- if (tile.pip.roll === roll) {
- ctx.save();
- ctx.beginPath();
- ctx.arc(tile.pos.x, tile.pos.y, tileHeight * 0.5, 0, Math.PI * 2);
- ctx.fill();
- ctx.stroke();
- ctx.restore();
- }
- });
+
+ if (this.game.state != 'lobby') {
+ const roll = dice[0].pips + dice[1].pips;
+ if (roll) this.tiles.forEach((tile) => {
+ if (tile.pip.roll === roll) {
+ ctx.save();
+ ctx.beginPath();
+ ctx.arc(tile.pos.x, tile.pos.y, tileHeight * 0.5, 0, Math.PI * 2);
+ ctx.fill();
+ ctx.stroke();
+ ctx.restore();
+ }
+ });
+ }
if (this.closest.tile) {
ctx.save();
@@ -828,7 +937,7 @@ class Board extends React.Component {
ctx.save();
ctx.translate(tileWidth * -2.5, -tileWidth * 2);
ctx.rotate(Math.PI * -0.25)
-
+
if (dice[0].pips) {
ctx.translate(-0.5 * (diceSize + diceMargin), 0);
this.drawDie(ctx, dice[0]);
@@ -1076,12 +1185,12 @@ class Board extends React.Component {
this.borders = this.game.borders.map((file) => {
return Border(this, file);
});
-
- this.loadTimer = window.setTimeout(this.loadGame, 1000);
}).catch((error) => {
console.error(error);
alert(error);
- })
+ }).then(() => {
+ this.resetGameLoad();
+ });
setTimeout(this.updateDimensions, 1000);
}
@@ -1107,6 +1216,7 @@ class Board extends React.Component {
}
In hand
diff --git a/server/routes/games.js b/server/routes/games.js
index 7dc3922..7818443 100755
--- a/server/routes/games.js
+++ b/server/routes/games.js
@@ -99,6 +99,43 @@ for (let i = 0; i < 5; i++) {
const games = {};
+const roll = (game, player) => {
+ if (player == 0) {
+ console.log("No player active; roll has no action");
+ return;
+ }
+
+ switch (game.state) {
+ case "lobby":
+ if (game.players[player].order) {
+ console.log(`Player ${player} already rolled for order.`);
+ return;
+ }
+ game.dice = [ Math.ceil(Math.random() * 6) ];
+ game.players[player].order = game.dice[0];
+ const message = `${player} rolled ${game.dice[0]} for play order.`;
+ game.chat.push({ date: Date.now(), message: message });
+ console.log(message);
+ return;
+ }
+}
+
+router.put("/:id/:action", (req, res) => {
+ console.log(`PUT games/${req.params.id}/${req.params.action}`);
+ if (!req.params.action in games) {
+ const error = `Game not found: ${req.params.id}`;
+ return res.status(404).send(error);
+ }
+ const game = games[req.params.id];
+ switch (req.params.action) {
+ case "roll":
+ roll(game, req.session.activePlayer);
+ break;
+ }
+
+ return sendGame(res, req, game);
+})
+
router.get("/:id", (req, res/*, next*/) => {
console.log("GET games/" + req.params.id);
if (req.params.id in games) {
diff --git a/server/routes/users.js b/server/routes/users.js
index 9eef075..a58cd74 100755
--- a/server/routes/users.js
+++ b/server/routes/users.js
@@ -15,15 +15,14 @@ require("../db/users.js").then(function(db) {
router.get("/", function(req, res/*, next*/) {
console.log("/users/");
- return getSessionUser(req).then(function(user) {
+ return getSessionUser(req).then((user) => {
return res.status(200).send(user);
- }).catch(function(error) {
+ }).catch((error) => {
console.log("User not logged in: " + error);
return res.status(200).send({});
});
});
-
router.put("/password", function(req, res) {
console.log("/users/password");