diff options
author | iainp5 <iain.pearce.ip@gmail.com> | 2024-11-23 08:51:45 +0000 |
---|---|---|
committer | iainp5 <iain.pearce.ip@gmail.com> | 2024-11-23 08:51:45 +0000 |
commit | a35b49e654f2ad82c14855b3c36195c2c2e26d10 (patch) | |
tree | 0f56a45c62741907a2ac9dbbe315e025af2dcd7c /rules.js | |
parent | dd4ef001caac00050d00f8ae1dfa87da9e95eb7c (diff) | |
parent | db464d9b4adb87cd4316f59058b6b70f61fbeaa3 (diff) | |
download | 1989-dawn-of-freedom-a35b49e654f2ad82c14855b3c36195c2c2e26d10.tar.gz |
Merge branch 'work-in-progress'
Diffstat (limited to 'rules.js')
-rw-r--r-- | rules.js | 18574 |
1 files changed, 8917 insertions, 9657 deletions
@@ -1,9657 +1,8917 @@ -//"use strict"
-
-const { spaces, cards, power_cards } = require("./data.js")
-
-var game, view, states = {}
-
-const DEM = "Democrat"
-const COM = "Communist"
-
-const first_strategy_card = 1
-const last_strategy_card = 110
-
-const dem_tst_req = [5, 5, 6, 6, 7, 8, 9, 10]
-const com_tst_req = [6, 6, 7, 7, 8, 7, 6, 5]
-const scoring_cards = [22, 23, 42, 43, 55, 95]
-const leader_cards = [37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48]
-const leaders = [1, 4, 5, 6, 7]
-const support_loss_roll = [0, 0, 1, 1, 2, 2, 3, 4]
-const vp_roll = [0, 0, 1, 1, 2, 2, 3, 4]
-const countries = ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania']
-const elite_spaces = [12, 15, 27, 43, 51, 69]
-const all_power_cards = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 ]
-const numberless_cards = [25, 26, 27, 28, 29, 30, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52]
-const auto_resolve_events = [5, 8, 9, 13, 17, 25, 26, 30, 35, 50, 53, 54, 58, 59, 62, 63, 65, 70, 72, 74, 99, 102, 108]
-const switch_events = [6, 20, 71]
-
-exports.scenarios = [ "Standard" ]
-
-exports.roles = [ DEM, COM ]
-
-// --- SET UP ---
-
-exports.setup = function (seed, scenario, options) {
- game = {
- seed: seed,
- log: [],
- undo: [],
- summary: [],
- active: null,
- state: "com_init",
- return: '',
- vm: null,
- vm_event: 0,
- vm_event_to_do: false,
- vm_infl_to_do: false,
-
- played_card: 0,
- table_cards: [],
- available_ops: 0,
- vm_available_ops: 0,
- valid_spaces: [],
- valid_cards: [],
-
- vp: 0,
- turn: 0,
- round: 0,
- round_player: COM,
- stability: 0,
- dem_tst_position: 0,
- com_tst_position: 0,
- dem_tst_attempted: 0,
- com_tst_attempted: 0,
- dem_tst_attempted_this_turn: 0,
- com_tst_attempted_this_turn: 0,
-
- demInfl: [],
- comInfl: [],
-
- strategy_deck: [],
- strategy_discard: [],
- discard: false,
- view_opp_hand: false,
- strategy_removed: [],
- persistent_events: [],
- power_struggle_deck: [],
- power_struggle_discard: [],
- dem_hand_limit: 8,
- com_hand_limit: 8,
- democrat_hand: [],
- communist_hand: [],
-
- pwr_struggle_in: [],
- is_pwr_struggle: false,
- dem_pwr_hand_limit: 0,
- com_pwr_hand_limit: 0,
- dem_pwr_hand: [],
- com_pwr_hand: [],
- raised_stakes_discard: 0,
- raised_stakes: 0,
- raised_stakes_round: 0,
- phase: 0,
- times_held: [0, 0, 0, 0, 0, 0],
- revolutions: [false, false, false, false, false, false],
- remove_opponent_infl: false,
- tactics_fails: '',
- }
-
- log_h1("1989 Dawn of Freedom")
-
- game.active = COM
- start_game()
-
- return game
-}
-
-function start_game() {
- //starting influence
-
- // Draw cards
- /* const card_numbers = cards.filter(card => card !== null && card !== undefined).map(card => card.number);
- console.log('card numbers: ', card_numbers) */
- game.strategy_deck = draw_deck(cards)
- reset_power()
-
- //Set starting influence
- spaces.forEach((space, index) => {
- if (space !== null) {
- game.demInfl[index] = space.demInfl
- game.comInfl[index] = space.comInfl
- }
- })
-
- //Set starting placement ops
- game.starting_infl = {
- com_starting_infl: 0,
- dem_starting_infl: 0
- },
-
- // Set variable event cards where event is playable at start of game
-
- game.playable_cards = [14, 15, 21, 70]
-
- //console.log('game.strategy_deck: ', game.strategy_deck[1])
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.dem_hand_limit, game.com_hand_limit)
- //.log('game.strategy_deck: ', game.strategy_deck[1], 'democrat_hand:', game.democrat_hand)
-
- game.valid_spaces = valid_spaces_setup()
- game.available_ops = 2
- game.phase = 0
- log_h1("Place starting Support Points")
- log_side()
-}
-
-
-exports.view = function(state, player) {
- game = state
-
- view = {
- log: game.log,
- active: game.active,
- prompt: null,
- actions: null,
-
- played_card: game.played_card,
- table_cards: game.table_cards,
- valid_spaces: game.valid_spaces,
- valid_cards: game.valid_cards,
-
- demInfl: game.demInfl,
- comInfl: game.comInfl,
- turn: game.turn,
- round: game.round,
- round_player: game.round_player,
- vp: game.vp,
- stability: game.stability,
- dem_tst: game.dem_tst_position,
- com_tst: game.com_tst_position,
- persistent_events: game.persistent_events,
- systematization: game.systematization,
- the_tyrant_is_gone: game.the_tyrant_is_gone,
-
- strategy_deck: game.strategy_deck.length,
- strategy_removed: game.strategy_removed,
- discard: game.discard,
- show_opp_hand: game.view_opp_hand,
-
- democrat_hand: game.democrat_hand.length,
- communist_hand: game.communist_hand.length,
- democrat_power_hand: game.dem_pwr_hand.length,
- communist_power_hand: game.com_pwr_hand.length,
- ceausescu_cards: game.ceausescu_cards,
- is_pwr_struggle: game.is_pwr_struggle,
- times_held: game.times_held,
- revolutions: game.revolutions,
-
- hand: [],
- set_aside: [],
- pwr_hand: [],
-
-
- }
-
- if (game.is_pwr_struggle) {
- view.strategy_discard = game.power_struggle_discard
- } else {
- view.strategy_discard = game.strategy_discard
- }
-
- if (player === game.active && game.vm && game.vm.draw)
- view.drawn = game.vm.draw
-
- if (player === game.active) {
- if (game.selected_space > 0 ) {
- view.valid_spaces = [game.selected_space]
- } else {
- view.valid_spaces = game.valid_spaces
- }
- } else {
- view.valid_spaces = []
- }
-
- if (player === game.active) {
- view.valid_cards = game.valid_cards
- } else {
- view.valid_cards = []
- }
-
- if (player === DEM) {
- view.hand = game.democrat_hand
- if (game.communist_hand_red) {
- view.opp_hand = game.communist_hand_red
- }
- view.set_aside = game.democrat_set_aside /*Is this being used? */
- view.power_hand = game.dem_pwr_hand.sort((a, b) => a - b)
-
- } else if (player === COM) {
- view.hand = game.communist_hand
- view.opp_hand = game.dem_pwr_hand.sort((a, b) => a - b) /*Does the Communist ever see Democrat hand? */
- view.power_hand = game.com_pwr_hand.sort((a, b) => a - b)
- }
-
- if (game.active === DEM) {
- view.samizdat = game.samizdat_card
- }
-
- if (game.state === "game_over") {
- view.prompt = game.victory
- } else if (player === "Observer" || (game.active !== player && game.active !== "Both")) {
- if (states[game.state]) {
- let inactive = states[game.state].inactive
- if (typeof inactive === "function")
- view.prompt = `Waiting for ${game.active} ${inactive()}`
- else
- view.prompt = `Waiting for ${game.active} to ${inactive}`
- } else {
- view.prompt = "A Unknown state: " + game.state
- }
- } else {
- view.actions = {}
-
- if (states[game.state])
- states[game.state].prompt(player)
- else
- view.prompt = "B Unknown state: " + game.state
- if (view.actions.undo === undefined) {
- if (game.undo && game.undo.length > 0)
- view.actions.undo = 1
- else
- view.actions.undo = 0
- }
- }
-
- return view
-}
-
-
-// === ACTIONS ===========
-
-function gen_action(action, argument) {
-//console.log('gen_action called with ', action, ' and ', argument)
- if (argument === undefined) {
- //console.log('argument undefined')
- view.actions[action] = 1
- } else {
- if (!(action in view.actions)) {
- //console.log('push argument')
- view.actions[action] = []
- }
- view.actions[action].push(argument)
- }
- //console.log('view.actions: ', view.actions, 'view.actions[action]: ', view.actions[action])
-}
-
-function gen_action_infl(space){
- gen_action("infl", space)
-}
-
-function gen_action_card(card){
- gen_action("card", card)
-}
-
-function gen_action_sc(space){
- gen_action("sc", space)
-}
-
-function gen_action_scoring(){
- gen_action("scoring")
-}
-
-exports.action = function (state, player, action, arg) {
- //console.log('exports.action called with state:' , state, 'player:', player, 'action: ', action, 'arg: ', arg)
- game = state
- if (states[game.state] && action in states[game.state]) {
- states[game.state][action](arg, player)
- } else {
- if (action === "undo" && game.undo && game.undo.length > 0)
- pop_undo()
- else
- throw new Error("Invalid action: " + action)
- }
- return game
-}
-
-// ============= GAME STATES =======================
-
-states.com_init = {
- inactive: 'place starting SPs',
- prompt() {
- if (game.available_ops == 0) {
- view.prompt = 'Place starting SPs: done.';
- gen_action("done");
- return;
- } else if (game.starting_infl.dem_starting_infl === 2) {
- view.prompt = `Place your last ${pluralize(game.available_ops,'starting SP')}.`
- } else {
- view.prompt = `Place ${pluralize(game.available_ops,'starting SP')}.`
- }
- for (let space_id of game.valid_spaces) {
- if (space_id) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- }
- },
- infl(space) {
- add_infl(space)
-
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- game.starting_infl.com_starting_infl++
- if (game.starting_infl.com_starting_infl == 1){
- game.available_ops = 3
- game.state = 'dem_init'
- valid_spaces_setup()
- next_player()
- } else if (game.starting_infl.com_starting_infl == 2) {
- game.available_ops = 4
- game.state = 'dem_init'
- valid_spaces_setup()
- next_player()
- } else if (game.starting_infl.com_starting_infl == 3) {
- delete game.starting_infl
- game.state = 'start_game'
- }
- }
-}
-
-states.dem_init = {
- inactive: 'place starting SPs.',
- prompt() {
- if (game.available_ops == 0) {
- view.prompt = 'Place starting SPs: done.';
- gen_action("done");
- return;
- } else if (game.starting_infl.com_starting_infl === 2) {
- view.prompt = `Place your last ${pluralize(game.available_ops,'starting SP')}.`
- } else {
- view.prompt = `Place ${pluralize(game.available_ops,'starting SP')}.`
- }
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- },
- infl(space) {
- add_infl(space)
- },
-
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- game.starting_infl.dem_starting_infl++
- if (game.starting_infl.dem_starting_infl == 1){
- game.available_ops = 3
- } else if (game.starting_infl.dem_starting_infl == 2) {
- game.available_ops = 2
- }
- game.state = 'com_init'
- valid_spaces_setup()
- next_player()
- }
-}
-
-states.start_game = {
- inactive: 'start Turn 1.',
- prompt() {
- view.prompt = 'Start Turn 1.'
- gen_action('start')
- },
- start() {
- new_turn()
- clear_undo()
- game.state = 'choose_card'
- }
-}
-
-states.choose_card = {
- inactive: 'choose a card.',
- prompt() {
- /*if (game.played_card > 0) {
- game.state = 'play_card'
- view.prompt = 'Choose a card: done.'
- gen_action("done");
- return;
- } */
- if ((game.active===DEM && game.democrat_hand.length === 0) || game.active === COM && game.communist_hand.length === 0) {
- view.prompt = 'No cards remaining: you must pass.'
- gen_action('pass')
- } else {
- view.prompt = 'Play a card.'
- let available_cards
- if (game.active === DEM) {
- available_cards = game.democrat_hand
- } else {
- available_cards = game.communist_hand
- }
- for (let card of available_cards) {
- //gen_action('card_event', card)
-
- if (scoring_cards.includes(card)) {
- /*view.prompt = 'Play for:'*/
- gen_action('card_event', card)
- }
-
-
- //Check for Tiananmen Square Track awards special abilities
-
- if ((game.active === DEM && cards[card].side !== 'C' && game.dem_tst_position >= 7 && game.com_tst_position < 7 && !game.tst_7) || (game.active === COM && cards[card].side !== 'D' && game.com_tst_position >= 7 && game.dem_tst_position < 7 && !game.tst_7)){
- gen_action('card_tst_7', card)
- }
-
- console.log('game.tst_8', game.tst_8)
- if ((game.active === DEM && cards[card].side !== 'C' && game.dem_tst_position >= 8 && game.com_tst_position < 8 && !game.tst_8) || (game.active === COM && cards[card].side !== 'D' && game.com_tst_position >= 8 && game.dem_tst_position < 8 && !game.tst_8)){
- gen_action('card_tst_8', card)
- }
-
- // Check for Reformer Rehabilitated
-
- //console.log('game.active', game.active, 'game.playable_cards[67].playable', game.playable_cards[67].playable)
-
-
- if (card === 67 && game.playable_cards.includes(67)){
- if (game.active === DEM && (game.dem_tst_position > game.com_tst_position)) {
- gen_action('card_event', card)
- }
- if (game.active === COM && (game.dem_tst_position < game.com_tst_position)) {
- gen_action('card_event', card)
- }
- }
-
- //Continue with normal logic
-
- //Check if it is a card with an event which is always playable
-
- if (cards[card].playable) {
- get_events(card)
- }
-
- // Resolve cards with variable events (not Reformer)
-
- if (card !== 67 && game.playable_cards.includes(card)) {
- get_events(card)
- }
-
- //Actions for non-scoring cards
-
- if (!scoring_cards.includes(card)) {
- gen_action('card_influence', card)
- if (game.active === DEM && game.dem_tst_attempted_this_turn === 0 && game.dem_tst_position <=8 || game.active === COM && game.com_tst_attempted_this_turn === 0 && game.com_tst_position <= 8) {
- gen_action('card_tst', card)
- }
- gen_action('card_support_check', card)
- }
- }
- }
- },
- /*card_event(card) {
- push_undo()
- //Check if player is at risk of losing game due to held scoring card
- if (!scoring_cards.includes(card)) {
- let scoring_cards_count = count_scoring_cards()
-
- if (game.round !== 8 && scoring_cards_count >= (8-game.round)){
- game.temp = card
- game.state = 'confirm_card'
- return
- }
- }
- select_card(card)
- },*/
- pass() {
- log('No cards remaining. Passed')
- end_round()
- },
- card_event(card) {
- push_undo()
- select_card(card)
- console.log('played event, game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- if (scoring_cards.includes(game.played_card)) {game.phase = 0}
- else {game.phase = 1}
- game.return = game.active
- if (switch_events.includes(game.played_card)) {next_player()}
- game.vm_event = game.played_card
- goto_vm(game.vm_event)
- },
- card_opp_event(card) {
- push_undo()
- select_card(card)
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- game.phase = 1 /*Do I still need this?*/
- game.vm_infl_to_do = true
- game.return = game.active
- game.vm_event = game.played_card
- if (auto_resolve_events.includes(game.played_card) || switch_events.includes(game.played_card)) {
- goto_vm(game.vm_event)}
- else {
- next_player()
- log(`C${game.vm_event}`)
- goto_vm(game.vm_event)
- }
- },
- card_influence(card) {
- push_undo()
- select_card(card)
- log_gap(`Played C${cards[game.played_card].number} to place SPs`)
-
-
- // Check if Common European Home played for influence
- if (game.played_card === 21) {
- if (game.active === DEM) {
- game.vp --
- log('-1 VP')
- if (check_vp()) {
- return
- }
- } else {
- game.vp ++
- log('+1 VP')
- if (check_vp()) {
- return
- }
- }
- }
- // Check if card is opponent card with event that needs to be resolved
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- //game.phase = 1 /*Do I need this? */
- game.vm_event_to_do = true
- }
- }
-
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state='add_influence'
- valid_spaces_infl()
- },
- card_tst(card) {
- push_undo()
- select_card(card)
- log_gap(`Played C${cards[game.played_card].number} to the Tiananmen Square Track`)
- game.state='tiananmen_square_attempt'
- },
- card_support_check(card) {
- push_undo()
- select_card(card)
- log_gap(`Played C${cards[game.played_card].number} for support checks`)
-
- // Check if card is opponent card with event that needs to be resolved
- /*if (game.phase === 0 && game.active === DEM && cards[game.played_card].side === "C" && game.playable_cards[game.played_card].playable === 1 || game.phase === 0 && game.active === COM && cards[game.played_card].side === "D" && game.playable_cards[game.played_card].playable === 1 ) {
- game.vm_event_to_do = true
- }*/
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- game.vm_event_to_do = true
- }
- }
-
- game.available_ops = 2
- game.state='support_check_prep'
- valid_spaces_sc()
- },
- card_tst_7() {
- select_card(card)
- game.vm_infl_to_do = true
- game.tst_7 = true
- game.state = 'resolve_opponent_event'
- },
- card_tst_8(card) { /*Play card for ops and event */
- select_card(card)
- game.vm_event_to_do = true
- game.vm_infl_to_do = true
- game.tst_8 = true
- game.state = 'vm_tst_8'
- },
-
- /*done () {
- game.state = 'play_card'
- } */
-}
-
-states.confirm_card = {
- inactive: 'choose a card.',
- prompt() {
- let scoring_cards_count = count_scoring_cards()
- view.prompt = `${pluralize(scoring_cards_count,'scoring card')} in hand with ${pluralize(8-game.round,'turn')} remaining. Scoring cards may not be held. Continue?`
- gen_action('continue')
- },
- continue() {
- select_card(game.temp)
- }
-}
-
-states.play_card ={
- get inactive() {
- return `play ${clean_name(cards[game.played_card].name)}.`
- },
- prompt () {
- if (game.phase >= 1) {
- view.prompt = `${clean_name(cards[game.played_card].name)}: done.`
- gen_action('done')
- return
- }
-
- view.prompt = `Play ${clean_name(cards[game.played_card].name)} for:`
-
- if (scoring_cards.includes(game.played_card)) {
- /*view.prompt = 'Play for:'*/
- gen_action('event')
- return
- }
-
-
- //Check for Tiananmen Square Track awards special abilities
- if ((game.active === DEM && cards[game.played_card].side !== 'C' && game.dem_tst_position >= 8 && game.com_tst_position < 8 && !game.tst_8) || (game.active === COM && cards[game.played_card].side !== 'D' && game.com_tst_position >= 8 && game.dem_tst_position < 8 && !game.tst_8)){
- gen_action('tst_8')
- }
-
- // Check for Reformer Rehabilitated
-
- //console.log('game.active', game.active, 'game.playable_cards[67].playable', game.playable_cards[67].playable)
-
-
- if (game.played_card === 67 && game.playable_cards.includes(67)){
- if (game.active === DEM && (game.dem_tst_position > game.com_tst_position)) {
- gen_action('event')
- }
- if (game.active === COM && (game.dem_tst_position < game.com_tst_position)) {
- gen_action('event')
- }
- }
-
- //Continue with normal logic
-
- //Check if it is a card with an event which is always playable
-
- if (cards[game.played_card].playable) {
- get_events(game.played_card)
- }
-
- // Resolve cards with variable events (not Reformer)
-
- if (game.played_card !== 67 && game.playable_cards.includes(game.played_card)) {
- get_events(game.played_card)
- } /*
- if ((game.active === DEM && cards[game.played_card].side === 'D' && game.playable_cards[game.played_card].playable === 1) || (game.active === COM && cards[game.played_card].side === 'C' && game.playable_cards[game.played_card].playable ===1) || (cards[game.played_card].side === 'N'&& game.playable_cards[game.played_card].playable ===1)) {
- gen_action('event')
- } else if ((game.active === DEM && (cards[game.played_card].side === 'C' && game.playable_cards[game.played_card].playable ===1)) || game.active === COM && (cards[game.played_card].side === 'D' && game.playable_cards[game.played_card].playable ===1)) {
- gen_action('opp_event')
- } */
-
- gen_action('influence')
- if (game.active === DEM && game.dem_tst_attempted_this_turn === 0 && game.dem_tst_position <=8 || game.active === COM && game.com_tst_attempted_this_turn === 0 && game.com_tst_position <= 8) {
- gen_action('tst')
- }
- gen_action('support_check')
- },
- event() {
- push_undo()
- console.log('played event, game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- if (scoring_cards.includes(game.played_card)) {game.phase = 0}
- else {game.phase = 1}
- game.return = game.active
- if (switch_events.includes(game.played_card)) {next_player()}
- game.vm_event = game.played_card
- goto_vm(game.vm_event)
- },
- opp_event() {
- push_undo()
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- game.phase = 1 /*Do I still need this?*/
- game.vm_infl_to_do = true
- game.return = game.active
- game.vm_event = game.played_card
- if (auto_resolve_events.includes(game.played_card) || switch_events.includes(game.played_card)) {
- goto_vm(game.vm_event)}
- else {
- next_player()
- log(`C${game.vm_event}`)
- goto_vm(game.vm_event)
- }
- },
- influence() {
- push_undo()
- log_gap(`Played C${cards[game.played_card].number} to place SPs`)
-
-
- // Check if Common European Home played for influence
- if (game.played_card === 21) {
- if (game.active === DEM) {
- game.vp --
- log('-1 VP')
- if (check_vp()) {
- return
- }
- } else {
- game.vp ++
- log('+1 VP')
- if (check_vp()) {
- return
- }
- }
- }
- // Check if card is opponent card with event that needs to be resolved
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- //game.phase = 1 /*Do I need this? */
- game.vm_event_to_do = true
- }
- }
-
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state='add_influence'
- valid_spaces_infl()
- },
- tst() {
- push_undo()
- log_gap(`Played C${cards[game.played_card].number} to the Tiananmen Square Track`)
- game.state='tiananmen_square_attempt'
- },
- support_check() {
- push_undo()
- log_gap(`Played C${cards[game.played_card].number} for support checks`)
-
- // Check if card is opponent card with event that needs to be resolved
- /*if (game.phase === 0 && game.active === DEM && cards[game.played_card].side === "C" && game.playable_cards[game.played_card].playable === 1 || game.phase === 0 && game.active === COM && cards[game.played_card].side === "D" && game.playable_cards[game.played_card].playable === 1 ) {
- game.vm_event_to_do = true
- }*/
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- game.vm_event_to_do = true
- }
- }
-
-
-
- game.available_ops = 2
- game.state='support_check_prep'
- valid_spaces_sc()
- },
- tst_8() { /*Play card for ops and event */
- game.vm_event_to_do = true
- game.vm_infl_to_do = true
- game.tst_8 = true
- game.state = 'vm_tst_8'
- },
- done () {
- end_round()
- }
-
-}
-
-states.resolve_opponent_event = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- console.log('in resolve opponent event: discard', game.strategy_discard)
- if (game.vm_infl_to_do) {
- view.prompt = 'Event resolved. Choose to play card for:'
- gen_action('influence')
- gen_action('support_check')
- } else if (game.vm_event_to_do) {
- // Check for Tiananmen Square Track ability - play opponent card without triggering event
- if ((game.active === DEM && game.dem_tst_position >= 7 && game.com_tst_position < 7 && !game.tst_7) || (game.active === COM && game.com_tst_position >= 7 && game.dem_tst_position < 7 && !game.tst_7)){
- gen_action('tst_7')
- }
- view.prompt = `${clean_name(cards[game.played_card].name)}: you must resolve the opponent event.`
- gen_action('opp_event')
- } else {
- view.prompt = 'Event resolved. End the action round.'
- gen_action('done')
- }
- },
- influence(){
- push_undo()
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'finish_add_infl'
- valid_spaces_infl()
- },
- support_check() {
- push_undo()
- game.available_ops = 2
- game.state = 'finish_support_check_prep'
- valid_spaces_sc()
- },
- opp_event() {
- game.vm_event_to_do = false
- game.return_state = 'resolve_opponent_event'
- if (auto_resolve_events.includes(game.played_card) || switch_events.includes(game.played_card)) {
- game.return = game.active
- log(`Played C${game.played_card} for the event`)
- goto_vm(game.played_card)}
- else {
- if (game.active === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- next_player()
- log(`C${game.played_card}`)
- goto_vm(game.played_card)
- }
- },
- tst_7() {
- push_undo()
- log('Event cancelled using Tiananmen Square Track Award')
- game.tst_7 = true
- game.vm_event_to_do = false
- },
- done() {
- /*if(game.round_player === COM && game.active === DEM) {
- log_h3('End of Communist Action Round')
- change_player()
- } */
- end_round()
- }
-}
-
-
-states.finish_add_infl = {
- inactive: 'add SPs.',
- prompt () {
- if (game.available_ops === 0) {
- view.prompt = 'Place SPs: done.'
- gen_action("done")
- return;
- }
-
- view.prompt = `Add SPs: ${game.available_ops} remaining`
-
- // Generate actions for valid spaces
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique)
- }
- },
- infl(space) {
- add_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- end_round()
- }
-}
-
-states.finish_support_check_prep = {
- inactive: 'do support checks.',
- prompt () {
- if (game.available_ops === 0) {
- view.prompt = 'Support checks: done.'
- gen_action('done')
- //return
- } else {
- view.prompt = `Select a space. ${pluralize(game.available_ops, 'support check')} remaining.`
- for (let space_id of game.valid_spaces) {
- gen_action_sc(spaces[space_id].name_unique)
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = find_space_index(space)
- // Check for Austria-Hungary Border Reopened - check on first support check only
- //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
- if (game.persistent_events.includes(58)){
- if (game.active === DEM && game.available_ops > 1) {
- //console.log('in ahb check, country, ', spaces[game.selected_space].country, 'ahb', 'austria_hungary_border_reopened'])
- if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
- game.state = 'finish_austria_hungary_border_reopened_check'
- return
- }
- }
- }
- game.state = 'finish_do_support_check'
- },
- done () {
- end_round()
- }
-}
-
-states.finish_austria_hungary_border_reopened_check = {
- inactive: 'decide Austria-Hungary Border Reopened',
- prompt() {
- view.prompt = 'Austria-Hungary Border Reopened: will both support checks be in East Germany?'
- gen_action('yes')
- gen_action('no')
- },
- yes() {
- game.austria_hungary_border_reopened_tracker = true
- game.state = 'finish_do_support_check'
- },
- no() {
- game.state = 'finish_do_support_check'
- }
-}
-
-states.finish_do_support_check = {
- inactive: 'do support checks',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(spaces[game.selected_space].name_unique)
- game.available_ops--
- if (game.available_ops === 0) {
- game.valid_spaces = []
- }
- game.state = 'finish_support_check_prep'
- return
- }
-}
-
-states.add_influence = {
- inactive: 'add SPs.',
- prompt () {
- if (game.available_ops <= 0) {
- view.prompt = 'Place SPs: done.'
- gen_action("done")
- return
- }
-
- view.prompt = `Add SPs: ${game.available_ops} remaining.`
-
- // Generate actions for valid spaces
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- },
- infl(space) {
- add_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- if(game.vm_event_to_do) {
- reset_austria_hungary_border_reopened()
- game.state = 'resolve_opponent_event'}
- else {
- end_round()}
- }
-}
-
-states.tiananmen_square_attempt = {
- inactive: 'do Tiananmen Square Attempt.',
- prompt () {
- view.prompt = 'Tiananmen Square Track attempt: Roll a die.'
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_tst_attempt ()
- }
-}
-
-states.tiananmen_square_attempt_success = {
- inactive: 'do Tiananmen Square Attempt.',
- prompt () {
- view.prompt = 'Tiananmen Square Track attempt successful.'
- gen_action('done')
- },
- done () {
- end_round()
- }
-}
-
-states.tiananmen_square_attempt_fail = {
- inactive: 'do Tiananmen Square Attempt.',
- prompt () {
- view.prompt = 'Tiananmen Square Track attempt failed.'
- gen_action('done')
- },
- done () {
- end_round()
- }
-}
-
-states.tst_goddess = {
- inactive: 'choose whether to discard a card.',
- prompt() {
- //if (game.phase === 0) {
- view.prompt = 'Tiananmen Square Track award: you may discard a non-Power Struggle Card and draw a replacement.'
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- gen_action('pass')
- /*} else {
- view.prompt = 'Discard a card: done.'
- gen_action('done')
- }*/
- },
- card(card) {
- push_undo()
- discard(card)
- game.valid_cards = []
- game.state = 'tst_goddess_draw'
- //game.phase++
- /*if (game.active === DEM) {
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length +1, game.communist_hand.length)
- } else {
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length +1)
- }*/
- },
- pass() {
- log('Did not discard')
- log_h2("Action Round " + game.round)
- if (game.active === DEM) {
- next_player()
- } else {
- log_side()
- }
- if (game.persistent_events.includes(5)) {
- game.state = 'general_strike'
- } else {
- game.state = 'choose_card'
- }
- },
- done() {
-
- log_h2("Action Round " + game.round)
- if (game.active === DEM) {
- next_player()
- } else {
- log_side()
- }
- game.phase = 0
- if (game.persistent_events.includes(5)) {
- game.state = 'general_strike'
- } else {
- game.state = 'choose_card'
- }
- }
-}
-
-states.tst_goddess_draw = {
- inactive: 'choose whether to discard a card.',
- prompt() {
- view.prompt = 'Draw a replacement card.'
- gen_action('draw')
- },
- draw() {
- if (game.active === DEM) {
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length +1, game.communist_hand.length)
- } else {
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length +1)
- }
- log_h2("Action Round " + game.round)
- if (game.active === DEM) {
- next_player()
- } else {
- log_side()
- }
- game.phase = 0
- if (game.persistent_events.includes(5)) {
- game.state = 'general_strike'
- } else {
- game.state = 'choose_card'
- }
- }
-}
-
-
-
-states.support_check_prep = {
- inactive: 'do support checks',
- prompt () {
- if (game.available_ops === 0) {
- view.prompt = 'Support checks: done.'
- gen_action('done')
- //return
- }
- if (game.available_ops > 0) {
- view.prompt = `Select a space. ${pluralize(game.available_ops, 'support check')} remaining.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_sc(spaces[space_id].name_unique)
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = find_space_index(space)
-
- // Check for Austria-Hungary Border Reopened - check on first support check only
- //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
- if (game.persistent_events.includes(58)) {
- if (game.active === DEM && game.available_ops > 1) {
- if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
- game.state = 'austria_hungary_border_reopened_check'
- return
- }
- //game.state = 'do_support_check'
- } /*else { */
- }
- game.state = 'do_support_check'
- console.log('game.state after space selected:', game.state)
- //}
- },
- done () {
- if (game.is_pwr_struggle) {/*Crowd Turns Against Ceausescu should be the only time you end up here during a power struggle */
- if (game.return !== game.active) {
- next_player()
- }
- game.state = 'raise_stakes_1'
- return
- }
-
- if (game.vm_event_to_do) {
- reset_austria_hungary_border_reopened()
- game.state = 'resolve_opponent_event'
- } else {
- end_round()
- }
- }
-}
-
-states.do_support_check = {
- inactive: 'do support checks.',
- prompt () {
- console.log('in do_support_check')
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(spaces[game.selected_space].name_unique)
- game.available_ops--
- if (game.available_ops === 0) {
- game.valid_spaces = []
- }
- game.state = 'support_check_prep'
- return
- }
-}
-
-states.austria_hungary_border_reopened_check = {
- inactive: 'decide Austria-Hungary Border Reopened',
- prompt() {
- view.prompt = 'Austria-Hungary Border Reopened: will both support checks be in East Germany?'
- gen_action('yes')
- gen_action('no')
- },
- yes() {
- game.austria_hungary_border_reopened_tracker = true
- game.state = 'do_support_check'
- },
- no() {
- game.state = 'do_support_check'
- }
-}
-
-//======================= POWER STRUGGLE ===============================
-
-states.draw_power_cards = {
- inactive: 'draw cards.',
- prompt() {
- view.prompt = 'Draw cards.'
- gen_action('draw')
- },
- draw() {
- push_undo()
- game.power_struggle_deck = [...all_power_cards]
- console.log('game.power_struggle_deck.length', game.power_struggle_deck.length)
- console.log('called draw cards, country', game.pwr_struggle_in, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- console.log('test3')
- let presence = check_presence(game.pwr_struggle_in)
- console.log('test2')
- if (presence.dem_spaces > 0) {
- game.dem_pwr_hand_limit = 6 + 2*(presence.dem_spaces - 1)
- } else {
- game.dem_pwr_hand_limit = 0
- }
- if (presence.com_spaces > 0 ) {
- game.com_pwr_hand_limit = 6 + 2*(presence.com_spaces - 1)
- } else {
- game.com_pwr_hand_limit = 0
- }
- // Events which affect cards drawn
- if (game.persistent_events.includes(17) && game.com_pwr_hand_limit >= 2) {
- log('Democrat receives 2 cards from Communist due to C17')
- game.dem_pwr_hand_limit += 2
- game.com_pwr_hand_limit -= 2
- discard_from_table(17)
- game.persistent_events = game.persistent_events.filter(n => n !== 17)
- }
-
- if (game.persistent_events.includes(72)) {
- let farmer_check
- for (let space of spaces) {
- if (space && space.country === game.pwr_struggle_in && space.socio === 3 && check_dem_control(space.space_id)) {
- farmer_check = true
- }
- }
- if (farmer_check && game.com_pwr_hand_limit > 0) {
- log('Democrat receives 1 cards from Communist due to C72')
- game.dem_pwr_hand_limit += 1
- game.com_pwr_hand_limit -= 1
- permanently_remove(72)
- game.persistent_events = game.persistent_events.filter(n => n !== 72)
- }
- }
-
- if (game.persistent_events.includes(102) && game.dem_pwr_hand_limit >=2 && (game.pwr_struggle_in === 'Romania' || game.pwr_struggle_in === 'Bulgaria')) {
- log('Communist receives 2 cards from Democrat due to C102')
- game.dem_pwr_hand_limit -= 2
- game.com_pwr_hand_limit += 2
- permanently_remove(102)
- game.persistent_events = game.persistent_events.filter(n => n !== 102)
- }
-
- //Draw Power Cards
- game.is_pwr_struggle = true
- console.log('game.dem_pwr_hand_limit', game.dem_pwr_hand_limit, 'game.com_pwr_hand_limit', game.com_pwr_hand_limit)
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand_limit, game.com_pwr_hand_limit)
- game.valid_cards = all_power_cards
-
- log(`Communist: ${game.com_pwr_hand.length} cards`)
- log(`Democrat: ${game.dem_pwr_hand.length} cards`)
-
- //Check if The Crowd Turns Against Ceausescu occurs
- if (game.table_cards.includes(54) && game.pwr_struggle_in === 'Romania') {
- console.log('draw cards: crowd subcheck, game.active', game.active)
- if (game.active === COM) {
- game.return = COM
- next_player()
- }
- log_h3('The Crowd Turns Against Ceausescu')
- game.persistent_events.push(54)
- game.state = 'the_crowd_turns_against_ceausescu_prep'
- } else {
- log_h2('Raise the Stakes')
- game.state = 'raise_stakes_1'
- console.log('game.state', game.state, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- }
- }
-}
-
-states.the_crowd_turns_against_ceausescu_prep = {
- get inactive() {
- return `resolve ${clean_name(cards[54].name)}.`
- },
- prompt() {
- view.prompt = 'The Crowd Turns Against Ceausescu: draw cards.'
- gen_action('draw')
- },
- draw() {
- game.ceausescu_cards = []
- draw_cards(game.power_struggle_deck, game.ceausescu_cards, game.com_pwr_hand, 15, game.com_pwr_hand.length)
- console.log('game.ceausescu_cards', game.ceausescu_cards)
- game.temp = game.ceausescu_cards.filter(card => card && card >=25 && card <= 30).length
- log(`Drew ${pluralize(game.temp, 'Rally in the Square')}.`)
- game.vm_available_ops = game.temp * 3
- game.state = 'vm_the_crowd_turns_against_ceausescu'
- }
-}
-
-states.vm_the_crowd_turns_against_ceausescu = {
- get inactive() {
- return `resolve ${clean_name(cards[54].name)}.`
- },
- prompt() {
- view.prompt = `You have ${game.vm_available_ops} operations points. Play for:`
- gen_action('influence')
- gen_action('support_check')
- },
- influence() {
- push_undo()
- delete game.ceausescu_cards
- valid_spaces_infl()
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'Romania')
- game.state = 'the_crowd_turns_against_ceausescu_infl' /* Send this to add_infl. Add check at end of add_infl similar to valid_spaces*/
- },
- support_check() {
- push_undo()
- delete game.ceausescu_cards
- valid_spaces_sc()
- game.available_ops = 2
- game.state = 'support_check_prep'
- }
-}
-
-states.the_crowd_turns_against_ceausescu_infl = {
- inactive: 'add SPs.',
- prompt () {
- if (game.vm_available_ops === 0)
- {
- view.prompt = 'Place SPs: done.';
- gen_action("done");
- return;
- }
-
- view.prompt = `Add SPs: ${game.vm_available_ops} remaining`
- for (let space of game.valid_spaces) {
- gen_action_infl(spaces[space].name_unique)
- }
- },
- infl(space) {
- vm_do_add_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- if (game.return !== game.active) {
- next_player()
- }
- log_h2('Raise the Stakes')
- game.state = 'raise_stakes_1'
- }
-}
-
-states.raise_stakes_1 = {
- inactive: 'raise the stakes',
-
- prompt () {
- console.log('raise the stakes: game.played_power_card', game.played_power_card, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- if (game.raised_stakes_discard === 3) {
- view.prompt = 'Raise the stakes: done.'
- gen_action('done')
- } else {
- view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes.`
- if (game.raised_stakes_discard === 0) {
- gen_action('pass')
- }
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- }
- },
- card(card) {
- push_undo()
- if (numberless_cards.includes(card)) {
- log(`Discarded: P${card}`)
- } else {
- log(`Discarded: P${card} V${power_cards[card].value}`)
- }
- discard(card)
-
- game.raised_stakes_discard ++
- if (game.raised_stakes_discard === 3) {
- game.raised_stakes++
- }
-
-
- },
- pass(){
- log('Did not raise the stakes')
- game.raised_stakes_discard = 0
- next_player()
- game.state = 'raise_stakes_2'
- },
- done () {
- log_gap('Raised the stakes')
- game.raised_stakes_discard = 0
- next_player()
- game.state = 'raise_stakes_2'
- }
-}
-
-states.raise_stakes_2 = {
- inactive: 'raise the stakes',
-
- prompt () {
-
- if (game.raised_stakes_discard === 3) {
- view.prompt = 'Raise the stakes: done.'
- gen_action('done')
- } else {
- view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes.`
- if (game.raised_stakes_discard === 0) {
- gen_action('pass')
- }
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- }
- },
- card(card) {
- push_undo()
- if (numberless_cards.includes(card)) {
- log(`Discarded: P${card}`)
- } else {
- log(`Discarded: P${card} V${power_cards[card].value}`)
- }
- discard(card)
-
- game.raised_stakes_discard ++
- if (game.raised_stakes_discard === 3) {
- game.raised_stakes++
- }
-
- },
- pass() {
- log('Did not raise the stakes')
- game.raised_stakes_discard = 0
- game.valid_cards = []
- log_h2('Play Cards')
- next_player()
- game.state = 'begin_power_struggle'
- },
- done () {
- log_gap('Raised the stakes')
- game.raised_stakes_discard = 0
- game.valid_cards = []
- log_h2('Play Cards')
- next_player()
- game.state = 'begin_power_struggle'
- },
-}
-
-states.begin_power_struggle = {
- inactive: 'begin power struggle.',
- prompt() {
- view.prompt = 'Begin power struggle.'
- gen_action('struggle')
- },
- struggle () {
- do_valid_cards()
- game.state = 'power_struggle'
- }
-}
-
-states.power_struggle = {
- inactive: 'play a card.',
- prompt () {
- console.log('game.tactics_fails', game.tactics_fails)
- if (game.phase === 0) {
- if (game.valid_cards.length > 0) {
- view.prompt = "Play a card."
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- } else if ( game.valid_cards.length === 0) {
- view.prompt = 'No valid cards. You must concede.'
- gen_action('concede')
- }
- }
- if (game.phase === 1) {
- if (game.valid_cards.length > 0) {
- view.prompt = `${power_cards[game.played_power_card].name} played. You must match or concede.`
- gen_action('concede')
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- } else if (game.valid_cards.length === 0) {
- view.prompt = `${power_cards[game.played_power_card].name} played. You must concede.`
- gen_action('concede')
- }
- }
- else if (game.phase === 2) {
- view.prompt = 'You matched. Roll a die.'
- gen_action('roll')
- }
- else if (game.phase === 3) {
- view.prompt = 'Play leader as:'
- if (game.tactics_fails !== "Strike") {gen_action('strike')}
- if (game.tactics_fails !== "March") {gen_action('march')}
- if (game.tactics_fails !== "Rally in the Square") {gen_action('rally')}
- if (game.tactics_fails !== "Petition") {gen_action('petition')}
- }
- },
- card(card) {
- push_undo()
- discard(card)
- game.valid_cards=[]
- game.return_state = 'power_struggle'
- if (card === 52) {
- log_gap(`Played P52: P${power_cards[game.played_power_card].number} no longer playable`)
-
- } else {
- if (game.phase === 0 && leader_cards.includes(card)) {} /* Log nothing. Probably a better way to do this */
- else if (numberless_cards.includes(card)) {
- log_gap(`Played: P${card}`)
- } else {
- log_gap(`Played: P${card} V${power_cards[card].value}`)
- }
- }
- if (game.phase === 0) {
- if (card >= 37 && card <= 48) { /*When a leader is played */
- game.played_power_card = card
- game.phase = 3
- } else if (card === 49){ /*Scare Tactics */
- game.return = ''
- goto_vm(349) /*Can I combine these 3 into a single stage where you goto_vm(300 + card) ? */
- } else if (card === 50) { /*Support Surges */
- if (game.active === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- goto_vm(350)
- } else if (game.phase === 0 && card === 51) { /*Support Falters */
- next_player()
- goto_vm(351)
- } else {
- game.played_power_card = card
- game.phase = 1
- next_player()
- do_valid_cards()
- }
- } else if (game.phase === 1) {
- if (card === 52) {
- game.tactics_fails = power_cards[game.played_power_card].name
- game.phase = 0
- next_player()
- do_valid_cards()
- } else if (power_cards[game.played_power_card].value === 1) {
- log('Takes initiative')
- game.phase = 0
- do_valid_cards()
- } else {
- game.phase = 2
- }
- }
- },
- roll () {
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- if (roll >= power_cards[game.played_power_card].value) {
- log('Initiative roll successful')
- game.phase = 0
- do_valid_cards()
- } else {
- log(`Initiative roll failed. Required ${power_cards[game.played_power_card].value} or more`)
- game.phase = 0
- next_player()
- do_valid_cards()
- }
- },
- concede () {
- push_undo()
- log('Conceded')
- log_h2('Aftermath')
- log_h3('Support Loss')
- //if ((game.played_power_card >= 25 && game.played_power_card <= 30) || game.played_power_card === 53) {game.rally_win = 2}
- //if ((game.played_power_card >= 31 && game.played_power_card <= 36) || game.played_power_card === 54) {game.petition_win = 2}
- if (game.phase === 0) {
- game.played_power_card = 0 /*If conceded when held the initiative but had no playable cards, ignore the last played card */
- }
- game.phase = 0
- game.state = 'support_loss'
- },
- strike () {
- log(`Played: P${power_cards[game.played_power_card].number} as a Strike`)
- game.played_power_card = 9
- game.phase = 1
- next_player()
- do_valid_cards()
- },
- march () {
- log(`Played: P${power_cards[game.played_power_card].number} as a March`)
- game.played_power_card = 21
- game.phase = 1
- next_player()
- do_valid_cards()
- },
- rally () {
- log(`Played: P${power_cards[game.played_power_card].number} as a Rally in the Square`)
- game.played_power_card = 53
- game.phase = 1
- next_player()
- do_valid_cards()
- },
- petition () {
- log(`Played: P${power_cards[game.played_power_card].number} as a Petition`)
- game.played_power_card = 54
- game.phase = 1
- next_player()
- do_valid_cards()
- },
- /*draw () {
- if (game.active === DEM) {
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+2, game.com_pwr_hand.length)
- } else {draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+2)}
- game.phase = 0
- next_player()
- do_valid_cards()
- },*/
- /*infl(space) {
- game.remove_opponent_infl = true
- remove_infl(space)
- game.phase = 6
- },
- discard () { /*Is this still needed?
- if (game.active === DEM) {discard_card(game.dem_pwr_hand)}
- else {discard_card(game.com_pwr_hand)}
- game.available_ops --
- }, */
- done () {
- if (game.phase === 7) { /*Is this ever called anymore? */
- game.phase = 0
- log_msg_gap('Takes initiative')
- do_valid_cards()
- } else {
- game.phase = 0
- next_player()
- do_valid_cards()
- }
- }
-}
-
-states.support_loss ={
- inactive: 'do Support Loss.',
- prompt () {
- console.log('game.played_power_card', game.played_power_card)
- if (game.phase === 0) {
- view.prompt = 'You lost the Power Struggle. Roll a die for Support Loss.'
- gen_action('roll')
- } else if (game.phase === 1 && game.available_ops > 0 && game.valid_spaces.length > 0) {
- view.prompt = `Support Loss: remove ${pluralize(game.available_ops,'SP')}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique)
- }
- } else if (game.phase === 1 && game.available_ops === 0 ) {
- view.prompt = 'Support Loss: finished.'
- gen_action('done')
- } else if (game.phase === 1 && game.valid_spaces.length === 0) {
- view.prompt = 'Support Loss: no remaining SPs to remove.'
- gen_action('done')
- }
- },
- roll () {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- let rally_win = 0
- let petition_win = 0
- log(`Rolled a ${roll}`)
- if ((game.played_power_card >= 25 && game.played_power_card <= 30) || game.played_power_card === 53) { rally_win = 2}
- if ((game.played_power_card >= 31 && game.played_power_card <= 36) || game.played_power_card === 54) { petition_win = 2}
- let modified_roll = roll + game.raised_stakes + rally_win - petition_win
-
- // Roll modifiers
- if (game.active === COM && game.persistent_events.includes(62)) {
- log('+1 from C62')
- modified_roll ++
- }
-
- if (modified_roll < 0) {modified_roll = 0}
- else if (modified_roll > 7) {modified_roll = 7}
-
-
- if (game.raised_stakes !== 0) {
- log(`+${game.raised_stakes} from Raising the Stakes`)
- }
- if (rally_win !== 0) {
- log('+2 from winning on a P25')
- }
- if (petition_win !== 0) {
- log('-2 from winning on a P31')
- }
- if (modified_roll !== roll) {
- log(`Modified roll: ${modified_roll}`)
- }
- game.available_ops = support_loss_roll[modified_roll]
- if (game.available_ops === 0) {
- log('Does not remove SPs')
- }
- game.phase++
- valid_spaces_support_loss()
- },
- infl (space) {
- game.remove_opponent_infl = false /* Don't know why this is needed... */
- remove_infl(space)
- if (game.available_ops === 0 ) {
- game.valid_spaces = []
- }
- },
- done () {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- next_player()
- log_h3('Victory Point')
- game.phase = 0
- game.state = 'vp_roll'
- }
-}
-
-states.vp_roll = {
- inactive: 'do VP Roll',
- prompt () {
- if (game.phase === 0) {
- view.prompt = 'Roll a die for Victory.'
- gen_action('roll')
- } else if (game.phase === 1) {
- view.prompt = 'Take power.'
- gen_action('take')
- } else if (game.phase === 2) {
- view.prompt = 'Proceed to scoring.'
- gen_action('scoring')
- }
- },
- roll () {
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- let rally_win = 0
- let petition_win = 0
- if ((game.played_power_card >= 25 && game.played_power_card <= 30) || game.played_power_card === 53) {rally_win = 2}
- if ((game.played_power_card >= 31 && game.played_power_card <= 36) || game.played_power_card === 54) {petition_win = 2}
- let modified_roll = roll + game.raised_stakes + rally_win - petition_win
- if (game.active === DEM && game.persistent_events.includes(62)) {
- log('+1 from C62')
- modified_roll ++
- }
- if (modified_roll < 0) {modified_roll = 0}
- else if (modified_roll > 7) {modified_roll = 7}
-
- if (game.raised_stakes !== 0) {
- log(`+${game.raised_stakes} from Raising the Stakes`)
- }
- if (rally_win !== 0) {
- log('+2 from winning on a P25')
- }
- if (petition_win !== 0) {
- log('-2 from winning on a P31')
- }
- if (modified_roll !== roll) {
- log(`Modified roll: ${modified_roll}`)
- }
- let vp_change = vp_roll[modified_roll]
- if (game.active === DEM) {
- log(`+${vp_change} VP`)
- } else {
- log(`-${vp_change} VP`)
- }
- if (roll >= 4)
- console.log('VP before', game.vp)
- if (game.active === DEM) {game.vp += vp_change}
- else {game.vp -= vp_change}
- console.log('VP after', game.vp)
- if (game.active === DEM && modified_roll >= 4) {
- game.phase = 1
- } else {
- game.phase = 0
- if (game.active === DEM) {next_player()}
- game.state = 'choose_power'
- }
- },
- take () {
- push_undo()
- //Find name of scoring card
- let scoring_card = scoring_cards[countries.indexOf(game.pwr_struggle_in)]
- permanently_remove(scoring_card)
- take_power(game.pwr_struggle_in)
- game.phase = 2
- },
- scoring () {
- push_undo()
- log_h2('Scoring')
- score_country(game.pwr_struggle_in)
- game.state = 'finish_scoring'
- },
-}
-
-states.choose_power = {
- inactive: 'choose whether to remain in power.',
- prompt () {
- if (game.phase === 0) {
- view.prompt = 'Choose whether to remain in power.'
- gen_action('retain')
- gen_action('surrender')
- } else if (game.phase === 1) {
- view.prompt = 'Proceed to scoring.'
- gen_action('scoring')
- }
- },
- retain() {
- push_undo()
- retain_power(game.pwr_struggle_in)
- game.phase = 1
- },
- surrender () {
- push_undo()
- take_power(game.pwr_struggle_in)
- permanently_remove(game.played_card)
- game.phase = 1
- },
- scoring () {
- push_undo()
- score_country(game.pwr_struggle_in)
-
- //Check if The Tyrant is Gone occurs
- if (game.table_cards.includes(97) && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(54)) {
- game.return_state = 'finish_scoring'
- game.state = 'the_tyrant_is_gone'
- } else {
- game.state = 'finish_scoring'
- }
- }
-}
-/*
-states.score_country = {
- inactive: `score country`,
- prompt () {
- view.prompt = 'Scoring: done.'
- gen_action('done')
- },
- done () {
- reset_power()
- /*if (game.return !== game.active) {
- next_player()}
- game.state = 'finish_scoring'
- }
-}
-*/
-
-states.the_tyrant_is_gone ={
- inactive: 'resolve The Tyrant is Gone.',
- prompt() {
- view.prompt = 'Play The Tyrant is Gone for the event.'
- gen_action('event')
- },
- event() {
- if (game.active !== DEM) {
- next_player()
- }
- log_h3(`C97`)
- game.vm_event = 97
- goto_vm(game.vm_event)
- }
-}
-
-states.finish_scoring ={
- inactive: 'finish scoring.',
- prompt() {
- view.prompt = 'End power struggle.'
- gen_action('done')
- } ,
- done() {
- console.log('game.return_state', game.return_state)
- log('Power Struggle resolved') /*At this point log card dicarded or permanently removed? */
- if (game.persistent_events.includes(111)) {
- game.state = 'new_years_eve_party'
- return
- }
- if (check_vp()) {
- return
- }
- reset_power()
- end_round()
- }
-}
-
-// ======================================= END TURN STATES ==========================================
-
-states.end_turn_4_5_4 = {
- inactive: 'verify held cards.',
- prompt() {
- view.prompt = 'End Turn: verify held cards.'
- gen_action('check')
- },
- check() {
- log_h2('Verify held cards')
- const dem_has_scoring_card = game.democrat_hand.some(card => scoring_cards.includes(card))
- const com_has_scoring_card = game.communist_hand.some(card => scoring_cards.includes(card))
- if (!dem_has_scoring_card && !com_has_scoring_card) {
- log('No held scoring cards')
- }
-
- if (dem_has_scoring_card && com_has_scoring_card) {
- log('Both players have held scoring cards')
- game.state = 'game_end_tie'
- }
- else if (dem_has_scoring_card) {
- log('Democrat player has a held scoring card')
- goto_game_over(COM, `${COM} won by held scoring card!`)
- }
- else if (com_has_scoring_card) {
- log('Communist player has a held scoring card')
- goto_game_over(DEM, `${DEM} won by held scoring card!`)
- }
- else if (game.persistent_events.includes(104)) {
- log_h1(`New Year's Eve Party`)
- //Check if the Communist receives VP from The Tyrant is Gone
- if (game.persistent_events.includes(97)) {
- game.vp -= 2
- log(`Communist receives 2 VP from C97`)
- }
- game.persistent_events.push(111)
- game.state = 'new_years_eve_party'
- }
- else if(game.turn === 10) {
- clear_undo()
- log_h2('Final Scoring')
-
- //Check if the Communist receives VP from The Tyrant is Gone
- if (game.persistent_events.includes(97)) {
- game.vp -= 2
- log(`Communist receives 2 VP from C97`)
- }
- game.state = 'final_scoring_held'
-
- } else {
- game.return_state = ''
- new_turn()
- }
- }
-}
-
-states.final_scoring_held = {
- inactive: 'resolve final scoring.',
- prompt() {
- view.prompt = 'Final Scoring: Communist scores VP bonus for the number of countries they retain power.'
- gen_action('bonus')
- },
- bonus() {
- console.log('game.revolutions: ', game.revolutions)
- const held_countries = game.revolutions.filter(value => value === false).length
- let vp_gain = 4*held_countries
- log(`Communist holds ${held_countries} countries: -${vp_gain} VP`)
- game.vp -= 4*held_countries
- game.temp = {'East_Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false}
- game.state = 'final_scoring'
- }
-}
-
-states.final_scoring = {
- inactive: 'score countries.',
- prompt() {
- if (game.temp['East_Germany'] && game.temp['Poland'] && game.temp['Czechoslovakia'] && game.temp['Hungary'] && game.temp['Romania'] && game.temp['Bulgaria']) {
- view.prompt = 'Country scoring: done.'
- gen_action('done')
- } else {
- view.prompt = 'Choose a country to score'
- if (!game.temp['East_Germany']) {gen_action('east_germany')}
- if (!game.temp['Poland']) {gen_action('poland')}
- if (!game.temp['Czechoslovakia']) {gen_action('czechoslovakia')}
- if (!game.temp['Hungary']) {gen_action('hungary')}
- if (!game.temp['Romania']) {gen_action('romania')}
- if (!game.temp['Bulgaria']) {gen_action('bulgaria')}
- }
- },
- east_germany() {
- score_country('East_Germany')
- game.temp['East_Germany'] = true
- },
- poland() {
- score_country('Poland')
- game.temp['Poland'] = true
- },
- czechoslovakia() {
- score_country('Czechoslovakia')
- game.temp['Czechoslovakia'] = true
- },
- hungary() {
- score_country('Hungary')
- game.temp['Hungary'] = true
- },
- romania() {
- score_country('Romania')
- game.temp['Romania'] = true
- },
- bulgaria() {
- score_country('Bulgaria')
- game.temp['Bulgaria'] = true
- },
- done() {
- delete game.temp
- if (game.vp > 0) {
- goto_game_over(DEM, `${DEM} wins on Victory Point Track!`)
- } else if (game.vp < 0) {
- goto_game_over(COM, `${COM} wins on Victory Point Track!`)
- } else if (game.vp === 0) {
- goto_game_over('', `The game is tied!`) /*Not sure what to pass for result */
- }
- }
-}
-
-states.game_over = {
- get inactive() {
- return game.victory
- },
- prompt() {
- view.prompt = game.victory
- },
-}
-
-// ========================== EVENT SPECIFIC STATES =================================
-
-states.general_strike = {
- inactive: 'discard a card.',
- prompt() {
- if (game.played_card === 0 ) {
- view.prompt = 'General Strike: you must discard a card or play a Scoring Card.'
- available_cards = game.communist_hand
- for (let card of available_cards) {
- gen_action_card(card)
- }
- } else if (game.phase >= 1) {
- view.prompt = 'General Strike: done.'
- gen_action('done')
- } else if (game.played_card > 0 ) {
- view.prompt = 'Roll a die.'
- gen_action('roll')
- }
- },
- card (card) {
- push_undo()
- game.played_card = card
- let find_card
- find_card = game.communist_hand.indexOf(card)
- game.communist_hand.splice(find_card, 1)
- game.available_ops = get_card_ops(card)
- if (scoring_cards.includes(card)) {
- game.vm_event = card
- log(`Played C${card} for the event`)
- game.return_state = 'general_strike'
- goto_vm(game.vm_event)
- } else {
- log(`Discarded C${cards[card].number}`)
- }
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
-
- log(`+${game.available_ops} from card ops`)
-
- let total = roll + game.available_ops
- log(`Modified total: ${total}`)
-
- if (total > 5) {
- log('The strike is over.')
- permanently_remove(5)
- game.persistent_events = game.persistent_events.filter(n => n !== 5)
- } else {
- log('The strike continues. Required 6 or more')
- }
- game.phase = 1
- },
- done () {
- end_round()
- }
-}
-
-states.honecker ={
- inactive: 'resolve Honecker.',
- prompt() {
- view.prompt = 'Honecker: you may take an extra action round.'
- gen_action('extra')
- gen_action('pass')
- },
- extra() {
- push_undo()
- game.round++
- game.round_player = COM
- game.persistent_events = game.persistent_events.filter(n => n !== 15)
- game.state = 'choose_card'
- },
- pass() {
- log('C15: passed')
- game.persistent_events = game.persistent_events.filter(n => n !== 15)
- end_round()
- }
-}
-
-states.new_years_eve_party = {
- get inactive() {
- return `resolve ${clean_name(cards[104].name)}.`
- },
- prompt() {
- if (!game.is_pwr_struggle) {
- view.prompt = `New Year's Eve Party: you may choose a country to have a final power struggle.`
- if (!game.revolutions[0]) {gen_action('poland')}
- if (!game.revolutions[1]) {gen_action('hungary')}
- if (!game.revolutions[2]) {gen_action('east_germany')}
- if (!game.revolutions[3]) {gen_action('bulgaria')}
- if (!game.revolutions[4]) {gen_action('czechoslovakia')}
- if (!game.revolutions[5]) {gen_action('romania')}
- gen_action('pass')
- } else {
- view.prompt = `New Year's Eve Party: done.`
- gen_action('end')
- }
- },
- east_germany() {
- push_undo()
- log('Chose to score East Germany')
- game.vm_event = 42
- goto_vm(42)
- },
- poland() {
- push_undo()
- log('Chose to score Poland')
- game.vm_event = 22
- goto_vm(22)
- },
- czechoslovakia() {
- push_undo()
- log('Chose to score Czechoslovakia')
- game.vm_event = 55
- goto_vm(55)
- },
- hungary() {
- push_undo()
- log('Chose to score Hungary')
- game.vm_event = 23
- goto_vm(23)
- },
- romania() {
- push_undo()
- log('Chose to score Romania')
- game.vm_event = 95
- goto_vm(95)
- },
- bulgaria () {
- push_undo()
- log('Chose to score Bulgaria')
- game.vm_event = 43
- goto_vm(43)
- },
- pass() {
- push_undo()
- log('No final power struggle')
- if (game.vp > 0) {
- goto_game_over(DEM, `C104: ${DEM} wins on Victory Point Track!`)
- } else if (game.vp < 0) {
- goto_game_over(COM, `C104: ${COM} wins on Victory Point Track!`)
- } else if (game.vp === 0) {
- goto_game_over('', `C104: The game is tied!`) /*Not sure what to pass for result */
- }
- },
- end() {
- if (game.vp > 0) {
- goto_game_over(DEM, `C104: ${DEM} wins on Victory Point Track!`)
- } else if (game.vp < 0) {
- goto_game_over(COM, `C104: ${COM} wins on Victory Point Track!`)
- } else if (game.vp === 0) {
- goto_game_over('', `C104: The game is tied!`) /*Not sure what to pass for result */
- }
- }
-}
-
-states.stasi_end_round = {
- inactive: 'choose next card due to Stasi.',
- prompt() {
- console.log('game.stasi_card', game.stasi_card)
- if (!game.stasi_card || game.stasi_card === 0 ) {
- let available_cards = game.democrat_hand
- if (available_cards.length === 0) {
- view.prompt = 'Stasi: no cards remaining.'
- gen_action('pass')
- return
- }
- view.prompt = 'Stasi: you must select your next card to play.'
-
- for (let card of available_cards) {
- gen_action_card(card)
- }
- } else {
- view.prompt = 'Stasi. Choose card: done.'
- gen_action('done')
- }
- },
- card(card) {
- push_undo()
- log_gap(`Stasi: selected C${cards[card].number}`)
- game.stasi_card = card
- },
- pass() {
- log('Stasi: Democrat has no remaining cards')
- game.stasi_card = 0
- end_stasi_choose_card()
- },
- done() {
- push_undo()
- if (game.stasi_card === 21) {
- game.state = 'stasi_confirm'
- } else {
- end_stasi_choose_card()
- }
- }
-}
-
-states.stasi_confirm = {
- inactive: 'choose next card due to Stasi.',
- prompt() {
- if (game.stasi_card === 21 ) {
- view.prompt = `If Common European Home selected, it must be played for Operations. Otherwise select the opponent's card instead.`
- gen_action('done')
- }
- },
- done() {
- game.playable_cards = game.playable_cards.filter( n => n !== 21)
- end_stasi_choose_card()
- }
-}
-
-states.stasi_play_card = {
- inactive: 'play a card.',
- prompt () { /*Should get rid of the play card 'done' prompt for consistency with general play */
- /*if (game.played_card > 0) {
- game.state = 'play_card'
- view.prompt = 'Play card: done.'
- gen_action("done");
- return;*/
- //} else
- if (game.stasi_card === 0) {
- view.prompt = 'Stasi: you must pass.'
- gen_action('pass')
- } else {
- view.prompt = `Stasi: you must play ${clean_name(cards[game.stasi_card].name)}.`
- /*let available_cards = [game.stasi_card]
- for (let card of available_cards) {
- gen_action_card(card)
- }*/
- let available_cards = [game.stasi_card]
-
- for (let card of available_cards) {
-
- if (scoring_cards.includes(card)) {
- /*view.prompt = 'Play for:'*/
- gen_action('card_event', card)
- return
- }
-
- //Check if Player has Common European Home in hand
- if (game.active === DEM) {
- if (game.democrat_hand.includes(21) && cards[card].side === "C" && card !== 21) {
- gen_action('card_ceh', card)
- }
- } else {
- if (game.communist_hand.includes(21) && cards[card].side === "D" && card !== 21) {
- gen_action('card_ceh', card)
- }
- }
-
- //Check for Tiananmen Square Track awards special abilities
- if ((game.active === DEM && cards[card].side !== 'C' && game.dem_tst_position >= 8 && game.com_tst_position < 8 && !game.tst_8) || (game.active === COM && cards[card].side !== 'D' && game.com_tst_position >= 8 && game.dem_tst_position < 8 && !game.tst_8)){
- gen_action('card_tst_8', card)
- }
-
- // Check for Reformer Rehabilitated
-
- //console.log('game.active', game.active, 'game.playable_cards[67].playable', game.playable_cards[67].playable)
-
-
- if (card === 67 && game.playable_cards.includes(67)){
- if (game.active === DEM && (game.dem_tst_position > game.com_tst_position)) {
- gen_action('card_event', card)
- }
- if (game.active === COM && (game.dem_tst_position < game.com_tst_position)) {
- gen_action('card_event', card)
- }
- }
-
- //Continue with normal logic
-
- //Check if it is a card with an event which is always playable. May not play Common European Home for event in Stasi
-
- if (cards[card].playable && card !== 21) {
- console.log('get events called normally for card', card)
- get_events(card)
- }
-
- // Resolve cards with variable events (not Reformer, not Common European Home in Stasi)
-
- if (card !== 67 && card !== 21 && game.playable_cards.includes(card)) {
- console.log('get events called variable for card', card)
- get_events(card)
- } /*
- if ((game.active === DEM && cards[game.played_card].side === 'D' && game.playable_cards[game.played_card].playable === 1) || (game.active === COM && cards[game.played_card].side === 'C' && game.playable_cards[game.played_card].playable ===1) || (cards[game.played_card].side === 'N'&& game.playable_cards[game.played_card].playable ===1)) {
- gen_action('event')
- } else if ((game.active === DEM && (cards[game.played_card].side === 'C' && game.playable_cards[game.played_card].playable ===1)) || game.active === COM && (cards[game.played_card].side === 'D' && game.playable_cards[game.played_card].playable ===1)) {
- gen_action('opp_event')
- } */
-
- gen_action('card_influence', card)
- if (game.active === DEM && game.dem_tst_attempted_this_turn === 0 && game.dem_tst_position <=8 || game.active === COM && game.com_tst_attempted_this_turn === 0 && game.com_tst_position <= 8) {
- gen_action('card_tst', card)
- }
- gen_action('card_support_check', card)
- }
- }
- },
- card(card) {
- push_undo()
- log_msg_gap(`Stasi: played C${card}`)
- game.played_card = card
- let find_card
- find_card = game.democrat_hand.indexOf(card);
- game.democrat_hand.splice(find_card, 1);
- game.available_ops = get_card_ops(card)
-
- game.stasi_card = 0
- if (game.democrat_hand.includes(21)) {
- game.state = 'stasi_resolve_common_european_home'
- } else {
- game.state = 'play_card'
- }
-
- },
- pass () {
- log('No cards remaining. Passed')
- end_round()
- },
- card_ceh(card) {
- push_undo()
- select_card(card)
- game.stasi_card = 0
- log(`${clean_name(cards[game.played_card].name)} played with Common European Home`)
- //silent_discard(21)
- game.vm_infl_to_do = true
- game.vm_event_to_do = false
- game.state = 'resolve_opponent_event'
- },
-
- card_event(card) {
- push_undo()
- select_card(card)
- game.stasi_card = 0
- console.log('played event, game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- if (scoring_cards.includes(game.played_card)) {game.phase = 0}
- else {game.phase = 1}
- game.return = game.active
- if (switch_events.includes(game.played_card)) {next_player()}
- game.vm_event = game.played_card
- goto_vm(game.vm_event)
- },
- card_opp_event(card) {
- push_undo()
- select_card(card)
- game.stasi_card = 0
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- game.phase = 1 /*Do I still need this?*/
- game.vm_infl_to_do = true
- game.return = game.active
- game.vm_event = game.played_card
- if (auto_resolve_events.includes(game.played_card) || switch_events.includes(game.played_card)) {
- goto_vm(game.vm_event)}
- else {
- next_player()
- log(`C${game.vm_event}`)
- goto_vm(game.vm_event)
- }
- },
- card_influence(card) {
- push_undo()
- select_card(card)
- game.stasi_card = 0
- log_gap(`Played C${cards[game.played_card].number} to place SPs`)
-
-
- // Check if Common European Home played for influence
- if (game.played_card === 21) {
- if (game.active === DEM) {
- game.vp --
- log('-1 VP')
- if (check_vp()) {
- return
- }
- } else {
- game.vp ++
- log('+1 VP')
- if (check_vp()) {
- return
- }
- }
- }
- // Check if card is opponent card with event that needs to be resolved
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- //game.phase = 1 /*Do I need this? */
- game.vm_event_to_do = true
- }
- }
-
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state='add_influence'
- valid_spaces_infl()
- },
- card_tst(card) {
- push_undo()
- select_card(card)
- game.stasi_card = 0
- log_gap(`Played C${cards[game.played_card].number} to the Tiananmen Square Track`)
- game.state='tiananmen_square_attempt'
- },
- card_support_check(card) {
- push_undo()
- select_card(card)
- log_gap(`Played C${cards[game.played_card].number} for support checks`)
-
- // Check if card is opponent card with event that needs to be resolved
- /*if (game.phase === 0 && game.active === DEM && cards[game.played_card].side === "C" && game.playable_cards[game.played_card].playable === 1 || game.phase === 0 && game.active === COM && cards[game.played_card].side === "D" && game.playable_cards[game.played_card].playable === 1 ) {
- game.vm_event_to_do = true
- }*/
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- game.vm_event_to_do = true
- }
- }
-
- game.available_ops = 2
- game.state='support_check_prep'
- valid_spaces_sc()
- },
- card_tst_8(card) { /*Play card for ops and event */
- select_card(card)
- game.vm_event_to_do = true
- game.vm_infl_to_do = true
- game.tst_8 = true
- game.state = 'vm_tst_8'
- },
- done () {
- game.stasi_card = 0
- if (game.democrat_hand.includes(21)) {
- game.state = 'stasi_resolve_common_european_home'
- } else {
- game.state = 'play_card'
- }
- }
-}
-
-states.stasi_resolve_common_european_home = {
- inactive: 'play a card.',
- prompt () {
- view.prompt = `Do you wish to play ${clean_name(cards[game.played_card].name)} with Common European Home?`
- gen_action('yes')
- gen_action('no')
- },
- yes() {
- log(`${clean_name(cards[game.played_card].name)}} played with Common European Home`)
- silent_discard(21)
- game.vm_infl_to_do = true
- game.vm_event_to_do = false
- game.state = 'resolve_opponent_event'
- },
- no() {
- game.state = 'play_card'
- }
-}
-
-
-// ==================== SUPPORTING STATE FUNCTIONS =============================
-
-
-function add_infl(space) {
- push_undo()
- console.log('adding infl to', space)
- const clicked_space = find_space_index(space)
- console.log('clicked_space', clicked_space)
- //console.log('at start, event', game.persistent_events['austria_hungary_border_reopened'], 'ahbr', game.austria_hungary_border_reopened, 'tracker', game.austria_hungary_border_reopened_tracker)
- //log(`Added 1 influence in %${clicked_space}`)
- log_summary(`Added £ SP in %${clicked_space}`)
-
- //If AHBR - check AHBR conditions
- if (game.persistent_events.includes(58)) {
- if (spaces[clicked_space].country !== 'East_Germany'){
- game.austria_hungary_border_reopened_tracker = false
- }
- }
-
- // Check Genscher
- if (game.persistent_events.includes(63) && game.active === DEM && spaces[clicked_space].country === 'East_Germany') {
- game.available_ops--
- log_summary(`(-1 op due to C63)`)
- } else if (check_opp_control(clicked_space)) {
- game.available_ops -= 2
- //Check if Austria Hungary Border Reopened was used to place last SP in a controlled space in East Germany. If so, game.available_op will be negative
- if (game.available_ops < 0) {
- log_summary(`(Used +1 op from C58)`)
- }
- } else {
- game.available_ops--
- }
-
- // Update influence values
- if (game.active === COM) {
- game.comInfl[clicked_space]++
- } else {
- game.demInfl[clicked_space]++
- }
-
- // Check whether spaces are controlled
- check_control_change(clicked_space)
-
- // Check Austria Hungary Border Reopened is true and condition has been met
- if (game.available_ops === 0 && game.active === DEM && game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker) {
- game.available_ops ++
- log('+1 op from C58')
- game.austria_hungary_border_reopened_tracker = false
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
- }
-
- // If only 1 IP remaining, may not place in opponent controlled spaces
-
- // Check for Genscher & Austria Hungary Border Reopened
-
- if (game.available_ops === 1) {
- //console.log(`in Genscher / AHBR check, game.persistent_events['genscher']`, game.persistent_events['genscher'])
- if (game.active === DEM) {
- if (game.persistent_events.includes(63) || (game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker)) {
- console.log('in gensher subcheck - remove non-East German controlled ')
- game.valid_spaces = game.valid_spaces.filter(n => !(check_opp_control(n) && spaces[n].country !== 'East_Germany'))
- } else {
- console.log('remove all controlled spaces')
- game.valid_spaces = game.valid_spaces.filter(n => !check_opp_control(n))
- }
- } else {
- console.log('remove all dem controlled spaces')
- game.valid_spaces = game.valid_spaces.filter(n => !check_opp_control(n))
- }
- }
-
- //Clear valid spaces if no IP remaining.
- if (game.available_ops <= 0 ) {
- game.valid_spaces = []
- }
-}
-
-function remove_infl(space) {
- push_undo()
- const clicked_space = find_space_index(space)
- //log(`Removed 1 influence from %${clicked_space}.`)
- log_summary(`Removed £ SP from %${clicked_space}.`)
-
- if (game.remove_opponent_infl === true) {
- if (game.active === COM) {
- game.demInfl[clicked_space]--
- if (game.demInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- } else {
- game.comInfl[clicked_space]--
- if (game.comInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- }
- check_control_change(clicked_space)
-
- } else {
- if (game.active === COM) {
- game.comInfl[clicked_space]--
- if (game.comInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- } else {
- game.demInfl[clicked_space]--
- if (game.demInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- }
- check_control_change(clicked_space)
- }
- game.available_ops--
-}
-
-function do_sc(space) {
- clear_undo()
- let clicked_space = find_space_index(space)
- log_gap(`Support check: %${clicked_space}`)
-
- //Check Helsinki Final Act
-
- if (game.active === COM && game.persistent_events.includes(26) && (spaces[clicked_space].socio === 5 || spaces[clicked_space].socio === 6) ) {
- log('+1 VP from C26')
- game.vp ++
- if (check_vp()) {
- game.state = 'game.over'
- console.log('after check_vp, game.state', game.state)
- return
- }
- }
- console.log('continue support check, game.state', game.state)
- // Continue with Support Check Logic
-
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- console.log('game.vm_event', game.vm_event)
- console.log('game.is_pwr_struggle', game.is_pwr_struggle)
- /*
- //Check if support check is being done with game.played_card or a subsequent card (e.g. Common European Home, Dash for the West, etc)
- if (game.vm_event > 0) {
- roll+= cards[game.vm_event].ops
- log(`+${cards[game.vm_event].ops} from card ops`)
- }
- */
- // Check for the Crowd Turns Against Ceausescu
-
- //else
- if (game.is_pwr_struggle) {
- roll += game.vm_available_ops
- log(`+${game.vm_available_ops} from Ceausescu`)
- }
-
- // Check if in Tiananmen Square Track Award
-
- else if (game.state === 'vm_tst_6_sc') {
- roll += get_tst_6_ops()
- roll += 2
- log('+2 from Tiananmen Square Track award')
- }
- else {
- //let modifier = 0
- let card_ops = get_card_ops(this_card())
-
- roll += card_ops
- log(`+${card_ops} from card ops`)
- }
-
- if (game.support_check_modifier > 0) {
- roll += game.support_check_modifier
- log(`+${game.support_check_modifier} from event`)
- }
-
- // Events which modify SC rolls
- //Tear Gas
- if (game.active === COM && game.persistent_events.includes(30) && spaces[clicked_space].socio === 6) {
- roll ++
- log('+1 from C30')
- permanently_remove(30)
- game.persistent_events = game.persistent_events.filter(n => n !== 30)
- }
- //FRG Embassies
- if (game.active === DEM && spaces[clicked_space].region === 'Eastern Europe' && game.persistent_events.includes(74)) {
- roll++
- log('+1 from C74')
- }
- //GrenzTruppen
- if (game.active === DEM && spaces[clicked_space].country === 'East_Germany' && game.persistent_events.includes(59)) {
- roll--
- log('-1 from C59')
- }
- //Stand Fast
- if ((game.active === COM && game.stand_fast === DEM && check_dem_control(clicked_space)) || (game.active === DEM && game.stand_fast === COM && check_com_control(clicked_space))){
- roll--
- log('-1 from C100')
- }
- //Elena
- if (game.active === DEM && game.persistent_events.includes(101) && spaces[clicked_space].country === 'Romania') {
- roll--
- log('-1 from C101')
- }
- //Austria Hungary Border Reopened
- if (game.active === DEM && game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker) {
- roll++
- log(`+1 from C58`)
- }
-
- // Continue with logic - check for adjacency
-
- // Events which affect adjacency - The Wall
-
- const adj = count_adj(space)
- console.log('adj', adj)
- if (game.active === COM && game.persistent_events.includes(9) && spaces[clicked_space].country === 'East_Germany') {
- log('No adjacency for Democrats due to C9')
- log('C9 no longer in effect')
- roll += adj.com_adj
- if (adj.com_adj > 0) {
- log(`+${adj.com_adj} from adjacent control`)
- }
- game.persistent_events = game.persistent_events.filter(n => n !== 9)
-
- // Standard adjacency
- } else {
- if (adj.dem_adj > 0 || adj.com_adj > 0 ){
- if (game.active === DEM) {
- roll += adj.dem_adj
- roll -= adj.com_adj
- if (adj.dem_adj > 0) {
- log(`+${adj.dem_adj} from adjacent control`)
- }
- if (adj.com_adj > 0) {
- log(`-${adj.com_adj} from adjacent opponent control`)
- }
- } else {
- roll += adj.com_adj
- roll -= adj.dem_adj
- if (adj.com_adj > 0) {
- log(`+${adj.com_adj} from adjacent control`)
- }
- if (adj.dem_adj > 0) {
- log(`-${adj.dem_adj} from adjacent opponent control`)
- }
- }
- }
-
- }
-
- // Support check calcs
- log(`Total support check strength: ${roll}`)
- const stability = spaces[find_space_index(space)].stability
- log(`Stability is ${stability}. Defence is ${stability*2}`)
- const change_infl = Math.max(0, roll - stability*2)
- if (change_infl > 0) {
- log_msg_gap(`${change_infl} point swing`)
- let clicked_space = find_space_index(space)
- if(game.active === DEM) {
- if (change_infl > game.comInfl[clicked_space]) {
- const residual = change_infl - game.comInfl[clicked_space]
- game.comInfl[clicked_space] = 0
- game.demInfl[clicked_space] += residual
- } else {
- game.comInfl[clicked_space] -= change_infl
- }
- if (game.comInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
- }
- } else {
- if (change_infl > game.demInfl[clicked_space]) {
- const residual = change_infl - game.demInfl[clicked_space]
- game.demInfl[clicked_space] = 0
- game.comInfl[clicked_space] += residual
- } else {
- game.demInfl[clicked_space] -= change_infl
- }
- if (game.demInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
- }
- }
- check_control_change(clicked_space)
-
- } else {
- log_msg_gap('No change in influence')
- }
- if (game.active === COM && game.persistent_events.includes(39) && spaces[clicked_space].space_id === 66) {
- log_msg_gap('+1 VP from C39')
- game.vp++
- if (check_vp()) {
- return
- }
- }
-
- // If Austria-Hungary Border Reopened used, all future support checks must be in East Germany
- if (game.persistent_events.includes(58)){
- if (game.austria_hungary_border_reopened_tracker) {
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
- }
- }
- game.selected_space = 0
-
-}
-
-
-function valid_spaces_setup() {
- game.valid_spaces = []
- let valid_spaces_set = new Set();
- console.log('in vs setup, state', game.state)
- for (let i =1 ; i < 75 ; i++) {
- space = spaces[i]
-
- if (game.state === 'com_init') {
- infl = game.demInfl[i]
-
- if (infl === 0) {
- valid_spaces_set.add(space.space_id);
- }
- } else if (game.state === 'dem_init') {
- infl = game.comInfl[i]
- if (infl === 0) {
- valid_spaces_set.add(space.space_id);
- }
- }
- }
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
-}
-
-function valid_spaces_sc() {
- let valid_spaces_set = new Set();
- console.log('valid spaces sc, persistent events', game.persistent_events)
-
- for (let i = 1 ; i < 75; i++) {
- space = spaces[i]
-
- if (game.active === DEM) {
- infl = game.comInfl[i]
- if (infl !== 0 ) {
- valid_spaces_set.add(space.space_id);
- }
- } else {
- infl = game.demInfl[i]
- if (infl !== 0 ) {
- // Check Solidarity Legalised
- if (game.persistent_events.includes(2) && space.space_id === 14) {continue}
-
- // Check Civic Forum
- if (game.persistent_events.includes(90) && space.space_id === 30) {continue}
-
- // Check We Are the People
- if (game.persistent_events.includes(48) && space.space_id === 9) {continue}
-
- //Check for Foreign Currency Debt Burden
- if (game.persistent_events.includes(49) && space.country === game.foreign_currency_debt_burden) {continue} {
-
- valid_spaces_set.add(space.space_id);
-
- }
- }
- }
- }
-
-
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
-
- //Check for the Crown Turns Against Ceausescu
- if (game.is_pwr_struggle && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(54)) {
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'Romania')
- }
- return game.valid_spaces;
-}
-
-function valid_spaces_support_loss() {
- let valid_spaces_set = new Set();
- for (let i = 1; i < game.demInfl.length; i++) {
- //console.log('spaces.length', game.demInfl.length, 'i', i)
- space = spaces[i]
- if (game.active === DEM) {
- infl = game.demInfl[i]
- if (infl > 0 && space.country === game.pwr_struggle_in) {
- valid_spaces_set.add(space.space_id);
- }
- } else {
- infl = game.comInfl[i]
- if (infl > 0 && space.country === game.pwr_struggle_in) {
- valid_spaces_set.add(space.space_id);
- }
- }
- }
-
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
-}
-/*
-function valid_spaces_support_falters() {
- let valid_spaces_set = new Set();
- if (game.active === DEM) {
- for (let piece of game.pieces) {
- if (!piece) continue
- let space = spaces.find(s => s && s.space_id === piece.space_id);
- if (space && piece.comInfl > 0 && space.country === game.pwr_struggle_in) {
- valid_spaces_set.add(space.space_id);
- }
- }
- } else {
- for (let piece of game.pieces) {
- if (!piece) continue
- let space = spaces.find(s => s && s.space_id === piece.space_id);
- if (space && piece.demInfl > 0 && space.country === game.pwr_struggle_in) {
- valid_spaces_set.add(space.space_id);
- }
- }
- }
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
-}
- */
-
-function valid_spaces_infl() {
- /*if (game.state.startsWith('vm')) {
- console.log('valid_spaces_infl called from VM')
- } else {
- console.log('valid_spaces_infl called not from VM')
- }*/
- // Check if function is called from the VM or not, take relevant ops variable
- let ops = game.state.startsWith('vm') ? game.vm_available_ops : game.available_ops;
-
- let valid_spaces_set = new Set();
- // Iterate over all spaces to find the ones with the player's influence
- for (let i = 1; i < game.demInfl.length; i++) {
- //piece = game.pieces[i]
- space = spaces[i]
-
- let player_influence = game.active === COM ? game.comInfl[i] : game.demInfl[i];
-
- // If the piece has the player's influence, add it and its adjacent spaces to the set
- if (player_influence > 0) {
- valid_spaces_set.add(space.space_id);
-
- // Check adjacency information
- let adjacent_spaces = get_adjusted_adjacency(space.space_id)
-
- for (let adj_space_id of adjacent_spaces) {
- //console.log('adj_space_id', adj_space_id)
- if (adj_space_id) {
-
- const adj_piece = spaces[adj_space_id];
- //console.log('adjacent piece name', adj_piece.name_unique)
-
- // Check if the adjacent space is controlled by the opponent
- const opponent_control = check_opp_control(adj_piece.space_id)
- //console.log('controlled?', opponent_control)
-
- //Check for Genscher. Can always place in East Germany even with 1 op
- if (game.active === DEM && adj_piece.country === 'East_Germany' && game.persistent_events.includes(63)){
- // console.log('space added with genscher')
- valid_spaces_set.add(adj_piece.space_id)
- }
-
- // Otherwise, only add the adjacent space if the available_ops >= 2 or the space is not controlled by the opponent
- if (ops >= 2 || !opponent_control) {
- valid_spaces_set.add(adj_piece.space_id)
- }
- }
- }
- }
- }
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
-}
-
-function valid_cards(player_hand, presence) {
- const valid_cards_set= new Set();
- if (game.phase === 0) {
- for (let c of player_hand) {
- let card = power_cards.find(card => card && card.number === c);
- if (card.number === 52) {continue} // Never add tactics fails
- if (card.name === game.tactics_fails) {continue} //Cannot play the suit of Tactics Fails
- if (card.socio === 0) {
- valid_cards_set.add(card.number);
- } else if (leaders.includes(card.socio) && presence[card.socio]) {
- valid_cards_set.add(card.number);
- }
- }
- } else if (game.phase === 1) {
- for (let c of player_hand) {
- let card = power_cards.find(card => card && card.number === c);
- if (card.name === power_cards[game.played_power_card].name) {
- valid_cards_set.add(card.number);
- } else if (leaders.includes(card.socio) && presence[card.socio]) {
- valid_cards_set.add(card.number);
- } else if (card.number === 52) {valid_cards_set.add(card.number)}
- }
- }
- game.valid_cards = Array.from(valid_cards_set);
- return game.valid_cards;
-}
-
-function do_valid_cards() {
- let presence = check_presence(game.pwr_struggle_in)
- if (game.active === DEM) {
- valid_cards(game.dem_pwr_hand, presence.dem_leaders)
-
- } else {
- valid_cards(game.com_pwr_hand, presence.com_leaders)}
-}
-
-function count_adj(name_unique) {
- const space = spaces[find_space_index(name_unique)]
- let dem_adj = 0
- let com_adj = 0
-
- let adjacent_spaces = get_adjusted_adjacency(space.space_id)
-
- for (let adj_space_id of adjacent_spaces) {
- if (adj_space_id) {
- const adj_piece = spaces.find(piece => piece && piece.space_id === adj_space_id);
- console.log('adj_piece.space_id', adj_piece.space_id, 'space', space)
- if (adj_piece && adj_piece.space_id !== space.space_id) {
- if (check_dem_control(adj_piece.space_id)) {
- console.log('added DEM space', spaces[adj_piece.space_id].name)
- dem_adj++
- }
- if (check_com_control(adj_piece.space_id)) {
- console.log('added COM space', spaces[adj_piece.space_id].name)
- com_adj++
- }
- }
- }
- }
- console.log('dem_adj: ', dem_adj, 'com_adj: ', com_adj)
- return {dem_adj, com_adj}
-}
-
-/*function count_adj_worker(space_id) {
- const space = spaces[space_id]
- let dem_adj = 0
- let com_adj = 0
-
- for (let adj_space_id of space.adjacent) {
- if (adj_space_id) {
- const adj_space = spaces[adj_space_id]
- if (adj_space && adj_space.socio === 4) {
- const adj_piece = game.pieces.find(piece => piece && piece.space_id === adj_space_id );
- if (adj_piece) {
- if (adj_piece.demCtrl === 1 ) {
- dem_adj++
- }
- if (adj_piece.comCtrl === 1 ) {
- com_adj++
- }
- }
- }
- }
- }
- return {dem_adj, com_adj}
-} */
-
-function check_control(space_id) {
- //console.log('in check control, space', spaces[space_id].name_unique)
- if ( (game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) {
- return true;
- } else if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) {
- //console.log('true')
- return true;
- } else {
- //console.log('false')
- return false;
- }
-}
-
-function check_opp_control(space_id) {
- if (spaces[space_id].country === 'Romania') {
- //console.log('in check opp control, space', spaces[space_id].name_unique)
- }
- if (game.active === DEM && ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability)) {
- if (spaces[space_id].country === 'Romania') {
- //console.log('control true')
- }
- return true;
- } else if (game.active === COM && ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability)) {
- //console.log('true')
- return true;
- } else {
- //console.log('false')
- return false;
- }
-}
-
-function check_dem_control(space_id) {
- if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) {
- return true;
- } else {
- return false;
- }
-}
-
-function check_com_control(space_id) {
- if ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) {
- return true;
- } else {
- return false;
- }
-}
-
-function do_tst_attempt() {
- let roll = Math.floor(Math.random() * 6) + 1;
- log(`Rolled a ${roll}`);
-
- roll += game.available_ops
- log(`+${game.available_ops} from card ops`)
-
- // TIANANMEN SQUARE MODIFIERS
-
- if (game.active === DEM && game.dem_tst_attempted === 1 || game.active === COM && game.com_tst_attempted === 1) {
- roll ++;
- log('+1 modifier from previous Tiananmen Square Track attempts')
- }
- if (game.active === DEM && game.dem_tst_position >= 1 && game.com_tst_position === 0) {
- roll ++
- log('+1 from TST award')
- }
- if (game.active === COM && game.com_tst_position >= 1 && game.dem_tst_position === 0) {
- roll ++
- log('+1 from TST award')
- }
- if ((game.active === DEM && cards[game.played_card].side === 'D') || (game.active === COM && cards[game.played_card].side === 'C')) {
- roll ++;
- log('+1 for playing own card');
- }
- if (game.active === COM && game.persistent_events.includes(53)) {
- roll ++
- log('+1 from C53')
- }
- log(`Modified die roll: ${roll}`)
-
- // TIANANMEN SQUARE ATTEMPT
- game.return = game.active
- game.return_state = 'tiananmen_square_attempt_success'
- if (game.active === DEM) {
- game.dem_tst_attempted_this_turn = 1
- if (roll >= dem_tst_req[game.dem_tst_position]) {
- log(`${dem_tst_req[game.dem_tst_position]} required: success`)
- game.dem_tst_position++
- game.dem_tst_attempted = 0
-
- //Check if they have reached box 7 or 8 first
- if (game.dem_tst_position === 7 && game.com_tst_position < 7) {
- game.tst_7 = false
- }
- if (game.dem_tst_position === 8 && game.com_tst_position < 8) {
- game.tst_8 = false
- }
-
- //Check if they have caught up to box 7 or 8
- if (game.dem_tst_position >= 7 && game.com_tst_position >= 7) {
- delete game.tst_7
- }
- if (game.dem_tst_position >= 8 && game.com_tst_position >= 8) {
- delete game.tst_8
- }
-
- //Check if TST events occur
- if (game.dem_tst_position === 3 && game.com_tst_position < 3) {goto_vm(203)}
- else if (game.dem_tst_position === 4 && game.com_tst_position < 4) {goto_vm(204)}
- else {game.state = 'tiananmen_square_attempt_success'}
- } else {
- log(`${dem_tst_req[game.dem_tst_position]} required: fail`)
- game.dem_tst_attempted = 1
- game.state = 'tiananmen_square_attempt_fail'
- }
- } else {
- game.com_tst_attempted_this_turn = 1
- if (roll >= com_tst_req[game.com_tst_position]) {
- log(`${com_tst_req[game.com_tst_position]} required: success`)
- game.com_tst_position++
- game.com_tst_attempted = 0
-
- //Check if they have reached box 7 or 8 first
- if (game.dem_tst_position === 7 && game.com_tst_position < 7) {
- game.tst_7 = false
- }
- if (game.dem_tst_position === 8 && game.com_tst_position < 8) {
- game.tst_8 = false
- }
-
- //Check if they have caught up to box 7 or 8
- if (game.dem_tst_position >= 7 && game.com_tst_position >= 7) {
- delete game.tst_7
- }
- if (game.dem_tst_position >= 8 && game.com_tst_position >= 8) {
- delete game.tst_8
- }
-
- //Check if TST events occur
- if (game.com_tst_position === 3 && game.dem_tst_position < 3) {goto_vm(203)}
- else if (game.com_tst_position === 4 && game.dem_tst_position < 4) {goto_vm(204)}
- else {game.state = 'tiananmen_square_attempt_success'}
- } else {
- log(`${com_tst_req[game.com_tst_position]} required: fail`)
- game.com_tst_attempted = 1
- game.state = 'tiananmen_square_attempt_fail'
- }
- }
-}
-
-function check_presence(country) {
-
- let dem_spaces = 0;
- let com_spaces = 0;
- let dem_battlegrounds = 0;
- let com_battlegrounds = 0;
- let dem_leaders = {1: false, 4: false, 5: false, 6: false, 7: false};
- let com_leaders = {1: false, 4: false, 5: false, 6: false, 7: false};
-
-
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (space.country === country) {
-
- if (check_dem_control(i)) {
- dem_spaces++;
- if (space.battleground === 1) {
- dem_battlegrounds++;
- }
- if (leaders.includes(space.socio)) {
- dem_leaders[space.socio] = true;
- }
- }
- if (check_com_control(i)) {
- com_spaces++;
- if (space.battleground === 1) {
- com_battlegrounds++;
- }
- if (leaders.includes(space.socio)) {
- com_leaders[space.socio] = true;
- }
- }
- }
- }
-
- // Determine domination
- let dem_domination = dem_battlegrounds > com_battlegrounds && dem_spaces > com_spaces && dem_spaces - dem_battlegrounds > 0;
- let com_domination = com_battlegrounds > dem_battlegrounds && com_spaces > dem_spaces && com_spaces - com_battlegrounds > 0;
-
- // Determine control
- let total_battlegrounds = battlegrounds(country);
- let dem_control = dem_battlegrounds === total_battlegrounds && dem_spaces > com_spaces;
- let com_control = com_battlegrounds === total_battlegrounds && com_spaces > dem_spaces;
-
- return {
- dem_spaces: dem_spaces,
- com_spaces: com_spaces,
- dem_battlegrounds: dem_battlegrounds,
- com_battlegrounds: com_battlegrounds,
- dem_domination: dem_domination,
- com_domination: com_domination,
- dem_control: dem_control,
- com_control: com_control,
- dem_leaders: dem_leaders,
- com_leaders: com_leaders
- };
-}
-
-function battlegrounds(country) {
- let battlegrounds = 0;
- if (country === "Hungary") {
- battlegrounds = 4
- } else if (country === "Bulgaria") {
- battlegrounds = 5
- } else {
- battlegrounds = 6
- }
- return battlegrounds;
-}
-
-function take_power(country) {
-
- log(`Democrat takes power in ${game.pwr_struggle_in}`)
- game.revolutions[find_country_index(country)] = true
- game.times_held[find_country_index(country)] = 1
-
-}
-
-function retain_power(country){
- game.times_held[find_country_index(country)]++
- let vp_gain = get_value(country)*game.times_held[find_country_index(country)]
- log(`Chooses to retain power`)
- log(`-${vp_gain} VP`)
- game.vp -= vp_gain
-}
-
-function score_country(country) {
- log_h3(`Scoring: ${country}`)
-
-//Get scoring values
- let value_presence = get_value(country)
- let value_domination = value_presence*2
- let value_control
- if (country !== "Hungary") {
- value_control = value_presence*3
- } else {
- value_control = 4
- }
-//Log for scoring
-
- let dem_vp = 0
- let com_vp = 0
- //Check for presence
- let presence = check_presence(country)
- console.log('presence: ', presence)
-
- //If one side has domination or control
- if (presence.dem_control || presence.dem_domination) {
- log(`Democrat:`)
- if (presence.dem_control) {
- log(`Control: +${value_control} VP`)
- dem_vp += value_control
- }
- else {
- log(`Domination: +${value_domination} VP`)
- dem_vp += value_domination
- }
- log(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
- dem_vp += presence.dem_battlegrounds
- log(`Total: +${dem_vp} VP`)
-
- log_gap('Communist:')
- if (presence.com_spaces > 0) {
- log(`Presence: -${value_presence} VP`)
- com_vp -= value_presence
- if (presence.com_battlegrounds >0) {
- log(`Battlegrounds: -${presence.com_battlegrounds} VP`)
- com_vp -= presence.com_battlegrounds
- }
- log(`Total: ${com_vp} VP`)
- } else {
- log('No presence: 0 VP')
- }
-
- }
- else if (presence.com_control || presence.com_domination) {
- log('Communist:')
- if (presence.com_control) {
- log(`Control: -${value_control} VP`)
- com_vp -= value_control
- }
- else {
- log(`Domination: -${value_domination} VP`)
- com_vp -= value_domination
- }
- log(`Battlegrounds: -${presence.com_battlegrounds} VP`)
- com_vp -= presence.com_battlegrounds
- log(`Total: ${com_vp} VP`)
-
- log_gap('Democrat:')
- if (presence.dem_spaces > 0) {
- log(`Presence: +${value_presence} VP`)
- dem_vp += value_presence
- if (presence.dem_battlegrounds > 0) {
- log(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
- dem_vp += presence.dem_battlegrounds
- }
- log (`Total: +${dem_vp} VP`)
- } else {
- log('No presence: 0 VP')
- }
-
- }
-
- //Otherwise, presence and battlegrounds
- else {
- log("No domination or control")
- log_gap(`Communist:`)
- if (presence.com_spaces > 0) {
- log(`Presence: -${value_presence} VP`)
- com_vp -= value_presence
- if (presence.com_battlegrounds > 0) {
- log(`Battlegrounds: -${presence.com_battlegrounds} VP`)
- com_vp -= presence.com_battlegrounds
- } else {
- log('No battlegrounds')
- }
- log(`Total: ${com_vp} VP`)
- } else {
- log('No presence: 0 VP')
- }
- log_gap('Democrat:')
- if (presence.dem_spaces > 0) {
- log(`Presence: +${value_presence} VP`)
- dem_vp += value_presence
- if (presence.dem_battlegrounds > 0) {
- log(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
- dem_vp += presence.dem_battlegrounds
- } else {
- log('No battlegrounds')
- }
- log(`Total: +${dem_vp} VP`)
- } else {
- log('No presence: 0 VP')
- }
- }
-
-
-//Calculate change VP
- /*let dem_vp = 0
- if (presence.dem_spaces > 0) {dem_vp += value_presence}
- if (presence.dem_domination) {dem_vp += value_presence}
- if (presence.dem_control && country !== "Hungary") {
- dem_vp += value_control
- }
- else if (presence.dem_control && country === "Hungary") {dem_vp += 2}
- dem_vp += presence.dem_battlegrounds
-
- let com_vp = 0
- if (presence.com_spaces > 0) {com_vp += value_presence}
- if (presence.com_domination) {com_vp += value_presence}
- if (presence.com_control && country !== "Hungary") {com_vp += value_presence}
- else if (presence.com_control && country === "Hungary") {com_vp += 2}
- com_vp += presence.com_battlegrounds */
- let change_vp = dem_vp + com_vp
- game.vp += change_vp
- if (change_vp > 0 ) {
- log_gap(`Final change VP: +${change_vp} VP`)
- } else {
- log_gap(`Final change VP: ${change_vp} VP`)
- }
-}
-
-function get_value(country) {
- let value
- if (country === "East_Germany" || country === "Poland") {value = 3}
- else if (country === "Czechoslovakia" || country === "Romania") {value = 2}
- else value = 1
- return value
-}
-
-function permanently_remove(card) {
- console.log('card:', card)
- log_msg_gap(`C${cards[card].number} permanently removed`)
- remove_from_discard(card)
-
- /*let card_index = game.strategy_discard.indexOf(card)
- if (card_index !== -1) {
- console.log('sub 1 called')
- game.strategy_discard.splice(card_index, 1)
- }*/
- card_index = game.table_cards.indexOf(card)
- if (card_index !== -1) {
- console.log('sub 2 called')
- game.table_cards.splice(card_index, 1)
- }
- game.strategy_removed.push(card)
- console.log('game.strategy_removed', game.strategy_removed)
-}
-
-function check_vp() {
- if (game.vp >= 20) {
- goto_game_over(DEM, `${DEM} won an Automatic Victory!`)
- console.log('after goto_game_over, game.state', game.state)
- return true
- } else if(game.vp <= -20) {
- goto_game_over(COM, `${COM} won an Automatic Victory!`)
- return true
- }
- return false
-}
-
-function game_over() {
- if (game.vp >= 20 || game.vp <= -20) {
- return true
- } else { return false}
-}
-
-function goto_game_over(result, victory) {
- game.state = "game_over"
- game.active = "None"
- game.result = result
- game.victory = victory
- log_h1("Game Over")
- log(game.victory)
- console.log('game over, game.state', game.state)
- return
-
-}
-
-function reset_austria_hungary_border_reopened() {
- //game.austria_hungary_border_reopened_checked = false
- game.austria_hungary_border_reopened_tracker = false
-}
-
-function end_stasi_choose_card() {
- game.round_player = COM
- game.round ++
- log_h2(`Action Round ${game.round}`)
- next_player()
- game.valid_spaces = []
- if (game.persistent_events.includes(5)) {
- log_h3('C5')
- game.state = 'general_strike'
- } else {
- game.state = 'choose_card'
- }
-}
-
-function check_reformer() {
- if (game.dem_tst_position !== game.com_tst_position) {
- if (!game.playable_cards.includes(67)) {
- game.playable_cards.push(67)
- }
- } else {
- game.playable_cards = game.playable_cards.filter(n => n !== 67)
- }
-
-}
-
-function count_scoring_cards() {
- let scoring_check
- if (game.active === DEM) {
- scoring_check = game.democrat_hand.filter(card => scoring_cards.includes(card)).length
- } else {
- scoring_check = game.communist_hand.filter(card => scoring_cards.includes(card)).length
- }
- return scoring_check
-}
-
-function select_card(card){
- game.played_card = card
- game.temp = 0
- let find_card
- if (game.active === COM) {
- find_card = game.communist_hand.indexOf(card)
- game.communist_hand.splice(find_card, 1)
- } else {
- find_card = game.democrat_hand.indexOf(card)
- game.democrat_hand.splice(find_card, 1)
- }
- game.available_ops = get_card_ops(card)
-
- //Check Ligachev
- if (game.active === DEM && game.persistent_events.includes(99) && card !== 14) {
- log('-3 VP from C99')
- game.vp -= 3
- if (check_vp()) {
- return
- }
- game.persistent_events = game.persistent_events.filter(n => n !== 99)
- }
- game.state = 'play_card'
- console.log('game.state', game.state)
-}
-
-function find_event(card) {
- return variable_events.indexOf(card)
-}
-
-function get_events(card){
- if (cards[card].side === 'D') {
- if (game.active === DEM) {gen_action('card_event', card)}
- if (game.active === COM) {gen_action('card_opp_event', card)}
- }
- else if (cards[card].side === 'C') {
- if (game.active === COM) {gen_action('card_event', card)}
- if (game.active === DEM) {gen_action('card_opp_event', card)}
- } else {
- gen_action('card_event', card)
- }
-}
-
-function get_card_ops(card) {
- let ops = 0
-
- if (card) {
- ops = cards[card].ops
- }
- if (game.persistent_events.includes(25) && game.active === COM) {
- if(game.state === 'choose_card' || game.state === 'stasi_play_card') {
- log('+1 op from C25')
- }
- ops ++
- }
- if (game.persistent_events.includes(50) && game.active === DEM) {
- if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_laszlo_tokes') {
- log('+1 op from C50')
- }
- ops ++
- }
-
- if ((game.active === DEM && game.dem_tst_position >= 2 && game.com_tst_position <= 1 && cards[card].ops === 1) || (game.active === COM && game.com_tst_position >=2 && game.dem_tst_position <= 1 && cards[card].ops === 1)) {
- if(game.state === 'choose_card' || game.state === 'stasi_play_card') {
- log('+1 op from Tiananmen Square Track')
- }
- ops ++
- }
-
- if ((game.active === DEM && game.prudence && game.prudence.DEM !== 0)) {
- if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_laszlo_tokes') {
- if (ops > 2) {
- log(`${pluralize(game.prudence.DEM,'op')} from C8`)
- } else {
- if (ops > 1) {
- log(`-1 op from C8`)
- }
- }
- }
- ops += game.prudence.DEM
-
- if (ops < 1) {
- ops = 1
- }
- }
-
- if (game.active === COM && game.prudence && game.prudence.COM < 0) {
- if(game.state === 'choose_card') {
- if (ops > 2) {
- log(`${pluralize(game.prudence.COM,'op')} from C8`)
- } else if (ops > 1) {
- log(`-1 op from C8`)
- }
- }
- ops += game.prudence.COM
- if (ops < 1) {
- ops = 1
- }
- } return ops
-}
-
-function get_tst_6_ops() {
- let ops = 0
-
- if (game.persistent_events.includes(25) && game.active === COM) {
- log('+1 op from C25')
- ops ++
- }
- if (game.persistent_events.includes(50) && game.active === DEM) {
- log('+1 op from C50')
- ops ++
- }
-
- if ((game.active === DEM && game.prudence && game.prudence.DEM !== 0)) {
- if (ops > 0) {
- log(`${pluralize(game.prudence.DEM,'op')} from C8`)
- } else {
- log(`-1 op from C8`)
- }
-
- ops += game.prudence.DEM
-
- if (ops < -1) {
- ops = -1
- }
- }
-
- if (game.active === COM && game.prudence && game.prudence.COM < 0) {
-
- if (ops > 0) {
- log(`${pluralize(game.prudence.COM,'op')} from C8`)
- } else {
- log(`-1 op from C8`)
- }
-
- ops += game.prudence.COM
- if (ops < -1) {
- ops = -1
- }
- }
- return ops
-}
-
-
-// =========== MOVING THROUGH TURNS ============
-
-function end_round() {
- //Check if the game is over!
- if (game.state === 'game_over') {
- console.log('in end')
- return}
-
- //Check if the card has been removed or played to table, and if a card has been not been played. If not, discard.
- if (!game.strategy_removed.includes(game.played_card) && !game.table_cards.includes(game.played_card) && game.played_card > 0) {
- game.strategy_discard.push(game.played_card)
- }
-
- //Reset
- game.played_card = 0
- game.temp = 0
- game.vm_event = 0
- game.phase = 0
- game.remove_opponent_infl = false
- game.is_pwr_struggle = false
- game.vm_infl_to_do = false /*Can get rid of this and use game.return_state? */
- game.vm_event_to_do = false
- game.vm_active_country = ''
- game.return_state = ''
- game.discard = false
- game.return = ''
- game.valid_cards = []
- game.valid_spaces = []
- check_common_european_home()
- //game.playable_cards[find_event(21)] = true
- reset_austria_hungary_border_reopened() /*This should be redundant! */
-
-
- // Check for duplicate card entries
- let card_check
- if (game.samizdat_card > 0) {
- card_check = [...game.strategy_deck, ...game.strategy_discard, ...game.strategy_removed, ...game.table_cards, ...game.communist_hand, ... game.democrat_hand, game.samizdat_card];
- } else {
- card_check = [...game.strategy_deck, ...game.strategy_discard, ...game.strategy_removed, ...game.table_cards, ...game.communist_hand, ... game.democrat_hand];
- }
-
- function check_duplicates(array) {
- return new Set(array).size !== array.length;
- }
-
- function find_duplicates(array) {
- const duplicates = array.filter((item, index) => array.indexOf(item) !== index);
- return [...new Set(duplicates)];
- }
-
- console.log('game.strategy_deck', game.strategy_deck, 'game.strategy_discard', game.strategy_discard, 'game.strategy_removed', game.strategy_removed, 'game.table_cards', game.table_cards, 'game.communist_hand', game.communist_hand, 'game.democrat_hand', game.democrat_hand)
-
- if (check_duplicates(card_check)) {
- const duplicates = find_duplicates(card_check)
- console.log('discard', game.strategy_discard, 'removed', game.strategy_removed, 'game.table_cards', game.table_cards, 'com hand', game.communist_hand, 'dem hand', game.democrat_hand)
- throw new Error(`Duplicate cards detected: ${duplicates.join(', ')}`)
- }
- console.log('cards in game', card_check.length)
- card_check = card_check.sort((a, b) => a - b)
- console.log('cards in game', card_check)
- if (game.turn <= 3) {
- if (card_check.length !== 40) {
- throw new Error(`Wrong number of cards: ${card_check.length}`)
- }
- } else if (game.turn <=7) {
- if (card_check.length !== 81) {
- throw new Error(`Wrong number of cards: ${card_check.length}`)
- }
- } else if (card_check.length !== 110) {
- throw new Error(`Wrong number of cards: ${card_check.length}`)
- }
-
-
-
- console.log('game.dem_tst_position ', game.dem_tst_position , 'game.com_tst_position ', game.com_tst_position )
- //Check if the Reformer is playable
- check_reformer()
-
- // Check if last round and if so resolve end turn events
- if (game.round_player === DEM && game.round === 7) {
- if(game.persistent_events.includes(15)) {
- if (game.active !== COM) {
- next_player()
- }
- game.state = 'honecker'
- return
- }
- else if (game.dem_tst_position >= 6 && game.com_tst_position <= 5) {
- log_h2('Tiananmen Square Track Award')
- if (game.active !== DEM) {
- next_player()
- }
- game.return = game.active
- clear_undo()
- game.return_state = 'end_turn_4_5_4'
- goto_vm(206)
- return
- } else if (game.com_tst_position >= 6 && game.dem_tst_position <= 5) {
- log_h2('Tiananmen Square Track Award')
- if (game.active !== COM) {
- next_player()
- }
- game.return = game.active
- clear_undo()
- game.return_state = 'end_turn_4_5_4'
- goto_vm(206)
- return
- }
- else {
- clear_undo()
- game.state = 'end_turn_4_5_4'
- return
- }
- }
-
- // Resolve end action round
- //Stasi check
- if(game.round_player === COM && game.persistent_events.includes(13)) {
- game.round_player = DEM
- if (game.active !== DEM) {
- next_player()
- } else {
- log_h3('Democratic Action Round')
- log_h3('C13')
- }
- if (game.democrat_hand.includes(game.stasi_card)) {
- game.state = 'stasi_play_card'
- } else {
- game.stasi_card = 0
- game.state = 'choose_card'
- }
- return
- }
- //Check if in extra Action Round
- else if (game.round_player === COM && game.round === 8) {
- clear_undo()
- game.state = 'end_turn_4_5_4'
- return
- }
- //Normal round end
- else if (game.round_player===COM) {
- game.round_player = DEM
- if (game.active !== DEM) {
- next_player()
- } else {
- log_h3('Democratic Action Round')
- }
- game.state = 'choose_card'
- return
- }
- if (game.round_player === DEM) {
- console.log('checking stasi', game.persistent_events.includes(13))
- if(game.persistent_events.includes(13)) {
- console.log('stasi sub function')
- if (game.active !== DEM) {
- next_player()
- }
- game.state = 'stasi_end_round'
- return
- } else if(game.round_player === DEM && game.persistent_events.includes(5)){
- game.state = 'general_strike'
- game.round ++
- log_h2(`Action Round ${game.round}`)
- game.round_player = COM
- if (game.active !== COM) {
- next_player()
- }
- log_h3('C5')
- return
- } else {
- game.state = 'choose_card'
- game.round_player = COM
- game.round ++
- log_h2(`Action Round ${game.round}`)
- if (game.active !== COM) {
- next_player()
- }
- }
- }
- //game.state = 'choose_card' Does this do anything any more?
-}
-
-/*
-function end_turn(){
- /*End Turn sequence
- TST support check
- Verify held cards
- New Year's Eve Party
- Advance Turn Marker
-
-// CHECK FOR OPTIONAL SUPPORT CHECK
- if (game.dem_tst_position >=6 && game.com_tst_position <= 5) {
- if (game.active !== DEM) {
- next_player_()
- }
- game.state = 'tst_support_check'
- }
- if (game.com_tst_position >=6 && game.dem_tst_position <= 5) {
- if (game.active !== COM) {
- next_player_()
- }
- game.state = 'tst_support_check'
- }
-
-
-//CHECK HELD CARDS
-
-} */
-
-function new_turn() {
- clear_undo()
- game.turn ++
- game.round = 1
- game.valid_spaces=[]
- game.active = COM
- game.round_player = COM
- game.dem_tst_attempted_this_turn = 0
- game.com_tst_attempted_this_turn = 0
- if (game.tst_7) {game.tst_7 = false}
- if (game.tst_8) {game.tst_8 = false}
-
- //Remove events that only last one turn
- game.persistent_events = game.persistent_events.filter(n => n !== 25) /*Perestroika*/
- game.persistent_events = game.persistent_events.filter(n => n !== 50) /*Sinatra Doctrine*/
- game.persistent_events = game.persistent_events.filter(n => n !== 13) /*Stasi*/
- game.persistent_events = game.persistent_events.filter(n => n !== 15) /*Honecker*/
- delete game.prudence
- delete game.stasi_card
-
- //Austria Hungary Border Reopened
- if (game.persistent_events.includes(58)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 58)
- delete game.austria_hungary_border_reopened_tracker
- log(`C58 no longer in effect`)
- //permanently_remove(58)
- }
- //Elena
- if (game.persistent_events.includes(101)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 101)
- log(`C101 no longer in effect`)
- //permanently_remove(101)
- }
- //GrenzTruppen
- if (game.persistent_events.includes(59)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 59)
- log(`C59 no longer in effect`)
- //permanently_remove(59)
- }
- //Foreign Currency Debt Burden
- if (game.persistent_events.includes(49)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 49)
- delete game.foreign_currency_debt_burden
- log(`C49 no longer in effect`)
- //permanently_remove(49)
- }
- //FRG Embassies
- if (game.persistent_events.includes(74)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 74)
- log(`C74 no longer in effect`)
- discard_from_table(74)
- permanently_remove(74)
- }
- //Genscher
- if (game.persistent_events.includes(63)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 63)
- log(`C63 no longer in effect`)
- discard_from_table(63)
- permanently_remove(63)
- }
- //Stand Fast
- if (game.persistent_events.includes(100)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 100)
- delete game.stand_fast
- log(`C100 no longer in effect`)
- //permanently_remove(100)
- }
-
- if (game.samizdat_card > 0 ) {
- game.democrat_hand.push(game.samizdat_card)
- delete game.samizdat_card
- }
-
- log_h1("Turn " + game.turn)
-
- if (game.turn === 4) {
- add_midyear()
- }
- if (game.turn === 8) {
- add_lateyear()
- }
- if (game.turn > 1) {
- if (game.persistent_events.includes(65)) {
- game.com_hand_limit = 7
- log('Communist draws 7 cards due to C65')
- //permanently_remove(65)
- game.persistent_events = game.persistent_events.filter(n => n !== 65)
- }
- console.log('deck', game.strategy_deck)
- console.log('game.com_hand_limit', game.com_hand_limit, 'communist hand before draw', game.communist_hand)
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.dem_hand_limit, game.com_hand_limit)
- game.com_hand_limit = 8
- console.log('communist hand after draw', game.communist_hand)
-
- }
-
- //Check if TST effects need to be resolved
- if (game.dem_tst_position >=5 && game.com_tst_position <= 4) {
- log_h2('Tiananmen Square Track award')
- if(game.active !== DEM) { next_player() }
- for (let card of game.democrat_hand) {
- if (scoring_cards.includes(card)) continue
- game.valid_cards.push(card)
- }
- game.state = 'tst_goddess' /* Goddess only name of Democrat bonus, not Communist*/
- return
- }
- else if (game.com_tst_position >=5 && game.dem_tst_position <= 4) {
- log_h2('Tiananmen Square Track award')
- if(game.active !== COM) { next_player() }
- for (let card of game.communist_hand) {
- if (scoring_cards.includes(card)) continue
- game.valid_cards.push(card)
- }
- game.state = 'tst_goddess'
- } else {
- log_h2("Action Round " + game.round)
- log_side()
- //console.log('in start new AR call, game.active', game.active)
- if (game.persistent_events.includes(5)) {
- log_h3('C5')
- game.state = 'general_strike'
- }
- else {
- game.state = 'choose_card'
- }
- }
-}
-
-function next_player() {
- clear_undo()
- //console.log('next player called')
- if (game.active === DEM)
- game.active = COM
- else
- game.active = DEM
-
- log_side()
-}
-
-function change_player() {
- clear_undo()
- //console.log('next player called')
- if (game.active === DEM)
- game.active = COM
- else
- game.active = DEM
-}
-
-function find_space_index(name_unique) {
- return spaces.findIndex(space => space && space.name_unique === name_unique)
-}
-
-function find_country_index(country) {
- return countries.indexOf(country)
-}
-
-function draw_deck(deck) {
- return deck.filter(card => card && card.period === 1).map(card => card.number)
-}
-
-function draw_cards(deck, democrat_hand, communist_hand, dem_hand_limit, com_hand_limit) {
- //console.log('game.valid_cards at start of draw cards: ', game.valid_cards)
- let turn = 'communist'; // Start with the communist player
- //console.log('game.strategy_deck', game.strategy_deck)
- console.log('deck', deck, 'democrat_hand', democrat_hand, 'communist_hand', communist_hand, 'dem_hand_limit', dem_hand_limit, 'com_hand_limit', com_hand_limit)
- while (democrat_hand.length < dem_hand_limit || communist_hand.length < com_hand_limit) {
- //console.log('deck.length: ', deck.length)
- //console.log('discard.length', game.strategy_discard )
- if (deck.length === 0) {
- log_h3('--- Reshuffle ---')
-
- deck.push(...game.strategy_discard)
- game.strategy_discard = []
- }
-
- else if (turn === 'communist' && communist_hand.length < com_hand_limit) {
- communist_hand.push(draw_card(deck));
- //console.log('game.valid_cards after communist draw: ', JSON.stringify(game.valid_cards));
- turn = 'democrat';
- } else if(turn === 'communist' && communist_hand.length === com_hand_limit) {
- turn = 'democrat';
- }
- else if (turn === 'democrat' && democrat_hand.length < dem_hand_limit) {
- democrat_hand.push(draw_card(deck));
- //console.log('democrat_hand: ', democrat_hand)
-
- //console.log('game.valid_cards after democrat draw: ', JSON.stringify(game.valid_cards));
- turn = 'communist';
- }
- else if (turn === 'democrat' && democrat_hand.length === dem_hand_limit) {
- turn = 'communist';
- }
- }
-
- clear_undo()
-}
-
-function draw_card(deck) {
- //console.log('draw card called with:', deck)
- //console.log('game.strategy_deck before', game.strategy_deck)
- if (deck.length === 0) {
- log_h3('--- Reshuffle ---')
-
- deck.push(...game.strategy_discard)
- game.strategy_discard = []
- }
- const randomIndex = Math.floor(Math.random() * deck.length)
- //console.log('card chosen:', randomIndex)
- //console.log('game.strategy_deck after', game.strategy_deck)
- return deck.splice(randomIndex, 1)[0];
-}
-
-function discard(card) {
- //console.log('in discard(card)')
- let find_card
- if (!game.is_pwr_struggle) {
- if (game.active === COM) {
- find_card = game.communist_hand.indexOf(card)
- game.communist_hand.splice(find_card, 1)
- } else {
- find_card = game.democrat_hand.indexOf(card)
- game.democrat_hand.splice(find_card, 1)
- }
- game.strategy_discard.push(card)
- log(`Discarded C${cards[card].number}`)
-
- } else if (game.is_pwr_struggle) {
- if (game.active === COM) {
- find_card = game.com_pwr_hand.indexOf(card);
- game.com_pwr_hand.splice(find_card, 1);
- } else {
- find_card = game.dem_pwr_hand.indexOf(card);
- game.dem_pwr_hand.splice(find_card, 1);
- }
- game.power_struggle_discard.push(card)
- //log(`Discarded P${power_cards[card].number}`)
- }
-}
-function silent_discard(card) {
- //console.log('in discard(card)')
- let find_card
- if (!game.is_pwr_struggle) {
- if (game.active === COM) {
- find_card = game.communist_hand.indexOf(card)
- game.communist_hand.splice(find_card, 1)
- } else {
- find_card = game.democrat_hand.indexOf(card)
- game.democrat_hand.splice(find_card, 1)
- }
- game.strategy_discard.push(card)
-
- } else if (game.is_pwr_struggle) {
- if (game.active === COM) {
- find_card = game.com_pwr_hand.indexOf(card);
- game.com_pwr_hand.splice(find_card, 1);
- } else {
- find_card = game.dem_pwr_hand.indexOf(card);
- game.dem_pwr_hand.splice(find_card, 1);
- }
- game.power_struggle_discard.push(card)
- }
-}
-
-function remove_from_discard(card) {
- let card_index = game.strategy_discard.indexOf(card)
- if (card_index !== -1) {
- game.strategy_discard.splice(card_index, 1)
- }
-}
-
-function discard_card(hand) {
- //let find_card
- let card = Math.floor(Math.random()*hand.length)
- let discarded_card = hand.splice(card, 1)[0]
- if (game.is_pwr_struggle) {
- if (numberless_cards.includes(discarded_card)) {
- log_gap(`Discarded: P${discarded_card}`)
- } else {
- log_gap(`Discarded: P${discarded_card} V${power_cards[discarded_card].value}`)
- }
- } else {
- log(`Discarded C${cards[discarded_card].number}`)
- game.strategy_discard.push(discarded_card)
- }
- return discarded_card
-}
-
-function discard_from_table(card) {
- find_card = game.table_cards.indexOf(card)
- game.table_cards.splice(find_card, 1)
- game.strategy_discard.push(card)
-}
-
-
-function add_midyear() {
- const mid_year = cards.filter(card => card && card.period === 2).map(card => card.number);
- game.strategy_deck.push(...mid_year);
- log_h3('Mid-year cards added to draw deck')
-}
-
-
-function add_lateyear() {
- const late_year = cards.filter(card => card && card.period === 3).map(card => card.number)
- game.strategy_deck.push(...late_year)
- log_h3('Late-year cards added to draw deck')
-}
-
-function reset_power() {
- game.power_struggle_deck = []
- game.power_struggle_discard = []
- game.dem_pwr_hand = []
- game.com_pwr_hand = []
- game.phase = 1
- game.raised_stakes_round = 0
- game.raised_stakes = 0
- game.played_power_card = 0
- game.tactics_fails = ''
- game.view_opp_hand = false
-
- if (game.persistent_events.includes(72)){
- permanently_remove(72)
- game.table_cards = game.table_cards.filter(card => card !== 72)
- game.persistent_events = game.persistent_events.filter(n => n !== 72)
- }
- if (game.persistent_events.includes(62)) {
- permanently_remove(62)
- game.table_cards = game.table_cards.filter(card => card !== 62)
- game.persistent_events = game.persistent_events.filter(n => n !== 62)
- }
- if (game.persistent_events.includes(54) && game.pwr_struggle_in === 'Romania'){
- permanently_remove(54)
- //game.table_cards = game.table_cards.filter(card => card !== 54)
-
- }
- if (game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(70)){
- //permanently_remove(70)
- //game.table_cards = game.table_cards.filter(card => card !== 70)
- game.persistent_events = game.persistent_events.filter(n => n !== 70)
- }
-}
-
-function check_control_change(space_id) {
- /*game.pieces[space_id].demCtrl = 0
- game.pieces[space_id].comCtrl = 0
-
- if ((game.demInfl[space_id] - game.comInfl[space_id]) >= game.pieces[space_id].stability) {
- game.pieces[space_id].demCtrl = 1
- }
- if ((game.comInfl[space_id] - game.demInfl[space_id]) >= game.pieces[space_id].stability) {
- game.pieces[space_id].comCtrl = 1
- }*/
-
- // Check if the Tyrant is Gone has been fulfilled
- console.log('check control change_player, game.the_tyrant_is_gone', game.the_tyrant_is_gone)
- //console.log('dem control', check_dem_control(game.the_tyrant_is_gone))
- if (game.the_tyrant_is_gone > 0 && check_dem_control(game.the_tyrant_is_gone)) {
- console.log('in tyrant')
- log('+2 VP from C97')
- game.vp += 2
- if (check_vp()) {
- return
- }
- game.persistent_events = game.persistent_events.filter(n => n !== 97)
- delete game.the_tyrant_is_gone
- }
-}
-
-function check_systematization() {
- // Check for Systematization - may not use this space
- if (game.systematization > 0) {
- game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
- }
-}
-
-function check_common_european_home() {
- if (!game.playable_cards.includes(21)) {
- game.playable_cards.push(21)
- }
-}
-
-function this_card() {
- return game.vm_event > 0 ? game.vm_event : game.played_card
-}
-/*
-function get_ops(card) {
- let ops = cards[card].ops
- if (game.active === COM) {
- //Check TST op bonus
- if (ops === 1 && game.com_tst_position >=2 && game.dem_tst_position <=1) {
- ops++
- }
- //Events that influence ops
- if (game.persistent_events.includes(25)) {
- ops++
- }
- if (game.prudence.COM && game.prudence.COM <0) {
- ops += game.prudence.COM
- }
-
- } else {
- //Check TST op bonus
- if (ops === 1 && game.dem_tst_position >=2 && game.com_tst_position <=1) {
- ops++
- }
- //Events that influence ops
- if (game.persistent_events.includes(50)) {
- ops++
- }
- if (game.prudence.DEM && game.prudence.DEM <0) {
- ops += game.prudence.DEM
- }
- }
- //Ops can never be less than one
- if (ops <1) { ops = 1 }
- return ops
-}
- */
-
-const pluralize = (count, noun, suffix = 's') =>
- `${count} ${noun}${Math.abs(count) !== 1 ? suffix : ''}`
-
-function clean_name(str) {
- if (str && str.slice(-1) === '*') {
- return str.slice(0, -1)
- } else {
- return str;
- }
-}
-
-function country_name(country) {
- return country.replace(/_/g, ' ')
-}
-
-// ======== LOG FUNCTIONS =============
-
-function log(msg) {
- game.log.push(msg)
-}
-
-function log_br() {
- if (game.log.length > 0 && game.log[game.log.length - 1] !== "")
- game.log.push("")
-}
-
-function logi(msg) {
- game.log.push(">" + msg)
-}
-
-function log_h1(msg) {
- log_br()
- log(".h1 " + msg)
- log_br()
-}
-
-function log_h2(msg) {
- log_br()
- log(".h2 " + msg)
- log_br()
-}
-
-function log_h3(msg) {
- log_br()
- log(".h3 " + msg)
-}
-
-function log_gap(msg) {
- log_br()
- game.log.push(msg)
-}
-
-function log_msg_gap(msg) {
- game.log.push(msg)
- log_br()
-}
-
-
-function log_side() {
- log_br()
- if (game.active === DEM)
- log(".h2d " + game.active)
- else
- log(".h2c " + game.active)
- log_br()
-}
-
-function log_sep() {
- log(".hr")
-}
-
-function log_action(msg) {
- log_br()
- log(msg)
-}
-
-// ============= SUMMARY FUNCTIONS =============
-
-function push_summary() {
- if (game.summary)
- throw "TOO MANY SUMMARIES"
- game.summary = []
-}
-
-function log_summary(msg) {
-
- if (msg.startsWith('Added') || msg.startsWith('Removed')) {
- for (let item of game.summary) {
- if (item[1] === msg) {
- item[0]++
- return
- }
- }
- }
- game.summary.push([1, msg])
-}
-
-function pop_summary() {
- console.log('summary', game.summary)
- if (game.summary.length > 0) {
- for (let [n, msg] of game.summary) {
- if (n > 1) {
- log(msg.replace("£ SP", `${n} SPs`));
- } else {
- log(msg.replace("£ SP", `${n} SP`));
- }
- }
- }
- game.summary = []
-}
-
-function log_summary_place(p) {
- let from = piece_space(p)
- if (from !== AVAILABLE)
- log_summary("% " + piece_name(p) + " from S" + from)
- else
- log_summary("% " + piece_name(p))
-}
-
-function log_summary_move_to_from(p, to) {
- log_summary("% " + piece_name(p) + " to S" + to + " from S" + piece_space(p))
-}
-
-function log_summary_remove(p) {
- log_summary("Removed % " + piece_name(p))
-}
-
-function log_summary_activated(p) {
- log_summary("Activated % " + piece_faction_name(p))
-}
-
-// ============ UNDO FUNCTIONS ==================
-
-function clear_undo() {
- if (game.undo.length > 0)
- game.undo = []
-}
-
-function push_undo() {
- let copy = {}
- for (let k in game) {
- let v = game[k]
- if (k === "undo")
- continue
- else if (k === "log")
- v = v.length
- else if (typeof v === "object" && v !== null)
- v = object_copy(v)
- copy[k] = v
- }
- game.undo.push(copy)
-}
-
-function pop_undo() {
- let save_log = game.log
- let save_undo = game.undo
- game = save_undo.pop()
- save_log.length = game.log
- game.log = save_log
- game.undo = save_undo
-}
-
-// Fast deep copy for objects without cycles
-function object_copy(original) {
- if (Array.isArray(original)) {
- let n = original.length
- let copy = new Array(n)
- for (let i = 0; i < n; ++i) {
- let v = original[i]
- if (typeof v === "object" && v !== null)
- copy[i] = object_copy(v)
- else
- copy[i] = v
- }
- return copy
- } else {
- let copy = {}
- for (let i in original) {
- let v = original[i]
- if (typeof v === "object" && v !== null)
- copy[i] = object_copy(v)
- else
- copy[i] = v
- }
- return copy
- }
-}
-
-
-/* =================== VM FUNCTIONS ========================== */
-
-function goto_vm(proc) {
- let old_vm = game.vm;
-
- game.state = "vm";
- game.vm = {
- prompt: 0,
- fp: proc,
- ip: 0,
- };
-
- if (old_vm) {
- game.vm.return_vm = old_vm;
- }
-
- vm_exec();
-}
-
-function vm_exec() {
- vm_inst(0)();
-}
-
-function vm_inst(a) {
- console.log('game.vm.fp', game.vm.fp, 'game.vm.ip', game.vm.ip)
- return CODE[game.vm.fp][game.vm.ip][a]
-}
-
-function vm_next() {
- game.vm.ip++;
- console.log('vm_next called, game.vm.ip', game.vm.ip)
- vm_exec();
-}
-
-function vm_operand(a) {
- let x = CODE[game.vm.fp][game.vm.ip][a]
- if (a > 0 && typeof x === "function")
- return x()
- return x
-}
-
-function vm_assert_argcount(n) {
- const argcount = CODE[game.vm.fp][game.vm.ip].length - 1
- if (argcount !== n)
- throw Error(`ASSERT Invalid number of arguments on event ${game.vm.fp}: ${argcount} instead of ${n}`)
-}
-
-function vm_log() {
- log(vm_operand(1));
- vm_next();
-}
-
-function vm_if() {
- console.log('game.temp', game.temp)
- console.log('vm_operand(1)', vm_operand(1))
- if (!vm_operand(1)) {
- let balance = 1
- while (balance > 0) {
- ++game.vm.ip
- switch (vm_operand(0)) {
- case vm_if:
- ++balance
- break
- case vm_endif:
- --balance
- break
- case vm_else:
- if (balance === 1)
- --balance
- break
- }
- if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length)
- throw "ERROR"
- }
- }
- vm_next()
-}
-
-function vm_else() {
- vm_goto(vm_endif, vm_if, 1, 1)
-}
-
-function vm_endif() {
- vm_next()
-}
-
-function vm_goto_step(step) {
- console.log('vm_goto_step called, target:', step)
- console.log('game.vm.ip', game.vp.ip)
- for (let i = game.vm.ip; i < CODE[game.vm.fp].length; i++) {
- console.log('i', i)
- console.log('step', CODE[game.vm.fp][i][0])
- if (CODE[game.vm.fp][i][0] === step) {
- game.vm.ip = i;
- vm_exec();
- return;
- }
- }
-
- console.log("ERROR: Target operation not found in the current procedure.");
-}
-
-
-function vm_goto(op, nop, dir, step) {
- console.log('vm_inst(0)', vm_inst(0), op, nop)
- console.log('vm_inst(0)', vm_inst(1), op, nop)
- let balance = 1
- while (balance > 0) {
- game.vm.ip += dir
- if (vm_inst(0) === op)
- --balance
- if (vm_inst(0) === nop)
- ++balance
- if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length)
- throw "ERROR"
- }
- game.vm.ip += step
- vm_exec()
-}
-
-function event_prompt(str) {
- //console.log('event_prompt called with', str)
- if (typeof str === "undefined")
- str = CODE[game.vm.fp][game.vm.prompt][1]
- if (typeof str === "function")
- str = str()
- //console.log('str:', str)
- if (!str) {
- str = ""
- }
- return str
-}
-
-function vm_prompt() {
- if (game.vm.prompt)
- game.vm._prompt = game.vm.prompt
- game.vm.prompt = game.vm.ip
- vm_next()
-}
-
-function pop_vm_prompt() {
- if (game.vm._prompt) {
- game.vm.prompt = game.vm._prompt
- delete game.vm._prompt
- } else {
- game.vm.prompt = 0
- }
-}
-
-function vm_return() {
-
- //Remove temporary vm variables
- delete game.support_check_modifier
- delete game.vm_max_infl
- delete game.vm_influence_added
- delete game.communist_hand_red
-
- game.vm_event = 0 /*Reset to 0 now that event has been completed. Hopefully this doesn't cause issues! */
- if (game.persistent_events.includes(58)) {
- reset_austria_hungary_border_reopened()
- }
-
- //game.view_opp_hand = false
- console.log('in vm_return, game.return:', game.return, 'game.return_state:', game.return_state, 'game.vm_infl_to_do', game.vm_infl_to_do, 'game.vm_event_to_do', game.vm_event_to_do)
- /*if (!game.vm_infl_to_do && !game.vm_event_to_do) {
- if (game.round_player !== game.active) {
- change_player()
- log_h2('End of Action Round')
- }
- end_round()
- return
- } /*Go direct to end round if card fully resolved */
- if (game.return !== game.active) {
- next_player()}
- if (game.return_state === 'power_struggle') {
- do_valid_cards()
- }
- if (game.return_state && game.return_state !== '') {
- game.state = game.return_state
- console.log( 'game.state', game.state)
- }
- else if (game.vm_infl_to_do) {game.state = 'resolve_opponent_event'} /*Can use game.return state for this? */
- else {game.state = "play_card"}
-}
-
-/* ================== VM ACTIONS =========================== */
-
-function vm_opp_hand_false() {
- game.view_opp_hand = false
- vm_next()
-}
-
-function vm_valid_spaces() {
- let space_1 = vm_operand(1)
- let space_2 = vm_operand(2)
- let space_3 = vm_operand(3)
- let space_4 = vm_operand(4)
- let space_5 = vm_operand(5)
- let space_6 = vm_operand(6)
- game.valid_spaces = [space_1, space_2, space_3, space_4, space_5, space_6]
- game.valid_spaces = game.valid_spaces.filter( n => n )
-
- // Check for Systematization - may not use this space
- check_systematization()
-
- vm_next()
-}
-
-function vm_valid_spaces_opponent () {
- let valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
-
- if (game.active === DEM) {
- let infl = game.comInfl[i]
- if (infl > 0) {
- valid_spaces.push(space.space_id)
- }
- } else {
- infl = game.demInfl[i]
- if (infl > 0) {
- valid_spaces.push(space.space_id)
- }
- }
- }
- game.valid_spaces = valid_spaces
- console.log('game.valid_spaces', game.valid_spaces)
- vm_next()
-}
-
-function vm_valid_spaces_socio () {
- let valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
-
- if (space.socio === vm_operand(1)) {
- valid_spaces.push(space.space_id)
- }
- }
- game.valid_spaces = valid_spaces
-
- // Check for Systematization - may not use this space
- if (game.systematization && game.systematization > 0) {
- game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
- }
- vm_next()
-}
-
-function vm_valid_spaces_opponent_socio () {
- let valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
-
- if (game.active === DEM) {
- let infl = game.comInfl[i]
- if (infl > 0 && space.socio === vm_operand(1)) {
- valid_spaces.push(space.space_id)
- }
- } else {
- let infl = game.demInfl[i]
- if (infl > 0 && space.socio === vm_operand(1)) {
- valid_spaces.push(space.space_id)
- }
- }
- }
- game.valid_spaces = valid_spaces
- // Check for Systematization - may not use this space
- if (game.systematization && game.systematization > 0) {
- game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
- }
- vm_next()
-}
-
-function vm_valid_spaces_country () {
- let country
- if (vm_operand(1)) {country = vm_operand(1)}
- else {country = game.vm_active_country}
- for (let space of spaces) {
- if (!space) continue
- if (space.country === country) {
- game.valid_spaces.push(space.space_id);
- }
- }
- // Check for Systematization - may not use this space
- if (game.systematization && game.systematization > 0) {
- game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
- }
- vm_next()
-}
-
-function vm_valid_spaces_sc () {
- valid_spaces_sc()
- vm_next()
-}
-
-function vm_valid_spaces_country_opp () {
- let country = ''
-
- if (vm_operand(1)) {
- country = vm_operand(1) }
- else {
- country = game.vm_active_country
- }
- for (let space of spaces) {
- if (!space) continue
- if (game.active === DEM) {
- if (space.country === country && game.comInfl[space.space_id] >0) {
- game.valid_spaces.push(space.space_id);
- }
- } else {
- if (space.country === country && game.demInfl[space.space_id]>0) {
- game.valid_spaces.push(space.space_id);
- }
- }
- }
- vm_next()
-}
-
-function vm_valid_spaces_country_sc () {
- let valid_spaces = []
- let country = ''
- console.log('in vm_valid_spaces_country_sc')
- if (vm_operand(1)) {
- country = vm_operand(1) }
- else {
- country = game.vm_active_country
- }
- for (let space of spaces) {
- if (!space) continue
- if (game.active === DEM) {
- if (space.country === country && game.comInfl[space.space_id] >0) {
- valid_spaces.push(space.space_id);
- }
- } else {
- if (space.country === country && game.demInfl[space.space_id] >0) {
- //Check Solidarity Legalised
- if (game.persistent_events.includes(2) && space.space_id === 14) {continue}
-
- //Check Civic Forum
- if (game.persistent_events.includes(90) && space.space_id === 30) {continue}
-
- //Check We are the People
- if (game.persistent_events.includes(48) && space.space_id === 9) {continue}
- valid_spaces.push(space.space_id);
-
- //Check Foreign Currency Debt Burden
- if (game.persistent_events.includes(49) && space.country === game.foreign_currency_debt_burden) {continue}
- }
- }
- }
- game.valid_spaces = valid_spaces
-
- //Check for Foreign Currency Debt Burden
- /*if (game.persistent_events.includes(49) && game.active === COM) {
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country !== game.foreign_currency_debt_burden)
- }*/
- vm_next()
-}
-
-function vm_valid_spaces_country_socio_2() {
- for (let space of spaces) {
- if (!space) continue
- if (space.space_id === game.systematization) continue
- if ((space.country === vm_operand(1) && space.socio === vm_operand(2)) || (space.country === vm_operand(1) && space.socio === vm_operand(3))) {
- game.valid_spaces.push(space.space_id);
- }
- }
- vm_next()
-}
-
-function vm_valid_spaces_region_socio() {
- let valid_spaces = []
- for (let space of spaces) {
- if (!space) continue
- if (space.space_id === game.systematization) continue
- if (space.region === vm_operand(1) && space.socio === vm_operand(2)) {
- valid_spaces.push(space.space_id);
- }
- }
- game.valid_spaces = valid_spaces
- vm_next()
-}
-
-function vm_valid_spaces_region_opp() {
- let valid_spaces = []
- for (let space of spaces) {
- if (!space) continue
- let s = space.space_id
- if ((game.active === DEM && space.region === vm_operand(1) && game.comInfl[s] > 0 ) || (game.active === COM && space.region === vm_operand(1) && game.demInfl[s] > 0 )) {
- valid_spaces.push(space.space_id);
- }
- }
- game.valid_spaces = valid_spaces
- vm_next()
-}
-
-function vm_valid_spaces_solidarity_legalised() {
- let valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- let uncontrolled = (!check_control(i) && !check_opp_control(i))
- if ((space.country === 'Poland' && uncontrolled && space.socio === 3) || (space.country === 'Poland' && uncontrolled && space.socio === 4)) {
- valid_spaces.push(space.space_id);
- }
- }
- game.valid_spaces = valid_spaces
- vm_next()
-}
-
-function vm_active_country () {
- game.valid_spaces = game.valid_spaces.filter(space_id => {
- let space = spaces.find(s => s && s.space_id === space_id);
- return space && space.country === game.vm_active_country;
- });
- vm_next()
-}
-
-function vm_take_control_prep() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_take_control'
- console.log('in vm_take_control_prep game.state', game.state)
-}
-
-function vm_take_control(space) {
- let clicked_space = find_space_index(space)
- if (game.active === DEM) {
- let current_infl = game.demInfl[clicked_space]
- let opponent_infl = game.comInfl[clicked_space]
- let stability = spaces[clicked_space].stability
-
- if ((current_infl - opponent_infl) < stability) {
- game.demInfl[clicked_space] += stability - current_infl + opponent_infl
- //game.pieces[clicked_space].demCtrl = 1
- //game.pieces[clicked_space].comCtrl = 0
- }
- } else if (game.active === COM) {
- let current_infl = game.comInfl[clicked_space]
- let opponent_infl = game.demInfl[clicked_space]
- let stability = spaces[clicked_space].stability
-
- if ((current_infl - opponent_infl) < stability) {
- game.comInfl[clicked_space] += stability - current_infl + opponent_infl
- //game.pieces[clicked_space].comCtrl = 1
- //game.pieces[clicked_space].demCtrl = 0
- }
- }
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
- log(`Took control of %${clicked_space}`)
-}
-
-
-function vm_do_add_infl(space) {
- push_undo()
- console.log('in vm_do_add_infl, space', space, 'ops', game.vm_available_ops, 'ahbr tracker', game.austria_hungary_border_reopened_tracker, 'ahbr in events', game.persistent_events.includes(58))
- const clicked_space = find_space_index(space)
-
- //log(`Added 1 influence in %${clicked_space}.`)
-
- log_summary(`Added £ SP in %${clicked_space}.`)
-
- //If AHBR - check AHBR condition
- if (game.persistent_events.includes(58)) {
- if (spaces[clicked_space].country !== 'East_Germany'){
- game.austria_hungary_border_reopened_tracker = false
- }
- }
-
- // Check Genscher
- if (game.persistent_events.includes(63) && game.active === DEM && spaces[clicked_space].country === 'East_Germany') {
- game.vm_available_ops--
- log_summary(`(-1 op due to C63)`)
- } else if (check_opp_control(clicked_space)) {
- game.vm_available_ops -= 2
- //Check if Austria Hungary Border Reopened was used to place last SP in a controlled space in East Germany. If so, game.vm_available_op will be negative
- if (game.vm_available_ops < 0) {
- log_summary(`(Used +1 op from C58)`)
- }
- } else {
- game.vm_available_ops--
- }
-
- // Update influence values
- if (game.active === COM) {
- game.comInfl[clicked_space]++
- } else {
- game.demInfl[clicked_space]++
- }
-
- // Check whether spaces are controlled
- check_control_change(clicked_space)
-
- console.log('before check, ahbr in events', game.persistent_events.includes(58), 'tracker', game.austria_hungary_border_reopened_tracker)
- // Check Austria Hungary Border Reopened is true and condition has been met
- if (game.vm_available_ops === 0 && game.active === DEM && game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker) {
- console.log('in award extra op')
- game.vm_available_ops ++
- log('+1 Op from C58')
- game.austria_hungary_border_reopened_tracker = false
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
- }
-
- // If only 1 IP remaining, may not place in opponent controlled spaces
-
- // Check for Genscher & Austria Hungary Border Reopened
-
- if (game.vm_available_ops === 1) {
-
- if (game.active === DEM) {
- //Check Genscher and AHBR
- if (game.persistent_events.includes(63) || (game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker)) {
- console.log('in gensher subcheck - remove non-East German controlled ')
- game.valid_spaces = game.valid_spaces.filter(n => !(check_com_control(n) && spaces[n].country !== 'East_Germany'))
- } else {
- console.log('remove all controlled spaces')
- game.valid_spaces = game.valid_spaces.filter(n => !check_com_control(n))
- }
- } else {
- game.valid_spaces = game.valid_spaces.filter(n => !check_dem_control(n))
- }
- }
-
- //Clear valid spaces if no IP remaining.
- if (game.vm_available_ops <= 0 ) {
- game.valid_spaces = []
- }
-}
-
-function vm_do_add_infl_free(space) {
- push_undo()
- const clicked_space = find_space_index(space)
- //log(`Added 1 influence in %${clicked_space}.`)
-
- log_summary(`Added £ SP in %${clicked_space}.`)
-
- // Update influence values
- if (game.active === COM) {
- game.comInfl[clicked_space]++
- } else {
- game.demInfl[clicked_space]++
- }
- game.vm_available_ops--
- // Check whether spaces are controlled
- check_control_change(clicked_space)
-
-
- //console.log('game pieces:', game.pieces[clicked_space])
-}
-
-function vm_add_infl() {
- if (vm_operand(1)) {game.vm_available_ops = vm_operand(1)}
- game.state = 'vm_add_infl'
-}
-
-function vm_add_infl_free() {
- if (vm_operand(1)) {game.vm_available_ops = vm_operand(1)}
- game.state = 'vm_add_infl_free'
-}
-
-function vm_add_x_infl() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_add_x_infl'
-}
-
-function vm_do_add_x_infl(space) {
- push_undo()
- const clicked_space = find_space_index(space)
- log(`Added ${game.vm_available_ops} SPs in %${clicked_space}.`)
-
-
- if (game.active === COM) {
- game.comInfl[clicked_space] += game.vm_available_ops
- } else {
- game.demInfl[clicked_space] += game.vm_available_ops
- }
- check_control_change(clicked_space)
- game.vm_available_ops = 0
- game.valid_spaces = []
-}
-
-function vm_add_limited_infl() {
- game.vm_available_ops = vm_operand(1)
- game.vm_max_infl = vm_operand(2)
- game.state = 'vm_add_limited_infl'
-}
-
-function vm_do_add_limited_infl(space, max_infl) {
- push_undo()
- const clicked_space = find_space_index(space)
- //log(`Added 1 influence in %${clicked_space}.`)
-
- log_summary(`Added £ SP in %${clicked_space}.`)
- game.vm_available_ops --
-
- if (!game.vm_influence_added) {
- game.vm_influence_added = {};
- }
-
- if (!game.vm_influence_added[clicked_space]) {
- game.vm_influence_added[clicked_space] = 0;
- }
-
- if (game.active === COM) {
- game.comInfl[clicked_space] ++
- } else {
- game.demInfl[clicked_space] ++
- }
-
- game.vm_influence_added[clicked_space] ++
-
- //console.log('valid_spaces before update', game.valid_spaces)
- //console.log('influence added:', game.vm_influence_added[clicked_space], 'max infl', max_infl)
- if (game.vm_influence_added[clicked_space] === max_infl) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- check_control_change(clicked_space)
- if (game.vm_available_ops === 0) {game.valid_spaces = [] }
-}
-
-function vm_remove_infl() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_remove_infl'
-}
-
-function vm_remove_opp_infl() {
- game.vm_available_ops = vm_operand(1)
- game.remove_opponent_infl = true
- game.state = 'vm_remove_infl'
-}
-
-function vm_remove_x_opp_infl() {
- game.vm_available_ops = vm_operand(1)
- game.remove_opponent_infl = true
- game.state = 'vm_remove_x_infl'
-}
-
-function vm_do_remove_infl(space) {
- push_undo()
- const clicked_space = find_space_index(space)
- //log(`Removed 1 influence from %${clicked_space}.`)
- log_summary(`Removed £ SP from %${clicked_space}.`)
-
- if (!game.vm_influence_added) {
- game.vm_influence_added = {};
- }
-
- if (!game.vm_influence_added[clicked_space]) {
- game.vm_influence_added[clicked_space] = 0;
- }
- if (game.remove_opponent_infl === true) {
- if (game.active === COM) {
- game.demInfl[clicked_space]--
- if (game.demInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- } else {
- game.comInfl[clicked_space]--
- if (game.comInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- }
-
-
- } else {
- if (game.active === COM) {
- game.comInfl[clicked_space]--
- if (game.comInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- } else {
- game.demInfl[clicked_space]--
- if (game.demInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
- }
- }
- check_control_change(clicked_space)
- game.vm_influence_added[clicked_space]++
- game.vm_available_ops--
- if (game.vm_available_ops===0) {game.valid_spaces = []}
-}
-
-function vm_do_remove_x_infl(space) {
- push_undo()
- const clicked_space = find_space_index(space)
-
- if (game.remove_opponent_infl) {
- if (game.active === COM) {
- if (game.demInfl[clicked_space] >= game.vm_available_ops) {
- game.demInfl[clicked_space] -= game.vm_available_ops
- } else {
- game.vm_available_ops = game.demInfl[clicked_space]
- game.demInfl[clicked_space] -= game.vm_available_ops
- }
- } else {
- if (game.comInfl[clicked_space] >= game.vm_available_ops) {
- game.comInfl[clicked_space] -= game.vm_available_ops
- } else {
- game.vm_available_ops = game.comInfl[clicked_space]
- game.comInfl[clicked_space] -= game.vm_available_ops
- }
- }
- } else {
- if (game.active === COM) {
- if (game.comInfl[clicked_space] >= game.vm_available_ops) {
- game.comInfl[clicked_space] -= game.vm_available_ops
- } else {
- game.vm_available_ops = game.comInfl[clicked_space]
- game.comInfl[clicked_space] -= game.vm_available_ops
- }
- } else {
- if (game.demInfl[clicked_space] >= game.vm_available_ops) {
- game.demInfl[clicked_space] -= game.vm_available_ops
- } else {
- game.vm_available_ops = game.demInfl[clicked_space]
- game.demInfl[clicked_space] -= game.vm_available_ops
- }
- }
- }
-
- log(`Removed ${game.vm_available_ops} SPs from %${clicked_space}`)
- check_control_change(clicked_space)
-
- game.vm_available_ops = 0
- game.valid_spaces = []
-}
-
-function vm_remove_limited_opp_infl() {
- game.vm_available_ops = vm_operand(1)
- game.vm_max_infl = vm_operand(2)
- game.remove_opponent_infl = true
- game.state = 'vm_remove_limited_infl'
-}
-
-function vm_do_remove_limited_infl(space, max_infl) {
- push_undo()
- const clicked_space = find_space_index(space)
- log(`Removed SP from %${clicked_space}.`)
- game.vm_available_ops --
-
-
- if (!game.vm_influence_added) {
- game.vm_influence_added = {};
- }
-
- if (!game.vm_influence_added[clicked_space]) {
- game.vm_influence_added[clicked_space] = 0;
- }
-
- if (game.active === COM) {
- game.demInfl[clicked_space] --
- if (game.demInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
- }
- } else {
- game.comInfl[clicked_space] --
- if (game.comInfl[clicked_space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
- }
- }
-
- game.vm_influence_added[clicked_space] ++
-
- if (game.vm_influence_added[clicked_space] === max_infl) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
- }
-
- check_control_change(clicked_space)
- if (game.vm_available_ops === 0) {game.valid_spaces = []}
-}
-
-function vm_remove_all_infl() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_remove_all_infl'
-}
-
-function vm_do_remove_all_infl(space) {
- push_undo()
- const clicked_space = find_space_index(space)
- log(`Removed all SP from %${clicked_space}.`)
-
- if (game.remove_opponent_infl === true) {
- if (game.active === COM) {
- game.demInfl[clicked_space] = 0
- } else {
- game.comInfl[clicked_space] = 0
- }
- check_control_change(clicked_space)
-
- } else {
- if (game.active === COM) {
- game.comInfl[clicked_space] = 0
- } else {
- game.demInfl[clicked_space] = 0
- }
- check_control_change(clicked_space)
- }
- game.vm_available_ops --
- game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
-}
-
-function vm_replace_all_infl(space_id) {
- if (game.active === DEM) {
- game.demInfl[space_id] += game.comInfl[space_id]
- game.comInfl[space_id] = 0
- } else {
- game.comInfl[space_id] += game.demInfl[space_id]
- game.demInfl[space_id] = 0
- }
- check_control_change(space_id)
-}
-
-function vm_1_support_check() {
- game.vm_available_ops = 1
- game.state = 'vm_1_support_check_prep'
-}
-
-function vm_support_check() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_support_check_prep'
-}
-
-function vm_support_check_modified() {
- game.vm_available_ops = vm_operand(1)
- game.support_check_modifier = vm_operand(2)
- game.state = 'vm_support_check_prep'
-}
-
-function vm_switch_infl(space){
- push_undo()
- let clicked_space = find_space_index(space)
- game.demInfl[clicked_space] -= game.vm_available_ops
- game.comInfl[clicked_space] += game.vm_available_ops
- log(`Replaced ${pluralize(game.vm_available_ops,'SP')} in ${spaces[clicked_space].name_unique}`)
- game.vm_available_ops = 0
- check_control_change(clicked_space)
-}
-
-/* ===================== EVENT SPECIFIC FUNCTIONS ========== */
-
-function vm_40th_anniversary_celebration() {
- if (game.vp < 0 ) {game.vm_available_ops = 4}
- else {game.vm_available_ops = 2}
- vm_next()
-}
-
-function vm_40th_anniversary_celebration_vp() {
- game.vp --
- log('-1VP')
- if (check_vp()) {
- return
- }
- vm_next()
-}
-
-function vm_adamec() {
- game.state = 'vm_adamec'
-}
-
-function vm_army_backs_revolution() {
- game.persistent_events = game.persistent_events.filter(n => n !== 70)
- game.playable_cards = game.playable_cards.filter(n => n !== 70)
- /*if (game.table_cards.includes(70)) {
- permanently_remove(70)
- }*/
- vm_next()
-}
-
-function vm_austria_hungary_border_reopened() {
- game.persistent_events.push(58)
- permanently_remove(58)
- game.austria_hungary_border_reopened_tracker = false
- //game.table_cards.push(58)
- //remove_from_discard(58)
- vm_next()
-}
-
-function vm_betrayal() {
- if (game.demInfl[58] > 0 ) { game.valid_spaces.push(58) }
- if (game.demInfl[65] >0 ) { game.valid_spaces.push(65) }
- game.vm_available_ops = Math.max(game.demInfl[58], game.demInfl[65])
- game.state = 'vm_switch_infl'
-}
-
-function vm_breakaway_baltic_republics() {
- log('+5 VP')
- game.vp += 5
- game.stability++
- if (check_vp()) {
- return
- }
- game.playable_cards.push(109)
- game.playable_cards = game.playable_cards.filter(n => n !== 14)
- if (!check_dem_control(56) && game.systematization !== 56) {game.valid_spaces.push(56)}
- if (!check_dem_control(70)) {game.valid_spaces.push(70)}
- vm_next()
-}
-
-function vm_brought_in_for_questioning() {
- if (game.active === COM) {
- game.active = DEM
- }
- //game.return = game.active
- console.log('in bifg, game.return', game.return)
- game.phase = 0
- game.state = 'vm_brought_in_for_questioning'
-}
-
-function vm_bulgarian_turks_expelled(){
- game.remove_opponent_infl = true
- game.vp -= 2
- log('-2VP')
- if (check_vp()) {
- return
- }
- if (game.demInfl[70] > 0) {game.valid_spaces = [70]}
- vm_next()
-}
-
-function vm_ceausescu() {
- let adj_cluj = false
- if (game.demInfl[50] > 0 ) {adj_cluj = true}
- if (game.demInfl[54] > 0 ) {adj_cluj = true}
- if (game.demInfl[58] > 0 ) {adj_cluj = true}
- if (game.demInfl[61] > 0 ) {adj_cluj = true}
-
- if (adj_cluj && game.comInfl[61]>0) {
- game.valid_spaces = [61]
- game.vm_available_ops = 1
- //next_player()
- game.remove_opponent_infl = false
- game.state = 'vm_remove_infl'
- }
- else {vm_next()}
-}
-
-function vm_central_committee_reshuffle() {
- game.state = 'vm_central_committee_reshuffle'
-}
-
-function vm_civic_forum() {
- log('+1 VP')
- game.vp++
- if (check_vp()) {
- return
- }
- game.persistent_events.push(90)
- if (check_dem_control(31)) {
- vm_next()
- } else {
- permanently_remove(90)
- vm_return()
- }
-}
-
-function vm_common_european_home() {
- let valid_cards = [];
- for (let c of cards) {
- //if (c === null) {continue}
- if (game.active === DEM) {
- if (c && c.side === 'C') {
- valid_cards.push(c.number)
- }
- } else {
- if (c && c.side === 'D') {
- valid_cards.push(c.number)
- }
- }
- }
- game.valid_cards = valid_cards
- game.state = 'vm_common_european_home_choose'
-}
-
-function vm_dash_for_the_west() {
- game.valid_cards = []
- for (let c of game.strategy_discard) {
- if (cards[c].side === 'D' && cards[c].remove === 1 && (cards[c].playable || game.playable_cards.includes(c))) {
- game.valid_cards.push(c)
- }
- }
- game.state = 'vm_dash_for_the_west'
-}
-
-function vm_deutsche_marks() {
- let max_value = 1;
- for (let c of game.democrat_hand) {
- if (cards[c].ops > max_value) {
- max_value = cards[c].ops
- }
- }
- let valid_cards = [];
- for (let c of game.democrat_hand) {
- if (cards[c].ops === max_value) {
- valid_cards.push(c);
- }
- }
- game.valid_cards = valid_cards
- game.state = 'vm_deutsche_marks_prep'
-}
-
-function vm_domino_theory() {
- game.discard = true
- for (let card of game.strategy_discard) {
- if (scoring_cards.includes(card)) {game.valid_cards.push(card) }
- }
- game.phase = 0
- game.state = 'vm_play_event_from_discard'
-}
-
-function vm_eco_glasnost() {
- game.persistent_events.push(39)
- permanently_remove(39)
- vm_next()
-}
-
-function vm_elena(){
- game.persistent_events.push(101)
- permanently_remove(101)
- //game.table_cards.push(101)
- //remove_from_discard(101)
- vm_next()
-}
-
-function vm_eliminate(space_id) {
- log(`Eliminated %${space_id}`)
- const adjacent_spaces = spaces[space_id].adjacent.filter(Number.isInteger);
-
- //console.log('adjacency before: Iasi', game.pieces[53].adjacent, 'Ploesti:', game.pieces[59].adjacent, 'Bucharesti:', game.pieces[61].adjacent)
-
- // Remove clicked_space from the adjacency lists of its adjacent spaces
- /* adjacent_spaces.forEach(s => {
- game.pieces[s].adjacent = spaces[s].adjacent.filter(id => id !== space_id);
- });
-
- //console.log('adjacency after: Iasi', game.pieces[53].adjacent, 'Ploesti:', game.pieces[59].adjacent, 'Bucharesti:', game.pieces[61].adjacent)
-
- // Connect adjacent spaces to each other
- // No longer used - spaces done dynamically
-/*
- for (let i = 0; i < adjacent_spaces.length; i++) {
- for (let j = i + 1; j < adjacent_spaces.length; j++) {
- console.log(' checking i,', spaces[adjacent_spaces[i]].name, 'j', spaces[adjacent_spaces[j]].name)
- if (!game.pieces[adjacent_spaces[i]].adjacent.includes(adjacent_spaces[j])) {
- game.pieces[adjacent_spaces[i]].adjacent.push(adjacent_spaces[j]);
- }
- if (!game.pieces[adjacent_spaces[j]].adjacent.includes(adjacent_spaces[i])) {
- game.pieces[adjacent_spaces[j]].adjacent.push(adjacent_spaces[i]);
- }
- }
- }
-
- console.log('adjacency after addition: Iasi', game.pieces[53].adjacent, 'Ploesti:', game.pieces[59].adjacent, 'Bucharesti:', game.pieces[61].adjacent)
- // Clear the adjacency list of the clicked space
- game.pieces[space_id].adjacent = [];
-*/
- // Eliminate the democrat influence and move the communist influence to Bucuresti
- game.demInfl[space_id] = 0
- game.comInfl[61] += game.comInfl[space_id]
- if (game.comInfl[space_id] > 0 ) {
- log(`${game.comInfl[space_id]} Communist SP relocated to Bucuresti`)
- }
- game.comInfl[space_id] = 0
-
- //Update control in the eliminated space and in Bucuresti
- check_control_change(space_id)
- check_control_change(61)
-
-}
-
-function get_adjusted_adjacency(space_id) {
- let adjacent_spaces = spaces[space_id].adjacent;
- if (adjacent_spaces.includes(game.systematization)) {
- //console.log('in get adjusted adjacency, systemization',game.systematization)
- //console.log('adjacent_spaces', adjacent_spaces)
- }
- if (game.systematization !== 0) {
- //console.log('in systematization check')
- let eliminated_space_id = game.systematization;
-
- return adjacent_spaces.map(adj_space_id => {
- if (adj_space_id === eliminated_space_id) {
- // Replace the eliminated space with its adjacencies
- //console.log('in map check, return', spaces[eliminated_space_id].adjacent)
- return spaces[eliminated_space_id].adjacent;
- }
- //console.log('2nd check, return', adj_space_id)
- return adj_space_id;
- }).flat(); // Flatten in case the eliminated space has multiple adjacencies
- }
- //console.log('final adjacent spaces', adjacent_spaces)
- return adjacent_spaces;
-}
-
-function vm_exit_visas() {
- game.state = 'vm_exit_visas'
-}
-
-function vm_foreign_currency_debt_burden() {
- log('+1VP')
- game.vp++
- if (check_vp()) {
- return
- }
- //game.table_cards.push(49)
- //remove_from_discard(49)
- game.persistent_events.push(49)
- game.state = 'vm_foreign_currency_debt_burden'
-}
-
-function vm_foreign_television() {
- for (let i = 1 ; i < spaces.length; i++) {
- if (i === 12) {continue} /*Does not apply to Dresden*/
- if (game.comInfl[i] > 0 ) {
- game.valid_spaces.push(i)
- }
- }
- vm_next()
-}
-function vm_frg_embassies() {
- game.persistent_events.push(74)
- game.table_cards.push(74)
- remove_from_discard(74)
- log('C74 in effect')
- vm_next()
-}
-
-function vm_general_strike() {
- game.persistent_events.push(5)
- game.table_cards.push(5)
- remove_from_discard(5)
- log('C5 in effect')
- vm_next()
-}
-
-function vm_genscher() {
- game.persistent_events.push(63)
- game.table_cards.push(63)
- remove_from_discard(63)
- log(`C63 in effect`)
- vm_next()
-}
-
-function vm_goodbye_lenin() {
- game.view_opp_hand = true
- game.communist_hand_red = []
- // Select Red cards to show
- for (let card of game.communist_hand) {
- console.log('checking card ', card, 'red', cards[card].red)
- if (cards[card].red) {
- game.communist_hand_red.push(card)
- }
- }
- //Check if these cards are playabl
- for (let card of game.communist_hand_red) {
- if (cards[card].playable || game.playable_cards.includes(card)) {
- game.valid_cards.push(card)
- }
- }
- game.state = 'vm_goodbye_lenin'
-}
-
-function vm_government_resigns() {
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (space.socio === 1 && game.comInfl[i] > 0 && !check_control(i)) {
- game.valid_spaces.push(i)
- }
- }
- game.remove_opponent_infl = true
- vm_next()
-}
-
-function vm_grenztruppen() {
- console.log('in grenztruppen - player active:', game.active)
- game.persistent_events.push(59)
- permanently_remove(59)
- //game.table_cards.push(59)
- //remove_from_discard(59)
- vm_next()
-}
-
-function vm_heal_our_bleeding_wounds() {
- let change_vp = 0
- if (game.turn <= 3) {change_vp = -3 }
- else if (game.turn <= 7) {change_vp = -1}
- else change_vp = 3
- if (change_vp >0) {
- log(`+${change_vp} VP`)
- } else {
- log(`-${change_vp} VP`)
- }
- game.vp += change_vp
- if (check_vp()) {
- return
- }
- vm_next()
-}
-
-function vm_helsinki_final_act() {
- game.persistent_events.push(26)
- vm_next()
-}
-
-function vm_honecker() {
- game.persistent_events.push(15)
- game.valid_cards = []
- for (let c of game.strategy_discard) {
- if (scoring_cards.includes(c)) {
- continue}
- else {
- game.valid_cards.push(c)
- }
- }
- game.discard = true
- game.state = 'vm_honecker'
-}
-
-function vm_inflationary_currency() {
- game.state = 'vm_inflationary_currency'
-}
-
-function vm_inflationary_currency_discard() {
- // This function starts with the player who is playing Inflationary Currency for the Event
- // Switch player and check the hand of their opponent to see if the have cards with ops > 3 to discard
- next_player()
- if (game.active === COM) {
- for (let card of game.communist_hand){
- if (get_card_ops(card) >= 3) {
- game.valid_cards.push(card)
- }
- }
- } else {
- for (let card of game.democrat_hand){
- if (get_cards_ops(card) >= 3) {
- game.valid_cards.push(card)
- }
- }
- }
- game.state = 'vm_inflationary_currency_discard'
-}
-
-function vm_kiss_of_death() {
- game.state = 'vm_kiss_of_death'
-}
-
-function vm_klaus_and_komarek() {
- if (game.comInfl[29] > 0 ) {game.valid_spaces = [29]}
- vm_next()
-}
-
-function vm_kohl_proposes_reunification() {
- log('+2 VP')
- game.vp += 2
- if (check_vp()) {
- return
- }
- if (game.persistent_events.includes(86)) {
- game.vm_event = 87
- game.state = 'vm_common_european_home_play'
- } else {
- permanently_remove(87)
- vm_return()
- }
-
-}
-
-function vm_kremlin_coup() {
- log('-3 VP')
- game.vp -= 3
- if (check_vp()) {
- return
- }
- game.support_check_modifier = 1
- //countries = ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania']
- //revolutions: {'East_Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false}
- game.temp = []
- countries.forEach(country => {
- if (!game.revolutions[find_country_index(country)]) {
- game.temp.push(country)
- }
- })
- console.log('game.temp', game.temp)
- game.state = 'vm_kremlin_coup_choose_country'
-}
-
-function vm_laszlo_tokes() {
- game.persistent_events.push(73)
- game.playable_cards.push(107)
- game.state = 'vm_laszlo_tokes'
-}
-
-function vm_legacy_of_martial_law() {
- game.vm_available_ops = 1
- game.state = 'vm_switch_infl'
-}
-
-function vm_legacy_of_1968() {
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if ((!check_com_control(i) && space.country === 'Czechoslovakia')) {
- game.valid_spaces.push(space.space_id);
- }
- }
- vm_next()
-}
-
-function vm_li_peng() {
- game.persistent_events.push(53)
- //game.table_cards.push(53)
- remove_from_discard(53)
- vm_next()
-}
-
-function vm_ligachev() {
- game.persistent_events.push(99)
- vm_next()
-}
-
-function vm_malta_summit() {
- game.state = 'vm_malta_summit'
-}
-
-function vm_massacre_in_timisoara() {
- game.persistent_events = game.persistent_events.filter(n => n !== 73)
- vm_next()
-}
-
-function vm_modrow() {
- game.playable_cards.push(15)
- game.state = 'vm_modrow'
-}
-
-function vm_nagy_reburied(){
- if (game.comInfl[43] > 0) {
- game.valid_spaces.push(43)
- }
- vm_next()
-}
-
-function vm_national_salvation_front() {
- game.persistent_events.push(102)
- game.table_cards.push(102)
- remove_from_discard(102)
- vm_next()
-}
-
-function vm_nepotism() {
- game.state = 'vm_nepotism'
-}
-
-function vm_new_years_eve_party() {
- game.state = 'vm_new_years_eve_party'
-}
-
-function vm_nomenklatura() {
- game.state = 'vm_nomenklatura'
-}
-
-function vm_normalisation() {
- if (game.demInfl[27] >0) {game.valid_spaces.push(27)}
- if (game.demInfl[29] > 0) {game.valid_spaces.push(29)}
- game.remove_opponent_infl = true
- vm_next()
-}
-
-function vm_peasant_parties_revolt() {
- game.persistent_events.push(72)
- log_msg_gap('C72 in effect')
- game.table_cards.push(72)
- remove_from_discard(72)
- vm_next()
-}
-
-function vm_perestroika() {
- game.persistent_events.push(25)
- log_msg_gap('C25 in effect')
- permanently_remove(25)
- vm_next()
-}
-
-function vm_poszgay() {
- let valid_spaces = []
- for (let space of spaces) {
- if (space && space.country === 'Hungary' && !check_dem_control(space.space_id)) {
- valid_spaces.push(space.space_id);
- }
- }
- game.valid_spaces = valid_spaces
- vm_next()
-}
-
-function vm_power_struggle() {
- console.log('in vm_power_struggle. game.vm_event', game.vm_event, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- game.is_pwr_struggle = true
-
- /* TO DELETE?
- //Check if Power Struggle is because of an event
- */
-
- if (game.vm_event > 0) {
- console.log('vm_power_struggle, in game.vm_event check')
- game.pwr_struggle_in = countries[scoring_cards.indexOf(game.vm_event)]
- log_h2(`C${game.vm_event}`)
- }
-/*
- //Otherwise set Power Struggle country normally
- else {
- console.log('vm_power_struggle, country set normally')
- game.pwr_struggle_in = countries[scoring_cards.indexOf(game.played_card)]
- log_h2(`C${game.played_card}`)
- }*/
-
-
- //Check for Securitate
- if (game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(70)) {
- console.log('in Securitate subcheck')
- log('C70: Democrat reveals Power Struggle cards')
- game.view_opp_hand = true
- }
- log_h2('Deal Cards')
- game.state = 'draw_power_cards'
- console.log('game.state',game.state)
-}
-
-function vm_presidential_visit() {
- game.persistent_events.push(65)
- //game.table_cards.push(65)
- //remove_from_discard(65)
- log_msg_gap('C65 in effect')
- vm_next()
-}
-
-function vm_prudence() {
- if (!game.prudence) {
- game.prudence = {DEM: 0, COM: 0}
- }
- if (game.active === DEM) {
- game.prudence.COM --
- log(`${game.prudence.COM} to Communist ops this turn`)
- } else {
- game.prudence.DEM --
- log(`${game.prudence.DEM} to Democrat ops this turn`)}
- vm_next()
-}
-
-function vm_public_against_violence() {
- game.valid_spaces = []
- if (game.comInfl[34] > 0 ) {game.valid_spaces.push(34)}
- vm_next()
-}
-
-function vm_reformer_rehabilitated () {
- permanently_remove(67)
- game.discard = true
- for (let card of game.strategy_discard) {
- if (card === game.played_card) continue
- if (game.table_cards.includes(card)) continue
- if (scoring_cards.includes(card)) continue
-
- game.valid_cards.push(card)
- }
- game.state = 'vm_play_event_from_discard'
-}
-
-function vm_roundtable_talks() {
- game.persistent_events.push(17)
- game.table_cards.push(17)
- remove_from_discard(17)
- log_msg_gap('C17 in effect')
- vm_next()
-}
-
-function vm_sajudis_check() {
- if (!check_dem_control(56)) {
- game.valid_spaces.push(56)
- }
- if (!check_dem_control(70)) {
- game.valid_spaces.push(70)
- }
- vm_next()
-}
-
-function vm_sajudis() {
- game.playable_cards.push(81)
- game.stability++
- log('+1 VP')
- game.vp++
- if (check_vp()) {
- return
- }
- vm_next()
-}
-
-function vm_samizdat() {
- game.state = 'vm_samizdat'
-}
-
-function vm_securitate() {
- game.persistent_events.push(70)
- permanently_remove(70)
- //game.table_cards.push(70)
- vm_next()
-}
-
-function vm_shock_therapy() {
- game.state = 'vm_shock_therapy'
-}
-
-function vm_social_democratic_platform_adopted() {
- game.state = 'vm_social_democratic_platform_adopted'
-}
-
-function vm_solidarity_legalised() {
- log_msg_gap(`C2 in effect`)
- game.playable_cards.push(3)
- game.persistent_events.push(2)
- console.log('game.persistent_events', game.persistent_events)
- vm_next()
-}
-
-function vm_st_nicholas_church () {
- game.persistent_events.push(24)
- game.playable_cards.push(61)
- permanently_remove(24)
- vm_next()
-}
-
-function vm_stasi() {
- log_msg_gap('C13 in effect')
- game.persistent_events.push(13)
- vm_next()
-}
-
-function vm_stand_fast() {
- game.persistent_events.push(100)
- if (game.active === DEM) {
- game.stand_fast = DEM
- } else {game.stand_fast = COM}
- //game.table_cards.push(100)
- vm_next()
-}
-
-function vm_systematization() {
- game.state = 'vm_systematization'
-}
-
-function vm_tank_column() {
- if (game.active === DEM) {
- game.dem_tst_position++
- game.dem_tst_attempted = 0
- } else {
- game.com_tst_position++
- game.com_tst_attempted = 0
- }
- vm_next()
-}
-
-function vm_tear_gas () {
- game.persistent_events.push(30)
- game.table_cards.push(30)
- remove_from_discard(30)
- log_msg_gap('C30 in effect')
- vm_next()
-}
-
-function vm_the_baltic_way() {
- game.playable_cards.push(84)
- game.stability++
- if (!check_dem_control(56) && game.systematization !== 56) {game.valid_spaces.push(56)}
- if (!check_dem_control(70) && game.systematization !== 70) {game.valid_spaces.push(70)}
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- console.log('game.state', game.state)
- vm_next()
-}
-
-function vm_the_chinese_solution() {
- game.state = 'vm_the_chinese_solution'
-}
-
-function vm_the_crowd_turns_against_ceausescu() {
- game.table_cards.push(54)
- remove_from_discard(54)
- game.playable_cards.push(97)
- vm_next()
-}
-
-function vm_the_monday_demonstrations() {
- if (!check_dem_control(6)) {game.valid_spaces.push(6)}
- if (!check_dem_control(9)) {game.valid_spaces.push(9)}
- vm_next()
-}
-
-function vm_the_sinatra_doctrine() {
- game.persistent_events.push(50)
- log_msg_gap('C50 in effect')
- vm_next()
-}
-
-function vm_the_third_way() {
- log('-2VP')
- vm_next()
-}
-
-function vm_the_tyrant_is_gone() {
- game.valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (game.demInfl[i] === 0 && space.country === 'Romania') {
- if (space.space_id === game.systematization) {continue}
- game.valid_spaces.push(space.space_id)
- }
- }
- /*game.playable_cards[10].playable = 0
- game.playable_cards[41].playable = 0
- game.playable_cards[101].playable = 0
- game.playable_cards[107].playable = 0*/
- console.log('game.vm_event', game.vm_event, 'game.played_card', game.played_card)
- game.state = 'vm_the_tyrant_is_gone'
-}
-
-
-function vm_the_tyrant_is_gone_prep() {
- game.table_cards.push(97)
- remove_from_discard(97)
- vm_next()
-}
-
-function vm_the_wall () {
- game.persistent_events.push(9)
- //game.strategy_removed.push(9)
- //game.table_cards.push(9)
- log_msg_gap('C9 in effect')
- vm_next()
-}
-
-function vm_the_wall_must_go() {
- game.the_wall_must_go = {}
- game.the_wall_must_go['dem_wins'] = 0
- game.the_wall_must_go['com_wins'] = 0
- game.the_wall_must_go['dem_roll'] = 0
- game.the_wall_must_go['com_roll'] = 0
- game.state = 'vm_the_wall_must_go'
-}
-
-function vm_warsaw_pact_summit() {
- game.warsaw_pact_summit = true /*What does this do? */
- game.state = 'vm_warsaw_pact_summit'
-}
-
-function vm_we_are_the_people() {
- if (game.demInfl[6] > 0) {game.valid_spaces = [6]}
- game.persistent_events.push(48)
- if (!game.vm_influence_added) {
- game.vm_influence_added = {};
- }
- game.vm_influence_added[6] = 0
- game.vm_available_ops = 4
- game.state = 'vm_we_are_the_people_remove'
-}
-
-function vm_workers_revolt() {
- if (game.active === DEM) {
- for (let space of spaces) {
- if (!space) continue
- let country = space.country
- if (!game.revolutions[find_country_index(country)] && game.comInfl[space.space_id] > 0 && space.socio === 4) {
- game.valid_spaces.push(space.space_id);
- }
- }
- } else {
- for (let space of spaces) {
- if (!space) continue
- let country = space.country
- if (game.revolutions[find_country_index(country)] && game.demInfl[space.space_id] > 0 && space.socio === 4) {
- game.valid_spaces.push(space.space_id);
- }
- }
- }
- game.state = 'vm_workers_revolt'
-}
-
-function vm_yakovlev_counsels_gorbachev() {
- game.persistent_events.push(62)
- log_msg_gap('C62 in effect')
- game.table_cards.push(62)
- remove_from_discard(62)
- vm_next()
-}
-
-function vm_permanently_remove () {
- // Check if the event is being played as the result of another card, e.g. Dash for the West, is a card which should be removed, and which hasn't already been removed!
- if (game.vm_event !== 0 && cards[game.vm_event].remove === 1 && !game.strategy_removed.includes(game.vm_event)) {
- permanently_remove(game.vm_event)
- }
- if (cards[game.played_card].remove ===1 && !game.strategy_removed.includes(game.played_card)) {
- permanently_remove(game.played_card)
- } /*This means the card that called the event being played is also removed if relevant. Think this makes sense */
- vm_next()
-}
-
-function discarded_card() {
- return game.temp > 0
-}
-
-// =================== TIANANMEN SQUARE TRACK FUNCTIONS ====================
-
-function vm_tst_3() {
- log_gap('Tiananmen Square Track award')
- game.state = 'vm_tst_3_prep'
-}
-
-function vm_tst_4() {
- log_gap('Tiananmen Square Track award')
- game.vm_available_ops = 2
- game.remove_opponent_infl = true
- game.state = 'vm_tst_4'
-}
-function vm_tst_6() {
- log_h3('Tiananmen Square Track award')
- game.vm_available_ops = 1
- game.temp = 1 //Set temp to 1, so that Card 1 is called during the support check, which has 2 ops
- game.state = 'vm_tst_6'
-}
-
-function vm_tst_8() {
- game.state = 'vm_goodbye_lenin_ops' // Use this to resolve ops.
-}
-
-// ==================== POWER STRUGGLE FUNCTIONS ======================
-
-function vm_scare_tactics() {
- game.vm_active_country = game.pwr_struggle_in
- vm_next()
-}
-function vm_support_surges() {
- game.state = 'vm_support_surges'
-}
-
-function vm_support_falters() {
- game.vm_available_ops = 2
- game.return === game.active
- game.state = 'vm_support_falters'
-}
-
-function vm_kremlin_coup_elite() {
- game.valid_spaces=[]
- elite_spaces.forEach(space => {
- if (spaces[space].country === game.vm_active_country && !check_com_control(space)) {
- game.valid_spaces.push(space);
- }
- })
- game.state = 'vm_kremlin_coup_take_control'
-}
-
-/* ================== VM STATES ============================== */
-
-states.vm_take_control = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt () {
- console.log('game.vm_available_ops', game.vm_available_ops)
- if (game.vm_available_ops > 0 && game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: all spaces controlled. Continue.`
- gen_action('done')
- } else if (game.vm_available_ops > 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}: take control of ${event_prompt()}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Take control: done.`
- gen_action('done')
- }
- },
- infl(space) {
- push_undo()
- vm_take_control(space)
- game.vm_available_ops--
- if (game.vm_available_ops === 0) {
- vm_next()
- }
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_add_infl = {
- inactive: 'add Support Points.',
- prompt () {
- console.log('in vm add infl')
- if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) {
- view.prompt = 'No available spaces remaining. Add SPs: done.'
- gen_action('done')
- }
- else if (game.vm_available_ops > 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique)
- }
- } else {
- view.prompt = 'Add SP: done.'
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_add_infl(space)
- },
- done () {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- game.vm_event_done = true
- vm_next()
- }
-}
-
-states.vm_add_infl_free = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}: add SPs.`
- },
- prompt () {
- if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) {
- view.prompt = 'No available spaces remaining. Add SPs: done.'
- gen_action('done')
- }
- else if (game.vm_available_ops > 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}: add ${game.vm_available_ops} SPs to ${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Add influence: done.`
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_add_infl_free(space)
- /*if (game.vm_available_ops === 0 ) {
-
- }*/
- },
- done () {
- game.valid_spaces = []
- game.vm_event_done = true
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_add_x_infl = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}: add Support Points.`
- },
-// inactive: `resolve ${cards[this_card()].name}: add influence.`,
- prompt () {
- if (game.vm_available_ops > 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}: Add ${game.vm_available_ops} SPs to ${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique)
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Add influence: done.`
- gen_action('done')
- }
- },
- infl(space) {
- push_undo()
- vm_do_add_x_infl(space)
- //game.vm_event_done = true
- //vm_next()
- },
- done () {
- game.vm_event_done = true
- vm_next()
- }
-}
-
-states.vm_add_limited_infl = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}: add Support Points.`
- },
- prompt () {
- if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) {
- if (game.vm_max_infl === 1) {
- view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_max_infl,'SP')} ${event_prompt()}.`
- }
- else {
- view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_available_ops,'SP')} to ${event_prompt()}.`
- }
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Add SPs: done.`
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_add_limited_infl(space, game.vm_max_infl)
- /*if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
- game.vm_event_done = true
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }*/
- /*if (game.vm_available_ops === 0 || game.valid_spaces.length === 0 ) {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- game.vm_event_done = true
- vm_next()
- }*/
- },
- done () {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- game.vm_event_done = true
- vm_next()
- }
-}
-
-states.vm_remove_infl = {
- inactive: 'remove Support Points.',
- prompt () {
- // Keep this so that there is an undo option in, e.g., Scare Tactics
- if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no further SPs to remove.`
- gen_action('done')
- return
- }
- if (game.vm_available_ops === 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
- gen_action('done')
- return
- }
- if (game.remove_opponent_infl) {
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops, 'opponent SP')}${event_prompt()}.`
- }
- else {
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}.`
- }
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- },
- infl(space) {
- push_undo()
- vm_do_remove_infl(space)
- const clicked_space = find_space_index(space)
- game.vm_active_country = spaces[clicked_space].country
- /*if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
- vm_next()
- }*/
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-
-states.vm_remove_x_infl = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}: remove SP from ${event_prompt()}.`
- },
- prompt () {
- if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
- gen_action('done')
- } else if (game.vm_available_ops > 0) {
-
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')} from ${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove influence: done.`
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_remove_x_infl(space)
- /*game.vm_event_done = true
- vm_next()*/
- },
- done () {
- game.vm_event_done = true
- vm_next()
- }
-}
-
-states.vm_remove_limited_infl = {
- inactive: 'remove SP.',
- prompt () {
- if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${game.vm_available_ops} SP${event_prompt()}, no more than ${game.vm_max_infl} per space.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else if (game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no further SP to remove.`
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_remove_limited_infl(space, game.vm_max_infl)
- /*if (game.vm_available_ops === 0) {
- game.vm_event_done = true
- } */
- },
- done () {
- game.vm_event_done = true
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_remove_all_infl = {
- inactive: 'remove Support Points',
- prompt () {
- if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
- gen_action('done')
- } else if (game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: remove all SPs from ${event_prompt()}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_remove_all_infl(space)
- const clicked_space = find_space_index(space)
- game.vm_active_country = spaces[clicked_space].country
- /*if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
- vm_next()
- }*/
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_support_check_prep = {
- inactive: 'do support checks.',
- prompt () {
- console.log('in states.vm_support_check_prep, game.vm_available_ops: ', game.vm_available_ops)
- if (game.vm_available_ops === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}. Support check: done.`
- gen_action('done')
- } else if (game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no valid targets for support check.`
- gen_action('done')
- } else {
- if (game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: ${event_prompt()}. ${pluralize(game.vm_available_ops, 'support check')} remaining.`
- }
- for (let space_id of game.valid_spaces) {
- if (!space_id) continue
- gen_action_sc(spaces[space_id].name_unique);
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = find_space_index(space)
-
- // Check for Austria-Hungary Border Reopened - check on first support check only
- //First check for Monday Demonstrations - support checks will always be in East Germany
- if (game.vm_event === 61 && game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- game.state = 'vm_do_support_check'
- return
- }
-
- //Then check Austria-Hungary Border Reopened normally
- //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
- if (game.persistent_events.includes(58)) {
- if (game.active === DEM && game.vm_available_ops > 1) {
- if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
- game.state = 'vm_austria_hungary_border_reopened_check'
- return
- }
- //game.state = 'do_support_check'
- } /*else { */
- }
- game.state = 'vm_do_support_check'
- },
- done () {
- game.vm_available_ops = 0
- vm_next ()
- }
-}
-
-states.vm_ceh_support_check_prep = {
- inactive: 'do support checks.',
- prompt () {
- if (game.vm_available_ops === 0) {
- view.prompt = 'Support checks: done.'
- gen_action('done')
- //return
- }
- if (game.vm_available_ops > 0) {
- view.prompt = `Select a space. ${pluralize(game.vm_available_ops, 'support check')} remaining.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_sc(spaces[space_id].name_unique)
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = find_space_index(space)
-
- //Then check Austria-Hungary Border Reopened normally
- //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
- if (game.persistent_events.includes(58)) {
- if (game.active === DEM && game.vm_available_ops > 1) {
- console.log('in ahb check, country, ', spaces[game.selected_space].country, 'ahb', game.persistent_events.includes(58))
- if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
- game.state = 'vm_austria_hungary_border_reopened_check'
- return
- }
- //game.state = 'do_support_check'
- } /*else { */
- }
- game.state = 'vm_ceh_do_support_check'
- },
- done () {
- vm_next ()
- }
-}
-
-
-states.vm_ceh_do_support_check = {
- inactive: 'do support checks.',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(spaces[game.selected_space].name_unique)
-
- game.vm_available_ops--
- if (game.vm_available_ops === 0) {
- game.valid_spaces = []
- }
- game.state = 'vm_ceh_support_check_prep'
- return
- }
-}
-
-states.vm_austria_hungary_border_reopened_check = {
- inactive: 'decide Austria-Hungary Border Reopened',
- prompt() {
- view.prompt = 'Austria-Hungary Border Reopened: will all support checks be in East Germany?'
- gen_action('yes')
- gen_action('no')
- },
- yes() {
- game.austria_hungary_border_reopened_tracker = true
- game.state = 'vm_do_support_check'
- },
- no() {
- game.state = 'vm_do_support_check'
- }
-}
-
-states.vm_1_support_check_prep = {
- inactive: 'do support checks.',
- prompt () {
- if (game.vm_available_ops === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}. Support check: done.`
- gen_action('done')
- } else if (game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no valid targets for support check.`
- gen_action('done')
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}: ${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- if (!space_id) continue
- gen_action_sc(spaces[space_id].name_unique);
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = find_space_index(space)
- game.state = 'vm_do_support_check'
- },
- done () {
- game.vm_available_ops = 0
- vm_next ()
- }
-}
-
-states.vm_do_support_check = {
- inactive: 'do support checks.',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(spaces[game.selected_space].name_unique)
- game.vm_available_ops--
- if (game.vm_available_ops === 0) {
- game.valid_spaces = []
- }
- game.state = 'vm_support_check_prep'
- return
- }
-}
-
-states.vm_tiananmen_square_attempt = {
- inactive: 'do Tiananmen Square',
- prompt () {
- if (game.active === DEM && game.dem_tst_attempted_this_turn > 0 || game.active === COM && game.com_tst_attempted_this_turn > 0) {
- view.prompt = 'Tiananmen Square Track attempt: done.'
- gen_action('done')
- return
- }
- view.prompt = 'Roll a die'
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_tst_attempt ()
- },
- done () {
- vm_next()
- }
-}
-
-//================================== EVENT SPECIFIC STATES ======================================
-
-states.vm_adamec = {
- get inactive() {
- return `resolve ${clean_name(cards[88].name)}.`
- },
- prompt() {
- view.prompt = 'Adamec: roll a die.'
- gen_action('roll')
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- let worker_spaces = spaces.filter(space => space && space.country === 'Czechoslovakia' && space.socio === 4 && check_dem_control(space.space_id)).length
- if (worker_spaces > 0) {
- log(`-${worker_spaces} from Democrat controlled worker spaces`)
- roll -= worker_spaces
- }
- log(`Modified roll: ${roll}`)
- if (roll > 2) {
- log('Adamec succeeds')
- vm_next()
- return
- }
- log('Adamec fails: 3 or more required')
- permanently_remove(88)
- vm_return()
- }
-}
-
-states.vm_brought_in_for_questioning = {
- inactive: 'discard a card.',
- prompt() {
- if (game.phase === 1) {
- view.prompt = 'Discard a card: done.'
- gen_action('done')
- } else if (game.democrat_hand.length === 0) {
- view.prompt = 'Brought in for Questioning. No cards to discard.'
- gen_action('pass')
- } else {
- view.prompt = 'Brought in for Questioning: you must discard a random card.'
- gen_action('discard')
- }
- },
- discard() {
- game.vm_event = discard_card(game.democrat_hand)
- game.phase = 1
- if (cards[game.vm_event].side === 'C' && (cards[game.vm_event].playable || game.playable_cards.includes(game.vm_event))) {
- //game.return = game.active
- if (!game.vm_infl_to_do) {
- if(game.round_player === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- }
- console.log('BIFQ discard: game.return', game.return)
- if (!auto_resolve_events.includes(game.vm_event) && !switch_events.includes(game.vm_event)) {
- next_player()
- }
- goto_vm(game.vm_event)
- } else {
- game.return = DEM
- }
- },
- pass() {
- log('No cards to discard')
- vm_return()
- },
- done() {
- vm_return()
- }
-}
-
-states.vm_central_committee_reshuffle = {
- get inactive() {
- return `resolve ${clean_name(cards[57].name)}.`
- },
- prompt() {
- view.prompt = 'Choose a country to add SP.'
- if (!game.revolutions[0]) {gen_action('poland')}
- if (!game.revolutions[1]) {gen_action('hungary')}
- if (!game.revolutions[2]) {gen_action('east_germany')}
- if (!game.revolutions[3]) {gen_action('bulgaria')}
- if (!game.revolutions[4]) {gen_action('czechoslovakia')}
- if (!game.revolutions[5]) {gen_action('romania')}
- },
- east_germany() {
- game.vm_active_country = "East_Germany"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [1,2,3,4,5,6,7,8,9,10,11,12]
- vm_next()
- },
- poland() {
- game.vm_active_country = "Poland"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [13,14,15,16,17,18,19,20,21,22,23,24,25,26]
- vm_next()
- },
- czechoslovakia() {
- game.vm_active_country = "Czechoslovakia"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [27,28,29,30,31,32,33,34,35,36,37]
- vm_next()
- },
- hungary() {
- game.vm_active_country = "Hungary"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [38,39,40,41,42,43,44,45,46,47,48,49]
- vm_next()
- },
- romania() {
- game.vm_active_country = "Romania"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [50,51,52,53,54,55,56,57,58,59,60,61,62,63]
- game.valid_spaces = game.valid_spaces.filter(space => space !== game.systematization)
- vm_next()
- },
- bulgaria () {
- game.vm_active_country = "Bulgaria"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [64,65,66,67,68,69,70,71,72,73,74,75]
- vm_next()
- },
-
-}
-
-states.vm_common_european_home_choose = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = `Common European Home: play an opponent's card, event does not occur.`
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- },
- card(card) {
- push_undo()
- log(`Played with C${cards[card].number}`)
- game.valid_cards = []
- silent_discard(card)
- game.vm_event = card
- game.state = 'vm_common_european_home_play'
- }
-}
-
-states.vm_common_european_home_play = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- view.prompt = `Play ${clean_name(cards[this_card()].name)} for:`
- gen_action('influence')
- gen_action('support_check')
- if (game.active === DEM && game.vm_event === 87 ) {
- return /*Special condition if card is actually Kohl Proposes Reunification*/
- }
- if (game.active === DEM && game.dem_tst_attempted_this_turn === 0 || game.active === COM && game.com_tst_attempted_this_turn === 0) {
- gen_action('tst')
- }
- },
- influence(){
- push_undo()
- game.vm_available_ops = cards[game.vm_event].ops
- valid_spaces_infl()
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- game.vm_available_ops = 2
- game.state = 'vm_ceh_support_check_prep'
- valid_spaces_sc()
- },
- tst() {
- game.state = 'vm_tiananmen_square_attempt'
- }
-}
-
-states.vm_dash_for_the_west = {
- get inactive() {
- return `resolve ${clean_name(cards[36].name)}.`
- },
- prompt() {
- /* if (game.phase === 1) {*/
- view.prompt = 'Dash for the West: roll a die'
- gen_action('roll')
- /*} else {
- view.prompt = 'Dash for the West: roll a die. Done.'
- gen_action('done')
- }*/
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- let com_control = check_presence('East_Germany').com_spaces
-
- if (roll > com_control) {
- log(`Success. More than the ${com_control} Communist controlled spaces in East Germany`)
- log('+1 VP')
- game.vp++
- if (check_vp()) {
- return
- }
- game.discard = true
- game.state = 'vm_play_event_from_discard'
- } else {
- log(`Fail: more than a ${com_control} required`)
- //game.phase++
- vm_next()
- }
- },/*
- done() {
- vm_next()
- }*/
-}
-
-states.vm_play_event_from_discard = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_cards.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no valid cards in discard.`
- gen_action('pass')
- } else if (game.temp === 0) {
- view.prompt = `${event_prompt()}.`
- for (let card of game.valid_cards) {
- gen_action('pass')
- gen_action_card(card)
- }
- } else {
- view.prompt = 'Choose a card: done.'
- gen_action('done')
- }
- },
- card(card) {
- push_undo()
- log(`Chose C${cards[card].number}`)
- game.vm_event = card
- game.vm_available_ops = cards[card].ops
- game.discard = false
- //game.return = game.active Does turning this off cause problems?
- console.log('card:', card)
- if (switch_events.includes(card)) {next_player()}
- goto_vm(card)
- },
- pass(){
- push_undo()
- if (game.valid_cards.length === 0) {
- log('No valid cards to choose')
- } else{
- log('Did not choose a card')
- }
- vm_next()
- },
- done(){
- game.discard = false
- vm_next()
- }
-}
-
-states.vm_deutsche_marks_prep = {
- inactive: 'choose a card.',
- prompt() {
- if (game.valid_cards.length === 0) {
- view.prompt = 'Deutsche Marks: no cards to give.'
- gen_action('pass')
- } else {
- view.prompt = 'Deutsche Marks: choose a card to give.'
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- }
- },
- card(card) {
- push_undo()
- log(`Gave C${cards[card].number}`)
- game.valid_cards = []
- silent_discard(card)
- //next_player()
- game.state = 'vm_deutsche_marks_confirm'
- game.vm_event = card
- },
- pass() {
- vm_next()
- }
-}
-
-states.vm_deutsche_marks_confirm = {
- inactive: 'choose a card.',
- prompt() {
- view.prompt = `Deutsche Marks: gave ${cards[game.vm_event].name}.`
- gen_action('done')
- },
- done() {
- next_player()
- game.state = 'vm_deutsche_marks'
- }
-}
-
-states.vm_deutsche_marks = {
- get inactive() {
- return `resolve ${clean_name(cards[20].name)}.`
- },
- prompt() {
- if(cards[game.vm_event].side === 'C' && (cards[game.vm_event].playable || game.playable_cards.includes(game.vm_event))) {
- view.prompt = `Deutsche Marks: you must play ${clean_name(cards[this_card()].name)} for the event.`
- gen_action('event')
- } else {
- view.prompt = `Deutsche Marks: play ${clean_name(cards[this_card()].name)} for:`
- gen_action('influence')
- gen_action('support_check')
- if (game.com_tst_attempted_this_turn === 0) {
- gen_action('tst')
- }
- }
- },
- event() {
- log(`Played C${cards[game.vm_event].number} for the event`)
- console.log('game.active', game.active)
- if (!game.vm_infl_to_do) {
- game.return = game.active
- }
- console.log('DM Event played, game.return', game.return)
- goto_vm(game.vm_event)
- },
- influence() {
- push_undo()
- log(`Played C${cards[game.vm_event].number} to place SPs`)
- game.vm_available_ops = get_card_ops(game.vm_event)
-
- /*cards[game.vm_event].ops
- if (game.persistent_events.includes(25)) {game.vm_available_ops++ }
- if (game.prudence.COM && game.prudence.COM < 0 ) {
- game.vm_available_ops += game.prudence.COM
- }*/
- valid_spaces_infl()
- game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- log_gap(`Played C${cards[game.vm_event].number} for support checks`)
- game.vm_available_ops = 2
- game.state='vm_support_check_prep'
- valid_spaces_sc()
- },
- tst() {
- push_undo()
- log_gap(`Played C${cards[game.vm_event].number} to the Tiananmen Square Track`)
- game.state='vm_tiananmen_square_attempt'
- }
-}
-
-states.vm_exit_visas = {
- get inactive() {
- return `resolve ${clean_name(cards[75].name)}.`
- },
- prompt() {
- view.prompt = 'Exit Visas: you may discard cards from your hand and draw replacements.'
- for (let card of game.democrat_hand) {
- gen_action_card(card)
- }
- if (game.temp === 0) {
- gen_action('pass')
- } else {
- gen_action('done')
- }
- },
- card(card){
- push_undo()
- discard(card)
- game.temp++
- },
- pass() {
- push_undo()
- game.state = 'vm_exit_visas_finish'
- },
- done() {
- push_undo()
- game.state = 'vm_exit_visas_finish'
- }
-}
-
-states.vm_exit_visas_finish = {
- get inactive() {
- return `resolve ${clean_name(cards[75].name)}.`
- },
- prompt() {
- if (game.temp > 0 ) {
- view.prompt = 'Draw replacement cards.'
- gen_action('draw')
- } else {
- view.prompt = 'Exit Visas: done.'
- gen_action('done')
- }
- },
- draw() {
- clear_undo()
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length + game.temp, game.communist_hand.length)
- game.temp = 0
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_foreign_currency_debt_burden = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Choose a country. The Communist may not make support checks there for the rest of the turn.'
- gen_action('east_germany')
- gen_action('poland')
- gen_action('czechoslovakia')
- gen_action('hungary')
- gen_action('bulgaria')
- },
- east_germany() {
- push_undo()
- game.foreign_currency_debt_burden = 'East_Germany'
- log('Selected East Germany')
- vm_next()
- },
- poland() {
- push_undo()
- game.foreign_currency_debt_burden = 'Poland'
- log('Selected Poland')
- vm_next()
- },
- czechoslovakia() {
- push_undo()
- game.foreign_currency_debt_burden = 'Czechoslovakia'
- log('Selected Czechoslovakia')
- vm_next()
- },
- hungary() {
- push_undo()
- game.foreign_currency_debt_burden = 'Hungary'
- log('Selected Hungary')
- vm_next()
- },
- bulgaria() {
- push_undo()
- game.foreign_currency_debt_burden = 'Bulgaria'
- log('Selected Bulgaria')
- vm_next()
- }
-}
-
-states.vm_goodbye_lenin = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- console.log('in vm_goodbye lenin')
- if (game.valid_cards.length > 0 ) {
- view.prompt = 'Choose a card to play for the event, or play Goodbye Lenin for operations'
- for (let card of game.valid_cards) {
- gen_action_card(card)
- gen_action('ops')
- }
- } else {
- view.prompt = 'Communist has no valid cards. Play Goodbye Lenin for operations.'
- gen_action('ops')
- }
- },
- card(card) {
- push_undo()
- log(`Chose to play C${card} for the event`)
- let card_index = game.communist_hand.indexOf(card)
- game.communist_hand.splice(card_index, 1)
- game.vm_event = card
- game.view_opp_hand = false
- goto_vm(card)
- },
- ops() {
- log('C46 played for operations')
- game.view_opp_hand = false
- game.state = 'vm_goodbye_lenin_ops'
- }
-}
-
-states.vm_goodbye_lenin_ops = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- view.prompt = `Play ${clean_name(cards[this_card()].name)} for:`
- gen_action('influence')
- gen_action('support_check')
- if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 )) {
- gen_action('tst')
- }
- },
- influence(){
- push_undo()
- game.vm_available_ops = get_card_ops(this_card())
- /*if (game.persistent_events.includes(50)) {
- log(`+1 from C50`)
- game.vm_available_ops++
- }*/
- console.log('goodbye lenin: influence selected')
- valid_spaces_infl()
-
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- game.vm_available_ops = 2
- game.state = 'vm_support_check_prep'
- valid_spaces_sc()
- },
- tst() {
- game.state = 'vm_tiananmen_square_attempt'
- }
-}
-
-states.vm_honecker = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_cards.length === 0 && game.temp === 0) {
- view.prompt = 'Honecker: no valid cards to choose.'
- gen_action('done')
- } else
- if (game.temp === 0) {view.prompt = 'Honecker: choose a card to add to your hand.'
- for (let card of game.valid_cards) {
- gen_action_card(card)
- gen_action('pass')
- }
- } else {
- view.prompt = 'Honecker. Choose a card: done.'
- gen_action('done')
- }
- },
- card(card) {
- push_undo()
- game.valid_cards = []
- log(`Took C${cards[card].number} into hand`)
- game.temp = card
- let card_index = game.strategy_discard.indexOf(card)
- game.strategy_discard.splice(card_index, 1)
- game.communist_hand.push(card)
- console.log('removed after honecker', game.strategy_removed)
- },
- pass(){
- log('Did not take a card')
- vm_next()
- },
- done(){
- if (game.temp === 0) {
- log('Did not take a card')
- }
- game.discard = false
- vm_next()
- }
-
-}
-
-states.vm_inflationary_currency = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- console.log('game.revolutions', game.revolutions, 'length', game.revolutions.length)
- if (game.revolutions.every(n => n === false)) {
- view.prompt = 'Inflationary Currency: no countries to choose.'
- gen_action('pass')
- } else {
- view.prompt = 'Inflationary Currency: choose a country where your opponent has power.'
- if (game.active === DEM) {
- if (!game.revolutions[0]) {gen_action('poland')}
- if (!game.revolutions[1]) {gen_action('hungary')}
- if (!game.revolutions[2]) {gen_action('east_germany')}
- if (!game.revolutions[3]) {gen_action('bulgaria')}
- if (!game.revolutions[4]) {gen_action('czechoslovakia')}
- if (!game.revolutions[5]) {gen_action('romania')}
- } else {
- if (game.revolutions[0]) {gen_action('poland')}
- if (game.revolutions[1]) {gen_action('hungary')}
- if (game.revolutions[2]) {gen_action('east_germany')}
- if (game.revolutions[3]) {gen_action('bulgaria')}
- if (game.revolutions[4]) {gen_action('czechoslovakia')}
- if (game.revolutions[5]) {gen_action('romania')}
- }
- }
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- pass() {
- log('Passed')
- vm_return()
- }
-}
-
-states.vm_inflationary_currency_discard = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_cards.length === 0 ) {
- view.prompt = 'Inflationary Currency: no valid cards to discard. You must pass.'
- gen_action('pass')
- } else if (game.temp === 0 ) {
- view.prompt = 'Inflationary Currency: you may discard a 3 op or higher value card to cancel the support check.'
- gen_action('pass')
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- } else {
- view.prompt = 'Discard a card: done.'
- gen_action('done')
- }
- },
- card(card) {
- push_undo()
- discard(card)
- game.temp = card
- },
- pass() {
- log('Did not discard')
- next_player()
- game.vm_available_ops = 1
- vm_next()
- //game.state = 'vm_support_check_prep'
- },
- done() {
- if (!game.vm_infl_to_do) {
- if(game.round_player === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- }
- vm_next()
- }
-}
-
-
-states.vm_kiss_of_death = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.communist_hand.length === 0) {
- view.prompt = 'Kiss of Death. No cards to discard.'
- gen_action('pass')
- } else {
- view.prompt = 'Kiss of Death: you must randomly discard a card.'
- gen_action('discard')
- }
- },
- discard() {
- game.vm_event = discard_card(game.communist_hand)
- next_player()
- game.state = 'vm_kiss_of_death_finish'
- },
- pass() {
- log('No card to discard')
- vm_next()
- }
-}
-
-states.vm_kiss_of_death_finish = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- console.log('game.vm_event', game.vm_event)
- if (game.vm_event > 0 && game.vm_event !== 21 && (cards[game.vm_event].side === 'D' || cards[game.vm_event].side === 'N')) {
- view.prompt = `Play ${clean_name(cards[game.vm_event].name)} for the event.`
- console.log('kiss of death before event button: game.stategy_discard', game.strategy_discard)
- gen_action('event')
- } else {
- view.prompt = 'Event does not occur.'
- gen_action('done')
- }
- },
- event() {
- //game.return = game.active
- console.log('kiss of death event section, discard', game.strategy_discard)
- // Remove game.vm_event from the discard
- //game.strategy_discard = game.strategy_discard.filter(n => n !== game.vm_event)
- console.log('kiss of death event section 2, discard', game.strategy_discard)
-
- goto_vm(game.vm_event)
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_kremlin_coup_choose_country = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- if (game.temp.length > 0) {
- view.prompt = 'Kremlin Coup! Select a country where the Communist retains power.'
- for (let country of countries) {
- console.log(`checking`, country)
- if (game.temp.includes(country)) {
- console.log('country in game.temp')
- gen_action(`${country.toLowerCase()}`)
- }
- }
- } else {
- view.prompt = 'Kremlin Coup! There are no countries where the Communist retains power.'
- gen_action('done')
- }
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- log(`${country_name(game.vm_active_country)}:`)
- vm_kremlin_coup_elite()
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- done() {
- game.temp = 0
- vm_next()
- }
-}
-
-states.vm_kremlin_coup_take_control = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_spaces.length === 0){
- view.prompt = `Kremlin Coup! ${country_name(game.vm_active_country)}'s Elite space is already controlled.`
- gen_action('done')
- } else {
- view.prompt = `Kremlin Coup! Take control of the Elite space in ${country_name(game.vm_active_country)}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- }
- },
- infl(space) {
- vm_take_control(space)
- if (game.vm_active_country === 'East_Germany') {game.selected_space = 3 }
- if (game.vm_active_country === 'Poland') {game.selected_space = 17}
- if (game.vm_active_country === 'Czechoslovakia') {game.selected_space = 29}
- if (game.vm_active_country === 'Hungary') {game.selected_space = 45}
- if (game.vm_active_country === 'Romania') {game.selected_space = 61}
- if (game.vm_active_country === 'Bulgaria') {game.selected_space = 68}
- game.state = 'vm_kremlin_coup_sc_prep'
- },
- done() {
- if (game.vm_active_country === 'East_Germany') {game.selected_space = 3 }
- if (game.vm_active_country === 'Poland') {game.selected_space = 17}
- if (game.vm_active_country === 'Czechoslovakia') {game.selected_space = 29}
- if (game.vm_active_country === 'Hungary') {game.selected_space = 45}
- if (game.vm_active_country === 'Romania') {game.selected_space = 61}
- if (game.vm_active_country === 'Bulgaria') {game.selected_space = 68}
- game.state = 'vm_kremlin_coup_sc_prep'
- }
-}
-
-states.vm_kremlin_coup_sc_prep = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = `Kremlin Coup! Conduct a support check in ${game.vm_active_country}'s Bureaucratic space.`
- gen_action_sc(spaces[game.selected_space].name_unique);
- },
- sc(space) {
- //game.selected_space = find_space_index(space)
- game.state = 'vm_kremlin_coup_sc'
- }
-}
-
-states.vm_kremlin_coup_sc = {
- inactive: 'do support checks',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(spaces[game.selected_space].name_unique)
- if (game.temp.length > 0 ){
- game.state = 'vm_kremlin_coup_choose_country'
- } else {
- game.state = 'vm_kremlin_coup_end'
- }
- }
-}
-
-states.vm_kremlin_coup_end = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- view.prompt = `${clean_name(cards[this_card()].name)}: done.`
- gen_action('done')
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_laszlo_tokes = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = `Laszlo Tokes. Choose to:`
- gen_action('influence')
- gen_action('support_check')
- },
- influence(){
- push_undo()
- game.vm_available_ops = get_card_ops(73)
- valid_spaces_infl()
- game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania')
- game.phase = 3
- vm_next()
- //game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- game.vm_available_ops = 2
- //game.state = 'vm_support_check_prep'
- valid_spaces_sc()
- game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania')
- vm_next()
- }
-}
-
-states.vm_switch_infl = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: No SPs to remove.`
- gen_action('pass')
- } else {
- /*if (game.vm_available_ops > 0 ) {*/
- view.prompt = `${clean_name(cards[game.played_card].name)}: ${event_prompt()}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } /*else {
- view.prompt = 'Influence replaced.'
- gen_action('done')
- }*/
- },
- infl(space) {
- push_undo()
- vm_switch_infl(space)
- if (game.vm_available_ops === 0) {
- game.valid_spaces = []
- }
- vm_next()
- },
- pass() {
- vm_next()
- }
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_malta_summit = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- /*if (game.phase === 1) {*/
- view.prompt = 'Malta Summit: roll a die.'
- gen_action('roll')
- /*} else {
- view.prompt = 'Done.'
- gen_action('done')
- }*/
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- if (game.stability > 0) {
- log(`+${game.stability} from USSR Stability Track`)
- log(`Modified roll: ${roll + game.stability}`)
- }
- if (roll + game.stability > 3) {
- log('Summit successful')
- game.vp += 3
- log('+3 VP')
- if (check_vp()) {
- return
- }
- if (game.comInfl[12] > 0 ) {game.valid_spaces.push(12)}
- if (game.comInfl[15] > 0 ) {game.valid_spaces.push(15)}
- if (game.comInfl[27] > 0 ) {game.valid_spaces.push(27)}
- if (game.comInfl[43] > 0 ) {game.valid_spaces.push(43)}
- if (game.comInfl[51] > 0 ) {game.valid_spaces.push(51)}
- if (game.comInfl[69] > 0 ) {game.valid_spaces.push(69)}
- //game.vm_available_ops = 5
- game.remove_opponent_infl = true
- vm_next()
- }
- else {
- log('Summit failed. Required 4 or more')
- //game.phase++
- vm_goto_step(vm_permanently_remove)
- }
- },
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_modrow = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = `Modrow: roll a die.`
- gen_action('roll')
- },
- roll(){
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- let dem_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_dem_control(space.space_id)).length
- if (roll > dem_spaces) {
- log(`Rolled a ${roll}`)
- log(`Success. More than the ${dem_spaces} Democratically controlled spaces`)
- vm_next()
- } else {
- log(`Rolled a ${roll}`)
- log(`Fail. More than ${dem_spaces} required`)
- permanently_remove(83)
- vm_return()
- }
- }
-}
-
-states.vm_nepotism = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- //if (game.phase === 1 ) {
- view.prompt = 'Nepotism: roll a die.'
- gen_action('roll')
- /*} else {
- view.prompt = 'Roll a die: done.'
- gen_action('done')
- }*/
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- if (roll < 3) {
- log(`Rolled a ${roll}: adds 4 SPs`)
- game.vm_available_ops = 4}
- else if (roll < 5 ) {
- log(`Rolled a ${roll}: adds 3 SPs`)
- game.vm_available_ops = 3}
- else {
- log(`Rolled a ${roll}: adds 1 SP`)
- game.vm_available_ops = 1}
- //game.phase = 2
- vm_next()
- },
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_new_years_eve_party = {
- get inactive() {
- return `resolve ${clean_name(cards[104].name)}.`
- },
- prompt() {
- view.prompt = 'Choose whether the game ends at the end of this turn.'
- gen_action('end')
- gen_action('continue')
- },
- end() {
- push_undo()
- game.persistent_events.push(104)
- log('Chooses to end the game. There will be no final scoring')
- let power = game.revolutions.filter(value => value === false).length
- if (power > 3) {
- log(`Communist holds power in ${power} countries. -3 VP`)
- game.vp -= 3
- } else {
- log(`Communist holds power in ${power} countries. +3 VP`)
- game.vp += 3
- }
- if (check_vp()) {
- return
- }
- //game.table_cards.push(104)
- permanently_remove(104)
- vm_next()
- },
- continue() {
- log('Chooses to continue')
- permanently_remove(104)
- vm_next()
- }
-}
-
-states.vm_nomenklatura = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Nomenklatura: choose to remove all Democratic SPs from Elite spaces or add 3 SPs to any Elite space(s).'
- gen_action('remove')
- gen_action('add')
- },
- remove() {
- push_undo()
- game.valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
-
- if (space.socio === 1 && game.demInfl[i] > 0) {
- game.valid_spaces.push(space.space_id)
- }
- }
- game.vm_available_ops = game.valid_spaces.length
- game.remove_opponent_infl = true
- game.state = 'vm_nomenklatura_remove'
- },
- add() {
- push_undo()
- game.valid_spaces = []
- for (let space of spaces) {
- if (!space) continue
- if (space.socio === 1) {
- game.valid_spaces.push(space.space_id)
- }
- }
- game.vm_available_ops = 3
- game.state = 'vm_nomenklatura_add'
- }
-}
-
-states.vm_nomenklatura_remove = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.vm_available_ops === 0 || game.valid_spaces.length === 0 ) {
- view.prompt = 'Remove SPs: done.'
- gen_action('done')
- } else {
- view.prompt = 'Nomenklatura: remove all Democratic SPs from Elite spaces.'
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- }
- },
- infl(space) {
- push_undo()
- vm_do_remove_all_infl(space)
- if (game.vm_available_ops === 0) {
- vm_next()
- }
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_nomenklatura_add = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.vm_available_ops === 0 || game.valid_spaces.length === 0 ) {
- view.prompt = 'Add SPs: done.'
- gen_action('done')
- } else {
- view.prompt = `Nomenklatura: add 3 SPs to any Elite space(s). ${pluralize(game.vm_available_ops, 'SP')} remaining.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- }
- },
- infl(space) {
- push_undo()
- vm_do_add_infl_free(space)
- if (game.vm_available_ops === 0 ) {game.valid_spaces = []}
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_samizdat = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Samizdat: you may set aside a card from your hand and draw a replacement.'
- for (let card of game.democrat_hand) {
- gen_action_card(card)
- }
- gen_action('pass')
- },
- card(card) {
- push_undo()
- game.samizdat_card = card
- game.democrat_hand = game.democrat_hand.filter(c => c !== card)
- log('Set aside a card')
- game.state = 'vm_samizdat_finish'
- },
- pass() {
- //if (game.samizdat_card > 0) {game.state = 'vm_samizdat_finish'}
- /*else { */
- log('Did not set aside a card')
- vm_next()
- //}
- }
-}
-
-states.vm_samizdat_finish = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- /*if (game.phase ) {
- view.prompt = 'Samizdat: done.'
- gen_action('done')
- } else {*/
- view.prompt = 'Draw a replacement card.'
- gen_action('draw')
- //}
- },
- draw() {
- clear_undo()
- game.democrat_hand.push(draw_card(game.strategy_deck))
- vm_next()
- //game.phase ++
- },
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_shock_therapy = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.vm_active_country === '' ) {
- view.prompt = 'Shock Therapy: choose a country where you hold Power:'
- if (game.revolutions[0]) {gen_action('poland')}
- if (game.revolutions[1]) {gen_action('hungary')}
- if (game.revolutions[2]) {gen_action('east_germany')}
- if (game.revolutions[3]) {gen_action('bulgaria')}
- if (game.revolutions[4]) {gen_action('czechoslovakia')}
- if (game.revolutions[5]) {gen_action('romania')}
- } else if (game.phase === 2) {
- view.prompt = 'Shock Therapy: done.'
- gen_action('done')
- } else {
- view.prompt = 'Shock Therapy: roll a die.'
- gen_action('roll')
- }
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- let worker_farmer = 0
- for (let space of spaces) {
- if (space && space.country === game.vm_active_country && check_com_control(space.space_id) && (space.socio === 3 || space.socio === 4)) {
- worker_farmer++
- }
- }
- log(`Rolled a ${roll}`)
- log(`-${worker_farmer} from Communist controlled Worker and Farmer spaces`)
- log(`Modified roll: ${roll - worker_farmer}`)
- if ((roll - worker_farmer) > 2) {
- log('C93 is successful. +3 VP')
- vm_next()
- } else {
- log('C93 is unsuccessful. Required 3 or more')
- game.phase++
- }
- },
- done() {
- permanently_remove(93)
- vm_return()
- }
-}
-
-states.vm_social_democratic_platform_adopted = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Select a country where the Democrat holds Power.'
- if (game.revolutions[0]) {gen_action('poland')}
- if (game.revolutions[1]) {gen_action('hungary')}
- if (game.revolutions[2]) {gen_action('east_germany')}
- if (game.revolutions[3]) {gen_action('bulgaria')}
- if (game.revolutions[4]) {gen_action('czechoslovakia')}
- if (game.revolutions[5]) {gen_action('romania')}
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()},
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()},
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()}
-}
-
-states.vm_systematization = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- /*if (game.systematization === 0) { */
- view.prompt = 'Systematization: eliminate a space in Romania.'
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- /*} else {
- view.prompt = 'Systematization: done.'
- gen_action('done')
- }*/
- },
- infl(space) {
- push_undo()
- vm_eliminate(find_space_index(space))
- game.valid_spaces = []
- game.systematization = find_space_index(space)
- game.persistent_events.push(69)
- vm_next()
- },
-/* done() {
- vm_next()
- } */
-}
-
-states.vm_the_chinese_solution = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'You may give up 3 VP to conduct support checks in a country where you hold power.'
- if (!game.revolutions[0]) {gen_action('poland')}
- if (!game.revolutions[1]) {gen_action('hungary')}
- if (!game.revolutions[2]) {gen_action('east_germany')}
- if (!game.revolutions[3]) {gen_action('bulgaria')}
- if (!game.revolutions[4]) {gen_action('czechoslovakia')}
- if (!game.revolutions[5]) {gen_action('romania')}
- gen_action('pass')
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- pass() {
- permanently_remove(96)
- vm_return()
- }
-}
-
-states.vm_the_tyrant_is_gone = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (!game.the_tyrant_is_gone) {
- view.prompt = 'The Tyrant is Gone: Select a space in Romania for the Ceausescus to flee to.'
- for (let space_id of game.valid_spaces) {
- if (!space_id) continue
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = 'Select a space: done.'
- gen_action('done')
- }
- },
- infl(space) {
- push_undo()
- log(`The Ceausescus flee to %${find_space_index(space)}`)
- game.the_tyrant_is_gone = find_space_index(space)
- game.persistent_events.push(97)
- },
- done () {
- vm_next()
- }
-}
-
-states.vm_the_wall_must_go = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- if (game.the_wall_must_go['dem_wins'] === 2 || game.the_wall_must_go['com_wins'] === 2) {
- view.prompt = 'The Wall Must Go! Done.'
- gen_action('done')
- } else {
- view.prompt = ('The Wall Must Go! Roll a die.')
- gen_action('roll')
- }
- },
- roll() {
- clear_undo()
- let attempt = game.the_wall_must_go['dem_wins'] + game.the_wall_must_go['com_wins']
- if (game.the_wall_must_go['dem_roll'] === 0 && game.the_wall_must_go['com_roll'] === 0) {
- log_h3(`Round ${attempt+1}`)
- }
-
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- if (game.active === DEM) {
- let controlled_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_dem_control(space.space_id)).length
- if (controlled_spaces > 0) {
- log(`+${controlled_spaces} from controlled spaces in East Germany`)
- log(`Modified roll: ${roll + controlled_spaces}`)
- roll += controlled_spaces
- }
- game.the_wall_must_go['dem_roll'] = roll
- } else {
- let controlled_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_com_control(space.space_id)).length
- if (controlled_spaces > 0) {
- log(`+${controlled_spaces} from controlled spaces in East Germany`)
- log(`Modified roll: ${roll + controlled_spaces}`)
- roll += controlled_spaces
- }
- game.the_wall_must_go['com_roll'] = roll
-
- }
- if (game.the_wall_must_go['dem_roll'] > 0 && game.the_wall_must_go['com_roll'] > 0) {
- if (game.the_wall_must_go['dem_roll'] > game.the_wall_must_go['com_roll'] ) {
- log('Democrat wins')
- game.the_wall_must_go['dem_wins']++
- } else if (game.the_wall_must_go['dem_roll'] === game.the_wall_must_go['com_roll'] ) {
- log('Tie. Re-roll')
- } else {
- log('Communist wins')
- game.the_wall_must_go['com_wins']++
- }
-
- log(`Democrat: ${game.the_wall_must_go['dem_wins']}, Communist: ${game.the_wall_must_go['com_wins']}`)
- }
- if (game.the_wall_must_go['dem_wins'] === 2) {
- log('The Democrat wins C86')
- return
- }
- if (game.the_wall_must_go['com_wins'] === 2) {
- log('The Communist wins C86')
- return
- }
- if (game.the_wall_must_go['dem_roll'] === 0 || game.the_wall_must_go['com_roll'] === 0) {
- next_player()
- } else {
- game.the_wall_must_go['dem_roll'] = 0
- game.the_wall_must_go['com_roll'] = 0
- }
- },
- done() {
- if (game.the_wall_must_go['dem_wins'] === 2) {
- game.persistent_events.push(86)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (space.country === 'East_Germany' && game.comInfl[i] > 0){
- game.valid_spaces.push(space.space_id)
- }
- }
- if (!game.vm_infl_to_do) {
- if (game.round_player === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- }
- if (game.active === DEM) {next_player()}
- vm_next ()
- } else {
- permanently_remove(86)
- delete game.the_wall_must_go
- vm_return()
- }
- }
-}
-
-states.vm_warsaw_pact_summit = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Choose to play for support checks or place SPs.'
- gen_action('influence')
- gen_action('support_check')
- },
- influence(){
- push_undo()
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (game.demInfl[i] === 0) {
- game.valid_spaces.push(space.space_id);
- }
- }
- game.vm_available_ops = 4
- game.phase = 3
- //game.state = 'vm_add_infl'
- vm_next()
- },
- support_check(){
- push_undo()
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (game.demInfl[i] > 0 && (space.socio === 5 || space.socio === 6)) {
- game.valid_spaces.push(space.space_id)
- }
- }
- game.vm_available_ops = 2
- //game.state = 'vm_support_check_prep'
- console.log('game.phase',game.phase)
- vm_next()
- }
-}
-
-states.vm_we_are_the_people_remove = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.demInfl[6] === 0) {
- view.prompt = '"We are the People!": no SPs to remove.'
- gen_action('done')
- } else if (game.vm_available_ops > 0 ) {
- view.prompt = '"We are the People!": remove up to 4 SPs from the Lutherian Church.'
- gen_action('done')
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- } else {
- view.prompt = 'Remove SPs: done.'
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_remove_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- if (!game.vm_influence_added[6]) {
- log('No SPs removed')
- vm_next()
- } else {
- game.valid_spaces = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
- game.state = 'vm_we_are_the_people_add'
- }
- }
-}
-states.vm_we_are_the_people_add = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (!game.vm_influence_added[6]) {
- view.prompt = '"We are the People!": done.'
- gen_action('done')
- return
- }
-
- view.prompt = `"We are the People!": you must add the ${pluralize(game.vm_influence_added[6],'SP')} to spaces in Germany.`
- gen_action('done')
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- },
- infl(space) {
- push_undo()
- vm_do_add_infl_free(space)
- game.vm_influence_added[6]--
- if (game.vm_influence_added[6] === 0 ) {game.valid_spaces = []}
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_workers_revolt = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Workers Revolt: select a Worker Space in a country your opponent has power.'
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique)
- }
- },
- infl(space) {
- game.selected_space = find_space_index(space)
- log(`Chose %${game.selected_space}`)
- game.state = 'vm_workers_revolt_finish'
- }
-}
-
-
-states.vm_workers_revolt_finish = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.selected_space > 0) {
- view.prompt = `Target: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- } else {
- view.prompt = 'Workers Revolt: done.'
- gen_action('done')
- }
-
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Rolled a ${roll}`)
- let adj = count_adj(spaces[game.selected_space].name_unique)
- if (game.active === DEM) {
- log(`-${adj.com_adj} from opponent controlled spaces`)
- roll -= adj.com_adj
- } else {
- log(`-${adj.dem_adj} from opponent controlled spaces`)
- roll -= adj.dem_adj
- }
- log(`Modified roll: ${roll}`)
- if (roll >= 4) {
- log('Workers Revolt successful')
- vm_replace_all_infl(game.temp)
- } else {log('Workers Revolt fails. Required 4 or more')}
- game.selected_space = 0
- },
- done() {
- vm_next()
- }
-}
-
-// ==================== TIANANMEN SQUARE TRACK STATES =====================
-
-states.vm_tst_3_prep = {
- inactive: 'resolve Tiananmen Square Track award.',
- prompt() {
- view.prompt = 'Tiananmen Square Track award: draw 3 cards.'
- gen_action('draw')
- },
- draw() {
- if (game.active === DEM) {
- game.temp = game.democrat_hand.length
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length + 3, game.communist_hand.length)
- game.valid_cards = [game.democrat_hand[game.temp], game.democrat_hand[game.temp + 1], game.democrat_hand[game.temp + 2]]
- } else {
- game.temp = game.communist_hand.length
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length + 3)
- game.valid_cards = [game.communist_hand[game.temp], game.communist_hand[game.temp + 1], game.communist_hand[game.temp + 2]]
- }
- game.temp = 0
- game.state = 'vm_tst_3'
- }
-}
-
-states.vm_tst_3 = {
- inactive: 'resolve Tiananmen Square Track bonus.',
- prompt() {
- if (game.temp < 2) {
- view.prompt = `Discard 2 of the drawn cards`
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- } else {
- view.prompt = 'Discard cards: done.'
- gen_action('done')
- }
- },
- card(card) {
- push_undo()
- discard(card)
- game.temp ++
- if (game.temp === 2) {
- game.valid_cards = []
- }
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_tst_4 = {
- inactive: 'remove SPs',
- prompt () {
- if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
- view.prompt = 'Remove SPs: done.'
- gen_action('done')
- return
- }
- view.prompt = 'Tiananmen Square Track award: select a space to remove SPs'
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(spaces[space_id].name_unique);
- }
- },
- infl(space) {
- vm_do_remove_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_tst_6 = {
- inactive: 'make their free support check.',
- prompt() {
- if (game.vm_available_ops === 0) {
- view.prompt = 'Tiananmen Square Track award support check: done.'
- gen_action('done')
- return
- } else {
- view.prompt = 'Tiananmen Square Track award: you have a free 2 Ops support check.'
- for (let space_id of game.valid_spaces) {
- if (space_id) {
- gen_action_sc(spaces[space_id].name_unique);
- }
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = find_space_index(space)
- if (game.active === DEM && game.persistent_events.includes(58) && spaces[space].country === "East_Germany") {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'vm_tst_6_sc'
- },
- done () {
- vm_next()
- }
-}
-
-states.vm_tst_6_sc = {
- inactive: 'do support check.',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(spaces[game.selected_space].name_unique)
- game.vm_available_ops--
- game.valid_spaces = []
- game.state = 'vm_tst_6'
- return
- }
-}
-
-states.vm_tst_8 = {
- inactive: 'use Tiananmen Square Track award.',
- prompt() {
- if (game.vm_event_to_do && game.vm_infl_to_do) {
- view.prompt = 'Choose whether to play for event or operations first.'
- gen_action('event')
- gen_action('ops')
- }
- else if (!game.vm_event_to_do && game.vm_infl_to_do) {
- view.prompt = 'Event resolved. Use card for operations.'
- gen_action('ops')
- }
- else if (game.vm_event_to_do && !game.vm_infl_to_do) {
- view.prompt = 'Operations resolved. Use card for event.'
- gen_action('event')
- }
- else if (!game.vm_event_to_do && !game.vm_infl_to_do) {
- view.prompt = 'Event and operations: done.'
- gen_action('done')
- }
- },
- event() {
- push_undo()
- game.vm_event_to_do = false
- game.return_state = 'vm_tst_8'
- game.return = game.active
- game.vm_event = game.played_card
- goto_vm(game.vm_event)
- },
- ops() {
- push_undo()
- game.vm_infl_to_do = false
- game.return = game.active
- game.return_state = 'vm_tst_8'
- goto_vm(208)
- },
- done() {
- game.tst_8 = true
- end_round()
- }
-}
-
-
-states.vm_tst_8_ops = {
- inactive: 'play card for operations.',
- prompt() {
- view.prompt = `Play ${clean_name(cards[game.played_card].name)} for:`
- gen_action('influence')
- gen_action('support_check')
- if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 )) {
- gen_action('tst')
- }
- },
- influence(){
- push_undo()
- game.vm_available_ops = cards[game.played_card].ops
- valid_spaces_infl()
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- game.vm_available_ops = 2
- game.state = 'vm_support_check_prep'
- },
- tst() {
- game.state = 'vm_tiananmen_square_attempt'
- }
-}
-
-// ========================= POWER STRUGGLE STATES ========================
-
-states.vm_support_surges = {
- inactive: 'draw cards.',
- prompt() {
- view.prompt = 'Support Surges: draw 2 cards.'
- gen_action('draw')
- },
- draw() {
- if (game.active === DEM) {
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+2, game.com_pwr_hand.length)
- } else {
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+2)
- }
- game.phase = 0
- log('Drew 2 cards')
- log('Surrenders initiative')
- vm_next()
- }
-}
-
-states.vm_support_falters = {
- inactive: 'discard cards.',
- prompt() {
- if ((game.active === DEM && game.dem_pwr_hand.length === 0) || (game.active === COM && game.com_pwr_hand.length === 0)) {
- view.prompt = 'Support Falters: no remaining cards to discard.'
- gen_action('pass')
- } else if (game.vm_available_ops > 0) {
- view.prompt = 'Support Falters: discard a card.'
- gen_action('discard')
- } else {
- view.prompt = 'Support Falters: done.'
- gen_action('done')
- }
- },
- discard() {
- console.log('game.com_pwr_hand', game.com_pwr_hand)
- if (game.active === DEM) {discard_card(game.dem_pwr_hand)}
- else {discard_card(game.com_pwr_hand)}
- game.vm_available_ops --
- },
- pass() {
- log_msg_gap('Takes initiative')
- game.return = game.active
- vm_next()
- },
- done() {
- log_msg_gap('Takes initiative')
- game.return = game.active
- vm_next()
- }
-}
-
-/* =================== EVENTS ================================ */
-
-// #region GENERATED EVENT CODE
-const CODE = []
-
-CODE[1] = [ // Legacy of Martial Law*
- [ vm_valid_spaces_country_opp, 'Poland' ],
- [ vm_prompt, 'replace 1 Democratic SP in Poland with a Communist SP' ],
- [ vm_legacy_of_martial_law ],
- [ vm_valid_spaces_country_sc, 'Poland' ],
- [ vm_prompt, 'make a Support Check in Poland' ],
- [ vm_1_support_check ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[2] = [ // Solidarity Legalised*
- [ vm_solidarity_legalised ],
- [ vm_valid_spaces_solidarity_legalised ],
- [ vm_prompt, 'to every uncontrolled Worker and Farmer space in Poland' ],
- [ vm_add_limited_infl, 9, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[3] = [ // Walesa
- [ vm_valid_spaces_country, 'Poland' ],
- [ vm_prompt, 'any space(s) in Poland' ],
- [ vm_add_infl_free, 4 ],
- [ vm_valid_spaces_country_sc, 'Poland' ],
- [ vm_prompt, 'Make Support Checks in Poland' ],
- [ vm_support_check, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[4] = [ // Michnik
- [ vm_valid_spaces, 26 ],
- [ vm_prompt, 'the Polish Intellectuals space' ],
- [ vm_add_x_infl, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[5] = [ // General strike
- [ vm_general_strike ],
- [ vm_return ],
-]
-
-CODE[6] = [ // Brought in for Questioning
- [ vm_brought_in_for_questioning ],
- [ vm_return ],
-]
-
-CODE[7] = [ // State Run Media*
- [ vm_valid_spaces_opponent ],
- [ vm_remove_limited_opp_infl, 4, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[8] = [ // Prudence
- [ vm_prudence ],
- [ vm_return ],
-]
-
-CODE[9] = [ // The Wall*
- [ vm_the_wall ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[10] = [ // Cult of Personality
- [ vm_if, ()=>!game.the_tyrant_is_gone ],
- [ vm_valid_spaces_country_socio_2, 'Romania', 3, 4 ],
- [ vm_prompt, 'Worker or Farmer spaces in Romania, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_endif ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[11] = [ // Dissident arrested
- [ vm_valid_spaces_opponent_socio, 5 ],
- [ vm_prompt, 'any Intellectuals space' ],
- [ vm_remove_x_opp_infl, 2 ],
- [ vm_return ],
-]
-
-CODE[12] = [ // Apparatchicks
- [ vm_valid_spaces_socio, 2 ],
- [ vm_prompt, ' to any Bureaucratic space(s)' ],
- [ vm_add_infl_free, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[13] = [ // Stasi
- [ vm_stasi ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[14] = [ // Gorbachev Charms the West
- [ vm_valid_spaces_opponent ],
- [ vm_remove_opp_infl, 2 ],
- [ vm_valid_spaces_sc ],
- [ vm_prompt, 'select a space for the Support Check' ],
- [ vm_1_support_check ],
- [ vm_return ],
-]
-
-CODE[15] = [ // Honecker
- [ vm_permanently_remove ],
- [ vm_honecker ],
- [ vm_return ],
-]
-
-CODE[16] = [ // Nomenklatura*
- [ vm_nomenklatura ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[17] = [ // Roundtable talks
- [ vm_roundtable_talks ],
- [ vm_return ],
-]
-
-CODE[18] = [ // Poszgay Defends the Revolution
- [ vm_poszgay ],
- [ vm_prompt, 'to 4 spaces in Hungary not under Democratic control' ],
- [ vm_add_limited_infl, 4, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[19] = [ // Papal vist
- [ vm_valid_spaces, 20, 35, 38 ],
- [ vm_prompt, 'any Catholic Church space' ],
- [ vm_add_x_infl, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[20] = [ // Deutsche Marks*
- [ vm_permanently_remove ],
- [ vm_deutsche_marks ],
- [ vm_return ],
-]
-
-CODE[21] = [ // Common European Home
- [ vm_common_european_home ],
- [ vm_return ],
-]
-
-CODE[22] = [ // Power Struggle - Poland
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[23] = [ // Power Struggle - Hungary
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[24] = [ // St Nicolas Church
- [ vm_valid_spaces, 6 ],
- [ vm_prompt, 'the Lutheran Church' ],
- [ vm_take_control_prep, 1 ],
- [ vm_st_nicholas_church ],
- [ vm_return ],
-]
-
-CODE[25] = [ // Perestroika
- [ vm_perestroika ],
- [ vm_return ],
-]
-
-CODE[26] = [ // Helsinki Final Act*
- [ vm_helsinki_final_act ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[27] = [ // Consumerism
- [ vm_valid_spaces_opponent_socio, 4 ],
- [ vm_prompt, ' from a Worker space' ],
- [ vm_remove_opp_infl, 1 ],
- [ vm_valid_spaces_opponent_socio, 4 ],
- [ vm_active_country ],
- [ vm_prompt, ()=>`make a support check in a Worker space in ${country_name(game.vm_active_country)}` ],
- [ vm_1_support_check ],
- [ vm_return ],
-]
-
-CODE[28] = [ // Factory Party Cells
- [ vm_valid_spaces_opponent_socio, 4 ],
- [ vm_prompt, ' from Worker spaces' ],
- [ vm_remove_limited_opp_infl, 3, 2 ],
- [ vm_return ],
-]
-
-CODE[29] = [ // Jan Palach Week*
- [ vm_valid_spaces, 30 ],
- [ vm_prompt, 'the Charles University space' ],
- [ vm_add_x_infl, 6 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[30] = [ // Tear Gas
- [ vm_tear_gas ],
- [ vm_return ],
-]
-
-CODE[31] = [ // Intelligentsia
- [ vm_valid_spaces, 4, 26, 31, 46, 55, 73 ],
- [ vm_prompt, 'Intellectual spaces, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_return ],
-]
-
-CODE[32] = [ // Peasant Parties*
- [ vm_valid_spaces_socio, 3 ],
- [ vm_prompt, 'Farmer spaces, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[33] = [ // Sajudis*
- [ vm_sajudis_check ],
- [ vm_prompt, 'any Minorities space' ],
- [ vm_take_control_prep, 1 ],
- [ vm_sajudis ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[34] = [ // Fidesz*
- [ vm_valid_spaces, 47 ],
- [ vm_prompt, 'the Hungary students space' ],
- [ vm_add_x_infl, 5 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[35] = [ // Heal our Bleeding Wounds*
- [ vm_heal_our_bleeding_wounds ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[36] = [ // Dash for the West*
- [ vm_permanently_remove ],
- [ vm_prompt, 'Dash for the West: select any Democratic event with an asterix(*) from the discard pile. Event occurs immediately' ],
- [ vm_dash_for_the_west ],
- [ vm_return ],
-]
-
-CODE[37] = [ // Nagy Reburied*
- [ vm_nagy_reburied ],
- [ vm_prompt, 'the Hungary Elite space' ],
- [ vm_remove_all_infl, 1 ],
- [ vm_valid_spaces_country, 'Hungary' ],
- [ vm_prompt, 'Hungary, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[38] = [ // July Concept
- [ vm_valid_spaces_country, 'Bulgaria' ],
- [ vm_prompt, 'Bulgaria' ],
- [ vm_add_infl_free, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[39] = [ // Eco-Glasnost*
- [ vm_valid_spaces, 66 ],
- [ vm_prompt, 'Ruse' ],
- [ vm_add_x_infl, 4 ],
- [ vm_eco_glasnost ],
- [ vm_return ],
-]
-
-CODE[40] = [ // Hungarian Democratic Forum
- [ vm_valid_spaces_country, 'Hungary' ],
- [ vm_prompt, 'Hungary' ],
- [ vm_add_infl_free, 3 ],
- [ vm_valid_spaces_country_sc, 'Hungary' ],
- [ vm_prompt, 'make a Support Check in Hungary' ],
- [ vm_1_support_check ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[41] = [ // Ceausescu*
- [ vm_if, ()=>!game.the_tyrant_is_gone ],
- [ vm_valid_spaces_country_opp, 'Romania' ],
- [ vm_prompt, ' from Romania' ],
- [ vm_remove_opp_infl, 3 ],
- [ vm_valid_spaces_country_sc, 'Romania' ],
- [ vm_prompt, 'make a support check in Romania' ],
- [ vm_1_support_check ],
- [ vm_prompt, ' from Bucharesti' ],
- [ vm_ceausescu ],
- [ vm_endif ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[42] = [ // Power Struggle - East Germany
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[43] = [ // Power Struggle - Bulgaria
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[44] = [ // Inflationary Currency
- [ vm_inflationary_currency ],
- [ vm_valid_spaces_country_opp ],
- [ vm_prompt, ()=>` from ${country_name(game.vm_active_country)}` ],
- [ vm_remove_opp_infl, 2 ],
- [ vm_inflationary_currency_discard ],
- [ vm_if, ()=>!discarded_card() ],
- [ vm_valid_spaces_country_sc ],
- [ vm_prompt, ()=>`make a Support Check in ${country_name(game.vm_active_country)}` ],
- [ vm_1_support_check ],
- [ vm_endif ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[45] = [ // Soviet Troop Withdrawals*
- [ vm_valid_spaces_region_opp, 'Eastern Europe' ],
- [ vm_prompt, ' from Eastern Europe' ],
- [ vm_remove_limited_opp_infl, 5, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[46] = [ // Goodbye Lenin!*
- [ vm_goodbye_lenin ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[47] = [ // Bulgarian Turks Expelled*
- [ vm_bulgarian_turks_expelled ],
- [ vm_prompt, 'Razgrad' ],
- [ vm_remove_all_infl, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[48] = [ // We are the People!*
- [ vm_we_are_the_people ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[49] = [ // Foreign Currency Debt Burden*
- [ vm_foreign_currency_debt_burden ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[50] = [ // The Sinatra Doctrine*
- [ vm_the_sinatra_doctrine ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[51] = [ // 40th Anniversary Celebration*
- [ vm_40th_anniversary_celebration ],
- [ vm_valid_spaces_country, 'East_Germany' ],
- [ vm_prompt, 'East Germany' ],
- [ vm_add_infl_free ],
- [ vm_40th_anniversary_celebration_vp ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[52] = [ // Normalisation
- [ vm_normalisation ],
- [ vm_prompt, 'the Czechoslovakia Elite and Bureaucrat Spaces' ],
- [ vm_remove_all_infl, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[53] = [ // Li Peng*
- [ vm_li_peng ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[54] = [ // The Crowd Turns Against Ceausescu*
- [ vm_the_crowd_turns_against_ceausescu ],
- [ vm_return ],
-]
-
-CODE[55] = [ // Power Struggle - Czechoslovakia
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[56] = [ // Foreign Television
- [ vm_foreign_television ],
- [ vm_remove_limited_opp_infl, 4, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[57] = [ // Central Committee Reshuffle*
- [ vm_central_committee_reshuffle ],
- [ vm_prompt, ()=>`${country_name(game.vm_active_country)}` ],
- [ vm_add_infl_free, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[58] = [ // Austria-Hungary Border Reopened*
- [ vm_austria_hungary_border_reopened ],
- [ vm_return ],
-]
-
-CODE[59] = [ // GrenzTruppen*
- [ vm_grenztruppen ],
- [ vm_return ],
-]
-
-CODE[60] = [ // Toxic Waste*
- [ vm_valid_spaces_socio, 4 ],
- [ vm_prompt, 'any Worker space(s)' ],
- [ vm_add_infl_free, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[61] = [ // The Monday Demonstrations*
- [ vm_the_monday_demonstrations ],
- [ vm_prompt, 'the Lutheran Church Space and Leipzig' ],
- [ vm_take_control_prep, 2 ],
- [ vm_valid_spaces_country_sc, 'East_Germany' ],
- [ vm_prompt, 'make 5 Support Checks in East Germany' ],
- [ vm_support_check, 5 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[62] = [ // Yakovlev Counsels Gorbachev*
- [ vm_yakovlev_counsels_gorbachev ],
- [ vm_return ],
-]
-
-CODE[63] = [ // Genscher*
- [ vm_genscher ],
- [ vm_return ],
-]
-
-CODE[64] = [ // Legacy of 1968*
- [ vm_legacy_of_1968 ],
- [ vm_prompt, 'all spaces in Czechoslovakia not controlled by the Communist Player' ],
- [ vm_add_limited_infl, 11, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[65] = [ // Presidential Visit*
- [ vm_presidential_visit ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[66] = [ // New Forum
- [ vm_valid_spaces_country, 'East_Germany' ],
- [ vm_prompt, '3 spaces in East Germany' ],
- [ vm_add_limited_infl, 3, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[67] = [ // Reformer Rehabilitated*
- [ vm_prompt, 'Reformer Rehabilitated: chose any non-scoring card in the discard pile. Event takes place immediately' ],
- [ vm_reformer_rehabilitated ],
- [ vm_return ],
-]
-
-CODE[68] = [ // Klaus and Komarek*
- [ vm_klaus_and_komarek ],
- [ vm_prompt, 'Prague' ],
- [ vm_remove_x_opp_infl, 2 ],
- [ vm_valid_spaces, 29 ],
- [ vm_add_x_infl, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[69] = [ // Systematization*
- [ vm_valid_spaces_country, 'Romania' ],
- [ vm_systematization ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[70] = [ // Securitate*
- [ vm_securitate ],
- [ vm_return ],
-]
-
-CODE[71] = [ // Kiss of Death*
- [ vm_permanently_remove ],
- [ vm_kiss_of_death ],
- [ vm_return ],
-]
-
-CODE[72] = [ // Peasant Parties Revolt
- [ vm_peasant_parties_revolt ],
- [ vm_return ],
-]
-
-CODE[73] = [ // Laszlo Tokes*
- [ vm_valid_spaces, 50, 56 ],
- [ vm_prompt, 'in Timisoara and Harghita/Covasna' ],
- [ vm_add_limited_infl, 2, 1 ],
- [ vm_laszlo_tokes ],
- [ vm_if, ()=>game.phase === 3 ],
- [ vm_prompt, ' in Romania' ],
- [ vm_add_infl ],
- [ vm_else ],
- [ vm_prompt, 'make 2 Support Checks in Romania' ],
- [ vm_support_check, 2 ],
- [ vm_endif ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[74] = [ // FRG Embassies
- [ vm_frg_embassies ],
- [ vm_return ],
-]
-
-CODE[75] = [ // Exit Visas*
- [ vm_exit_visas ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[76] = [ // Warsaw Pact Summit
- [ vm_warsaw_pact_summit ],
- [ vm_if, ()=>game.phase === 3 ],
- [ vm_prompt, ' spaces with no Democratic SPs' ],
- [ vm_add_infl_free, 4 ],
- [ vm_else ],
- [ vm_prompt, 'Select a Student or Intellectual space' ],
- [ vm_valid_spaces_country_socio_2, 3,, 4 ],
- [ vm_support_check_modified, 2, 2 ],
- [ vm_endif ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[77] = [ // Samizdat
- [ vm_samizdat ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[78] = [ // Workers Revolt
- [ vm_workers_revolt ],
- [ vm_return ],
-]
-
-CODE[79] = [ // The Third Way*
- [ vm_the_third_way ],
- [ vm_valid_spaces, 4 ],
- [ vm_prompt, 'the East German Writers space' ],
- [ vm_add_x_infl, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[80] = [ // Nepotism*
- [ vm_nepotism ],
- [ vm_valid_spaces_region_socio, 'Balkans', 4 ],
- [ vm_prompt, 'Worker spaces in the Balkans' ],
- [ vm_add_infl_free ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[81] = [ // The Baltic Way*
- [ vm_the_baltic_way ],
- [ vm_prompt, 'any Minorities space' ],
- [ vm_take_control_prep, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[82] = [ // Spitzel*
- [ vm_valid_spaces_country_opp, 'East_Germany' ],
- [ vm_prompt, ' from East Germany' ],
- [ vm_remove_opp_infl, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[83] = [ // Modrow*
- [ vm_modrow ],
- [ vm_valid_spaces_country, 'East_Germany' ],
- [ vm_prompt, 'East Germany' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[84] = [ // Breakaway Baltic Republics*
- [ vm_breakaway_baltic_republics ],
- [ vm_prompt, 'any Minorities space' ],
- [ vm_take_control_prep, 1 ],
- [ vm_valid_spaces_sc ],
- [ vm_prompt, 'select a space for the support check' ],
- [ vm_1_support_check ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[85] = [ // Tank Column/Tank Man*
- [ vm_tank_column ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[86] = [ // The Wall Must Go!*
- [ vm_the_wall_must_go ],
- [ vm_remove_infl, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[87] = [ // Kohl Proposes Reunification*
- [ vm_kohl_proposes_reunification ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[88] = [ // Adamec*
- [ vm_adamec ],
- [ vm_valid_spaces_country, 'Czechoslovakia' ],
- [ vm_prompt, 'Czechoslovakia' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[89] = [ // Domino Theory*
- [ vm_prompt, 'Domino Theory: choose a Power Struggle card to play from the discard pile.' ],
- [ vm_domino_theory ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[90] = [ // Civic Forum*
- [ vm_valid_spaces_country, 'Czechoslovakia' ],
- [ vm_prompt, 'Czechoslovakia' ],
- [ vm_add_infl_free, 4 ],
- [ vm_civic_forum ],
- [ vm_valid_spaces_country_sc, 'Czechoslovakia' ],
- [ vm_prompt, 'Select a space in Czechoslovakia' ],
- [ vm_support_check, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[91] = [ // My First Banana*
- [ vm_valid_spaces_country_opp, 'East_Germany' ],
- [ vm_prompt, ' from East Germany' ],
- [ vm_remove_opp_infl, 2 ],
- [ vm_valid_spaces_country_sc, 'East_Germany' ],
- [ vm_prompt, 'select a space in East Germany' ],
- [ vm_support_check, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[92] = [ // Betrayal
- [ vm_prompt, 'choose any Orthodox Church space. Replace all Democratic SPs with Communist SPs' ],
- [ vm_betrayal ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[93] = [ // Shock Therapy*
- [ vm_shock_therapy ],
- [ vm_valid_spaces_country ],
- [ vm_prompt, ()=>` ${country_name(game.vm_active_country)}` ],
- [ vm_add_infl_free, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[94] = [ // Union of Democratic Forces*
- [ vm_valid_spaces_country_opp, 'Bulgaria' ],
- [ vm_prompt, ' from Bulgaria' ],
- [ vm_remove_opp_infl, 4 ],
- [ vm_valid_spaces_country_sc, 'Bulgaria' ],
- [ vm_prompt, 'Make 2 Support Checks in Bulgaria' ],
- [ vm_support_check, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[95] = [ // Power Struggle - Romania
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[96] = [ // The Chinese Solution*
- [ vm_the_chinese_solution ],
- [ vm_valid_spaces_country_sc ],
- [ vm_prompt, ()=>`Make 5 Support Checks in ${country_name(game.vm_active_country)}` ],
- [ vm_support_check_modified, 5, 3 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[97] = [ // The Tyrant is Gone*
- [ vm_if, ()=>game.persistent_events['the_crowd_turns_against_ceausescu'] ],
- [ vm_valid_spaces, 51 ],
- [ vm_prompt, 'the Romanian Elite Space' ],
- [ vm_remove_x_opp_infl, 4 ],
- [ vm_the_tyrant_is_gone ],
- [ vm_permanently_remove ],
- [ vm_else ],
- [ vm_the_tyrant_is_gone_prep ],
- [ vm_endif ],
- [ vm_return ],
-]
-
-CODE[98] = [ // Politburo Intrigue*
- [ vm_valid_spaces_country_opp, 'Bulgaria' ],
- [ vm_prompt, ' from Bulgaria' ],
- [ vm_remove_limited_opp_infl, 3, 2 ],
- [ vm_valid_spaces_country_sc, 'Bulgaria' ],
- [ vm_prompt, 'make a support check in Bulgaria' ],
- [ vm_1_support_check ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[99] = [ // Ligachev*
- [ vm_ligachev ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[100] = [ // Stand Fast*
- [ vm_stand_fast ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[101] = [ // Elena*
- [ vm_if, ()=>!game.the_tyrant_is_gone ],
- [ vm_valid_spaces, 51 ],
- [ vm_prompt, 'the Romania Elite Space' ],
- [ vm_add_x_infl, 2 ],
- [ vm_endif ],
- [ vm_elena ],
- [ vm_return ],
-]
-
-CODE[102] = [ // National Salvation Front*
- [ vm_national_salvation_front ],
- [ vm_return ],
-]
-
-CODE[103] = [ // Government Resigns*
- [ vm_government_resigns ],
- [ vm_prompt, 'any uncontrolled Elite space' ],
- [ vm_remove_all_infl, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[104] = [ // New Year's Eve Party*
- [ vm_new_years_eve_party ],
- [ vm_return ],
-]
-
-CODE[105] = [ // Public Against Violence*
- [ vm_valid_spaces, 36, 37 ],
- [ vm_prompt, 'Kosice and Presov' ],
- [ vm_add_x_infl, 2 ],
- [ vm_valid_spaces, 36, 37 ],
- [ vm_add_x_infl, 2 ],
- [ vm_public_against_violence ],
- [ vm_prompt, 'Make a Support Check in Bratislava' ],
- [ vm_support_check_modified, 1, 2 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[106] = [ // Social Democratic Platform Adopted*
- [ vm_social_democratic_platform_adopted ],
- [ vm_valid_spaces_country ],
- [ vm_prompt, ()=>`${country_name(game.vm_active_country)}` ],
- [ vm_add_infl_free, 2 ],
- [ vm_valid_spaces_country_sc ],
- [ vm_prompt, ()=>`make a Support Check in ${country_name(game.vm_active_country)}` ],
- [ vm_1_support_check ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[107] = [ // Massacre in Timisoara*
- [ vm_if, ()=>!game.the_tyrant_is_gone ],
- [ vm_massacre_in_timisoara ],
- [ vm_valid_spaces_country_sc, 'Romania' ],
- [ vm_prompt, 'Make Support Checks in Romania' ],
- [ vm_support_check_modified, 2, 2 ],
- [ vm_endif ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[108] = [ // Army Backs Revolution*
- [ vm_army_backs_revolution ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[109] = [ // Kremlin Coup*
- [ vm_kremlin_coup ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[110] = [ // Malta Summit*
- [ vm_malta_summit ],
- [ vm_prompt, ' from Elite spaces' ],
- [ vm_remove_opp_infl, 5 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-// #endregion
-
-
-// ============= TIANANMEN SQUARE TRACK AWARDS ====================
-CODE[203] = [//Tiananmen Square space 3 award
- [vm_tst_3],
- [vm_return]
-]
-CODE[204] = [//Tiananmen Square space 4 award
- [vm_valid_spaces_opponent],
- [vm_tst_4],
- [vm_return]
-]
-CODE[206] = [//Tiananmen Square space 6
- [vm_valid_spaces_sc],
- [vm_tst_6],
- [vm_return]
-]
-CODE[208] = [//Tiananmen Square space 8 event
- [vm_tst_8],
- [vm_return]
-]
-
-// ============= POWER STRUGGLE WILDCARDS =========================
-
-CODE[349] = [//Scare Tactics
- [vm_scare_tactics],
- [vm_valid_spaces_country_opp],
- [vm_prompt, ()=>` from ${country_name(game.vm_active_country)}`],
- [vm_remove_opp_infl, 1],
- [vm_return]
-]
-CODE[350] = [//Support Surges
- [vm_support_surges],
- [vm_return]
-]
-CODE[351] = [//Support Falters
- [vm_support_falters],
- [vm_return]
-]
+"use strict" + +// vim:set foldmethod=marker: + +const { spaces, cards, power_cards } = require("./data.js") + +var game, view, states = {} + +const DEM = "Democrat" +const COM = "Communist" + +const first_strategy_card = 1 +const last_strategy_card = 110 + +// BEGIN CONSTANTS {{{ + +// SPACES +const S_SCHWERIN = 0 +const S_ROSTOCK = 1 +const S_BERLIN = 2 +const S_GERMAN_WRITERS = 3 +const S_WALTER_ULBRICHT_ACADEMY = 4 +const S_LUTHERAN_CHURCH = 5 +const S_MAGDEBURG = 6 +const S_HALLE = 7 +const S_LEIPZIG = 8 +const S_ERFURT = 9 +const S_KARL_MARX_STADT = 10 +const S_DRESDEN = 11 +const S_SZCZECIN = 12 +const S_GDANSK = 13 +const S_BYDGOSZCZ = 14 +const S_POZNAN = 15 +const S_WARSZAWA = 16 +const S_BIALYSTOK = 17 +const S_WROCLAW = 18 +const S_CATHOLIC_CHURCH_POLAND = 19 +const S_LODZ = 20 +const S_KATOWICE = 21 +const S_KRAKOW = 22 +const S_LUBLIN = 23 +const S_JAGIELLONIAN_UNIVERSITY = 24 +const S_POLISH_WRITERS = 25 +const S_PLZEN = 26 +const S_CESKE_BUDEJOVICE = 27 +const S_PRAHA = 28 +const S_CHARLES_UNIVERSITY = 29 +const S_CZECH_WRITERS = 30 +const S_BRNO = 31 +const S_OSTRAVA = 32 +const S_BRATISLAVA = 33 +const S_CATHOLIC_CHURCH_CZECHOSLOVAKIA = 34 +const S_PRESOV = 35 +const S_KOSICE = 36 +const S_CATHOLIC_CHURCH_HUNGARY = 37 +const S_GYOR = 38 +const S_TATABANYA = 39 +const S_MISKOLC = 40 +const S_DEBRECEN = 41 +const S_SZOMBATHELY = 42 +const S_SZEKESFEHERVAR = 43 +const S_BUDAPEST = 44 +const S_HUNGARIAN_WRITERS = 45 +const S_EOTVOS_LORAND_UNIVERSITY = 46 +const S_SZEGED = 47 +const S_PECS = 48 +const S_TIMISOARA = 49 +const S_CLUJ_NAPOCA = 50 +const S_TARGU_MURES = 51 +const S_IASI = 52 +const S_BABES_BOLYAI_UNIVERSITY = 53 +const S_ROMANIAN_WRITERS = 54 +const S_HARGHITA_COVASNA = 55 +const S_BRASOV = 56 +const S_ORTHODOX_CHURCH_ROMANIA = 57 +const S_PLOIESTI = 58 +const S_CRAIOVA = 59 +const S_BUCURESTI = 60 +const S_GALATI = 61 +const S_CONSTANTA = 62 +const S_PLEVEN = 63 +const S_ORTHODOX_CHURCH_BULGARIA = 64 +const S_RUSE = 65 +const S_SOFIA_UNIVERSITY = 66 +const S_SOFIA = 67 +const S_STARA_ZAGORA = 68 +const S_RAZGRAD = 69 +const S_BURGAS = 70 +const S_VARNA = 71 +const S_BULGARIAN_WRITERS = 72 +const S_PLOVDIV = 73 +const S_SLIVEN = 74 + +// CARDS +const C_LEGACY_OF_MARTIAL_LAW = 1 +const C_SOLIDARITY_LEGALIZED = 2 +const C_WALESA = 3 +const C_MICHNIK = 4 +const C_GENERAL_STRIKE = 5 +const C_BROUGHT_IN_FOR_QUESTIONING = 6 +const C_STATE_RUN_MEDIA = 7 +const C_PRUDENCE = 8 +const C_THE_WALL = 9 +const C_CULT_OF_PERSONALITY = 10 +const C_DISSIDENT_ARRESTED = 11 +const C_APPARATCHIKS = 12 +const C_STASI = 13 +const C_GORBACHEV_CHARMS_THE_WEST = 14 +const C_HONECKER = 15 +const C_NOMENKLATURA = 16 +const C_ROUNDTABLE_TALKS = 17 +const C_POSZGAY_DEFENDS_THE_REVOLUTION = 18 +const C_PAPAL_VISIT = 19 +const C_DEUTSCHE_MARKS = 20 +const C_COMMON_EUROPEAN_HOME = 21 +const C_POWER_STRUGGLE_POLAND = 22 +const C_POWER_STRUGGLE_HUNGARY = 23 +const C_ST_NICHOLAS_CHURCH = 24 +const C_PERESTROIKA = 25 +const C_HELSINKI_FINAL_ACT = 26 +const C_CONSUMERISM = 27 +const C_FACTORY_PARTY_CELLS = 28 +const C_JAN_PALACH_WEEK = 29 +const C_TEAR_GAS = 30 +const C_INTELLIGENTSIA = 31 +const C_PEASANT_PARTIES = 32 +const C_SAJUDIS = 33 +const C_FIDESZ = 34 +const C_HEAL_OUR_BLEEDING_WOUND = 35 +const C_DASH_FOR_THE_WEST = 36 +const C_NAGY_REBURIED = 37 +const C_THE_JULY_CONCEPT = 38 +const C_ECO_GLASNOST = 39 +const C_HUNGARIAN_DEMOCRATIC_FORUM = 40 +const C_CEAUSESCU = 41 +const C_POWER_STRUGGLE_EAST_GERMANY = 42 +const C_POWER_STRUGGLE_BULGARIA = 43 +const C_INFLATIONARY_CURRENCY = 44 +const C_SOVIET_TROOP_WITHDRAWALS = 45 +const C_GOODBYE_LENIN = 46 +const C_BULGARIAN_TURKS_EXPELLED = 47 +const C_WE_ARE_THE_PEOPLE = 48 +const C_FOREIGN_CURRENCY_DEBT_BURDEN = 49 +const C_THE_SINATRA_DOCTRINE = 50 +const C_40TH_ANNIVERSARY_CELEBRATION = 51 +const C_NORMALIZATION = 52 +const C_LI_PENG = 53 +const C_THE_CROWD_TURNS_AGAINST_CEAUSESCU = 54 +const C_POWER_STRUGGLE_CZECHOSLOVAKIA = 55 +const C_FOREIGN_TELEVISION = 56 +const C_CENTRAL_COMMITTEE_RESHUFFLE = 57 +const C_AUSTRIA_HUNGARY_BORDER_REOPENED = 58 +const C_GRENZTRUPPEN = 59 +const C_TOXIC_WASTE = 60 +const C_THE_MONDAY_DEMONSTRATIONS = 61 +const C_YAKOVLEV_COUNSELS_GORBACHEV = 62 +const C_GENSCHER = 63 +const C_LEGACY_OF_1968 = 64 +const C_PRESIDENTIAL_VISIT = 65 +const C_NEW_FORUM = 66 +const C_REFORMER_REHABILITATED = 67 +const C_KLAUS_AND_KOMAREK = 68 +const C_SYSTEMATIZATION = 69 +const C_SECURITATE = 70 +const C_KISS_OF_DEATH = 71 +const C_PEASANT_PARTIES_REVOLT = 72 +const C_LASZLO_TOKES = 73 +const C_FRG_EMBASSIES = 74 +const C_EXIT_VISAS = 75 +const C_WARSAW_PACT_SUMMIT = 76 +const C_SAMIZDAT = 77 +const C_WORKERS_REVOLT = 78 +const C_THE_THIRD_WAY = 79 +const C_NEPOTISM = 80 +const C_THE_BALTIC_WAY = 81 +const C_SPITZEL = 82 +const C_MODROW = 83 +const C_BREAKAWAY_BALTIC_REPUBLICS = 84 +const C_TANK_COLUMN_TANK_MAN = 85 +const C_THE_WALL_MUST_GO = 86 +const C_KOHL_PROPOSES_REUNIFICATION = 87 +const C_ADAMEC = 88 +const C_DOMINO_THEORY = 89 +const C_CIVIC_FORUM = 90 +const C_MY_FIRST_BANANA = 91 +const C_BETRAYAL = 92 +const C_SHOCK_THERAPY = 93 +const C_UNION_OF_DEMOCRATIC_FORCES = 94 +const C_POWER_STRUGGLE_ROMANIA = 95 +const C_THE_CHINESE_SOLUTION = 96 +const C_THE_TYRANT_IS_GONE = 97 +const C_POLITBURO_INTRIGUE = 98 +const C_LIGACHEV = 99 +const C_STAND_FAST = 100 +const C_ELENA = 101 +const C_NATIONAL_SALVATION_FRONT = 102 +const C_GOVERNMENT_RESIGNS = 103 +const C_NEW_YEARS_EVE_PARTY = 104 +const C_PUBLIC_AGAINST_VIOLENCE = 105 +const C_SOCIAL_DEMOCRATIC_PLATFORM_ADOPTED = 106 +const C_MASSACRE_IN_TIMISOARA = 107 +const C_ARMY_BACKS_REVOLUTION = 108 +const C_KREMLIN_COUP = 109 +const C_MALTA_SUMMIT = 110 + +// END CONSTANTS }}} + +const dem_tst_req = [5, 5, 6, 6, 7, 8, 9, 10] +const com_tst_req = [6, 6, 7, 7, 8, 7, 6, 5] +const scoring_cards = [22, 23, 42, 43, 55, 95] +const leader_cards = [37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48] +const rallies = [1, 2, 3, 4, 5, 6] +const petitions = [31, 32, 33, 34, 35, 36] +const wildcards = [49, 50, 51, 52] +const elite_leaders = [37, 38, 39, 40] +const leaders = [1, 4, 5, 6, 7] +const support_loss_roll = [0, 0, 1, 1, 2, 2, 3, 4] +const vp_roll = [0, 0, 1, 1, 2, 2, 3, 4] +const countries = ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania'] +const elite_spaces = [11, 14, 26, 42, 50, 68] +const all_power_cards = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 ] +const numberless_cards = [1, 2, 3, 4, 5, 6, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 ] +const auto_resolve_events = [5, 8, 9, 13, 17, 25, 26, 30, 35, 50, 53, 54, 58, 59, 62, 63, 65, 70, 72, 74, 86, 99, 102, 108] +const switch_events = [6, 20, 71] +const one_turn_events = [ 8, 13, 25, 50, 63, 74, 49, 58, 59, 100, 101 ] +const dem_asterisks = [2, 3, 4, 5, 19, 24, 26, 29, 33, 34, 36, 39, 40, 45, 46, 48, 49, 50, 54, 56, 58, 60, 61, 62, 63, 64, 65, 66, 68, 71, 72, 73, 74, 75, 77, 81, 84, 86, 87, 89, 90, 91, 93, 94, 97, 103, 105, 108, 110] + +const PC_TACTIC_FAILS = 52 +const PC_SUPPORT_FALTERS = 49 +const THE_CROWD_TURNS_AGAINST_CEAUSESCU_OCCURRED = 540 +const THE_TYRANT_IS_GONE_OCCURRED = 970 + +// COUNTRY CONSTANTS + +const S_EAST_GERMANY = [0,1,2,3,4,5,6,7,8,9,10,11] +const S_POLAND = [12,13,14,15,16,17,18,19,20,21,22,23,24,25] +const S_CZECHOSLOVAKIA = [26,27,28,29,30,31,32,33,34,35,36] +const S_HUNGARY = [37,38,39,40,41,42,43,44,45,46,47,48] +const S_ROMANIA = [49,50,51,52,53,54,55,56,57,58,59,60,61,62] +const S_BULGARIA = [63,64,65,66,67,68,69,70,71,72,73,74] + +exports.scenarios = [ "Standard" ] + +exports.roles = [ DEM, COM ] + +// --- SET UP --- + +exports.setup = function (seed, scenario, options) { + game = { + seed: seed, + log: [], + undo: [], + summary: [], + active: null, + state: 'place_starting_infl', + state: 'place_starting_infl', + return: '', + vm: null, + vm_event: 0, + + played_card: 0, + available_ops: 0, + vm_available_ops: 0, + valid_spaces: [], + valid_cards: [], + + vp: 0, + turn: 0, + round: 0, + round_player: COM, + stability: 0, + dem_tst_position: 0, + com_tst_position: 0, + dem_tst_attempted: 0, + com_tst_attempted: 0, + dem_tst_attempted_this_turn: 0, + com_tst_attempted_this_turn: 0, + + demInfl: [], + comInfl: [], + + strategy_deck: [], + strategy_discard: [], + discard: false, + view_opp_hand: false, + strategy_removed: [], + persistent_events: [], + power_struggle_deck: [], + power_struggle_discard: [], + dem_hand_limit: 8, + com_hand_limit: 8, + democrat_hand: [], + communist_hand: [], + + is_pwr_struggle: false, + dem_pwr_hand_limit: 0, + com_pwr_hand_limit: 0, + dem_pwr_hand: [], + com_pwr_hand: [], + times_held: [0, 0, 0, 0, 0, 0], + revolutions: [false, false, false, false, false, false], + } + + log_h1("1989 Dawn of Freedom") + game.active = COM + start_game() + return game +} + +function start_game() { + // Draw cards + game.strategy_deck = draw_deck() + + //Set starting influence + spaces.forEach((space, index) => { + game.demInfl[index] = space.demInfl + game.comInfl[index] = space.comInfl + }) + + //Set starting placement ops + game.starting_infl = [2, 3, 3, 4, 2] + game.temp = 0 + + // Set variable event cards where event is playable at start of game + + game.playable_cards = [C_THE_WALL, C_GORBACHEV_CHARMS_THE_WEST, C_HONECKER, C_COMMON_EUROPEAN_HOME, C_MALTA_SUMMIT] + + draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.dem_hand_limit, game.com_hand_limit) + + valid_spaces_setup() + game.available_ops = 2 + log_h1("Place starting Support Points") + log_side() +} + +exports.view = function(state, player) { + game = state + + view = { + log: game.log, + active: game.active, + prompt: null, + actions: null, + + played_card: game.played_card, + valid_spaces: game.valid_spaces, + valid_cards: game.valid_cards, + + demInfl: game.demInfl, + comInfl: game.comInfl, + turn: game.turn, + round: game.round, + round_player: game.round_player, + vp: game.vp, + stability: game.stability, + dem_tst: game.dem_tst_position, + com_tst: game.com_tst_position, + persistent_events: game.persistent_events, + systematization: game.systematization, + the_tyrant_is_gone: game.the_tyrant_is_gone, + + strategy_deck: game.strategy_deck.length, + strategy_removed: game.strategy_removed, + discard: game.discard, + show_opp_hand: game.view_opp_hand, /* Is this still needed?*/ + + democrat_hand: game.democrat_hand.length, + communist_hand: game.communist_hand.length, + democrat_power_hand: game.dem_pwr_hand.length, + communist_power_hand: game.com_pwr_hand.length, + ceausescu_cards: game.ceausescu_cards, + is_pwr_struggle: game.is_pwr_struggle, + times_held: game.times_held, + revolutions: game.revolutions, + + hand: [], + set_aside: [], + pwr_hand: [], + } + + if (game.is_pwr_struggle) { + view.power_struggle_discard = game.power_struggle_discard + view.played_power_card = game.played_power_card + view.power_card_1 = game.power_card_1 + view.power_card_2 = game.power_card_2 + } + view.strategy_discard = game.strategy_discard + + + if (player === game.active && game.vm && game.vm.draw) + view.drawn = game.vm.draw + + if (player === game.active) { + if (game.selected_space >= 0) + view.selected_space = game.selected_space + } + + if (player === DEM) { + view.hand = game.democrat_hand + if (game.communist_hand_red) { + view.opp_hand = game.communist_hand_red + } + view.set_aside = game.democrat_set_aside /*Is this being used? */ + view.power_hand = [...game.dem_pwr_hand].sort((a, b) => a - b) + + } else if (player === COM) { + view.hand = game.communist_hand + if (game.opp_power_hand && game.pwr_struggle_in === 'Romania') {view.opp_power_hand = [...game.dem_pwr_hand].sort((a, b) => a - b) } + view.power_hand = [...game.com_pwr_hand].sort((a, b) => a - b) + } + + if (player === DEM) { + view.samizdat = game.samizdat_card + } + + if (game.state === "game_over") { + view.prompt = game.victory + } else if (player === "Observer" || (game.active !== player && game.active !== "Both")) { + if (states[game.state]) { + let inactive = states[game.state].inactive + if (typeof inactive === "function") + view.prompt = `Waiting for ${game.active} ${inactive()}` + else + view.prompt = `Waiting for ${game.active} to ${inactive}` + } else { + view.prompt = "A Unknown state: " + game.state + } + } else { + view.actions = {} + + if (states[game.state]) + states[game.state].prompt(player) + else + view.prompt = "B Unknown state: " + game.state + if (view.actions.undo === undefined) { + if (game.undo && game.undo.length > 0) + view.actions.undo = 1 + else + view.actions.undo = 0 + } + } + return view +} + +// === ACTIONS =========== + +function gen_action(action, argument) { + if (argument === undefined) { + view.actions[action] = 1 + } else { + if (!(action in view.actions)) { + view.actions[action] = [] + } + view.actions[action].push(argument) + } +} + +function gen_action_space(space){ + gen_action("space", space) +} + +function gen_action_card(card){ + gen_action("card", card) +} + +function gen_action_power_card(card){ + gen_action("power_card", card) +} + +exports.action = function (state, player, action, arg) { + game = state + if (states[game.state] && action in states[game.state]) { + states[game.state][action](arg, player) + } else { + if (action === "undo" && game.undo && game.undo.length > 0) + pop_undo() + else + throw new Error("Invalid action: " + action) + } + return game +} + +// ============= GAME STATES ======================= + +states.place_starting_infl = { + inactive: 'place starting SPs.', + prompt() { + if (game.temp === 4 && game.available_ops === 0 ) { + view.prompt = 'Place starting SPs: done. Start Turn 1.'; + gen_action("start"); + } else if (game.available_ops === 0) { + view.prompt = 'Place starting SPs: done.'; + gen_action("done"); + return; + } else if (game.temp > 2) { + view.prompt = `Place your last ${pluralize(game.available_ops,'starting SP')}.` + } else { + view.prompt = `Place ${pluralize(game.available_ops,'starting SP')}.` + } + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + }, + space(space) { + add_infl(space, 'available_ops') + }, + done() { + do_log_summary() + game.temp ++ + game.available_ops = game.starting_infl[game.temp] + next_player() + valid_spaces_setup() + }, + start() { + do_log_summary() + delete game.starting_infl + new_turn() + clear_undo() + game.state = 'choose_card' + } +} + +states.choose_card = { + inactive: 'choose a card.', + prompt() { + if ((game.active===DEM && game.democrat_hand.length === 0) || game.active === COM && game.communist_hand.length === 0) { + view.prompt = 'No cards remaining: you must pass.' + gen_action('pass') + } else { + view.prompt = 'Choose a card.' + let available_cards + if (game.active === DEM) { + available_cards = game.democrat_hand + } else { + available_cards = game.communist_hand + } + for (let card of available_cards) { + gen_action_card(card) + } + } + }, + card(card) { + push_undo() + + //Check if player is at risk of losing game due to held scoring card + if (!scoring_cards.includes(card)) { + let scoring_cards_count = count_scoring_cards() + + if (game.round !== 8 && scoring_cards_count >= (8-game.round)){ + game.temp = card + game.state = 'confirm_card' + return + } + } + select_card(card) + }, + pass() { + log('No cards remaining. Passed') + game.state = 'end_round' + } +} + +states.confirm_card = { + inactive: 'choose a card.', + prompt() { + let scoring_cards_count = count_scoring_cards() + view.prompt = `${pluralize(scoring_cards_count,'scoring card')} in hand with ${pluralize(8-game.round,'Action Round')} remaining. Scoring cards may not be held. Continue?` + gen_action('continue') + }, + continue() { + select_card(game.temp) + } +} + +states.play_card ={ + get inactive() { + return `play ${clean_name(cards[game.played_card].name)}.` + }, + prompt () { + view.prompt = `Play ${clean_name(cards[game.played_card].name)} for:` + + if (scoring_cards.includes(game.played_card)) { + gen_action('event') + return + } + + // Check for Reformer Rehabilitated + if (game.played_card === C_REFORMER_REHABILITATED && game.playable_cards.includes(C_REFORMER_REHABILITATED)){ + if (game.active === DEM && (game.dem_tst_position > game.com_tst_position)) { + gen_action('event') + } + if (game.active === COM && (game.dem_tst_position < game.com_tst_position)) { + gen_action('event') + } + } + + //Check for events + if (event_is_playable(game.played_card)) { + if ((game.active === DEM && cards[game.played_card].side === 'C' && game.dem_tst_position >= 7 && game.com_tst_position < 7 && !game.tst_7) || (game.active === COM && cards[game.played_card].side === 'D' && game.com_tst_position >= 7 && game.dem_tst_position < 7 && !game.tst_7)){ + gen_action('tst_7') + } + if ((game.active === DEM && cards[game.played_card].side !== 'C' && game.dem_tst_position >= 8 && game.com_tst_position < 8 && !game.tst_8) || (game.active === COM && cards[game.played_card].side !== 'D' && game.com_tst_position >= 8 && game.dem_tst_position < 8 && !game.tst_8)){ + gen_action('tst_8') + } + + //Continue with normal logic + get_events(game.played_card) + } + + gen_action('influence') + gen_action('support_check') + + if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 && game.dem_tst_position < 8 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 && game.com_tst_position < 8)) { + gen_action('tst') + } + }, + event() { + push_undo() + log_gap(`Played C${game.played_card} for the event`) + game.vm_infl_to_do = false + game.return = game.active + if (switch_events.includes(game.played_card)) {next_player()} + game.vm_event = game.played_card + goto_vm(game.vm_event) + }, + opp_event() { + push_undo() + log_gap(`Played C${game.played_card} for the event`) + game.vm_infl_to_do = true + game.return = game.active + game.vm_event = game.played_card + if (is_auto_resolve(game.played_card) || switch_events.includes(game.played_card)) { + goto_vm(game.vm_event)} + else { + next_player() + log(`C${game.vm_event}:`) + goto_vm(game.vm_event) + } + }, + influence() { + push_undo() + log_gap(`Played C${game.played_card} to place SPs`) + finish_play_card() + + // If ABHR - Set AHBR tracker to true + if (game.persistent_events.includes(58)) { + game.austria_hungary_border_reopened_tracker = true + } + game.state='add_influence' + valid_spaces_infl() + }, + tst() { + push_undo() + log_gap(`Played C${game.played_card} to the Tiananmen Square Track`) + finish_play_card() + game.state='tiananmen_square_attempt' + }, + support_check() { + push_undo() + log_gap(`Played C${game.played_card} for support checks`) + finish_play_card() + game.available_ops = 2 + game.state='support_check_prep' + valid_spaces_sc() + }, + tst_7() { /*Cancel opponent event */ + push_undo() + log(`Played C${game.played_card}. Event cancelled using TST Award`) + game.tst_7 = true + game.vm_infl_to_do = true + game.state = 'resolve_opponent_event' + }, + tst_8() { /*Play card for ops and event */ + push_undo() + game.vm_event_to_do = true + game.vm_infl_to_do = true + game.tst_8 = true + log(`Played C${game.played_card} for event and operations`) + game.state = 'vm_tst_8' + }, + end_round () { + end_round() + } +} + +states.resolve_opponent_event = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (game.vm_infl_to_do) { + view.prompt = 'Event resolved. Choose to play card for:' + gen_action('influence') + gen_action('support_check') + } else if (game.vm_event_to_do) { + // Check for Tiananmen Square Track ability - play opponent card without triggering event + if ((game.active === DEM && game.dem_tst_position >= 7 && game.com_tst_position < 7 && !game.tst_7) || (game.active === COM && game.com_tst_position >= 7 && game.dem_tst_position < 7 && !game.tst_7)){ + gen_action('tst_7') + } + view.prompt = `${clean_name(cards[game.played_card].name)}: you must resolve the opponent event.` + gen_action('opp_event') + } else { + view.prompt = 'Event resolved. End the action round.' + gen_action('end_round') + } + }, + influence(){ + push_undo() + // If ABHR - Set AHBR tracker to true + if (game.persistent_events.includes(58)) { + game.austria_hungary_border_reopened_tracker = true + } + game.state = 'add_influence' + valid_spaces_infl() + }, + support_check() { + push_undo() + game.available_ops = 2 + game.state = 'support_check_prep' + valid_spaces_sc() + }, + opp_event() { + game.vm_event_to_do = false + game.return_state = 'resolve_opponent_event' + game.vm_event = game.played_card + log(`Played C${game.played_card} for the event`) + if (is_auto_resolve(game.played_card) || switch_events.includes(game.played_card)) { + game.return = game.active + goto_vm(game.vm_event)} + else { + if (game.active === DEM) { + game.return = COM + } else { + game.return = DEM + } + next_player() + log(`C${game.played_card}:`) + goto_vm(game.vm_event) + } + }, + tst_7() { + push_undo() + log('Event cancelled using TST Award') + game.tst_7 = true + game.vm_event_to_do = false + }, + end_round() { + push_undo() + end_round() + } +} + +states.add_influence = { + inactive: 'add SPs.', + prompt () { + if (game.available_ops <= 0) { + view.prompt = 'Place SPs: done.' + if (!game.vm_event_to_do) { + gen_action("end_round") + } else { + gen_action('done') + } + } else { + view.prompt = `Add SPs: ${game.available_ops} remaining.` + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } + }, + space(space) { + add_infl(space, 'available_ops') + }, + end_round() { + push_undo() + do_log_summary() + end_round() + }, + done() { + do_log_summary() + reset_austria_hungary_border_reopened() + game.state = 'resolve_opponent_event' + } +} + +states.tiananmen_square_attempt = { + inactive: 'do Tiananmen Square Attempt.', + prompt () { + view.prompt = 'Tiananmen Square Track attempt: Roll a die.' + gen_action('roll') + }, + roll() { + clear_undo() + game.vm_event_to_do = false + do_tst_attempt () + } +} + +states.tiananmen_square_attempt_success = { + inactive: 'do Tiananmen Square Attempt.', + prompt () { + if (game.vm_event > 200) { + view.prompt = 'Tiananmen Square Track attempt successful. Go to TST Award.' + gen_action('done') + } else { + view.prompt = 'Tiananmen Square Track attempt successful.' + gen_action('end_round') + } + + }, + done () { + push_undo() + goto_vm(game.vm_event) + }, + end_round () { + push_undo() + end_round() + } +} + +states.tiananmen_square_attempt_fail = { + inactive: 'do Tiananmen Square Attempt.', + prompt () { + view.prompt = 'Tiananmen Square Track attempt failed.' + gen_action('end_round') + }, + end_round () { + push_undo() + end_round() + } +} + +states.tiananmen_square_attempt_done = { + inactive: 'do Tiananmen Square Attempt.', + prompt () { + view.prompt = 'Tiananmen Square Track attempt: done.' + gen_action('end_round') + }, + end_round () { + end_round() + } +} + +states.tst_goddess = { + inactive: 'choose whether to discard a card.', + prompt() { + view.prompt = 'Tiananmen Square Track award: you may discard a non-Power Struggle Card and draw a replacement.' + for (let card of game.valid_cards) { + gen_action_card(card) + } + gen_action('pass') + }, + card(card) { + push_undo() + discard(card) + game.valid_cards = [] + game.state = 'tst_goddess_draw' + }, + pass() { + log('Did not discard') + end_goddess() + }, +} + +states.tst_goddess_draw = { + inactive: 'choose whether to discard a card.', + prompt() { + view.prompt = 'Draw a replacement card.' + gen_action('draw') + }, + draw() { + if (game.active === DEM) { + draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length +1, game.communist_hand.length) + } else { + draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length +1) + } + end_goddess() + } +} + +states.support_check_prep = { + inactive: 'do support checks', + prompt () { + if (game.available_ops === 0) { + if (game.is_pwr_struggle) { + view.prompt = 'The Crowd Turns Against Ceausescu. Support checks: done.' + gen_action('done') + } else if (!game.vm_event_to_do) { + view.prompt = 'Support checks: done.' + gen_action('end_round') + } else { + view.prompt = 'Support checks: done.' + gen_action('done') + } + } else if (game.available_ops > 0) { + view.prompt = `Select a space. ${pluralize(game.available_ops, 'support check')} remaining.` + for (let space_id of game.valid_spaces) { + gen_action_space(space_id) + } + } + }, + space(space) { + push_undo() + game.selected_space = space + + // Check for Austria-Hungary Border Reopened - check on first support check only + if (game.persistent_events.includes(58)) { + if (game.active === DEM && game.available_ops > 1) { + if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) { + game.state = 'austria_hungary_border_reopened_check' + return + } + } + } + + game.state = 'do_support_check' + }, + end_round() { + push_undo() + end_round() + }, + done() { + push_undo() + if (game.is_pwr_struggle) {/*Crowd Turns Against Ceausescu should be the only time you end up here during a power struggle */ + if (game.return !== game.active) { + next_player() + } + log_h2('Raise the Stakes') + game.state = 'raise_stakes_1' + return + } + reset_austria_hungary_border_reopened() + game.state = 'resolve_opponent_event' + } +} + +states.do_support_check = { + inactive: 'do support checks.', + prompt () { + view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.` + gen_action('roll') + }, + roll() { + clear_undo() + do_sc(game.selected_space) + game.available_ops-- + if (game.available_ops === 0) { + game.valid_spaces = [] + } + if (check_vp()) { + return + } else { + game.state = 'support_check_prep' + return + } + } +} + +states.austria_hungary_border_reopened_check = { + inactive: 'decide Austria-Hungary Border Reopened.', + prompt() { + view.prompt = 'Austria-Hungary Border Reopened: will both support checks be in East Germany?' + gen_action('yes') + gen_action('no') + }, + yes() { + game.austria_hungary_border_reopened_tracker = true + game.state = 'do_support_check' + }, + no() { + game.state = 'do_support_check' + } +} + +states.end_round = { + inactive: 'finish playing a card.', + prompt() { + view.prompt = 'End the Action Round.' + gen_action('end_round') + }, + end_round() { + push_undo() + end_round() + } +} + +//======================= POWER STRUGGLE =============================== + +states.draw_power_cards = { + inactive: 'draw cards.', + prompt() { + view.prompt = `${clean_name(cards[this_card()].name)}: draw cards.` + gen_action('draw') + }, + draw() { + push_undo() + game.power_struggle_deck = [...all_power_cards] + let presence = check_presence(game.pwr_struggle_in) + if (presence.dem_spaces > 0) { + game.dem_pwr_hand_limit = 6 + 2*(presence.dem_spaces - 1) + } else { + game.dem_pwr_hand_limit = 0 + } + if (presence.com_spaces > 0 ) { + game.com_pwr_hand_limit = 6 + 2*(presence.com_spaces - 1) + } else { + game.com_pwr_hand_limit = 0 + } + // Events which affect cards drawn + if (game.persistent_events.includes(C_ROUNDTABLE_TALKS) && game.com_pwr_hand_limit >= 2) { + log(`Democrat receives 2 cards from Communist due to C${C_ROUNDTABLE_TALKS}`) + game.dem_pwr_hand_limit += 2 + game.com_pwr_hand_limit -= 2 + game.persistent_events = game.persistent_events.filter(n => n !== C_ROUNDTABLE_TALKS) + game.strategy_discard.push(C_ROUNDTABLE_TALKS) + } + + if (game.persistent_events.includes(C_PEASANT_PARTIES_REVOLT)) { + let farmer_check + for (let space of spaces) { + if (space && space.country === game.pwr_struggle_in && space.socio === 3 && check_dem_control(space.space_id)) { + farmer_check = true + } + } + if (farmer_check && game.com_pwr_hand_limit > 0) { + log(`Democrat receives 1 cards from Communist due to C${C_PEASANT_PARTIES_REVOLT}`) + game.dem_pwr_hand_limit += 1 + game.com_pwr_hand_limit -= 1 + permanently_remove(C_PEASANT_PARTIES_REVOLT) + } + } + + if (game.persistent_events.includes(C_NATIONAL_SALVATION_FRONT) && game.dem_pwr_hand_limit >=2 && (game.pwr_struggle_in === 'Romania' || game.pwr_struggle_in === 'Bulgaria')) { + log(`Communist receives 2 cards from Democrat due to C${C_NATIONAL_SALVATION_FRONT}`) + game.dem_pwr_hand_limit -= 2 + game.com_pwr_hand_limit += 2 + permanently_remove(C_NATIONAL_SALVATION_FRONT) + } + + //Draw Power Cards + game.is_pwr_struggle = true + draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand_limit, game.com_pwr_hand_limit) + if (game.active === DEM) { + game.valid_cards = [...game.dem_pwr_hand] + } else { + game.valid_cards = [...game.com_pwr_hand] + } + + log(`Communist: ${game.com_pwr_hand.length} cards`) + log(`Democrat: ${game.dem_pwr_hand.length} cards`) + + //Check if The Crowd Turns Against Ceausescu occurs + if (game.persistent_events.includes(C_THE_CROWD_TURNS_AGAINST_CEAUSESCU) && !game.persistent_events.includes(THE_CROWD_TURNS_AGAINST_CEAUSESCU_OCCURRED) && game.pwr_struggle_in === 'Romania') { + if (game.active === COM) { + game.return = COM + next_player() + } + log_h3(`C${C_THE_CROWD_TURNS_AGAINST_CEAUSESCU}`) + game.persistent_events.push(THE_CROWD_TURNS_AGAINST_CEAUSESCU_OCCURRED) + game.state = 'the_crowd_turns_against_ceausescu_prep' + } else { + log_h2('Raise the Stakes') + game.state = 'raise_stakes_1' + } + } +} + +states.the_crowd_turns_against_ceausescu_prep = { + get inactive() { + return `resolve ${clean_name(cards[C_THE_CROWD_TURNS_AGAINST_CEAUSESCU].name)}.` + }, + prompt() { + view.prompt = 'The Crowd Turns Against Ceausescu: draw cards.' + gen_action('draw') + }, + draw() { + game.ceausescu_cards = [] + draw_cards(game.power_struggle_deck, game.ceausescu_cards, game.com_pwr_hand, 15, game.com_pwr_hand.length) + game.temp = game.ceausescu_cards.filter(card => rallies.includes(card)).length + log(`Drew ${pluralize(game.temp, 'Rally in the Square')}.`) + game.vm_available_ops = game.temp * 3 + log(`Democrat takes a ${game.vm_available_ops} Op Action Round`) + game.state = 'vm_the_crowd_turns_against_ceausescu' + } +} + +states.vm_the_crowd_turns_against_ceausescu = { + get inactive() { + return `resolve ${clean_name(cards[C_THE_CROWD_TURNS_AGAINST_CEAUSESCU].name)}.` + }, + prompt() { + view.prompt = `You have ${game.vm_available_ops} operations points. Play for:` + gen_action('influence') + gen_action('support_check') + }, + influence() { + push_undo() + delete game.ceausescu_cards + valid_spaces_infl() + game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'Romania') + game.state = 'the_crowd_turns_against_ceausescu_infl' /* Send this to add_infl. Add check at end of add_infl similar to valid_spaces*/ + }, + support_check() { + push_undo() + delete game.ceausescu_cards + valid_spaces_sc() + game.available_ops = 2 + game.state = 'support_check_prep' + } +} + +states.the_crowd_turns_against_ceausescu_infl = { + inactive: 'add SPs.', + prompt () { + if (game.vm_available_ops === 0) + { + view.prompt = 'Place SPs: done.'; + gen_action("done"); + return; + } + + view.prompt = `Add SPs: ${game.vm_available_ops} remaining` + for (let space of game.valid_spaces) { + gen_action_space(space) + } + }, + space(space) { + add_infl(space, 'vm_available_ops') + }, + done() { + do_log_summary() + if (game.return !== game.active) { + next_player() + } + log_h2('Raise the Stakes') + game.state = 'raise_stakes_1' + } +} + +states.raise_stakes_1 = { + inactive: 'raise the stakes.', + prompt () { + if ((game.active === DEM && game.dem_pwr_hand.length < 3) || (game.active === COM && game.com_pwr_hand.length < 3)) { + view.prompt = 'Raise the stakes: you must pass.' + gen_action('pass') + } + else if (game.raised_stakes_discard === 3) { + view.prompt = 'Raise the stakes: done.' + gen_action('done') + } else { + view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes.` + if (game.raised_stakes_discard === 0) { + gen_action('pass') + } + for (let card of game.valid_cards) { + gen_action_power_card(card) + } + } + }, + power_card(card) { + push_undo() + if (numberless_cards.includes(card)) { + log(`Discarded: P${card}`) + } else { + log(`Discarded: P${card} V${power_cards[card].value}`) + } + discard(card) + + game.raised_stakes_discard ++ + if (game.raised_stakes_discard === 3) { + game.raised_stakes++ + game.valid_cards = [] + } + }, + pass(){ + log('Did not raise the stakes') + game.raised_stakes_discard = 0 + next_player() + if (game.active === DEM) { + game.valid_cards = [...game.dem_pwr_hand] + } else { + game.valid_cards = [...game.com_pwr_hand] + } + game.state = 'raise_stakes_2' + }, + done () { + log_gap('Raised the stakes') + game.raised_stakes_discard = 0 + next_player() + if (game.active === DEM) { + game.valid_cards = [...game.dem_pwr_hand] + } else { + game.valid_cards = [...game.com_pwr_hand] + } + game.state = 'raise_stakes_2' + } +} + +states.raise_stakes_2 = { + inactive: 'raise the stakes.', + prompt () { + if ((game.active === DEM && game.dem_pwr_hand.length < 3) || (game.active === COM && game.com_pwr_hand.length < 3)) { + view.prompt = 'Raise the stakes: you must pass.' + gen_action('pass') + return + } + if (game.raised_stakes_discard === 3) { + view.prompt = 'Raise the stakes: done.' + gen_action('done') + } else { + view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes.` + if (game.raised_stakes_discard === 0) { + gen_action('pass') + } + for (let card of game.valid_cards) { + gen_action_power_card(card) + } + } + }, + power_card(card) { + push_undo() + if (numberless_cards.includes(card)) { + log(`Discarded: P${card}`) + } else { + log(`Discarded: P${card} V${power_cards[card].value}`) + } + discard(card) + + game.raised_stakes_discard ++ + if (game.raised_stakes_discard === 3) { + game.raised_stakes++ + game.valid_cards = [] + } + }, + pass() { + log('Did not raise the stakes') + goto_struggle() + }, + done () { + log_gap('Raised the stakes') + goto_struggle() + }, +} + +states.power_struggle = { + inactive: 'play a card.', + prompt () { + if (game.phase === 0) { + if (game.valid_cards.length > 0) { + view.prompt = "Play a card." + for (let card of game.valid_cards) { + gen_action_power_card(card) + } + } else if ( game.valid_cards.length === 0) { + view.prompt = 'No valid cards. You must concede.' + gen_action('concede') + } + } + if (game.phase === 1) { + let base_prompt = `${power_cards[game.played_power_card].name} played` + (leader_cards.includes(game.played_power_card) ? ` as a ${game.proxy_power_card}.` : ".") + if (game.valid_cards.length > 0) { + view.prompt = `${base_prompt} You must match or concede.`; + for (let card of game.valid_cards) { + gen_action_power_card(card); + } + } else { + view.prompt = `${base_prompt} You must concede.`; + } + gen_action('concede') + } + else if (game.phase === 2) { + view.prompt = 'You matched. Roll a die.' + gen_action('roll') + } + else if (game.phase === 3) { + view.prompt = 'Play leader as:' + if (game.tactics_fails !== "Strike") {gen_action('strike')} + if (game.tactics_fails !== "March") {gen_action('march')} + if (game.tactics_fails !== "Rally in the Square") {gen_action('rally')} + if (game.tactics_fails !== "Petition") {gen_action('petition')} + } + }, + power_card(card) { + push_undo() + discard(card) + if (game.phase === 0) { + game.power_card_1 = card + delete game.power_card_2 + } + if (game.phase === 1) { + game.power_card_2 = card + } + game.valid_cards=[] + game.return_state = 'power_struggle' + if (game.phase === 0) {delete game.proxy_power_card} + if (card === PC_TACTIC_FAILS) { + if (game.proxy_power_card) { + log_gap(`Played P${PC_TACTIC_FAILS}: ${game.proxy_power_card} no longer playable`) + } else { + log_gap(`Played P${PC_TACTIC_FAILS}: P${game.played_power_card} no longer playable`) + } + } else { + if (game.phase === 0 && leader_cards.includes(card)) {} /* Log nothing. Probably a better way to do this */ + else if (numberless_cards.includes(card)) { + log_gap(`Played: P${card}`) + } else { + log_gap(`Played: P${card} V${power_cards[card].value}`) + } + } + if (game.phase === 0) { + if (leader_cards.includes(card)) { + game.played_power_card = card + game.phase = 3 + } else if (card === 51){ /*Scare Tactics */ + game.return = '' + goto_vm(351) /*Can I combine these 3 into a single stage where you goto_vm(300 + card) ? */ + } else if (card === 50) { /*Support Surges */ + if (game.active === DEM) { + game.return = COM + } else { + game.return = DEM + } + goto_vm(350) + } else if (game.phase === 0 && card === 49) { /*Support Falters */ + next_player() + goto_vm(349) + } else { + game.played_power_card = card + game.phase = 1 + next_player() + do_valid_cards() + } + } else if (game.phase === 1) { + if (card === PC_TACTIC_FAILS) { + if (game.proxy_power_card) { + game.tactics_fails = game.proxy_power_card + } else { + game.tactics_fails = power_cards[game.played_power_card].name + } + game.phase = 0 + next_player() + do_valid_cards() + } else if (power_cards[game.played_power_card].value === 1) { + log('Takes initiative') + game.phase = 0 + do_valid_cards() + } else { + game.phase = 2 + } + } + }, + roll () { + clear_undo() + let roll = roll_d6() + log(`Roll: D${roll}`) + if (roll >= power_cards[game.played_power_card].value) { + log('Initiative roll successful') + game.phase = 0 + do_valid_cards() + } else { + log(`Initiative roll failed. Required ${power_cards[game.played_power_card].value} or more`) + game.phase = 0 + next_player() + do_valid_cards() + } + }, + concede () { + push_undo() + game.valid_cards = [] + delete game.power_card_1 + delete game.power_card_2 + log('Conceded') + log_h2('Aftermath') + log_h3('Support Loss') + if (game.phase === 0) { + game.played_power_card = 0 + game.proxy_power_card = 0 /*If conceded when held the initiative but had no playable cards, ignore the last played card */ + } + game.phase = 0 + game.state = 'support_loss' + }, + strike () { + log(`Played: P${game.played_power_card} as a Strike`) + game.proxy_power_card = 'Strike' + game.phase = 1 + next_player() + do_valid_cards() + }, + march () { + log(`Played: P${game.played_power_card} as a March`) + game.proxy_power_card = 'March' + game.phase = 1 + next_player() + do_valid_cards() + }, + rally () { + log(`Played: P${game.played_power_card} as a Rally in the Square`) + game.proxy_power_card = 'Rally in the Square' + game.phase = 1 + next_player() + do_valid_cards() + }, + petition () { + log(`Played: P${game.played_power_card} as a Petition`) + game.proxy_power_card = 'Petition' + game.phase = 1 + next_player() + do_valid_cards() + } +} + +states.support_loss ={ + inactive: 'do Support Loss.', + prompt () { + let ps_state = game.persistent_events.includes(111) ? "New Year's Eve Party" : "Power Struggle" + if (game.phase === 0) { + view.prompt = 'You lost the Power Struggle. Roll a die for Support Loss.' + gen_action('roll') + } else if (game.phase === 1 && game.available_ops > 0 && game.valid_spaces.length > 0) { + view.prompt = `${ps_state} - ${country_name(game.pwr_struggle_in)}. Support Loss: remove ${pluralize(game.available_ops,'SP')}.` + + for (let space_id of game.valid_spaces) { + gen_action_space(space_id) + } + } else if (game.phase === 1 && game.available_ops === 0 ) { + view.prompt = `${ps_state} - ${country_name(game.pwr_struggle_in)}. Support Loss: finished.` + gen_action('done') + } else if (game.phase === 1 && game.valid_spaces.length === 0) { + view.prompt = `${ps_state} - ${country_name(game.pwr_struggle_in)}. Support Loss: no remaining SPs to remove.` + gen_action('done') + } + }, + roll () { + game.available_ops = support_loss_roll[get_aftermath_roll()] + if (game.available_ops === 0) { + log('Does not remove SPs') + } + game.phase++ + if (game.available_ops > 0) { + valid_spaces_support_loss() + } + }, + space(space) { + game.remove_opponent_infl = false /* Don't know why this is needed... */ + remove_infl(space, 'available_ops') + }, + done () { + do_log_summary() + next_player() + log_h3('Victory Point') + game.phase = 0 + game.state = 'vp_roll' + } +} + +states.vp_roll = { + inactive: 'do VP Roll.', + prompt () { + let ps_state = game.persistent_events.includes(111) ? "New Year's Eve Party" : "Power Struggle" + if (game.phase === 0) { + view.prompt = `${ps_state} - ${country_name(game.pwr_struggle_in)}: roll a die for Victory.` + gen_action('roll') + } else if (game.phase === 1) { + view.prompt = `${ps_state} - ${country_name(game.pwr_struggle_in)}: take power.` + gen_action('take') + } else if (game.phase === 2) { + view.prompt = `${ps_state} - ${country_name(game.pwr_struggle_in)}: proceed to scoring.` + gen_action('scoring') + } + }, + roll () { + let roll = get_aftermath_roll() + let vp_change = vp_roll[roll] + if (game.active === DEM) { + log(`+${vp_change} VP`) + } else { + log(`-${vp_change} VP`) + } + if (game.active === DEM) {game.vp += vp_change} + else {game.vp -= vp_change} + if (game.active === DEM && roll >= 4) { + game.phase = 1 + } else { + game.phase = 0 + if (game.active === DEM) {next_player()} + game.state = 'choose_power' + } + }, + take () { + push_undo() + let scoring_card = scoring_cards[countries.indexOf(game.pwr_struggle_in)] + permanently_remove(scoring_card) + take_power(game.pwr_struggle_in) + game.phase = 2 + }, + scoring () { + push_undo() + log_h2('Scoring') + score_country(game.pwr_struggle_in) + resolve_tyrant() + }, +} + +states.choose_power = { + inactive: 'choose whether to remain in power.', + prompt () { + if (game.phase === 0) { + view.prompt = 'Choose whether to remain in power.' + gen_action('retain') + gen_action('surrender') + } else if (game.phase === 1) { + view.prompt = 'Proceed to scoring.' + gen_action('scoring') + } + }, + retain() { + push_undo() + retain_power(game.pwr_struggle_in) + game.phase = 1 + }, + surrender () { + push_undo() + take_power(game.pwr_struggle_in) + permanently_remove(game.played_card) + game.phase = 1 + }, + scoring () { + push_undo() + score_country(game.pwr_struggle_in) + resolve_tyrant() + } +} + +states.the_tyrant_is_gone ={ + inactive: 'resolve The Tyrant is Gone.', + prompt() { + view.prompt = 'Play The Tyrant is Gone for the event.' + gen_action('event') + }, + event() { + if (game.active !== DEM) { + next_player() + } + log_h3(`C${C_THE_TYRANT_IS_GONE}`) + game.vm_event = C_THE_TYRANT_IS_GONE + goto_vm(game.vm_event) + } +} + +states.finish_scoring ={ + inactive: 'finish scoring.', + prompt() { + view.prompt = 'End power struggle.' + gen_action('done') + } , + done() { + log_msg_gap('Power Struggle resolved') /*At this point log card dicarded or permanently removed? */ + if (game.persistent_events.includes(111)) { + game.state = 'new_years_eve_party' + return + } + if (check_vp()) { + return + } + reset_power() + end_round() + } +} + +// ======================================= END TURN STATES ========================================== + +states.end_turn_4_5_4 = { + inactive: 'verify held cards.', + prompt() { + view.prompt = 'End Turn: verify held cards.' + gen_action('check') + }, + check() { + log_h2('Verify held cards') + const dem_has_scoring_card = game.democrat_hand.some(card => scoring_cards.includes(card)) + const com_has_scoring_card = game.communist_hand.some(card => scoring_cards.includes(card)) + if (!dem_has_scoring_card && !com_has_scoring_card) { + log('No held scoring cards') + } + + if (dem_has_scoring_card && com_has_scoring_card) { + log('Both players have held scoring cards') + goto_game_over('', `The game is tied due to held scoring cards!`) + } + else if (dem_has_scoring_card) { + log('Democrat player has a held scoring card') + goto_game_over(COM, `${COM} won by held scoring card!`) + } + else if (com_has_scoring_card) { + log('Communist player has a held scoring card') + goto_game_over(DEM, `${DEM} won by held scoring card!`) + } + else if (game.persistent_events.includes(C_NEW_YEARS_EVE_PARTY)) { + log_h1(`New Year's Eve Party`) + game.vm_event = 104 + //Check if the Communist receives VP from The Tyrant is Gone + if (game.the_tyrant_is_gone && game.the_tyrant_is_gone > 0) { + game.vp -= 2 + log(`Communist receives 2 VP from C97`) + } + game.persistent_events.push(111) + if (game.active !== DEM) { + next_player() + } + game.state = 'new_years_eve_party' + } + else if(game.turn === 10) { + clear_undo() + log_h2('Final Scoring') + + //Check if the Communist receives VP from The Tyrant is Gone + if (game.the_tyrant_is_gone && game.the_tyrant_is_gone > 0) { + game.vp -= 2 + log(`Communist receives 2 VP from C97`) + } + game.state = 'final_scoring_held' + + } else { + new_turn() + } + } +} + +states.final_scoring_held = { + inactive: 'resolve final scoring.', + prompt() { + view.prompt = 'Final Scoring: Communist scores VP bonus for the number of countries they retain power.' + gen_action('bonus') + }, + bonus() { + push_undo() + const held_countries = game.revolutions.filter(value => value === false).length + let vp_gain = 4*held_countries + log(`Communist holds power in ${pluralize(held_countries, 'country', 's')}: -${vp_gain} VP`) + game.vp -= 4*held_countries + game.temp = {'East_Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false} + game.state = 'final_scoring' + } +} + +states.final_scoring = { + inactive: 'score countries.', + prompt() { + if (game.temp['East_Germany'] && game.temp['Poland'] && game.temp['Czechoslovakia'] && game.temp['Hungary'] && game.temp['Romania'] && game.temp['Bulgaria']) { + view.prompt = 'Final scoring: done.' + gen_action('end') + } else { + view.prompt = 'Choose a country to score:' + if (!game.temp['East_Germany']) {gen_action('east_germany')} + if (!game.temp['Poland']) {gen_action('poland')} + if (!game.temp['Czechoslovakia']) {gen_action('czechoslovakia')} + if (!game.temp['Hungary']) {gen_action('hungary')} + if (!game.temp['Romania']) {gen_action('romania')} + if (!game.temp['Bulgaria']) {gen_action('bulgaria')} + } + }, + east_germany() { + score_country('East_Germany') + game.temp['East_Germany'] = true + }, + poland() { + score_country('Poland') + game.temp['Poland'] = true + }, + czechoslovakia() { + score_country('Czechoslovakia') + game.temp['Czechoslovakia'] = true + }, + hungary() { + score_country('Hungary') + game.temp['Hungary'] = true + }, + romania() { + score_country('Romania') + game.temp['Romania'] = true + }, + bulgaria() { + score_country('Bulgaria') + game.temp['Bulgaria'] = true + }, + end() { + delete game.temp + if (game.vp > 0) { + goto_game_over(DEM, `${DEM} wins on Victory Point Track!`) + } else if (game.vp < 0) { + goto_game_over(COM, `${COM} wins on Victory Point Track!`) + } else if (game.vp === 0) { + goto_game_over('', `The game is tied!`) /*Not sure what to pass for result */ + } + } +} + +states.game_over = { + get inactive() { + return game.victory + }, + prompt() { + view.prompt = game.victory + }, +} + +// ========================== EVENT SPECIFIC STATES ================================= + +states.general_strike = { + inactive: 'discard a card.', + prompt() { + if (game.played_card === 0 ) { + view.prompt = 'General Strike: you must discard a card or play a Scoring Card.' + game.communist_hand + for (let card of game.communist_hand) { + gen_action_card(card) + } + } else if (game.played_card > 0 ) { + view.prompt = 'General Strike: roll a die.' + gen_action('roll') + } + }, + card (card) { + push_undo() + game.played_card = card + let find_card + find_card = game.communist_hand.indexOf(card) + game.communist_hand.splice(find_card, 1) + game.available_ops = get_card_ops(card) + if (scoring_cards.includes(card)) { + game.vm_event = card + log(`Played C${card} for the event`) + game.return_state = 'general_strike' + goto_vm(game.vm_event) + } else { + log(`Discarded C${card}`) + } + }, + roll() { + clear_undo() + let roll = roll_d6() + log(`Roll: D${roll}`) + logi(`+${game.available_ops} ops`) + let total = roll + game.available_ops + log(`Modified roll: ${total}`) + + if (total > 5) { + log('The strike is over.') + permanently_remove(C_GENERAL_STRIKE) + game.persistent_events = game.persistent_events.filter(n => n !== 5) + } else { + log('The strike continues. Required 6 or more') + } + game.state = 'end_round' + }, +} + +states.honecker ={ + inactive: 'resolve Honecker.', + prompt() { + view.prompt = 'Honecker: you may take an extra action round.' + gen_action('extra') + gen_action('pass') + }, + extra() { + push_undo() + game.round++ + log(`Communist chooses to take an extra Action Round due to C${C_HONECKER}`) + log_h2(`Action Round ${game.round}`) + game.round_player = COM + permanently_remove(C_HONECKER) + if (game.persistent_events.includes(C_GENERAL_STRIKE)) { + game.state = 'general_strike' + } else { + game.state = 'choose_card' + } + }, + pass() { + push_undo() + log(`C${C_HONECKER}: passed`) + permanently_remove(C_HONECKER) + game.state = 'end_round' + } +} + +states.new_years_eve_party = { + get inactive() { + return `resolve ${clean_name(cards[104].name)}.` + }, + prompt() { + if (!game.is_pwr_struggle) { + view.prompt = `New Year's Eve Party: you may choose a country to have a final power struggle.` + if (!game.revolutions[0]) {gen_action('poland')} + if (!game.revolutions[1]) {gen_action('hungary')} + if (!game.revolutions[2]) {gen_action('east_germany')} + if (!game.revolutions[3]) {gen_action('bulgaria')} + if (!game.revolutions[4]) {gen_action('czechoslovakia')} + if (!game.revolutions[5]) {gen_action('romania')} + gen_action('pass') + } else { + view.prompt = `New Year's Eve Party: done.` + gen_action('end') + } + }, + east_germany() { + push_undo() + log('Chose to score East Germany') + game.vm_event = 42 + goto_vm(42) + }, + poland() { + push_undo() + log('Chose to score Poland') + game.vm_event = 22 + goto_vm(22) + }, + czechoslovakia() { + push_undo() + log('Chose to score Czechoslovakia') + game.vm_event = 55 + goto_vm(55) + }, + hungary() { + push_undo() + log('Chose to score Hungary') + game.vm_event = 23 + goto_vm(23) + }, + romania() { + push_undo() + log('Chose to score Romania') + game.vm_event = 95 + goto_vm(95) + }, + bulgaria () { + push_undo() + log('Chose to score Bulgaria') + game.vm_event = 43 + goto_vm(43) + }, + pass() { + push_undo() + log('No final power struggle') + if (game.vp > 0) { + goto_game_over(DEM, `New Year's Eve Party: ${DEM} wins on Victory Point Track!`) + } else if (game.vp < 0) { + goto_game_over(COM, `New Year's Eve Party: ${COM} wins on Victory Point Track!`) + } else if (game.vp === 0) { + goto_game_over('', `New Year's Eve Party: The game is tied!`) /*Not sure what to pass for result */ + } + }, + end() { + if (game.vp > 0) { + goto_game_over(DEM, `New Year's Eve Party: ${DEM} wins on Victory Point Track!`) + } else if (game.vp < 0) { + goto_game_over(COM, `New Year's Eve Party: ${COM} wins on Victory Point Track!`) + } else if (game.vp === 0) { + goto_game_over('', `New Year's Eve Party: The game is tied!`) /*Not sure what to pass for result */ + } + } +} + +states.stasi_end_round = { + inactive: 'choose next card due to Stasi.', + prompt() { + if (game.democrat_hand.length === 0) { + view.prompt = 'Stasi: no cards remaining.' + gen_action('pass') + return + } + view.prompt = 'Stasi: you must select your next card to play.' + + for (let card of game.democrat_hand) { + gen_action_card(card) + } + }, + card(card) { + push_undo() + log_gap(`Democrat selected C${card} as next card.`) + game.stasi_card = card + if (!scoring_cards.includes(card) && count_scoring_cards() >= (7-game.round)){ + game.temp = card + game.state = 'stasi_confirm_scoring_card' + return + } + game.state = 'stasi_finish' + }, + pass() { + log('Stasi: Democrat has no remaining cards') + game.stasi_card = 0 + end_stasi_choose_card() + }, +} + +states.stasi_confirm_scoring_card = { + inactive: 'choose a card.', + prompt() { + view.prompt = `${pluralize(count_scoring_cards(),'scoring card')} in hand with ${pluralize(7-game.round,'Action Round')} remaining. Scoring cards may not be held. Continue?` + gen_action('continue') + }, + continue() { + push_undo() + end_stasi_choose_card() + } +} + +states.stasi_finish = { + inactive: 'choose next card due to Stasi.', + prompt() { + view.prompt = 'Stasi. Choose card: done.' + gen_action('done') + }, + done() { + push_undo() + end_stasi_choose_card() + } +} + +states.stasi_confirm = { + inactive: 'choose next card due to Stasi.', + prompt() { + view.prompt = `If Common European Home selected, it must be played for Operations. Otherwise select the opponent's card instead.` + gen_action('done') + }, + done() { + game.playable_cards = game.playable_cards.filter( n => n !== C_COMMON_EUROPEAN_HOME) + end_stasi_choose_card() + } +} + +states.stasi_play_card = { + inactive: 'play a card.', + prompt () { + if (game.democrat_hand.length === 0) { + view.prompt = 'Stasi: you must pass.' + gen_action('pass') + } else { + view.prompt = `Stasi: you must play ${clean_name(cards[game.stasi_card].name)}.` + gen_action_card(game.stasi_card) + } + }, + card(card) { + push_undo() + game.played_card = card + let find_card + find_card = game.democrat_hand.indexOf(card); + game.democrat_hand.splice(find_card, 1); + game.available_ops = get_card_ops(card) + + if (game.democrat_hand.includes(C_COMMON_EUROPEAN_HOME) && cards[card].side === "C") { + game.state = 'stasi_resolve_common_european_home' + } else { + game.state = 'play_card' + } + }, + pass () { + log('No cards remaining. Passed') + //end_round() + game.state = 'end_round' + }, + done () { + if (game.democrat_hand.includes(C_COMMON_EUROPEAN_HOME)) { + game.state = 'stasi_resolve_common_european_home' + } else { + game.state = 'play_card' + } + } +} + +states.stasi_resolve_common_european_home = { + inactive: 'play a card.', + prompt () { + view.prompt = `Stasi: play ${clean_name(cards[game.played_card].name)} with Common European Home?` + gen_action('yes') + gen_action('no') + }, + yes() { + log(`Played C${game.played_card} with Common European Home`) + silent_discard(C_COMMON_EUROPEAN_HOME) + game.vm_infl_to_do = true + game.vm_event_to_do = false + game.state = 'resolve_opponent_event' + }, + no() { + game.state = 'play_card' + } +} + + +// ==================== SUPPORTING STATE FUNCTIONS ============================= + + +function add_infl(space, ops) { + push_undo() + log_summary(`Added £ SP in %${space}`) + + //If AHBR - check AHBR conditions + if (game.persistent_events.includes(58)) { + if (spaces[space].country !== 'East_Germany'){ + game.austria_hungary_border_reopened_tracker = false + } + } + + // Check Genscher + if (game.persistent_events.includes(C_GENSCHER) && game.active === DEM && spaces[space].country === 'East_Germany' && check_com_control(space)) { + game[ops]-- + log_summary(`(-1 op due to C${C_GENSCHER})`) + } else if (check_opp_control(space)) { + game[ops] -= 2 + //Check if Austria Hungary Border Reopened was used to place last SP in a controlled space in East Germany. If so, game.available_op will be negative + if (game[ops] < 0) { + log_summary(`(Used +1 op from C${C_AUSTRIA_HUNGARY_BORDER_REOPENED})`) + } + } else { + game[ops]-- + } + + // Update influence values + if (game.active === COM) { + game.comInfl[space]++ + } else { + game.demInfl[space]++ + } + check_tyrant() + + // Check Austria Hungary Border Reopened is true and condition has been met + if (game[ops] === 0 && game.active === DEM && game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED) && game.austria_hungary_border_reopened_tracker) { + game[ops] ++ + log('+1 op from C58') + game.austria_hungary_border_reopened_tracker = false + game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany') + } + + // If only 1 IP remaining, may not place in opponent controlled spaces + + // Check for Genscher & Austria Hungary Border Reopened + + if (game[ops] === 1) { + if (game.active === DEM) { + if (game.persistent_events.includes(63) || (game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker)) { + game.valid_spaces = game.valid_spaces.filter(n => !(check_opp_control(n) && spaces[n].country !== 'East_Germany')) + } else { + game.valid_spaces = game.valid_spaces.filter(n => !check_opp_control(n)) + } + } else { + game.valid_spaces = game.valid_spaces.filter(n => !check_opp_control(n)) + } + } + + //Clear valid spaces if no IP remaining. + if (game[ops] <= 0 ) { + game.valid_spaces = [] + } +} + +function remove_infl(space, ops) { + push_undo() + log_summary(`Removed £ SP from %${space}`) + + if (game.remove_opponent_infl === true) { + if (game.active === COM) { + game.demInfl[space]-- + if (game.demInfl[space] === 0) { + game.valid_spaces = game.valid_spaces.filter(id => id !== space); + } + } else { + game.comInfl[space]-- + if (game.comInfl[space] === 0) { + game.valid_spaces = game.valid_spaces.filter(id => id !== space); + } + } + check_tyrant() + + } else { + if (game.active === COM) { + game.comInfl[space]-- + if (game.comInfl[space] === 0) { + game.valid_spaces = game.valid_spaces.filter(id => id !== space); + } + } else { + game.demInfl[space]-- + if (game.demInfl[space] === 0) { + game.valid_spaces = game.valid_spaces.filter(id => id !== space); + } + } + check_tyrant() + } + game[ops]-- + if (game.vm_influence_added && game.vm_influence_added[space] >= 0) {game.vm_influence_added[space]++} + if (game[ops]===0) {game.valid_spaces = []} +} + +function do_sc(space) { + clear_undo() + let tear_gas_start = game.persistent_events.includes(C_TEAR_GAS) + let the_wall_start = game.persistent_events.includes(C_THE_WALL) + log_gap(`Support check: %${space}`) + let roll = roll_d6() + + // Check for The Wall + if (game.active === COM && game.persistent_events.includes(C_THE_WALL) && spaces[space].country === 'East_Germany') { + logi(`No adjacency for Democrats due to C${C_THE_WALL}`) + log_gap(`Roll: D${roll}`) + } + // Continue with Support Check Logic + else { log(`Roll: D${roll}`) } + + // Check for the Crowd Turns Against Ceausescu + + if (game.is_pwr_struggle) { + roll += game.vm_available_ops + logi(`+${game.vm_available_ops} from Ceausescu`) + } + + // Check if in Tiananmen Square Track Award + + else if (game.state === 'vm_tst_6_sc') { + roll += get_tst_6_ops() + roll += 2 + logi('+2 TST award') + } + else { + let card_ops = get_card_ops(this_card()) + roll += card_ops + logi(`+${card_ops} from card ops`) + } + + if (game.support_check_modifier > 0) { + roll += game.support_check_modifier + logi(`+${game.support_check_modifier} from event`) + } + + // Events which modify SC rolls + if (game.active === COM && game.persistent_events.includes(C_TEAR_GAS) && spaces[space].socio === 6) { + roll ++ + logi(`+1 from C${C_TEAR_GAS}`) + permanently_remove(C_TEAR_GAS) + game.persistent_events = game.persistent_events.filter(n => n !== C_TEAR_GAS) + } + if (game.active === DEM && spaces[space].region === 'Eastern Europe' && game.persistent_events.includes(C_FRG_EMBASSIES)) { + roll++ + logi(`+1 from C${C_FRG_EMBASSIES}`) + } + if (game.active === DEM && spaces[space].country === 'East_Germany' && game.persistent_events.includes(C_GRENZTRUPPEN)) { + roll-- + logi(`-1 from C${C_GRENZTRUPPEN}`) + } + if ((game.active === COM && game.stand_fast === DEM && check_dem_control(space)) || (game.active === DEM && game.stand_fast === COM && check_com_control(space))){ + roll-- + logi(`-1 from C${C_STAND_FAST}`) + } + if (game.active === DEM && game.persistent_events.includes(C_ELENA) && spaces[space].country === 'Romania') { + roll-- + logi(`-1 from C${C_ELENA}`) + } + if (game.active === DEM && game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED) && game.austria_hungary_border_reopened_tracker) { + roll++ + logi(`+1 from C${C_AUSTRIA_HUNGARY_BORDER_REOPENED}`) + } + + // Continue with logic - check for adjacency + + // Events which affect adjacency - The Wall + + const adj = count_adj(space) + if (game.active === COM && game.persistent_events.includes(C_THE_WALL) && spaces[space].country === 'East_Germany') { + roll += adj.com_adj + if (adj.com_adj > 0) { + logi(`+${adj.com_adj} adjacency`) + } + permanently_remove(C_THE_WALL) + + // Standard adjacency + } else { + if (adj.dem_adj > 0 || adj.com_adj > 0 ){ + if (game.active === DEM) { + roll += adj.dem_adj + roll -= adj.com_adj + if (adj.dem_adj > 0) { + logi(`+${adj.dem_adj} from adjacency`) + } + if (adj.com_adj > 0) { + logi(`-${adj.com_adj} from opponent adjacency`) + } + } else { + roll += adj.com_adj + roll -= adj.dem_adj + if (adj.com_adj > 0) { + logi(`+${adj.com_adj} from adjacency`) + } + if (adj.dem_adj > 0) { + logi(`-${adj.dem_adj} from opponent adjacency`) + } + } + } + } + + // Support check calcs + log(`Modified roll: ${roll}`) + const stability = spaces[space].stability + logi(`-${stability*2} (stability * 2)`) + const change_infl = Math.max(0, roll - stability*2) + if (change_infl > 0) { + log_msg_gap(`Change influence: ${change_infl} SP`) + if(game.active === DEM) { + if (change_infl > game.comInfl[space]) { + const residual = change_infl - game.comInfl[space] + game.comInfl[space] = 0 + game.demInfl[space] += residual + } else { + game.comInfl[space] -= change_infl + } + if (game.comInfl[space] === 0) { + game.valid_spaces = game.valid_spaces.filter(id => id !== space) + } + } else { + if (change_infl > game.demInfl[space]) { + const residual = change_infl - game.demInfl[space] + game.demInfl[space] = 0 + game.comInfl[space] += residual + } else { + game.demInfl[space] -= change_infl + } + if (game.demInfl[space] === 0) { + game.valid_spaces = game.valid_spaces.filter(id => id !== space) + } + } + check_tyrant() + + } else { + log_msg_gap('Change influence: 0 SP') + } + //Check VP awards + if (game.active === COM && game.persistent_events.includes(C_HELSINKI_FINAL_ACT) && (spaces[space].socio === 5 || spaces[space].socio === 6) ) { + log('+1 VP from C26') + game.vp ++ + } + if (game.active === COM && game.persistent_events.includes(C_ECO_GLASNOST) && spaces[space].space_id === S_RUSE) { + log('+1 VP from C39') + game.vp++ + } + + //Check if Tear Gas or The Wall used + let tear_gas_end = game.persistent_events.includes(C_TEAR_GAS) + let the_wall_end = game.persistent_events.includes(C_THE_WALL) + if (tear_gas_start && !tear_gas_end) { + log(`C${C_TEAR_GAS} no longer in effect`) + } + if (the_wall_start && !the_wall_end) { + log(`C${C_THE_WALL} no longer in effect`) + } + + + // If Austria-Hungary Border Reopened used, all future support checks must be in East Germany + if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)){ + if (game.austria_hungary_border_reopened_tracker) { + game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany') + } + } + delete game.selected_space +} + +function valid_spaces_setup() { + for (let i =0 ; i < spaces.length ; i++) { + let space = spaces[i] + + if (game.active === COM) { + let infl = game.demInfl[i] + + if (infl === 0) { + game.valid_spaces.push(space.space_id); + } + } else { + let infl = game.comInfl[i] + if (infl === 0) { + game.valid_spaces.push(space.space_id); + } + } + } +} + +function valid_spaces_sc() { + let valid_spaces_set = new Set(); + + for (let i = 0 ; i < spaces.length; i++) { + let space = spaces[i] + + if (game.active === DEM) { + let infl = game.comInfl[i] + if (infl !== 0 ) { + valid_spaces_set.add(space.space_id); + } + } else { + let infl = game.demInfl[i] + if (infl !== 0 ) { + // Check Events that block support checks in a given space + if (game.persistent_events.includes(C_SOLIDARITY_LEGALIZED) && space.space_id === S_GDANSK) {continue} + if (game.persistent_events.includes(C_WE_ARE_THE_PEOPLE) && space.space_id === S_LEIPZIG) {continue} + if (game.persistent_events.includes(C_FOREIGN_CURRENCY_DEBT_BURDEN) && space.country === game.foreign_currency_debt_burden) {continue} + + valid_spaces_set.add(space.space_id); + } + } + } + game.valid_spaces = Array.from(valid_spaces_set); + + //Check for the Crown Turns Against Ceausescu + if (game.is_pwr_struggle && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(C_THE_CROWD_TURNS_AGAINST_CEAUSESCU)) { + game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'Romania') + } + return game.valid_spaces; +} + +function valid_spaces_support_loss() { + let valid_spaces_set = new Set(); + for (let i = 0; i < game.demInfl.length; i++) { + let space = spaces[i] + if (game.active === DEM) { + let infl = game.demInfl[i] + if (infl > 0 && space.country === game.pwr_struggle_in) { + valid_spaces_set.add(space.space_id); + } + } else { + let infl = game.comInfl[i] + if (infl > 0 && space.country === game.pwr_struggle_in) { + valid_spaces_set.add(space.space_id); + } + } + } + game.valid_spaces = Array.from(valid_spaces_set); + return game.valid_spaces; +} + +function valid_spaces_infl() { + // Check if function is called from the VM or not, take relevant ops variable + let ops = game.state.startsWith('vm') ? game.vm_available_ops : game.available_ops; + + let valid_spaces_set = new Set(); + for (let i = 0; i < game.demInfl.length; i++) { + let space = spaces[i] + let player_influence = game.active === COM ? game.comInfl[i] : game.demInfl[i]; + + // If the piece has the player's influence, add it and its adjacent spaces to the set + if (player_influence > 0) { + valid_spaces_set.add(space.space_id); + let adjacent_spaces = get_adjusted_adjacency(space.space_id) + + for (let adj_space_id of adjacent_spaces) { + if (adj_space_id >= 0) { + const adj_piece = spaces[adj_space_id]; + + // Check if the adjacent space is controlled by the opponent + const opponent_control = check_opp_control(adj_piece.space_id) + + //Check for Genscher. Can always place in East Germany even with 1 op + if (game.active === DEM && adj_piece.country === 'East_Germany' && game.persistent_events.includes(C_GENSCHER)){ + valid_spaces_set.add(adj_piece.space_id) + } + + + // Otherwise, only add the adjacent space if the available_ops >= 2 or the space is not controlled by the opponent + if (ops >= 2 || !opponent_control) { + valid_spaces_set.add(adj_piece.space_id) + } + } + } + } + } + game.valid_spaces = Array.from(valid_spaces_set); + return game.valid_spaces; +} + +function valid_cards(player_hand, presence) { + const valid_cards_set = new Set() + if (game.phase === 0) { + + for (let c of player_hand) { + let card = power_cards[c] + // Never add tactics fails + if (c === PC_TACTIC_FAILS) { + continue + } + // Cannot play the suit of Tactics Fails + if (card.name === game.tactics_fails) { + continue + } + + + if (card.socio === 0) { + valid_cards_set.add(c) + } else if (leaders.includes(card.socio) && presence[card.socio]) { + valid_cards_set.add(c) + } + } + } else if (game.phase === 1) { + for (let c of player_hand) { + let card = power_cards[c] + if (!leader_cards.includes(c) && card.name === power_cards[game.played_power_card].name) { + valid_cards_set.add(c) + } else if (card.name === game.proxy_power_card) { + valid_cards_set.add(c) + } else if (leaders.includes(card.socio) && presence[card.socio]) { + valid_cards_set.add(c) + } else if (c === PC_TACTIC_FAILS) { + valid_cards_set.add(c) + } + } + } + game.valid_cards = Array.from(valid_cards_set) + return game.valid_cards +} + +function do_valid_cards() { + let presence = check_presence(game.pwr_struggle_in) + if (game.active === DEM) { + valid_cards(game.dem_pwr_hand, presence.dem_leaders) + } else { + valid_cards(game.com_pwr_hand, presence.com_leaders)} +} + +function count_adj(space_id) { + let dem_adj = 0 + let com_adj = 0 + + let adjacent_spaces = get_adjusted_adjacency(space_id) + for (let adj_space_id of adjacent_spaces) { + if (check_dem_control(adj_space_id)) { + dem_adj++ + } + if (check_com_control(adj_space_id)) { + com_adj++ + } + } + return {dem_adj, com_adj} +} + +function check_control(space_id) { + if ( (game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) { + return true; + } else if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) { + return true; + } else { + return false; + } +} + +function check_opp_control(space_id) { + if (game.active === DEM && ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability)) { + return true; + } else if (game.active === COM && ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability)) { + return true; + } else { + return false; + } +} + +function check_dem_control(space_id) { + if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) { + return true; + } else { + return false; + } +} + +function check_com_control(space_id) { + if ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) { + return true; + } else { + return false; + } +} + +function do_tst_attempt() { + let roll = roll_d6(); + log(`Roll: D${roll}`); + + roll += game.available_ops + logi(`+${game.available_ops} from card ops`) + + // TIANANMEN SQUARE MODIFIERS + + if (game.active === DEM && game.dem_tst_attempted === 1 || game.active === COM && game.com_tst_attempted === 1) { + roll ++; + logi('+1 from previous TST attempts') + } + if (game.active === DEM && game.dem_tst_position >= 1 && game.com_tst_position === 0) { + roll ++ + logi('+1 from TST award') + } + if (game.active === COM && game.com_tst_position >= 1 && game.dem_tst_position === 0) { + roll ++ + logi('+1 from TST award') + } + if ((game.active === DEM && cards[game.played_card].side === 'D') || (game.active === COM && cards[game.played_card].side === 'C')) { + roll ++; + logi('+1 for playing own card'); + } + if (game.active === COM && game.persistent_events.includes(53)) { + roll ++ + logi('+1 from C53') + } + log(`Modified roll: ${roll}`) + + // TIANANMEN SQUARE ATTEMPT + game.return = game.active + game.return_state = 'tiananmen_square_attempt_done' + if (game.active === DEM) { + game.dem_tst_attempted_this_turn = 1 + if (roll >= dem_tst_req[game.dem_tst_position]) { + log(`${dem_tst_req[game.dem_tst_position]} required: success`) + game.dem_tst_position++ + game.dem_tst_attempted = 0 + + //Check if they have reached box 7 or 8 first + if (game.dem_tst_position === 7 && game.com_tst_position < 7) { + game.tst_7 = false + } + if (game.dem_tst_position === 8 && game.com_tst_position < 8) { + game.tst_8 = false + } + + //Check if they have caught up to box 7 or 8 + if (game.dem_tst_position >= 7 && game.com_tst_position >= 7) { + delete game.tst_7 + } + if (game.dem_tst_position >= 8 && game.com_tst_position >= 8) { + delete game.tst_8 + } + + //Check if TST events occur + if (game.dem_tst_position === 3 && game.com_tst_position < 3) {game.vm_event = 203} + else if (game.dem_tst_position === 4 && game.com_tst_position < 4) {game.vm_event = 204} + game.state = 'tiananmen_square_attempt_success' + } else { + log(`${dem_tst_req[game.dem_tst_position]} required: fail`) + game.dem_tst_attempted = 1 + game.state = 'tiananmen_square_attempt_fail' + } + } else { + game.com_tst_attempted_this_turn = 1 + if (roll >= com_tst_req[game.com_tst_position]) { + log(`${com_tst_req[game.com_tst_position]} required: success`) + game.com_tst_position++ + game.com_tst_attempted = 0 + + //Check if they have reached box 7 or 8 first + if (game.com_tst_position === 7 && game.dem_tst_position < 7) { + game.tst_7 = false + } + if (game.com_tst_position === 8 && game.dem_tst_position < 8) { + game.tst_8 = false + } + + //Check if they have caught up to box 7 or 8 + if (game.com_tst_position >= 7 && game.dem_tst_position >= 7) { + delete game.tst_7 + } + if (game.com_tst_position >= 8 && game.dem_tst_position >= 8) { + delete game.tst_8 + } + + //Check if TST events occur + if (game.com_tst_position === 3 && game.dem_tst_position < 3) {game.vm_event = 203} + else if (game.com_tst_position === 4 && game.dem_tst_position < 4) {game.vm_event = 204} + game.state = 'tiananmen_square_attempt_success' + } else { + log(`${com_tst_req[game.com_tst_position]} required: fail`) + game.com_tst_attempted = 1 + game.state = 'tiananmen_square_attempt_fail' + } + } +} + +function check_presence(country) { + + let dem_spaces = 0; + let com_spaces = 0; + let dem_battlegrounds = 0; + let com_battlegrounds = 0; + let dem_leaders = {1: false, 4: false, 5: false, 6: false, 7: false}; + let com_leaders = {1: false, 4: false, 5: false, 6: false, 7: false}; + + + for (let i = 0; i < spaces.length; i++) { + let space = spaces[i] + if (space.country === country) { + + if (check_dem_control(i)) { + dem_spaces++; + if (space.battleground === 1) { + dem_battlegrounds++; + } + if (leaders.includes(space.socio)) { + dem_leaders[space.socio] = true; + } + } + if (check_com_control(i)) { + com_spaces++; + if (space.battleground === 1) { + com_battlegrounds++; + } + if (leaders.includes(space.socio)) { + com_leaders[space.socio] = true; + } + } + } + } + + // Determine domination + let dem_domination = dem_battlegrounds > com_battlegrounds && dem_spaces > com_spaces && dem_spaces - dem_battlegrounds > 0; + let com_domination = com_battlegrounds > dem_battlegrounds && com_spaces > dem_spaces && com_spaces - com_battlegrounds > 0; + + // Determine control + let total_battlegrounds = battlegrounds(country); + let dem_control = dem_battlegrounds === total_battlegrounds && dem_spaces > com_spaces; + let com_control = com_battlegrounds === total_battlegrounds && com_spaces > dem_spaces; + + return { + dem_spaces: dem_spaces, + com_spaces: com_spaces, + dem_battlegrounds: dem_battlegrounds, + com_battlegrounds: com_battlegrounds, + dem_domination: dem_domination, + com_domination: com_domination, + dem_control: dem_control, + com_control: com_control, + dem_leaders: dem_leaders, + com_leaders: com_leaders + }; +} + +function battlegrounds(country) { + let battlegrounds = 0; + if (country === "Hungary") { + battlegrounds = 4 + } else if (country === "Bulgaria") { + battlegrounds = 5 + } else { + battlegrounds = 6 + } + return battlegrounds; +} + +function take_power(country) { + log(`Democrat takes power in ${game.pwr_struggle_in}`) + game.revolutions[find_country_index(country)] = true + game.times_held[find_country_index(country)] = 1 +} + +function retain_power(country){ + game.times_held[find_country_index(country)]++ + let vp_gain = get_value(country)*game.times_held[find_country_index(country)] + log(`Chooses to retain power`) + log(`-${vp_gain} VP`) + game.vp -= vp_gain +} + +function score_country(country) { + log_h3(`Scoring: ${country}`) + +//Get scoring values + let value_presence = get_value(country) + let value_domination = value_presence*2 + let value_control + if (country !== "Hungary") { + value_control = value_presence*3 + } else { + value_control = 4 + } + + let dem_vp = 0 + let com_vp = 0 + //Check for presence + let presence = check_presence(country) + + //If one side has domination or control + if (presence.dem_control || presence.dem_domination) { + log(`Democrat:`) + if (presence.dem_control) { + logi(`Control: +${value_control} VP`) + dem_vp += value_control + } + else { + logi(`Domination: +${value_domination} VP`) + dem_vp += value_domination + } + logi(`Battlegrounds: +${presence.dem_battlegrounds} VP`) + dem_vp += presence.dem_battlegrounds + log(`Total: +${dem_vp} VP`) + + log_gap('Communist:') + if (presence.com_spaces > 0) { + logi(`Presence: -${value_presence} VP`) + com_vp -= value_presence + if (presence.com_battlegrounds >0) { + logi(`Battlegrounds: -${presence.com_battlegrounds} VP`) + com_vp -= presence.com_battlegrounds + } + log(`Total: ${com_vp} VP`) + } else { + log('No presence: 0 VP') + } + } + else if (presence.com_control || presence.com_domination) { + log('Communist:') + if (presence.com_control) { + logi(`Control: -${value_control} VP`) + com_vp -= value_control + } + else { + logi(`Domination: -${value_domination} VP`) + com_vp -= value_domination + } + logi(`Battlegrounds: -${presence.com_battlegrounds} VP`) + com_vp -= presence.com_battlegrounds + log(`Total: ${com_vp} VP`) + + log_gap('Democrat:') + if (presence.dem_spaces > 0) { + logi(`Presence: +${value_presence} VP`) + dem_vp += value_presence + if (presence.dem_battlegrounds > 0) { + logi(`Battlegrounds: +${presence.dem_battlegrounds} VP`) + dem_vp += presence.dem_battlegrounds + } + log (`Total: +${dem_vp} VP`) + } else { + log('No presence: 0 VP') + } + } + + //Otherwise, presence and battlegrounds + else { + log("No domination or control") + log_gap(`Communist:`) + if (presence.com_spaces > 0) { + logi(`Presence: -${value_presence} VP`) + com_vp -= value_presence + if (presence.com_battlegrounds > 0) { + logi(`Battlegrounds: -${presence.com_battlegrounds} VP`) + com_vp -= presence.com_battlegrounds + } else { + logi('No battlegrounds') + } + logi(`Total: ${com_vp} VP`) + } else { + logi('No presence: 0 VP') + } + log_gap('Democrat:') + if (presence.dem_spaces > 0) { + logi(`Presence: +${value_presence} VP`) + dem_vp += value_presence + if (presence.dem_battlegrounds > 0) { + logi(`Battlegrounds: +${presence.dem_battlegrounds} VP`) + dem_vp += presence.dem_battlegrounds + } else { + logi('No battlegrounds') + } + logi(`Total: +${dem_vp} VP`) + } else { + logi('No presence: 0 VP') + } + } + +//Calculate change VP + let change_vp = dem_vp + com_vp + game.vp += change_vp + if (change_vp > 0 ) { + log_gap(`Scoring: +${change_vp} VP`) + } else { + log_gap(`Scoring: ${change_vp} VP`) + } +} + +function get_value(country) { + let value + if (country === "East_Germany" || country === "Poland") {value = 3} + else if (country === "Czechoslovakia" || country === "Romania") {value = 2} + else value = 1 + return value +} + +function get_end_infl_prompt() { + view.prompt = `${clean_name(cards[this_card()].name)}. Add SPs: done.` + if (!game.vm_infl_to_do) { + gen_action('end_round') + } else { + gen_action('done') + } +} + +function get_aftermath_roll() { + clear_undo() + let roll = roll_d6() + log(`Roll: D${roll}`) + let rally_win = 0 + let petition_win = 0 + if (rallies.includes(game.played_power_card) || game.proxy_power_card === 'Rally in the Square') { rally_win = 2} + if (petitions.includes(game.played_power_card) || game.proxy_power_card === 'Petition') { petition_win = 2} + let modified_roll = roll + game.raised_stakes + rally_win - petition_win + + // Special check for Yakovlev Counsels Gobachev. Applies only if Democrat wins, so only if Com is doing support loss and if Dem is doing VP roll + if (game.state === 'support_loss') { + if (game.active === COM && game.persistent_events.includes(C_YAKOVLEV_COUNSELS_GORBACHEV)) { + logi(`+1 from C${C_YAKOVLEV_COUNSELS_GORBACHEV}`) + modified_roll ++ + } + } else { + if (game.active === DEM && game.persistent_events.includes(C_YAKOVLEV_COUNSELS_GORBACHEV)) { + logi(`+1 from C${C_YAKOVLEV_COUNSELS_GORBACHEV}`) + modified_roll ++ + } + } + if (modified_roll < 0) {modified_roll = 0} + else if (modified_roll > 7) {modified_roll = 7} + + if (game.raised_stakes !== 0) { + logi(`+${game.raised_stakes} from Raising the Stakes`) + } + if (rally_win !== 0) { + logi('+2 from winning on a P1') + } + if (petition_win !== 0) { + logi('-2 from winning on a P31') + } + if (modified_roll !== roll) { + log(`Modified roll: ${modified_roll}`) + } + return modified_roll +} + +function add_to_persistent_events(card) { + game.persistent_events.push(card) + remove_from_discard(card) + //let silent_cards = [C_SYSTEMATIZATION, C_FOREIGN_CURRENCY_DEBT_BURDEN] + if (is_auto_resolve(card)) {log_gap(`C${card}:`)} +} + +function permanently_remove(card) { + game.persistent_events = game.persistent_events.filter( c => c !== card) + remove_from_discard(card) + if (!game.strategy_removed.includes(card)) { + game.strategy_removed.push(card) + } +} + +function check_vp() { + if (game.vp >= 20) { + goto_game_over(DEM, `${DEM} won an Automatic Victory!`) + return true + } else if(game.vp <= -20) { + goto_game_over(COM, `${COM} won an Automatic Victory!`) + return true + } + return false +} + +function game_over() { + if (game.vp >= 20 || game.vp <= -20) { + return true + } else { return false} +} + +function goto_game_over(result, victory) { + game.state = "game_over" + game.active = "None" + game.result = result + game.victory = victory + log_h1("Game Over") + log(game.victory) + return +} + +function goto_struggle(){ + game.raised_stakes_discard = 0 + game.valid_cards = [] + log_h2('Play Cards') + next_player() + game.state = 'power_struggle' + do_valid_cards() +} + +function reset_austria_hungary_border_reopened() { + game.austria_hungary_border_reopened_tracker = false +} + +function end_stasi_choose_card() { + if (game.stasi_card === C_COMMON_EUROPEAN_HOME) { + game.state = 'stasi_confirm' + } else { + game.round_player = COM + game.round ++ + log_h2(`Action Round ${game.round}`) + next_player() + game.valid_spaces = [] + if (game.persistent_events.includes(5)) { + log_h3('C5') + game.state = 'general_strike' + } else { + game.state = 'choose_card' + } + } +} + +function end_goddess() { + game.return_state = '' + log_h2("Action Round " + game.round) + if (game.active === DEM) { + next_player() + } else { + log_side() + } + if (game.persistent_events.includes(5)) { + game.state = 'general_strike' + } else { + game.state = 'choose_card' + } +} + +function check_reformer() { /*Is this function still used?*/ + if (game.dem_tst_position !== game.com_tst_position) { + if (!game.playable_cards.includes(67)) { + game.playable_cards.push(67) + } + } else { + game.playable_cards = game.playable_cards.filter(n => n !== 67) + } +} + +function count_scoring_cards() { + let scoring_check + if (game.active === DEM) { + scoring_check = game.democrat_hand.filter(card => scoring_cards.includes(card)).length + } else { + scoring_check = game.communist_hand.filter(card => scoring_cards.includes(card)).length + } + return scoring_check +} + +function select_card(card){ + game.played_card = card + game.temp = 0 + let find_card + if (game.active === COM) { + find_card = game.communist_hand.indexOf(card) + game.communist_hand.splice(find_card, 1) + } else { + find_card = game.democrat_hand.indexOf(card) + game.democrat_hand.splice(find_card, 1) + } + game.available_ops = get_card_ops(card) + + //Check Ligachev + if (game.active === DEM && game.persistent_events.includes(99) && card !== C_GORBACHEV_CHARMS_THE_WEST) { + log(`-3 VP from C${C_LIGACHEV}`) + game.vp -= 3 + if (check_vp()) { + return + } + game.persistent_events = game.persistent_events.filter(n => n !== 99) + game.strategy_removed.push(C_LIGACHEV) + } + game.state = 'play_card' +} + +function is_auto_resolve(card) { + let ceausecu_events = [10, 41, 69, 101, 107] + if (auto_resolve_events.includes(card)) { + return true + } + else if (card === C_THE_TYRANT_IS_GONE) { + if (game.persistent_events.includes(C_THE_CROWD_TURNS_AGAINST_CEAUSESCU)) { + return true + } + } + else if (ceausecu_events.includes(card) && game.persistent_events.includes(THE_TYRANT_IS_GONE_OCCURRED)) { + return true + } + else if (card === C_KOHL_PROPOSES_REUNIFICATION && !game.persistent_events.includes(C_THE_WALL_MUST_GO)) { + return true + } + else if (card === C_BROUGHT_IN_FOR_QUESTIONING && game.active === DEM) { + if (game.democrat_hand.length === 0) { + if (!game.state.startsWith('vm')) { logi('Democrat has no cards to discard') } + return true } + } + else if (card === C_DEUTSCHE_MARKS && game.active === DEM) { + if (game.democrat_hand.length === 0) { + if (!game.state.startsWith('vm')) { logi('Democrat has no cards to give') } + return true } + } + else if (card === C_KISS_OF_DEATH && game.active === COM) { + if (game.communist_hand.length === 0) { + if (!game.state.startsWith('vm')) { logi('Communist has no cards to discard') } + return true } + } + else if (card === C_DISSIDENT_ARRESTED && game.active === DEM) { + let dem_intellectual_infl = spaces.filter(space => space.socio === 5 && game.demInfl[space.space_id] > 0).length + if (dem_intellectual_infl === 0) { + if (!game.state.startsWith('vm')) { logi('No influence to remove') } + return true + } + } else if ((card === C_SAJUDIS || card === C_THE_BALTIC_WAY) && game.active === COM) { + if (game.systematization && game.systematization === S_HARGHITA_COVASNA ) { + if (check_dem_control(S_RAZGRAD)) { + if (!game.state.startsWith('vm')) { logi('Minorities spaces already controlled') } + return true + } + } else if (check_dem_control(S_RAZGRAD) && check_dem_control(S_HARGHITA_COVASNA)) { + if (!game.state.startsWith('vm')) { logi('Minorities spaces already controlled') } + return true + } + } else if (card === C_CEAUSESCU && game.active === DEM) { + let dem_romania_infl = spaces.filter(space => space.country === 'Romania' && game.demInfl[space.space_id] > 0).length + if (dem_romania_infl === 0) { + if (!game.state.startsWith('vm')) { logi('No influence to remove') } + return true + } + } + else if (card === C_WE_ARE_THE_PEOPLE && game.active === COM) { + if (game.demInfl[S_LUTHERAN_CHURCH] === 0) { + if (!game.state.startsWith('vm')) { logi('No influence to remove') } + return true + } + } + else if (card === C_BETRAYAL && game.active === DEM) { + if (!game.systematization === S_ORTHODOX_CHURCH_ROMANIA) { + if (game.demInfl[S_ORTHODOX_CHURCH_BULGARIA] === 0) { + if (!game.state.startsWith('vm')) { logi('No influence to remove') } + return true + } + } else if (game.demInfl[S_ORTHODOX_CHURCH_BULGARIA] === 0 && game.demInfl[S_ORTHODOX_CHURCH_ROMANIA] === 0) { + if (!game.state.startsWith('vm')) { logi('No influence to remove') } + return true + } + } + else if (card === C_GOVERNMENT_RESIGNS && game.active === COM) { + let uncontrolled_elites = spaces.filter( space => spaces[space.space_id].socio === 1 && game.comInfl[space.space_id] > 0 && !check_control(space.space_id)).length + if (uncontrolled_elites === 0) { + if (!game.state.startsWith('vm')) { logi('No uncontrolled Elite spaces') } + return true + } + } else if (card === C_ST_NICHOLAS_CHURCH && game.active === COM) { + if (check_dem_control(S_LUTHERAN_CHURCH)) { + if (!game.state.startsWith('vm')) { logi('Lutheran Church already controlled') } + return true + } + } else if (card === C_BULGARIAN_TURKS_EXPELLED && game.active === DEM) { + if (game.demInfl[S_RAZGRAD] === 0 ) { + if (!game.state.startsWith('vm')) { logi('No influence to remove') } + return true + } + } else if (card === C_NORMALIZATION && game.active === DEM) { + if (game.demInfl[S_PRAHA] === 0 && game.demInfl[S_PLZEN] === 0 ) { + if (!game.state.startsWith('vm')) { logi('No influence to remove') } + return true + } + } else if (card === C_DOMINO_THEORY) { + if (game.revolutions.filter(value => value === true).length < 2) { + return true + } else if (!scoring_cards.some(card => game.strategy_discard.includes(card))) { + return true + } + } else if (card === C_UNION_OF_DEMOCRATIC_FORCES && game.active === COM) { + let bulgarian_presence = spaces.filter(space => space.country === 'Bulgaria' && game.comInfl[space.space_id] > 0).length + if (bulgarian_presence === 0) { + if (!game.state.startsWith('vm')) { logi('No SPs to remove') } + return true + } + } else if (card === C_EXIT_VISAS && game.active === COM) { + if (game.democrat_hand.length === 0) { + if (!game.state.startsWith('vm')) { logi('Democrat has no cards to discard') } + return true + } + } else if (card === C_SAMIZDAT && game.active === COM) { + if (game.democrat_hand.length === 0) { + if (!game.state.startsWith('vm')) { logi('Democrat has no cards to set aside') } + return true + } + } else if (card === C_SPITZEL && game.active === DEM) { + let dem_germany_infl = spaces.filter(space => space.country === 'East_Germany' && game.demInfl[space.space_id] > 0).length + if (dem_germany_infl === 0) { + if (!game.state.startsWith('vm')) { logi('No influence to remove') } + return true + } + } else if (card === C_MY_FIRST_BANANA && game.active === COM) { + let com_germany_infl = spaces.filter(space => space.country === 'East_Germany' && game.comInfl[space.space_id] > 0).length + if (com_germany_infl === 0) { + if (!game.state.startsWith('vm')) { logi('No influence to remove') } + return true + } + } else if (card === C_POLITBURO_INTRIGUE && game.active === DEM) { + let dem_bulgaria_infl = spaces.filter(space => space.country === 'Bulgaria' && game.demInfl[space.space_id] > 0).length + if (dem_bulgaria_infl === 0) { + if (!game.state.startsWith('vm')) { logi('No influence to remove') } + return true + } + } + else { + return false + } +} + +function get_events(card){ + if (event_is_playable(card)) { + if (cards[card].side === 'D') { + if (game.active === DEM) {gen_action('event')} + if (game.active === COM) {gen_action('opp_event')} + } + else if (cards[card].side === 'C') { + if (game.active === COM) {gen_action('event')} + if (game.active === DEM) {gen_action('opp_event')} + } + else { + gen_action('event') + } + } +} + +function event_is_playable(card) { + //Reformer never playable here + if (card === C_REFORMER_REHABILITATED) { + return false + } + //Check for Common European Home under Stasi + else if (game.stasi_card === C_COMMON_EUROPEAN_HOME && card === C_COMMON_EUROPEAN_HOME && game.active === DEM) { + return false + } + //Check for The Chinese Solution + else if (game.com_tst_position >= 7 && card === C_THE_CHINESE_SOLUTION) { + return true + } + + //Check for Gorbachev Charms the West after Breakaway Baltic Republics + else if (card === C_GORBACHEV_CHARMS_THE_WEST && !game.playable_cards.includes(C_GORBACHEV_CHARMS_THE_WEST)) { + return false + } + //Then check normally + else if (game.playable_cards.includes(card)) { + return true + } else if (cards[card].playable) { + return true + } else { + return false + } +} + +function get_card_ops(card) { + let ops = cards[card].ops + if (game.persistent_events.includes(C_PERESTROIKA) && game.active === COM) { + if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_common_european_home_play' || game.state === 'general_strike') { + log(`+1 op from C${C_PERESTROIKA}`) + } + ops ++ + } + if (game.persistent_events.includes(C_THE_SINATRA_DOCTRINE) && game.active === DEM) { + if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_common_european_home_play' || game.state === 'vm_laszlo_tokes') { + log(`+1 op from C${C_THE_SINATRA_DOCTRINE}`) + } + ops ++ + } + + if ((game.active === DEM && game.dem_tst_position >= 2 && game.com_tst_position <= 1 && cards[card].ops === 1) || (game.active === COM && game.com_tst_position >=2 && game.dem_tst_position <= 1 && cards[card].ops === 1)) { + if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_common_european_home_play') { + log('+1 op from Tiananmen Square Track') + } + ops ++ + } + + if ((game.active === DEM && game.prudence && game.prudence.DEM !== 0)) { + if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_common_european_home_play' || game.state === 'vm_laszlo_tokes') { + if (ops > 2) { + log(`${pluralize(game.prudence.DEM,'op')} from C${C_PRUDENCE}`) + } else { + if (ops > 1) { + log(`-1 op from C${C_PRUDENCE}`) + } + } + } + ops += game.prudence.DEM + + if (ops < 1) { + ops = 1 + } + } + + if (game.active === COM && game.prudence && game.prudence.COM < 0) { + if(game.state === 'choose_card' || game.state === 'general_strike' || game.state === 'vm_common_european_home_play') { + if (ops > 2) { + log(`${pluralize(game.prudence.COM,'op')} from C${C_PRUDENCE}`) + } else if (ops > 1) { + log(`-1 op from C${C_PRUDENCE}`) + } + } + ops += game.prudence.COM + if (ops < 1) { + ops = 1 + } + } return ops +} + +function get_tst_6_ops() { + let ops = 0 + if (game.persistent_events.includes(C_PERESTROIKA) && game.active === COM) { + logi(`+1 op from C${C_PERESTROIKA}`) + ops ++ + } + if (game.persistent_events.includes(C_THE_SINATRA_DOCTRINE) && game.active === DEM) { + logi(`+1 op from C${C_THE_SINATRA_DOCTRINE}`) + ops ++ + } + if ((game.active === DEM && game.prudence && game.prudence.DEM !== 0)) { + if (ops > 0) { + log(`${pluralize(game.prudence.DEM,'op')} from C${C_PRUDENCE}`) + } else { + logi(`-1 op from C${C_PRUDENCE}`) + } + ops += game.prudence.DEM + if (ops < -1) { + ops = -1 + } + } + + if (game.active === COM && game.prudence && game.prudence.COM < 0) { + if (ops > 0) { + logi(`${pluralize(game.prudence.COM,'op')} from C${C_PRUDENCE}`) + } else { + logi(`-1 op from C${C_PRUDENCE}`) + } + ops += game.prudence.COM + if (ops < -1) { + ops = -1 + } + } + return ops +} + +function finish_play_card() { + // Check if Common European Home played for influence + if (game.played_card === C_COMMON_EUROPEAN_HOME) { + if (game.active === DEM) { + game.vp -- + logi(`-1 VP for playing C${C_COMMON_EUROPEAN_HOME} for operations`) + } else { + game.vp ++ + logi(`+1 VP for playing C${C_COMMON_EUROPEAN_HOME} for operations`) + } + if (check_vp()) { + return + } + } + // Check if card is opponent card with event that needs to be resolved + + if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) { + if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) { + game.vm_event_to_do = true + } + } +} + +function finish_the_wall() { + if (game.the_wall_must_go['dem_wins'] === 2) { + game.persistent_events.push(C_THE_WALL_MUST_GO) + game.playable_cards = game.playable_cards.filter(card => card !== C_THE_WALL) + log('+3 VP') + game.vp += 3 + if (check_vp()) { + return + } + for (let i = 0; i < spaces.length; i++) { + let space = spaces[i] + if (space.country === 'East_Germany' && game.comInfl[i] > 0){ + game.valid_spaces.push(space.space_id) + } + } + if (game.active === DEM) {next_player()} + game.return = COM + vm_next () + } else { + permanently_remove(C_THE_WALL_MUST_GO) + delete game.the_wall_must_go + if (game.vm_infl_to_do) { + game.return = COM + } else { + game.return = game.active + } + vm_return() + } +} + +// =========== MOVING THROUGH TURNS ============ + +function end_round() { + //Check if the game is over! WHY IS THIS NEEDED? + if (game.state === 'game_over') { + return} + + //Check if the card needs to be discarded. + let discard_check = [...game.strategy_removed, ...game.persistent_events] + if (!discard_check.includes(game.played_card) && game.played_card > 0) { + game.strategy_discard.push(game.played_card) + } + + //Reset + game.played_card = 0 + delete game.temp + delete game.vm_event + delete game.phase + game.remove_opponent_infl = false + game.is_pwr_struggle = false + game.vm_infl_to_do = false /*Can get rid of this and use game.return_state? */ + delete game.vm_event_to_do + delete game.vm_infl_to_do + delete game.vm_active_country + game.return_state = '' + game.discard = false + game.return = '' + game.valid_cards = [] + game.valid_spaces = [] + check_common_european_home() + reset_austria_hungary_border_reopened() /*This should be redundant! */ + + // Check for duplicate card entries + let card_check + if (game.samizdat_card > 0) { + card_check = [...game.strategy_deck, ...game.strategy_discard, ...game.strategy_removed, ...game.persistent_events, ...game.communist_hand, ... game.democrat_hand, game.samizdat_card]; + } else { + card_check = [...game.strategy_deck, ...game.strategy_discard, ...game.strategy_removed, ...game.persistent_events, ...game.communist_hand, ... game.democrat_hand]; + } + card_check = card_check.filter(card => card <= last_strategy_card) + function check_duplicates(array) { + return new Set(array).size !== array.length; + } + + function find_duplicates(array) { + const duplicates = array.filter((item, index) => array.indexOf(item) !== index); + return [...new Set(duplicates)]; + } + + card_check = card_check.sort((a, b) => a - b) + + if (check_duplicates(card_check)) { + console.log('duplicate cards: card check', card_check) + const duplicates = find_duplicates(card_check) + console.log('game.strategy_deck', game.strategy_deck, 'game.strategy_discard', game.strategy_discard, 'game.strategy_removed', game.strategy_removed, 'game.persistent_events', game.persistent_events, 'game.communist_hand', game.communist_hand, 'game.democrat_hand', game.democrat_hand) + throw new Error(`Duplicate cards detected: ${duplicates.join(', ')}`) + } + + if (game.turn <= 3) { + if (card_check.length !== 40) { + console.log('wrong number of cards in game', card_check) + throw new Error(`Wrong number of cards: ${card_check.length}`) + } + } else if (game.turn <=7) { + if (card_check.length !== 81) { + console.log('wrong number of cards in game', card_check) + throw new Error(`Wrong number of cards: ${card_check.length}`) + } + } else if (card_check.length !== 110) { + console.log('Entire array:', JSON.stringify(card_check)) + throw new Error(`Wrong number of cards: ${card_check.length}`) + } + + //Check if the Reformer is playable + check_reformer() + + // Check if last round and if so resolve end turn events + if (game.round_player === DEM && game.round === 7) { + if(game.persistent_events.includes(C_HONECKER)) { + if (game.active !== COM) { + next_player() + } + game.state = 'honecker' + return + } + else if (game.dem_tst_position >= 6 && game.com_tst_position <= 5) { + if (game.active !== DEM) { + next_player() + } + game.return = game.active + clear_undo() + game.return_state = 'end_turn_4_5_4' + goto_vm(206) + return + } else if (game.com_tst_position >= 6 && game.dem_tst_position <= 5) { + if (game.active !== COM) { + next_player() + } + game.return = game.active + clear_undo() + game.return_state = 'end_turn_4_5_4' + goto_vm(206) + return + } + else { + clear_undo() + game.state = 'end_turn_4_5_4' + return + } + } + + // Resolve end action round + //Stasi check + if(game.round_player === COM && game.persistent_events.includes(C_STASI)) { + //If in Honecker, turn ends + if (game.round === 8) { + clear_undo() + game.state = 'end_turn_4_5_4' + return + } + //Otherwise go to Stasi + game.round_player = DEM + if (game.active !== DEM) { + next_player() + } else { + log_h3('Democratic Action Round') + } + if (game.democrat_hand.includes(game.stasi_card)) { + log_h3('C13') + game.state = 'stasi_play_card' + } else { + game.stasi_card = 0 + game.state = 'choose_card' + } + return + } + //Check if in extra Action Round + else if (game.round_player === COM && game.round === 8) { + clear_undo() + game.state = 'end_turn_4_5_4' + return + } + //Normal round end + else if (game.round_player===COM) { + game.round_player = DEM + if (game.active !== DEM) { + next_player() + } else { + log_h3('Democratic Action Round') + } + game.state = 'choose_card' + return + } + if (game.round_player === DEM) { + + if(game.persistent_events.includes(C_STASI)) { + if (game.active !== DEM) { + next_player() + } + log_h3('C13') + game.state = 'stasi_end_round' + return + } else if(game.round_player === DEM && game.persistent_events.includes(C_GENERAL_STRIKE)){ + game.state = 'general_strike' + game.round ++ + log_h2(`Action Round ${game.round}`) + game.round_player = COM + if (game.active !== COM) { + next_player() + } + log_h3('C5') + return + } else { + game.state = 'choose_card' + game.round_player = COM + game.round ++ + log_h2(`Action Round ${game.round}`) + if (game.active !== COM) { + next_player() + } + } + } +} + +function new_turn() { + clear_undo() + game.turn ++ + game.round = 1 + game.valid_spaces=[] + game.active = COM + game.round_player = COM + game.dem_tst_attempted_this_turn = 0 + game.com_tst_attempted_this_turn = 0 + if (game.tst_7) {game.tst_7 = false} + if (game.tst_8) {game.tst_8 = false} + delete game.selected_space + + //Remove events that only last one turn + + for (let e of one_turn_events) { + if (game.persistent_events.includes(e)) { + end_one_turn_event(e) + } + } + if (game.prudence) { + delete game.prudence + log_summary(`C${8}`) + } + if (game.summary.length > 0) { + log('No longer in effect:') + pop_summary_i() + log_br() + } + delete game.stasi_card + delete game.stand_fast + + if (game.samizdat_card > 0 ) { + game.democrat_hand.push(game.samizdat_card) + delete game.samizdat_card + } + + log_h1("Turn " + game.turn) + + if (game.turn === 4) { add_midyear() } + if (game.turn === 8) { add_lateyear() } + + if (game.turn > 1) { + if (game.persistent_events.includes(C_PRESIDENTIAL_VISIT)) { + game.com_hand_limit = 7 + log('Communist draws 7 cards due to C65') + permanently_remove(C_PRESIDENTIAL_VISIT) + game.persistent_events = game.persistent_events.filter( card => card !== C_PRESIDENTIAL_VISIT) + } + draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.dem_hand_limit, game.com_hand_limit) + game.com_hand_limit = 8 + } + + //Check if TST effects need to be resolved + if ((game.dem_tst_position >=5 && game.com_tst_position <= 4) || (game.com_tst_position >= 5 && game.dem_tst_position <= 4)) { + log_h2('Tiananmen Square Track Award') + + if ((game.dem_tst_position >= 5 && game.com_tst_position <= 4 && game.active !== DEM) || (game.com_tst_position >= 5 && game.dem_tst_position <= 4 && game.active !== COM)) { + next_player() + } + let hand = game.dem_tst_position >=5 ? game.democrat_hand : game.communist_hand + for (let card of hand) { + if (scoring_cards.includes(card)) continue + game.valid_cards.push(card) + } + game.state = 'tst_goddess' + } else { + log_h2("Action Round " + game.round) + log_side() + if (game.persistent_events.includes(5)) { + log_h3('C5') + game.state = 'general_strike' + } + else { + game.state = 'choose_card' + } + } +} + +function end_one_turn_event(event) { + game.persistent_events = game.persistent_events.filter(n => n !== event) + game.strategy_removed.push(event) + log_summary(`C${event}`) +} + +function next_player() { + clear_undo() + if (game.active === DEM) + game.active = COM + else + game.active = DEM + log_side() +} + +function change_player() { + clear_undo() + if (game.active === DEM) + game.active = COM + else + game.active = DEM +} + +function random(range) { + return (game.seed = game.seed * 200105 % 34359738337) % range +} + +function roll_d6() { + return random(6) + 1 +} + +function find_country_index(country) { + return countries.indexOf(country) +} + +function draw_deck() { + let deck = [] + for (let c = first_strategy_card; c <= last_strategy_card; ++c) + if (cards[c].period === 1) + deck.push(c) + return deck +} + +function draw_cards(deck, democrat_hand, communist_hand, dem_hand_limit, com_hand_limit) { + //Start with the communist player + let turn = 'communist'; + while (democrat_hand.length < dem_hand_limit || communist_hand.length < com_hand_limit) { + if (deck.length === 0) { + log_h3('--- Reshuffle ---') + deck.push(...game.strategy_discard) + game.strategy_discard = [] + } else if (turn === 'communist' && communist_hand.length < com_hand_limit) { + communist_hand.push(draw_card(deck)); + turn = 'democrat'; + } else if(turn === 'communist' && communist_hand.length === com_hand_limit) { + turn = 'democrat'; + } + else if (turn === 'democrat' && democrat_hand.length < dem_hand_limit) { + democrat_hand.push(draw_card(deck)); + turn = 'communist'; + } + else if (turn === 'democrat' && democrat_hand.length === dem_hand_limit) { + turn = 'communist'; + } + } + clear_undo() +} + +function draw_card(deck) { + if (deck.length === 0) { + log_h3('--- Reshuffle ---') + deck.push(...game.strategy_discard) + game.strategy_discard = [] + } + const randomIndex = Math.floor(random(deck.length)) + return deck.splice(randomIndex, 1)[0]; +} + +function discard(card) { + let find_card + if (!game.is_pwr_struggle) { + if (game.active === COM) { + find_card = game.communist_hand.indexOf(card) + game.communist_hand.splice(find_card, 1) + } else { + find_card = game.democrat_hand.indexOf(card) + game.democrat_hand.splice(find_card, 1) + } + if (!game.strategy_discard.includes(card)) { + game.strategy_discard.push(card) + log(`Discarded C${card}`) + } + } else if (game.is_pwr_struggle) { + if (game.active === COM) { + find_card = game.com_pwr_hand.indexOf(card); + game.com_pwr_hand.splice(find_card, 1); + } else { + find_card = game.dem_pwr_hand.indexOf(card); + game.dem_pwr_hand.splice(find_card, 1); + } + game.power_struggle_discard.push(card) + } +} +function silent_discard(card) { + let find_card + if (!game.is_pwr_struggle) { + if (game.active === COM) { + find_card = game.communist_hand.indexOf(card) + game.communist_hand.splice(find_card, 1) + } else { + find_card = game.democrat_hand.indexOf(card) + game.democrat_hand.splice(find_card, 1) + } + if (!game.strategy_discard.includes(card)) { + game.strategy_discard.push(card) + } + } else if (game.is_pwr_struggle) { + if (game.active === COM) { + find_card = game.com_pwr_hand.indexOf(card); + game.com_pwr_hand.splice(find_card, 1); + } else { + find_card = game.dem_pwr_hand.indexOf(card); + game.dem_pwr_hand.splice(find_card, 1); + } + game.power_struggle_discard.push(card) + } +} + +function remove_from_discard(card) { + let card_index = game.strategy_discard.indexOf(card) + if (card_index !== -1) { + game.strategy_discard.splice(card_index, 1) + } +} + +function discard_card(hand) { + let card = Math.floor(random(hand.length)) + let discarded_card = hand.splice(card, 1)[0] + if (game.is_pwr_struggle) { + if (numberless_cards.includes(discarded_card)) { + logi(`Discarded: P${discarded_card}`) + } else { + logi(`Discarded: P${discarded_card} V${power_cards[discarded_card].value}`) + } + game.power_struggle_discard.push(discarded_card) + } else { + log(`Discarded C${discarded_card}`) + game.strategy_discard.push(discarded_card) + } + return discarded_card +} + +function add_midyear() { + for (let c = first_strategy_card; c <= last_strategy_card; ++c) + if (cards[c].period === 2) + game.strategy_deck.push(c) + log_h3('Mid-year cards added to draw deck') +} + +function add_lateyear() { + for (let c = first_strategy_card; c <= last_strategy_card; ++c) + if (cards[c].period === 3) + game.strategy_deck.push(c) + log_h3('Late-year cards added to draw deck') +} + +function reset_power() { + game.power_struggle_deck = [] + game.power_struggle_discard = [] + game.dem_pwr_hand = [] + game.com_pwr_hand = [] + delete game.phase + delete game.raised_stakes_round + delete game.raised_stakes + delete game.raised_stakes_discard + delete game.played_power_card + delete game.tactics_fails + delete game.view_opp_power_hand + + let scoring_events = [C_PEASANT_PARTIES_REVOLT, C_YAKOVLEV_COUNSELS_GORBACHEV, C_THE_CROWD_TURNS_AGAINST_CEAUSESCU] + for (let e of scoring_events ) { + if (e === C_THE_CROWD_TURNS_AGAINST_CEAUSESCU ) { + if (game.persistent_events.includes(e) && game.pwr_struggle_in === 'Romania') { + permanently_remove(e) + } + } else if (game.persistent_events.includes(e)) { + permanently_remove(e) + } + } +} + +function check_tyrant() { + if (game.the_tyrant_is_gone > 0 && check_dem_control(game.the_tyrant_is_gone)) { + log('+2 VP from C97') + game.vp += 2 + if (check_vp()) { + return + } + delete game.the_tyrant_is_gone + } +} + +function resolve_tyrant() { + if (game.persistent_events.includes(C_THE_TYRANT_IS_GONE) && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(THE_CROWD_TURNS_AGAINST_CEAUSESCU_OCCURRED)) { + game.return_state = 'finish_scoring' + if (game.active !== DEM) { + next_player() + } + game.state = 'the_tyrant_is_gone' + } else { + game.state = 'finish_scoring' + } +} + +function check_systematization() { /* Check for Systematization - may not use this space */ + if (game.systematization > 0) { + game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization) + } +} + +function check_common_european_home() { + if (!game.playable_cards.includes(C_COMMON_EUROPEAN_HOME)) { + game.playable_cards.push(C_COMMON_EUROPEAN_HOME) + } +} + +function this_card() { + return game.vm_event > 0 ? game.vm_event : game.played_card +} + +const pluralize = (count, noun, suffix = 's') => { + if (Math.abs(count) === 1) { + return `${count} ${noun}` + } else { + if (noun.endsWith('y') && !/[aeiou]y$/.test(noun)) { + noun = noun.slice(0, -1) + 'ie' + } + return `${count} ${noun}${suffix}` + } +} + +function clean_name(str) { + if (str && str.slice(-1) === '*') { + return str.slice(0, -1) + } else { + return str; + } +} + +function country_name(country) { + return country.replace(/_/g, ' ') +} + +// ======== LOG FUNCTIONS ============= + +function log(msg) { + game.log.push(msg) +} + +function log_br() { + if (game.log.length > 0 && game.log[game.log.length - 1] !== "") + game.log.push("") +} + +function logi(msg) { + game.log.push(">" + msg) +} + +function log_h1(msg) { + log_br() + log(".h1 " + msg) + log_br() +} + +function log_h2(msg) { + log_br() + log(".h2 " + msg) + log_br() +} + +function log_h3(msg) { + log_br() + log(".h3 " + msg) +} + +function log_gap(msg) { + log_br() + game.log.push(msg) +} + +function log_msg_gap(msg) { + game.log.push(msg) + log_br() +} + + +function log_side() { + log_br() + if (game.active === DEM) + log(".h2d " + game.active) + else + log(".h2c " + game.active) + log_br() +} + +function log_sep() { + log(".hr") +} + +function log_action(msg) { + log_br() + log(msg) +} + +// ============= SUMMARY FUNCTIONS ============= + +function push_summary() { + if (game.summary) + throw "TOO MANY SUMMARIES" + game.summary = [] +} + +function log_summary(msg) { + + if (msg.startsWith('Added') || msg.startsWith('Removed')) { + for (let item of game.summary) { + if (item[1] === msg) { + item[0]++ + return + } + } + } + game.summary.push([1, msg]) +} + +function pop_summary() { + if (game.summary.length > 0) { + for (let [n, msg] of game.summary) { + if (n > 1) { + log(msg.replace("£ SP", `${n} SPs`)); + } else { + log(msg.replace("£ SP", `${n} SP`)); + } + } + } + game.summary = [] +} + +function pop_summary_i() { + if (game.summary.length > 0) { + for (let [n, msg] of game.summary) { + if (n > 1) { + logi(msg.replace("£ SP", `${n} SPs`)); + } else { + logi(msg.replace("£ SP", `${n} SP`)); + } + } + } + game.summary = [] +} + +function do_log_summary() { + if (game.summary.length > 0) { + pop_summary() + log_br() + } +} + +// ============ UNDO FUNCTIONS ================== + +function clear_undo() { + if (game.undo.length > 0) + game.undo = [] +} + +function push_undo() { + let copy = {} + for (let k in game) { + let v = game[k] + if (k === "undo") + continue + else if (k === "log") + v = v.length + else if (typeof v === "object" && v !== null) + v = object_copy(v) + copy[k] = v + } + game.undo.push(copy) +} + +function pop_undo() { + let save_log = game.log + let save_undo = game.undo + game = save_undo.pop() + save_log.length = game.log + game.log = save_log + game.undo = save_undo +} + +// Fast deep copy for objects without cycles +function object_copy(original) { + if (Array.isArray(original)) { + let n = original.length + let copy = new Array(n) + for (let i = 0; i < n; ++i) { + let v = original[i] + if (typeof v === "object" && v !== null) + copy[i] = object_copy(v) + else + copy[i] = v + } + return copy + } else { + let copy = {} + for (let i in original) { + let v = original[i] + if (typeof v === "object" && v !== null) + copy[i] = object_copy(v) + else + copy[i] = v + } + return copy + } +} + + +/* =================== VM FUNCTIONS ========================== */ + +function goto_vm(proc) { + let old_vm = game.vm; + + game.state = "vm"; + game.vm = { + prompt: 0, + fp: proc, + ip: 0, + }; + + if (old_vm) { + game.vm.return_vm = old_vm; + } + + vm_exec(); +} + +function vm_exec() { + vm_inst(0)(); +} + +function vm_inst(a) { + return CODE[game.vm.fp][game.vm.ip][a] +} + +function vm_next() { + game.vm.ip++; + vm_exec(); +} + +function vm_logi(){ + logi(vm_operand(1)) + vm_next() +} + +function vm_operand(a) { + let x = CODE[game.vm.fp][game.vm.ip][a] + if (a > 0 && typeof x === "function") + return x() + return x +} + +function vm_if() { + if (!vm_operand(1)) { + let balance = 1 + while (balance > 0) { + ++game.vm.ip + switch (vm_operand(0)) { + case vm_if: + ++balance + break + case vm_endif: + --balance + break + case vm_else: + if (balance === 1) + --balance + break + } + if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length) + throw "ERROR" + } + } + vm_next() +} + +function vm_else() { + vm_goto(vm_endif, vm_if, 1, 1) +} + +function vm_endif() { + vm_next() +} + +function vm_goto_step(step) { + for (let i = game.vm.ip; i < CODE[game.vm.fp].length; i++) { + if (CODE[game.vm.fp][i][0] === step) { + game.vm.ip = i; + vm_exec(); + return; + } + } + + console.log("ERROR: Target operation not found in the current procedure."); +} + + +function vm_goto(op, nop, dir, step) { + let balance = 1 + while (balance > 0) { + game.vm.ip += dir + if (vm_inst(0) === op) + --balance + if (vm_inst(0) === nop) + ++balance + if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length) + throw "ERROR" + } + game.vm.ip += step + vm_exec() +} + +function event_prompt(str) { + if (typeof str === "undefined") + str = CODE[game.vm.fp][game.vm.prompt][1] + if (typeof str === "function") + str = str() + if (!str) { + str = "" + } + return str +} + +function vm_prompt() { + if (game.vm.prompt) + game.vm._prompt = game.vm.prompt + game.vm.prompt = game.vm.ip + vm_next() +} + +function vm_return() { + //Remove temporary vm variables + delete game.support_check_modifier + delete game.vm_max_infl + delete game.vm_influence_added + delete game.communist_hand_red + game.vm_event = 0 /*Reset to 0 now that event has been completed. Hopefully this doesn't cause issues! */ + if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) { + reset_austria_hungary_border_reopened() + } + + //Check if end event state is needed + if (game.is_pwr_struggle || game.state === 'vm_tst_6' || game.return_state === 'tiananmen_square_attempt_done') { + vm_end_event() + } + //Check if auto-resolve opponent event + else if (is_auto_resolve(game.played_card) && ((cards[game.played_card].side === 'C' && game.active === DEM) || (cards[game.played_card].side === 'D' && game.active === COM) )) { + vm_end_event() + } + else { + game.state = 'vm_end_event' + } +} + +function vm_end_event() { + if (game.return !== game.active) { + next_player()} + if (game.return_state === 'power_struggle') { + do_valid_cards() + } + if (game.return_state && game.return_state !== '') { + game.state = game.return_state + } + else if (game.vm_infl_to_do) { + game.state = 'resolve_opponent_event'} + else { + end_round() + } +} + +/* ================== VM ACTIONS =========================== */ + +function vm_valid_spaces() { + for (let i = 1; i <= 6; i++) { + let operand = vm_operand(i) + if (operand) { + let space = spaces.find(space => space.ascii_name === operand) + game.valid_spaces.push(space.space_id) + } + } + check_systematization(); + vm_next(); +} + +function vm_valid_spaces_com() { + let operand = vm_operand(1) + let space = spaces.find(space => space.ascii_name === operand) + if (game.comInfl[space.space_id] >0) { + game.valid_spaces.push(space.space_id) + } + check_systematization(); + vm_next(); +} + +function vm_valid_spaces_opponent () { + let valid_spaces = [] + for (let i = 0; i < spaces.length; i++) { + let space = spaces[i] + + if (game.active === DEM) { + let infl = game.comInfl[i] + if (infl > 0) { + valid_spaces.push(space.space_id) + } + } else { + let infl = game.demInfl[i] + if (infl > 0) { + valid_spaces.push(space.space_id) + } + } + } + game.valid_spaces = valid_spaces + vm_next() +} + +function vm_valid_spaces_socio () { + let valid_spaces = [] + for (let i = 0; i < spaces.length; i++) { + let space = spaces[i] + if (space.socio === vm_operand(1)) { + valid_spaces.push(space.space_id) + } + } + game.valid_spaces = valid_spaces + check_systematization() + vm_next() +} + +function vm_valid_spaces_opponent_socio () { + let valid_spaces = [] + for (let i = 0; i < spaces.length; i++) { + let space = spaces[i] + if (game.active === DEM) { + let infl = game.comInfl[i] + if (infl > 0 && space.socio === vm_operand(1)) { + valid_spaces.push(space.space_id) + } + } else { + let infl = game.demInfl[i] + if (infl > 0 && space.socio === vm_operand(1)) { + valid_spaces.push(space.space_id) + } + } + } + game.valid_spaces = valid_spaces + check_systematization() + vm_next() +} + +function vm_valid_spaces_country () { + let country + if (vm_operand(1)) {country = vm_operand(1)} + else {country = game.vm_active_country} + for (let space of spaces) { + if (space.country === country) { + game.valid_spaces.push(space.space_id); + } + } + check_systematization() + vm_next() +} + +function vm_valid_spaces_sc () { + valid_spaces_sc() + vm_next() +} + +function vm_valid_spaces_country_opp () { + let country = '' + if (vm_operand(1)) { + country = vm_operand(1) } + else { + country = game.vm_active_country + } + for (let space of spaces) { + if (game.active === DEM) { + if (space.country === country && game.comInfl[space.space_id] >0) { + game.valid_spaces.push(space.space_id); + } + } else { + if (space.country === country && game.demInfl[space.space_id]>0) { + game.valid_spaces.push(space.space_id); + } + } + } + vm_next() +} + +function vm_valid_spaces_country_sc () { + let active_country + if (vm_operand(1)) { + active_country = vm_operand(1) } + else { + active_country = game.vm_active_country + } + valid_spaces_sc() + game.valid_spaces = game.valid_spaces.filter( s => spaces[s].country === active_country) + vm_next() +} + +function vm_valid_spaces_country_socio_2() { + for (let space of spaces) { + if (space.space_id === game.systematization) continue + if ((space.country === vm_operand(1) && space.socio === vm_operand(2)) || (space.country === vm_operand(1) && space.socio === vm_operand(3))) { + game.valid_spaces.push(space.space_id); + } + } + vm_next() +} + +function vm_valid_spaces_region_socio() { + let valid_spaces = [] + for (let space of spaces) { + if (space.space_id === game.systematization) continue + if (space.region === vm_operand(1) && space.socio === vm_operand(2)) { + valid_spaces.push(space.space_id); + } + } + game.valid_spaces = valid_spaces + vm_next() +} + +function vm_valid_spaces_region_opp() { + let valid_spaces = [] + for (let space of spaces) { + let s = space.space_id + if ((game.active === DEM && space.region === vm_operand(1) && game.comInfl[s] > 0 ) || (game.active === COM && space.region === vm_operand(1) && game.demInfl[s] > 0 )) { + valid_spaces.push(space.space_id); + } + } + game.valid_spaces = valid_spaces + vm_next() +} + +function vm_valid_spaces_solidarity_legalised() { + let valid_spaces = [] + for (let i = 0; i < spaces.length; i++) { + let space = spaces[i] + let uncontrolled = (!check_control(i) && !check_opp_control(i)) + if ((space.country === 'Poland' && uncontrolled && space.socio === 3) || (space.country === 'Poland' && uncontrolled && space.socio === 4)) { + valid_spaces.push(space.space_id); + } + } + game.valid_spaces = valid_spaces + vm_next() +} + +function vm_active_country () { + game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === game.vm_active_country) + vm_next() +} + +function vm_take_control_prep() { + game.vm_available_ops = vm_operand(1) + game.state = 'vm_take_control' +} + +function vm_take_control(space) { + if (game.active === DEM) { + let current_infl = game.demInfl[space] + let opponent_infl = game.comInfl[space] + let stability = spaces[space].stability + + if ((current_infl - opponent_infl) < stability) { + game.demInfl[space] += stability - current_infl + opponent_infl + } + } else if (game.active === COM) { + let current_infl = game.comInfl[space] + let opponent_infl = game.demInfl[space] + let stability = spaces[space].stability + + if ((current_infl - opponent_infl) < stability) { + game.comInfl[space] += stability - current_infl + opponent_infl + } + } + game.valid_spaces = game.valid_spaces.filter(id => id !== space) + log(`Took control of %${space}`) +} + +function vm_do_add_infl_free(space) { + push_undo() + log_summary(`Added £ SP in %${space}.`) + + // Update influence values + if (game.active === COM) { + game.comInfl[space]++ + } else { + game.demInfl[space]++ + } + game.vm_available_ops-- + check_tyrant() +} + +function vm_add_infl() { + if (vm_operand(1)) {game.vm_available_ops = vm_operand(1)} + game.state = 'vm_add_infl' +} + +function vm_add_infl_free() { + if (vm_operand(1)) {game.vm_available_ops = vm_operand(1)} + game.state = 'vm_add_infl_free' +} + +function vm_add_x_infl() { + game.vm_available_ops = vm_operand(1) + game.state = 'vm_add_x_infl' +} + +function vm_do_add_x_infl(space) { + push_undo() + log(`Added ${game.vm_available_ops} SPs in %${space}.`) + if (game.active === COM) { + game.comInfl[space] += game.vm_available_ops + } else { + game.demInfl[space] += game.vm_available_ops + } + check_tyrant() + game.vm_available_ops = 0 + game.valid_spaces = [] +} + +function vm_add_limited_infl() { + game.vm_available_ops = vm_operand(1) + game.vm_max_infl = vm_operand(2) + game.state = 'vm_add_limited_infl' +} + +function vm_do_add_limited_infl(space, max_infl) { + push_undo() + log_summary(`Added £ SP in %${space}`) + game.vm_available_ops -- + + if (!game.vm_influence_added) { + game.vm_influence_added = {}; + } + + if (!game.vm_influence_added[space]) { + game.vm_influence_added[space] = 0; + } + + if (game.active === COM) { + game.comInfl[space] ++ + } else { + game.demInfl[space] ++ + } + + game.vm_influence_added[space] ++ + + if (game.vm_influence_added[space] === max_infl) { + game.valid_spaces = game.valid_spaces.filter(id => id !== space); + } + check_tyrant() + if (game.vm_available_ops === 0) {game.valid_spaces = [] } +} + +function vm_remove_infl() { + game.vm_available_ops = vm_operand(1) + game.state = 'vm_remove_infl' +} + +function vm_remove_opp_infl() { + game.vm_available_ops = vm_operand(1) + game.remove_opponent_infl = true + if (game.is_pwr_struggle) { + game.state = 'vm_scare_tactics' + } else { + game.state = 'vm_remove_infl' + } +} + +function vm_remove_x_opp_infl() { + game.vm_available_ops = vm_operand(1) + game.remove_opponent_infl = true + game.state = 'vm_remove_x_infl' +} + +function vm_do_remove_x_infl(space) { + push_undo() + + if (game.remove_opponent_infl) { + if (game.active === COM) { + if (game.demInfl[space] >= game.vm_available_ops) { + game.demInfl[space] -= game.vm_available_ops + } else { + game.vm_available_ops = game.demInfl[space] + game.demInfl[space] -= game.vm_available_ops + } + } else { + if (game.comInfl[space] >= game.vm_available_ops) { + game.comInfl[space] -= game.vm_available_ops + } else { + game.vm_available_ops = game.comInfl[space] + game.comInfl[space] -= game.vm_available_ops + } + } + } else { + if (game.active === COM) { + if (game.comInfl[space] >= game.vm_available_ops) { + game.comInfl[space] -= game.vm_available_ops + } else { + game.vm_available_ops = game.comInfl[space] + game.comInfl[space] -= game.vm_available_ops + } + } else { + if (game.demInfl[space] >= game.vm_available_ops) { + game.demInfl[space] -= game.vm_available_ops + } else { + game.vm_available_ops = game.demInfl[space] + game.demInfl[space] -= game.vm_available_ops + } + } + } + + log(`Removed ${game.vm_available_ops} SPs from %${space}`) + check_tyrant() + game.vm_available_ops = 0 + game.valid_spaces = [] +} + +function vm_remove_limited_opp_infl() { + game.vm_available_ops = vm_operand(1) + game.vm_max_infl = vm_operand(2) + game.remove_opponent_infl = true + game.state = 'vm_remove_limited_infl' +} + +function vm_do_remove_limited_infl(space, max_infl) { + push_undo() + log_summary(`Removed £ SP from %${space}.`) + game.vm_available_ops -- + + if (!game.vm_influence_added) { + game.vm_influence_added = {}; + } + + if (!game.vm_influence_added[space]) { + game.vm_influence_added[space] = 0; + } + + if (game.active === COM) { + game.demInfl[space] -- + if (game.demInfl[space] === 0) { + game.valid_spaces = game.valid_spaces.filter(id => id !== space) + } + } else { + game.comInfl[space] -- + if (game.comInfl[space] === 0) { + game.valid_spaces = game.valid_spaces.filter(id => id !== space) + } + } + + game.vm_influence_added[space] ++ + + if (game.vm_influence_added[space] === max_infl) { + game.valid_spaces = game.valid_spaces.filter(id => id !== space); + } + + check_tyrant() + if (game.vm_available_ops === 0) {game.valid_spaces = []} +} + +function vm_remove_all_infl() { + game.vm_available_ops = vm_operand(1) + game.state = 'vm_remove_all_infl' +} + +function vm_do_remove_all_infl(space) { + push_undo() + + if (game.remove_opponent_infl === true) { + if (game.active === COM) { + log(`Removed all Democratic SP from %${space}`) + game.demInfl[space] = 0 + } else { + log(`Removed all Communist SP from %${space}`) + game.comInfl[space] = 0 + } + check_tyrant() + + } else { + if (game.active === COM) { + log(`Removed all Communist SP from %${space}`) + game.comInfl[space] = 0 + } else { + log(`Removed all Democratic SP from %${space}`) + game.demInfl[space] = 0 + } + check_tyrant() + } + game.vm_available_ops -- + game.valid_spaces = game.valid_spaces.filter(id => id !== space) +} + +function vm_replace_all_infl(space_id) { + if (game.active === DEM) { + game.demInfl[space_id] += game.comInfl[space_id] + log(`Replaced ${game.comInfl[space_id]} Communist SP in %${space_id} with Democratic SP`) + game.comInfl[space_id] = 0 + } else { + game.comInfl[space_id] += game.demInfl[space_id] + log(`Replaced ${game.demInfl[space_id]} Democrat SP in %${space_id} with Communist SP`) + game.demInfl[space_id] = 0 + } + check_tyrant() +} + +function vm_1_support_check() { + game.vm_available_ops = 1 + game.state = 'vm_1_support_check_prep' +} + +function vm_support_check() { + game.vm_available_ops = vm_operand(1) + game.state = 'vm_support_check_prep' +} + +function vm_support_check_modified() { + game.vm_available_ops = vm_operand(1) + game.support_check_modifier = vm_operand(2) + game.state = 'vm_support_check_prep' +} + +function vm_switch_infl(id){ + push_undo() + game.demInfl[id] -= game.vm_available_ops + game.comInfl[id] += game.vm_available_ops + log(`Replaced ${pluralize(game.vm_available_ops,'SP')} in %${id}`) + game.vm_available_ops = 0 + check_tyrant() +} + +/* ===================== EVENT SPECIFIC FUNCTIONS ========== */ + +function vm_40th_anniversary_celebration() { + if (game.vp < 0 ) {game.vm_available_ops = 4} + else {game.vm_available_ops = 2} + vm_next() +} + +function vm_40th_anniversary_celebration_vp() { + game.vp -- + log('-1VP') + if (check_vp()) { + return + } + vm_next() +} + +function vm_adamec() { + game.state = 'vm_adamec' +} + +function vm_army_backs_revolution() { + if (game.persistent_events.includes(C_SECURITATE)) { + permanently_remove(C_SECURITATE) + } + add_to_persistent_events(C_ARMY_BACKS_REVOLUTION) + logi(`C${C_SECURITATE} no longer has any effect`) + vm_next() +} + +function vm_army_block() { + permanently_remove(C_SECURITATE) + logi(`Has no effect after C${C_ARMY_BACKS_REVOLUTION}`) + vm_next() +} + +function vm_austria_hungary_border_reopened() { + add_to_persistent_events(C_AUSTRIA_HUNGARY_BORDER_REOPENED) + logi(`For the remainder of the turn, cards played by the Democrat have +1 Ops value if all Operations Points are used in East Germany`) + game.austria_hungary_border_reopened_tracker = false + vm_next() +} + +function vm_betrayal() { + if (game.demInfl[S_ORTHODOX_CHURCH_ROMANIA] > 0 ) { game.valid_spaces.push(S_ORTHODOX_CHURCH_ROMANIA) } + if (game.demInfl[S_ORTHODOX_CHURCH_BULGARIA] >0 ) { game.valid_spaces.push(S_ORTHODOX_CHURCH_BULGARIA) } + game.state = 'vm_switch_infl' +} + +function vm_breakaway_baltic_republics() { + log('+5 VP') + game.vp += 5 + game.stability++ + if (check_vp()) { + return + } + game.playable_cards.push(C_KREMLIN_COUP) + game.playable_cards = game.playable_cards.filter(n => n !== C_GORBACHEV_CHARMS_THE_WEST) + if (!check_dem_control(S_HARGHITA_COVASNA) && game.systematization !== S_HARGHITA_COVASNA) {game.valid_spaces.push(S_HARGHITA_COVASNA)} + if (!check_dem_control(S_RAZGRAD)) {game.valid_spaces.push(S_RAZGRAD)} + vm_next() +} + +function vm_brought_in_for_questioning() { + if (game.active === COM) { + game.active = DEM + } + game.phase = 0 + game.state = 'vm_brought_in_for_questioning' +} + +function vm_bulgarian_turks_expelled(){ + game.remove_opponent_infl = true + game.vp -= 2 + log('-2VP') + if (check_vp()) { + return + } + vm_next() +} + +function vm_ceausescu() { + let adj_cluj = false + + if (game.demInfl[S_TIMISOARA] > 0 ) {adj_cluj = true} + if (game.demInfl[S_BABES_BOLYAI_UNIVERSITY] > 0 ) {adj_cluj = true} + if (game.demInfl[S_ORTHODOX_CHURCH_ROMANIA] > 0 ) {adj_cluj = true} + if (game.demInfl[S_BUCURESTI] > 0 ) {adj_cluj = true} + + if (adj_cluj && game.comInfl[S_BUCURESTI]>0) { + game.valid_spaces = [S_BUCURESTI] + game.vm_available_ops = 1 + game.remove_opponent_infl = false + game.state = 'vm_remove_infl' + } + else {vm_next()} +} + +function vm_central_committee_reshuffle() { + game.state = 'vm_central_committee_reshuffle' +} + +function vm_civic_forum_prep() { + log('+1 VP') + game.vp++ + if (check_vp()) { + return + } + vm_next() +} + +function vm_civic_forum() { + if (check_dem_control(S_CZECH_WRITERS)) { + vm_next() + } else { + vm_return() + } +} + +function vm_cluj_check(){ + if (game.comInfl[S_CLUJ_NAPOCA] > 0 ) { + game.valid_spaces.push(S_CLUJ_NAPOCA) + } + vm_next() +} + +function vm_common_european_home() { + if (game.active === DEM) { + for (let c of game.democrat_hand) { + if (cards[c].side === 'C') { + game.valid_cards.push(c) + } + } + } else { + for (let c of game.communist_hand) { + if (cards[c].side === 'D') { + game.valid_cards.push(c) + } + } + } + game.state = "vm_common_european_home_choose" +} + +function vm_dash_for_the_west() { + game.valid_cards = [] + for (let c of game.strategy_discard) { + if (cards[c].side === 'D' && cards[c].remove && (cards[c].playable || game.playable_cards.includes(c))) { + game.valid_cards.push(c) + } + } + game.state = 'vm_dash_for_the_west' +} + +function vm_deutsche_marks() { + let max_value = 1; + for (let c of game.democrat_hand) { + if (cards[c].ops > max_value) { + max_value = cards[c].ops + } + } + let valid_cards = []; + for (let c of game.democrat_hand) { + if (cards[c].ops === max_value) { + valid_cards.push(c); + } + } + game.valid_cards = valid_cards + game.state = 'vm_deutsche_marks_prep' +} + +function vm_domino_theory() { + game.discard = true + for (let card of game.strategy_discard) { + if (scoring_cards.includes(card)) {game.valid_cards.push(card) } + } + game.phase = 0 + game.state = 'vm_play_event_from_discard' +} + +function vm_domino_theory_pass() { + if (game.revolutions.filter(value => value === true).length < 2) { + logi('Democrat holds power in fewer than 2 countries') + } else if (!scoring_cards.some(card => game.strategy_discard.includes(card))) { + logi('No scoring cards in discard') + } + vm_next() +} + +function vm_eco_glasnost() { + add_to_persistent_events(C_ECO_GLASNOST) + logi(`+1 VP for Communist support checks in Ruse for the rest of the game`) + vm_next() +} + +function vm_elena(){ + add_to_persistent_events(C_ELENA) + logi(`-1 modifier to Democratic Support checks in Romania for the rest of this turn`) + vm_next() +} + +function vm_eliminate(space_id) { // Eliminate the democrat influence and move the communist influence to Bucuresti + log(`Eliminated %${space_id}`) + if (space_id === S_BUCURESTI) { + game.demInfl[space_id] = 0 + game.comInfl[space_id] = 0 + } else { + game.demInfl[space_id] = 0 + game.comInfl[S_BUCURESTI] += game.comInfl[space_id] + if (game.comInfl[space_id] > 0 ) { + log(`${pluralize(game.comInfl[space_id],'Communist SP')} relocated to %${S_BUCURESTI}`) + } + game.comInfl[space_id] = 0 + } +} + +function get_adjusted_adjacency(space_id) { + let adjacent_spaces = spaces[space_id].adjacent; + if (adjacent_spaces.includes(game.systematization)) { + let eliminated_space_id = game.systematization; + adjacent_spaces = adjacent_spaces.map(adj_space_id => { + if (adj_space_id === eliminated_space_id) { + return spaces[eliminated_space_id].adjacent; + } + return adj_space_id; + }).flat(); // Flatten in case the eliminated space has multiple adjacencies + } + adjacent_spaces = adjacent_spaces.filter(s => s !== space_id) + return adjacent_spaces; +} + +function vm_exit_visas() { + game.state = 'vm_exit_visas' +} + +function vm_foreign_currency_debt_burden() { + log('+1VP') + game.vp++ + if (check_vp()) { + return + } + add_to_persistent_events(C_FOREIGN_CURRENCY_DEBT_BURDEN) + game.state = 'vm_foreign_currency_debt_burden' +} + +function vm_foreign_television() { + for (let i = 0 ; i < spaces.length; i++) { + if (i === S_DRESDEN) {continue} /*Does not apply to Dresden*/ + if (game.comInfl[i] > 0 ) { + game.valid_spaces.push(i) + } + } + vm_next() +} +function vm_frg_embassies() { + add_to_persistent_events(C_FRG_EMBASSIES) + logi(`+1 modifier for Democratic Support Checks in Eastern Europe for the rest of this turn`) + vm_next() +} + +function vm_general_strike() { + add_to_persistent_events(C_GENERAL_STRIKE) + logi(`Each Action Round the Communist must instead discard a card and roll a die until the modified die roll exceeds 5`) + vm_next() +} + +function vm_genscher() { + add_to_persistent_events(C_GENSCHER) + logi(`Cancels +1 Ops cost to place Democratic SPs in Communist controlled spaces in East Germany for the rest of the turn`) + vm_next() +} + +function vm_goodbye_lenin() { + game.view_opp_hand = true + game.communist_hand_red = [] + // Select Red cards to show + for (let card of game.communist_hand) { + if (cards[card].red) { + game.communist_hand_red.push(card) + } + } + //Check if these cards are playable + for (let card of game.communist_hand_red) { + if (cards[card].playable || game.playable_cards.includes(card)) { + game.valid_cards.push(card) + } + } + game.state = 'vm_goodbye_lenin' +} + +function vm_government_resigns() { + for (let i = 0; i < spaces.length; i++) { + let space = spaces[i] + if (space.socio === 1 && game.comInfl[i] > 0 && !check_control(i)) { + game.valid_spaces.push(i) + } + } + game.remove_opponent_infl = true + vm_next() +} + +function vm_grenztruppen() { + add_to_persistent_events(C_GRENZTRUPPEN) + logi(`-1 modifier for Democratic Support Checks in East Germany for the rest of this turn`) + vm_next() +} + +function vm_heal_our_bleeding_wounds() { + let change_vp = 0 + if (game.turn <= 3) {change_vp = -3 } + else if (game.turn <= 7) {change_vp = -1} + else change_vp = 3 + if (change_vp >0) { + log(`+${change_vp} VP`) + } else { + log(`-${change_vp} VP`) + } + game.vp += change_vp + if (check_vp()) { + return + } + vm_next() +} + +function vm_helsinki_final_act() { + add_to_persistent_events(C_HELSINKI_FINAL_ACT) + logi(`+1 VP for every Support Check by the Communist Player in Student or Intellectual spaces for the rest of the game`) + vm_next() +} + +function vm_honecker() { + add_to_persistent_events(C_HONECKER) + logi(`The Communist may take one extra Action Round this turn`) + game.valid_cards = [] + for (let c of game.strategy_discard) { + if (scoring_cards.includes(c)) { + continue} + else { + game.valid_cards.push(c) + } + } + game.discard = true + game.state = 'vm_honecker' +} + +function vm_inflationary_currency() { + game.state = 'vm_inflationary_currency' +} + +function vm_inflationary_currency_discard() { + // This function starts with the player who is playing Inflationary Currency for the Event + // Switch player and check the hand of their opponent to see if the have cards with ops > 3 to discard + next_player() + if (game.active === COM) { + for (let card of game.communist_hand){ + if (get_card_ops(card) >= 3) { + game.valid_cards.push(card) + } + } + } else { + for (let card of game.democrat_hand){ + if (get_card_ops(card) >= 3) { + game.valid_cards.push(card) + } + } + } + game.state = 'vm_inflationary_currency_discard' +} + +function vm_kiss_of_death() { + game.state = 'vm_kiss_of_death' +} + +function vm_klaus_and_komarek() { + if (game.comInfl[S_PRAHA] > 0 ) {game.valid_spaces = [S_PRAHA]} + vm_next() +} + +function vm_kohl_proposes_reunification_prep() { + log('+2 VP') + game.vp += 2 + if (check_vp()) { + return + } + vm_next() +} +function vm_kohl_proposes_reunification() { + game.vm_event = C_KOHL_PROPOSES_REUNIFICATION + game.state = 'vm_common_european_home_play' +} + +function vm_kremlin_coup() { + log('-3 VP') + game.vp -= 3 + game.stability ++ + if (check_vp()) { + return + } + game.support_check_modifier = 1 + game.temp = [] + countries.forEach(country => { + if (!game.revolutions[find_country_index(country)]) { + game.temp.push(country) + } + }) + game.playable_cards = game.playable_cards.filter(c => c !== C_MALTA_SUMMIT) + game.state = 'vm_kremlin_coup_choose_country' +} + +function vm_laszlo_tokes() { + add_to_persistent_events(C_LASZLO_TOKES) + logi(`Allows play of C${C_MASSACRE_IN_TIMISOARA}`) + game.playable_cards.push(C_MASSACRE_IN_TIMISOARA) + game.state = 'vm_laszlo_tokes' +} + +function vm_legacy_of_martial_law() { + game.vm_available_ops = 1 + game.state = 'vm_switch_infl' +} + +function vm_legacy_of_1968() { + for (let i = 0; i < spaces.length; i++) { + let space = spaces[i] + if ((!check_com_control(i) && space.country === 'Czechoslovakia')) { + game.valid_spaces.push(space.space_id); + } + } + vm_next() +} + +function vm_li_peng() { + add_to_persistent_events(C_LI_PENG) + logi(`+1 modifier to all Communist Tiananmen Square Track attempts for the rest of the game`) + vm_next() +} + +function vm_ligachev() { + add_to_persistent_events(C_LIGACHEV) + logi(`-3VPs if the Democrat does not play C${C_GORBACHEV_CHARMS_THE_WEST} next Action Round`) + vm_next() +} + +function vm_malta_summit() { + game.state = 'vm_malta_summit' +} + +function vm_massacre_in_timisoara() { + game.persistent_events = game.persistent_events.filter(n => n !== C_LASZLO_TOKES) + game.strategy_removed.push(C_LASZLO_TOKES) + vm_next() +} + +function vm_modrow() { + game.playable_cards = game.playable_cards.filter(n => n !== C_HONECKER) + add_to_persistent_events(C_MODROW) + logi(`Prevents play of C${C_HONECKER} for the event`) + game.state = 'vm_modrow' +} + +function vm_nagy_reburied(){ + if (game.comInfl[S_SZOMBATHELY] > 0) { + game.valid_spaces.push(S_SZOMBATHELY) + } + vm_next() +} + +function vm_national_salvation_front() { + add_to_persistent_events(C_NATIONAL_SALVATION_FRONT) + logi(`In the next Power Struggle in the Balkans, the Communist draws 2 random Power Struggle cards from the Democrat hand`) + vm_next() +} + +function vm_nepotism() { + game.state = 'vm_nepotism' +} + +function vm_new_years_eve_party() { + game.state = 'vm_new_years_eve_party' +} + +function vm_nomenklatura() { + game.state = 'vm_nomenklatura' +} + +function vm_normalization() { + if (game.demInfl[S_PLZEN] >0) {game.valid_spaces.push(S_PLZEN)} + if (game.demInfl[S_PRAHA] > 0) {game.valid_spaces.push(S_PRAHA)} + game.remove_opponent_infl = true + vm_next() +} + +function vm_peasant_parties_revolt() { + add_to_persistent_events(C_PEASANT_PARTIES_REVOLT) + logi(`In the next Power Stuggle, if the Democrat controls a Farmer space draw 1 Power Struggle card at random from the Communist hand`) + vm_next() +} + +function vm_perestroika() { + add_to_persistent_events(C_PERESTROIKA) + logi(`+1 Ops value for cards played by the Communist for the rest of this turn`) + vm_next() +} + +function vm_poszgay() { + let valid_spaces = [] + for (let space of spaces) { + if (space && space.country === 'Hungary' && !check_dem_control(space.space_id)) { + valid_spaces.push(space.space_id); + } + } + game.valid_spaces = valid_spaces + vm_next() +} + +function vm_power_struggle() { + game.is_pwr_struggle = true + game.phase = 0 + game.raised_stakes = 0 + game.raised_stakes_round = 0 + game.raised_stakes_discard = 0 + game.pwr_struggle_in = countries[scoring_cards.indexOf(game.vm_event)] + log_h2(`C${game.vm_event}`) + + //Check for Securitate + if (game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(C_SECURITATE)) { + log(`C${C_SECURITATE}: Democrat reveals Power Struggle cards`) + game.opp_power_hand = true + } + log_h2('Deal Cards') + game.state = 'draw_power_cards' +} + +function vm_presidential_visit() { + add_to_persistent_events(C_PRESIDENTIAL_VISIT) + logi(`Communist hand size is reduced to 7 next turn`) + vm_next() +} + +function vm_prudence() { + if (!game.prudence) { + game.prudence = {DEM: 0, COM: 0} + } + if (game.active === DEM) { + game.prudence.COM -- + log(`${game.prudence.COM} to Communist Ops this turn`) + } else { + game.prudence.DEM -- + log(`${game.prudence.DEM} to Democrat Ops this turn`)} + vm_next() +} + +function vm_public_against_violence() { + game.valid_spaces = [] + if (game.comInfl[S_BRATISLAVA] > 0 ) {game.valid_spaces.push(S_BRATISLAVA)} + vm_next() +} + +function vm_reformer_rehabilitated () { + permanently_remove(C_REFORMER_REHABILITATED) + game.discard = true + for (let card of game.strategy_discard) { + if (!event_is_playable(card)) continue + if (card === game.played_card) continue + if (card === C_COMMON_EUROPEAN_HOME) continue + if (scoring_cards.includes(card)) continue + + game.valid_cards.push(card) + } + game.state = 'vm_play_event_from_discard' +} + +function vm_roundtable_talks() { + add_to_persistent_events(C_ROUNDTABLE_TALKS) + logi(`In the next Power Struggle the Democrat draws 2 random Power Struggle cards from the Communist hand`) + vm_next() +} + +function vm_sajudis_check() { + if (!check_dem_control(S_RAZGRAD)) { + game.valid_spaces.push(S_RAZGRAD) + } + if (!check_dem_control(S_HARGHITA_COVASNA)) { + game.valid_spaces.push(S_HARGHITA_COVASNA) + } + vm_next() +} + +function vm_sajudis() { + game.playable_cards.push(C_THE_BALTIC_WAY) + game.stability++ + log('+1 VP') + game.vp++ + if (check_vp()) { + return + } + log(`Allows play of C${C_THE_BALTIC_WAY} for the event`) + vm_next() +} + +function vm_samizdat() { + game.state = 'vm_samizdat' +} + +function vm_securitate() { + add_to_persistent_events(C_SECURITATE) + logi(`The Democrat must reveal their Power Struggle cards at the start of Power Struggles in Romania`) + vm_next() +} + +function vm_shock_therapy() { + game.state = 'vm_shock_therapy' +} + +function vm_social_democratic_platform_adopted() { + game.state = 'vm_social_democratic_platform_adopted' +} + +function vm_solidarity_legalised() { + game.playable_cards.push(C_WALESA) + add_to_persistent_events(C_SOLIDARITY_LEGALIZED) + logi(`Allows play of C${C_WALESA}`) + vm_next() +} + +function vm_st_nicholas_church () { + add_to_persistent_events(C_ST_NICHOLAS_CHURCH) + logi(`Allows play of C${C_THE_MONDAY_DEMONSTRATIONS}`) + game.playable_cards.push(C_THE_MONDAY_DEMONSTRATIONS) + vm_next() +} + +function vm_stasi() { + add_to_persistent_events(C_STASI) + logi(`For the rest of this turn the Democrat must reveal the card they will play this Action Round before the Communist player plays a card`) + vm_next() +} + +function vm_stand_fast() { + add_to_persistent_events(C_STAND_FAST) + if (game.active === DEM) { + logi(`-1 Modifier to Support Checks in Democratic controlled spaces for the rest of this turn`) + game.stand_fast = DEM + } else { + logi(`-1 Modifier to Support Checks in Communist controlled spaces for the rest of this turn`) + game.stand_fast = COM} + vm_next() +} + +function vm_systematization() { + game.state = 'vm_systematization' +} + +function vm_tank_column() { + if (game.active === DEM) { + game.dem_tst_position++ + game.dem_tst_attempted = 0 + } else { + game.com_tst_position++ + game.com_tst_attempted = 0 + } + // Check if TST Awards occur + if (game.active === DEM) { + if (game.dem_tst_position === 3 && game.com_tst_position < 3) { + game.vm_event = 203 + goto_vm(game.vm_event) + return + } + else if (game.dem_tst_position === 4 && game.com_tst_position < 4) { + game.vm_event = 204 + goto_vm(game.vm_event) + return + } + + } else { + if (game.com_tst_position === 3 && game.dem_tst_position < 3) { + game.vm_event = 203 + goto_vm(game.vm_event) + return + } + else if (game.com_tst_position === 4 && game.dem_tst_position < 4) { + game.vm_event = 204 + goto_vm(game.vm_event) + return + } + } + vm_next() +} + +function vm_tear_gas () { + add_to_persistent_events(C_TEAR_GAS) + logi(`+1 modifier to the next Communist Support Check in a Student space`) + vm_next() +} + +function vm_the_baltic_way_prep() { + game.playable_cards.push(C_BREAKAWAY_BALTIC_REPUBLICS) + game.stability++ + log('+3 VP') + game.vp += 3 + if (check_vp()) { + return + } + log(`Allows play of C${C_BREAKAWAY_BALTIC_REPUBLICS} for the event`) + vm_next() +} + +function vm_the_baltic_way() { + if (!check_dem_control(S_HARGHITA_COVASNA) && game.systematization !== S_HARGHITA_COVASNA) {game.valid_spaces.push(S_HARGHITA_COVASNA)} + if (!check_dem_control(S_RAZGRAD) ) {game.valid_spaces.push(S_RAZGRAD)} + vm_next() +} + +function vm_the_chinese_solution() { + game.state = 'vm_the_chinese_solution' +} + +function vm_the_crowd_turns_against_ceausescu() { + add_to_persistent_events(C_THE_CROWD_TURNS_AGAINST_CEAUSESCU) + logi(`Power Struggle: Romania. Democrat draws 15 Power Struggle cards and takes 1 Action Round using Ops 3 times the number of Rallies. Allows play of C${C_THE_TYRANT_IS_GONE}`) + game.playable_cards.push(C_THE_TYRANT_IS_GONE) + vm_next() +} + +function vm_the_monday_demonstrations() { + if (!check_dem_control(S_LUTHERAN_CHURCH)) {game.valid_spaces.push(S_LUTHERAN_CHURCH)} + if (!check_dem_control(S_LEIPZIG)) {game.valid_spaces.push(S_LEIPZIG)} + vm_next() +} + +function vm_the_sinatra_doctrine() { + add_to_persistent_events(C_THE_SINATRA_DOCTRINE) + logi(`+1 Ops value for cards played by the Democrat for the rest of this turn`) + vm_next() +} + +function vm_the_third_way() { + log('-2VP') + game.vp -= 2 + if (check_vp()) { + return + } + vm_next() +} + +function vm_the_tyrant_is_gone() { + permanently_remove(C_THE_CROWD_TURNS_AGAINST_CEAUSESCU) + game.persistent_events.push(THE_TYRANT_IS_GONE_OCCURRED) + game.valid_spaces = [] + for (let i = 0; i < spaces.length; i++) { + let space = spaces[i] + if (game.demInfl[i] === 0 && space.country === 'Romania') { + if (space.space_id === game.systematization) {continue} + game.valid_spaces.push(space.space_id) + } + } + game.state = 'vm_the_tyrant_is_gone' +} + +function vm_the_tyrant_is_gone_prep() { + add_to_persistent_events(C_THE_TYRANT_IS_GONE) + logi(`After C${C_THE_CROWD_TURNS_AGAINST_CEAUSESCU} occurs, remove 4 Commuist SPs from the Romanian Elite space. The Democrats choose where the Ceausescus flee to`) + vm_next() +} + +function vm_tyrant_block() { + logi(`Has no effect after C${C_THE_TYRANT_IS_GONE}`) + vm_next() +} + +function vm_the_wall () { + add_to_persistent_events(C_THE_WALL) + logi(`Cancels the modifier for any Democratic controlled spaces for the next Communist Support Check in East Germany`) + vm_next() +} + +function vm_the_wall_must_go() { + game.the_wall_must_go = {} + game.the_wall_must_go['dem_wins'] = 0 + game.the_wall_must_go['com_wins'] = 0 + game.the_wall_must_go['dem_roll'] = 0 + game.the_wall_must_go['com_roll'] = 0 + game.state = 'vm_the_wall_must_go' +} + +function vm_warsaw_pact_summit() { + game.state = 'vm_warsaw_pact_summit' +} + +function vm_we_are_the_people() { + if (game.demInfl[S_LUTHERAN_CHURCH] > 0) {game.valid_spaces = [S_LUTHERAN_CHURCH]} + add_to_persistent_events(C_WE_ARE_THE_PEOPLE) + logi(`The Communist may no longer make Support Checks in Leipzig`) + if (!game.vm_influence_added) { + game.vm_influence_added = {}; + } + game.vm_influence_added[S_LUTHERAN_CHURCH] = 0 + game.vm_available_ops = 4 + game.state = 'vm_we_are_the_people_remove' +} + +function vm_workers_revolt() { + if (game.active === DEM) { + for (let space of spaces) { + let country = space.country + if (!game.revolutions[find_country_index(country)] && game.comInfl[space.space_id] > 0 && space.socio === 4) { + game.valid_spaces.push(space.space_id); + } + } + } else { + for (let space of spaces) { + let country = space.country + if (game.revolutions[find_country_index(country)] && game.demInfl[space.space_id] > 0 && space.socio === 4) { + game.valid_spaces.push(space.space_id); + } + } + } + game.state = 'vm_workers_revolt' +} + +function vm_yakovlev_counsels_gorbachev() { + add_to_persistent_events(C_YAKOVLEV_COUNSELS_GORBACHEV) + logi(`The Democrat receives a +1 modifier to the Support Loss and Victory Point die rolls if they wins the next Power Struggle`) + vm_next() +} + +function vm_permanently_remove () { + // Check if the event is being played as the result of another card, e.g. Dash for the West, is a card which should be removed, and which hasn't already been removed! + if (game.vm_event !== 0 && cards[game.vm_event].remove && !game.strategy_removed.includes(game.vm_event)) { + permanently_remove(game.vm_event) + } + if (cards[game.played_card].remove && !game.strategy_removed.includes(game.played_card)) { + permanently_remove(game.played_card) + } /*This means the card that called the event being played is also removed if relevant. Think this makes sense */ + vm_next() +} + +function discarded_card() { + return game.temp > 0 +} + +// =================== TIANANMEN SQUARE TRACK FUNCTIONS ==================== + +function vm_tst_3() { + log_gap('Tiananmen Square Track Award') + game.state = 'vm_tst_3_prep' +} + +function vm_tst_4() { + log_gap('Tiananmen Square Track Award') + game.vm_available_ops = 2 + game.remove_opponent_infl = true + game.state = 'vm_tst_4' +} +function vm_tst_6() { + log_h3('Tiananmen Square Track Award') + game.vm_available_ops = 1 + game.temp = 1 //Set temp to 1, so that Card 1 is called during the support check, which has 2 ops + game.state = 'vm_tst_6' +} + +function vm_tst_8() { + game.state = 'vm_goodbye_lenin_ops' // Use this to resolve ops. +} + +// ==================== POWER STRUGGLE FUNCTIONS ====================== + +function vm_scare_tactics() { + game.vm_active_country = game.pwr_struggle_in + vm_next() +} +function vm_support_surges() { + game.state = 'vm_support_surges_1' +} + +function vm_support_falters() { + game.vm_available_ops = 2 + game.return === game.active + log(`P${PC_SUPPORT_FALTERS}:`) + game.state = 'vm_support_falters' +} + +function vm_kremlin_coup_elite() { + game.valid_spaces=[] + elite_spaces.forEach(space => { + if (spaces[space].country === game.vm_active_country && !check_com_control(space)) { + game.valid_spaces.push(space); + } + }) + game.state = 'vm_kremlin_coup_take_control' +} + +/* ================== VM STATES ============================== */ + +states.vm_end_event = { + get inactive() { + return `resolve ${clean_name(cards[this_card()].name)}.` + }, + prompt () { + view.prompt = `${clean_name(cards[this_card()].name)}: done.` + if (game.vm_infl_to_do || game.return_state === 'vm_tst_8') { + gen_action('done') + } else { + gen_action('end_round') + } + }, + done() { + push_undo() + vm_end_event() + }, + end_round() { + push_undo() + game.return_state = '' + vm_end_event() + } +} + +states.vm_take_control = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt () { + if (game.vm_available_ops > 0 && game.valid_spaces.length === 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: all spaces controlled. Continue.` + gen_action('done') + } else if (game.vm_available_ops > 0 ) { + view.prompt = `${clean_name(cards[this_card()].name)}: take control of ${event_prompt()}.` + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } else { + view.prompt = `${clean_name(cards[this_card()].name)}. Take control: done.` + if (game.vm_infl_to_do) { + gen_action('done') + } else { + gen_action('end_round') + } + } + }, + space(space) { + push_undo() + vm_take_control(space) + game.vm_available_ops-- + if (game.vm_available_ops === 0) { + game.valid_spaces = [] + vm_next() + } + }, + done() { + push_undo() + vm_next() + }, + end_round() { + push_undo() + vm_next() + } +} + +states.vm_add_infl = { + inactive: 'add Support Points.', + prompt () { + if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) { + view.prompt = `${clean_name(cards[this_card()].name)}. No available spaces remaining. Add SPs: done.` + gen_action('done') + } + else if (game.vm_available_ops > 0 ) { + view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}.` + + for (let space_id of game.valid_spaces) { + gen_action_space(space_id) + } + } else { + get_end_infl_prompt() + } + }, + space(space) { + add_infl(space, 'vm_available_ops') + if (game.vm_available_ops === 0) { + game.valid_spaces = [] + do_log_summary() + game.vm_event_done = true + vm_next() + } + }, + done () { + push_undo() + do_log_summary() + game.vm_event_done = true + vm_next() + }, + end_round() { + push_undo() + do_log_summary() + game.vm_event_done = true + vm_next() + } +} + +states.vm_add_infl_free = { + get inactive() { + return `resolve ${clean_name(cards[this_card()].name)}: add SPs.` + }, + prompt () { + if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) { + view.prompt = `${clean_name(cards[this_card()].name)}. No available spaces remaining. Add SPs: done.` + gen_action('done') + } else if (game.vm_available_ops > 0 ) { + view.prompt = `${clean_name(cards[this_card()].name)}: add ${game.vm_available_ops} SPs to ${event_prompt()}.` + + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } else { + get_end_infl_prompt() + } + }, + space(space) { + vm_do_add_infl_free(space) + if (game.vm_available_ops === 0) { + game.valid_spaces = [] + do_log_summary() + game.vm_event_done = true + vm_next() + } + }, + done () { + push_undo() + game.valid_spaces = [] + game.vm_event_done = true + do_log_summary() + vm_next() + }, + end_round () { + push_undo() + game.valid_spaces = [] + game.vm_event_done = true + do_log_summary() + vm_next() + } +} + +states.vm_add_x_infl = { + get inactive() { + return `resolve ${clean_name(cards[this_card()].name)}: add Support Points.` + }, + prompt () { + if (game.vm_event === 101 && game.valid_spaces.length === 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: the Romanian Elite space no longer exists.` + gen_action('done') + } + else if (game.vm_available_ops > 0 ) { + view.prompt = `${clean_name(cards[this_card()].name)}: Add ${game.vm_available_ops} SPs to ${event_prompt()}.` + + for (let space_id of game.valid_spaces) { + gen_action_space(space_id) + } + } + }, + space(space) { + push_undo() + vm_do_add_x_infl(space) + if (game.vm_available_ops === 0) { + game.vm_event_done = true + vm_next() + } + }, + done () { + push_undo() + game.vm_event_done = true + vm_next() + } +} + +states.vm_add_limited_infl = { + get inactive() { + return `resolve ${clean_name(cards[this_card()].name)}: add Support Points.` + }, + prompt () { + if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) { + if (game.vm_max_infl === 1) { + view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_max_infl,'SP')} ${event_prompt()}.` + } + else { + view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_available_ops,'SP')} to ${event_prompt()}.` + } + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } + }, + space(space) { + vm_do_add_limited_infl(space, game.vm_max_infl) + if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) { + game.valid_spaces = [] + do_log_summary() + game.vm_event_done = true + vm_next() + } + }, +} + +states.vm_remove_infl = { + inactive: 'remove Support Points.', + prompt () { + // Keep this so that there is an undo option in, e.g., Scare Tactics + if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: no further SPs to remove.` + gen_action('done') + return + } + if (game.vm_available_ops === 0 ) { + view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.` + gen_action('done') + return + } + if (game.remove_opponent_infl) { + view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops, 'opponent SP')}${event_prompt()}.` + } + else { + view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}.` + } + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + }, + space(space) { + remove_infl(space, 'vm_available_ops') + game.vm_active_country = spaces[space].country + let require_done = [C_INFLATIONARY_CURRENCY, C_THE_WALL_MUST_GO] + if (!require_done.includes(game.vm_event)) { + if (game.vm_available_ops === 0 ) { + do_log_summary() + vm_next() + } + } + }, + done() { + if (game.summary.length > 0) { + pop_summary() + log_br() + } else { + log('No influence to remove') + } + vm_next() + } +} + + +states.vm_remove_x_infl = { + get inactive() { + return `resolve ${clean_name(cards[this_card()].name)}: remove SP from ${event_prompt()}.` + }, + prompt () { + if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.` + gen_action('done') + } else if (game.vm_available_ops > 0) { + + view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')} from ${event_prompt()}.` + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } + }, + space(space) { + vm_do_remove_x_infl(space) + if (game.vm_available_ops === 0) { + game.vm_event_done = true + vm_next() + } + }, + done () { + game.vm_event_done = true + vm_next() + } +} + +states.vm_remove_limited_infl = { + inactive: 'remove SP.', + prompt () { + if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}, no more than ${game.vm_max_infl} per space.` + + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } else if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: no further SP to remove.` + gen_action('done') + } + }, + space(space) { + vm_do_remove_limited_infl(space, game.vm_max_infl) + if (game.vm_available_ops === 0) { + game.vm_event_done = true + do_log_summary() + vm_next() + } + }, + done () { + game.vm_event_done = true + do_log_summary() + vm_next() + } +} + +states.vm_remove_all_infl = { + inactive: 'remove Support Points', + prompt () { + if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.` + gen_action('pass') + } else if (game.vm_available_ops > 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: remove all SPs from ${event_prompt()}.` + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } + }, + space(space) { + vm_do_remove_all_infl(space) + game.vm_active_country = spaces[space].country + if (game.vm_available_ops === 0) { + vm_next() + } + }, + pass() { + push_undo() + vm_next() + } +} + +states.vm_support_check_prep = { + inactive: 'do support checks.', + prompt () { + if (game.valid_spaces.length === 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: no valid targets for support check.` + gen_action('done') + } else { + view.prompt = `${clean_name(cards[this_card()].name)}: ${event_prompt()}. ${pluralize(game.vm_available_ops, 'support check')} remaining.` + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } + }, + space(space) { + push_undo() + game.selected_space = space + + // Check for Austria-Hungary Border Reopened - check on first support check only + //First check for Monday Demonstrations - support checks will always be in East Germany + if (game.vm_event === C_THE_MONDAY_DEMONSTRATIONS && game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) { + game.austria_hungary_border_reopened_tracker = true + game.state = 'vm_do_support_check' + return + } + + //Then check Austria-Hungary Border Reopened normally + if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) { + if (game.active === DEM && game.vm_available_ops > 1) { + if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED) && game.active === DEM) { + game.state = 'vm_austria_hungary_border_reopened_check' + return + } + } + } + game.state = 'vm_do_support_check' + }, + done () { + push_undo() + game.vm_available_ops = 0 + vm_next () + } +} + +states.vm_ceh_support_check_prep = { + inactive: 'do support checks.', + prompt () { + if (game.vm_available_ops > 0) { + view.prompt = `Select a space. ${pluralize(game.vm_available_ops, 'support check')} remaining.` + + for (let space_id of game.valid_spaces) { + gen_action_space(space_id) + } + } + }, + space(space) { + push_undo() + game.selected_space = space + + //Then check Austria-Hungary Border Reopened normally + if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) { + if (game.active === DEM && game.vm_available_ops > 1) { + if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) { + game.state = 'vm_austria_hungary_border_reopened_check' + return + } + } + } + game.state = 'vm_ceh_do_support_check' + }, +} + + +states.vm_ceh_do_support_check = { + inactive: 'do support checks.', + prompt () { + view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.` + gen_action('roll') + }, + roll() { + clear_undo() + do_sc(game.selected_space) + game.vm_available_ops-- + if (game.vm_available_ops === 0) { + game.valid_spaces = [] + vm_next() + } else { + game.state = 'vm_ceh_support_check_prep' + return + } + } +} + +states.vm_austria_hungary_border_reopened_check = { + inactive: 'decide Austria-Hungary Border Reopened', + prompt() { + view.prompt = 'Austria-Hungary Border Reopened: will all support checks be in East Germany?' + gen_action('yes') + gen_action('no') + }, + yes() { + game.austria_hungary_border_reopened_tracker = true + game.state = 'vm_do_support_check' + }, + no() { + game.state = 'vm_do_support_check' + } +} + +states.vm_1_support_check_prep = { + inactive: 'do support checks.', + prompt () { + if (game.valid_spaces.length === 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: no valid targets for support check.` + gen_action('done') + } else { + view.prompt = `${clean_name(cards[this_card()].name)}: ${event_prompt()}.` + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } + }, + space(space) { + push_undo() + game.selected_space = space + game.state = 'vm_do_support_check' + }, + done () { + push_undo() + game.vm_available_ops = 0 + vm_next () + } +} + +states.vm_do_support_check = { + inactive: 'do support checks.', + prompt () { + view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.` + gen_action('roll') + }, + roll() { + clear_undo() + do_sc(game.selected_space) + game.vm_available_ops-- + if (check_vp()) { + return + } else if (game.vm_available_ops === 0) { + game.valid_spaces = [] + vm_next() + return + } else { + game.state = 'vm_support_check_prep' + return + } + } +} + +states.vm_tiananmen_square_attempt = { + inactive: 'do Tiananmen Square', + prompt () { + view.prompt = 'Tiananmen Square: roll a die' + gen_action('roll') + }, + roll() { + clear_undo() + do_tst_attempt () + }, +} + +//================================== EVENT SPECIFIC STATES ====================================== + +states.vm_adamec = { + get inactive() { + return `resolve ${clean_name(cards[C_ADAMEC].name)}.` + }, + prompt() { + view.prompt = 'Adamec: roll a die.' + gen_action('roll') + }, + roll() { + clear_undo() + let roll = roll_d6() + log(`Roll: D${roll}`) + let worker_spaces = spaces.filter(space => space && space.country === 'Czechoslovakia' && space.socio === 4 && check_dem_control(space.space_id)).length + if (worker_spaces > 0) { + logi(`-${worker_spaces} from Democrat controlled worker spaces`) + roll -= worker_spaces + } + log(`Modified roll: ${Math.max(roll, 0)}`) + if (roll > 2) { + log_msg_gap('Adamec succeeds') + vm_next() + return + } + log('Adamec fails: 3 or more required') + permanently_remove(C_ADAMEC) + vm_return() + } +} + +states.vm_brought_in_for_questioning = { + inactive: 'discard a card.', + prompt() { + if (game.democrat_hand.length === 0) { + view.prompt = 'Brought in for Questioning. No cards to discard.' + gen_action('pass') + } else { + view.prompt = 'Brought in for Questioning: you must discard a random card.' + gen_action('discard') + } + }, + discard() { + clear_undo() + log(`C${C_BROUGHT_IN_FOR_QUESTIONING}:`) + game.vm_event = discard_card(game.democrat_hand) + game.phase = 1 + if (cards[game.vm_event].side === 'C' && (cards[game.vm_event].playable || game.playable_cards.includes(game.vm_event))) { + if (!game.vm_infl_to_do) { + if(game.round_player === DEM) { + game.return = COM + } else { + game.return = DEM + } + } + if (!is_auto_resolve(game.vm_event) && !switch_events.includes(game.vm_event)) { + next_player() + } + log(`C${game.vm_event}:`) + goto_vm(game.vm_event) + } else { + logi('Event does not occur') + game.return = DEM + vm_return() + } + }, + pass() { + log('No cards to discard') + vm_return() + }, +} + +states.vm_central_committee_reshuffle = { + get inactive() { + return `resolve ${clean_name(cards[C_CENTRAL_COMMITTEE_RESHUFFLE].name)}.` + }, + prompt() { + if (game.revolutions.every(n => n === true)) { + view.prompt = 'Central Committee Reshuffle: no countries to choose.' + gen_action('pass') + } else { + view.prompt = 'Central Committee Reshuffle: choose a country to add SPs.' + if (!game.revolutions[0]) {gen_action('poland')} + if (!game.revolutions[1]) {gen_action('hungary')} + if (!game.revolutions[2]) {gen_action('east_germany')} + if (!game.revolutions[3]) {gen_action('bulgaria')} + if (!game.revolutions[4]) {gen_action('czechoslovakia')} + if (!game.revolutions[5]) {gen_action('romania')} + } + }, + east_germany() { + push_undo() + game.vm_active_country = "East_Germany" + log(`Chose ${country_name(game.vm_active_country)}`) + game.valid_spaces = [...S_EAST_GERMANY] + vm_next() + }, + poland() { + push_undo() + game.vm_active_country = "Poland" + log(`Chose ${country_name(game.vm_active_country)}`) + game.valid_spaces = [...S_POLAND] + vm_next() + }, + czechoslovakia() { + push_undo() + game.vm_active_country = "Czechoslovakia" + log(`Chose ${country_name(game.vm_active_country)}`) + game.valid_spaces = [...S_CZECHOSLOVAKIA] + vm_next() + }, + hungary() { + push_undo() + game.vm_active_country = "Hungary" + log(`Chose ${country_name(game.vm_active_country)}`) + game.valid_spaces = [...S_HUNGARY] + vm_next() + }, + romania() { + push_undo() + game.vm_active_country = "Romania" + log(`Chose ${country_name(game.vm_active_country)}`) + game.valid_spaces = [...S_ROMANIA] + game.valid_spaces = game.valid_spaces.filter(space => space !== game.systematization) + vm_next() + }, + bulgaria () { + push_undo() + game.vm_active_country = "Bulgaria" + log(`Chose ${country_name(game.vm_active_country)}`) + game.valid_spaces = [...S_BULGARIA] + vm_next() + }, + pass() { + log('Passed') + vm_return() + } +} + +states.vm_common_european_home_choose = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = `Common European Home: play an opponent's card, event does not occur.` + for (let card of game.valid_cards) { + gen_action_card(card) + } + }, + card(card) { + push_undo() + game.valid_cards = [] + silent_discard(card) + game.vm_event = card + game.state = 'vm_common_european_home_play' + } +} + +states.vm_common_european_home_play = { + get inactive() { + return `resolve ${clean_name(cards[this_card()].name)}.` + }, + prompt() { + view.prompt = `Play ${clean_name(cards[this_card()].name)} for:` + gen_action('influence') + gen_action('support_check') + if (game.active === DEM && game.vm_event === C_KOHL_PROPOSES_REUNIFICATION ) { + return /*Special condition if card is actually Kohl Proposes Reunification*/ + } + }, + influence(){ + push_undo() + log_gap(`Played C${game.vm_event} to place SPs`) + game.vm_available_ops = get_card_ops(game.vm_event) + valid_spaces_infl() + // If ABHR - Set AHBR tracker to true + if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) { + game.austria_hungary_border_reopened_tracker = true + } + game.state = 'vm_add_infl' + }, + support_check() { + push_undo() + log_gap(`Played C${game.vm_event} for support checks`) + game.vm_available_ops = 2 + game.state = 'vm_ceh_support_check_prep' + valid_spaces_sc() + }, + tst() { + push_undo() + log_gap(`Played C${game.vm_event} to the Tiananmen Square Track`) + game.state = 'vm_tiananmen_square_attempt' + } +} + +states.vm_dash_for_the_west = { + get inactive() { + return `resolve ${clean_name(cards[C_DASH_FOR_THE_WEST].name)}.` + }, + prompt() { + view.prompt = 'Dash for the West: roll a die' + gen_action('roll') + }, + roll() { + clear_undo() + let roll = roll_d6() + log(`Roll: D${roll}`) + let com_control = check_presence('East_Germany').com_spaces + + if (roll > com_control) { + log(`Success. More than the ${com_control} Communist controlled spaces in East Germany`) + log('+1 VP') + game.vp++ + if (check_vp()) { + return + } + game.discard = true + game.state = 'vm_play_event_from_discard' + } else { + log(`Fail: more than a ${com_control} required`) + vm_next() + } + }, +} + +states.vm_play_event_from_discard = { + get inactive() { + return `resolve ${clean_name(cards[this_card()].name)}.` + }, + prompt() { + if (game.valid_cards.length === 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: no valid cards in discard.` + gen_action('pass') + } else { + view.prompt = `${event_prompt()}.` + for (let card of game.valid_cards) { + gen_action('pass') + gen_action_card(card) + } + } + }, + card(card) { + push_undo() + log(`C${this_card()}:`) + log(`Chose C${card}`) + game.vm_event = card + game.vm_available_ops = cards[card].ops + game.discard = false + if (switch_events.includes(card)) {next_player()} + goto_vm(card) + }, + pass(){ + push_undo() + if (game.valid_cards.length === 0) { + log('No valid cards to choose') + } else{ + log('Did not choose a card') + } + vm_next() + }, +} + +states.vm_deutsche_marks_prep = { + inactive: 'choose a card.', + prompt() { + if (game.valid_cards.length === 0) { + view.prompt = 'Deutsche Marks: no cards to give.' + gen_action('pass') + } else { + view.prompt = 'Deutsche Marks: choose a card to give.' + for (let card of game.valid_cards) { + gen_action_card(card) + } + } + }, + card(card) { + push_undo() + log(`Gave C${card}`) + game.valid_cards = [] + silent_discard(card) + game.state = 'vm_deutsche_marks_confirm' + game.vm_event = card + }, + pass() { + push_undo() + vm_next() + } +} + +states.vm_deutsche_marks_confirm = { + inactive: 'choose a card.', + prompt() { + view.prompt = `Deutsche Marks: gave ${cards[game.vm_event].name}.` + gen_action('done') + }, + done() { + if (cards[game.vm_event].side === "C" && (is_auto_resolve(game.vm_event) || switch_events.includes(game.vm_event))) { + goto_vm(game.vm_event) + } else { + next_player() + game.state = 'vm_deutsche_marks' + } + } +} + +states.vm_deutsche_marks = { + get inactive() { + return `resolve ${clean_name(cards[C_DEUTSCHE_MARKS].name)}.` + }, + prompt() { + if(cards[game.vm_event].side === 'C' && (cards[game.vm_event].playable || game.playable_cards.includes(game.vm_event))) { + view.prompt = `Deutsche Marks: you must play ${clean_name(cards[this_card()].name)} for the event.` + gen_action('event') + } else { + view.prompt = `Deutsche Marks: play ${clean_name(cards[this_card()].name)} for:` + gen_action('influence') + gen_action('support_check') + if (game.com_tst_attempted_this_turn === 0) { + gen_action('tst') + } + } + }, + event() { + push_undo() + log(`Played C${game.vm_event} for the event`) + if (!game.vm_infl_to_do) { + game.return = game.active + } + goto_vm(game.vm_event) + }, + influence() { + push_undo() + log(`Played C${game.vm_event} to place SPs`) + game.vm_available_ops = get_card_ops(game.vm_event) + valid_spaces_infl() + game.state = 'vm_add_infl' + }, + support_check() { + push_undo() + log_gap(`Played C${game.vm_event} for support checks`) + game.vm_available_ops = 2 + game.state='vm_support_check_prep' + valid_spaces_sc() + }, + tst() { + push_undo() + log_gap(`Played C${game.vm_event} to the Tiananmen Square Track`) + game.state='vm_tiananmen_square_attempt' + } +} + +states.vm_exit_visas = { + get inactive() { + return `resolve ${clean_name(cards[C_EXIT_VISAS].name)}.` + }, + prompt() { + view.prompt = 'Exit Visas: you may discard cards from your hand and draw replacements.' + for (let card of game.democrat_hand) { + gen_action_card(card) + } + if (game.temp === 0) { + gen_action('pass') + } else { + gen_action('done') + } + }, + card(card){ + push_undo() + discard(card) + game.temp++ + }, + pass() { + push_undo() + log('Did not discard') + game.state = 'vm_exit_visas_finish' + }, + done() { + push_undo() + game.state = 'vm_exit_visas_finish' + } +} + +states.vm_exit_visas_finish = { + get inactive() { + return `resolve ${clean_name(cards[C_EXIT_VISAS].name)}.` + }, + prompt() { + if (game.temp > 0 ) { + view.prompt = 'Exit Visas: draw replacement cards.' + gen_action('draw') + } else { + view.prompt = 'Exit Visas: done.' + gen_action('done') + } + }, + draw() { + clear_undo() + draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length + game.temp, game.communist_hand.length) + game.temp = 0 + vm_next() + }, + done() { + vm_next() + } +} + +states.vm_foreign_currency_debt_burden = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = 'Choose a country. The Communist may not make support checks there for the rest of the turn.' + gen_action('east_germany') + gen_action('poland') + gen_action('czechoslovakia') + gen_action('hungary') + gen_action('bulgaria') + }, + east_germany() { + push_undo() + game.foreign_currency_debt_burden = 'East_Germany' + log('Selected East Germany') + vm_next() + }, + poland() { + push_undo() + game.foreign_currency_debt_burden = 'Poland' + log('Selected Poland') + vm_next() + }, + czechoslovakia() { + push_undo() + game.foreign_currency_debt_burden = 'Czechoslovakia' + log('Selected Czechoslovakia') + vm_next() + }, + hungary() { + push_undo() + game.foreign_currency_debt_burden = 'Hungary' + log('Selected Hungary') + vm_next() + }, + bulgaria() { + push_undo() + game.foreign_currency_debt_burden = 'Bulgaria' + log('Selected Bulgaria') + vm_next() + } +} + +states.vm_goodbye_lenin = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (game.valid_cards.length > 0 ) { + view.prompt = `Play a red event from your opponent's hand, or play Goodbye Lenin for operations.` + for (let card of game.valid_cards) { + gen_action_card(card) + gen_action('ops') + } + } else { + view.prompt = 'Communist has no red events. Play Goodbye Lenin for operations.' + gen_action('ops') + } + }, + card(card) { + push_undo() + log(`Chose to play C${card} for the event`) + let card_index = game.communist_hand.indexOf(card) + game.communist_hand.splice(card_index, 1) + game.vm_event = card + game.view_opp_hand = false + goto_vm(card) + }, + ops() { + push_undo() + if (game.valid_cards.length === 0) { + logi('No red events') + } + log('C46 played for operations') + game.view_opp_hand = false + game.state = 'vm_goodbye_lenin_ops' + } +} + +states.vm_goodbye_lenin_ops = { + get inactive() { + return `resolve ${clean_name(cards[this_card()].name)}.` + }, + prompt() { + view.prompt = `Play ${clean_name(cards[this_card()].name)} for:` + gen_action('influence') + gen_action('support_check') + if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 )) { + gen_action('tst') + } + }, + influence(){ + push_undo() + game.vm_available_ops = get_card_ops(this_card()) + valid_spaces_infl() + + // If ABHR - Set AHBR tracker to true + if (game.persistent_events.includes(58)) { + game.austria_hungary_border_reopened_tracker = true + } + game.state = 'vm_add_infl' + }, + support_check() { + push_undo() + game.vm_available_ops = 2 + game.state = 'vm_support_check_prep' + valid_spaces_sc() + }, + tst() { + push_undo() + game.state = 'vm_tiananmen_square_attempt' + } +} + +states.vm_honecker = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (game.valid_cards.length === 0 && game.temp === 0) { + view.prompt = 'Honecker: no valid cards to choose.' + gen_action('pass') + } else + if (game.temp === 0) {view.prompt = 'Honecker: choose a card to add to your hand.' + for (let card of game.valid_cards) { + gen_action_card(card) + gen_action('pass') + } + } + }, + card(card) { + push_undo() + game.valid_cards = [] + log(`Took C${card} into hand`) + game.temp = card + let card_index = game.strategy_discard.indexOf(card) + game.strategy_discard.splice(card_index, 1) + game.communist_hand.push(card) + vm_next() + }, + pass(){ + log('Did not take a card') + game.discard = false + vm_next() + }, +} + +states.vm_inflationary_currency = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if ((game.active === COM && game.revolutions.every(n => n === false)) || (game.active === DEM && game.revolutions.every(n => n === true))) { + view.prompt = 'Inflationary Currency: no countries to choose.' + gen_action('pass') + } else { + view.prompt = 'Inflationary Currency: choose a country where your opponent has power.' + if (game.active === DEM) { + if (!game.revolutions[0]) {gen_action('poland')} + if (!game.revolutions[1]) {gen_action('hungary')} + if (!game.revolutions[2]) {gen_action('east_germany')} + if (!game.revolutions[3]) {gen_action('bulgaria')} + if (!game.revolutions[4]) {gen_action('czechoslovakia')} + if (!game.revolutions[5]) {gen_action('romania')} + } else { + if (game.revolutions[0]) {gen_action('poland')} + if (game.revolutions[1]) {gen_action('hungary')} + if (game.revolutions[2]) {gen_action('east_germany')} + if (game.revolutions[3]) {gen_action('bulgaria')} + if (game.revolutions[4]) {gen_action('czechoslovakia')} + if (game.revolutions[5]) {gen_action('romania')} + } + } + }, + east_germany() { + push_undo() + game.vm_active_country = 'East_Germany' + log(`Chose ${country_name(game.vm_active_country)}`) + vm_next() + }, + poland() { + push_undo() + game.vm_active_country = 'Poland' + log(`Chose ${country_name(game.vm_active_country)}`) + vm_next() + }, + czechoslovakia() { + push_undo() + game.vm_active_country = 'Czechoslovakia' + log(`Chose ${country_name(game.vm_active_country)}`) + vm_next() + }, + hungary() { + push_undo() + game.vm_active_country = 'Hungary' + log(`Chose ${country_name(game.vm_active_country)}`) + vm_next() + }, + romania() { + push_undo() + game.vm_active_country = 'Romania' + log(`Chose ${country_name(game.vm_active_country)}`) + vm_next() + }, + bulgaria () { + push_undo() + game.vm_active_country = 'Bulgaria' + log(`Chose ${country_name(game.vm_active_country)}`) + vm_next() + }, + pass() { + log('Passed') + vm_return() + } +} + +states.vm_inflationary_currency_discard = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (game.valid_cards.length === 0 ) { + view.prompt = 'Inflationary Currency: no valid cards to discard. You must pass.' + gen_action('pass') + } else { + view.prompt = 'Inflationary Currency: you may discard a 3 op or higher value card to cancel the support check.' + gen_action('pass') + for (let card of game.valid_cards) { + gen_action_card(card) + } + } + }, + card(card) { + push_undo() + discard(card) + game.temp = card + if (!game.vm_infl_to_do) { + if(game.round_player === DEM) { + game.return = COM + } else { + game.return = DEM + } + } + vm_next() + }, + pass() { + push_undo() + log('Did not discard') + next_player() + game.vm_available_ops = 1 + vm_next() + }, +} + + +states.vm_kiss_of_death = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (game.communist_hand.length === 0) { + view.prompt = 'Kiss of Death. No cards to discard.' + gen_action('pass') + } else { + view.prompt = 'Kiss of Death: you must randomly discard a card.' + gen_action('discard') + } + }, + discard() { + clear_undo() + log(`C${C_KISS_OF_DEATH}:`) + game.vm_event = discard_card(game.communist_hand) + //Change player before checking if event is playable. Common European Home is not playable here + change_player() + // Special check for the Reformer Rehabilitated + if (game.vm_event === C_REFORMER_REHABILITATED && game.dem_tst_position > game.com_tst_position) { + log_side() + log(`C${game.vm_event}:`) + game.state = 'vm_kiss_of_death_finish' + } else if (cards[game.vm_event].side !== "C" && event_is_playable(game.vm_event) && game.vm_event !== C_COMMON_EUROPEAN_HOME) { + if (is_auto_resolve(game.vm_event)) { + change_player() + game.state = 'vm_kiss_of_death_finish' + } else { + log_side() + log(`C${game.vm_event}:`) + game.state = 'vm_kiss_of_death_finish' + } + } else { + change_player() + logi('Event does not occur') + vm_next() + } + }, + pass() { + log('No card to discard') + vm_next() + } +} + +states.vm_kiss_of_death_finish = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = `Play ${clean_name(cards[game.vm_event].name)} for the event.` + gen_action('event') + }, + event() { + goto_vm(game.vm_event) + }, +} + +states.vm_kremlin_coup_choose_country = { + get inactive() { + return `resolve ${clean_name(cards[this_card()].name)}.` + }, + prompt() { + if (game.temp.length > 0) { + view.prompt = 'Kremlin Coup! Select a country where the Communist retains power.' + for (let country of countries) { + if (game.temp.includes(country)) { + gen_action(`${country.toLowerCase()}`) + } + } + } else { + view.prompt = 'Kremlin Coup! There are no countries where the Communist retains power.' + gen_action('done') + } + }, + east_germany() { + push_undo() + game.vm_active_country = 'East_Germany' + game.temp = game.temp.filter(country => country !== game.vm_active_country) + log(`${country_name(game.vm_active_country)}:`) + vm_kremlin_coup_elite() + }, + poland() { + push_undo() + game.vm_active_country = 'Poland' + log(`${country_name(game.vm_active_country)}:`) + game.temp = game.temp.filter(country => country !== game.vm_active_country) + vm_kremlin_coup_elite() + }, + czechoslovakia() { + push_undo() + game.vm_active_country = 'Czechoslovakia' + log(`${country_name(game.vm_active_country)}:`) + game.temp = game.temp.filter(country => country !== game.vm_active_country) + vm_kremlin_coup_elite() + }, + hungary() { + push_undo() + game.vm_active_country = 'Hungary' + log(`${country_name(game.vm_active_country)}:`) + game.temp = game.temp.filter(country => country !== game.vm_active_country) + vm_kremlin_coup_elite() + }, + romania() { + push_undo() + game.vm_active_country = 'Romania' + log(`${country_name(game.vm_active_country)}:`) + game.temp = game.temp.filter(country => country !== game.vm_active_country) + vm_kremlin_coup_elite() + }, + bulgaria () { + push_undo() + game.vm_active_country = 'Bulgaria' + log(`${country_name(game.vm_active_country)}:`) + game.temp = game.temp.filter(country => country !== game.vm_active_country) + vm_kremlin_coup_elite() + }, + done() { + game.temp = 0 + vm_next() + } +} + +states.vm_kremlin_coup_take_control = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (game.valid_spaces.includes(game.systematization)) { + view.prompt = `Kremlin Coup! ${country_name(game.vm_active_country)}'s Elite space no longer exists.` + gen_action('done') + } + else if (game.valid_spaces.length === 0){ + view.prompt = `Kremlin Coup! ${country_name(game.vm_active_country)}'s Elite space is already controlled.` + gen_action('done') + } else { + view.prompt = `Kremlin Coup! Take control of the Elite space in ${country_name(game.vm_active_country)}.` + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } + }, + space(space) { + push_undo() + vm_take_control(space) + if (game.vm_active_country === 'East_Germany') {game.selected_space = S_BERLIN } + if (game.vm_active_country === 'Poland') {game.selected_space = S_WARSZAWA} + if (game.vm_active_country === 'Czechoslovakia') {game.selected_space = S_PRAHA} + if (game.vm_active_country === 'Hungary') {game.selected_space = S_BUDAPEST} + if (game.vm_active_country === 'Romania') {game.selected_space = S_BUCURESTI} + if (game.vm_active_country === 'Bulgaria') {game.selected_space = S_SOFIA} + game.state = 'vm_kremlin_coup_sc_prep' + }, + done() { + push_undo() + if (game.vm_active_country === 'East_Germany') {game.selected_space = S_BERLIN } + if (game.vm_active_country === 'Poland') {game.selected_space = S_WARSZAWA} + if (game.vm_active_country === 'Czechoslovakia') {game.selected_space = S_PRAHA} + if (game.vm_active_country === 'Hungary') {game.selected_space = S_BUDAPEST} + if (game.vm_active_country === 'Romania') {game.selected_space = S_BUCURESTI} + if (game.vm_active_country === 'Bulgaria') {game.selected_space = S_SOFIA} + game.state = 'vm_kremlin_coup_sc_prep' + } +} + +states.vm_kremlin_coup_sc_prep = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = `Kremlin Coup! Conduct a support check in ${country_name(game.vm_active_country)}'s Bureaucratic space.` + gen_action_space(game.selected_space); + }, + space(space) { + push_undo() + game.state = 'vm_kremlin_coup_sc' + } +} + +states.vm_kremlin_coup_sc = { + inactive: 'do support checks', + prompt () { + view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.` + gen_action('roll') + }, + roll() { + clear_undo() + do_sc(game.selected_space) + if (game.temp.length > 0 ){ + game.state = 'vm_kremlin_coup_choose_country' + } else { + vm_next() + } + } +} + +states.vm_laszlo_tokes = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = `Laszlo Tokes. Choose to:` + gen_action('influence') + gen_action('support_check') + }, + influence(){ + push_undo() + game.vm_available_ops = get_card_ops(C_LASZLO_TOKES) + valid_spaces_infl() + game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania') + game.phase = 3 + vm_next() + }, + support_check() { + push_undo() + game.vm_available_ops = 2 + valid_spaces_sc() + game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania') + vm_next() + } +} + +states.vm_switch_infl = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (game.valid_spaces.length === 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: No SPs to remove.` + gen_action('pass') + } else { + view.prompt = `${clean_name(cards[game.played_card].name)}: ${event_prompt()}.` + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } + }, + space(space) { + push_undo() + if (game.vm_event === C_BETRAYAL) { + game.vm_available_ops = game.demInfl[space] + } + vm_switch_infl(space) + if (game.vm_available_ops === 0) { + game.valid_spaces = [] + } + vm_next() + }, + pass() { + vm_next() + } +} + +states.vm_malta_summit = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = 'Malta Summit: roll a die.' + gen_action('roll') +}, + roll() { + clear_undo() + let roll = roll_d6() + log(`Roll: D${roll}`) + if (game.stability > 0) { + logi(`+${Math.min(game.stability, 3)} from USSR Stability Track`) + log(`Modified roll: ${roll + Math.min(game.stability, 3)}`) + } + if (roll + game.stability > 3) { + log('Summit successful') + game.vp += 3 + log('+3 VP') + if (check_vp()) { + return + } + if (game.comInfl[S_DRESDEN] > 0 ) {game.valid_spaces.push(S_DRESDEN)} + if (game.comInfl[S_BYDGOSZCZ] > 0 ) {game.valid_spaces.push(S_BYDGOSZCZ)} + if (game.comInfl[S_PLZEN] > 0 ) {game.valid_spaces.push(S_PLZEN)} + if (game.comInfl[S_SZOMBATHELY] > 0 ) {game.valid_spaces.push(S_SZOMBATHELY)} + if (game.comInfl[S_CLUJ_NAPOCA] > 0 ) {game.valid_spaces.push(S_CLUJ_NAPOCA)} + if (game.comInfl[S_STARA_ZAGORA] > 0 ) {game.valid_spaces.push(S_STARA_ZAGORA)} + game.remove_opponent_infl = true + vm_next() + } + else { + log('Summit failed. Required 4 or more') + vm_return() + } + }, +} + +states.vm_modrow = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = `Modrow: roll a die.` + gen_action('roll') + }, + roll(){ + clear_undo() + let roll = roll_d6() + let dem_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_dem_control(space.space_id)).length + if (roll > dem_spaces) { + log(`Roll: D${roll}`) + log(`Success. More than the ${dem_spaces} Democratically controlled spaces`) + vm_next() + } else { + log(`Roll: D${roll}`) + log(`Fail. More than ${dem_spaces} required`) + permanently_remove(C_MODROW) + vm_return() + } + } +} + +states.vm_nepotism = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = 'Nepotism: roll a die.' + gen_action('roll') + }, + roll() { + clear_undo() + let roll = roll_d6() + if (roll < 3) { + log(`Roll: D${roll} adds 4 SPs`) + game.vm_available_ops = 4} + else if (roll < 5 ) { + log(`Roll: D${roll} adds 3 SPs`) + game.vm_available_ops = 3} + else { + log(`Roll: D${roll} adds 1 SP`) + game.vm_available_ops = 1} + vm_next() + }, +} + +states.vm_new_years_eve_party = { + get inactive() { + return `resolve ${clean_name(cards[C_NEW_YEARS_EVE_PARTY].name)}.` + }, + prompt() { + view.prompt = 'Choose whether the game ends at the end of this turn.' + gen_action('end') + gen_action('continue') + }, + end() { + push_undo() + game.persistent_events.push(C_NEW_YEARS_EVE_PARTY) + log('Chooses to end the game. There will be no final scoring') + let power = game.revolutions.filter(value => value === false).length + if (power > 3) { + log(`Communist holds power in ${pluralize(power, 'country', 's')}. -3 VP`) + game.vp -= 3 + } else { + log(`Communist holds power in ${pluralize(power, 'country', 's')}. +3 VP`) + game.vp += 3 + } + if (check_vp()) { + return + } + vm_next() + }, + continue() { + push_undo() + log('Chooses to continue') + permanently_remove(C_NEW_YEARS_EVE_PARTY) + vm_next() + } +} + +states.vm_nomenklatura = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = 'Nomenklatura: choose to remove all Democratic SPs from Elite spaces or add 3 SPs to any Elite space(s).' + gen_action('remove') + gen_action('add') + }, + remove() { + push_undo() + game.valid_spaces = [] + for (let i = 0; i < spaces.length; i++) { + let space = spaces[i] + + if (space.socio === 1 && game.demInfl[i] > 0) { + game.valid_spaces.push(space.space_id) + } + } + game.vm_available_ops = game.valid_spaces.length + game.remove_opponent_infl = true + game.state = 'vm_nomenklatura_remove' + }, + add() { + push_undo() + game.valid_spaces = [] + for (let space of spaces) { + if (space.socio === 1) { + game.valid_spaces.push(space.space_id) + } + } + check_systematization() + game.vm_available_ops = 3 + game.state = 'vm_nomenklatura_add' + } +} + +states.vm_nomenklatura_remove = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (game.valid_spaces.length === 0 ) { + view.prompt = 'Nomenklatura. No SPs to remove: pass.' + gen_action('pass') + } else { + view.prompt = 'Nomenklatura: remove all Democratic SPs from Elite spaces.' + + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } + }, + space(space) { + push_undo() + vm_do_remove_all_infl(space) + if (game.valid_spaces.length === 0) { + vm_next() + } + }, + pass() { + push_undo() + vm_next() + } +} + +states.vm_nomenklatura_add = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = `Nomenklatura: add 3 SPs to any Elite space(s). ${pluralize(game.vm_available_ops, 'SP')} remaining.` + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + }, + space(space) { + vm_do_add_infl_free(space) + if (game.vm_available_ops === 0 ) { + game.valid_spaces = [] + do_log_summary() + vm_next() + } + }, +} + +states.vm_samizdat = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = 'Samizdat: you may set aside a card from your hand and draw a replacement.' + for (let card of game.democrat_hand) { + gen_action_card(card) + } + gen_action('pass') + }, + card(card) { + push_undo() + game.samizdat_card = card + game.democrat_hand = game.democrat_hand.filter(c => c !== card) + log('Set aside a card') + game.state = 'vm_samizdat_finish' + }, + pass() { + push_undo() + log('Did not set aside a card') + vm_next() + } +} + +states.vm_samizdat_finish = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = 'Draw a replacement card.' + gen_action('draw') + }, + draw() { + clear_undo() + game.democrat_hand.push(draw_card(game.strategy_deck)) + vm_next() + }, +} + +states.vm_shock_therapy = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (game.revolutions.every(n => n === false)) { + view.prompt = 'Shock Therapy: no countries to choose.' + gen_action('pass') + } else { + if (!game.vm_active_country || game.vm_active_country === '' ) { + view.prompt = 'Shock Therapy: choose a country where you hold Power:' + if (game.revolutions[0]) {gen_action('poland')} + if (game.revolutions[1]) {gen_action('hungary')} + if (game.revolutions[2]) {gen_action('east_germany')} + if (game.revolutions[3]) {gen_action('bulgaria')} + if (game.revolutions[4]) {gen_action('czechoslovakia')} + if (game.revolutions[5]) {gen_action('romania')} + } + else { + view.prompt = 'Shock Therapy: roll a die.' + gen_action('roll') + } + } + }, + east_germany() { + push_undo() + game.vm_active_country = 'East_Germany' + log(`Chose ${country_name(game.vm_active_country)}`) + }, + poland() { + push_undo() + game.vm_active_country = 'Poland' + log(`Chose ${country_name(game.vm_active_country)}`) + }, + czechoslovakia() { + push_undo() + game.vm_active_country = 'Czechoslovakia' + log(`Chose ${country_name(game.vm_active_country)}`) + }, + hungary() { + push_undo() + game.vm_active_country = 'Hungary' + log(`Chose ${country_name(game.vm_active_country)}`) + }, + romania() { + push_undo() + game.vm_active_country = 'Romania' + log(`Chose ${country_name(game.vm_active_country)}`) + }, + bulgaria () { + push_undo() + game.vm_active_country = 'Bulgaria' + log(`Chose ${country_name(game.vm_active_country)}`) + }, + roll() { + clear_undo() + let roll = roll_d6() + let worker_farmer = 0 + for (let space of spaces) { + if (space && space.country === game.vm_active_country && check_com_control(space.space_id) && (space.socio === 3 || space.socio === 4)) { + worker_farmer++ + } + } + log(`Roll: D${roll}`) + logi(`-${worker_farmer} from Communist controlled Worker and Farmer spaces`) + log(`Modified roll: ${Math.max(roll - worker_farmer, 0)}`) + if ((roll - worker_farmer) > 2) { + log(`C${C_SHOCK_THERAPY} is successful. +3 VP`) + game.vp += 3 + if (check_vp()) { + return + } + vm_next() + } else { + log('C93 is unsuccessful. Required 3 or more') + permanently_remove(C_SHOCK_THERAPY) + vm_return() + } + }, + pass() { + log('Passed') + vm_return() + } +} + +states.vm_social_democratic_platform_adopted = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (game.revolutions.every(n => n === false)) { + view.prompt = 'Social Democratic Platform Adopted: no countries to choose.' + gen_action('pass') + } else { + view.prompt = 'Select a country where the Democrat holds Power.' + if (game.revolutions[0]) {gen_action('poland')} + if (game.revolutions[1]) {gen_action('hungary')} + if (game.revolutions[2]) {gen_action('east_germany')} + if (game.revolutions[3]) {gen_action('bulgaria')} + if (game.revolutions[4]) {gen_action('czechoslovakia')} + if (game.revolutions[5]) {gen_action('romania')} + } + }, + east_germany() { + push_undo() + game.vm_active_country = 'East_Germany' + log(`Selected ${country_name(game.vm_active_country)}`) + vm_next() + }, + poland() { + push_undo() + game.vm_active_country = 'Poland' + log(`Selected ${country_name(game.vm_active_country)}`) + vm_next() + }, + czechoslovakia() { + push_undo() + game.vm_active_country = 'Czechoslovakia' + log(`Selected ${country_name(game.vm_active_country)}`) + vm_next() + }, + hungary() { + push_undo() + game.vm_active_country = 'Hungary' + log(`Selected ${country_name(game.vm_active_country)}`) + vm_next() + }, + romania() { + push_undo() + game.vm_active_country = 'Romania' + log(`Selected ${country_name(game.vm_active_country)}`) + vm_next() + }, + bulgaria () { + push_undo() + game.vm_active_country = 'Bulgaria' + log(`Selected ${country_name(game.vm_active_country)}`) + vm_next() + }, + pass() { + log('Passed') + vm_return() + } +} + +states.vm_systematization = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = 'Systematization: eliminate a space in Romania.' + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + }, + space(space) { + push_undo() + vm_eliminate(space) + game.valid_spaces = [] + game.systematization = space + add_to_persistent_events(C_SYSTEMATIZATION) + vm_next() + }, +} + +states.vm_the_chinese_solution = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = 'The Chinese Solution: you may give up 3 VP to conduct support checks in a country where you hold power.' + if (!game.revolutions[0]) {gen_action('poland')} + if (!game.revolutions[1]) {gen_action('hungary')} + if (!game.revolutions[2]) {gen_action('east_germany')} + if (!game.revolutions[3]) {gen_action('bulgaria')} + if (!game.revolutions[4]) {gen_action('czechoslovakia')} + if (!game.revolutions[5]) {gen_action('romania')} + gen_action('pass') + }, + east_germany() { + push_undo() + game.vm_active_country = 'East_Germany' + log(`Chose ${country_name(game.vm_active_country)}`) + log('+3 VP') + game.vp += 3 + if (check_vp()) { + return + } + vm_next() + }, + poland() { + push_undo() + game.vm_active_country = 'Poland' + log(`Chose ${country_name(game.vm_active_country)}`) + log('+3 VP') + game.vp += 3 + if (check_vp()) { + return + } + vm_next() + }, + czechoslovakia() { + push_undo() + game.vm_active_country = 'Czechoslovakia' + log(`Chose ${country_name(game.vm_active_country)}`) + log('+3 VP') + game.vp += 3 + if (check_vp()) { + return + } + vm_next() + }, + hungary() { + push_undo() + game.vm_active_country = 'Hungary' + log(`Chose ${country_name(game.vm_active_country)}`) + log('+3 VP') + game.vp += 3 + if (check_vp()) { + return + } + vm_next() + }, + romania() { + push_undo() + game.vm_active_country = 'Romania' + log(`Chose ${country_name(game.vm_active_country)}`) + log('+3 VP') + game.vp += 3 + if (check_vp()) { + return + } + vm_next() + }, + bulgaria () { + push_undo() + game.vm_active_country = 'Bulgaria' + log(`Chose ${country_name(game.vm_active_country)}`) + log('+3 VP') + game.vp += 3 + if (check_vp()) { + return + } + vm_next() + }, + pass() { + push_undo() + logi(`Chose not to conduct support checks`) + permanently_remove(C_THE_CHINESE_SOLUTION) + vm_return() + } +} + +states.vm_the_tyrant_is_gone = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (!game.the_tyrant_is_gone) { + view.prompt = 'The Tyrant is Gone: Select a space in Romania for the Ceausescus to flee to.' + for (let space_id of game.valid_spaces) { + if (!space_id) continue + gen_action_space(space_id); + } + } else { + view.prompt = 'The Tyrant is Gone: done.' + gen_action('done') + } + }, + space(space) { + push_undo() + log(`The Ceausescus flee to %${space}`) + game.the_tyrant_is_gone = space + game.valid_spaces = [] + }, + done () { + vm_next() + } +} + +states.vm_the_wall_must_go = { + get inactive() { + return `resolve ${clean_name(cards[this_card()].name)}.` + }, + prompt() { + view.prompt = ('The Wall Must Go! Roll a die.') + gen_action('roll') + }, + roll() { + clear_undo() + let attempt = game.the_wall_must_go['dem_wins'] + game.the_wall_must_go['com_wins'] + if (game.the_wall_must_go['dem_roll'] === 0 && game.the_wall_must_go['com_roll'] === 0) { + log_h3(`Round ${attempt+1}`) + } + + let roll = roll_d6() + log(`Roll: D${roll}`) + if (game.active === DEM) { + let controlled_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_dem_control(space.space_id)).length + if (controlled_spaces > 0) { + logi(`+${controlled_spaces} from controlled spaces in East Germany`) + log(`Modified roll: ${roll + controlled_spaces}`) + roll += controlled_spaces + } + game.the_wall_must_go['dem_roll'] = roll + } else { + let controlled_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_com_control(space.space_id)).length + if (controlled_spaces > 0) { + logi(`+${controlled_spaces} from controlled spaces in East Germany`) + log(`Modified roll: ${roll + controlled_spaces}`) + roll += controlled_spaces + } + game.the_wall_must_go['com_roll'] = roll + + } + if (game.the_wall_must_go['dem_roll'] > 0 && game.the_wall_must_go['com_roll'] > 0) { + if (game.the_wall_must_go['dem_roll'] > game.the_wall_must_go['com_roll'] ) { + log('Democrat wins') + game.the_wall_must_go['dem_wins']++ + } else if (game.the_wall_must_go['dem_roll'] === game.the_wall_must_go['com_roll'] ) { + log('Tie. Re-roll') + } else { + log('Communist wins') + game.the_wall_must_go['com_wins']++ + } + + log(`Democrat: ${game.the_wall_must_go['dem_wins']}, Communist: ${game.the_wall_must_go['com_wins']}`) + } + if (game.the_wall_must_go['dem_wins'] === 2) { + log('The Democrat wins C86') + finish_the_wall() + return + } + if (game.the_wall_must_go['com_wins'] === 2) { + log('The Communist wins C86') + finish_the_wall() + return + } + if (game.the_wall_must_go['dem_roll'] === 0 || game.the_wall_must_go['com_roll'] === 0) { + next_player() + } else { + game.the_wall_must_go['dem_roll'] = 0 + game.the_wall_must_go['com_roll'] = 0 + } + }, +} + +states.vm_warsaw_pact_summit = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = 'Choose to play for support checks or place SPs.' + gen_action('influence') + gen_action('support_check') + }, + influence(){ + push_undo() + for (let i = 0; i < spaces.length; i++) { + let space = spaces[i] + if (game.demInfl[i] === 0) { + game.valid_spaces.push(space.space_id); + } + } + game.vm_available_ops = 4 + game.phase = 3 + vm_next() + }, + support_check(){ + push_undo() + for (let i = 0; i < spaces.length; i++) { + let space = spaces[i] + if (game.demInfl[i] > 0 && (space.socio === 5 || space.socio === 6)) { + game.valid_spaces.push(space.space_id) + } + } + game.vm_available_ops = 2 + vm_next() + } +} + +states.vm_we_are_the_people_remove = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (game.demInfl[S_LUTHERAN_CHURCH] === 0 && game.vm_available_ops > 0) { + view.prompt = '"We are the People!": no SPs to remove.' + gen_action('done') + } else if (game.vm_available_ops > 0 ) { + view.prompt = '"We are the People!": remove up to 4 SPs from the Lutherian Church.' + gen_action('done') + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + } else { + view.prompt = '"We are the People!" Remove SPs: done.' + gen_action('done') + } + }, + space(space) { + remove_infl(space, 'vm_available_ops') + if (game.vm_influence_added[S_LUTHERAN_CHURCH] === 4) { + game.valid_spaces = [...S_EAST_GERMANY] + game.state = 'vm_we_are_the_people_add' + } + }, + done() { + do_log_summary() + if (!game.vm_influence_added[S_LUTHERAN_CHURCH]) { + log('No SPs removed') + vm_next() + } else { + game.valid_spaces = [...S_EAST_GERMANY] + game.state = 'vm_we_are_the_people_add' + } + } +} +states.vm_we_are_the_people_add = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = `"We are the People!": you must add the ${pluralize(game.vm_influence_added[S_LUTHERAN_CHURCH],'SP')} to spaces in Germany.` + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + }, + space(space) { + vm_do_add_infl_free(space) + game.vm_influence_added[S_LUTHERAN_CHURCH]-- + if (game.vm_influence_added[S_LUTHERAN_CHURCH] === 0 ) { + game.valid_spaces = [] + do_log_summary() + vm_next() + } + }, +} + +states.vm_workers_revolt = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + if (game.valid_spaces.length === 0 ) { + view.prompt = 'Workers Revolt: no valid spaces to select.' + gen_action('pass') + return + } + view.prompt = 'Workers Revolt: select a Worker Space in a country your opponent has power.' + for (let space_id of game.valid_spaces) { + gen_action_space(space_id) + } + }, + pass() { + push_undo() + vm_next() + }, + space(space) { + push_undo() + game.selected_space = space + log(`Chose %${game.selected_space}`) + game.state = 'vm_workers_revolt_finish' + } +} + +states.vm_workers_revolt_finish = { + get inactive() { + return `resolve ${clean_name(cards[game.played_card].name)}.` + }, + prompt() { + view.prompt = `Target: ${spaces[game.selected_space].name_unique}. Roll a die.` + gen_action('roll') + }, + roll() { + clear_undo() + let roll = roll_d6() + log(`Roll: D${roll}`) + let adj = count_adj(game.selected_space) + if (game.active === DEM) { + logi(`-${adj.com_adj} from opponent controlled spaces`) + roll -= adj.com_adj + } else { + logi(`-${adj.dem_adj} from opponent controlled spaces`) + roll -= adj.dem_adj + } + log(`Modified roll: ${Math.max(roll, 0)}`) + if (roll >= 4) { + log('Workers Revolt successful') + vm_replace_all_infl(game.selected_space) + } else {log('Workers Revolt fails. Required 4 or more')} + delete game.selected_space + vm_next() + }, +} +// ==================== TIANANMEN SQUARE TRACK STATES ===================== + +states.vm_tst_3_prep = { + inactive: 'resolve Tiananmen Square Track award.', + prompt() { + view.prompt = 'Tiananmen Square Track award: draw 3 cards.' + gen_action('draw') + }, + draw() { + if (game.active === DEM) { + game.temp = game.democrat_hand.length + draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length + 3, game.communist_hand.length) + game.valid_cards = [game.democrat_hand[game.temp], game.democrat_hand[game.temp + 1], game.democrat_hand[game.temp + 2]] + } else { + game.temp = game.communist_hand.length + draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length + 3) + game.valid_cards = [game.communist_hand[game.temp], game.communist_hand[game.temp + 1], game.communist_hand[game.temp + 2]] + } + game.temp = 0 + game.state = 'vm_tst_3' + } +} + +states.vm_tst_3 = { + inactive: 'resolve Tiananmen Square Track bonus.', + prompt() { + if (game.temp < 2) { + view.prompt = `Discard 2 of the drawn cards.` + for (let card of game.valid_cards) { + gen_action_card(card) + } + } + }, + card(card) { + push_undo() + discard(card) + game.temp ++ + if (game.temp === 2) { + game.valid_cards = [] + vm_next() + } + }, +} + +states.vm_tst_4 = { + inactive: 'remove SPs', + prompt () { + if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) { + view.prompt = 'Tiananmen Square Track award. Remove SPs: done.' + gen_action('done') + return + } + view.prompt = `Tiananmen Square Track award: remove ${pluralize(game.vm_available_ops,'SP')}.` + + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + }, + space(space) { + remove_infl(space, 'vm_available_ops') + if (game.vm_available_ops === 0) { + do_log_summary() + vm_next() + } + }, + done() { + do_log_summary() + vm_next() + } +} + +states.vm_tst_6 = { + inactive: 'make their free support check.', + prompt() { + view.prompt = 'Tiananmen Square Track award: you have a free 2 Ops support check.' + for (let space_id of game.valid_spaces) { + if (space_id) { + gen_action_space(space_id); + } + } + }, + space(space) { + push_undo() + game.selected_space = space + if (game.active === DEM && game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED) && spaces[space].country === "East_Germany") { + game.austria_hungary_border_reopened_tracker = true + } + game.state = 'vm_tst_6_sc' + }, +} + +states.vm_tst_6_sc = { + inactive: 'do support check.', + prompt () { + view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die` + gen_action('roll') + }, + roll() { + clear_undo() + do_sc(game.selected_space) + game.vm_available_ops-- + game.valid_spaces = [] + game.state = 'vm_tst_6' + vm_next() + return + } +} + +states.vm_tst_8 = { + inactive: 'use Tiananmen Square Track award.', + prompt() { + if (game.vm_event_to_do && game.vm_infl_to_do) { + view.prompt = 'Choose whether to play for event or operations first.' + gen_action('event') + gen_action('ops') + } + else if (!game.vm_event_to_do && game.vm_infl_to_do) { + view.prompt = 'Event resolved. Use card for operations.' + gen_action('ops') + } + else if (game.vm_event_to_do && !game.vm_infl_to_do) { + view.prompt = 'Operations resolved. Use card for event.' + gen_action('event') + } + else if (!game.vm_event_to_do && !game.vm_infl_to_do) { + view.prompt = 'Event and operations: done.' + gen_action('end_round') + } + }, + event() { + push_undo() + log(`C${game.played_card}:`) + game.vm_event_to_do = false + game.return_state = 'vm_tst_8' + game.return = game.active + game.vm_event = game.played_card + goto_vm(game.vm_event) + }, + ops() { + push_undo() + log('Operations') + game.vm_infl_to_do = false + game.return = game.active + game.return_state = 'vm_tst_8' + goto_vm(208) + }, + end_round() { + push_undo() + game.tst_8 = true + end_round() + } +} + +states.vm_tst_8_ops = { + inactive: 'play card for operations.', + prompt() { + view.prompt = `Play ${clean_name(cards[game.played_card].name)} for:` + gen_action('influence') + gen_action('support_check') + if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 )) { + gen_action('tst') + } + }, + influence(){ + push_undo() + game.vm_available_ops = cards[game.played_card].ops + valid_spaces_infl() + // If ABHR - Set AHBR tracker to true + if (game.persistent_events.includes(C_AUSTRIA_HUNGARY_BORDER_REOPENED)) { + game.austria_hungary_border_reopened_tracker = true + } + game.state = 'vm_add_infl' + }, + support_check() { + push_undo() + game.vm_available_ops = 2 + game.state = 'vm_support_check_prep' + }, + tst() { + push_undo() + game.state = 'vm_tiananmen_square_attempt' + } +} + +// ========================= POWER STRUGGLE STATES ======================== + +states.vm_scare_tactics = { + inactive: 'remove a Support Point.', + prompt () { + if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) { + view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.` + gen_action('done') + return + } + if (game.vm_available_ops === 0 ) { + view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.` + gen_action('done') + return + } + view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops, 'opponent SP')}${event_prompt()}.` + for (let space_id of game.valid_spaces) { + gen_action_space(space_id); + } + }, + space(space) { + push_undo() + remove_infl(space, 'vm_available_ops') + }, + done() { + do_log_summary() + vm_next() + } +} + +states.vm_support_surges_1 = { + inactive: 'draw cards.', + prompt() { + view.prompt = 'Support Surges: draw a card.' + gen_action('draw') + }, + draw() { + if (game.active === DEM) { + draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+1, game.com_pwr_hand.length) + game.temp = game.dem_pwr_hand[game.dem_pwr_hand.length-1] + } else { + draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+1) + game.temp = game.com_pwr_hand[game.com_pwr_hand.length-1] + } + game.state = 'vm_support_surges_2' + } +} + +states.vm_support_surges_2 = { + inactive: 'draw cards.', + prompt() { + if (wildcards.includes(game.temp)) { + view.prompt = `Support Surges: you drew ${power_cards[game.temp].name}. Draw a second card.` + } + else if (elite_leaders.includes(game.temp)) { + view.prompt = `Support Surges: you drew an ${power_cards[game.temp].name}. Draw a second card.` + } + else if (numberless_cards.includes(game.temp)) { + view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name}. Draw a second card.` + } else { + view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name} ${power_cards[game.temp].value}. Draw a second card.` + } + gen_action('draw') + }, + draw() { + if (game.active === DEM) { + draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+1, game.com_pwr_hand.length) + game.temp = game.dem_pwr_hand[game.dem_pwr_hand.length - 1] + } else { + draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+1) + game.temp = game.com_pwr_hand[game.com_pwr_hand.length - 1] + } + game.state = 'vm_support_surges_3' + } +} + +states.vm_support_surges_3 = { + inactive: 'draw cards.', + prompt() { + if (wildcards.includes(game.temp)) { + view.prompt = `Support Surges: you drew ${power_cards[game.temp].name}. Done.` + } + else if (elite_leaders.includes(game.temp)) { + view.prompt = `Support Surges: you drew an ${power_cards[game.temp].name}. Done.` + } + else if (numberless_cards.includes(game.temp)) { + view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name}. Done.` + } else { + view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name} ${power_cards[game.temp].value}. Done.` + } + gen_action('done') + }, + done() { + game.phase = 0 + delete game.temp + log('Drew 2 cards') + log('Surrenders initiative') + vm_next() + } +} + +states.vm_support_falters = { + inactive: 'discard cards.', + prompt() { + if ((game.active === DEM && game.dem_pwr_hand.length === 0) || (game.active === COM && game.com_pwr_hand.length === 0)) { + view.prompt = 'Support Falters: no remaining cards to discard.' + gen_action('pass') + } else if (game.vm_available_ops > 0) { + view.prompt = 'Support Falters: discard a card.' + gen_action('discard') + } else { + view.prompt = 'Support Falters: done.' + gen_action('done') + } + }, + discard() { + if (game.active === DEM) {discard_card(game.dem_pwr_hand)} + else {discard_card(game.com_pwr_hand)} + game.vm_available_ops -- + }, + pass() { + log_msg_gap('Takes initiative') + game.return = game.active + vm_next() + }, + done() { + log_gap('Takes initiative') + game.return = game.active + vm_next() + } +} + +/* =================== EVENTS ================================ */ + +// #region GENERATED EVENT CODE +const CODE = [] + +CODE[1] = [ // Legacy of Martial Law* + [ vm_permanently_remove ], + [ vm_valid_spaces_country_opp, 'Poland' ], + [ vm_prompt, 'replace 1 Democratic SP in Poland with a Communist SP' ], + [ vm_legacy_of_martial_law ], + [ vm_valid_spaces_country_sc, 'Poland' ], + [ vm_prompt, 'make a Support Check in Poland' ], + [ vm_1_support_check ], + [ vm_return ], +] + +CODE[2] = [ // Solidarity Legalised* + [ vm_solidarity_legalised ], + [ vm_valid_spaces_solidarity_legalised ], + [ vm_prompt, 'to every uncontrolled Worker and Farmer space in Poland' ], + [ vm_add_limited_infl, 9, 1 ], + [ vm_return ], +] + +CODE[3] = [ // Walesa + [ vm_permanently_remove ], + [ vm_valid_spaces_country, 'Poland' ], + [ vm_prompt, 'any space(s) in Poland' ], + [ vm_add_infl_free, 4 ], + [ vm_valid_spaces_country_sc, 'Poland' ], + [ vm_prompt, 'make Support Checks in Poland' ], + [ vm_support_check, 2 ], + [ vm_return ], +] + +CODE[4] = [ // Michnik + [ vm_permanently_remove ], + [ vm_valid_spaces, 'Polish Writers' ], + [ vm_prompt, 'the Polish Intellectuals space' ], + [ vm_add_x_infl, 3 ], + [ vm_return ], +] + +CODE[5] = [ // General strike + [ vm_general_strike ], + [ vm_return ], +] + +CODE[6] = [ // Brought in for Questioning + [ vm_if, ()=>!is_auto_resolve(C_BROUGHT_IN_FOR_QUESTIONING) ], + [ vm_brought_in_for_questioning ], + [ vm_endif ], + [ vm_return ], +] + +CODE[7] = [ // State Run Media* + [ vm_permanently_remove ], + [ vm_valid_spaces_opponent ], + [ vm_remove_limited_opp_infl, 4, 2 ], + [ vm_return ], +] + +CODE[8] = [ // Prudence + [ vm_prudence ], + [ vm_return ], +] + +CODE[9] = [ // The Wall* + [ vm_the_wall ], + [ vm_return ], +] + +CODE[10] = [ // Cult of Personality + [ vm_permanently_remove ], + [ vm_if, ()=>!game.persistent_events.includes(THE_TYRANT_IS_GONE_OCCURRED) ], + [ vm_valid_spaces_country_socio_2, 'Romania', 3, 4 ], + [ vm_prompt, 'Worker or Farmer spaces in Romania, no more than 2 per space' ], + [ vm_add_limited_infl, 4, 2 ], + [ vm_else ], + [ vm_tyrant_block ], + [ vm_endif ], + [ vm_return ], +] + +CODE[11] = [ // Dissident arrested + [ vm_if, ()=>!is_auto_resolve(C_DISSIDENT_ARRESTED) ], + [ vm_valid_spaces_opponent_socio, 5 ], + [ vm_prompt, 'any Intellectuals space' ], + [ vm_remove_x_opp_infl, 2 ], + [ vm_endif ], + [ vm_return ], +] + +CODE[12] = [ // Apparatchicks + [ vm_permanently_remove ], + [ vm_valid_spaces_socio, 2 ], + [ vm_prompt, ' to any Bureaucratic space(s)' ], + [ vm_add_infl_free, 3 ], + [ vm_return ], +] + +CODE[13] = [ // Stasi + [ vm_stasi ], + [ vm_return ], +] + +CODE[14] = [ // Gorbachev Charms the West + [ vm_valid_spaces_opponent ], + [ vm_remove_opp_infl, 2 ], + [ vm_valid_spaces_sc ], + [ vm_prompt, 'select a space for the Support Check' ], + [ vm_1_support_check ], + [ vm_return ], +] + +CODE[15] = [ // Honecker + [ vm_honecker ], + [ vm_return ], +] + +CODE[16] = [ // Nomenklatura* + [ vm_permanently_remove ], + [ vm_nomenklatura ], + [ vm_return ], +] + +CODE[17] = [ // Roundtable talks + [ vm_roundtable_talks ], + [ vm_return ], +] + +CODE[18] = [ // Poszgay Defends the Revolution + [ vm_permanently_remove ], + [ vm_poszgay ], + [ vm_prompt, 'to 4 spaces in Hungary not under Democratic control' ], + [ vm_add_limited_infl, 4, 1 ], + [ vm_return ], +] + +CODE[19] = [ // Papal vist + [ vm_permanently_remove ], + [ vm_valid_spaces, 'Catholic Church, Poland', 'Catholic Church, Czechoslovakia', 'Catholic Church, Hungary' ], + [ vm_prompt, 'any Catholic Church space' ], + [ vm_add_x_infl, 3 ], + [ vm_return ], +] + +CODE[20] = [ // Deutsche Marks* + [ vm_permanently_remove ], + [ vm_if, ()=>!is_auto_resolve(C_DEUTSCHE_MARKS) ], + [ vm_deutsche_marks ], + [ vm_endif ], + [ vm_return ], +] + +CODE[21] = [ // Common European Home + [ vm_common_european_home ], + [ vm_return ], +] + +CODE[22] = [ // Power Struggle - Poland + [ vm_power_struggle ], + [ vm_return ], +] + +CODE[23] = [ // Power Struggle - Hungary + [ vm_power_struggle ], + [ vm_return ], +] + +CODE[24] = [ // St Nicolas Church + [ vm_if, ()=>!check_dem_control(S_LUTHERAN_CHURCH) ], + [ vm_valid_spaces, 'Lutheran Church' ], + [ vm_prompt, 'the Lutheran Church' ], + [ vm_take_control_prep, 1 ], + [ vm_endif ], + [ vm_st_nicholas_church ], + [ vm_return ], +] + +CODE[25] = [ // Perestroika + [ vm_perestroika ], + [ vm_return ], +] + +CODE[26] = [ // Helsinki Final Act* + [ vm_helsinki_final_act ], + [ vm_return ], +] + +CODE[27] = [ // Consumerism + [ vm_valid_spaces_opponent_socio, 4 ], + [ vm_prompt, ' from a Worker space' ], + [ vm_remove_opp_infl, 1 ], + [ vm_valid_spaces_opponent_socio, 4 ], + [ vm_active_country ], + [ vm_prompt, ()=>`make a support check in a Worker space in ${country_name(game.vm_active_country)}` ], + [ vm_1_support_check ], + [ vm_return ], +] + +CODE[28] = [ // Factory Party Cells + [ vm_valid_spaces_opponent_socio, 4 ], + [ vm_prompt, ' from Worker spaces' ], + [ vm_remove_limited_opp_infl, 3, 2 ], + [ vm_return ], +] + +CODE[29] = [ // Jan Palach Week* + [ vm_permanently_remove ], + [ vm_valid_spaces, 'Charles University' ], + [ vm_prompt, 'the Charles University space' ], + [ vm_add_x_infl, 6 ], + [ vm_return ], +] + +CODE[30] = [ // Tear Gas + [ vm_tear_gas ], + [ vm_return ], +] + +CODE[31] = [ // Intelligentsia + [ vm_valid_spaces_socio, 5 ], + [ vm_prompt, 'Intellectual spaces, no more than 2 per space' ], + [ vm_add_limited_infl, 4, 2 ], + [ vm_return ], +] + +CODE[32] = [ // Peasant Parties* + [ vm_permanently_remove ], + [ vm_valid_spaces_socio, 3 ], + [ vm_prompt, 'Farmer spaces, no more than 2 per space' ], + [ vm_add_limited_infl, 4, 2 ], + [ vm_return ], +] + +CODE[33] = [ // Sajudis* + [ vm_permanently_remove ], + [ vm_sajudis ], + [ vm_if, ()=>!is_auto_resolve(C_SAJUDIS) ], + [ vm_sajudis_check ], + [ vm_prompt, 'any Minorities space' ], + [ vm_take_control_prep, 1 ], + [ vm_endif ], + [ vm_return ], +] + +CODE[34] = [ // Fidesz* + [ vm_permanently_remove ], + [ vm_valid_spaces, 'Eotvos Lorand University' ], + [ vm_prompt, 'the Hungary students space' ], + [ vm_add_x_infl, 5 ], + [ vm_return ], +] + +CODE[35] = [ // Heal our Bleeding Wounds* + [ vm_permanently_remove ], + [ vm_heal_our_bleeding_wounds ], + [ vm_return ], +] + +CODE[36] = [ // Dash for the West* + [ vm_permanently_remove ], + [ vm_prompt, 'Dash for the West: select any Democratic Event with an asterix(*) from the discard pile. Event occurs immediately' ], + [ vm_dash_for_the_west ], + [ vm_return ], +] + +CODE[37] = [ // Nagy Reburied* + [ vm_permanently_remove ], + [ vm_nagy_reburied ], + [ vm_prompt, 'the Hungary Elite space' ], + [ vm_remove_all_infl, 1 ], + [ vm_valid_spaces_country, 'Hungary' ], + [ vm_prompt, 'Hungary, no more than 2 per space' ], + [ vm_add_limited_infl, 4, 2 ], + [ vm_return ], +] + +CODE[38] = [ // July Concept + [ vm_permanently_remove ], + [ vm_valid_spaces_country, 'Bulgaria' ], + [ vm_prompt, 'Bulgaria' ], + [ vm_add_infl_free, 3 ], + [ vm_return ], +] + +CODE[39] = [ // Eco-Glasnost* + [ vm_valid_spaces, 'Ruse' ], + [ vm_prompt, 'Ruse' ], + [ vm_add_x_infl, 4 ], + [ vm_eco_glasnost ], + [ vm_return ], +] + +CODE[40] = [ // Hungarian Democratic Forum + [ vm_permanently_remove ], + [ vm_valid_spaces_country, 'Hungary' ], + [ vm_prompt, 'Hungary' ], + [ vm_add_infl_free, 3 ], + [ vm_valid_spaces_country_sc, 'Hungary' ], + [ vm_prompt, 'make a Support Check in Hungary' ], + [ vm_1_support_check ], + [ vm_return ], +] + +CODE[41] = [ // Ceausescu* + [ vm_permanently_remove ], + [ vm_if, ()=>game.persistent_events.includes(THE_TYRANT_IS_GONE_OCCURRED) ], + [ vm_tyrant_block ], + [ vm_else ], + [ vm_if, ()=>!is_auto_resolve(C_CEAUSESCU) ], + [ vm_valid_spaces_country_opp, 'Romania' ], + [ vm_prompt, ' from Romania' ], + [ vm_remove_opp_infl, 3 ], + [ vm_valid_spaces_country_sc, 'Romania' ], + [ vm_prompt, 'make a support check in Romania' ], + [ vm_1_support_check ], + [ vm_prompt, ' from Bucharesti' ], + [ vm_ceausescu ], + [ vm_endif ], + [ vm_return ], +] + +CODE[42] = [ // Power Struggle - East Germany + [ vm_power_struggle ], + [ vm_return ], +] + +CODE[43] = [ // Power Struggle - Bulgaria + [ vm_power_struggle ], + [ vm_return ], +] + +CODE[44] = [ // Inflationary Currency + [ vm_permanently_remove ], + [ vm_inflationary_currency ], + [ vm_valid_spaces_country_opp ], + [ vm_prompt, ()=>` from ${country_name(game.vm_active_country)}` ], + [ vm_remove_opp_infl, 2 ], + [ vm_inflationary_currency_discard ], + [ vm_if, ()=>!discarded_card() ], + [ vm_valid_spaces_country_sc ], + [ vm_prompt, ()=>`make a Support Check in ${country_name(game.vm_active_country)}` ], + [ vm_1_support_check ], + [ vm_endif ], + [ vm_return ], +] + +CODE[45] = [ // Soviet Troop Withdrawals* + [ vm_permanently_remove ], + [ vm_valid_spaces_region_opp, 'Eastern Europe' ], + [ vm_prompt, ' from Eastern Europe' ], + [ vm_remove_limited_opp_infl, 5, 2 ], + [ vm_return ], +] + +CODE[46] = [ // Goodbye Lenin!* + [ vm_permanently_remove ], + [ vm_goodbye_lenin ], + [ vm_return ], +] + +CODE[47] = [ // Bulgarian Turks Expelled* + [ vm_permanently_remove ], + [ vm_bulgarian_turks_expelled ], + [ vm_if, ()=>!is_auto_resolve(C_BULGARIAN_TURKS_EXPELLED) ], + [ vm_valid_spaces, 'Razgrad' ], + [ vm_prompt, 'Razgrad' ], + [ vm_remove_all_infl, 1 ], + [ vm_endif ], + [ vm_return ], +] + +CODE[48] = [ // We are the People!* + [ vm_if, ()=>!is_auto_resolve(C_WE_ARE_THE_PEOPLE) ], + [ vm_we_are_the_people ], + [ vm_endif ], + [ vm_return ], +] + +CODE[49] = [ // Foreign Currency Debt Burden* + [ vm_foreign_currency_debt_burden ], + [ vm_logi, ()=>`Communist cannot make Support Checks in ${country_name(game.foreign_currency_debt_burden)} for the rest of the turn` ], + [ vm_return ], +] + +CODE[50] = [ // The Sinatra Doctrine* + [ vm_the_sinatra_doctrine ], + [ vm_return ], +] + +CODE[51] = [ // 40th Anniversary Celebration* + [ vm_permanently_remove ], + [ vm_40th_anniversary_celebration ], + [ vm_valid_spaces_country, 'East_Germany' ], + [ vm_prompt, 'East Germany' ], + [ vm_add_infl_free ], + [ vm_40th_anniversary_celebration_vp ], + [ vm_return ], +] + +CODE[52] = [ // Normalization + [ vm_permanently_remove ], + [ vm_if, ()=>!is_auto_resolve(C_NORMALIZATION) ], + [ vm_normalization ], + [ vm_prompt, 'the Czechoslovakia Elite and Bureaucrat Spaces' ], + [ vm_remove_all_infl, 2 ], + [ vm_endif ], + [ vm_return ], +] + +CODE[53] = [ // Li Peng* + [ vm_li_peng ], + [ vm_return ], +] + +CODE[54] = [ // The Crowd Turns Against Ceausescu* + [ vm_the_crowd_turns_against_ceausescu ], + [ vm_return ], +] + +CODE[55] = [ // Power Struggle - Czechoslovakia + [ vm_power_struggle ], + [ vm_return ], +] + +CODE[56] = [ // Foreign Television + [ vm_permanently_remove ], + [ vm_foreign_television ], + [ vm_remove_limited_opp_infl, 4, 2 ], + [ vm_return ], +] + +CODE[57] = [ // Central Committee Reshuffle* + [ vm_permanently_remove ], + [ vm_central_committee_reshuffle ], + [ vm_prompt, ()=>`${country_name(game.vm_active_country)}` ], + [ vm_add_infl_free, 3 ], + [ vm_return ], +] + +CODE[58] = [ // Austria-Hungary Border Reopened* + [ vm_austria_hungary_border_reopened ], + [ vm_return ], +] + +CODE[59] = [ // Grenztruppen* + [ vm_grenztruppen ], + [ vm_return ], +] + +CODE[60] = [ // Toxic Waste* + [ vm_permanently_remove ], + [ vm_valid_spaces_socio, 4 ], + [ vm_prompt, 'any Worker space(s)' ], + [ vm_add_infl_free, 3 ], + [ vm_return ], +] + +CODE[61] = [ // The Monday Demonstrations* + [ vm_permanently_remove ], + [ vm_the_monday_demonstrations ], + [ vm_prompt, 'the Lutheran Church Space and Leipzig' ], + [ vm_take_control_prep, 2 ], + [ vm_valid_spaces_country_sc, 'East_Germany' ], + [ vm_prompt, 'make 5 Support Checks in East Germany' ], + [ vm_support_check, 5 ], + [ vm_return ], +] + +CODE[62] = [ // Yakovlev Counsels Gorbachev* + [ vm_yakovlev_counsels_gorbachev ], + [ vm_return ], +] + +CODE[63] = [ // Genscher* + [ vm_genscher ], + [ vm_return ], +] + +CODE[64] = [ // Legacy of 1968* + [ vm_permanently_remove ], + [ vm_legacy_of_1968 ], + [ vm_prompt, 'all spaces in Czechoslovakia not controlled by the Communist Player' ], + [ vm_add_limited_infl, 11, 1 ], + [ vm_return ], +] + +CODE[65] = [ // Presidential Visit* + [ vm_presidential_visit ], + [ vm_return ], +] + +CODE[66] = [ // New Forum + [ vm_permanently_remove ], + [ vm_valid_spaces_country, 'East_Germany' ], + [ vm_prompt, '3 spaces in East Germany' ], + [ vm_add_limited_infl, 3, 1 ], + [ vm_return ], +] + +CODE[67] = [ // Reformer Rehabilitated* + [ vm_prompt, 'Reformer Rehabilitated: chose any non-scoring card in the discard pile. Event takes place immediately' ], + [ vm_reformer_rehabilitated ], + [ vm_return ], +] + +CODE[68] = [ // Klaus and Komarek* + [ vm_permanently_remove ], + [ vm_klaus_and_komarek ], + [ vm_prompt, 'Prague' ], + [ vm_remove_x_opp_infl, 2 ], + [ vm_valid_spaces, 'Praha' ], + [ vm_add_x_infl, 2 ], + [ vm_return ], +] + +CODE[69] = [ // Systematization* + [ vm_if, ()=>!game.persistent_events.includes(THE_TYRANT_IS_GONE_OCCURRED) ], + [ vm_valid_spaces_country, 'Romania' ], + [ vm_systematization ], + [ vm_else ], + [ vm_tyrant_block ], + [ vm_endif ], + [ vm_return ], +] + +CODE[70] = [ // Securitate* + [ vm_if, ()=>!game.persistent_events.includes(C_ARMY_BACKS_REVOLUTION) ], + [ vm_securitate ], + [ vm_else ], + [ vm_army_block ], + [ vm_endif ], + [ vm_return ], +] + +CODE[71] = [ // Kiss of Death* + [ vm_permanently_remove ], + [ vm_if, ()=>!is_auto_resolve(C_KISS_OF_DEATH) ], + [ vm_kiss_of_death ], + [ vm_endif ], + [ vm_return ], +] + +CODE[72] = [ // Peasant Parties Revolt + [ vm_peasant_parties_revolt ], + [ vm_return ], +] + +CODE[73] = [ // Laszlo Tokes* + [ vm_valid_spaces, 'Timisoara', 'Harghita/Covasna' ], + [ vm_prompt, 'in Timisoara and Harghita/Covasna' ], + [ vm_add_limited_infl, 2, 1 ], + [ vm_laszlo_tokes ], + [ vm_if, ()=>game.phase === 3 ], + [ vm_prompt, ' in Romania' ], + [ vm_add_infl ], + [ vm_else ], + [ vm_prompt, 'make 2 Support Checks in Romania' ], + [ vm_support_check, 2 ], + [ vm_endif ], + [ vm_return ], +] + +CODE[74] = [ // FRG Embassies + [ vm_frg_embassies ], + [ vm_return ], +] + +CODE[75] = [ // Exit Visas* + [ vm_permanently_remove ], + [ vm_if, ()=>!is_auto_resolve(C_EXIT_VISAS) ], + [ vm_exit_visas ], + [ vm_endif ], + [ vm_return ], +] + +CODE[76] = [ // Warsaw Pact Summit + [ vm_permanently_remove ], + [ vm_warsaw_pact_summit ], + [ vm_if, ()=>game.phase === 3 ], + [ vm_prompt, ' spaces with no Democratic SPs' ], + [ vm_add_infl_free, 4 ], + [ vm_else ], + [ vm_prompt, 'Select a Student or Intellectual space' ], + [ vm_valid_spaces_country_socio_2, 3, 4 ], + [ vm_support_check_modified, 2, 2 ], + [ vm_endif ], + [ vm_return ], +] + +CODE[77] = [ // Samizdat + [ vm_permanently_remove ], + [ vm_if, ()=>!is_auto_resolve(C_SAMIZDAT) ], + [ vm_samizdat ], + [ vm_endif ], + [ vm_return ], +] + +CODE[78] = [ // Workers Revolt + [ vm_workers_revolt ], + [ vm_return ], +] + +CODE[79] = [ // The Third Way* + [ vm_permanently_remove ], + [ vm_the_third_way ], + [ vm_valid_spaces, 'German Writers' ], + [ vm_prompt, 'the East German Writers space' ], + [ vm_add_x_infl, 3 ], + [ vm_return ], +] + +CODE[80] = [ // Nepotism* + [ vm_permanently_remove ], + [ vm_nepotism ], + [ vm_valid_spaces_region_socio, 'Balkans', 4 ], + [ vm_prompt, 'Worker spaces in the Balkans' ], + [ vm_add_infl_free ], + [ vm_return ], +] + +CODE[81] = [ // The Baltic Way* + [ vm_permanently_remove ], + [ vm_the_baltic_way_prep ], + [ vm_if, ()=>!is_auto_resolve(C_THE_BALTIC_WAY) ], + [ vm_the_baltic_way ], + [ vm_prompt, 'any Minorities space' ], + [ vm_take_control_prep, 1 ], + [ vm_endif ], + [ vm_return ], +] + +CODE[82] = [ // Spitzel* + [ vm_permanently_remove ], + [ vm_if, ()=>!is_auto_resolve(C_SPITZEL) ], + [ vm_valid_spaces_country_opp, 'East_Germany' ], + [ vm_prompt, ' from East Germany' ], + [ vm_remove_opp_infl, 2 ], + [ vm_endif ], + [ vm_return ], +] + +CODE[83] = [ // Modrow* + [ vm_modrow ], + [ vm_valid_spaces_country, 'East_Germany' ], + [ vm_prompt, 'East Germany, no more than 2 per space' ], + [ vm_add_limited_infl, 4, 2 ], + [ vm_return ], +] + +CODE[84] = [ // Breakaway Baltic Republics* + [ vm_permanently_remove ], + [ vm_breakaway_baltic_republics ], + [ vm_prompt, 'any Minorities space' ], + [ vm_take_control_prep, 1 ], + [ vm_valid_spaces_sc ], + [ vm_prompt, 'select a space for the support check' ], + [ vm_1_support_check ], + [ vm_return ], +] + +CODE[85] = [ // Tank Column/Tank Man* + [ vm_permanently_remove ], + [ vm_tank_column ], + [ vm_return ], +] + +CODE[86] = [ // The Wall Must Go!* + [ vm_the_wall_must_go ], + [ vm_remove_infl, 3 ], + [ vm_return ], +] + +CODE[87] = [ // Kohl Proposes Reunification* + [ vm_permanently_remove ], + [ vm_kohl_proposes_reunification_prep ], + [ vm_if, ()=>!is_auto_resolve(C_KOHL_PROPOSES_REUNIFICATION) ], + [ vm_kohl_proposes_reunification ], + [ vm_else ], + [ vm_logi, ()=>`C${C_THE_WALL_MUST_GO} has not been successfully played for the event.` ], + [ vm_endif ], + [ vm_return ], +] + +CODE[88] = [ // Adamec* + [ vm_permanently_remove ], + [ vm_adamec ], + [ vm_valid_spaces_country, 'Czechoslovakia' ], + [ vm_prompt, 'Czechoslovakia' ], + [ vm_add_limited_infl, 4, 2 ], + [ vm_return ], +] + +CODE[89] = [ // Domino Theory* + [ vm_permanently_remove ], + [ vm_if, ()=>!is_auto_resolve(C_DOMINO_THEORY) ], + [ vm_prompt, 'Domino Theory: choose a Power Struggle card to play from the discard pile' ], + [ vm_domino_theory ], + [ vm_else ], + [ vm_domino_theory_pass ], + [ vm_endif ], + [ vm_return ], +] + +CODE[90] = [ // Civic Forum* + [ vm_permanently_remove ], + [ vm_civic_forum_prep ], + [ vm_valid_spaces_country, 'Czechoslovakia' ], + [ vm_prompt, 'Czechoslovakia' ], + [ vm_add_infl_free, 4 ], + [ vm_civic_forum ], + [ vm_valid_spaces_country_sc, 'Czechoslovakia' ], + [ vm_prompt, 'Select a space in Czechoslovakia' ], + [ vm_support_check, 2 ], + [ vm_return ], +] + +CODE[91] = [ // My First Banana* + [ vm_permanently_remove ], + [ vm_if, ()=>!is_auto_resolve(C_MY_FIRST_BANANA) ], + [ vm_valid_spaces_country_opp, 'East_Germany' ], + [ vm_prompt, ' from East Germany' ], + [ vm_remove_opp_infl, 2 ], + [ vm_valid_spaces_country_sc, 'East_Germany' ], + [ vm_prompt, 'select a space in East Germany' ], + [ vm_support_check, 2 ], + [ vm_endif ], + [ vm_return ], +] + +CODE[92] = [ // Betrayal + [ vm_permanently_remove ], + [ vm_if, ()=>!is_auto_resolve(C_BETRAYAL) ], + [ vm_prompt, 'choose any Orthodox Church space. Replace all Democratic SPs with Communist SPs' ], + [ vm_betrayal ], + [ vm_endif ], + [ vm_return ], +] + +CODE[93] = [ // Shock Therapy* + [ vm_permanently_remove ], + [ vm_shock_therapy ], + [ vm_valid_spaces_country ], + [ vm_prompt, ()=>` ${country_name(game.vm_active_country)}` ], + [ vm_add_infl_free, 3 ], + [ vm_return ], +] + +CODE[94] = [ // Union of Democratic Forces* + [ vm_permanently_remove ], + [ vm_if, ()=>!is_auto_resolve(C_UNION_OF_DEMOCRATIC_FORCES) ], + [ vm_valid_spaces_country_opp, 'Bulgaria' ], + [ vm_prompt, ' from Bulgaria' ], + [ vm_remove_limited_opp_infl, 4, 2 ], + [ vm_valid_spaces_country_sc, 'Bulgaria' ], + [ vm_prompt, 'Make 2 Support Checks in Bulgaria' ], + [ vm_support_check, 2 ], + [ vm_endif ], + [ vm_return ], +] + +CODE[95] = [ // Power Struggle - Romania + [ vm_power_struggle ], + [ vm_return ], +] + +CODE[96] = [ // The Chinese Solution* + [ vm_permanently_remove ], + [ vm_the_chinese_solution ], + [ vm_valid_spaces_country_sc ], + [ vm_prompt, ()=>`make 5 Support Checks in ${country_name(game.vm_active_country)}` ], + [ vm_support_check_modified, 5, 3 ], + [ vm_return ], +] + +CODE[97] = [ // The Tyrant is Gone* + [ vm_if, ()=>game.persistent_events.includes(THE_CROWD_TURNS_AGAINST_CEAUSESCU_OCCURRED) ], + [ vm_cluj_check ], + [ vm_prompt, 'the Romanian Elite Space' ], + [ vm_remove_x_opp_infl, 4 ], + [ vm_the_tyrant_is_gone ], + [ vm_permanently_remove ], + [ vm_else ], + [ vm_the_tyrant_is_gone_prep ], + [ vm_endif ], + [ vm_return ], +] + +CODE[98] = [ // Politburo Intrigue* + [ vm_permanently_remove ], + [ vm_if, ()=>!is_auto_resolve(C_POLITBURO_INTRIGUE) ], + [ vm_valid_spaces_country_opp, 'Bulgaria' ], + [ vm_prompt, ' from Bulgaria' ], + [ vm_remove_limited_opp_infl, 3, 2 ], + [ vm_valid_spaces_country_sc, 'Bulgaria' ], + [ vm_prompt, 'make a support check in Bulgaria' ], + [ vm_1_support_check ], + [ vm_endif ], + [ vm_return ], +] + +CODE[99] = [ // Ligachev* + [ vm_ligachev ], + [ vm_return ], +] + +CODE[100] = [ // Stand Fast* + [ vm_stand_fast ], + [ vm_return ], +] + +CODE[101] = [ // Elena* + [ vm_if, ()=>!game.persistent_events.includes(THE_TYRANT_IS_GONE_OCCURRED) ], + [ vm_valid_spaces, 'Cluj-Napoca' ], + [ vm_prompt, 'the Romania Elite Space' ], + [ vm_add_x_infl, 2 ], + [ vm_elena ], + [ vm_else ], + [ vm_tyrant_block ], + [ vm_endif ], + [ vm_return ], +] + +CODE[102] = [ // National Salvation Front* + [ vm_national_salvation_front ], + [ vm_return ], +] + +CODE[103] = [ // Government Resigns* + [ vm_permanently_remove ], + [ vm_if, ()=>!is_auto_resolve(C_GOVERNMENT_RESIGNS) ], + [ vm_government_resigns ], + [ vm_prompt, 'any uncontrolled Elite space' ], + [ vm_remove_all_infl, 1 ], + [ vm_endif ], + [ vm_return ], +] + +CODE[104] = [ // New Year's Eve Party* + [ vm_new_years_eve_party ], + [ vm_return ], +] + +CODE[105] = [ // Public Against Violence* + [ vm_permanently_remove ], + [ vm_valid_spaces, 'Kosice' ], + [ vm_prompt, 'Kosice' ], + [ vm_add_x_infl, 2 ], + [ vm_valid_spaces, 'Presov' ], + [ vm_prompt, 'Presov' ], + [ vm_add_x_infl, 2 ], + [ vm_public_against_violence ], + [ vm_prompt, 'Make a Support Check in Bratislava' ], + [ vm_support_check_modified, 1, 2 ], + [ vm_return ], +] + +CODE[106] = [ // Social Democratic Platform Adopted* + [ vm_permanently_remove ], + [ vm_social_democratic_platform_adopted ], + [ vm_valid_spaces_country ], + [ vm_prompt, ()=>`${country_name(game.vm_active_country)}` ], + [ vm_add_infl_free, 2 ], + [ vm_valid_spaces_country_sc ], + [ vm_prompt, ()=>`make a Support Check in ${country_name(game.vm_active_country)}` ], + [ vm_1_support_check ], + [ vm_return ], +] + +CODE[107] = [ // Massacre in Timisoara* + [ vm_permanently_remove ], + [ vm_if, ()=>!game.persistent_events.includes(THE_TYRANT_IS_GONE_OCCURRED) ], + [ vm_massacre_in_timisoara ], + [ vm_valid_spaces_country_sc, 'Romania' ], + [ vm_prompt, 'Make Support Checks in Romania' ], + [ vm_support_check_modified, 2, 2 ], + [ vm_else ], + [ vm_tyrant_block ], + [ vm_endif ], + [ vm_return ], +] + +CODE[108] = [ // Army Backs Revolution* + [ vm_army_backs_revolution ], + [ vm_return ], +] + +CODE[109] = [ // Kremlin Coup* + [ vm_permanently_remove ], + [ vm_kremlin_coup ], + [ vm_return ], +] + +CODE[110] = [ // Malta Summit* + [ vm_permanently_remove ], + [ vm_malta_summit ], + [ vm_prompt, ' from Elite spaces' ], + [ vm_remove_opp_infl, 5 ], + [ vm_return ], +] + +CODE[203] = [ // Tiananmen Square space 3 award + [ vm_tst_3 ], + [ vm_return ], +] + +CODE[204] = [ // Tiananmen Square space 4 award + [ vm_valid_spaces_opponent ], + [ vm_tst_4 ], + [ vm_return ], +] + +CODE[206] = [ // Tiananmen Square space 6 + [ vm_valid_spaces_sc ], + [ vm_tst_6 ], + [ vm_return ], +] + +CODE[208] = [ // Tiananmen Square space 8 event + [ vm_tst_8 ], + [ vm_return ], +] + +CODE[349] = [ // Support Falters + [ vm_support_falters ], + [ vm_return ], +] + +CODE[350] = [ // Support Surges + [ vm_support_surges ], + [ vm_return ], +] + +CODE[351] = [ // Scare Tactics + [ vm_scare_tactics ], + [ vm_valid_spaces_country_opp ], + [ vm_prompt, ()=>` from ${country_name(game.vm_active_country)}` ], + [ vm_remove_opp_infl, 1 ], + [ vm_return ], +] +// #endregion |