1
0

Fix #10 -- minimum road length starts at 5

Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
James Ketrenos 2022-02-26 13:49:23 -08:00
parent 54e1a51c04
commit fed7bcea6c

View File

@ -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,9 +2350,11 @@ 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.`;
@ -2251,8 +2364,11 @@ router.put("/:id/:action/:value?", async (req, res) => {
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) => {