1
0
peddlers-of-ketran/server/util/validLocations.js
James Ketrenos 2788265efc Implementing more admin commands
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
2022-06-26 11:17:43 -07:00

120 lines
3.6 KiB
JavaScript

const { layout } = require('./layout.js');
const isRuleEnabled = (game, rule) => {
return rule in game.rules && game.rules[rule].enabled;
};
const getValidRoads = (game, color) => {
const limits = [];
/* For each road, if the road is set, skip it.
* If no color is set, check the two corners. If the corner
* has a matching color, add this to the set. Otherwise skip.
*/
layout.roads.forEach((road, roadIndex) => {
if (game.placements.roads[roadIndex].color) {
return;
}
let valid = false;
for (let c = 0; !valid && c < road.corners.length; c++) {
const corner = layout.corners[road.corners[c]],
cornerColor = game.placements.corners[road.corners[c]].color;
/* Roads do not pass through other player's settlements */
if (cornerColor && cornerColor !== color) {
continue;
}
for (let r = 0; !valid && r < corner.roads.length; r++) {
/* This side of the corner is pointing to the road being validated. Skip it. */
if (corner.roads[r] === roadIndex) {
continue;
}
if (game.placements.roads[corner.roads[r]].color === color) {
valid = true;
}
}
}
if (valid) {
limits.push(roadIndex);
}
});
return limits;
}
const getValidCorners = (game, color, type) => {
const limits = [];
/* For each corner, if the corner already has a color set, skip it if type
* isn't set. If type is set, if it is a match, and the color is a match,
* add it to the list.
*
* If we are limiting based on active player, a corner is only valid
* if it connects to a road that is owned by that player.
*
* If no color is set, walk each road that leaves that corner and
* check to see if there is a settlement placed at the end of that road
*
* If so, this location cannot have a settlement.
*
* If still valid, and we are in initial settlement placement, and if
* Volcano is enabled, verify the tile is not the Volcano.
*/
layout.corners.forEach((corner, cornerIndex) => {
const placement = game.placements.corners[cornerIndex];
if (type) {
if (placement.color === color && placement.type === type) {
limits.push(cornerIndex);
}
return;
}
if (placement.color) {
return;
}
let valid;
if (!color) {
valid = true; /* Not filtering based on current player */
} else {
valid = false;
for (let r = 0; !valid && r < corner.roads.length; r++) {
valid = game.placements.roads[corner.roads[r]].color === color;
}
}
for (let r = 0; valid && r < corner.roads.length; r++) {
const road = layout.roads[corner.roads[r]];
for (let c = 0; valid && c < road.corners.length; c++) {
/* This side of the road is pointing to the corner being validated.
* Skip it. */
if (road.corners[c] === cornerIndex) {
continue;
}
/* There is a settlement within one segment from this
* corner, so it is invalid for settlement placement */
if (game.placements.corners[road.corners[c]].color) {
valid = false;
}
}
}
if (valid) {
/* During initial placement, if volcano is enabled, do not allow
* placement on a corner connected to the volcano (robber starts
* on the volcano) */
if (!(game.state === 'initial-placement'
&& isRuleEnabled(game, 'volcano')
&& layout.tiles[game.robber].corners.indexOf(cornerIndex) !== -1
)) {
limits.push(cornerIndex);
}
}
});
return limits;
}
module.exports = {
getValidCorners,
getValidRoads,
isRuleEnabled
};