diff options
author | Frans Bongers <fransbongers@franss-mbp.home> | 2024-11-24 22:36:37 +0100 |
---|---|---|
committer | Frans Bongers <fransbongers@franss-mbp.home> | 2024-11-24 22:36:37 +0100 |
commit | 902a07087c2808c77943b9617a2ab063b1c260e9 (patch) | |
tree | 0d11c373a0da7ab35d23df0d881f8eeeb1d14322 /rules.js | |
parent | 1b0d1a568e4224f6f3ff927e06997b9152e86ddf (diff) | |
download | land-and-freedom-902a07087c2808c77943b9617a2ab063b1c260e9.tar.gz |
initial setup
Diffstat (limited to 'rules.js')
-rw-r--r-- | rules.js | 369 |
1 files changed, 269 insertions, 100 deletions
@@ -1,108 +1,277 @@ -"use strict" - -var states = {} -var game = null -var view = null - -exports.scenarios = [ "Standard" ] - -exports.roles = [ "Anarchist", "Moderate", "Fascist" ] - +'use strict'; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.roles = exports.scenarios = void 0; +exports.action = action; +exports.view = game_view; +exports.setup = setup; +const data_1 = require("./data"); +const states = {}; +let game = {}; // = null +var view = {}; // = null +const ANARCHIST = 'Anarchist'; +const COMMUNIST = 'Communist'; +const MODERATE = 'Moderate'; +const ANARCHISTS_ID = 'a'; +const COMMUNISTS_ID = 'c'; +const MODERATES_ID = 'm'; +const { cards, +// fronts + } = data_1.default; +const faction_cards = { + [ANARCHIST]: make_list(37, 54), + [COMMUNIST]: make_list(19, 36), + [MODERATE]: make_list(1, 18), +}; +const fascist_decks = { + 1: make_list(55, 62), +}; +exports.scenarios = ['Standard']; +exports.roles = [ANARCHIST, COMMUNIST, MODERATE]; function gen_action(action, argument) { - if (!(action in view.actions)) - view.actions[action] = [] - view.actions[action].push(argument) + if (!(action in view.actions)) + view.actions[action] = []; + view.actions[action].push(argument); } - function gen_action_space(space) { - gen_action("space", space) + gen_action('space', space); } - function gen_action_piece(piece) { - gen_action("piece", piece) -} - -function gen_action_card(card) { - gen_action("card", card) -} - -exports.action = function (state, player, action, arg) { - game = state - let S = states[game.state] - if (action in S) - S[action](arg, player) - else if (action === "undo" && game.undo && game.undo.length > 0) - pop_undo() - else - throw new Error("Invalid action: " + action) - return game -} - -exports.view = function (state, player) { - game = state - - view = { - log: game.log, - prompt: null, - location: game.location, - selected: game.selected, - } - - if (player !== game.active) { - let inactive = states[game.state].inactive || game.state - view.prompt = `Waiting for ${game.active} to ${inactive}.` - } 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 -} - -exports.setup = function (seed, scenario, options) { - game = { - seed: seed, - state: null, - active: "Anarchist", - log: [], - undo: [], - } - - game.state = "move" - - return game -} - + gen_action('piece', piece); +} +// function gen_action_card(card) { +// gen_action('card', card); +// } +function action(state, player, action, arg) { + game = state; + let S = states[game.state]; + if (action in S) + S[action](arg, player); + else if (action === 'undo' && game.undo && game.undo.length > 0) + pop_undo(); + else + throw new Error('Invalid action: ' + action); + return game; +} +function game_view(state, player) { + console.log('game_view', state); + console.log('player', player); + game = state; + const faction_id = get_faction_id(player); + view = { + log: game.log, + prompt: null, + location: game.location, + selected: game.selected, + current_events: game.current_events, + hand: game.hands[faction_id], + }; + if (player !== game.active) { + let inactive = states[game.state].inactive || game.state; + view.prompt = `Waiting for ${game.active} to ${inactive}.`; + } + 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; +} +// #endregion +// #region setup +function setup(seed, _scenario, _options) { + game = { + seed: seed, + state: null, + active: ANARCHIST, + bag_of_glory: { + [ANARCHISTS_ID]: 1, + [COMMUNISTS_ID]: 1, + [MODERATES_ID]: 1, + }, + bonuses: [data_1.ON, data_1.ON], + current_events: [], + fronts: { + a: 2, + m: 2, + n: 2, + s: 2, + }, + hands: { + [ANARCHISTS_ID]: [ + draw_card(faction_cards[ANARCHIST]), + draw_card(faction_cards[ANARCHIST]), + draw_card(faction_cards[ANARCHIST]), + draw_card(faction_cards[ANARCHIST]), + draw_card(faction_cards[ANARCHIST]), + ], + [COMMUNISTS_ID]: [ + draw_card(faction_cards[COMMUNIST]), + draw_card(faction_cards[COMMUNIST]), + draw_card(faction_cards[COMMUNIST]), + draw_card(faction_cards[COMMUNIST]), + draw_card(faction_cards[COMMUNIST]), + ], + [MODERATES_ID]: [ + draw_card(faction_cards[MODERATE]), + draw_card(faction_cards[MODERATE]), + draw_card(faction_cards[MODERATE]), + draw_card(faction_cards[MODERATE]), + draw_card(faction_cards[MODERATE]), + ], + }, + hero_points: { + [ANARCHISTS_ID]: 2, + [COMMUNISTS_ID]: 2, + [MODERATES_ID]: 0, + }, + initiative: MODERATES_ID, + tracks: [5, 5, 6, 3, 3], + log: [], + undo: [], + turn: 1, + year: 1, + }; + fascist_event(); + game.state = 'move'; + return game; +} +// #endregion states.move = { - inactive: "move", - prompt() { - view.prompt = "Move a piece." - for (let p = 0; p < 32; ++p) - gen_action_piece(p) - }, - piece(p) { - game.selected = p - game.state = "move_to" - }, -} - + inactive: 'move', + prompt() { + view.prompt = 'Move a piece.'; + for (let p = 0; p < 32; ++p) + gen_action_piece(p); + }, + // piece(p) { + // game.selected = p + // game.state = "move_to" + // }, +}; states.move_to = { - inactive: "move", - prompt() { - view.prompt = "Move the piece to a space." - for (let s = 0; s < 64; ++s) - gen_action_space(s) - }, - space(to) { - game.location[game.selected] = to - game.state = "move" - if (game.active === PLAYER1) - game.active = PLAYER2 - else - game.active = PLAYER1 - }, + inactive: 'move', + prompt() { + view.prompt = 'Move the piece to a space.'; + for (let s = 0; s < 64; ++s) + gen_action_space(s); + }, + // space(to) { + // game.location[game.selected] = to + // game.state = "move" + // if (game.active === PLAYER1) + // game.active = PLAYER2 + // else + // game.active = PLAYER1 + // }, +}; +function pop_undo() { + const save_log = game.log; + const save_undo = game.undo; + game = save_undo.pop(); + save_log.length = game.log; + game.log = save_log; + game.undo = save_undo; +} +// #region CARDS +// function draw_faction_card(faction: Player): CardId { +// return draw_faction_cards(faction, 1)[0]; +// } +// function draw_faction_cards(faction: Player, count: number = 1): CardId[] { +// const drawnCards = []; +// } +function draw_card(deck) { + clear_undo(); + let i = random(deck.length); + let c = deck[i]; + set_delete(deck, c); + return c; +} +// #endregion +// #region EVENTS +function resolve_event_attack(target, value) { + switch (target) { + case 'v': + break; + case 'd': + break; + default: + game.fronts[target] += value; + } +} +function fascist_event() { + const deck = fascist_decks[game.year]; + const cardId = draw_card(deck); + game.current_events.push(cardId); + const card = cards[cardId]; + card.effects.forEach((effect) => { + switch (effect.type) { + case 'attack': + resolve_event_attack(effect.target, effect.value); + break; + case 'bonus': + break; + case 'hero_points': + break; + case 'track': + game.tracks[effect.target] += effect.value; + break; + } + }); +} +// #endregion +// #region UTILITY +function clear_undo() { + if (game.undo.length > 0) + game.undo = []; +} +function get_faction_id(player) { + switch (player) { + case ANARCHIST: + return ANARCHISTS_ID; + case COMMUNIST: + return COMMUNISTS_ID; + case MODERATE: + return MODERATES_ID; + default: + throw new Error('Unknown player'); + } +} +function make_list(first, last) { + let list = []; + for (let i = first; i <= last; i++) + list.push(i); + return list; +} +function random(range) { + // An MLCG using integer arithmetic with doubles. + // https://www.ams.org/journals/mcom/1999-68-225/S0025-5718-99-00996-5/S0025-5718-99-00996-5.pdf + // m = 2**35 − 31 + return (game.seed = (game.seed * 200105) % 34359738337) % range; +} +function set_delete(set, item) { + let a = 0; + let b = set.length - 1; + while (a <= b) { + let m = (a + b) >> 1; + let x = set[m]; + if (item < x) + b = m - 1; + else if (item > x) + a = m + 1; + else { + array_remove(set, m); + return; + } + } +} +// #endregion +// #region ARRAY +function array_remove(array, index) { + let n = array.length; + for (let i = index + 1; i < n; ++i) + array[i - 1] = array[i]; + array.length = n - 1; } |