diff options
Diffstat (limited to 'rules.js')
-rw-r--r-- | rules.js | 225 |
1 files changed, 210 insertions, 15 deletions
@@ -6,23 +6,20 @@ show who controls which power in player list +set-aside victory marker areas + austria/pragmatic move order on flanders (start with pragmatic) only stack if agree (undo/move to previous space) winter scoring -tc draw - no TCs for minor power if major fortress enemy controlled +when are subsidies given? + example france subsidy to prussia + at france's stage? + at prussia's stage? -- advanced -- -VICTORY BOXES - vp for winning (tracks) - electors (check victory markers) - emperor (bit) - italy (bit) - silesia (bit) - silesia home country for prussia tc subsidies @@ -49,7 +46,6 @@ neutrality // PLAN: move all austria on bohemia first, then alternate pragmatic and austria activations on flanders map // TODO: confirm mixed stack creation on flanders map (force "undo" to previous location if denied?) -// TODO: supreme commander in mixed stacks // TODO: TC subsidies // TODO: subsidy markers? @@ -93,6 +89,7 @@ const F_EMPEROR_AUSTRIA = 2 const F_ITALY_FRANCE = 4 const F_ITALY_AUSTRIA = 8 const F_SILESIA_ANNEXED = 16 +const F_IMPERIAL_ELECTION = 32 // imperial election card revealed! const SPADES = 0 const CLUBS = 1 @@ -105,6 +102,7 @@ const IMPERIAL_ELECTION = 25 const ELIMINATED = data.cities.name.length const all_powers = [ 0, 1, 2, 3, 4, 5 ] +const all_major_powers = [ 0, 1, 2, 3 ] const all_power_generals = [ [ 0, 1, 2, 3, 4 ], @@ -1093,6 +1091,12 @@ function count_used_cards() { held[to_deck(c)]++ } + // count cards in saved political display + for (let pow of all_major_powers) { + for (let c of game.saved[pow]) + held[to_deck(c)]++ + } + // count cards currently being held if (game.draw) for (let c of game.draw) @@ -3112,8 +3116,6 @@ function finish_combat() { lose_vp(game.loser_power, n) } - delete game.loser_power - delete game.winner_power delete game.lost_generals delete game.lost_troops @@ -3218,11 +3220,151 @@ function check_instant_victory() { /* POLITICS */ +const POWER_FROM_POLITICAL_STAGE = [ + P_PRUSSIA, + P_FRANCE, + P_PRAGMATIC, + P_AUSTRIA, +] + +function set_active_political_power() { + set_active_to_power(POWER_FROM_POLITICAL_STAGE[game.stage]) +} + function goto_politics() { - end_politics() + game.political = [] + game.display = [ 0, 0, 0, 0 ] + game.stage = 0 + + while (game.political.length < 2) { + let pc = game.pol_deck.pop() + if (pc === IMPERIAL_ELECTION) + game.flags |= F_IMPERIAL_ELECTION + else + game.political.push(pc) + } + + if (game.winner_power >= 0) { + set_active_to_power(game.winner_power) + game.state = "determine_trump_suit" + } else { + for (;;) { + draw_tc(1) + log("Trump " + format_card(game.draw[0]) + ".") + if (!is_reserve(game.draw[0])) { + game.trump = to_suit(game.draw[0]) + break + } + delete game.draw + } + goto_place_tc_on_display() + } +} + +states.determine_trump_suit = { + inactive: "determine the political trump suit", + prompt() { + prompt("Determine the political trump suit.") + view.actions.suit = [ 0, 1, 2, 3 ] + }, + suit(s) { + game.trump = s + goto_place_tc_on_display() + } +} + +function goto_place_tc_on_display() { + set_active_political_power() + game.state = "place_tc_on_display" +} + +states.place_tc_on_display = { + inactive: "place TC on political display", + prompt() { + prompt(`Place TC on political display (${suit_name[game.trump]} is trump).`) + for (let c of game.hand[game.power]) + gen_action_card(c) + view.actions.pass = 1 + }, + card(c) { + push_undo() + log(power_name[game.power] + " placed a TC.") + set_delete(game.hand[game.power], c) + game.display[game.power] = c + game.state = "place_tc_on_display_done" + }, + pass() { + log(power_name[game.power] + " passed.") + end_place_tc_on_display() + }, +} + +states.place_tc_on_display_done = { + inactive: "place TC on political display", + prompt() { + prompt(`Place TC on political display (${suit_name[game.trump]} is trump) done.`) + view.actions.next = 1 + }, + next() { + end_place_tc_on_display() + }, +} + +function end_place_tc_on_display() { + if (++game.stage === 4) + goto_determine_order_of_influence() + else + goto_place_tc_on_display() +} + +function goto_determine_order_of_influence() { + // Turn cards face-up and return bluff cards + for (let pow of all_major_powers) { + let c = game.display[pow] + if (c > 0) { + if (to_suit(c) === game.trump) { + log(power_name[pow] + " played " + format_card(c) + ".") + set_add(game.saved[pow], c) + } else { + log(power_name[pow] + " bluffed " + format_card(c) + ".") + set_add(game.hand[pow], c) + } + } + } + delete game.display + + game.stage = 4 + goto_select_political_cards() +} + +function goto_select_political_cards() { + if (--game.stage < 0) + end_politics() + set_active_to_power(most_influence()) + game.state = "select_political_card" +} + +states.select_political_card = { + inactive: "select a political card", + prompt() { + prompt(`Select a political card or save your TC.`) + for (let pc of game.political) + gen_action_political(pc) + view.actions.pass = 1 + }, + political(pc) { + push_undo() + log(power_name[game.power] + " chose C" + pc + ".") + throw "TODO" + }, + pass() { + log(power_name[game.power] + " saved its TC.") + goto_select_political_cards() + }, } function end_politics() { + delete game.political if (check_instant_victory()) return goto_place_hussars() @@ -3238,8 +3380,7 @@ const POWER_FROM_SETUP_STAGE = [ ] function set_active_setup_power() { - game.power = POWER_FROM_SETUP_STAGE[game.stage] - game.active = current_player() + set_active_to_power(POWER_FROM_SETUP_STAGE[game.stage]) } const setup_initial_tcs = [ 2, 9, 3, 5, 5, 3 ] @@ -3366,6 +3507,9 @@ function make_tactics_discard(n) { for (let pow of all_powers) if (set_has(game.hand[pow], c)) return false + for (let pow of all_major_powers) + if (set_has(game.saved[pow], c)) + return false return true }) } @@ -3389,9 +3533,16 @@ exports.setup = function (seed, _scenario, _options) { italy: 5, // political track flags: 0, // emperor vp, italy vp, silesia annexed, etc + // for tracking VP gains/losses and political trump suit + winner_power: -1, + loser_power: -1, + trump: SPADES, + pol_deck: null, deck: null, hand: [ [], [], [], [], [], [] ], + saved: [ [], [], [], [] ], + display: [ [], [], [], [] ], pos: setup_piece_position.slice(), oos: 0, @@ -3526,6 +3677,16 @@ function end_setup() { /* VIEW */ +function mask_pol_deck() { + if (game.pol_deck.length > 0) { + let top = game.pol_deck[game.pol_deck.length - 1] + if (top === IMPERIAL_ELECTION) + return 2 + return 1 + ((top-1) / 6 | 0) + } + return 0 +} + function mask_troops(player) { let view_troops = [] for (let pow of all_powers) { @@ -3559,6 +3720,30 @@ function mask_hand(player) { return view_hand } +function mask_display(player) { + let view_display = [] + for (let pow of all_major_powers) { + if (game.display[pow] === 0) + view_display[pow] = -1 + else if (player_from_power(pow) === player) + view_display[pow] = game.display[pow] + else + view_display[pow] = game.display[pow] & ~127 + } + return view_display +} + +function mask_saved(player) { + let view_saved = [] + for (let pow of all_major_powers) { + if (player_from_power(pow) === player) + view_saved[pow] = game.saved[pow] + else + view_saved[pow] = game.saved[pow].map(c => c & ~127) + } + return view_saved +} + function total_troops_list() { let list = [] for (let pow of all_powers) { @@ -3594,6 +3779,9 @@ exports.view = function (state, player) { pt: total_troops_list(), discard: total_discard_list(), + pol_deck: mask_pol_deck(), + saved: mask_saved(player), + power: game.power, retro: game.retro, } @@ -3603,6 +3791,9 @@ exports.view = function (state, player) { view.defender = game.defender } + if (game.display) + view.display = mask_display(player) + if (game.state === "game_over") { view.prompt = game.victory view.troops = game.troops @@ -3693,6 +3884,10 @@ function gen_action_card(c) { gen_action("card", c) } +function gen_action_political(c) { + gen_action("political", c) +} + function log(msg) { game.log.push(msg) } |