Implementing more admin commands
Signed-off-by: James Ketrenos <james_eikona@ketrenos.com>
This commit is contained in:
parent
71777e3a21
commit
2788265efc
@ -4,7 +4,7 @@ const fs = require('fs').promises;
|
|||||||
const calculateLongestRoad = require('./longest-road.js');
|
const calculateLongestRoad = require('./longest-road.js');
|
||||||
|
|
||||||
const { getValidRoads, getValidCorners } = require('../util/validLocations.js');
|
const { getValidRoads, getValidCorners } = require('../util/validLocations.js');
|
||||||
const layout = require('../util/layout.js');
|
const { layout, staticData } = require('../util/layout.js');
|
||||||
|
|
||||||
const version = '0.0.1';
|
const version = '0.0.1';
|
||||||
|
|
||||||
@ -206,26 +206,68 @@ const sleep = async (delay) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const bestSettlementPlacement = (game) => {
|
||||||
|
const best = {
|
||||||
|
index: -1,
|
||||||
|
pips: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
/* For each corner that is valid, find out which
|
||||||
|
* tiles are on that corner, and for each of those
|
||||||
|
* tiles, find the pip placement for that tile. */
|
||||||
|
game.turn.limits.corners.forEach(cornerIndex => {
|
||||||
|
const tiles = [];
|
||||||
|
layout.tiles.forEach((tile, index) => {
|
||||||
|
if (tile.corners.indexOf(cornerIndex) !== -1
|
||||||
|
&& tiles.indexOf(index) === -1) {
|
||||||
|
tiles.push({ tile, index });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
let cornerScore = 0;
|
||||||
|
|
||||||
|
/* Find the tileOrder holding this tile */
|
||||||
|
tiles.forEach(tile => {
|
||||||
|
const index = tile.index;
|
||||||
|
// const tileIndex = game.tileOrder.indexOf(index);
|
||||||
|
const pipIndex = game.pipOrder[index];
|
||||||
|
const score = staticData.pips[pipIndex].pips;
|
||||||
|
cornerScore += score;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (cornerScore > best.pips) {
|
||||||
|
best.index = cornerIndex;
|
||||||
|
best.pips = cornerScore;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(`${name} - Corner ${best.index} gives ${best.pips} pips.`);
|
||||||
|
return best.index;
|
||||||
|
}
|
||||||
|
|
||||||
const bestRoadPlacement = (game) => {
|
const bestRoadPlacement = (game) => {
|
||||||
const road = calculateLongestRoad(game);
|
const road = calculateLongestRoad(game);
|
||||||
console.log(`${name} - could make road ${road.segments + 1} long on ${road.index}`);
|
console.log(`${name} - could make road ${road.segments + 1} long on ${road.index}`);
|
||||||
|
|
||||||
let attempt = -1;
|
let attempt = -1;
|
||||||
layout.roads[road.index].corners.forEach(cornerIndex => {
|
if (road.index !== -1) {
|
||||||
if (attempt !== -1) {
|
layout.roads[road.index].corners.forEach(cornerIndex => {
|
||||||
return;
|
|
||||||
}
|
|
||||||
layout.corners[cornerIndex].roads.forEach(roadIndex => {
|
|
||||||
if (attempt !== -1) {
|
if (attempt !== -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const placedRoad = game.placements.roads[roadIndex];
|
layout.corners[cornerIndex].roads.forEach(roadIndex => {
|
||||||
if (placedRoad.color) {
|
if (attempt !== -1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
attempt = roadIndex;
|
const placedRoad = game.placements.roads[roadIndex];
|
||||||
|
if (placedRoad.color) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
attempt = roadIndex;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
if (game.turn.limits.roads.indexOf(attempt) !== -1) {
|
if (game.turn.limits.roads.indexOf(attempt) !== -1) {
|
||||||
console.log(`${name} - attempting to place on end of longest road`);
|
console.log(`${name} - attempting to place on end of longest road`);
|
||||||
@ -331,6 +373,18 @@ const processGameOrder = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const processInitialPlacement = async (received) => {
|
const processInitialPlacement = async (received) => {
|
||||||
|
/* Fetch the various game order elements so we can make
|
||||||
|
* educated location selections */
|
||||||
|
if (!game.pipOrder
|
||||||
|
|| !game.tileOrder
|
||||||
|
|| !game.borderOrder) {
|
||||||
|
return {
|
||||||
|
pipOrder: anyValue,
|
||||||
|
tileOrder: anyValue,
|
||||||
|
borderOrder: anyValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!game.turn || game.turn.color !== game.color) {
|
if (!game.turn || game.turn.color !== game.color) {
|
||||||
return {
|
return {
|
||||||
turn: {
|
turn: {
|
||||||
@ -363,8 +417,7 @@ const processInitialPlacement = async (received) => {
|
|||||||
if (type === 'place-road') {
|
if (type === 'place-road') {
|
||||||
index = bestRoadPlacement(game);
|
index = bestRoadPlacement(game);
|
||||||
} else if (type === 'place-settlement') {
|
} else if (type === 'place-settlement') {
|
||||||
index = game.turn.limits.corners[Math.floor(
|
index = bestSettlementPlacement(game);
|
||||||
Math.random() * game.turn.limits.corners.length)];
|
|
||||||
}
|
}
|
||||||
console.log(`Selecting ${type} at ${index}`);
|
console.log(`Selecting ${type} at ${index}`);
|
||||||
send({
|
send({
|
||||||
@ -626,9 +679,7 @@ const processNormal = async (received) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (game.turn.actions && game.turn.actions.indexOf('place-settlement') !== -1) {
|
if (game.turn.actions && game.turn.actions.indexOf('place-settlement') !== -1) {
|
||||||
console.log({ corners: game.turn.limits.corners });
|
const index = bestSettlementPlacement(game);
|
||||||
index = game.turn.limits.corners[Math.floor(
|
|
||||||
Math.random() * game.turn.limits.corners.length)];
|
|
||||||
send({
|
send({
|
||||||
type: 'place-settlement', index
|
type: 'place-settlement', index
|
||||||
});
|
});
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const layout = require('../util/layout.js');
|
const { layout } = require('../util/layout.js');
|
||||||
|
|
||||||
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 */
|
||||||
|
@ -8,7 +8,7 @@ const express = require("express"),
|
|||||||
accessSync = fs.accessSync,
|
accessSync = fs.accessSync,
|
||||||
randomWords = require("random-words"),
|
randomWords = require("random-words"),
|
||||||
equal = require("fast-deep-equal");
|
equal = require("fast-deep-equal");
|
||||||
const layout = require('../util/layout.js');
|
const { layout, staticData } = require('../util/layout.js');
|
||||||
|
|
||||||
const { getValidRoads, getValidCorners, isRuleEnabled } = require('../util/validLocations.js');
|
const { getValidRoads, getValidCorners, isRuleEnabled } = require('../util/validLocations.js');
|
||||||
|
|
||||||
@ -51,58 +51,6 @@ function shuffleArray(array) {
|
|||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
|
|
||||||
const staticData = {
|
|
||||||
tiles: [
|
|
||||||
{ type: "desert", card: 0 },
|
|
||||||
{ type: "wood", card: 0 },
|
|
||||||
{ type: "wood", card: 1 },
|
|
||||||
{ type: "wood", card: 2 },
|
|
||||||
{ type: "wood", card: 3 },
|
|
||||||
{ type: "wheat", card: 0 },
|
|
||||||
{ type: "wheat", card: 1 },
|
|
||||||
{ type: "wheat", card: 2 },
|
|
||||||
{ type: "wheat", card: 3 },
|
|
||||||
{ type: "stone", card: 0 },
|
|
||||||
{ type: "stone", card: 1 },
|
|
||||||
{ type: "stone", card: 2 },
|
|
||||||
{ type: "sheep", card: 0 },
|
|
||||||
{ type: "sheep", card: 1 },
|
|
||||||
{ type: "sheep", card: 2 },
|
|
||||||
{ type: "sheep", card: 3 },
|
|
||||||
{ type: "brick", card: 0 },
|
|
||||||
{ type: "brick", card: 1 },
|
|
||||||
{ type: "brick", card: 2 }
|
|
||||||
],
|
|
||||||
pips: [
|
|
||||||
{ roll: 5, pips: 4 },
|
|
||||||
{ roll: 2, pips: 1 },
|
|
||||||
{ roll: 6, pips: 5 },
|
|
||||||
{ roll: 3, pips: 2 },
|
|
||||||
{ roll: 8, pips: 5 },
|
|
||||||
{ roll: 10, pips: 3 },
|
|
||||||
{ roll: 9, pips: 4 },
|
|
||||||
{ roll: 12, pips: 1 },
|
|
||||||
{ roll: 11, pips: 2 },
|
|
||||||
{ roll: 4, pips: 3 },
|
|
||||||
{ roll: 8, pips: 5 },
|
|
||||||
{ roll: 10, pips: 3 },
|
|
||||||
{ roll: 9, pips: 4 },
|
|
||||||
{ roll: 4, pips: 3 },
|
|
||||||
{ roll: 5, pips: 4 },
|
|
||||||
{ roll: 6, pips: 6 },
|
|
||||||
{ roll: 3, pips: 2 },
|
|
||||||
{ roll: 11, pips: 2 },
|
|
||||||
{ roll: 7, pips: 0 }, /* Robber is at the end or indexing gets off */
|
|
||||||
],
|
|
||||||
borders: [
|
|
||||||
[ "bank", undefined, "sheep" ],
|
|
||||||
[ undefined, "bank", undefined ],
|
|
||||||
[ "bank", undefined, "brick" ],
|
|
||||||
[ undefined, "wood", undefined ],
|
|
||||||
[ "bank", undefined, "wheat" ],
|
|
||||||
[ undefined, "stone", undefined ]
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
const games = {};
|
const games = {};
|
||||||
const audio = {};
|
const audio = {};
|
||||||
@ -759,6 +707,12 @@ const adminCommands = (game, action, value, query) => {
|
|||||||
let color, player, parts, session, corners, error;
|
let color, player, parts, session, corners, error;
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
|
case 'rules':
|
||||||
|
const rule = value.replace(/^=.*/, '');
|
||||||
|
let values = value.replace(/^.*=/, '').split(',');
|
||||||
|
console.log(rule, values);
|
||||||
|
break;
|
||||||
|
|
||||||
case "debug":
|
case "debug":
|
||||||
if (parseInt(value) === 0 || value === 'false') {
|
if (parseInt(value) === 0 || value === 'false') {
|
||||||
delete game.debug;
|
delete game.debug;
|
||||||
|
34
server/rules
Executable file
34
server/rules
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
ADMIN=$(jq -r .admin config/local.json)
|
||||||
|
if [[ "${ADMIN}" == "" ]]; then
|
||||||
|
echo "You need to set your { 'admin': 'secret' } in config/local.json"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
id=$1
|
||||||
|
shift
|
||||||
|
rule=$1
|
||||||
|
shift
|
||||||
|
params="${*}"
|
||||||
|
params="${params// /,}"
|
||||||
|
|
||||||
|
if [[ "${id}" == "" ]] || [[ "${rule}" == "" ]] || [[ "${params}" == "" ]]; then
|
||||||
|
cat << EOF
|
||||||
|
Usage: rules GAME-ID RULE KEY:VALUE [KEY:VALUE]
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
./rules test volcano enabled:true gold:true number:4
|
||||||
|
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl --noproxy '*' -s -L \
|
||||||
|
--request PUT \
|
||||||
|
--header "PRIVATE-TOKEN: ${ADMIN}" \
|
||||||
|
--header "Content-Type: application/json" \
|
||||||
|
http://localhost:8930/ketr.ketran/api/v1/games/${id}/rules/${rule}=${params}
|
||||||
|
# jq -r .status
|
||||||
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
|
||||||
/* Board Tiles:
|
/* Board Tiles:
|
||||||
* 0 1 2
|
* 0 1 2
|
||||||
* 3 4 5 6
|
* 3 4 5 6
|
||||||
@ -262,4 +261,60 @@ const layout = {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = layout;
|
const staticData = {
|
||||||
|
tiles: [
|
||||||
|
{ type: "desert", card: 0 },
|
||||||
|
{ type: "wood", card: 0 },
|
||||||
|
{ type: "wood", card: 1 },
|
||||||
|
{ type: "wood", card: 2 },
|
||||||
|
{ type: "wood", card: 3 },
|
||||||
|
{ type: "wheat", card: 0 },
|
||||||
|
{ type: "wheat", card: 1 },
|
||||||
|
{ type: "wheat", card: 2 },
|
||||||
|
{ type: "wheat", card: 3 },
|
||||||
|
{ type: "stone", card: 0 },
|
||||||
|
{ type: "stone", card: 1 },
|
||||||
|
{ type: "stone", card: 2 },
|
||||||
|
{ type: "sheep", card: 0 },
|
||||||
|
{ type: "sheep", card: 1 },
|
||||||
|
{ type: "sheep", card: 2 },
|
||||||
|
{ type: "sheep", card: 3 },
|
||||||
|
{ type: "brick", card: 0 },
|
||||||
|
{ type: "brick", card: 1 },
|
||||||
|
{ type: "brick", card: 2 }
|
||||||
|
],
|
||||||
|
pips: [
|
||||||
|
{ roll: 5, pips: 4 },
|
||||||
|
{ roll: 2, pips: 1 },
|
||||||
|
{ roll: 6, pips: 5 },
|
||||||
|
{ roll: 3, pips: 2 },
|
||||||
|
{ roll: 8, pips: 5 },
|
||||||
|
{ roll: 10, pips: 3 },
|
||||||
|
{ roll: 9, pips: 4 },
|
||||||
|
{ roll: 12, pips: 1 },
|
||||||
|
{ roll: 11, pips: 2 },
|
||||||
|
{ roll: 4, pips: 3 },
|
||||||
|
{ roll: 8, pips: 5 },
|
||||||
|
{ roll: 10, pips: 3 },
|
||||||
|
{ roll: 9, pips: 4 },
|
||||||
|
{ roll: 4, pips: 3 },
|
||||||
|
{ roll: 5, pips: 4 },
|
||||||
|
{ roll: 6, pips: 5 },
|
||||||
|
{ roll: 3, pips: 2 },
|
||||||
|
{ roll: 11, pips: 2 },
|
||||||
|
{ roll: 7, pips: 0 }, /* Robber is at the end or indexing gets off */
|
||||||
|
],
|
||||||
|
borders: [
|
||||||
|
["bank", undefined, "sheep"],
|
||||||
|
[undefined, "bank", undefined],
|
||||||
|
["bank", undefined, "brick"],
|
||||||
|
[undefined, "wood", undefined],
|
||||||
|
["bank", undefined, "wheat"],
|
||||||
|
[undefined, "stone", undefined]
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
layout,
|
||||||
|
staticData
|
||||||
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
const layout = require('./layout.js');
|
const { layout } = require('./layout.js');
|
||||||
|
|
||||||
const isRuleEnabled = (game, rule) => {
|
const isRuleEnabled = (game, rule) => {
|
||||||
return rule in game.rules && game.rules[rule].enabled;
|
return rule in game.rules && game.rules[rule].enabled;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user