Longest road calculations are now correct for each segment. Visualize longest road
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
27cdcda2d4
commit
433eff8473
@ -25,7 +25,7 @@
|
|||||||
|
|
||||||
.Tile.Active {
|
.Tile.Active {
|
||||||
z-index: 10; /* Above non-Active Tile, below Road and Corner */
|
z-index: 10; /* Above non-Active Tile, below Road and Corner */
|
||||||
filter: drop-shadow(8px 8px 12px black);
|
filter: drop-shadow(0px 0px 12px black);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Border {
|
.Border {
|
||||||
@ -59,7 +59,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.Corner {
|
.Corner {
|
||||||
filter: drop-shadow(2.5px 2.5px 1.5px rgba(0, 0, 0, 0.75));
|
filter: drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.75));
|
||||||
z-index: 20; /* Above Tile, below Road */
|
z-index: 20; /* Above Tile, below Road */
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -167,7 +167,42 @@
|
|||||||
.Road-Shape:hover {
|
.Road-Shape:hover {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
filter: brightness(150%);
|
filter: brightness(150%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Road.LongestRoad .Road-Shape {
|
||||||
|
filter: brightness(135%);
|
||||||
|
transform: scale(1.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Road[data-longest="1"],
|
||||||
|
.Road[data-longest="2"],
|
||||||
|
.Road[data-longest="3"],
|
||||||
|
.Road[data-longest="4"] {
|
||||||
|
filter: drop-shadow(0px 0px 2.5px black);
|
||||||
|
}
|
||||||
|
|
||||||
|
.Road[data-longest="5"] {
|
||||||
|
filter: drop-shadow(0px 0px 5px black);
|
||||||
|
}
|
||||||
|
.Road[data-longest="6"] {
|
||||||
|
filter: drop-shadow(0px 0px 6px black);
|
||||||
|
}
|
||||||
|
.Road[data-longest="7"] {
|
||||||
|
filter: drop-shadow(0px 0px 7px black);
|
||||||
|
}
|
||||||
|
.Road[data-longest="8"] {
|
||||||
|
filter: drop-shadow(0px 0px 8px black);
|
||||||
|
}
|
||||||
|
.Road[data-longest="9"] {
|
||||||
|
filter: drop-shadow(0px 0px 9px black);
|
||||||
|
}
|
||||||
|
.Road[data-longest="10"],
|
||||||
|
.Road[data-longest="11"],
|
||||||
|
.Road[data-longest="12"],
|
||||||
|
.Road[data-longest="13"],
|
||||||
|
.Road[data-longest="14"],
|
||||||
|
.Road[data-longest="15"] {
|
||||||
|
filter: drop-shadow(0px 0px 10px black);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Board .Selected {
|
.Board .Selected {
|
||||||
|
@ -420,6 +420,16 @@ const Board = ({ table, game }) => {
|
|||||||
if (!road.color) {
|
if (!road.color) {
|
||||||
el.removeAttribute('data-color');
|
el.removeAttribute('data-color');
|
||||||
} else {
|
} else {
|
||||||
|
if (road.longestRoad) {
|
||||||
|
if (road.longestRoad === game.longestRoadLength) {
|
||||||
|
el.classList.add('LongestRoad');
|
||||||
|
} else {
|
||||||
|
el.classList.remove('LongestRoad');
|
||||||
|
}
|
||||||
|
el.setAttribute('data-longest', road.longestRoad);
|
||||||
|
} else {
|
||||||
|
el.removeAttribute('data-longest');
|
||||||
|
}
|
||||||
el.setAttribute('data-color', road.color);
|
el.setAttribute('data-color', road.color);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -494,7 +504,9 @@ const Board = ({ table, game }) => {
|
|||||||
return (
|
return (
|
||||||
<div className="Board">
|
<div className="Board">
|
||||||
<div className="BoardBox">
|
<div className="BoardBox">
|
||||||
|
<div className="Borders" disabled>
|
||||||
{ borders }
|
{ borders }
|
||||||
|
</div>
|
||||||
{ game && <>
|
{ game && <>
|
||||||
<div className="Tiles" disabled>
|
<div className="Tiles" disabled>
|
||||||
{ tiles }
|
{ tiles }
|
||||||
|
@ -474,6 +474,9 @@ const Players = ({ table }) => {
|
|||||||
let toggleText;
|
let toggleText;
|
||||||
if (name) {
|
if (name) {
|
||||||
toggleText = `${name} has ${item.points} VP`;
|
toggleText = `${name} has ${item.points} VP`;
|
||||||
|
if (item.unplayed) {
|
||||||
|
toggleText += ` and ${item.unplayed} unplayed DCs`;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
toggleText = "Available";
|
toggleText = "Available";
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,10 @@ import Button from '@material-ui/core/Button';
|
|||||||
import Resource from './Resource.js';
|
import Resource from './Resource.js';
|
||||||
|
|
||||||
const ViewCard = ({table, card}) => {
|
const ViewCard = ({table, card}) => {
|
||||||
|
if (!table.game.player) {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
|
||||||
const playCard = (event) => {
|
const playCard = (event) => {
|
||||||
table.playCard(card);
|
table.playCard(card);
|
||||||
}
|
}
|
||||||
@ -31,10 +35,30 @@ const ViewCard = ({table, card}) => {
|
|||||||
vp: <><b>1</b> victory point.
|
vp: <><b>1</b> victory point.
|
||||||
<p>You only reveal your victory point cards when the game is over, either
|
<p>You only reveal your victory point cards when the game is over, either
|
||||||
when you or an opponent reaches <b>10+</b> victory points on their turn and declares
|
when you or an opponent reaches <b>10+</b> victory points on their turn and declares
|
||||||
victory!</p></>
|
victory!</p></>,
|
||||||
|
'progress-road-2': <>
|
||||||
|
<p>Play <b>2</b> new roads as if you had just built them.</p>
|
||||||
|
<p>This is still limited by the number of roads you have (a maximum of 15.)</p>
|
||||||
|
<p><b>NOTE:</b> This card is not yet implemented. The server will give you <b>2</b> wood
|
||||||
|
and <b>2</b> brick and we trust you will use them to build <b>2</b> roads.</p>
|
||||||
|
<p>If
|
||||||
|
you do not have enough roads remaining, you may end up with extra resources...
|
||||||
|
but the game is in beta, so... be happy :)
|
||||||
|
</p>
|
||||||
|
<p>As an FYI, you currently have {15 - table.game.player.roads} roads remaining.</p>
|
||||||
|
</>
|
||||||
};
|
};
|
||||||
|
|
||||||
let description = descriptions[card.type];
|
let description;
|
||||||
|
if (card.type == 'progress') {
|
||||||
|
description = descriptions[`${card.type}-${card.card}`];
|
||||||
|
} else {
|
||||||
|
description = descriptions[card.type];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (description === undefined) {
|
||||||
|
console.log('No description for ', card);
|
||||||
|
}
|
||||||
|
|
||||||
let canPlay = false;
|
let canPlay = false;
|
||||||
if (card.type === 'vp') {
|
if (card.type === 'vp') {
|
||||||
|
@ -16,8 +16,17 @@ const Winner = ({table, color}) => {
|
|||||||
|
|
||||||
const name = getPlayerName(table.game.sessions, color),
|
const name = getPlayerName(table.game.sessions, color),
|
||||||
player = table.game.players[color];
|
player = table.game.players[color];
|
||||||
|
let playerCount = 0;
|
||||||
|
for (let key in table.game.players) {
|
||||||
|
if (table.game.players[key].status !== 'Not active') {
|
||||||
|
playerCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let description = <>Congratulations, <b>{name}</b>!</>;
|
let description = <>Congratulations, <b>{name}</b>!
|
||||||
|
They have won the game! The game played
|
||||||
|
for {Math.floor(table.game.turns / playerCount)} turns.
|
||||||
|
</>;
|
||||||
for (let key in table.game.players) {
|
for (let key in table.game.players) {
|
||||||
if (key === color) {
|
if (key === color) {
|
||||||
continue;
|
continue;
|
||||||
@ -30,6 +39,8 @@ const Winner = ({table, color}) => {
|
|||||||
description = <>{description}<p>{line}</p></>;
|
description = <>{description}<p>{line}</p></>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
description = <>{description}<p>If everyone goes back to the Lobby, you can play again.</p></>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="Winner">
|
<div className="Winner">
|
||||||
<Paper>
|
<Paper>
|
||||||
|
@ -7,6 +7,7 @@ const express = require("express"),
|
|||||||
accessSync = fs.accessSync,
|
accessSync = fs.accessSync,
|
||||||
randomWords = require("random-words");
|
randomWords = require("random-words");
|
||||||
|
|
||||||
|
const { clear } = require("console");
|
||||||
const { corners } = require("./layout.js");
|
const { corners } = require("./layout.js");
|
||||||
const layout = require('./layout.js');
|
const layout = require('./layout.js');
|
||||||
|
|
||||||
@ -854,11 +855,11 @@ const getPrevPlayer = (game, name) => {
|
|||||||
const processCorner = (game, color, cornerIndex, placedCorner) => {
|
const processCorner = (game, color, cornerIndex, placedCorner) => {
|
||||||
/* If this corner is allocated and isn't assigned to the walking color, skip it */
|
/* If this corner is allocated and isn't assigned to the walking color, skip it */
|
||||||
if (placedCorner.color && placedCorner.color !== color) {
|
if (placedCorner.color && placedCorner.color !== color) {
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
/* If this corner is already being walked, skip it */
|
/* If this corner is already being walked, skip it */
|
||||||
if (placedCorner.walking) {
|
if (placedCorner.walking) {
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
placedCorner.walking = true;
|
placedCorner.walking = true;
|
||||||
@ -866,7 +867,18 @@ const processCorner = (game, color, cornerIndex, placedCorner) => {
|
|||||||
let longest = 0;
|
let longest = 0;
|
||||||
layout.corners[cornerIndex].roads.forEach(roadIndex => {
|
layout.corners[cornerIndex].roads.forEach(roadIndex => {
|
||||||
const placedRoad = game.placements.roads[roadIndex];
|
const placedRoad = game.placements.roads[roadIndex];
|
||||||
longest = Math.max(processRoad(game, color, roadIndex, placedRoad), longest);
|
if (placedRoad.walking) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const tmp = processRoad(game, color, roadIndex, placedRoad);
|
||||||
|
longest = Math.max(tmp, longest);
|
||||||
|
/*if (tmp > longest) {
|
||||||
|
longest = tmp;
|
||||||
|
placedCorner.longestRoad = roadIndex;
|
||||||
|
placedCorner.longest
|
||||||
|
}
|
||||||
|
longest = Math.max(
|
||||||
|
*/
|
||||||
});
|
});
|
||||||
|
|
||||||
return longest;
|
return longest;
|
||||||
@ -893,24 +905,26 @@ const buildCornerGraph = (game, color, cornerIndex, placedCorner, set) => {
|
|||||||
const processRoad = (game, color, roadIndex, placedRoad) => {
|
const processRoad = (game, color, roadIndex, placedRoad) => {
|
||||||
/* If this road isn't assigned to the walking color, skip it */
|
/* If this road isn't assigned to the walking color, skip it */
|
||||||
if (placedRoad.color !== color) {
|
if (placedRoad.color !== color) {
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If this road is already being walked, skip it */
|
/* If this road is already being walked, skip it */
|
||||||
if (placedRoad.walking) {
|
if (placedRoad.walking) {
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
placedRoad.walking = true;
|
placedRoad.walking = true;
|
||||||
/* Calculate the longest road branching from both corners */
|
/* Calculate the longest road branching from both corners */
|
||||||
let longest = 0;
|
let roadLength = 1;
|
||||||
layout.roads[roadIndex].corners.forEach(cornerIndex => {
|
layout.roads[roadIndex].corners.forEach(cornerIndex => {
|
||||||
const placedCorner = game.placements.corners[cornerIndex];
|
const placedCorner = game.placements.corners[cornerIndex];
|
||||||
longest = Math.max(processCorner(game, color, cornerIndex, placedCorner), longest);
|
if (placedCorner.walking) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
roadLength += processCorner(game, color, cornerIndex, placedCorner);
|
||||||
});
|
});
|
||||||
placedRoad.longest = 1 + longest;
|
|
||||||
|
|
||||||
return placedRoad.longest;
|
return roadLength;
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildRoadGraph = (game, color, roadIndex, placedRoad, set) => {
|
const buildRoadGraph = (game, color, roadIndex, placedRoad, set) => {
|
||||||
@ -932,27 +946,29 @@ const buildRoadGraph = (game, color, roadIndex, placedRoad, set) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearRoadMarkers = (game) => {
|
const clearRoadWalking = (game) => {
|
||||||
/* Clear out walk markers on roads */
|
/* Clear out walk markers on roads */
|
||||||
layout.roads.forEach((item, itemIndex) => {
|
layout.roads.forEach((item, itemIndex) => {
|
||||||
const placed = game.placements.roads[itemIndex];
|
delete game.placements.roads[itemIndex].walking;
|
||||||
placed.walking = false;
|
|
||||||
placed.longest = 0;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Clear out walk markers on corners */
|
/* Clear out walk markers on corners */
|
||||||
layout.corners.forEach((item, itemIndex) => {
|
layout.corners.forEach((item, itemIndex) => {
|
||||||
const placed = game.placements.corners[itemIndex];
|
delete game.placements.corners[itemIndex].walking;
|
||||||
placed.walking = false;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const calculateRoadLengths = (game, session) => {
|
const calculateRoadLengths = (game, session) => {
|
||||||
clearRoadMarkers(game);
|
clearRoadWalking(game);
|
||||||
|
|
||||||
|
let currentLongest = game.longestRoad,
|
||||||
|
currentLength = currentLongest
|
||||||
|
? game.players[currentLongest].longestRoad
|
||||||
|
: -1;
|
||||||
|
|
||||||
/* Clear out player longest road counts */
|
/* Clear out player longest road counts */
|
||||||
for (let key in game.players) {
|
for (let key in game.players) {
|
||||||
game.players[key].roadLength = 0;
|
game.players[key].length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build a set of connected road graphs. Once all graphs are
|
/* Build a set of connected road graphs. Once all graphs are
|
||||||
@ -975,50 +991,87 @@ const calculateRoadLengths = (game, session) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(graphs);
|
console.log('Graphs A:', graphs);
|
||||||
|
|
||||||
|
clearRoadWalking(game);
|
||||||
|
graphs.forEach(graph => {
|
||||||
|
graph.longestRoad = 0;
|
||||||
|
graph.set.forEach(roadIndex => {
|
||||||
|
const placedRoad = game.placements.roads[roadIndex];
|
||||||
|
clearRoadWalking(game);
|
||||||
|
const length = processRoad(game, placedRoad.color, roadIndex, placedRoad);
|
||||||
|
if (length >= graph.longestRoad) {
|
||||||
|
graph.longestStartSegment = roadIndex;
|
||||||
|
graph.longestRoad = length;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('Graphs B:', graphs);
|
||||||
|
|
||||||
|
console.log('Pre update:', game.placements.roads.filter(road => road.color));
|
||||||
|
|
||||||
|
for (let color in game.players) {
|
||||||
|
if (game.players[color] === 'Not active') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
game.players[color].longestRoad = 0;
|
||||||
|
}
|
||||||
|
|
||||||
let currentLength = game.longestRoad ? game.players[game.longestRoad].roadLength : -1,
|
|
||||||
currentLongest = game.longestRoad;
|
|
||||||
clearRoadMarkers(game);
|
|
||||||
graphs.forEach(graph => {
|
graphs.forEach(graph => {
|
||||||
graph.set.forEach(roadIndex => {
|
graph.set.forEach(roadIndex => {
|
||||||
const placedRoad = game.placements.roads[roadIndex];
|
const placedRoad = game.placements.roads[roadIndex];
|
||||||
clearRoadMarkers(game);
|
clearRoadWalking(game);
|
||||||
const length = processRoad(game, placedRoad.color, roadIndex, placedRoad);
|
const longestRoad = processRoad(game, placedRoad.color, roadIndex, placedRoad);
|
||||||
game.players[placedRoad.color].roadLength =
|
placedRoad.longestRoad = longestRoad;
|
||||||
Math.max(game.players[placedRoad.color].roadLength, length);
|
game.players[placedRoad.color].longestRoad =
|
||||||
|
Math.max(game.players[placedRoad.color].longestRoad, longestRoad);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const checkForTies = false;
|
game.placements.roads.forEach(road => delete road.walking);
|
||||||
if (currentLongest && game.players[currentLongest].roadLength < currentLength) {
|
|
||||||
addChatMessage(game, session, `${getPlayerNameFromColor(game, game.currentLongest)} had their longest road split!`);
|
console.log('Post update:', game.placements.roads.filter(road => road.color));
|
||||||
|
|
||||||
|
let checkForTies = false;
|
||||||
|
|
||||||
|
console.log(currentLongest, currentLength);
|
||||||
|
|
||||||
|
if (currentLongest && game.players[currentLongest].longestRoad < currentLength) {
|
||||||
|
addChatMessage(game, session, `${playerNameFromColor(game, currentLongest)} had their longest road split!`);
|
||||||
checkForTies = true;
|
checkForTies = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let longest = 4, longestPlayers = [];
|
let longestRoad = 4, longestPlayers = [];
|
||||||
for (let key in game.players) {
|
for (let key in game.players) {
|
||||||
if (game.players[key].status === 'Not active') {
|
if (game.players[key].status === 'Not active') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (game.players[key].roadLength > longest) {
|
if (game.players[key].longestRoad > longestRoad) {
|
||||||
longestPlayers = [ key ];
|
longestPlayers = [ key ];
|
||||||
longest = game.players[key].roadLength;
|
longestRoad = game.players[key].longestRoad;
|
||||||
} else if (game.players[key].roadLength == longest && checkForTies) {
|
} else if (game.players[key].longestRoad == longestRoad && checkForTies) {
|
||||||
longestPlayers.push(key);
|
longestPlayers.push(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log({ longestPlayers });
|
||||||
|
|
||||||
if (longestPlayers.length > 0) {
|
if (longestPlayers.length > 0) {
|
||||||
if (longestPlayers.length === 1) {
|
if (longestPlayers.length === 1) {
|
||||||
|
game.longestRoadLength = longestRoad;
|
||||||
if (game.longestRoad !== longestPlayers[0]) {
|
if (game.longestRoad !== longestPlayers[0]) {
|
||||||
game.longestRoad = longestPlayers[0];
|
game.longestRoad = longestPlayers[0];
|
||||||
addChatMessage(game, session, `${playerNameFromColor(game, game.longestRoad)} now has the longest road (${longest})!`);
|
addChatMessage(game, session,
|
||||||
|
`${playerNameFromColor(game, game.longestRoad)} now has the longest ` +
|
||||||
|
`road (${longestRoad})!`);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (checkForTies) {
|
if (checkForTies) {
|
||||||
const names = longestPlayers.map(color => playerNameFromColor(color));
|
game.longestRoadLength = longestRoad;
|
||||||
addChatMessage(game, session, `${names.join(', ')} are tied for longest road (${longest})!`);
|
const names = longestPlayers.map(color => playerNameFromColor(game, color));
|
||||||
|
addChatMessage(game, session, `${names.join(', ')} are tied for longest ` +
|
||||||
|
`road (${longestRoad})!`);
|
||||||
}
|
}
|
||||||
game.longestRoad = null;
|
game.longestRoad = null;
|
||||||
}
|
}
|
||||||
@ -1399,6 +1452,8 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debugChat(game, 'Before trade');
|
||||||
|
|
||||||
/* Transfer goods */
|
/* Transfer goods */
|
||||||
player.gets.forEach(item => {
|
player.gets.forEach(item => {
|
||||||
if (target.name !== 'The bank') {
|
if (target.name !== 'The bank') {
|
||||||
@ -1425,6 +1480,8 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
delete session.player.gives;
|
delete session.player.gives;
|
||||||
delete session.player.gets;
|
delete session.player.gets;
|
||||||
|
|
||||||
|
debugChat(game, 'After trade');
|
||||||
|
|
||||||
game.turn.actions = [];
|
game.turn.actions = [];
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -1538,6 +1595,9 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
cards.push(field);
|
cards.push(field);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
debugChat(game, 'Before steal');
|
||||||
|
|
||||||
if (cards.length === 0) {
|
if (cards.length === 0) {
|
||||||
addChatMessage(game, session, `${playerNameFromColor(game, value)} did not have any cards to steal.`);
|
addChatMessage(game, session, `${playerNameFromColor(game, value)} did not have any cards to steal.`);
|
||||||
game.turn.actions = [];
|
game.turn.actions = [];
|
||||||
@ -1552,6 +1612,8 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
addChatMessage(game, session,
|
addChatMessage(game, session,
|
||||||
`${session.name} randomly stole ${type} from ${playerNameFromColor(game, value)}.`);
|
`${session.name} randomly stole ${type} from ${playerNameFromColor(game, value)}.`);
|
||||||
}
|
}
|
||||||
|
debugChat(game, 'After steal');
|
||||||
|
|
||||||
game.turn.robberInAction = false;
|
game.turn.robberInAction = false;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1585,10 +1647,13 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
if (game.turn.developmentPurchased) {
|
if (game.turn.developmentPurchased) {
|
||||||
error = `You have already purchased a development card this turn.`;
|
error = `You have already purchased a development card this turn.`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debugChat(game, 'Before development purchase');
|
||||||
addChatMessage(game, session, `${session.name} purchased a development card.`);
|
addChatMessage(game, session, `${session.name} purchased a development card.`);
|
||||||
player.stone--;
|
player.stone--;
|
||||||
player.wheat--;
|
player.wheat--;
|
||||||
player.sheep--;
|
player.sheep--;
|
||||||
|
debugChat(game, 'After development purchase');
|
||||||
card = game.developmentCards.pop();
|
card = game.developmentCards.pop();
|
||||||
card.turn = game.turns;
|
card.turn = game.turns;
|
||||||
player.development.push(card);
|
player.development.push(card);
|
||||||
@ -1644,6 +1709,11 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (card.type === 'progress' && card.card === 'road-2') {
|
||||||
|
addChatMessage(game, session, `${session.name} played a Road Building card. The server is giving them 2 brick and 2 wood to build those roads!`);
|
||||||
|
player.brick += 2;
|
||||||
|
player.wood += 2;
|
||||||
|
}
|
||||||
card.played = true;
|
card.played = true;
|
||||||
player.playedCard = game.turns;
|
player.playedCard = game.turns;
|
||||||
addChatMessage(game, session, `${session.name} played a ${card.type}-${card.card} development card.`);
|
addChatMessage(game, session, `${session.name} played a ${card.type}-${card.card} development card.`);
|
||||||
@ -1741,11 +1811,14 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
error = `You have already built all of your settlements.`;
|
error = `You have already built all of your settlements.`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
debugChat(game, 'Before settlement purchase');
|
||||||
player.settlements--;
|
player.settlements--;
|
||||||
player.brick--;
|
player.brick--;
|
||||||
player.wood--;
|
player.wood--;
|
||||||
player.wheat--;
|
player.wheat--;
|
||||||
player.sheep--;
|
player.sheep--;
|
||||||
|
debugChat(game, 'After settlement purchase');
|
||||||
|
|
||||||
corner.color = session.color;
|
corner.color = session.color;
|
||||||
corner.type = 'settlement';
|
corner.type = 'settlement';
|
||||||
if (layout.corners[index].banks.length) {
|
if (layout.corners[index].banks.length) {
|
||||||
@ -1870,10 +1943,13 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
}
|
}
|
||||||
corner.color = session.color;
|
corner.color = session.color;
|
||||||
corner.type = 'city';
|
corner.type = 'city';
|
||||||
|
debugChat(game, 'Before city purchase');
|
||||||
|
|
||||||
player.cities--;
|
player.cities--;
|
||||||
player.settlements++;
|
player.settlements++;
|
||||||
player.wheat -= 2;
|
player.wheat -= 2;
|
||||||
player.stone -= 3;
|
player.stone -= 3;
|
||||||
|
debugChat(game, 'After city purchase');
|
||||||
game.turn.actions = [];
|
game.turn.actions = [];
|
||||||
game.turn.limits = {};
|
game.turn.limits = {};
|
||||||
addChatMessage(game, session, `${name} upgraded a settlement to a city!`);
|
addChatMessage(game, session, `${name} upgraded a settlement to a city!`);
|
||||||
@ -1950,9 +2026,13 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
|||||||
error = `You have already built all of your roads.`;
|
error = `You have already built all of your roads.`;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debugChat(game, 'Before road purchase');
|
||||||
|
|
||||||
player.roads--;
|
player.roads--;
|
||||||
player.brick--;
|
player.brick--;
|
||||||
player.wood--;
|
player.wood--;
|
||||||
|
debugChat(game, 'After road purchase');
|
||||||
road.color = session.color;
|
road.color = session.color;
|
||||||
game.turn.actions = [];
|
game.turn.actions = [];
|
||||||
game.turn.limits = {};
|
game.turn.limits = {};
|
||||||
@ -2101,6 +2181,36 @@ router.get("/:id", async (req, res/*, next*/) => {
|
|||||||
return sendGame(req, res, game);
|
return sendGame(req, res, game);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const debugChat = (game, preamble) => {
|
||||||
|
preamble = `Degug ${preamble.trim()}`;
|
||||||
|
|
||||||
|
let playerInventory = preamble;
|
||||||
|
|
||||||
|
for (let key in game.players) {
|
||||||
|
if (game.players[key].status === 'Not active') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (playerInventory !== '') {
|
||||||
|
playerInventory += ' player';
|
||||||
|
} else {
|
||||||
|
playerInventory += ' Player'
|
||||||
|
}
|
||||||
|
playerInventory += ` ${playerNameFromColor(game, key)} has `;
|
||||||
|
const has = [ 'wheat', 'brick', 'sheep', 'stone', 'wood' ].map(resource => {
|
||||||
|
if (game.players[key][resource] > 0) {
|
||||||
|
return `${game.players[key][resource]} ${resource}`;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}).filter(item => item !== '').join(', ');
|
||||||
|
if (has) {
|
||||||
|
playerInventory += `${has}, `;
|
||||||
|
} else {
|
||||||
|
playerInventory += `nothing, `;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addChatMessage(game, null, playerInventory.replace(/, $/, '').trim());
|
||||||
|
}
|
||||||
|
|
||||||
const getActiveCount = (game) => {
|
const getActiveCount = (game) => {
|
||||||
let active = 0;
|
let active = 0;
|
||||||
for (let color in game.players) {
|
for (let color in game.players) {
|
||||||
@ -2183,10 +2293,14 @@ const sendGame = async (req, res, game, error) => {
|
|||||||
player.points += MAX_SETTLEMENTS - player.settlements;
|
player.points += MAX_SETTLEMENTS - player.settlements;
|
||||||
player.points += 2 * (MAX_CITIES - player.cities);
|
player.points += 2 * (MAX_CITIES - player.cities);
|
||||||
|
|
||||||
|
player.unplayed = 0;
|
||||||
player.development.forEach(card => {
|
player.development.forEach(card => {
|
||||||
if (card.type === 'vp' && card.played) {
|
if (card.type === 'vp' && card.played) {
|
||||||
player.points++;
|
player.points++;
|
||||||
}
|
}
|
||||||
|
if (!card.played) {
|
||||||
|
player.unplayed++;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!game.winner && (player.points >= 10 && session.color === key)) {
|
if (!game.winner && (player.points >= 10 && session.color === key)) {
|
||||||
@ -2195,6 +2309,8 @@ const sendGame = async (req, res, game, error) => {
|
|||||||
game.state = 'winner';
|
game.state = 'winner';
|
||||||
delete game.turn.roll;
|
delete game.turn.roll;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Shallow copy game, filling its sessions with a shallow copy of sessions so we can then
|
/* Shallow copy game, filling its sessions with a shallow copy of sessions so we can then
|
||||||
@ -2213,6 +2329,12 @@ const sendGame = async (req, res, game, error) => {
|
|||||||
reducedSessions.push(reduced);
|
reducedSessions.push(reduced);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Save per turn while debugging... */
|
||||||
|
await writeFile(`games/${game.id}.${game.turns}`, JSON.stringify(reducedGame, null, 2))
|
||||||
|
.catch((error) => {
|
||||||
|
console.error(`Unable to write to games/${game.id}`);
|
||||||
|
console.error(error);
|
||||||
|
});
|
||||||
await writeFile(`games/${game.id}`, JSON.stringify(reducedGame, null, 2))
|
await writeFile(`games/${game.id}`, JSON.stringify(reducedGame, null, 2))
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error(`Unable to write to games/${game.id}`);
|
console.error(`Unable to write to games/${game.id}`);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user