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");
|
||||
}
|
||||
|
||||
.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: inline-block;
|
||||
position: absolute;
|
||||
@ -42,7 +89,6 @@
|
||||
box-sizing: border-box;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.Stack {
|
||||
@ -81,7 +127,6 @@
|
||||
max-width: 40vw;
|
||||
z-index: 100;
|
||||
padding: 0.5em;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.Game > * {
|
||||
|
@ -72,14 +72,14 @@ const useStyles = makeStyles((theme) => ({
|
||||
|
||||
const Dice = ({ pips }) => {
|
||||
let name;
|
||||
switch (pips) {
|
||||
case 1: name = 'one'; break;
|
||||
case 2: name = 'two'; break;
|
||||
case 3: name = 'three'; break;
|
||||
case 4: name = 'four'; break;
|
||||
case 5: name = 'five'; break;
|
||||
switch (pips.toString()) {
|
||||
case '1': name = 'one'; break;
|
||||
case '2': name = 'two'; break;
|
||||
case '3': name = 'three'; break;
|
||||
case '4': name = 'four'; break;
|
||||
case '5': name = 'five'; break;
|
||||
default:
|
||||
case 6: name = 'six'; break;
|
||||
case '6': name = 'six'; break;
|
||||
}
|
||||
return (
|
||||
<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 newTableClick = (event) => {
|
||||
return table.shuffleTable();
|
||||
@ -299,8 +354,6 @@ const Action = ({ table }) => {
|
||||
<StartButton table={table}/>
|
||||
<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> </> }
|
||||
{ table.game.state === 'game-order' &&
|
||||
<Button disabled={table.game.order !== 0} onClick={rollClick}>Roll Dice</Button> }
|
||||
{ table.game.state === 'active' && <>
|
||||
<Button onClick={rollClick}>Roll Dice</Button>
|
||||
<Button disabled onClick={passClick}>Pass Turn</Button>
|
||||
@ -952,7 +1005,7 @@ class Table extends React.Component {
|
||||
const game = this.state.game;
|
||||
|
||||
return (
|
||||
<div className="Table" ref={el => this.el = el}>
|
||||
<div className="Table">
|
||||
<Board game={game}/>
|
||||
{ game && <div className={'Game ' + game.state}>
|
||||
<Paper className="Message">{ this.state.message }</Paper>
|
||||
@ -963,8 +1016,11 @@ class Table extends React.Component {
|
||||
<Action table={this}/>
|
||||
</> }
|
||||
</div> }
|
||||
{ game && game.state === 'game-order' &&
|
||||
<GameOrder table={this}/>
|
||||
}
|
||||
|
||||
<div className="Cards" ref={el => this.cards = el}>
|
||||
<div className="Cards">
|
||||
{ game && game.state === "active" && <>
|
||||
<div>In hand</div>
|
||||
<div className="Hand">
|
||||
|
@ -15,6 +15,7 @@ const express = require("express"),
|
||||
|
||||
require("./console-line.js"); /* Monkey-patch console.log with line numbers */
|
||||
|
||||
|
||||
const frontendPath = config.get("frontendPath").replace(/\/$/, "") + "/",
|
||||
serverConfig = config.get("server");
|
||||
|
||||
@ -46,8 +47,9 @@ app.use(bodyParser.urlencoded({
|
||||
* This runs before after cookie parsing, but before routes. If we set
|
||||
* 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";
|
||||
});
|
||||
|
||||
@ -56,7 +58,7 @@ const logSkipPaths = new RegExp("^" + basePath + "(" + [
|
||||
".*thumbs\\/",
|
||||
"bower_components",
|
||||
].join(")|(") + ")");
|
||||
app.use(morgan('common', {
|
||||
if (logging) app.use(morgan('common', {
|
||||
skip: function (req) {
|
||||
return logSkipPaths.exec(req.originalUrl);
|
||||
}
|
||||
@ -276,6 +278,12 @@ app.use(basePath, index);
|
||||
app.set("port", serverConfig.port);
|
||||
|
||||
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) {
|
||||
gameDB = db;
|
||||
|
@ -99,6 +99,90 @@ for (let i = 0; i < 5; i++) {
|
||||
|
||||
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) => {
|
||||
let message, error;
|
||||
|
||||
@ -110,14 +194,18 @@ const roll = (game, session) => {
|
||||
error = `Rolling dice in the lobby is not allowed!`;
|
||||
|
||||
case "game-order":
|
||||
if (player.order) {
|
||||
error = `Player ${name} already rolled for order.`;
|
||||
if (!player) {
|
||||
error = `This player is not active!`;
|
||||
break;
|
||||
}
|
||||
|
||||
if (player.order || player.orderRoll) {
|
||||
error = `Player ${name} has already rolled for player order.`;
|
||||
// break;
|
||||
}
|
||||
|
||||
game.dice = [ Math.ceil(Math.random() * 6) ];
|
||||
player.order = game.dice[0];
|
||||
message = `${name} rolled ${game.dice[0]} for play order.`;
|
||||
processGameOrder(game, player, game.dice[0]);
|
||||
break;
|
||||
|
||||
case "active":
|
||||
@ -231,12 +319,45 @@ const clearPlayer = (player) => {
|
||||
player.status = 'Not active';
|
||||
player.lastActive = 0;
|
||||
player.order = 0;
|
||||
delete player.orderRoll;
|
||||
delete player.orderStatus;
|
||||
}
|
||||
|
||||
const adminActions = (game, action, value) => {
|
||||
let color, player;
|
||||
|
||||
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":
|
||||
let color;
|
||||
switch (value) {
|
||||
case 'orange': color = 'O'; break;
|
||||
case 'red': color = 'R'; break;
|
||||
@ -247,7 +368,7 @@ const adminActions = (game, action, value) => {
|
||||
return `Unable to find player ${value}`
|
||||
}
|
||||
|
||||
const player = game.players[color];
|
||||
player = game.players[color];
|
||||
for (let id in game.sessions) {
|
||||
const session = game.sessions[id];
|
||||
if (session.player !== player) {
|
||||
@ -459,7 +580,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
|
||||
router.get("/:id", async (req, res/*, next*/) => {
|
||||
const { id } = req.params;
|
||||
console.log("GET games/" + id);
|
||||
// console.log("GET games/" + id);
|
||||
|
||||
let game = await loadGame(id);
|
||||
if (game) {
|
||||
@ -684,7 +805,7 @@ const shuffleBoard = (game) => {
|
||||
* pip value to the robber (18) otherwise set
|
||||
* the target pip value to the currently incremeneting
|
||||
* pip value. */
|
||||
if (game.tiles[game.tileOrder[target]].type === 'robber') {
|
||||
if (game.tiles[game.tileOrder[target]].type === 'desert') {
|
||||
game.pipOrder[target] = 18;
|
||||
} else {
|
||||
game.pipOrder[target] = p++;
|
||||
|
Loading…
x
Reference in New Issue
Block a user