1
0

Rolling for game order working

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-02-03 15:45:02 -08:00
parent 22156373e0
commit 8cd903afc5
4 changed files with 253 additions and 23 deletions

View File

@ -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 > * {

View File

@ -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">

View File

@ -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;

View File

@ -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++;