From 4bb51cd7884c3861446098ffca0750bddbfa833b Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Fri, 8 Apr 2022 01:29:30 +0200 Subject: Add Rommel in the Desert skeleton. --- about.html | 17 ++++++++ create.html | 0 rules.js | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ title.sql | 1 + 4 files changed, 156 insertions(+) create mode 100644 about.html create mode 100644 create.html create mode 100644 rules.js create mode 100644 title.sql diff --git a/about.html b/about.html new file mode 100644 index 0000000..f2b8595 --- /dev/null +++ b/about.html @@ -0,0 +1,17 @@ +

+Rommel in the Desert is a game of strategy for two players based on the North African Campaign of World War II. +A game of maneuver, each side has to move with precision and know when to strike, since a cut in supply spells disaster for either side. + +
+ +

+Designer: Craig Besinque + +

+Copyright © 1984-2022 +Columbia Games. + +

diff --git a/create.html b/create.html new file mode 100644 index 0000000..e69de29 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; +} diff --git a/title.sql b/title.sql new file mode 100644 index 0000000..d1f3bad --- /dev/null +++ b/title.sql @@ -0,0 +1 @@ +insert or replace into titles ( title_id, title_name, bgg ) values ( 'rommel-in-the-desert', 'Rommel in the Desert', 84 ); -- cgit v1.2.3