Fix #10 -- minimum road length starts at 5
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
54e1a51c04
commit
fed7bcea6c
@ -228,11 +228,10 @@ const processGameOrder = (game, player, dice) => {
|
||||
message = `Initial settlement placement has started!`;
|
||||
game.direction = 'forward';
|
||||
game.turn = {
|
||||
actions: [ 'place-settlement' ],
|
||||
limits: { corners: getValidCorners(game) },
|
||||
name: getPlayerName(game, players[0]),
|
||||
color: getPlayerColor(game, players[0])
|
||||
};
|
||||
placeSettlement(game, getValidCorners(game));
|
||||
addChatMessage(game, null, message);
|
||||
message = `It is ${game.turn.name}'s turn to place a settlement.`;
|
||||
} else {
|
||||
@ -524,7 +523,7 @@ const loadGame = async (id) => {
|
||||
}
|
||||
|
||||
if (typeof game.turn !== 'object') {
|
||||
delete game.turn;
|
||||
game.turn = {};
|
||||
}
|
||||
|
||||
if (!game.placements) {
|
||||
@ -563,8 +562,18 @@ const clearPlayer = (player) => {
|
||||
delete player.orderStatus;
|
||||
}
|
||||
|
||||
const canGiveBuilding = (game) => {
|
||||
if (!game.turn.roll) {
|
||||
return `Admin cannot give a building until the dice have been rolled.`;
|
||||
}
|
||||
if (game.turn.actions && game.turn.actions.length !== 0) {
|
||||
return `Admin cannot give a building while other actions in play: ${game.turn.actions.join(', ')}.`
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const adminActions = (game, action, value) => {
|
||||
let color, player, parts, session;
|
||||
let color, player, parts, session, corners, error;
|
||||
|
||||
switch (action) {
|
||||
case "debug":
|
||||
@ -585,25 +594,93 @@ const adminActions = (game, action, value) => {
|
||||
break;
|
||||
|
||||
case "give":
|
||||
parts = value.match(/^([^-]+)-(.*)$/);
|
||||
parts = value.match(/^([^-]+)(-(.*))?$/);
|
||||
if (!parts) {
|
||||
return `Unable to parse give request.`;
|
||||
}
|
||||
const type = parts[1], card = parts[2];
|
||||
const type = parts[1], card = parts[3];
|
||||
|
||||
for (let id in game.sessions) {
|
||||
if (game.sessions[id].name === game.turn.name) {
|
||||
session = game.sessions[id];
|
||||
}
|
||||
}
|
||||
|
||||
if (!session) {
|
||||
return `Unable to determine current player turn to give resources.`;
|
||||
}
|
||||
|
||||
if ([ 'wheat', 'sheep', 'wood', 'stone', 'brick' ].indexOf(type) !== -1) {
|
||||
const count = parseInt(card);
|
||||
session.player[type] += count;
|
||||
addChatMessage(game, null, `Admin gave ${count} ${type} to ${game.turn.name}.`);
|
||||
let done = true;
|
||||
switch (type) {
|
||||
case 'road':
|
||||
error = canGiveBuilding(game);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (session.player.roads === 0) {
|
||||
return `Player ${game.turn.name} does not have any more roads to give.`;
|
||||
}
|
||||
let roads = getValidRoads(game, session.color);
|
||||
if (roads.length === 0) {
|
||||
return `There are no valid locations for ${game.turn.name} to place a road.`;
|
||||
}
|
||||
game.turn.free = true;
|
||||
placeRoad(game, roads);
|
||||
addChatMessage(game, null, `Admin gave a road to ${game.turn.name}.` +
|
||||
`They must now place the road.`);
|
||||
break;
|
||||
case 'city':
|
||||
error = canGiveBuilding(game);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (session.player.cities === 0) {
|
||||
return `Player ${game.turn.name} does not have any more cities to give.`;
|
||||
}
|
||||
corners = getValidCorners(game, session.color);
|
||||
if (corners.length === 0) {
|
||||
return `There are no valid locations for ${game.turn.name} to place a settlement.`;
|
||||
}
|
||||
corners = getValidCorners(game, session.color, 'settlement');
|
||||
game.turn.free = true;
|
||||
placeCity(game, corners);
|
||||
addChatMessage(game, null, `Admin gave a city to ${game.turn.name}. ` +
|
||||
`They must now place the city.`);
|
||||
break;
|
||||
case 'settlement':
|
||||
error = canGiveBuilding(game);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (session.player.settlements === 0) {
|
||||
return `Player ${game.turn.name} does not have any more settlements to give.`;
|
||||
}
|
||||
corners = getValidCorners(game, session.color);
|
||||
if (corners.length === 0) {
|
||||
return `There are no valid locations for ${game.turn.name} to place a settlement.`;
|
||||
}
|
||||
game.turn.free = true;
|
||||
placeSettlement(game, corners);
|
||||
addChatMessage(game, null, `Admin gave a settlment to ${game.turn.name}. ` +
|
||||
`They must now place the settlement.`);
|
||||
break;
|
||||
case 'wheat':
|
||||
case 'sheep':
|
||||
case 'wood':
|
||||
case 'stone':
|
||||
case 'brick':
|
||||
const count = parseInt(card);
|
||||
session.player[type] += count;
|
||||
addChatMessage(game, null, `Admin gave ${count} ${type} to ${game.turn.name}.`);
|
||||
break;
|
||||
default:
|
||||
done = false;
|
||||
break;
|
||||
}
|
||||
if (done) {
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1096,7 +1173,9 @@ const calculateRoadLengths = (game, session) => {
|
||||
longestPlayers = [ key ];
|
||||
longestRoad = game.players[key].longestRoad;
|
||||
} else if (game.players[key].longestRoad === longestRoad) {
|
||||
longestPlayers.push(key);
|
||||
if (longestRoad >= 5) {
|
||||
longestPlayers.push(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1385,6 +1464,21 @@ const offerToString = (offer) => {
|
||||
offer.gets.map(item => `${item.count} ${item.type}`).join(', ');
|
||||
}
|
||||
|
||||
const placeRoad = (game, limits) => {
|
||||
game.turn.actions = [ 'place-road' ];
|
||||
game.turn.limits = { roads: limits };
|
||||
}
|
||||
|
||||
const placeCity = (game, limits) => {
|
||||
game.turn.actions = [ 'place-city' ];
|
||||
game.turn.limits = { corners: limits };
|
||||
}
|
||||
|
||||
const placeSettlement = (game, limits) => {
|
||||
game.turn.actions = [ 'place-settlement' ];
|
||||
game.turn.limits = { corners: limits };
|
||||
}
|
||||
|
||||
router.put("/:id/:action/:value?", async (req, res) => {
|
||||
const { action, id } = req.params,
|
||||
value = req.params.value ? req.params.value : "";
|
||||
@ -1683,7 +1777,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
game.turn.placedRobber = true;
|
||||
|
||||
pickRobber(game);
|
||||
addChatMessage(game, session, `${game.robberName} Robber Robinson entered the scene as the nefarious robber!`);
|
||||
addChatMessage(game, null, `${game.robberName} Robber Robinson entered the scene as the nefarious robber!`);
|
||||
|
||||
let colors = [];
|
||||
layout.tiles[robber].corners.forEach(cornerIndex => {
|
||||
@ -1701,7 +1795,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
game.turn.actions = [];
|
||||
game.turn.robberInAction = false;
|
||||
delete game.turn.limits;
|
||||
addChatMessage(game, session, `The dread robber ${game.robberName} was placed on a terrain with no other players, ` +
|
||||
addChatMessage(game, null, `The dread robber ${game.robberName} was placed on a terrain with no other players, ` +
|
||||
`so ${game.turn.name} does not steal resources from anyone.`);
|
||||
}
|
||||
|
||||
@ -1877,7 +1971,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
|
||||
game.turn.robberInAction = true;
|
||||
delete game.turn.placedRobber;
|
||||
addChatMessage(game, session, `The robber ${game.robberName} has fled before the power of the Knight, ` +
|
||||
addChatMessage(game, null, `The robber ${game.robberName} has fled before the power of the Knight, ` +
|
||||
`but a new robber has returned and ${session.name} must now place them.`);
|
||||
game.turn.actions = [ 'place-robber' ];
|
||||
game.turn.limits = { pips: [] };
|
||||
@ -1989,8 +2083,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
error = `There are no valid locations for you to place a settlement.`;
|
||||
break;
|
||||
}
|
||||
game.turn.actions = [ 'place-settlement' ];
|
||||
game.turn.limits = { corners };
|
||||
placeSettlement(game, corners);
|
||||
addChatMessage(game, session, `${game.turn.name} is considering placing a settlement.`);
|
||||
break;
|
||||
|
||||
@ -2024,24 +2117,33 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
}
|
||||
|
||||
if (game.state === 'normal') {
|
||||
if (player.brick < 1 || player.wood < 1 || player.wheat < 1 || player.sheep < 1) {
|
||||
error = `You have insufficient resources to build a settlement.`;
|
||||
break;
|
||||
if (!game.turn.free) {
|
||||
if (player.brick < 1 || player.wood < 1 || player.wheat < 1 || player.sheep < 1) {
|
||||
error = `You have insufficient resources to build a settlement.`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (player.settlements < 1) {
|
||||
error = `You have already built all of your settlements.`;
|
||||
break;
|
||||
}
|
||||
debugChat(game, 'Before settlement purchase');
|
||||
player.settlements--;
|
||||
player.brick--;
|
||||
player.wood--;
|
||||
player.wheat--;
|
||||
player.sheep--;
|
||||
|
||||
if (!game.turn.free) {
|
||||
player.brick--;
|
||||
player.wood--;
|
||||
player.wheat--;
|
||||
player.sheep--;
|
||||
}
|
||||
delete game.turn.free;
|
||||
debugChat(game, 'After settlement purchase');
|
||||
|
||||
corner.color = session.color;
|
||||
corner.type = 'settlement';
|
||||
let bankType = undefined;
|
||||
|
||||
if (layout.corners[index].banks.length) {
|
||||
layout.corners[index].banks.forEach(bank => {
|
||||
const border = game.borderOrder[Math.floor(bank / 3)],
|
||||
@ -2051,6 +2153,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
console.log(`Bank ${bank}`)
|
||||
return;
|
||||
}
|
||||
bankType = (type === 'bank') ? '3:1' : type;
|
||||
if (player.banks.indexOf(type) === -1) {
|
||||
player.banks.push(type);
|
||||
}
|
||||
@ -2058,7 +2161,11 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
}
|
||||
game.turn.actions = [];
|
||||
game.turn.limits = {};
|
||||
addChatMessage(game, session, `${name} placed a settlement.`);
|
||||
if (bankType) {
|
||||
addChatMessage(game, session, `${name} placed a settlement by a maritime bank for ${bankType}.`);
|
||||
} else {
|
||||
addChatMessage(game, session, `${name} placed a settlement.`);
|
||||
}
|
||||
calculateRoadLengths(game, session);
|
||||
} else if (game.state === 'initial-placement') {
|
||||
if (game.direction && game.direction === 'backward') {
|
||||
@ -2083,8 +2190,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
}
|
||||
player.settlements--;
|
||||
player.maritime = player.banks.map(bank => game.borders[Math.floor(bank / 3) + bank % 3]);
|
||||
game.turn.actions = ['place-road'];
|
||||
game.turn.limits = { roads: layout.corners[index].roads }; /* road placement is limited to be near this corner */
|
||||
placeRoad(game, layout.corners[index].roads);
|
||||
addChatMessage(game, session, `Placed a settlement. Next, they need to place a road.`);
|
||||
}
|
||||
break;
|
||||
@ -2121,8 +2227,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
error = `There are no valid locations for you to place a city.`;
|
||||
break;
|
||||
}
|
||||
game.turn.actions = ['place-city'];
|
||||
game.turn.limits = { corners };
|
||||
placeCity(game, corners);
|
||||
addChatMessage(game, session, `${game.turn.name} is considering upgrading a settlement to a city.`);
|
||||
break;
|
||||
|
||||
@ -2154,22 +2259,29 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
error = `This location already has a city!`;
|
||||
break;
|
||||
}
|
||||
if (player.wheat < 2 || player.stone < 3) {
|
||||
error = `You have insufficient resources to build a city.`;
|
||||
break;
|
||||
if (!game.turn.free) {
|
||||
if (player.wheat < 2 || player.stone < 3) {
|
||||
error = `You have insufficient resources to build a city.`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (player.city < 1) {
|
||||
error = `You have already built all of your cities.`;
|
||||
break;
|
||||
}
|
||||
|
||||
corner.color = session.color;
|
||||
corner.type = 'city';
|
||||
debugChat(game, 'Before city purchase');
|
||||
|
||||
player.cities--;
|
||||
player.settlements++;
|
||||
player.wheat -= 2;
|
||||
player.stone -= 3;
|
||||
if (!game.turn.free) {
|
||||
player.wheat -= 2;
|
||||
player.stone -= 3;
|
||||
}
|
||||
delete game.turn.free;
|
||||
|
||||
debugChat(game, 'After city purchase');
|
||||
game.turn.actions = [];
|
||||
game.turn.limits = {};
|
||||
@ -2208,8 +2320,7 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
error = `There are no valid locations for you to place a road.`;
|
||||
break;
|
||||
}
|
||||
game.turn.actions = ['place-road'];
|
||||
game.turn.limits = { roads };
|
||||
placeRoad(game, roads);
|
||||
addChatMessage(game, session, `${game.turn.name} is considering building a road.`);
|
||||
break;
|
||||
|
||||
@ -2239,20 +2350,25 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
}
|
||||
|
||||
if (game.state === 'normal') {
|
||||
if (player.brick < 1 || player.wood < 1) {
|
||||
error = `You have insufficient resources to build a road.`;
|
||||
break;
|
||||
if (!game.turn.free) {
|
||||
if (player.brick < 1 || player.wood < 1) {
|
||||
error = `You have insufficient resources to build a road.`;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (player.roads < 1) {
|
||||
error = `You have already built all of your roads.`;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
debugChat(game, 'Before road purchase');
|
||||
|
||||
player.roads--;
|
||||
player.brick--;
|
||||
player.wood--;
|
||||
if (!game.turn.free) {
|
||||
player.brick--;
|
||||
player.wood--;
|
||||
}
|
||||
delete game.turn.free;
|
||||
debugChat(game, 'After road purchase');
|
||||
road.color = session.color;
|
||||
game.turn.actions = [];
|
||||
@ -2281,11 +2397,10 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
}
|
||||
if (next) {
|
||||
game.turn = {
|
||||
actions: ['place-settlement'],
|
||||
limits: { corners: getValidCorners(game) },
|
||||
name: next,
|
||||
color: getColorFromName(game, next)
|
||||
};
|
||||
placeSettlement(game, getValidCorners(game));
|
||||
calculateRoadLengths(game, session);
|
||||
addChatMessage(game, null, `It is ${next}'s turn to place a settlement.`);
|
||||
} else {
|
||||
@ -2398,9 +2513,8 @@ router.put("/:id/:action/:value?", async (req, res) => {
|
||||
}
|
||||
|
||||
resetGame(game);
|
||||
|
||||
message = `${name} requested to start the game.`;
|
||||
addChatMessage(game, null, message);
|
||||
addChatMessage(game, null, `${name} requested to start the game.`);
|
||||
addChatMessage(game, null, `${game.robberName} Robber Robinson entered the scene as the nefarious robber!`);
|
||||
game.state = state;
|
||||
break;
|
||||
}
|
||||
@ -2620,7 +2734,8 @@ const resetGame = (game) => {
|
||||
wheat: 19,
|
||||
longestRoad: null,
|
||||
largestArmy: null,
|
||||
developmentCards: assetData.developmentCards.slice()
|
||||
developmentCards: assetData.developmentCards.slice(),
|
||||
turn: {}
|
||||
});
|
||||
|
||||
for (let key in game.players) {
|
||||
@ -2666,8 +2781,6 @@ const resetGame = (game) => {
|
||||
type: undefined
|
||||
};
|
||||
}
|
||||
|
||||
delete game.turn;
|
||||
}
|
||||
|
||||
const createGame = (id) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user