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");