Rolling for game order working
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
22156373e0
commit
8cd903afc5
@ -8,6 +8,53 @@
|
|||||||
background-image: url("./assets/tabletop.png");
|
background-image: url("./assets/tabletop.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.GameOrder {
|
||||||
|
display: flex;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
top: 0;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
background: rgba(0,0,0,0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
.GameOrder .Title {
|
||||||
|
align-self: center;
|
||||||
|
padding: 2px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GameOrder .PlayerList {
|
||||||
|
padding: 0.5em;
|
||||||
|
background-color:rgba(224, 224, 224);
|
||||||
|
margin: 0.5em 0;
|
||||||
|
}
|
||||||
|
.GameOrder > * {
|
||||||
|
width: 20em;
|
||||||
|
display: inline-flex;
|
||||||
|
padding: 0.5em;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GameOrder .PlayerColor {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GameOrder .GameOrderPlayer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 100%;
|
||||||
|
align-items: center;
|
||||||
|
padding: 2px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.GameOrderPlayer > * {
|
||||||
|
margin: 0 0.25em;
|
||||||
|
}
|
||||||
|
|
||||||
.Display {
|
.Display {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -42,7 +89,6 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
opacity: 0.7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.Stack {
|
.Stack {
|
||||||
@ -81,7 +127,6 @@
|
|||||||
max-width: 40vw;
|
max-width: 40vw;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
opacity: 0.7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.Game > * {
|
.Game > * {
|
||||||
|
@ -72,14 +72,14 @@ const useStyles = makeStyles((theme) => ({
|
|||||||
|
|
||||||
const Dice = ({ pips }) => {
|
const Dice = ({ pips }) => {
|
||||||
let name;
|
let name;
|
||||||
switch (pips) {
|
switch (pips.toString()) {
|
||||||
case 1: name = 'one'; break;
|
case '1': name = 'one'; break;
|
||||||
case 2: name = 'two'; break;
|
case '2': name = 'two'; break;
|
||||||
case 3: name = 'three'; break;
|
case '3': name = 'three'; break;
|
||||||
case 4: name = 'four'; break;
|
case '4': name = 'four'; break;
|
||||||
case 5: name = 'five'; break;
|
case '5': name = 'five'; break;
|
||||||
default:
|
default:
|
||||||
case 6: name = 'six'; break;
|
case '6': name = 'six'; break;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<img alt={name} className="Dice" src={`${assetsPath}/dice-six-faces-${name}.svg`}/>
|
<img alt={name} className="Dice" src={`${assetsPath}/dice-six-faces-${name}.svg`}/>
|
||||||
@ -271,6 +271,61 @@ const StartButton = ({ table }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const GameOrder = ({table}) => {
|
||||||
|
|
||||||
|
const rollClick = (event) => {
|
||||||
|
table.throwDice();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!table.game) {
|
||||||
|
return (<></>);
|
||||||
|
}
|
||||||
|
|
||||||
|
let players = [];
|
||||||
|
for (let color in table.game.players) {
|
||||||
|
const item = table.game.players[color],
|
||||||
|
name = getPlayerName(table.game.sessions, color);
|
||||||
|
if (name) {
|
||||||
|
if (!item.orderRoll) {
|
||||||
|
item.orderRoll = 0;
|
||||||
|
}
|
||||||
|
players.push({ name: name, color: color, ...item });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
players.sort((A, B) => {
|
||||||
|
if (A.order === B.order) {
|
||||||
|
if (A.orderRoll === B.orderRoll) {
|
||||||
|
return A.name.localeCompare(B.name);
|
||||||
|
}
|
||||||
|
return B.orderRoll - A.orderRoll;
|
||||||
|
}
|
||||||
|
return B.order - A.order;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(players);
|
||||||
|
players = players.map(item =>
|
||||||
|
<div className="GameOrderPlayer" key={`player-${item.color}`}>
|
||||||
|
<PlayerColor color={item.color}/>
|
||||||
|
<div>{item.order+1}. {item.name}</div>
|
||||||
|
{ item.orderRoll !== 0 && <>rolled <Dice pips={item.orderRoll}/>.</> }
|
||||||
|
{ item.orderRoll === 0 && <>has not rolled yet.</>}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="GameOrder">
|
||||||
|
{ table.game && <Paper>
|
||||||
|
<div className="Title">Game Order</div>
|
||||||
|
<div className="PlayerList">
|
||||||
|
{ players }
|
||||||
|
</div>
|
||||||
|
<Button disabled={table.game.order !== 0} onClick={rollClick}>Roll Dice</Button>
|
||||||
|
</Paper> }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const Action = ({ table }) => {
|
const Action = ({ table }) => {
|
||||||
const newTableClick = (event) => {
|
const newTableClick = (event) => {
|
||||||
return table.shuffleTable();
|
return table.shuffleTable();
|
||||||
@ -299,8 +354,6 @@ const Action = ({ table }) => {
|
|||||||
<StartButton table={table}/>
|
<StartButton table={table}/>
|
||||||
<Button disabled={!table.game.color} onClick={newTableClick}>New table</Button>
|
<Button disabled={!table.game.color} onClick={newTableClick}>New table</Button>
|
||||||
<Button disabled={table.game.color ? true : false} onClick={() => {table.setState({ pickName: true})}}>Change name</Button> </> }
|
<Button disabled={table.game.color ? true : false} onClick={() => {table.setState({ pickName: true})}}>Change name</Button> </> }
|
||||||
{ table.game.state === 'game-order' &&
|
|
||||||
<Button disabled={table.game.order !== 0} onClick={rollClick}>Roll Dice</Button> }
|
|
||||||
{ table.game.state === 'active' && <>
|
{ table.game.state === 'active' && <>
|
||||||
<Button onClick={rollClick}>Roll Dice</Button>
|
<Button onClick={rollClick}>Roll Dice</Button>
|
||||||
<Button disabled onClick={passClick}>Pass Turn</Button>
|
<Button disabled onClick={passClick}>Pass Turn</Button>
|
||||||
@ -952,7 +1005,7 @@ class Table extends React.Component {
|
|||||||
const game = this.state.game;
|
const game = this.state.game;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="Table" ref={el => this.el = el}>
|
<div className="Table">
|
||||||
<Board game={game}/>
|
<Board game={game}/>
|
||||||
{ game && <div className={'Game ' + game.state}>
|
{ game && <div className={'Game ' + game.state}>
|
||||||
<Paper className="Message">{ this.state.message }</Paper>
|
<Paper className="Message">{ this.state.message }</Paper>
|
||||||
@ -963,8 +1016,11 @@ class Table extends React.Component {
|
|||||||
<Action table={this}/>
|
<Action table={this}/>
|
||||||
</> }
|
</> }
|
||||||
</div> }
|
</div> }
|
||||||
|
{ game && game.state === 'game-order' &&
|
||||||
|
<GameOrder table={this}/>
|
||||||
|
}
|
||||||
|
|
||||||
<div className="Cards" ref={el => this.cards = el}>
|
<div className="Cards">
|
||||||
{ game && game.state === "active" && <>
|
{ game && game.state === "active" && <>
|
||||||
<div>In hand</div>
|
<div>In hand</div>
|
||||||
<div className="Hand">
|
<div className="Hand">
|
||||||
|
@ -15,6 +15,7 @@ const express = require("express"),
|
|||||||
|
|
||||||
require("./console-line.js"); /* Monkey-patch console.log with line numbers */
|
require("./console-line.js"); /* Monkey-patch console.log with line numbers */
|
||||||
|
|
||||||
|
|
||||||
const frontendPath = config.get("frontendPath").replace(/\/$/, "") + "/",
|
const frontendPath = config.get("frontendPath").replace(/\/$/, "") + "/",
|
||||||
serverConfig = config.get("server");
|
serverConfig = config.get("server");
|
||||||
|
|
||||||
@ -46,8 +47,9 @@ app.use(bodyParser.urlencoded({
|
|||||||
* This runs before after cookie parsing, but before routes. If we set
|
* This runs before after cookie parsing, but before routes. If we set
|
||||||
* immediate: true on the morgan options, it happens before cookie parsing
|
* immediate: true on the morgan options, it happens before cookie parsing
|
||||||
* */
|
* */
|
||||||
|
const logging = false;
|
||||||
|
|
||||||
morgan.token('remote-user', function (req) {
|
if (logging) morgan.token('remote-user', function (req) {
|
||||||
return req.user ? req.user.username : "N/A";
|
return req.user ? req.user.username : "N/A";
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -56,7 +58,7 @@ const logSkipPaths = new RegExp("^" + basePath + "(" + [
|
|||||||
".*thumbs\\/",
|
".*thumbs\\/",
|
||||||
"bower_components",
|
"bower_components",
|
||||||
].join(")|(") + ")");
|
].join(")|(") + ")");
|
||||||
app.use(morgan('common', {
|
if (logging) app.use(morgan('common', {
|
||||||
skip: function (req) {
|
skip: function (req) {
|
||||||
return logSkipPaths.exec(req.originalUrl);
|
return logSkipPaths.exec(req.originalUrl);
|
||||||
}
|
}
|
||||||
@ -276,6 +278,12 @@ app.use(basePath, index);
|
|||||||
app.set("port", serverConfig.port);
|
app.set("port", serverConfig.port);
|
||||||
|
|
||||||
const server = require("http").createServer(app);
|
const server = require("http").createServer(app);
|
||||||
|
process.on('SIGINT', () => {
|
||||||
|
server.close(() => {
|
||||||
|
console.log("Gracefully shutting down from SIGINT (Ctrl-C)");
|
||||||
|
process.exit(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
require("./db/games").then(function(db) {
|
require("./db/games").then(function(db) {
|
||||||
gameDB = db;
|
gameDB = db;
|
||||||
|
@ -99,6 +99,90 @@ for (let i = 0; i < 5; i++) {
|
|||||||
|
|
||||||
const games = {};
|
const games = {};
|
||||||
|
|
||||||
|
const processTies = (players) => {
|
||||||
|
players.sort((A, B) => {
|
||||||
|
if (A.order === B.order) {
|
||||||
|
return B.orderRoll - A.orderRoll;
|
||||||
|
}
|
||||||
|
return A.order - B.order;
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Sort the players into buckets based on their
|
||||||
|
* order, and their current roll. If a resulting
|
||||||
|
* roll array has more than one element, then there
|
||||||
|
* is a tie that must be resolved */
|
||||||
|
|
||||||
|
let slots = [];
|
||||||
|
players.forEach(player => {
|
||||||
|
if (!slots[player.order]) {
|
||||||
|
slots[player.order] = [];
|
||||||
|
}
|
||||||
|
if (!(player.orderRoll in slots[player.order])) {
|
||||||
|
slots[player.order][player.orderRoll] = [];
|
||||||
|
}
|
||||||
|
slots[player.order][player.orderRoll].push(player);
|
||||||
|
});
|
||||||
|
|
||||||
|
let ties = false, order = 0;
|
||||||
|
slots.forEach((slot) => {
|
||||||
|
slot.forEach(pips => {
|
||||||
|
if (pips.length !== 1) {
|
||||||
|
ties = true;
|
||||||
|
pips.forEach(player => {
|
||||||
|
player.orderRoll = 0;
|
||||||
|
player.order = order;
|
||||||
|
player.orderStatus = `Tied for ${order}`;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
pips[0].order = order;
|
||||||
|
pips[0].orderStatus = `Placed in ${order}`;
|
||||||
|
}
|
||||||
|
order += pips.length
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
return !ties;
|
||||||
|
}
|
||||||
|
|
||||||
|
const processGameOrder = (game, player, dice) => {
|
||||||
|
let message;
|
||||||
|
|
||||||
|
console.log(`rolled ${dice}`);
|
||||||
|
player.orderRoll = dice;
|
||||||
|
|
||||||
|
let players = [];
|
||||||
|
|
||||||
|
let doneRolling = true;
|
||||||
|
|
||||||
|
for (let key in game.players) {
|
||||||
|
const tmp = game.players[key];
|
||||||
|
if (tmp.status === 'Not active') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!tmp.orderRoll) {
|
||||||
|
doneRolling = false;
|
||||||
|
}
|
||||||
|
tmp.color = key;
|
||||||
|
players.push(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If 'doneRolling' is TRUE then everyone has rolled */
|
||||||
|
if (doneRolling) {
|
||||||
|
if (processTies(players)) {
|
||||||
|
message = `Player order set to ${players.map(player => player.color).join(',')}.`;
|
||||||
|
game.chat.push({ date: Date.now(), message: message });
|
||||||
|
game.state = 'active'
|
||||||
|
message = `Game has started!`;
|
||||||
|
} else {
|
||||||
|
message = `There are still ties for player order!`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (message) {
|
||||||
|
game.chat.push({ date: Date.now(), message: message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const roll = (game, session) => {
|
const roll = (game, session) => {
|
||||||
let message, error;
|
let message, error;
|
||||||
|
|
||||||
@ -110,14 +194,18 @@ const roll = (game, session) => {
|
|||||||
error = `Rolling dice in the lobby is not allowed!`;
|
error = `Rolling dice in the lobby is not allowed!`;
|
||||||
|
|
||||||
case "game-order":
|
case "game-order":
|
||||||
if (player.order) {
|
if (!player) {
|
||||||
error = `Player ${name} already rolled for order.`;
|
error = `This player is not active!`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (player.order || player.orderRoll) {
|
||||||
|
error = `Player ${name} has already rolled for player order.`;
|
||||||
|
// break;
|
||||||
|
}
|
||||||
|
|
||||||
game.dice = [ Math.ceil(Math.random() * 6) ];
|
game.dice = [ Math.ceil(Math.random() * 6) ];
|
||||||
player.order = game.dice[0];
|
processGameOrder(game, player, game.dice[0]);
|
||||||
message = `${name} rolled ${game.dice[0]} for play order.`;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "active":
|
case "active":
|
||||||
@ -231,12 +319,45 @@ const clearPlayer = (player) => {
|
|||||||
player.status = 'Not active';
|
player.status = 'Not active';
|
||||||
player.lastActive = 0;
|
player.lastActive = 0;
|
||||||
player.order = 0;
|
player.order = 0;
|
||||||
|
delete player.orderRoll;
|
||||||
|
delete player.orderStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
const adminActions = (game, action, value) => {
|
const adminActions = (game, action, value) => {
|
||||||
|
let color, player;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
|
case "state":
|
||||||
|
switch (value) {
|
||||||
|
case 'game-order':
|
||||||
|
for (let key in game.players) {
|
||||||
|
game.players[key].order = 0;
|
||||||
|
delete game.players[key].orderRoll;
|
||||||
|
delete game.players[key].orderStatus;
|
||||||
|
}
|
||||||
|
game.state = 'game-order';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "roll":
|
||||||
|
let dice = value.replace(/.*-/, '');
|
||||||
|
switch (value.replace(/-.*/, '')) {
|
||||||
|
case 'orange': color = 'O'; break;
|
||||||
|
case 'red': color = 'R'; break;
|
||||||
|
case 'blue': color = 'B'; break;
|
||||||
|
case 'white': color = 'W'; break;
|
||||||
|
}
|
||||||
|
if (!color) {
|
||||||
|
return `Unable to find player ${value.replace(/-.*/, '')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
player = game.players[color];
|
||||||
|
processGameOrder(game, player, dice);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case "kick":
|
case "kick":
|
||||||
let color;
|
|
||||||
switch (value) {
|
switch (value) {
|
||||||
case 'orange': color = 'O'; break;
|
case 'orange': color = 'O'; break;
|
||||||
case 'red': color = 'R'; break;
|
case 'red': color = 'R'; break;
|
||||||
@ -247,7 +368,7 @@ const adminActions = (game, action, value) => {
|
|||||||
return `Unable to find player ${value}`
|
return `Unable to find player ${value}`
|
||||||
}
|
}
|
||||||
|
|
||||||
const player = game.players[color];
|
player = game.players[color];
|
||||||
for (let id in game.sessions) {
|
for (let id in game.sessions) {
|
||||||
const session = game.sessions[id];
|
const session = game.sessions[id];
|
||||||
if (session.player !== player) {
|
if (session.player !== player) {
|
||||||
@ -459,7 +580,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
|
|
||||||
router.get("/:id", async (req, res/*, next*/) => {
|
router.get("/:id", async (req, res/*, next*/) => {
|
||||||
const { id } = req.params;
|
const { id } = req.params;
|
||||||
console.log("GET games/" + id);
|
// console.log("GET games/" + id);
|
||||||
|
|
||||||
let game = await loadGame(id);
|
let game = await loadGame(id);
|
||||||
if (game) {
|
if (game) {
|
||||||
@ -684,7 +805,7 @@ const shuffleBoard = (game) => {
|
|||||||
* pip value to the robber (18) otherwise set
|
* pip value to the robber (18) otherwise set
|
||||||
* the target pip value to the currently incremeneting
|
* the target pip value to the currently incremeneting
|
||||||
* pip value. */
|
* pip value. */
|
||||||
if (game.tiles[game.tileOrder[target]].type === 'robber') {
|
if (game.tiles[game.tileOrder[target]].type === 'desert') {
|
||||||
game.pipOrder[target] = 18;
|
game.pipOrder[target] = 18;
|
||||||
} else {
|
} else {
|
||||||
game.pipOrder[target] = p++;
|
game.pipOrder[target] = p++;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user