summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2022-04-08 01:29:30 +0200
committerTor Andersson <tor@ccxvii.net>2022-04-08 01:29:30 +0200
commit4bb51cd7884c3861446098ffca0750bddbfa833b (patch)
treea87e22311dfc0828170eed49ddc2329c8cd31f17 /rules.js
downloadrommel-in-the-desert-4bb51cd7884c3861446098ffca0750bddbfa833b.tar.gz
Add Rommel in the Desert skeleton.
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js138
1 files changed, 138 insertions, 0 deletions
diff --git a/rules.js b/rules.js
new file mode 100644
index 0000000..142e0c4
--- /dev/null
+++ b/rules.js
@@ -0,0 +1,138 @@
+"use strict";
+
+let game = null;
+let view = null;
+
+exports.roles = [ "Axis", "Allied" ];
+
+exports.scenarios = [
+ "1940",
+ "1941",
+ "1941-42",
+ "Crusader",
+ "Battleaxe",
+ "1942",
+ "Gazala",
+ "Pursuit to Alamein",
+];
+
+exports.ready = function (scenario, options, players) {
+ return players.length === 2;
+}
+
+function random(n) {
+ return ((game.seed = game.seed * 69621 % 0x7fffffff) / 0x7fffffff) * n | 0;
+}
+
+function shuffle(deck) {
+ for (let i = deck.length - 1; i > 0; --i) {
+ let j = random(i + 1);
+ let tmp = deck[j];
+ deck[j] = deck[i];
+ deck[i] = tmp;
+ }
+}
+
+function remove_from_array(array, item) {
+ let i = array.indexOf(item);
+ if (i >= 0)
+ array.splice(i, 1);
+}
+
+function logbr() {
+ if (game.log.length > 0 && game.log[game.log.length-1] !== "")
+ game.log.push("");
+}
+
+function log(msg) {
+ game.log.push(msg);
+}
+
+function clear_undo() {
+ game.undo = [];
+}
+
+function push_undo() {
+ game.undo.push(JSON.stringify(game, (k,v) => {
+ if (k === 'undo') return 0;
+ if (k === 'log') return v.length;
+ return v;
+ }));
+}
+
+function pop_undo() {
+ let save_undo = game.undo;
+ let save_log = game.log;
+ game = JSON.parse(save_undo.pop());
+ game.undo = save_undo;
+ save_log.length = game.log;
+ game.log = save_log;
+}
+
+function gen_action(action, argument) {
+ if (argument !== undefined) {
+ if (!(action in view.actions)) {
+ view.actions[action] = [ argument ];
+ } else {
+ if (!view.actions[action].includes(argument))
+ view.actions[action].push(argument);
+ }
+ } else {
+ view.actions[action] = 1;
+ }
+}
+
+let states = {};
+
+exports.setup = function (seed, scenario, options) {
+ game = {
+ seed: seed,
+ log: [],
+ undo: [],
+ };
+ return game;
+}
+
+exports.action = function (state, current, action, arg) {
+ game = state;
+ update_aliases();
+ let S = states[game.state];
+ if (action in S) {
+ S[action](arg, current);
+ } else {
+ if (action === 'undo' && game.undo && game.undo.length > 0)
+ pop_undo();
+ else
+ throw new Error("Invalid action: " + action);
+ }
+ return game;
+}
+
+exports.resign = function (state, current) {
+ // No resigning allowed.
+ return state;
+}
+
+exports.view = function(state, current) {
+ game = state;
+ update_aliases();
+
+ view = {
+ log: game.log,
+ active: game.active,
+ prompt: null,
+ };
+
+ if (current === 'Observer' || game.active !== current) {
+ view.prompt = `Waiting for ${game.active} \u2014 ${game.state}...`;
+ } else {
+ view.actions = {}
+ states[game.state].prompt();
+ if (game.undo && game.undo.length > 0)
+ view.actions.undo = 1;
+ else
+ view.actions.undo = 0;
+ }
+
+ return view;
+}