summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rules.js6927
1 files changed, 6074 insertions, 853 deletions
diff --git a/rules.js b/rules.js
index 90dab53..abe0a25 100644
--- a/rules.js
+++ b/rules.js
@@ -1,7 +1,13 @@
//"use strict"
-const { finished } = require("nodemailer/lib/xoauth2/index.js")
-const data = require("./data.js")
+const { getMaxListeners } = require("ws")
+
+const { spaces, cards, power_cards } = require("./data.js")
+const { resolveContent } = require("nodemailer/lib/shared/index.js")
+const { pipeline, PassThrough } = require("nodemailer/lib/xoauth2/index.js")
+const e = require("express")
+const { getTestMessageUrl } = require("nodemailer")
+
var game, view, states = {}
@@ -13,269 +19,22 @@ 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 = [17, 18, 19, 21, 22, 23]
+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 = ['East Germany', 'Poland', 'Czechoslovakia', 'Hungary', 'Romania', 'Bulgaria']
+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 spaces = [
-{name: 'Schwerin', name_unique: 'Schwerin', space_id: 1, socio: 4, stability: 3, battleground: 0, country: 'East Germany', box: {x: 111, y: 61, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [2, 3, , , ]},
-{name: 'Rostock', name_unique: 'Rostock', space_id: 2, socio: 4, stability: 3, battleground: 0, country: 'East Germany', box: {x: 228, y: 41, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [1, 3, , , ]},
-{name: 'Berlin', name_unique: 'Berlin', space_id: 3, socio: 2, stability: 3, battleground: 1, country: 'East Germany', box: {x: 251, y: 113, h: 65, w: 105}, demInfl: 0, comInfl: 2, demCtrl: 0, comCtrl: 0, adjacent: [1, 2, 5, 9, ]},
-{name: 'German Writers', name_unique: 'German Writers', space_id: 4, socio: 5, stability: 2, battleground: 0, country: 'East Germany', box: {x: 58, y: 185, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [5, , , , ]},
-{name: 'Walter Ulbricht Academy', name_unique: 'Walter Ulbricht Academy', space_id: 5, socio: 6, stability: 1, battleground: 0, country: 'East Germany', box: {x: 175, y: 187, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [3, 4, , , ]},
-{name: 'Lutherian Church', name_unique: 'Lutherian Church', space_id: 6, socio: 7, stability: 5, battleground: 1, country: 'East Germany', box: {x: 300, y: 212, h: 65, w: 105}, demInfl: 1, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [9, , , , ]},
-{name: 'Magdeburg', name_unique: 'Magdeburg', space_id: 7, socio: 4, stability: 3, battleground: 1, country: 'East Germany', box: {x: 58, y: 275, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [8, 10, 11, , ]},
-{name: 'Halle', name_unique: 'Halle', space_id: 8, socio: 4, stability: 3, battleground: 0, country: 'East Germany', box: {x: 175, y: 278, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [7, 10, 11, , ]},
-{name: 'Leipzig', name_unique: 'Leipzig', space_id: 9, socio: 4, stability: 3, battleground: 1, country: 'East Germany', box: {x: 297, y: 297, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [3, 6, 8, 11, 12]},
-{name: 'Erfurt', name_unique: 'Erfurt', space_id: 10, socio: 3, stability: 4, battleground: 0, country: 'East Germany', box: {x: 23, y: 356, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [7, , , , ]},
-{name: 'Karl-Marx-Stadt', name_unique: 'Karl-Marx-Stadt', space_id: 11, socio: 4, stability: 3, battleground: 1, country: 'East Germany', box: {x: 138, y: 385, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [7, 8, 9, 12, ]},
-{name: 'Dresden', name_unique: 'Dresden', space_id: 12, socio: 1, stability: 4, battleground: 1, country: 'East Germany', box: {x: 262, y: 375, h: 65, w: 105}, demInfl: 0, comInfl: 2, demCtrl: 0, comCtrl: 0, adjacent: [9, 11, 19, 27, ]},
-{name: 'Szczecin', name_unique: 'Szczecin', space_id: 13, socio: 4, stability: 3, battleground: 0, country: 'Poland', box: {x: 434, y: 204, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [14, 16, , , ]},
-{name: 'Gdansk', name_unique: 'Gdansk', space_id: 14, socio: 4, stability: 3, battleground: 1, country: 'Poland', box: {x: 699, y: 215, h: 65, w: 105}, demInfl: 1, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [13, 15, 16, 17, 18]},
-{name: 'Bydgoszcz', name_unique: 'Bydgoszcz', space_id: 15, socio: 1, stability: 4, battleground: 0, country: 'Poland', box: {x: 679, y: 304, h: 65, w: 105}, demInfl: 0, comInfl: 1, demCtrl: 0, comCtrl: 0, adjacent: [15, 17, , , ]},
-{name: 'Poznan', name_unique: 'Poznan', space_id: 16, socio: 4, stability: 3, battleground: 1, country: 'Poland', box: {x: 521, y: 355, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [13, 14, 19, 20, ]},
-{name: 'Warszawa', name_unique: 'Warszawa', space_id: 17, socio: 2, stability: 3, battleground: 1, country: 'Poland', box: {x: 806, y: 383, h: 65, w: 105}, demInfl: 0, comInfl: 1, demCtrl: 0, comCtrl: 0, adjacent: [14, 15, 18, 21, 24]},
-{name: 'Bialystok', name_unique: 'Bialystok', space_id: 18, socio: 3, stability: 4, battleground: 0, country: 'Poland', box: {x: 940, y: 342, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [14, 17, 24, , ]},
-{name: 'Wroclaw', name_unique: 'Wroclaw', space_id: 19, socio: 4, stability: 3, battleground: 1, country: 'Poland', box: {x: 462, y: 443, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [12, 16, 20, 22, ]},
-{name: 'Catholic Church', name_unique: 'Catholic Church Poland', space_id: 20, socio: 7, stability: 5, battleground: 0, country: 'Poland', box: {x: 625, y: 437, h: 65, w: 105}, demInfl: 5, comInfl: 0, demCtrl: 1, comCtrl: 0, adjacent: [16, 19, 21, 22, 23]},
-{name: 'Lodz', name_unique: 'Lodz', space_id: 21, socio: 4, stability: 3, battleground: 1, country: 'Poland', box: {x: 749, y: 486, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [17, 20, 23, 24, ]},
-{name: 'Katowice', name_unique: 'Katowice', space_id: 22, socio: 4, stability: 3, battleground: 0, country: 'Poland', box: {x: 570, y: 569, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [19, 20, 21, 33, ]},
-{name: 'Krakow', name_unique: 'Krakow', space_id: 23, socio: 4, stability: 3, battleground: 1, country: 'Poland', box: {x: 711, y: 598, h: 65, w: 105}, demInfl: 1, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [20, 21, 23, 25, ]},
-{name: 'Lublin', name_unique: 'Lublin', space_id: 24, socio: 3, stability: 4, battleground: 0, country: 'Poland', box: {x: 879, y: 603, h: 65, w: 105}, demInfl: 0, comInfl: 1, demCtrl: 0, comCtrl: 0, adjacent: [17, 18, 21, , ]},
-{name: 'Jagiellian University', name_unique: 'Jagiellian University', space_id: 25, socio: 6, stability: 1, battleground: 0, country: 'Poland', box: {x: 679, y: 681, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [23, 26, , , ]},
-{name: 'Polish Writers', name_unique: 'Polish Writers', space_id: 26, socio: 5, stability: 2, battleground: 0, country: 'Poland', box: {x: 832, y: 694, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [25, , , , ]},
-{name: 'Plzen', name_unique: 'Plzen', space_id: 27, socio: 1, stability: 4, battleground: 0, country: 'Czechoslovakia', box: {x: 159, y: 483, h: 65, w: 105}, demInfl: 0, comInfl: 2, demCtrl: 0, comCtrl: 0, adjacent: [12, 29, , , ]},
-{name: 'Ceske Budejovice', name_unique: 'Ceske Budejovice', space_id: 28, socio: 3, stability: 3, battleground: 0, country: 'Czechoslovakia', box: {x: 196, y: 601, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [28, 29, , , ]},
-{name: 'Praha', name_unique: 'Praha', space_id: 29, socio: 2, stability: 3, battleground: 1, country: 'Czechoslovakia', box: {x: 317, y: 614, h: 65, w: 105}, demInfl: 0, comInfl: 2, demCtrl: 0, comCtrl: 0, adjacent: [27, 28, 30, 32, ]},
-{name: 'Charles University', name_unique: 'Charles University', space_id: 30, socio: 6, stability: 1, battleground: 1, country: 'Czechoslovakia', box: {x: 380, y: 532, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [29, 31, , , ]},
-{name: 'Czech Writers', name_unique: 'Czech Writers', space_id: 31, socio: 5, stability: 2, battleground: 1, country: 'Czechoslovakia', box: {x: 444, y: 607, h: 65, w: 105}, demInfl: 2, comInfl: 0, demCtrl: 1, comCtrl: 0, adjacent: [30, , , , ]},
-{name: 'Brno', name_unique: 'Brno', space_id: 32, socio: 4, stability: 3, battleground: 1, country: 'Czechoslovakia', box: {x: 403, y: 711, h: 65, w: 105}, demInfl: 0, comInfl: 1, demCtrl: 0, comCtrl: 0, adjacent: [29, 33, 34, , ]},
-{name: 'Ostrava', name_unique: 'Ostrava', space_id: 33, socio: 4, stability: 3, battleground: 1, country: 'Czechoslovakia', box: {x: 523, y: 681, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [22, 32, 34, 35, ]},
-{name: 'Bratislava', name_unique: 'Bratislava', space_id: 34, socio: 4, stability: 3, battleground: 1, country: 'Czechoslovakia', box: {x: 417, y: 797, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [32, 33, 35, , ]},
-{name: 'Catholic Church', name_unique: 'Catholic Church Czech', space_id: 35, socio: 7, stability: 5, battleground: 0, country: 'Czechoslovakia', box: {x: 538, y: 794, h: 65, w: 105}, demInfl: 1, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [33, 34, 36, , ]},
-{name: 'Presov', name_unique: 'Presov', space_id: 36, socio: 3, stability: 4, battleground: 0, country: 'Czechoslovakia', box: {x: 658, y: 794, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [35, 37, , , ]},
-{name: 'Kosice', name_unique: 'Kosice', space_id: 37, socio: 3, stability: 4, battleground: 0, country: 'Czechoslovakia', box: {x: 777, y: 815, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [36, 42, , , ]},
-{name: 'Catholic Church', name_unique: 'Catholic Church Hungary', space_id: 38, socio: 7, stability: 5, battleground: 0, country: 'Hungary', box: {x: 314, y: 886, h: 65, w: 105}, demInfl: 1, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [39, 43, , , ]},
-{name: 'Gyor', name_unique: 'Gyor', space_id: 39, socio: 4, stability: 3, battleground: 0, country: 'Hungary', box: {x: 434, y: 887, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [38, 40, 43, 44, ]},
-{name: 'Tatabanya', name_unique: 'Tatabanya', space_id: 40, socio: 4, stability: 3, battleground: 0, country: 'Hungary', box: {x: 549, y: 886, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [39, 41, 45, , ]},
-{name: 'Miskolc', name_unique: 'Miskolc', space_id: 41, socio: 4, stability: 3, battleground: 1, country: 'Hungary', box: {x: 664, y: 901, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [40, 42, 45, , ]},
-{name: 'Debrecen', name_unique: 'Debrecen', space_id: 42, socio: 4, stability: 3, battleground: 1, country: 'Hungary', box: {x: 781, y: 938, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [37, 41, , , ]},
-{name: 'Szombathely', name_unique: 'Szombathely', space_id: 43, socio: 1, stability: 4, battleground: 0, country: 'Hungary', box: {x: 316, y: 963, h: 65, w: 105}, demInfl: 0, comInfl: 1, demCtrl: 0, comCtrl: 0, adjacent: [38, 39, 44, , ]},
-{name: 'Szekesfehervar', name_unique: 'Szekesfehervar', space_id: 44, socio: 4, stability: 3, battleground: 0, country: 'Hungary', box: {x: 442, y: 962, h: 65, w: 105}, demInfl: 1, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [39, 43, 45, , ]},
-{name: 'Budapest', name_unique: 'Budapest', space_id: 45, socio: 2, stability: 3, battleground: 1, country: 'Hungary', box: {x: 630, y: 983, h: 65, w: 105}, demInfl: 1, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [41, 42, 44, 47, 48]},
-{name: 'Hungarian Writers', name_unique: 'Hungarian Writers', space_id: 46, socio: 5, stability: 2, battleground: 0, country: 'Hungary', box: {x: 348, y: 1040, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [47, , , , ]},
-{name: 'Eotvos Lorand University', name_unique: 'Eotvos Lorand University', space_id: 47, socio: 6, stability: 1, battleground: 0, country: 'Hungary', box: {x: 512, y: 1034, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [46, 45, , , ]},
-{name: 'Szeged', name_unique: 'Szeged', space_id: 48, socio: 3, stability: 4, battleground: 1, country: 'Hungary', box: {x: 632, y: 1073, h: 65, w: 105}, demInfl: 1, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [45, 49, 50, , ]},
-{name: 'Pecs', name_unique: 'Pecs', space_id: 49, socio: 3, stability: 4, battleground: 1, country: 'Hungary', box: {x: 486, y: 1105, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [48, , , , ]},
-{name: 'Timisoara', name_unique: 'Timisoara', space_id: 50, socio: 4, stability: 3, battleground: 1, country: 'Romania', box: {x: 597, y: 1204, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [48, 51, 60, , ]},
-{name: 'Cluj-Napoca', name_unique: 'Cluj-Napoca', space_id: 51, socio: 1, stability: 4, battleground: 1, country: 'Romania', box: {x: 756, y: 1125, h: 65, w: 105}, demInfl: 0, comInfl: 2, demCtrl: 0, comCtrl: 0, adjacent: [50, 54, 58, , ]},
-{name: 'Targu Mures', name_unique: 'Targu Mures', space_id: 52, socio: 3, stability: 4, battleground: 0, country: 'Romania', box: {x: 915, y: 1136, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [53, 56, , , ]},
-{name: 'Iasi', name_unique: 'Iasi', space_id: 53, socio: 4, stability: 3, battleground: 1, country: 'Romania', box: {x: 1072, y: 1097, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [52, 57, 62, , ]},
-{name: 'Babes-Bolyai University', name_unique: 'Babes-Bolyai University', space_id: 54, socio: 6, stability: 1, battleground: 0, country: 'Romania', box: {x: 746, y: 1203, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [51, 55, , , ]},
-{name: 'Romanian Writers', name_unique: 'Romanian Writers', space_id: 55, socio: 5, stability: 2, battleground: 0, country: 'Romania', box: {x: 739, y: 1278, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [54, , , , ]},
-{name: 'Hargita/Covasna', name_unique: 'Hargita/Covasna', space_id: 56, socio: 8, stability: 4, battleground: 0, country: 'Romania', box: {x: 928, y: 1227, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [52, , , , ]},
-{name: 'Brasov', name_unique: 'Brasov', space_id: 57, socio: 4, stability: 3, battleground: 1, country: 'Romania', box: {x: 1049, y: 1225, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [53, 59, 61, , ]},
-{name: 'Orthodox Church', name_unique: 'Orthodox Church Romania', space_id: 58, socio: 7, stability: 3, battleground: 0, country: 'Romania', box: {x: 855, y: 1338, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [51, 60, , , ]},
-{name: 'Ploiesti', name_unique: 'Ploiesti', space_id: 59, socio: 4, stability: 3, battleground: 0, country: 'Romania', box: {x: 1061, y: 1316, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [57, 61, 62, , ]},
-{name: 'Craiova', name_unique: 'Craiova', space_id: 60, socio: 3, stability: 4, battleground: 0, country: 'Romania', box: {x: 763, y: 1411, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [50, 58, 61, , ]},
-{name: 'Bucuresti', name_unique: 'Bucuresti', space_id: 61, socio: 2, stability: 3, battleground: 1, country: 'Romania', box: {x: 929, y: 1445, h: 65, w: 105}, demInfl: 0, comInfl: 2, demCtrl: 0, comCtrl: 0, adjacent: [51, 57, 59, 60, 63]},
-{name: 'Galatii', name_unique: 'Galatii', space_id: 62, socio: 4, stability: 3, battleground: 1, country: 'Romania', box: {x: 1104, y: 1399, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [53, 59, 63, , ]},
-{name: 'Constanta', name_unique: 'Constanta', space_id: 63, socio: 4, stability: 3, battleground: 0, country: 'Romania', box: {x: 1130, y: 1517, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [61, 62, 72, , ]},
-{name: 'Pleven', name_unique: 'Pleven', space_id: 64, socio: 3, stability: 4, battleground: 0, country: 'Bulgaria', box: {x: 764, y: 1534, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [67, , , , ]},
-{name: 'Orthodox Church', name_unique: 'Orthodox Church Bulgaria', space_id: 65, socio: 7, stability: 3, battleground: 0, country: 'Bulgaria', box: {x: 882, y: 1540, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [66, 68, , , ]},
-{name: 'Ruse', name_unique: 'Ruse', space_id: 66, socio: 4, stability: 3, battleground: 1, country: 'Bulgaria', box: {x: 998, y: 1540, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [65, 69, 70, 71, 72]},
-{name: 'Sofia University', name_unique: 'Sofia University', space_id: 67, socio: 6, stability: 1, battleground: 0, country: 'Bulgaria', box: {x: 645, y: 1650, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [68, 73, , , ]},
-{name: 'Sofia', name_unique: 'Sofia', space_id: 68, socio: 2, stability: 3, battleground: 1, country: 'Bulgaria', box: {x: 768, y: 1653, h: 65, w: 105}, demInfl: 0, comInfl: 2, demCtrl: 0, comCtrl: 0, adjacent: [64, 65, 67, 69, 74]},
-{name: 'Stara Zagora', name_unique: 'Stara Zagora', space_id: 69, socio: 1, stability: 4, battleground: 0, country: 'Bulgaria', box: {x: 886, y: 1694, h: 65, w: 105}, demInfl: 0, comInfl: 1, demCtrl: 0, comCtrl: 0, adjacent: [66, 68, 71, , ]},
-{name: 'Razgrad', name_unique: 'Razgrad', space_id: 70, socio: 8, stability: 4, battleground: 0, country: 'Bulgaria', box: {x: 954, y: 1620, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [66, , , , ]},
-{name: 'Burgas', name_unique: 'Burgas', space_id: 71, socio: 4, stability: 3, battleground: 1, country: 'Bulgaria', box: {x: 1004, y: 1695, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [66, 69, 72, , ]},
-{name: 'Varna', name_unique: 'Varna', space_id: 72, socio: 4, stability: 3, battleground: 1, country: 'Bulgaria', box: {x: 1086, y: 1613, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [63, 66, 71, , ]},
-{name: 'Bulgarian Writers', name_unique: 'Bulgarian Writers', space_id: 73, socio: 5, stability: 2, battleground: 0, country: 'Bulgaria', box: {x: 652, y: 1726, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [67, , , , ]},
-{name: 'Plovdiv', name_unique: 'Plovdiv', space_id: 74, socio: 4, stability: 3, battleground: 1, country: 'Bulgaria', box: {x: 771, y: 1739, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [68, 75, , , ]},
-{name: 'Sliven', name_unique: 'Sliven', space_id: 75, socio: 3, stability: 4, battleground: 0, country: 'Bulgaria', box: {x: 894, y: 1768, h: 65, w: 105}, demInfl: 0, comInfl: 0, demCtrl: 0, comCtrl: 0, adjacent: [75, , , , ]},
- ]
-
-const cards = [
- null,
- {number: 1, period: 1, side: 'C', name: 'Legacy of Martial Law*', ops: 2, remove: 1, playable: 1},
- {number: 2, period: 1, side: 'D', name: 'Solidarity Legalized*', ops: 4, remove: 1, playable: 1},
- {number: 3, period: 1, side: 'D', name: 'Walesa*', ops: 3, remove: 1, playable: 0},
- {number: 4, period: 1, side: 'D', name: 'Michnik*', ops: 1, remove: 1, playable: 1},
- {number: 5, period: 1, side: 'D', name: 'General Strike', ops: 3, remove: 0, playable: 1},
- {number: 6, period: 1, side: 'C', name: 'Brought in for Questioning', ops: 3, remove: 0, playable: 1},
- {number: 7, period: 1, side: 'C', name: 'State Run Media*', ops: 2, remove: 1, playable: 1},
- {number: 8, period: 3, side: 'C', name: 'The Chinese Solution*', ops: 1, remove: 1, playable: 1},
- {number: 9, period: 1, side: 'C', name: 'The Wall*', ops: 1, remove: 1, playable: 1},
- {number: 10, period: 1, side: 'C', name: 'Cult of Personality*', ops: 3, remove: 1, playable: 1},
- {number: 11, period: 1, side: 'C', name: 'Dissident Arrested', ops: 2, remove: 0, playable: 1},
- {number: 12, period: 1, side: 'C', name: 'Apparatchiks*', ops: 2, remove: 1, playable: 1},
- {number: 13, period: 1, side: 'C', name: 'Stasi*', ops: 1, remove: 1, playable: 1},
- {number: 14, period: 2, side: 'C', name: 'Ceausescu*', ops: 3, remove: 1, playable: 1},
- {number: 15, period: 1, side: 'C', name: 'Honecker*', ops: 3, remove: 1, playable: 1},
- {number: 16, period: 1, side: 'C', name: 'Nomenklatura*', ops: 2, remove: 1, playable: 1},
- {number: 17, period: 2, side: 'N', name: 'Power Struggle - East Germany', ops: 0, remove: 0, playable: 1},
- {number: 18, period: 2, side: 'N', name: 'Power Struggle - Czechoslovakia', ops: 0, remove: 0, playable: 1},
- {number: 19, period: 2, side: 'N', name: 'Power Struggle - Bulgaria', ops: 0, remove: 0, playable: 1},
- {number: 20, period: 2, side: 'N', name: 'Workers Revolt', ops: 2, remove: 0, playable: 1},
- {number: 21, period: 3, side: 'N', name: 'Power Struggle - Romania', ops: 0, remove: 0, playable: 1},
- {number: 22, period: 1, side: 'N', name: 'Power Struggle - Poland', ops: 0, remove: 0, playable: 1},
- {number: 23, period: 1, side: 'N', name: 'Power Struggle - Hungary', ops: 0, remove: 0, playable: 1},
- {number: 24, period: 3, side: 'C', name: 'Betrayal*', ops: 3, remove: 1, playable: 1},
- {number: 25, period: 2, side: 'D', name: 'Genscher*', ops: 2, remove: 1, playable: 1},
- {number: 26, period: 2, side: 'C', name: 'Securitate*', ops: 2, remove: 1, playable: 1},
- {number: 27, period: 1, side: 'D', name: 'Consumerism', ops: 3, remove: 0, playable: 1},
- {number: 28, period: 1, side: 'C', name: 'Factory Party Cells', ops: 3, remove: 0, playable: 1},
- {number: 29, period: 1, side: 'D', name: 'Jan Palach Week*', ops: 1, remove: 1, playable: 1},
- {number: 30, period: 1, side: 'C', name: 'Tear Gas*', ops: 1, remove: 1, playable: 1},
- {number: 31, period: 1, side: 'D', name: 'Intelligentsia', ops: 2, remove: 0, playable: 1},
- {number: 32, period: 1, side: 'C', name: 'Peasant Parties*', ops: 2, remove: 1, playable: 1},
- {number: 33, period: 2, side: 'D', name: 'Legacy of 1968*', ops: 4, remove: 1, playable: 1},
- {number: 34, period: 1, side: 'D', name: 'Fidesz*', ops: 2, remove: 1, playable: 1},
- {number: 35, period: 2, side: 'C', name: 'Systematization*', ops: 3, remove: 1, playable: 1},
- {number: 36, period: 3, side: 'D', name: 'Public Against Violence*', ops: 3, remove: 1, playable: 1},
- {number: 37, period: 1, side: 'C', name: 'Nagy Reburied*', ops: 3, remove: 1, playable: 1},
- {number: 38, period: 1, side: 'D', name: 'Roundtable Talks', ops: 3, remove: 0, playable: 1},
- {number: 39, period: 2, side: 'D', name: 'Toxic Waste*', ops: 2, remove: 1, playable: 1},
- {number: 40, period: 3, side: 'C', name: 'Adamec*', ops: 2, remove: 1, playable: 1},
- {number: 41, period: 3, side: 'D', name: 'My First Banana*', ops: 3, remove: 1, playable: 1},
- {number: 42, period: 1, side: 'D', name: 'St. Nicholas Church*', ops: 1, remove: 1, playable: 1},
- {number: 43, period: 3, side: 'N', name: 'Tank Column/Tank Man*', ops: 2, remove: 1, playable: 1},
- {number: 44, period: 2, side: 'N', name: 'Inflationary Currency*', ops: 3, remove: 1, playable: 1},
- {number: 45, period: 2, side: 'D', name: 'Soviet Troop Withdrawals*', ops: 4, remove: 1, playable: 1},
- {number: 46, period: 2, side: 'D', name: 'Goodbye Lenin!*', ops: 3, remove: 1, playable: 1},
- {number: 47, period: 2, side: 'C', name: 'Bulgarian Turks expelled*', ops: 3, remove: 1, playable: 1},
- {number: 48, period: 3, side: 'D', name: 'Shock Therapy*', ops: 3, remove: 1, playable: 1},
- {number: 49, period: 3, side: 'N', name: 'Stand Fast*', ops: 3, remove: 1, playable: 1},
- {number: 50, period: 2, side: 'D', name: 'This Sinatra Doctrine*', ops: 3, remove: 1, playable: 1},
- {number: 51, period: 2, side: 'C', name: '40th Anniversary Celebration*', ops: 2, remove: 1, playable: 1},
- {number: 52, period: 2, side: 'C', name: 'Normalization*', ops: 3, remove: 1, playable: 1},
- {number: 53, period: 2, side: 'C', name: 'Li Peng*', ops: 2, remove: 1, playable: 1},
- {number: 54, period: 2, side: 'D', name: 'The Crowd Turns Against Ceausescu*', ops: 3, remove: 1, playable: 1},
- {number: 55, period: 1, side: 'C', name: 'Perestroika*', ops: 3, remove: 1, playable: 1},
- {number: 56, period: 2, side: 'D', name: 'Foreign Television*', ops: 2, remove: 1, playable: 1},
- {number: 57, period: 2, side: 'C', name: 'Central Committee Reshuffle*', ops: 2, remove: 1, playable: 1},
- {number: 58, period: 2, side: 'D', name: 'Austria-Hungary Border Reopened*', ops: 2, remove: 1, playable: 1},
- {number: 59, period: 3, side: 'C', name: 'Massacre in Timisoara*', ops: 3, remove: 1, playable: 0},
- {number: 60, period: 1, side: 'D', name: 'Hungarian Democratic Forum*', ops: 3, remove: 1, playable: 1},
- {number: 61, period: 2, side: 'D', name: 'The Monday Demonstrations*', ops: 4, remove: 1, playable: 0},
- {number: 62, period: 1, side: 'N', name: 'Prudence', ops: 4, remove: 0, playable: 1},
- {number: 63, period: 3, side: 'D', name: 'Army Backs Revolution*', ops: 3, remove: 1, playable: 1},
- {number: 64, period: 1, side: 'D', name: 'Papal Visit*', ops: 2, remove: 1, playable: 1},
- {number: 65, period: 3, side: 'C', name: 'Politburo Intrigue*', ops: 2, remove: 1, playable: 1},
- {number: 66, period: 3, side: 'D', name: 'Civic Forum*', ops: 4, remove: 1, playable: 1},
- {number: 67, period: 2, side: 'N', name: 'Reformer Rehabilitated*', ops: 2, remove: 1, playable: 1},
- {number: 68, period: 2, side: 'D', name: 'Klaus and Komarek*', ops: 3, remove: 1, playable: 1},
- {number: 69, period: 3, side: 'C', name: 'New Year\'s Eve Party*', ops: 2, remove: 1, playable: 1},
- {number: 70, period: 3, side: 'D', name: 'Government Resigns*', ops: 3, remove: 1, playable: 1},
- {number: 71, period: 2, side: 'D', name: 'Kiss of Death*', ops: 3, remove: 1, playable: 1},
- {number: 72, period: 2, side: 'D', name: 'Peasant Parties Revolt*', ops: 3, remove: 1, playable: 1},
- {number: 73, period: 1, side: 'C', name: 'Poszgay Defends the Revolution*', ops: 2, remove: 1, playable: 1},
- {number: 74, period: 2, side: 'D', name: 'FRG Embassies*', ops: 3, remove: 1, playable: 1},
- {number: 75, period: 2, side: 'D', name: 'Exit Visas*', ops: 3, remove: 1, playable: 1},
- {number: 76, period: 2, side: 'C', name: 'Warsaw Pact Summit*', ops: 2, remove: 1, playable: 1},
- {number: 77, period: 3, side: 'C', name: 'Social Democratic Platform Adopted*', ops: 2, remove: 1, playable: 1},
- {number: 78, period: 1, side: 'N', name: 'Gorbachev Charms the West', ops: 4, remove: 0, playable: 1},
- {number: 79, period: 2, side: 'C', name: 'The Third Way*', ops: 2, remove: 1, playable: 1},
- {number: 80, period: 3, side: 'D', name: 'Domino Theory*', ops: 3, remove: 1, playable: 1},
- {number: 81, period: 3, side: 'C', name: 'Modrow*', ops: 2, remove: 1, playable: 1},
- {number: 82, period: 3, side: 'C', name: 'Spitzel*', ops: 1, remove: 1, playable: 1},
- {number: 83, period: 2, side: 'D', name: 'The Baltic Way*', ops: 3, remove: 1, playable: 0},
- {number: 84, period: 3, side: 'D', name: 'Breakaway Baltic Republics*', ops: 4, remove: 1, playable: 0},
- {number: 85, period: 1, side: 'N', name: 'Common European Home', ops: 2, remove: 0, playable: 1},
- {number: 86, period: 3, side: 'D', name: '\"The Wall Must Go!*\"', ops: 3, remove: 0, playable: 1},
- {number: 87, period: 3, side: 'D', name: 'Kohl Proposes Reunification*', ops: 3, remove: 1, playable: 1},
- {number: 88, period: 1, side: 'D', name: 'Sajudis*', ops: 2, remove: 1, playable: 1},
- {number: 89, period: 1, side: 'D', name: 'Eco-Glasnost*', ops: 2, remove: 1, playable: 1},
- {number: 90, period: 2, side: 'C', name: 'GrenzTruppen*', ops: 2, remove: 1, playable: 1},
- {number: 91, period: 1, side: 'D', name: 'Dash for the West*', ops: 3, remove: 1, playable: 1},
- {number: 92, period: 1, side: 'C', name: 'Deutsche Marks*', ops: 4, remove: 1, playable: 1},
- {number: 93, period: 2, side: 'D', name: 'New Forum*', ops: 1, remove: 1, playable: 1},
- {number: 94, period: 3, side: 'D', name: 'Union of Democratic Forces*', ops: 4, remove: 1, playable: 1},
- {number: 95, period: 1, side: 'C', name: 'The July Concept*', ops: 3, remove: 1, playable: 1},
- {number: 96, period: 1, side: 'D', name: 'Helsinki Final Act*', ops: 1, remove: 1, playable: 1},
- {number: 97, period: 3, side: 'D', name: 'The Tyrant is Gone*', ops: 2, remove: 1, playable: 0},
- {number: 98, period: 2, side: 'D', name: 'Laszlo Tokes*', ops: 2, remove: 1, playable: 1},
- {number: 99, period: 3, side: 'C', name: 'Ligachev*', ops: 3, remove: 1, playable: 1},
- {number: 100, period: 2, side: 'D', name: 'Yakovlev Counsels Gorbachev*', ops: 2, remove: 1, playable: 1},
- {number: 101, period: 3, side: 'C', name: 'Elena*', ops: 1, remove: 1, playable: 1},
- {number: 102, period: 3, side: 'C', name: 'National Salvation Front*', ops: 3, remove: 1, playable: 1},
- {number: 103, period: 2, side: 'C', name: 'Nepotism*', ops: 3, remove: 1, playable: 1},
- {number: 104, period: 2, side: 'D', name: 'Presidential Visit*', ops: 3, remove: 1, playable: 1},
- {number: 105, period: 2, side: 'D', name: 'Samizdat*', ops: 3, remove: 1, playable: 1},
- {number: 106, period: 2, side: 'D', name: '\"We are the People!\"', ops: 3, remove: 0, playable: 1},
- {number: 107, period: 2, side: 'D', name: 'Foreign Currency Debt Burden', ops: 1, remove: 0, playable: 1},
- {number: 108, period: 1, side: 'C', name: 'Heal Our Bleeding Wound', ops: 3, remove: 0, playable: 1},
- {number: 109, period: 3, side: 'C', name: 'Kremlin Coup!*', ops: 3, remove: 1, playable: 0},
- {number: 110, period: 3, side: 'D', name: 'Malta Summit*', ops: 3, remove: 1, playable: 1},
- ]
-
-const power_cards = [
-null,
-{number: 1, name: 'Strike', value: 6, socio: 0, url: 'ps2'},
-{number: 2, name: 'Strike', value: 6, socio: 0, url: 'ps2'},
-{number: 3, name: 'Strike', value: 5, socio: 0, url: 'ps3'},
-{number: 4, name: 'Strike', value: 5, socio: 0, url: 'ps3'},
-{number: 5, name: 'Strike', value: 4, socio: 0, url: 'ps4'},
-{number: 6, name: 'Strike', value: 4, socio: 0, url: 'ps4'},
-{number: 7, name: 'Strike', value: 4, socio: 0, url: 'ps4'},
-{number: 8, name: 'Strike', value: 4, socio: 0, url: 'ps4'},
-{number: 9, name: 'Strike', value: 3, socio: 0, url: 'ps5'},
-{number: 10, name: 'Strike', value: 3, socio: 0, url: 'ps5'},
-{number: 11, name: 'Strike', value: 3, socio: 0, url: 'ps5'},
-{number: 12, name: 'Strike', value: 3, socio: 0, url: 'ps5'},
-{number: 13, name: 'March', value: 6, socio: 0, url: 'ps6'},
-{number: 14, name: 'March', value: 6, socio: 0, url: 'ps6'},
-{number: 15, name: 'March', value: 5, socio: 0, url: 'ps7'},
-{number: 16, name: 'March', value: 5, socio: 0, url: 'ps7'},
-{number: 17, name: 'March', value: 4, socio: 0, url: 'ps8'},
-{number: 18, name: 'March', value: 4, socio: 0, url: 'ps8'},
-{number: 19, name: 'March', value: 4, socio: 0, url: 'ps8'},
-{number: 20, name: 'March', value: 4, socio: 0, url: 'ps8'},
-{number: 21, name: 'March', value: 3, socio: 0, url: 'ps9'},
-{number: 22, name: 'March', value: 3, socio: 0, url: 'ps9'},
-{number: 23, name: 'March', value: 3, socio: 0, url: 'ps9'},
-{number: 24, name: 'March', value: 3, socio: 0, url: 'ps9'},
-{number: 25, name: 'Rally in the Square', value: 1, socio: 0, url: 'ps1'},
-{number: 26, name: 'Rally in the Square', value: 1, socio: 0, url: 'ps1'},
-{number: 27, name: 'Rally in the Square', value: 1, socio: 0, url: 'ps1'},
-{number: 28, name: 'Rally in the Square', value: 1, socio: 0, url: 'ps1'},
-{number: 29, name: 'Rally in the Square', value: 1, socio: 0, url: 'ps1'},
-{number: 30, name: 'Rally in the Square', value: 1, socio: 0, url: 'ps1'},
-{number: 31, name: 'Petition', value: 6, socio: 0, url: 'ps10'},
-{number: 32, name: 'Petition', value: 6, socio: 0, url: 'ps10'},
-{number: 33, name: 'Petition', value: 6, socio: 0, url: 'ps10'},
-{number: 34, name: 'Petition', value: 5, socio: 0, url: 'ps11'},
-{number: 35, name: 'Petition', value: 5, socio: 0, url: 'ps11'},
-{number: 36, name: 'Petition', value: 5, socio: 0, url: 'ps11'},
-{number: 37, name: 'Elite Leader', value: 3, socio: 1, url: 'ps16'},
-{number: 38, name: 'Elite Leader', value: 3, socio: 1, url: 'ps17'},
-{number: 39, name: 'Elite Leader', value: 3, socio: 1, url: 'ps18'},
-{number: 40, name: 'Elite Leader', value: 3, socio: 1, url: 'ps19'},
-{number: 41, name: 'Intellectual Leader', value: 3, socio: 5, url: 'ps12'},
-{number: 42, name: 'Intellectual Leader', value: 3, socio: 5, url: 'ps13'},
-{number: 43, name: 'Intellectual Leader', value: 3, socio: 5, url: 'ps14'},
-{number: 44, name: 'Intellectual Leader', value: 3, socio: 5, url: 'ps15'},
-{number: 45, name: 'Worker Leader', value: 3, socio: 4, url: 'ps20'},
-{number: 46, name: 'Worker Leader', value: 3, socio: 4, url: 'ps21'},
-{number: 47, name: 'Church Leader', value: 3, socio: 7, url: 'ps23'},
-{number: 48, name: 'Student Leader', value: 3, socio: 6, url: 'ps22'},
-{number: 49, name: 'Scare Tactics', value: 0, socio: 0, url: 'ps26'},
-{number: 50, name: 'Support Surges', value: 0, socio: 0, url: 'ps25'},
-{number: 51, name: 'Support Falters', value: 0, socio: 0, url: 'ps24'},
-{number: 52, name: 'Tactic Fails', value: 0, socio: 0, url: 'ps27'},
-{number: 53, name: 'Rally in the Square', value: 3, socio: 0, url: 'ps1'},
-{number: 54, name: 'Petition', value: 3, socio: 0, url: 'ps10'}
-]
+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, 59, 62, 63, 65, 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) {
@@ -285,9 +44,25 @@ exports.setup = function (seed, scenario, options) {
undo: [],
active: null,
state: "com_init",
-
- played_card: [],
+ return: '',
+ vm: null,
+ vm_event: 0,
+ vm_event_to_do: false,
+ vm_infl_to_do: false,
+ vm_active_country: 0,
+ vm_influence_added: {},
+ vm_max_infl: 0,
+
+ played_card: 0,
+ stasi_card: 0,
+ samizdat_card: 0,
+ table_cards: [],
+ austria_hungary_border_reopened: false,
+ austria_hungary_border_reopened_tracker: true,
+ austria_hungary_border_reopened_checked: false,
+ temp: 0,
available_ops: 0,
+ vm_available_ops: 0,
starting_infl: {
com_starting_infl: 0,
dem_starting_infl: 0
@@ -305,20 +80,26 @@ exports.setup = function (seed, scenario, options) {
com_tst_attempted: 0,
dem_tst_attempted_this_turn: 0,
com_tst_attempted_this_turn:0,
+ tst_success: false,
+ tst_7: false,
+ tst_8: false,
vp: 0,
- pieces: [],
+ pieces: [null],
strategy_deck: [],
strategy_discard: [],
+ discard: false,
+ view_opp_hand: false,
strategy_removed: [],
+ persistent_events: {austria_hungary_border_reopened: false, civic_forum: false, eco_glasnost: false, elena: false, foreign_currency_debt_burden: '', frg_embassies: false, general_strike: false, genscher: false, grenztruppen: false, helsinki_final_act: false, honecker: false, li_peng: false, ligachev: false, national_salvation_front: false, perestroika: false, presidential_visit: false, prudence: '', roundtable_talks: false, securitate: false, sinatra_doctrine: false, solidarity_legalised: false, stand_fast: '', stasi: false, st_nicholas_church: false, systematization: 0, tear_gas: false, the_tyrant_is_gone: 0, the_wall: false, the_wall_must_go: false, we_are_the_people: false, yakovlev: false},
power_struggle_deck: [],
power_struggle_discard: [],
dem_hand_limit: 8,
com_hand_limit: 8,
democrat_hand: [],
communist_hand: [],
- democrat_set_aside: [],
+ communist_hand_red: [],
pwr_struggle_in: [],
is_pwr_struggle: false,
@@ -326,19 +107,25 @@ exports.setup = function (seed, scenario, options) {
com_pwr_hand_limit: 0,
dem_pwr_hand: [],
com_pwr_hand: [],
+ ceausescu_cards: [],
raised_stakes_discard: 0,
raised_stakes: 0,
raised_stakes_round: 0,
rally_win: 0,
petition_win: 0,
- respond: 0,
- times_held: {'East Germany': 0, 'Poland': 0, 'Czechoslovakia': 0, 'Hungary': 0, 'Romania': 0, 'Bulgaria': 0},
- revolutions: {'East Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false},
+ phase: 0,
+ times_held: {'East_Germany': 0, 'Poland': 0, 'Czechoslovakia': 0, 'Hungary': 0, 'Romania': 0, 'Bulgaria': 0},
+ revolutions: {'East_Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false},
+ scored_countries: {'East_Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false},
remove_opponent_infl: false,
- tactics_fails: ''
+ tactics_fails: '',
+ warsaw_pact_summit: false,
+ the_wall_must_go: {dem_wins: 0, com_wins: 0, dem_roll: 0, com_roll: 0},
+ tyrant_space: 0
}
log_h1("1989 Dawn of Freedom")
+
game.active = COM
start_game()
@@ -349,10 +136,21 @@ 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()
+ game.playable_cards = cards.map(card => {
+ if (card === null) return null
+ return {
+ number: card.number,
+ playable: card.playable
+ }})
+ //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)
- spaces.forEach(space => {
+ //.log('game.strategy_deck: ', game.strategy_deck[1], 'democrat_hand:', game.democrat_hand)
+ spaces.forEach((space, index) => {
+ if(index === 0 ) return
game.pieces.push({
name_unique: space.name_unique,
space_id: space.space_id,
@@ -360,12 +158,13 @@ function start_game() {
comInfl: space.comInfl,
demCtrl: space.demCtrl,
comCtrl: space.comCtrl,
- stability: space.stability
+ stability: space.stability,
+ adjacent: space.adjacent
});
});
- game.valid_spaces = valid_spaces();
- //Communist starts by placing 2 influence
+ game.valid_spaces = valid_spaces_setup()
game.available_ops = 2
+ game.phase = 0
log_h1("Place starting influence")
log_side()
}
@@ -381,7 +180,7 @@ exports.view = function(state, player) {
actions: null,
played_card: game.played_card,
- selected_space: game.selected_space,
+ table_cards: game.table_cards,
valid_spaces: game.valid_spaces,
valid_cards: game.valid_cards,
@@ -393,13 +192,18 @@ exports.view = function(state, player) {
stability: game.stability,
dem_tst: game.dem_tst_position,
com_tst: game.com_tst_position,
-
+ persistent_events: game.persistent_events,
strategy_deck: game.strategy_deck.length,
strategy_discard: game.strategy_discard,
+ 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,
@@ -415,19 +219,31 @@ exports.view = function(state, player) {
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
- view.set_aside = game.democrat_set_aside
- view.power_hand = game.dem_pwr_hand
+ 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.power_hand = game.com_pwr_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.state === "game_over") {
@@ -440,7 +256,7 @@ exports.view = function(state, player) {
else
view.prompt = `Waiting for ${game.active} to ${inactive}`
} else {
- view.prompt = "Unknown state: " + game.state
+ view.prompt = "A Unknown state: " + game.state
}
} else {
view.actions = {}
@@ -448,7 +264,7 @@ exports.view = function(state, player) {
if (states[game.state])
states[game.state].prompt(player)
else
- view.prompt = "Unknown state: " + game.state
+ view.prompt = "B Unknown state: " + game.state
if (view.actions.undo === undefined) {
if (game.undo && game.undo.length > 0)
view.actions.undo = 1
@@ -472,6 +288,7 @@ function gen_action(action, 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){
@@ -491,6 +308,7 @@ function 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)
@@ -512,13 +330,14 @@ states.com_init = {
view.prompt = 'Place starting influence: done.';
gen_action("done");
return;
+ } else if (game.starting_infl.dem_starting_infl === 2) {
+ view.prompt = `Place your last ${game.available_ops} starting influence.`
+ } else {
+ view.prompt = `Place ${game.available_ops} starting influence.`
}
- view.prompt = `Place ${game.available_ops} starting influence`
-
for (let space_id of game.valid_spaces) {
- const space = spaces.find(s => s.space_id === space_id);
- if (space) {
- gen_action_infl(space.name_unique);
+ if (space_id) {
+ gen_action_infl(spaces[space_id].name_unique);
}
}
},
@@ -528,41 +347,38 @@ states.com_init = {
},
done() {
- view.prompt='Influence added'
+ view.prompt='Influence added.'
game.starting_infl.com_starting_infl++
if (game.starting_infl.com_starting_infl == 1){
game.available_ops = 3
game.state = 'dem_init'
- valid_spaces()
+ valid_spaces_setup()
next_player()
} else if (game.starting_infl.com_starting_infl == 2) {
game.available_ops = 4
game.state = 'dem_init'
- valid_spaces()
+ valid_spaces_setup()
next_player()
} else if (game.starting_infl.com_starting_infl == 3) {
- new_turn()
- clear_undo()
- game.state = 'choose_card'
+ game.state = 'start_game'
}
}
}
states.dem_init = {
- inactive: 'place starting influence',
+ inactive: 'place starting influence.',
prompt() {
if (game.available_ops == 0) {
view.prompt = 'Place starting influence: done.';
gen_action("done");
return;
+ } else if (game.starting_infl.com_starting_infl === 2) {
+ view.prompt = `Place your last ${game.available_ops} starting influence.`
+ } else {
+ view.prompt = `Place ${game.available_ops} starting influence`
}
- view.prompt = `Place ${game.available_ops} starting influence`
-
for (let space_id of game.valid_spaces) {
- const space = spaces.find(s => s.space_id === space_id);
- if (space) {
- gen_action_infl(space.name_unique);
- }
+ gen_action_infl(spaces[space_id].name_unique);
}
},
infl(space) {
@@ -578,11 +394,24 @@ states.dem_init = {
game.available_ops = 2
}
game.state = 'com_init'
- valid_spaces()
+ 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() {
@@ -606,19 +435,46 @@ states.choose_card = {
},
card(card) {
push_undo()
- log(`Played ${cards[card].name}`)
game.played_card = card
let find_card
if (game.active === COM) {
- find_card = game.communist_hand.indexOf(card);
- const [playedCard] = game.communist_hand.splice(find_card, 1);
+ find_card = game.communist_hand.indexOf(card)
+ game.communist_hand.splice(find_card, 1)
} else {
- find_card = game.democrat_hand.indexOf(card);
- const [playedCard] = game.democrat_hand.splice(find_card, 1);
+ find_card = game.democrat_hand.indexOf(card)
+ game.democrat_hand.splice(find_card, 1)
}
- game.strategy_discard.push(card)
game.available_ops = cards[card].ops
-
+
+ //Check events which affect game ops
+ if (game.persistent_events['perestroika'] && game.active === COM) {
+ log('+1 op from C25')
+ game.available_ops ++
+ }
+ if (game.persistent_events['sinatra_doctrine'] && game.active === DEM) {
+ log('+1 op from C50')
+ game.available_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)) {
+ log('+1 op from Tiananmen Square Track')
+ game.available_ops ++
+ }
+
+ if ((game.active === DEM && game.persistent_events['prudence'] === DEM) || (game.active === COM && game.persistent_events['prudence'] === COM)) {
+ if (game.available_ops > 1) {
+ log('-1 op from C8')
+ game.available_ops --
+ }
+ }
+
+ //Check Ligachev
+ if (game.active === DEM && game.persistent_events['ligachev'] && card !== 14) {
+ log('-3 VP from Ligachev')
+ game.vp -= 3
+ check_vp()
+ game.persistent_events['ligachev'] = false
+ }
},
done () {
game.state = 'play_card'
@@ -626,208 +482,633 @@ states.choose_card = {
}
states.play_card ={
- inactive: 'play a card',
+ get inactive() {
+ return `play ${cards[game.played_card].name}.`
+ },
prompt () {
- if (game.is_pwr_struggle) {
- view.prompt = 'Draw cards'
- gen_action('draw')
+ if (game.phase >= 1) {
+ view.prompt = 'Event: done.'
+ gen_action('done')
return
}
+ if (scoring_cards.includes(game.played_card)) {
+ view.prompt = 'Play for:'
+ gen_action('event')
+ return
+ }
view.prompt = 'Play for:'
-
- if (scoring_cards.includes(game.played_card)) {
- gen_action('scoring');
- } else {
- if (cards[game.played_card].playable ===1) {
+
+ //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')
+ }
+
+ // Special check for Reformer Rehabilitated
+ if ((game.active === DEM && game.playable_cards[game.played_card] === 2 && (game.dem_tst_position > game.com_tst_position)) || (game.active === COM && game.playable_cards[game.played_card] === 2 && (game.dem_tst_position < game.com_tst_position))) {
gen_action('event')
- }
- gen_action('influence')
- if (game.active === DEM && game.dem_tst_attempted_this_turn === 0 || game.active === COM && game.com_tst_attempted_this_turn === 0) {
+ }
+
+ //Continue with normal logic
+ 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') {
+ 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.active === COM && game.com_tst_attempted_this_turn === 0) {
gen_action('tst')
}
- gen_action('support_check')
+ gen_action('support_check')
+ },
+ event() {
+ push_undo()
+ log(`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()}
+ goto_vm(game.played_card)
+ },
+ opp_event() {
+ log(`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
+ if (auto_resolve_events.includes(game.played_card) || switch_events.includes(game.played_card)) {
+ goto_vm(game.played_card)}
+ else {
+ next_player()
+ goto_vm(game.played_card)
}
},
- scoring() {
+ influence() {
push_undo()
- if (game.played_card === 17) { game.pwr_struggle_in ="East Germany" }
- if (game.played_card === 18) { game.pwr_struggle_in = "Czechoslovakia" }
- if (game.played_card === 19) { game.pwr_struggle_in = "Bulgaria"}
- if (game.played_card === 21) { game.pwr_struggle_in = "Romania" }
- if (game.played_card === 22) { game.pwr_struggle_in = "Poland" }
- if (game.played_card === 23) { game.pwr_struggle_in = "Hungary" }
- game.is_pwr_struggle = true
+ log(`Played C${cards[game.played_card].number} for influence`)
+
+ // Check if Common European Home played for influence
+ if (game.played_card === 21) {
+ if (game.active === DEM) {
+ game.vp --
+ log('-1 VP')
+ check_vp()
+ } else {
+ game.vp ++
+ log('+1 VP')
+ check_vp()
+ }
+ }
+ // Check if card is opponent card with event that needs to be resolved
+ 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 )) {
+ game.phase = 1 /*Do I need this? */
+ game.vm_event_to_do = true
+ }
+ game.state='add_influence'
+ valid_spaces_infl()
},
- draw() {
+ tst() {
push_undo()
- 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
+ log(`Played C${cards[game.played_card].number} to the Tiananmen Square Track`)
+ game.state='tiananmen_square_attempt'
+ },
+ support_check() {
+ push_undo()
+ log(`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 (presence.com_spaces > 0 ) {
- game.com_pwr_hand_limit = 6 + 2*(presence.com_spaces - 1)
+ 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 ${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 = 'You must resolve the opponent event.'
+ gen_action('event')
} else {
- game.com_pwr_hand_limit = 0
+ view.prompt = 'Event resolved. End the action round.'
+ gen_action('done')
}
- 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
- game.state = 'raise_stakes'
},
- event() {
+ influence(){
push_undo()
- call_event(game.played_card)
+ game.state = 'finish_add_infl'
+ valid_spaces_infl()
},
- influence(influence) {
+ support_check() {
push_undo()
- game.state='add_influence'
- valid_spaces()
+ game.available_ops = 2
+ game.state = 'finish_support_check_prep'
+ valid_spaces_sc()
},
- tst(tst) {
- push_undo()
- game.state='tiananmen_square_attempt'
+ 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
+ goto_vm(game.played_card)}
+ else {
+ if (game.active === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ next_player()
+ goto_vm(game.played_card)
+ }
},
- support_check(space) {
+ tst_7() {
push_undo()
- game.available_ops = 2
- game.state='support_check_prep'
- valid_spaces()
+ 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.add_influence = {
- inactive: 'add influence',
+states.finish_add_infl = {
+ inactive: 'add influence.',
prompt () {
- if (game.available_ops == 0) {
- view.prompt = 'Place influence: done.';
- gen_action("done");
- return;
- }
+ if (game.available_ops === 0) {
+ view.prompt = 'Place influence: done.'
+ gen_action("done")
+ return;
+ }
view.prompt = `Add influence: ${game.available_ops} remaining`
+ // Generate actions for valid spaces
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) {*/
+ gen_action_infl(spaces[space_id].name_unique)
+ //}
+ }
+ },
+ infl(space) {
+ add_infl(space)
+ },
+ done() {
+ 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) {
+ /*const space = spaces.find(s => s && s.space_id === space_id); */
+ if (space_id) {
+ gen_action_sc(spaces[space_id].name_unique)
+ }
+ }
+ },
+ sc(space) {
+ game.selected_space = find_space_index(space)
+ game.state = 'finish_do_support_check'
+ },
+ done () {
+ end_round()
+ }
+}
+
+states.finish_do_support_check = {
+ inactive: 'do support checks',
+ prompt () {
+ view.prompt = `Target: ${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--
+ game.state = 'finish_support_check_prep'
+ return
+ }
+}
+
+states.add_influence = {
+ inactive: 'add influence.',
+ prompt () {
+ if (game.available_ops === 0) {
+ view.prompt = 'Place influence: done.'
+ gen_action("done")
+ return
+ }
+
+ view.prompt = `Add influence: ${game.available_ops} remaining.`
+
// Generate actions for valid spaces
for (let space_id of game.valid_spaces) {
- const space = spaces.find(s => s.space_id === space_id);
- if (space) {
- gen_action_infl(space.name_unique);
- }
+ /* const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) { */
+ gen_action_infl(spaces[space_id].name_unique);
+ //}
}
-
},
infl(space) {
add_infl(space)
- },
+ },
done() {
- view.prompt = 'Influence added'
- end_round()
+ if(game.vm_event_to_do) {
+ game.state = 'resolve_opponent_event'}
+ else {
+ end_round()}
}
}
states.tiananmen_square_attempt = {
- inactive: 'do Tiananmen Square',
+ inactive: 'do Tiananmen Square Attempt.',
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'
+ if ((game.active === DEM && game.dem_tst_attempted_this_turn > 0 )|| (game.active === COM && game.com_tst_attempted_this_turn > 0)) {
+ if (game.tst_success) {
+ view.prompt = 'Tiananmen Square Track attempt successful.'
+ } else {
+ view.prompt = 'Tiananmen Square Track attempt failed.'
+ }
gen_action('done')
return
}
- view.prompt = 'Roll a die'
+ view.prompt = 'Tiananmen Square Track attempt: Roll a die.'
gen_action('roll')
},
- roll(roll) {
- do_tst_attempt ()
+ roll() {
clear_undo()
+ do_tst_attempt ()
},
done () {
- game.available_ops = 0
+ game.tst_success = false
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.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()
+ }
+ game.state = 'choose_card'
+ },
+ done() {
+
+ log_h2("Action Round " + game.round)
+ if (game.active === DEM) {
+ next_player()
+ } else {
+ log_side()
+ }
+ game.phase = 0
+ 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
+ //return
}
- if (game.available_ops > 1) {
- view.prompt = `Select a space. ${game.available_ops} support checks remaining`
- } else {
- view.prompt = ` Select a space. ${game.available_ops} support check remaining`
- }
-
- for (let space_id of game.valid_spaces) {
- const space = spaces.find(s => s.space_id === space_id);
- if (space) {
- gen_action_sc(space.name_unique);
- }
+ 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) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) {*/
+ gen_action_sc(spaces[space_id].name_unique);
+ //}
+ }
}
},
sc(space) {
- game.selected_space = space
- game.state = 'do_support_check'
+ 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.austria_hungary_border_reopened_checked) {
+ game.austria_hungary_border_reopened_checked = true
+ console.log('in ahb check, country, ', spaces[game.selected_space].country, 'ahb', game.persistent_events['austria_hungary_border_reopened'])
+ if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events['austria_hungary_border_reopened'] && game.active === DEM) {
+ game.state = 'austria_hungary_border_reopened_check'
+ }
+ game.state = 'do_support_check'
+ } else {
+ game.state = 'do_support_check'
+ }
},
done () {
- game.available_ops = 0
- end_round()
+ 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
+ }
+ game.austria_hungary_border_reopened_checked = false
+ game.austria_hungary_border_reopened_used = false
+ if (game.vm_event_to_do) {
+ game.state = 'resolve_opponent_event'
+ } else {
+ end_round()
+ }
}
}
states.do_support_check = {
- inactive: 'do support checks',
+ inactive: 'do support checks.',
prompt () {
- view.prompt = `Target: ${game.selected_space}. Roll a die`
+ view.prompt = `Target: ${spaces[game.selected_space].name_unique}. Roll a die.`
gen_action('roll')
},
roll() {
- do_sc(game.selected_space)
- valid_spaces()
+ 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.raise_stakes = {
+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_used = 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()
+ 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['roundtable_talks']) {
+ 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['roundtable_talks'] = false
+ }
+
+ if (game.persistent_events['national_salvation_front'] && (game.pwr_struggle_in === 'Romania' || game.pwr_struggle_in === 'Bulgaria')) {
+ log('Communist receives 2 cards from Democrat due to National Salvation Front')
+ game.dem_pwr_hand_limit -= 2
+ game.com_pwr_hand_limit += 2
+ permanently_remove(102)
+ game.persistent_events['national_salvation_front'] = false
+ }
+
+ //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)
+ game.valid_cards = all_power_cards
+
+ //Check if The Crowd Turns Against Ceausescu occurs
+ if (game.persistent_events['the_crowd_turns_against_ceausescu'] && game.pwr_struggle_in === 'Romania') {
+ if (game.active === COM) {
+ game.return = COM
+ next_player()}
+ game.state = 'the_crowd_turns_against_ceausescu_prep'
+ } else {
+ game.state = 'raise_stakes_1'
+ }
+ }
+}
+
+states.the_crowd_turns_against_ceausescu_prep = {
+ get inactive() {
+ return `resolve ${cards[54].name}.`
+ },
+ prompt() {
+ view.prompt = 'The Crowd Turns Against Ceausescu: draw cards.'
+ gen_action('draw')
+ },
+ draw() {
+ 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 ${game.temp} Rally in the Squares.`)
+ game.temp = game.temp * 3
+ game.state = 'the_crowd_turns_against_ceausescu'
+ }
+}
+
+states.the_crowd_turns_against_ceausescu = {
+ get inactive() {
+ return `resolve ${cards[54].name}.`
+ },
+ prompt() {
+ view.prompt = `You have ${game.temp} influence points. Play for:`
+ gen_action('influence')
+ gen_action('support_check')
+ },
+ influence() {
+ push_undo()
+ game.ceausescu_cards = []
+ valid_spaces_infl()
+ 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()
+ game.ceausescu_cards = []
+ valid_spaces_sc()
+ game.available_ops = 2
+ game.state = 'support_check_prep'
+ }
+}
+
+states.the_crowd_turns_against_ceausescu_infl = {
+ inactive: 'add influence.',
+ prompt () {
+ if (game.temp === 0)
+ {
+ view.prompt = 'Place influence: done.';
+ gen_action("done");
+ return;
+ }
+
+ view.prompt = `Add influence: ${game.temp} remaining`
+ for (let space of game.valid_spaces) {
+ gen_action_infl(spaces[space.space_id].name_unique)
+ }
+ },
+ infl(space) {
+ add_infl(space)
+ },
+ done() {
+ if (game.return !== game.active) {
+ next_player()
+ }
+ game.state = 'raise_stakes_1'
+ }
+}
+
+states.raise_stakes_1 = {
inactive: 'raise the stakes',
prompt () {
- if (game.raised_stakes_round === 2) {
- console.log('game raised stakes round == 2')
- gen_action('struggle')
- return
- }
+ console.log('game.raised_stakes_discard', game.raised_stakes_discard)
if (game.raised_stakes_discard === 3) {
view.prompt = 'Raise the stakes: done'
gen_action('done')
} else if (game.raised_stakes_discard > 0) {
- console.log('in stakes >= 0')
view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes`
} else {
view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes`
- gen_action('done')
+ gen_action('pass')
}
for (let card of game.valid_cards) {
gen_action_card(card)
}
},
card(card) {
- log(`Discarded ${power_cards[card].name}`)
+ push_undo()
+ log(`Discarded P${power_cards[card].number}`) /*Set this to include value as with power struggle*/
+ discard(card)
- let find_card
- if (game.active === COM) {
- find_card = game.com_pwr_hand.indexOf(card);
- const [playedCard] = game.com_pwr_hand.splice(find_card, 1);
+ 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('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 if (game.raised_stakes_discard > 0) {
+ view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes`
} else {
- find_card = game.dem_pwr_hand.indexOf(card);
- const [playedCard] = game.dem_pwr_hand.splice(find_card, 1);
+ view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes`
+ gen_action('pass')
}
- game.power_struggle_discard.push(card)
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ },
+ card(card) {
+ push_undo()
+ log(`Discarded P${power_cards[card].number}`)
+ discard(card)
game.raised_stakes_discard ++
if (game.raised_stakes_discard === 3) {
@@ -835,197 +1116,201 @@ states.raise_stakes = {
}
},
+ pass() {
+ log('Did not raise the stakes')
+ game.raised_stakes_discard = 0
+ game.valid_cards = []
+ next_player()
+ game.state = 'begin_power_struggle'
+ },
done () {
- if (game.raised_stakes_discard === 0 ) {
- log('Did not raise the stakes')
- }
game.raised_stakes_discard = 0
- game.raised_stakes_round ++
+ game.valid_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 () {
- if (game.respond === 0 && game.valid_cards.length > 0) {
- view.prompt = "Play a card"
- for (let card of game.valid_cards) {
- gen_action_card(card)
+ 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')
}
- } else if (game.respond === 0 && game.valid_cards.length === 0) {
- view.prompt = 'No valid cards. You must concede.'
- gen_action('concede')
- } else if (game.respond === 1 && 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.respond === 1 && game.valid_cards.length === 0) {
- view.prompt = `${power_cards[game.played_power_card].name} played. You must 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')
-
- } else if (game.respond === 2) {
+ 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.respond === 3) {
+ }
+ 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')}
- } else if (game.respond === 4) {
- view.prompt = 'Draw 2 cards'
- gen_action('draw')
- } else if (game.respond === 5) {
- view.prompt = 'Remove 1 opponent influence'
-
- for (let space_id of game.valid_spaces) {
- const space = spaces.find(s => s.space_id === space_id);
- if (space) {
- gen_action_infl(space.name_unique);
- }
- }
- } else if (game.respond === 6) {
- view.prompt = 'Remove influence: done'
- gen_action('done')
- } else if (game.respond === 7 && game.available_ops > 0) {
- view.prompt = 'Discard 2 cards'
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- } else if (game.respond === 7 && game.available_ops === 0) {
- view.prompt = 'Discard cards: done'
- gen_action('done')
}
},
card(card) {
push_undo()
discard(card)
- if (game.respond === 0 && card >= 37 && card <= 48) {
- game.played_power_card = card
- game.respond = 3
- } else if (game.respond === 0 && card === 49){
- log(`Played: ${power_cards[card].name}`)
- game.played_power_card = card
- game.respond = 5
- valid_spaces()
- } else if (game.respond === 0 && card === 50) {
- log(`Played: ${power_cards[card].name}`)
- game.played_power_card = card
- game.respond = 4
- } else if (game.respond === 0 && card === 51) {
- log(`Played: ${power_cards[card].name}`)
- game.played_power_card = card
- game.respond = 7
- game.available_ops = 2
- next_player()
- if (game.active === DEM) {game.valid_cards = game.dem_pwr_hand}
- else {game.valid_cards = game.com_pwr_hand}
- }
- else if (game.respond === 0) {
- log(`Played: ${power_cards[card].name} ${power_cards[card].value}`)
- game.played_power_card = card
- game.respond = 1
- next_player()
- do_valid_cards()
-
- } else if (game.respond === 1) {
+ 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) {
- log(`Played Tactic Fails: ${power_cards[game.played_power_card].name} no longer playable`)
game.tactics_fails = power_cards[game.played_power_card].name
- game.respond = 0
+ 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 {
- log(`Played: ${power_cards[card].name} ${power_cards[card].value}. Roll for initiative`)
- game.respond = 2}
- } else if (game.respond === 7) {
- discard(card)
- game.available_ops --
- }
+ 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.respond = 0
+ game.phase = 0
do_valid_cards()
} else {
log(`Initiative roll failed. Required ${power_cards[game.played_power_card].value} or more`)
- game.respond = 0
+ game.phase = 0
next_player()
do_valid_cards()
}
},
concede () {
- log('Condeded')
+ log('Conceded')
log_h2('Aftermath')
log_h3('Support Loss')
- if (game.played_power_card >= 25 && game.played_power_card <= 30) {game.rally_win = 2}
- if (game.played_power_card >= 31 && game.played_power_card <= 36) {game.petition_win = 2}
- game.respond = 0
+ 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}
+ game.phase = 0
game.state = 'support_loss'
},
strike () {
- log(`Played: ${power_cards[game.played_power_card].name} as a Strike`)
+ log(`Played: P${power_cards[game.played_power_card].number} as a Strike`)
game.played_power_card = 9
- game.respond = 1
+ game.phase = 1
next_player()
do_valid_cards()
},
march () {
- log(`Played: ${power_cards[game.played_power_card].name} as a Strike`)
+ log(`Played: P${power_cards[game.played_power_card].number} as a Strike`)
game.played_power_card = 21
- game.respond = 1
+ game.phase = 1
next_player()
do_valid_cards()
},
rally () {
- log(`Played: ${power_cards[game.played_power_card].name} as a Rally in the Square`)
+ log(`Played: P${power_cards[game.played_power_card].number} as a Rally in the Square`)
game.played_power_card = 53
- game.respond = 1
+ game.phase = 1
next_player()
do_valid_cards()
},
petition () {
- log(`Played: ${power_cards[game.played_power_card].name} as a Strike`)
+ log(`Played: P${power_cards[game.played_power_card].number} as a Petition`)
game.played_power_card = 54
- game.respond = 1
+ game.phase = 1
next_player()
do_valid_cards()
},
- 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.respond = 0
+ game.phase = 0
next_player()
do_valid_cards()
- },
- infl(space) {
+ },*/
+ /*infl(space) {
game.remove_opponent_infl = true
remove_infl(space)
- game.respond = 6
+ game.phase = 6
},
- /* Think the code below is now redundant */
- discard () {
+ 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.respond === 7) {
- game.respond = 0
+ if (game.phase === 7) { /*Is this ever called anymore? */
+ game.phase = 0
+ log_msg_gap('Takes initiative')
do_valid_cards()
} else {
- game.respond = 0
+ game.phase = 0
next_player()
do_valid_cards()
}
@@ -1035,55 +1320,66 @@ states.power_struggle = {
states.support_loss ={
inactive: 'do Support Loss',
prompt () {
- if (game.respond === 0) {
- view.prompt = 'You lost the Power Struggle. Roll a die for Support Loss'
+ if (game.phase === 0) {
+ view.prompt = 'You lost the Power Struggle. Roll a die for Support Loss.'
gen_action('roll')
- } else if (game.respond === 1 && game.available_ops > 0 && game.valid_spaces.length > 0) {
- view.prompt = `Remove ${game.available_ops} influence`
+ } else if (game.phase === 1 && game.available_ops > 0 && game.valid_spaces.length > 0) {
+ view.prompt = `Remove ${game.available_ops} influence.`
for (let space_id of game.valid_spaces) {
- const space = spaces.find(s => s.space_id === space_id);
- if (space) {
- gen_action_infl(space.name_unique);
- }
+ /*const space = spaces.find(s => s && s.space_id === space_id); Don't think this is needed
+ if (space) { */
+ gen_action_infl(spaces[space_id].name_unique);
+ //}
}
- } else if (game.respond === 1 && game.available_ops === 0 ) {
+ } else if (game.phase === 1 && game.available_ops === 0 ) {
view.prompt = 'Support Loss: finished'
gen_action('done')
- } else if (game.respond === 1 && game.valid_spaces.length === 0) {
+ } else if (game.phase === 1 && game.valid_spaces.length === 0) {
view.prompt = 'No remaining influence to remove.'
gen_action('done')
}
},
roll () {
- let roll = Math.floor(Math.random() * 6)
+ let roll = Math.floor(Math.random() * 6) + 1
log(`Rolled a ${roll}`)
roll = roll + game.raised_stakes + game.rally_win - game.petition_win
+
+ // Roll modifiers
+ if (game.active === COM && game.persistent_events['yakovlev']) {
+ log('+1 from Yakovlev Counsels Gorbachev')
+ roll ++
+ }
+
if (roll < 0) {roll = 0}
else if (roll > 7) {roll = 7}
+
if (game.raised_stakes !== 0) {
- log(`+${game.raised_stakes} from raising the stakes`)
+ log(`+${game.raised_stakes} from Raising the Stakes`)
}
if (game.rally_win !== 0) {
- log('+2 from winning on a Rally in the Square')
+ log('+2 from winning on a P25')
}
if (game.petition_win !== 0) {
- log('-2 from winning on a Petition')
+ log('-2 from winning on a P31')
}
log(`Modified roll: ${roll}`)
game.available_ops = support_loss_roll[roll]
- game.respond++
- valid_spaces()
+ game.phase++
+ valid_spaces_support_loss()
},
infl (space) {
+ game.remove_opponent_infl = false /* Don't know why this is needed... */
remove_infl(space)
- valid_spaces()
+ if (game.available_ops === 0 ) {
+ game.valid_spaces = []
+ }
},
done () {
next_player()
log_h3('Victory Point')
- game.respond = 0
+ game.phase = 0
game.state = 'vp_roll'
}
}
@@ -1091,13 +1387,13 @@ states.support_loss ={
states.vp_roll = {
inactive: 'do VP Roll',
prompt () {
- if (game.respond === 0) {
+ if (game.phase === 0) {
view.prompt = 'Roll a die for Victory'
gen_action('roll')
- } else if (game.respond === 1) {
+ } else if (game.phase === 1) {
view.prompt = 'Take power'
gen_action('take')
- } else if (game.respond === 4) {
+ } else if (game.phase === 2) {
view.prompt = 'Proceed to scoring'
gen_action('scoring')
}
@@ -1106,36 +1402,44 @@ states.vp_roll = {
let roll = Math.floor(Math.random() * 6) + 1
log(`Rolled a ${roll}`)
roll = roll + game.raised_stakes + game.rally_win - game.petition_win
+ if (game.active === DEM && game.persistent_events['yakovlev']) {
+ log('+1 from Yakovlev Counsels Gorbachev')
+ roll ++
+ }
if (roll < 0) {roll = 0}
else if (roll > 7) {roll = 7}
if (game.raised_stakes !== 0) {
- log(`+${game.raised_stakes} from raising the stakes`)
+ log(`+${game.raised_stakes} from Raising the Stakes`)
}
if (game.rally_win !== 0) {
- log('+2 from winning on a Rally in the Square')
+ log('+2 from winning on a P25')
}
if (game.petition_win !== 0) {
- log('-2 from winning on a Petition')
+ log('-2 from winning on a P31')
}
log(`Modified roll: ${roll}`)
let vp_change = vp_roll[roll]
log(`Gain ${vp_change} VP`)
- if (roll >= 4) {log('Democrat takes power')}
+ if (roll >= 4)
if (game.active === DEM) {game.vp += vp_change}
else {game.vp -= vp_change}
if (game.active === DEM && roll >= 4) {
- game.respond = 1
+ game.phase = 1
} else {
- game.respond = 0
+ game.phase = 0
+ if (game.active === DEM) {next_player()}
game.state = 'choose_power'
}
},
take () {
+ push_undo()
+ permanently_remove(game.played_card)
take_power(game.pwr_struggle_in)
- game.respond = 4
+ game.phase = 2
},
scoring () {
+ push_undo()
score_country(game.pwr_struggle_in)
game.state = 'score_country'
},
@@ -1144,51 +1448,378 @@ states.vp_roll = {
states.choose_power = {
inactive: 'choose whether to remain in power.',
prompt () {
- if (game.respond === 0) {
+ if (game.phase === 0) {
view.prompt = 'Choose whether to remain in power'
gen_action('retain')
gen_action('surrender')
- } else if (game.respond === 1) {
+ } else if (game.phase === 1) {
view.prompt = 'Proceed to scoring.'
gen_action('scoring')
}
},
retain() {
+ push_undo()
retain_power(game.pwr_struggle_in)
- game.respond = 1
+ game.phase = 1
},
surrender () {
+ push_undo()
take_power(game.pwr_struggle_in)
- game.respond = 1
+ permanently_remove(game.played_card)
+ game.phase = 1
},
scoring () {
+ push_undo()
score_country(game.pwr_struggle_in)
- if (game_over()) {
- game.state = 'game_over'
- } else {game.state = 'score_country'}
+ check_vp()
+ game.state = 'score_country'
}
}
states.score_country = {
inactive: `score country`,
prompt () {
- view.prompt = 'Scoring: done'
+ view.prompt = 'Scoring: done.'
gen_action('done')
},
done () {
reset_power()
+ /*if (game.return !== game.active) {
+ next_player()}*/
+ game.state = 'finish_scoring'
+ }
+}
+
+states.finish_scoring ={
+ inactive: 'finish scoring.',
+ prompt() {
+ view.prompt = 'End power struggle.'
+ gen_action('done')
+ } ,
+ done() {
+ log('Power Struggle resolved') /*At this point log card dicarded or permanently removed? */
+ check_vp()
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['new_years_eve_party']) {
+ log('No held scoring cards')
+ game.state = 'new_years_eve_party'
+ }
+ else if(game.turn === 10) {
+ clear_undo()
+ game.state = 'final_scoring_held'
+ log_h2('Final Scoring')
+ } 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() {
+ const held_countries = Object.values(game.revolutions).filter(value => value === false).length
+ let vp_gain = 4*held_countries
+ log(`Communist holds ${held_countries}: gains ${vp_gain} VP`)
+ game.vp -= 4*held_countries
+ game.scored_countries = {'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.scored_countries['East_Germany'] && game.scored_countries['Poland'] && game.scored_countries['Czechoslovakia'] && game.scored_countries['Hungary'] && game.scored_countries['Romania'] && game.scored_countries['Bulgaria']) {
+ view.prompt = 'Country scoring: done.'
+ gen_action('done')
+ } else {
+ view.prompt = 'Choose a country to score'
+ if (!game.scored_countries['East_Germany']) {gen_action('east_germany')}
+ if (!game.scored_countries['Poland']) {gen_action('poland')}
+ if (!game.scored_countries['Czechoslovakia']) {gen_action('czechoslovakia')}
+ if (!game.scored_countries['Hungary']) {gen_action('hungary')}
+ if (!game.scored_countries['Romania']) {gen_action('romania')}
+ if (!game.scored_countries['Bulgaria']) {gen_action('bulgaria')}
+ }
+ },
+ east_germany() {
+ score_country('East_Germany')
+ game.scored_countries['East_Germany'] = true
+ },
+ poland() {
+ score_country('Poland')
+ game.scored_countries['Poland'] = true
+ },
+ czechoslovakia() {
+ score_country('Czechoslovakia')
+ game.scored_countries['Czechoslovakia'] = true
+ },
+ hungary() {
+ score_country('Hungary')
+ game.scored_countries['Hungary'] = true
+ },
+ romania() {
+ score_country('Romania')
+ game.scored_countries['Romania'] = true
+ },
+ bulgaria() {
+ score_country('Bulgaria')
+ game.scored_countries['Bulgaria'] = true
+ },
+ done() {
+ 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 = {
- inactive: 'victory'
+ 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.'
+ available_cards = game.communist_hand
+ for (let card of available_cards) {
+ gen_action_card(card)
+ }
+ } else if (game.phase === 1) {
+ view.prompt = 'Discard a card: finished.'
+ gen_action('done')
+ } else if (game.played_card > 0 ) {
+ view.prompt = 'Roll a die.'
+ gen_action('roll')
+ }
+ },
+ card (card) {
+ push_undo()
+ log(`Discarded C${cards[card].number}`)
+ game.played_card = card
+ let find_card
+ find_card = game.communist_hand.indexOf(card);
+ game.communist_hand.splice(find_card, 1);
+ if (game.persistent_events['perestroika'] && game.active === COM) {
+ log('+1 op from C25')
+ game.available_ops = cards[card].ops +1
+ } else {game.available_ops = cards[card].ops}
+ },
+ roll() {
+ clear_undo()
+ let roll = Math.floor(Math.random() * 6) + 1
+ log(`Rolled a ${roll}`)
+ log(`+${game.available_ops} from C${cards[game.played_card].number}.`)
+ let total = roll + game.available_ops
+
+ if (total > 5) {
+ log('The strike is over.')
+ permanently_remove(5)
+ game.persistent_events['general_strike'] = false
+ } else {
+ log('The strike continues.')
+ }
+ 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['honecker'] = false
+ game.state = 'choose_card'
+ },
+ pass() {
+ log('C15: passed')
+ game.persistent_events['honecker'] = false
+ end_round()
+ }
}
-states.test = {
- inactive: 'test',
+states.new_years_eve_party = {
+ get inactive() {
+ return `resolve ${cards[104].name}.`
+ },
+ prompt() {
+ if (!game.is_pwr_struggle) {
+ view.prompt = 'You may choose a country to have a final power struggle.'
+ if (!game.revolutions['East_Germany']) {gen_action('east_germany')}
+ if (!game.revolutions['Poland']) {gen_action('poland')}
+ if (!game.revolutions['Czechoslovakia']) {gen_action('czechoslovakia')}
+ if (!game.revolutions['Hungary']) {gen_action('hungary')}
+ if (!game.revolutions['Romania']) {gen_action('romania')}
+ if (!game.revolutions['Bulgaria']) {gen_action('bulgaria')}
+ gen_action('pass')
+ } else {
+ gen_action('end')
+ }
+ },
+ east_germany() {
+ game.pwr_struggle_in = 'East_Germany'
+ goto_vm(42)
+ },
+ poland() {
+ game.pwr_struggle_in = 'Poland'
+ goto_vm(22)
+ },
+ czechoslovakia() {
+ game.pwr_struggle_in = 'Czechoslovakia'
+ goto_vm(55)
+ },
+ hungary() {
+ game.pwr_struggle_in = 'Hungary'
+ goto_vm(23)
+ },
+ romania() {
+ game.pwr_struggle_in = 'Romania'
+ goto_vm(95)
+ },
+ bulgaria () {
+ game.pwr_struggle_in = 'Bulgaria'
+ goto_vm(43)
+ },
+ pass() {
+ 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.stasi_card === 0 ) {
+ view.prompt = 'Stasi: you must select your next card to play.'
+ let available_cards = game.democrat_hand
+ 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
+ },
+ done() {
+ game.round_player = COM
+ game.round ++
+ log_h2(`Action Round ${game.round}`)
+ next_player()
+ game.valid_spaces = []
+ if (game.persistent_events['general_strike']) {
+ game.state = 'general_strike'
+ } else {
+ game.state = 'choose_card'
+ }
+ }
+}
+
+states.stasi_play_card = {
+ inactive: 'play a card.',
prompt () {
- view.prompt = "test"
+ if (game.played_card > 0) {
+ game.state = 'play_card'
+ view.prompt = 'Play card: done'
+ gen_action("done");
+ return;
+ }
+
+ view.prompt = `Stasi: you must play ${cards[game.stasi_card].name}.`
+ let available_cards = [game.stasi_card]
+ for (let card of available_cards) {
+ gen_action_card(card)
+ }
+ },
+ card(card) {
+ push_undo()
+ log_msg_gap(`Stasi: played C${cards[card].number}`)
+ game.played_card = card
+ let find_card
+ find_card = game.democrat_hand.indexOf(card);
+ const [playedCard] = game.democrat_hand.splice(find_card, 1);
+ game.available_ops = cards[card].ops
+ if (game.available_ops > 1 && game.persistent_events['prudence'] === DEM) {
+ game.available_ops--
+ }
+ },
+ done () {
+ game.state = 'play_card'
+ game.stasi_card = 0
}
}
@@ -1197,106 +1828,230 @@ states.test = {
function add_infl(space) {
- log(`Added 1 influence in ${space}.`)
push_undo()
const clicked_space = find_space_index(space)
-
- if (check_control(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}.`)
+
+ if (spaces[clicked_space].country !== 'East_Germany'){
+ game.austria_hungary_border_reopened_tracker = false
+ }
+
+ // Check Genscher
+ if (game.persistent_events['genscher'] && game.active === DEM && spaces[clicked_space].country === 'East_Germany') {
+ game.available_ops--
+ } else if (check_control(clicked_space)) {
game.available_ops -= 2
} else {
game.available_ops--
}
+ // Update influence values
if (game.active === COM) {
game.pieces[clicked_space].comInfl++
} else {
game.pieces[clicked_space].demInfl++
}
- game.pieces[clicked_space].demCtrl = 0
- game.pieces[clicked_space].comCtrl = 0
+ // Check whether spaces are controlled
+ check_control_change(clicked_space)
- if ((game.pieces[clicked_space].demInfl - game.pieces[clicked_space].comInfl) >= game.pieces[clicked_space].stability) {
- game.pieces[clicked_space].demCtrl = 1
- }
- if ((game.pieces[clicked_space].comInfl - game.pieces[clicked_space].demInfl) >= game.pieces[clicked_space].stability) {
- game.pieces[clicked_space].comCtrl = 1
+ // Check Austria Hungary Border Reoponed is true and condition has been met
+ if (game.available_ops === 0 && game.active === DEM && game.persistent_events['austria_hungary_border_reopened'] && game.austria_hungary_border_reopened_tracker && !game.austria_hungary_border_reopened) {
+ game.available_ops ++
+ log('+1 influence from Austria-Hungary Border Reopened')
+ game.austria_hungary_border_reopened = true
+ 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
+
+ if (game.available_ops === 1) {
+ if (game.active === DEM) {
+ if (!game.persistent_events['genscher']) {
+ game.valid_spaces = game.valid_spaces.filter(n => game.pieces[n].comCtrl !== 1)
+ } else {
+ game.valid_spaces = game.valid_spaces.filter(n => !(game.pieces[n].comCtrl === 1 && spaces[n].country !== 'East_Germany'))
+ }
+ } else {
+ game.valid_spaces = game.valid_spaces.filter(n => game.pieces[n].demCtrl !== 1)
+ }
+ }
+
+ //Clear valid spaces if no IP remaining
+ if (game.available_ops === 0 ) {
+ game.valid_spaces = []
+ }
}
function remove_infl(space) {
- log(`Removed 1 influence from ${space}.`)
push_undo()
const clicked_space = find_space_index(space)
-
+ log(`Removed 1 influence from %${clicked_space}.`)
+
if (game.remove_opponent_infl === true) {
if (game.active === COM) {
game.pieces[clicked_space].demInfl--
+ if (game.pieces[clicked_space].demInfl === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
+ }
} else {
game.pieces[clicked_space].comInfl--
+ if (game.pieces[clicked_space].comInfl === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
+ }
}
-
- if ((game.pieces[clicked_space].demInfl - game.pieces[clicked_space].comInfl) < game.pieces[clicked_space].stability) {
- game.pieces[clicked_space].demCtrl = 0
- }
- if ((game.pieces[clicked_space].comInfl - game.pieces[clicked_space].demInfl) < game.pieces[clicked_space].stability) {
- game.pieces[clicked_space].comCtrl = 0
- }
+ check_control_change(clicked_space)
+
} else {
if (game.active === COM) {
game.pieces[clicked_space].comInfl--
+ if (game.pieces[clicked_space].comInfl === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
+ }
} else {
game.pieces[clicked_space].demInfl--
+ if (game.pieces[clicked_space].demInfl === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
+ }
}
-
- if ((game.pieces[clicked_space].demInfl - game.pieces[clicked_space].comInfl) < game.pieces[clicked_space].stability) {
- game.pieces[clicked_space].demCtrl = 0
- }
- if ((game.pieces[clicked_space].comInfl - game.pieces[clicked_space].demInfl) < game.pieces[clicked_space].stability) {
- game.pieces[clicked_space].comCtrl = 0
- }
+ check_control_change(clicked_space)
}
game.available_ops--
}
function do_sc(space) {
- log(`Target: ${space}`)
+ log_gap(`Target: ${space}`)
+ let clicked_space = find_space_index(space)
+
+ //Check Helsinki Final Act
+
+ if (game.persistent_events['helsinki_final_act'] && (spaces[clicked_space].socio === 5 || spaces[clicked_space].socio === 6) ) {
+ log('+1 VP from Helsinki Final Act')
+ game.vp ++
+ check_vp()
+ }
+
+ // 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
- roll += cards[game.played_card].ops
- log(`+${cards[game.played_card].ops} from card ops`)
-
+ else if (game.is_pwr_struggle) {
+ roll += game.temp
+ log(`+${game.temp} from Ceausescu`)
+ }
+
+ // Check if in Tiananmen Square Track Award
+
+ else if (game.state === 'vm_tst_6_sc') {
+ roll = 2
+ log('+2 from Tiananmen Square Track award')
+ }
+ else {
+ // Check for Perestoika
+ if (game.active === COM && game.persistent_events['perestroika']) {
+ roll++
+ }
+ roll += cards[game.played_card].ops
+ log(`+${cards[game.played_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
+
+ if (game.persistent_events['tear_gas'] && spaces[clicked_space.socio === 6]) {
+ roll ++
+ log('+1 from C30')
+ permanently_remove(30)
+ game.persistent_events['tear_gas'] = false
+ }
+ if (game.active === DEM && spaces[clicked_space].region === 'Eastern Europe' && game.persistent_events['frg_embassies']) {
+ roll++
+ log('+1 from C74')
+ }
+ if (game.warsaw_pact_summit) {
+ roll += 2
+ log('+2 from C76')
+ }
+ if (game.active === DEM && spaces[clicked_space].country === 'East_Germany' && game.persistent_events['grenztruppen']) {
+ roll--
+ log('-1 from C59')
+ }
+ if ((game.active === COM && game.persistent_events['stand_fast'] === DEM && game.pieces[clicked_space].demCtrl === 1) || (game.active === DEM && game.persistent_events['stand_fast'] === COM && game.pieces[clicked_space].comCtrl === 1)){
+ roll--
+ log('-1 from C100')
+ }
+ if (game.active === DEM && game.persistent_events['elena'] && spaces[clicked_space].country === 'Romania') {
+ roll--
+ log('-1 from C101')
+ }
+ if (game.active === DEM && game.austria_hungary_border_reopened_used) {
+ roll++
+ log(`+1 from C58`)
+ }
+
+ // Continue with logic - check for adjacency
+
+ // Events which affect adjacency - The Wall
+
const adj = count_adj(space)
- 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`)
+ if (game.active === COM && game.persistent_events['the_wall'] && spaces[clicked_space].country === 'East_Germany') {
+ log('No adjacency for Democrats due to The Wall')
+ permanently_remove(9)
+ roll += adj.com_adj
+ if (adj.com_adj > 0) {
+ log(`+${adj.com_adj} from adjacent control`)
+ }
+ game.persistent_events['the_wall'] = false
+ permanently_remove(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(`${change_infl} point swing`)
+ log_msg_gap(`${change_infl} point swing`)
let clicked_space = find_space_index(space)
if(game.active === DEM) {
if (change_infl > game.pieces[clicked_space].comInfl) {
@@ -1306,6 +2061,9 @@ function do_sc(space) {
} else {
game.pieces[clicked_space].comInfl -= change_infl
}
+ if (game.pieces[clicked_space].comInfl === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
+ }
} else {
if (change_infl > game.pieces[clicked_space].demInfl) {
const residual = change_infl - game.pieces[clicked_space].demInfl
@@ -1314,133 +2072,196 @@ function do_sc(space) {
} else {
game.pieces[clicked_space].demInfl -= change_infl
}
+ if (game.pieces[clicked_space].demInfl === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
+ }
}
- game.pieces[clicked_space].demCtrl = 0
- game.pieces[clicked_space].comCtrl = 0
- if ((game.pieces[clicked_space].demInfl - game.pieces[clicked_space].comInfl) >= game.pieces[clicked_space].stability) {
- game.pieces[clicked_space].demCtrl = 1
- }
- if ((game.pieces[clicked_space].comInfl - game.pieces[clicked_space].demInfl) >= game.pieces[clicked_space].stability) {
- game.pieces[clicked_space].comCtrl = 1
- }
+ check_control_change(clicked_space)
+
} else {
- log('No change in influence')
+ log_msg_gap('No change in influence')
}
+ if (game.active === COM && game.persistent_events['eco_glasnost'] && spaces[clicked_space].space_id === 66) {
+ log_msg_gap('+1 VP from Eco Glasnost')
+ game.vp++
+ check_vp()
+ }
+
+ // If Austria-Hungary Border Reopened used, all future support checks must be in East Germany
+ if (game.austria_hungary_border_reopened_used) {
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
+ }
+ game.selected_space = 0
clear_undo()
}
-function valid_spaces() {
+function valid_spaces_setup() {
+ game.valid_spaces = []
let valid_spaces_set = new Set();
if (game.state === 'com_init') {
- for (let space of game.pieces) {
- if (space.demInfl === 0) {
+ for (let space of game.pieces) {
+ if (space && space.demInfl === 0) {
valid_spaces_set.add(space.space_id);
}
}
} else if (game.state === 'dem_init') {
for (let space of game.pieces) {
- if (space.comInfl === 0) {
+ if (space && space.comInfl === 0) {
valid_spaces_set.add(space.space_id);
}
}
- } else if (game.state === 'support_check_prep' || game.state === 'do_support_check') {
- if (game.active === DEM) {
- for (let space of game.pieces) {
- if (space.comInfl !== 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();
+ if (game.active === DEM) {
+ for (let space of game.pieces) {
+ if (space && space.comInfl !== 0 ) {
+ valid_spaces_set.add(space.space_id);
+ }
+ }
+ } else {
+ for (let space of game.pieces) {
+ if (space && space.demInfl !== 0 ) {
+ if (game.persistent_events['solidarity_legalised']) {
+ if (space.space_id === 14) {continue}
}
- }
- } else {
- for (let space of game.pieces) {
- if (space.demInfl !== 0) {
- valid_spaces_set.add(space.space_id);
+ if (game.persistent_events['civic_forum']) {
+ if (space.space_id === 31) {continue}
+ }
+ if (game.persistent_events['we_are_the_people']) {
+ if (space.space_id === 9) {continue}
+ }
+ valid_spaces_set.add(space.space_id);
+ }
+ }
+
+ //Check for Foreign Currency Debt Burden
+ if (game.persistent_events['foreign_currency_debt_burden'] !== '') {
+ for (let n of valid_spaces_set) {
+ if (spaces[n].country === game.persistent_events['foreign_currency_debt_burden']) {
+ valid_spaces_set.delete(n);
}
}
}
- } else if (game.state === 'support_loss') {
+ }
+
+ // 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['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();
+ if (game.state === 'support_loss') {
if (game.active === DEM) {
for (let piece of game.pieces) {
- let space = spaces.find(s => s.space_id === piece.space_id);
+ 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);
}
}
} else {
for (let piece of game.pieces) {
- let space = spaces.find(s => s.space_id === piece.space_id);
+ 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 if (game.state === 'power_struggle') {
- if (game.active === DEM) {
- for (let piece of game.pieces) {
- let space = spaces.find(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);
- }
+ }
+ // 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) {
- let space = spaces.find(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);
- }
+ }
+ } 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;
+}
- else {
- // Iterate over all spaces to find the ones with the player's influence
- for (let piece of game.pieces) {
- const player_influence = game.active === COM ? piece.comInfl : piece.demInfl;
+function valid_spaces_infl() {
+ let valid_spaces_set = new Set();
+ // Iterate over all spaces to find the ones with the player's influence
+ for (let piece of game.pieces) {
+ if (!piece) continue
+ const player_influence = game.active === COM ? piece.comInfl : piece.demInfl;
- // 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(piece.space_id);
-
- // Find the corresponding space in the `spaces` array to get the adjacency information
- const space = spaces.find(s => s.space_id === piece.space_id);
- if (space) {
- for (let adj_space_id of space.adjacent) {
- if (adj_space_id) {
- const adj_piece = game.pieces.find(p => p.space_id === adj_space_id);
- const adj_space = spaces.find(s => s.space_id === adj_space_id);
-
- // Check if the adjacent space is controlled by the opponent
- const opponent_control = game.active === COM ? adj_piece.demCtrl : adj_piece.comCtrl;
-
- // Only add the adjacent space if the available_ops >= 2 or the space is not controlled by the opponent
- if (game.available_ops >= 2 || !opponent_control) {
- valid_spaces_set.add(adj_space.space_id);
- }
- }
+ // 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(piece.space_id);
+
+ // Check adjacency information
+ for (let adj_space_id of piece.adjacent) {
+ if (adj_space_id) {
+ const adj_piece = game.pieces.find(p => p && p.space_id === adj_space_id);
+
+ // Check if the adjacent space is controlled by the opponent
+ const opponent_control = game.active === COM ? adj_piece.demCtrl : adj_piece.comCtrl;
+ //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['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 (game.available_ops >= 2 || !opponent_control) {
+ valid_spaces_set.add(adj_piece.space_id)
}
- }
+ }
}
- }
- }
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
+ }
+ }
+ // 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.respond === 0) {
+ 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}
+ 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.respond === 1) {
+ } 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) {
@@ -1470,24 +2291,51 @@ function count_adj(name_unique) {
for (let adj_space_id of space.adjacent) {
if (adj_space_id) {
- const adj_piece = game.pieces.find(piece => piece.space_id === adj_space_id);
+ const adj_piece = game.pieces.find(piece => piece && piece.space_id === adj_space_id);
if (adj_piece) {
if (adj_piece.demCtrl === 1) {
+ console.log(adj_piece.name_unique, 'is dem controlled')
dem_adj++
}
if (adj_piece.comCtrl === 1) {
+ console.log(adj_piece.name_unique, 'is com controlled')
com_adj++
}
}
}
}
+ console.log('dem_adj: ', dem_adj, 'com_adj: ', com_adj)
return {dem_adj, com_adj}
}
-function check_control(space) {
- if (game.active === 'COM' && space.demCtrl === 1) {
+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) {
+ if (game.active === COM && game.pieces[space_id].demCtrl === 1) {
return true;
- } else if (game.active === 'DEM' && space.comCtrl === 1) {
+ } else if (game.active === DEM && game.pieces[space_id].comCtrl === 1) {
return true;
} else {
return false;
@@ -1500,21 +2348,35 @@ function do_tst_attempt() {
roll += game.available_ops
log(`+${game.available_ops} from the card operations value`)
+
+ // TIANANMEN SQUARE MODIFIERS
+
if (game.active === DEM && game.dem_tst_attempted === 1 || game.active === COM && game.com_tst_attempted === 1) {
- roll += 1;
+ roll ++;
log('+1 modifier from previous Tiananmen Square Track attempts')
}
if ((game.active === DEM && cards[game.played_card].side === 'D') || (game.active === COM && cards[game.played_card].side === 'C')) {
- roll += 1;
+ roll ++;
log('+1 for playing own card');
}
+ if (game.active === COM && game.persistent_events['li_peng']) {
+ roll ++
+ log('+1 from Li Peng')
+ }
log(`Modified die roll: ${roll}`)
+
+ // TIANANMEN SQUARE ATTEMPT
+ game.return = game.active
+ game.return_state = 'tiananmen_square_attempt'
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.tst_success = true
game.dem_tst_position++
game.dem_tst_attempted = 0
+ if (game.dem_tst_position === 3 && game.com_tst_position < 3) {goto_vm(203)}
+ if (game.dem_tst_position === 4 && game.com_tst_position < 4) {goto_vm(204)}
} else {
log(`${dem_tst_req[game.dem_tst_position]} required: fail`)
game.dem_tst_attempted = 1
@@ -1523,13 +2385,20 @@ function do_tst_attempt() {
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.tst_success = true
game.com_tst_position++
game.com_tst_attempted = 0
+ if (game.com_tst_position === 3 && game.dem_tst_position < 3) {goto_vm(203)}
+ if (game.com_tst_position === 4 && game.dem_tst_position < 4) {goto_vm(204)}
} else {
log(`${com_tst_req[game.com_tst_position]} required: fail`)
game.com_tst_attempted = 1
}
}
+ // Check whether The Reformer is playable:
+ if ((game.dem_tst_position !== game.com_tst_position)) {
+ game.playable_cards[67] = 2
+ }
}
function check_presence(country) {
@@ -1543,9 +2412,9 @@ function check_presence(country) {
for (let space of spaces) {
- if (space.country === country) {
+ if (space && space.country === country) {
- let piece = game.pieces.find(p => p.space_id === space.space_id);
+ let piece = game.pieces.find(p => p && p.space_id === space.space_id);
if (piece.demCtrl === 1) {
dem_spaces++;
@@ -1604,29 +2473,29 @@ function battlegrounds(country) {
}
function take_power(country) {
+
log(`Democrat takes power in ${game.pwr_struggle_in}`)
game.revolutions[country] = true
+
}
function retain_power(country){
game.times_held[country]++
let vp_gain = get_value(country)*game.times_held[country]
- log(`Communist gains ${vp_gain}VP from holding power`)
+ log(`Chooses to retain power`)
+ log(`-${vp_gain} VP`)
game.vp -= vp_gain
}
-function find_country(country) {
- return countries.indexOf(country)
-}
-
function score_country(country) {
- log_h3('Scoring')
+ log_h3(`Scoring: ${country}`)
let status
let presence = check_presence(country)
- if (presence.dem_domination) {status = "Democrat has domination"}
- else if (presence.com_domination) {status = "Communist has domination"}
- else if (presence.dem_control) {status = "Democrat has control"}
+ console.log('presence: ', presence)
+ if (presence.dem_control) {status = "Democrat has control"}
else if (presence.com_control) {status = "Communist has control"}
+ else if (presence.dem_domination) {status = "Democrat has domination"}
+ else if (presence.com_domination) {status = "Communist has domination"}
else {status = "No domination or control"}
log(`${status}`)
log(`${presence.dem_battlegrounds} Democrat battlegrounds`)
@@ -1637,7 +2506,8 @@ function score_country(country) {
if (presence.dem_spaces > 0) {dem_vp += value}
if (presence.dem_domination) {dem_vp += value}
if (presence.dem_control && country !== "Hungary") {
- dem_vp += value}
+ dem_vp += value
+ }
else if (presence.dem_control && country === "Hungary") {dem_vp += 2}
dem_vp += presence.dem_battlegrounds
@@ -1654,41 +2524,245 @@ function score_country(country) {
function get_value(country) {
let value
- if (country === "East Germany" || country === "Poland") {value = 3}
- else if (country === "Czechoslovakia" || country === "Romania" || country === "Bulgaria") {value = 2}
+ 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(`C${cards[card].number} permanently removed`)
+ 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!`)
+ } else if(game.vp <= -20) {
+ goto_game_over(COM, `${COM} won an Automatic Victory!`)
+ }
+}
+
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 true
+
+}
+
// =========== 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. If not, discard.
+ if (!game.strategy_removed.includes(game.played_card) && !game.table_cards.includes(game.played_card)) {
+ 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
- if (game.active === DEM && game.round === 7) {
- new_turn()
- game.state = 'choose_card'
+ 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.warsaw_pact_summit = false
+ game.vm_influence_added = {}
+ game.return = ''
+ game.valid_cards = []
+ game.valid_spaces = []
+
+ // Check for duplicate card entries
+ let 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}`)
+ }
+
+
+
+ // Resolve Events
+
+ if (game.persistent_events['austria_hungary_border_reopened']) {
+ game.austria_hungary_border_reopened = false
+ game.austria_hungary_border_reopened_tracker = true
+ }
+
+ console.log('game.dem_tst_position ', game.dem_tst_position , 'game.com_tst_position ', game.com_tst_position )
+ // Check if last round and if so resolve end turn events
+ if (game.round_player === DEM && game.round === 7) {
+ if(game.persistent_events['honecker']) {
+ next_player()
+ game.state = 'honecker'
+ return
+ } /*else if (game.persistent_events['new_years_eve_party']) {
+ game.state = 'new_years_eve_party'
+ 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
- if (game.active===COM) {
+ if(game.round_player === COM && game.stasi_card > 0 ) {
game.round_player = DEM
- } else {
- game.round_player = COM
- game.round ++
- log_h2(`Action Round ${game.round}`)
+ if (game.active !== DEM) {
+ next_player()
+ }
+ game.state = 'stasi_play_card'
+ return
+ } else if (game.round_player === COM && game.round === 8) {
+ clear_undo()
+ game.state = 'end_turn_4_5_4'
+ return
+ } else if (game.round_player===COM) {
+ game.round_player = DEM
+ if (game.active !== DEM) {
+ next_player()
+ }
+ game.state = 'choose_card'
+ return
}
- next_player()
- game.state = 'choose_card'
- game.valid_spaces = []
+ if (game.round_player === DEM) {
+ if(game.persistent_events['stasi']) {
+ //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['general_strike']){
+ game.state = 'general_strike'
+ game.round ++
+ log_h2(`Action Round ${game.round}`)
+ game.round_player = COM
+ if (game.active !== COM) {
+ next_player()
+ }
+ return
+ } else {
+ game.state = 'choose_card'
+ game.round_player = COM
+ game.round ++
+ if (game.active !== COM) {
+ next_player()
+ }
+ log_h2(`Action Round ${game.round}`)
+ }
+ }
+ //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 ++
@@ -1698,6 +2772,55 @@ function new_turn() {
game.round_player = COM
game.dem_tst_attempted_this_turn = 0
game.com_tst_attempted_this_turn = 0
+ game.tst_7 = false
+ game.tst_8 = false
+ game.persistent_events['perestroika'] = false
+ game.persistent_events['prudence'] = ''
+ game.persistent_events['sinatra_doctrine'] = false
+ game.persistent_events['stasi'] = false
+ game.persistent_events['honecker'] = false
+
+ //Remove Events on the table which last only 1 turn
+ console.log('in new turn')
+ if (game.persistent_events['austria_hungary_border_reopened']) {
+ game.persistent_events['austria_hungary_border_reopened'] = false
+ permanently_remove(58)
+ }
+ if (game.persistent_events['elena']) {
+ game.persistent_events['elena'] = false
+ permanently_remove(101)
+ }
+ if (game.persistent_events['grenztruppen']) {
+ game.persistent_events['grenztruppen'] = false
+ permanently_remove(59)
+ }
+
+ if (game.persistent_events['foreign_currency_debt_burden'] !== '') {
+ game.persistent_events['foreign_currency_debt_burden'] = ''
+ permanently_remove(49)
+ }
+
+ if (game.persistent_events['frg_embassies']) {
+ console.log('in new turn - frg embassies check')
+ game.persistent_events['frg_embassies'] = false
+ permanently_remove(74)
+ }
+
+ if (game.persistent_events['genscher']) {
+ game.persistent_events['genscher'] = false
+ permanently_remove(63)
+ }
+
+ if (game.persistent_events['stand_fast'] !== '') {
+ game.persistent_events['stand_fast'] = ''
+ permanently_remove(100)
+ }
+
+ if (game.samizdat_card > 0 ) {
+ game.democrat_hand.push(game.samizdat_card)
+ game.samizdat_card = 0
+ }
+
log_h1("Turn " + game.turn)
if (game.turn === 4) {
@@ -1707,15 +2830,50 @@ function new_turn() {
add_lateyear()
}
if (game.turn > 1) {
+ if (game.persistent_events['presidential_visit']) {
+ game.com_hand_limit = 7
+ log('Communist draws 7 cards due to Presidential Visit')
+ permanently_remove(65)
+ game.persistent_events['presidential_visit'] = false
+ }
+ 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)
+
}
- log_h2("Action Round " + game.round)
- log_side()
+
+ //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)
+ game.state = 'choose_card'
+ }
}
function next_player() {
clear_undo()
-
+ //console.log('next player called')
if (game.active === DEM)
game.active = COM
else
@@ -1724,12 +2882,17 @@ function next_player() {
log_side()
}
-function find_space_index(name_unique) {
- return game.pieces.findIndex(piece => piece && piece.name_unique === name_unique);
+function change_player() {
+ clear_undo()
+ //console.log('next player called')
+ if (game.active === DEM)
+ game.active = COM
+ else
+ game.active = DEM
}
-function find_card_index(card) {
- return cards.findIndex(card => card && card.number === card);
+function find_space_index(name_unique) {
+ return game.pieces.findIndex(piece => piece && piece.name_unique === name_unique);
}
function draw_deck(deck) {
@@ -1737,50 +2900,64 @@ function draw_deck(deck) {
}
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) {
- const randomIndex = Math.floor(Math.random() * deck.length);
+ //console.log('draw card called with:', deck)
+ const randomIndex = Math.floor(Math.random() * deck.length)
+ //console.log('card chosen:', randomIndex)
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);
+ 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);
+ 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) {
- log(`Discarded ${power_cards[card].name}`)
if (game.active === COM) {
find_card = game.com_pwr_hand.indexOf(card);
game.com_pwr_hand.splice(find_card, 1);
@@ -1789,45 +2966,104 @@ function discard(card) {
game.dem_pwr_hand.splice(find_card, 1);
}
game.power_struggle_discard.push(card)
+ //log(`Discarded P${power_cards[card].number}`)
}
+
+}
+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)
+ 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 === 2).map(card => card.number)
+ 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')
+ log_h3('Late-year cards added to draw deck')
}
function reset_power() {
- game.power_struggle_deck = power_cards.filter(card => card !== null).map(card => card.number)
+ game.power_struggle_deck = power_cards.filter(card => card !== null && card.number <= 52).map(card => card.number)
game.dem_pwr_hand = []
game.com_pwr_hand = []
- game.respond = 0
+ game.phase = 1
game.raised_stakes_round = 0
- game.raise_stakes = 0
+ game.raised_stakes = 0
+ game.rally_win = 0
+ game.petition_win = 0
game.tactics_fails = ''
+
+ if (game.persistent_events['peasant_parties_revolt']){
+ permanently_remove(72)
+ game.table_cards = game.table_cards.filter(card => card !== 72)
+ game.persistent_events['peasant_parties_revolt'] = false
+ }
+ if (game.persistent_events['yakovlev']) {
+ permanently_remove(62)
+ game.table_cards = game.table_cards.filter(card => card !== 62)
+ game.persistent_events['yakovlev'] = false
+ }
+ if (game.persistent_events['the_crowd_turns_against_ceausescu']){
+ permanently_remove(54)
+ game.table_cards = game.table_cards.filter(card => card !== 54)
+ game.persistent_events['the_crowd_turns_against_ceausescu'] = false
+ }
}
-// === COMMON LIBRARY ===
+function check_control_change(space_id) {
+ game.pieces[space_id].demCtrl = 0
+ game.pieces[space_id].comCtrl = 0
-function shuffle(list) {
- // Fisher-Yates shuffle
- for (let i = list.length - 1; i > 0; --i) {
- let j = random(i + 1)
- let tmp = list[j]
- list[j] = list[i]
- list[i] = tmp
+ if ((game.pieces[space_id].demInfl - game.pieces[space_id].comInfl) >= game.pieces[space_id].stability) {
+ game.pieces[space_id].demCtrl = 1
+ }
+ if ((game.pieces[space_id].comInfl - game.pieces[space_id].demInfl) >= game.pieces[space_id].stability) {
+ game.pieces[space_id].comCtrl = 1
+ }
+
+ // Check if the Tyrant is Gone has been fulfilled
+ if (game.persistent_events['the_tyrant_is_gone'] > 0 && game.pieces[game.persistent_events['the_tyrant_is_gone']].demCtrl === 1) {
+ log('+2 VP from The Tyrant is Gone')
+ game.persistent_events['the_tyrant_is_gone'] = 0
}
- return list
}
+function check_systematisation() {
+ // Check for Systematisation - may not use this space
+ if (game.persistent_events['systematization'] > 0) {
+ game.valid_spaces = game.valid_spaces.filter(n => n !== game.persistent_events['systematization'])
+ }
+}
+
+const pluralize = (count, noun, suffix = 's') =>
+ `${count} ${noun}${count !== 1 ? suffix : ''}`
+
// ======== LOG COMMANDS =============
function log(msg) {
@@ -1860,6 +3096,17 @@ function log_h3(msg) {
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)
@@ -1931,127 +3178,4101 @@ function object_copy(original) {
}
-/* =================== EVENTS ================================ */
+/* =================== 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() {
+ 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_return() {
+ /* let return_vm = game.vm.return_vm;
+ console.log('in vm_return')
+
+ // Return control to the phasing player
+ if (return_vm) {
+ game.vm = return_vm;
+ vm_next();
+ } else {
+ // End of VM execution, return to normal game state
+ game.state = "play_card";
+ } */
+
+ game.support_check_modifier = 0
+ game.view_opp_hand = false
+ console.log('in vm_return, game.vm_return:', game.vm_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_valid_spaces () {
+ //vm_assert_argcount(6)
+ 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 Systematisation - may not use this space
+ check_systematisation()
+
+ vm_next()
+}
+
+function vm_valid_spaces_opponent () {
+ let valid_spaces = []
+ if (game.active === DEM) {
+ for (let i = 1; i < game.pieces.length; i++) {
+ let gamePiece = game.pieces[i]
+
+ if (gamePiece.comInfl > 0) {
+ valid_spaces.push(gamePiece.space_id)
+ }
+ }
+ } else {
+ for (let i = 1; i < game.pieces.length; i++) {
+ let gamePiece = game.pieces[i]
+
+ if (gamePiece.demInfl > 0) {
+ valid_spaces.push(gamePiece.space_id)
+ }
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
+
+function vm_valid_spaces_socio () {
+ let valid_spaces = []
+ for (let i = 1; i < game.pieces.length; i++) {
+ let gamePiece = game.pieces[i]
+ let space = spaces[i]
+
+ if (space.socio === vm_operand(1)) {
+ valid_spaces.push(gamePiece.space_id)
+ }
+ }
+ game.valid_spaces = valid_spaces
+
+ // Check for Systematisation - may not use this space
+ if (game.persistent_events['systematization'] > 0) {
+ game.valid_spaces = game.valid_spaces.filter(n => n !== game.persistent_events['systematization'])
+ }
+ vm_next()
+}
+
+function vm_valid_spaces_opponent_socio () {
+ let valid_spaces = []
+ if (game.active === DEM) {
+ for (let i = 1; i < game.pieces.length; i++) {
+ let gamePiece = game.pieces[i]
+ let space = spaces[i]
+
+ if (gamePiece.comInfl > 0 && space.socio === vm_operand(1)) {
+ valid_spaces.push(gamePiece.space_id)
+ }
+ }
+ } else {
+ for (let i = 1; i < game.pieces.length; i++) {
+ let gamePiece = game.pieces[i]
+ let space = spaces[i]
+
+ if (gamePiece.demInfl > 0 && space.socio === vm_operand(1)) {
+ valid_spaces.push(gamePiece.space_id)
+ }
+ }
+ }
+ game.valid_spaces = valid_spaces
+ // Check for Systematisation - may not use this space
+ if (game.persistent_events['systematization'] > 0) {
+ game.valid_spaces = game.valid_spaces.filter(n => n !== game.persistent_events['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 Systematisation - may not use this space
+ if (game.persistent_events['systematization'] > 0) {
+ game.valid_spaces = game.valid_spaces.filter(n => n !== game.persistent_events['systematization'])
+ }
+ vm_next()
+}
+
+function vm_valid_spaces_sc () {
+ let valid_spaces = []
+ for (let space of game.pieces) {
+ if (!space) continue
+ if (game.active === DEM) {
+ if (space.comInfl >0) {
+ valid_spaces.push(space.space_id);
+ }
+ } else {
+ if (space.demInfl >0) {
+ valid_spaces.push(space.space_id);
+ }
+ if (game.persistent_events['civic_forum']) {
+ if (space.space_id === 31) {continue}
+ }
+ if (game.persistent_events['we_are_the_people']) {
+ if (space.space_id === 9) {continue}
+ }
+ }
+ }
+ game.valid_spaces = valid_spaces
+ if (game.persistent_events['foreign_currency_debt_burden'] !== '') {
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country !== game.persistent_events['foreign_currency_debt_burden'])
+ }
+ 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.pieces[space.space_id].comInfl >0) {
+ game.valid_spaces.push(space.space_id);
+ }
+ } else {
+ if (space.country === country && game.pieces[space.space_id].demInfl >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.pieces[space.space_id].comInfl >0) {
+ valid_spaces.push(space.space_id);
+ }
+ } else {
+ if (space.country === country && game.pieces[space.space_id].demInfl >0) {
+ if (game.persistent_events['solidarity_legalised'] && space.space_id === 14) {continue}
+ if (game.persistent_events['civic_forum'] && space.space_id === 31) {continue}
+ if (game.persistent_events['we_are_the_people'] && space.space_id === 9) {continue}
+ valid_spaces.push(space.space_id);
+ }
+ }
+ }
+ game.valid_spaces = valid_spaces
+
+ if (!game.is_pwr_struggle && game.persistent_events['foreign_currency_debt_burden'] !== '') {
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country !== game.persistent_events['foreign_currency_debt_burden'])
+ }
+ vm_next()
+}
+
+function vm_valid_spaces_country_socio_2() {
+ let valid_spaces = []
+ for (let space of spaces) {
+ if (!space) continue
+ if ((space.country === vm_operand(1) && space.socio === vm_operand(2)) || (space.country === vm_operand(1) && space.socio === vm_operand(3))) {
+ valid_spaces.push(space.space_id);
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
+
+function vm_valid_spaces_region_socio() {
+ let valid_spaces = []
+ for (let space of spaces) {
+ if (!space) 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.pieces[s].comInfl > 0 ) || (game.active === COM && space.region === vm_operand(1) && game.pieces[s].demInfl > 0 )) {
+ valid_spaces.push(space.space_id);
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
-global.event_1 = function() {console.log('event 1 called')}
-global.event_2 = function() {console.log('event 2 called')}
-global.event_3 = function() {console.log('event 3 called')}
-global.event_4 = function() {console.log('event 4 called')}
-global.event_5 = function() {console.log('event 5 called')}
-global.event_6 = function() {console.log('event 6 called')}
-global.event_7 = function() {console.log('event 7 called')}
-global.event_8 = function() {console.log('event 8 called')}
-global.event_9 = function() {console.log('event 9 called')}
-global.event_10 = function() {console.log('event 10 called')}
-global.event_11 = function() {console.log('event 11 called')}
-global.event_12 = function() {console.log('event 12 called')}
-global.event_13 = function() {console.log('event 13 called')}
-global.event_14 = function() {console.log('event 14 called')}
-global.event_15 = function() {console.log('event 15 called')}
-global.event_16 = function() {console.log('event 16 called')}
-global.event_17 = function() {console.log('event 17 called')}
-global.event_18 = function() {console.log('event 18 called')}
-global.event_19 = function() {console.log('event 19 called')}
-global.event_20 = function() {console.log('event 20 called')}
-global.event_21 = function() {console.log('event 21 called')}
-global.event_22 = function() {console.log('event 22 called')}
-global.event_23 = function() {console.log('event 23 called')}
-global.event_24 = function() {console.log('event 24 called')}
-global.event_25 = function() {console.log('event 25 called')}
-global.event_26 = function() {console.log('event 26 called')}
-global.event_27 = function() {console.log('event 27 called')}
-global.event_28 = function() {console.log('event 28 called')}
-global.event_29 = function() {console.log('event 29 called')}
-global.event_30 = function() {console.log('event 30 called')}
-global.event_31 = function() {console.log('event 31 called')}
-global.event_32 = function() {console.log('event 32 called')}
-global.event_33 = function() {console.log('event 33 called')}
-global.event_34 = function() {console.log('event 34 called')}
-global.event_35 = function() {console.log('event 35 called')}
-global.event_36 = function() {console.log('event 36 called')}
-global.event_37 = function() {console.log('event 37 called')}
-global.event_38 = function() {console.log('event 38 called')}
-global.event_39 = function() {console.log('event 39 called')}
-global.event_40 = function() {console.log('event 40 called')}
-global.event_41 = function() {console.log('event 41 called')}
-global.event_42 = function() {console.log('event 42 called')}
-global.event_43 = function() {console.log('event 43 called')}
-global.event_44 = function() {console.log('event 44 called')}
-global.event_45 = function() {console.log('event 45 called')}
-global.event_46 = function() {console.log('event 46 called')}
-global.event_47 = function() {console.log('event 47 called')}
-global.event_48 = function() {console.log('event 48 called')}
-global.event_49 = function() {console.log('event 49 called')}
-global.event_50 = function() {console.log('event 50 called')}
-global.event_51 = function() {console.log('event 51 called')}
-global.event_52 = function() {console.log('event 52 called')}
-global.event_53 = function() {console.log('event 53 called')}
-global.event_54 = function() {console.log('event 54 called')}
-global.event_55 = function() {console.log('event 55 called')}
-global.event_56 = function() {console.log('event 56 called')}
-global.event_57 = function() {console.log('event 57 called')}
-global.event_58 = function() {console.log('event 58 called')}
-global.event_59 = function() {console.log('event 59 called')}
-global.event_60 = function() {console.log('event 60 called')}
-global.event_61 = function() {console.log('event 61 called')}
-global.event_62 = function() {console.log('event 62 called')}
-global.event_63 = function() {console.log('event 63 called')}
-global.event_64 = function() {console.log('event 64 called')}
-global.event_65 = function() {console.log('event 65 called')}
-global.event_66 = function() {console.log('event 66 called')}
-global.event_67 = function() {console.log('event 67 called')}
-global.event_68 = function() {console.log('event 68 called')}
-global.event_69 = function() {console.log('event 69 called')}
-global.event_70 = function() {console.log('event 70 called')}
-global.event_71 = function() {console.log('event 71 called')}
-global.event_72 = function() {console.log('event 72 called')}
-global.event_73 = function() {console.log('event 73 called')}
-global.event_74 = function() {console.log('event 74 called')}
-global.event_75 = function() {console.log('event 75 called')}
-global.event_76 = function() {console.log('event 76 called')}
-global.event_77 = function() {console.log('event 77 called')}
-global.event_78 = function() {console.log('event 78 called')}
-global.event_79 = function() {console.log('event 79 called')}
-global.event_80 = function() {console.log('event 80 called')}
-global.event_81 = function() {console.log('event 81 called')}
-global.event_82 = function() {console.log('event 82 called')}
-global.event_83 = function() {console.log('event 83 called')}
-global.event_84 = function() {console.log('event 84 called')}
-global.event_85 = function() {console.log('event 85 called')}
-global.event_86 = function() {console.log('event 86 called')}
-global.event_87 = function() {console.log('event 87 called')}
-global.event_88 = function() {console.log('event 88 called')}
-global.event_89 = function() {console.log('event 89 called')}
-global.event_90 = function() {console.log('event 90 called')}
-global.event_91 = function() {console.log('event 91 called')}
-global.event_92 = function() {console.log('event 92 called')}
-global.event_93 = function() {console.log('event 93 called')}
-global.event_94 = function() {console.log('event 94 called')}
-global.event_95 = function() {console.log('event 95 called')}
-global.event_96 = function() {console.log('event 96 called')}
-global.event_97 = function() {console.log('event 97 called')}
-global.event_98 = function() {console.log('event 98 called')}
-global.event_99 = function() {console.log('event 99 called')}
-global.event_100 = function() {console.log('event 100 called')}
-global.event_101 = function() {console.log('event 101 called')}
-global.event_102 = function() {console.log('event 102 called')}
-global.event_103 = function() {console.log('event 103 called')}
-global.event_104 = function() {console.log('event 104 called')}
-global.event_105 = function() {console.log('event 105 called')}
-global.event_106 = function() {console.log('event 106 called')}
-global.event_107 = function() {console.log('event 107 called')}
-global.event_108 = function() {console.log('event 108 called')}
-global.event_109 = function() {console.log('event 109 called')}
-global.event_110 = function() {console.log('event 110 called')}
-
-
-function call_event(card) {
- const event_function = `event_${card}`
- console.log('checking for function: ', event_function)
- console.log('available function: ', Object.keys(global))
- if (typeof global[event_function] === 'function') {
- global[event_function]();
+function vm_valid_spaces_solidarity_legalised() {
+ let valid_spaces = []
+ for (let space of spaces) {
+ if (!space) continue
+ let uncontrolled = game.pieces[space.space_id].demCtrl === 0 && game.pieces[space.space_id].comCtrl === 0
+ 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'
+}
+
+function vm_take_control(space) {
+ let clicked_space = find_space_index(space)
+ if (game.active === DEM) {
+ let current_infl = game.pieces[clicked_space].demInfl
+ let opponent_infl = game.pieces[clicked_space].comInfl
+ let stability = spaces[clicked_space].stability
+
+ if ((current_infl - opponent_infl) < stability) {
+ game.pieces[clicked_space].demInfl += 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.pieces[clicked_space].comInfl
+ let opponent_infl = game.pieces[clicked_space].demInfl
+ let stability = spaces[clicked_space].stability
+
+ if ((current_infl - opponent_infl) < stability) {
+ game.pieces[clicked_space].comInfl += 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 ${spaces[clicked_space].name_unique}`)
+ vm_next()
+}
+
+
+function vm_do_add_infl(space) {
+ push_undo()
+ const clicked_space = find_space_index(space)
+ log(`Added 1 influence in %${clicked_space}.`)
+
+ if (spaces[clicked_space].country !== 'East_Germany'){
+ game.austria_hungary_border_reopened_tracker = false
+ }
+
+ // Check Genscher
+ if (game.persistent_events['genscher'] && game.active === DEM && spaces[clicked_space].country === 'East_Germany') {
+ game.vm_available_ops--
+ } else if (check_control(clicked_space)) {
+ game.vm_available_ops -= 2
+ } else {
+ game.vm_available_ops--
+}
+
+ // Update influence values
+ if (game.active === COM) {
+ game.pieces[clicked_space].comInfl++
+ } else {
+ game.pieces[clicked_space].demInfl++
+ }
+
+ // Check Austria Hungary Border Reoponed is true and condition has been met
+ if (game.vm_available_ops === 0 && game.active === DEM && game.persistent_events['austria_hungary_border_reopened'] && game.austria_hungary_border_reopened_tracker && !game.austria_hungary_border_reopened) {
+ game.vm_available_ops ++
+ log('+1 influence from Austria-Hungary Border Reopened')
+ game.austria_hungary_border_reopened = true
+ 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
+
+ if (game.vm_available_ops === 1) {
+ if (game.active === DEM) {
+ if (!game.persistent_events['genscher']) {
+ game.valid_spaces = game.valid_spaces.filter(n => game.pieces[n].comCtrl !== 1)
+ } else {
+ game.valid_spaces = game.valid_spaces.filter(n => !(game.pieces[n].comCtrl === 1 && spaces[n].country !== 'East_Germany'))
+ }
+ } else {
+ game.valid_spaces = game.valid_spaces.filter(n => game.pieces[n].demCtrl !== 1)
+ }
+ }
+
+ // Check whether spaces are controlled
+ check_control_change(clicked_space)
+
+ if (game.vm_available_ops === 0) {game.valid_spaces = []}
+ //console.log('game pieces:', game.pieces[clicked_space])
+}
+
+function vm_do_add_infl_free(space) {
+ push_undo()
+ const clicked_space = find_space_index(space)
+ log(`Added 1 influence in %${clicked_space}.`)
+
+ // Update influence values
+ if (game.active === COM) {
+ game.pieces[clicked_space].comInfl++
+ } else {
+ game.pieces[clicked_space].demInfl++
+ }
+ game.vm_available_ops--
+ // Check whether spaces are controlled
+ check_control_change(clicked_space)
+
+ if (game.vm_available_ops === 0) {game.valid_spaces = []}
+ //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} influence in %${clicked_space}.`)
+
+
+ if (game.active === COM) {
+ game.pieces[clicked_space].comInfl += game.vm_available_ops
+ } else {
+ game.pieces[clicked_space].demInfl += 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}.`)
+ 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.pieces[clicked_space].comInfl ++
} else {
- console.error(`Event function ${event_function} not found.`);
+ game.pieces[clicked_space].demInfl ++
+ }
+
+ 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}.`)
+
+
+ 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.pieces[clicked_space].demInfl--
+ if (game.pieces[clicked_space].demInfl === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
+ }
+ } else {
+ game.pieces[clicked_space].comInfl--
+ if (game.pieces[clicked_space].comInfl === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
+ }
+ }
+
+
+ } else {
+ if (game.active === COM) {
+ game.pieces[clicked_space].comInfl--
+ if (game.pieces[clicked_space].comInfl === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space);
+ }
+ } else {
+ game.pieces[clicked_space].demInfl--
+ if (game.pieces[clicked_space].demInfl === 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)
+ log(`Removed ${game.vm_available_ops} influence from %${clicked_space}.`)
+
+ if (game.remove_opponent_infl) {
+ if (game.active === COM) {
+ game.pieces[clicked_space].demInfl -= game.vm_available_ops
+ } else {
+ game.pieces[clicked_space].comInfl -= game.vm_available_ops
+ }
+ } else {
+ if (game.active === COM) {
+ game.pieces[clicked_space].comInfl -= game.vm_available_ops
+ } else {
+ game.pieces[clicked_space].demInfl -= game.vm_available_ops
+ }
+ }
+
+ 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 influence 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.pieces[clicked_space].demInfl --
+ if (game.pieces[clicked_space].demInfl === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== clicked_space)
+ }
+ } else {
+ game.pieces[clicked_space].comInfl --
+ if (game.pieces[clicked_space].comInfl === 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)
+}
+
+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 influence from %${clicked_space}.`)
+
+ if (game.remove_opponent_infl === true) {
+ if (game.active === COM) {
+ game.pieces[clicked_space].demInfl = 0
+ } else {
+ game.pieces[clicked_space].comInfl = 0
+ }
+ check_control_change(clicked_space)
+
+ } else {
+ if (game.active === COM) {
+ game.pieces[clicked_space].comInfl = 0
+ } else {
+ game.pieces[clicked_space].demInfl = 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.pieces[space_id].demInfl += game.pieces[space_id].comInfl
+ game.pieces[space_id].comInfl = 0
+ } else {
+ game.pieces[space_id].comInfl += game.pieces[space_id].demInfl
+ game.pieces[space_id].demInfl = 0
+ }
+ check_control_change(space_id)
+}
+
+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.pieces[clicked_space].demInfl -= game.vm_available_ops
+ game.pieces[clicked_space].comInfl += game.vm_available_ops
+ log(`Replaced ${game.vm_available_ops} influence 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')
+ check_vp()
+ vm_next()
+}
+
+function vm_adamec() {
+ game.state = 'vm_adamec'
+}
+
+function vm_army_backs_revolution() {
+ game.persistent_events['securitate'] = false
+ game.playable_cards[70].playable = 0
+ vm_next()
+}
+
+function vm_austria_hungary_border_reopened() {
+ game.persistent_events['austria_hungary_border_reopened'] = true
+ game.austria_hungary_border_reopened = false
+ game.austria_hungary_border_reopened_tracker = true
+ game.table_cards.push(58)
+ vm_next()
+}
+
+function vm_betrayal() {
+ if (game.pieces[58].demInfl > 0 ) { game.valid_spaces.push(58) }
+ if (game.pieces[65].demInfl >0 ) { game.valid_spaces.push(65) }
+ game.vm_available_ops = Math.max(game.pieces[58].demInfl, game.pieces[65].demInfl)
+ game.state = 'vm_switch_infl'
+}
+
+function vm_breakaway_baltic_republics() {
+ log('+5 VP')
+ game.vp += 5
+ game.stability++
+ check_vp()
+ game.playable_cards[109].playable = 1
+ game.playable_cards[14].playable = 0
+ if (game.pieces[56].demCtrl === 0) {game.valid_spaces.push(56)}
+ if (game.pieces[70].demCtrl === 0) {game.valid_spaces.push(70)}
+ vm_next()
+}
+
+function vm_brought_in_for_questioning() {
+ if (game.active === COM) {
+ game.active = DEM
+ game.return = game.active
+ }
+ 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')
+ check_vp()
+ if (game.pieces[70].demInfl > 0) {game.valid_spaces = [70]}
+ vm_next()
+}
+
+function vm_ceausescu() {
+ let adj_cluj = false
+ if (game.pieces[50].demInfl > 0 ) {adj_cluj = true}
+ if (game.pieces[54].demInfl > 0 ) {adj_cluj = true}
+ if (game.pieces[58].demInfl > 0 ) {adj_cluj = true}
+ if (game.pieces[61].demInfl > 0 ) {adj_cluj = true}
+
+ if (adj_cluj && game.pieces[61].comInfl>0) {
+ game.valid_spaces = [61]
+ game.vm_available_ops = 1
+ next_player()
+ 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++
+ check_vp()
+ game.persistent_events['civic_forum'] = true
+ if (game.pieces[31].demCtrl === 1) {
+ 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'
+}
+
+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 && game.playable_cards[c].playable === 1) {
+ 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['eco_glasnost'] = true
+ permanently_remove(39)
+ vm_next()
+}
+
+function vm_elena(){
+ game.persistent_events['elena'] = true
+ game.table_cards.push(101)
+ vm_next()
+}
+
+function vm_eliminate(space_id) {
+ log(`Eliminated ${spaces[space_id].name}`)
+ const adjacent_spaces = spaces[space_id].adjacent.filter(Number.isInteger);
+
+ // 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);
+ });
+
+ // Connect adjacent spaces to each other
+ for (let i = 0; i < adjacent_spaces.length; i++) {
+ for (let j = i + 1; j < adjacent_spaces.length; j++) {
+ 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]);
+ }
+ }
+ }
+
+ // Clear the adjacency list of the clicked space
+ game.pieces[space_id].adjacent = [];
+
+ // Eliminate the democrat influence and move the communist influence to Bucharesti
+ game.pieces[space_id].demInfl = 0
+ game.pieces[61].comInfl += game.pieces[space_id].comInfl
+ log(`${game.pieces[space_id].comInfl} relocated to Bucharesti`)
+ game.pieces[space_id].comInfl = 0
+ check_control_change(space_id)
+
+ }
+
+function vm_exit_visas() {
+ game.state = 'vm_exit_visas'
+}
+
+function vm_foreign_currency_debt_burden() {
+ log('+1VP')
+ game.vp++
+ check_vp()
+ game.table_cards.push(49)
+ game.state = 'vm_foreign_currency_debt_burden'
+}
+
+function vm_foreign_television() {
+ for (let piece of game.pieces) {
+ if (!piece) continue
+ if (piece.space_id === 12) {continue} /*Does not apply to Dresden*/
+ if (piece.comInfl > 0 ) {
+ game.valid_spaces.push(piece.space_id)
+ }
+ }
+ vm_next()
+}
+function vm_frg_embassies() {
+ game.persistent_events['frg_embassies'] = true
+ game.table_cards.push(74)
+ vm_next()
+}
+
+function vm_general_strike() {
+ game.persistent_events['general_strike'] = true
+ game.table_cards.push(5)
+ vm_next()
+}
+
+function vm_genscher() {
+ game.persistent_events['genscher'] = true
+ game.table_cards.push(63)
+ log(`C63 in effect`)
+ vm_next()
+}
+
+function vm_goodbye_lenin() {
+ game.view_opp_hand = true
+ // 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)
+ }
+ console.log('game.communist_hand_red', game.communist_hand_red)
+ }
+ //Check if these cards are playabl
+ for (let card of game.communist_hand_red) {
+ if (game.playable_cards[card].playable === 1) {
+ game.valid_cards.push(card)
+ }
+ }
+ console.log('valid_cards', game.valid_cards)
+ game.state = 'vm_goodbye_lenin'
+}
+
+function vm_government_resigns() {
+ for (let space of game.pieces) {
+ if (space && spaces[space.space_id].socio === 1 && space.comInfl > 0 && space.comCtrl === 0 && space.demCtrl === 0) {
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ game.remove_opponent_infl = true
+ vm_next()
+}
+
+function vm_grenztruppen() {
+ console.log('in grenztruppen - player active:', game.active)
+ game.persistent_events['grenztruppen'] = true
+ game.table_cards.push(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
+ log(`${change_vp} VP`)
+ game.vp += change_vp
+ check_vp()
+ vm_next()
+}
+
+function vm_helsinki_final_act() {
+ game.persistent_events['helsinki_final_act'] = true
+ vm_next()
+}
+
+function vm_honecker() {
+ game.persistent_events['honecker'] = true
+ game.discard = true
+ game.valid_cards = []
+ for (let c of game.strategy_discard) {
+ if (scoring_cards.includes(c)) {
+ continue}
+ else {
+ game.valid_cards.push(c)
+ }
+ }
+ game.state = 'vm_honecker'
+}
+
+function vm_inflationary_currency() {
+ game.state = 'vm_inflationary_currency'
+}
+
+function vm_inflationary_currency_discard() {
+ for (let card of game.communist_hand){
+ if (game.persistent_events['perestroika']) {
+ if (cards[card].ops >= 2) {
+ game.valid_cards.push(card)
+ }
+ } else if (game.persistent_events['prudence'] === COM ) {
+ if (cards[card].ops >= 4) {
+ game.valid_cards.push(card)
+ }
+ } else {
+ if (cards[card].ops >= 3) {
+ game.valid_cards.push(card)
+ }
+ }
+ }
+ next_player()
+ game.state = 'vm_inflationary_currency_discard'
+}
+
+function vm_kiss_of_death() {
+ game.state = 'vm_kiss_of_death'
+}
+
+function vm_klaus_and_komarek() {
+ if (game.pieces[29].comInfl > 0 ) {game.valid_spaces = [29]}
+ vm_next()
+}
+
+function vm_kohl_proposes_reunification() {
+ log('+2 VP')
+ game.vp += 2
+ check_vp()
+ if (game.persistent_events['the_wall_must_go']) {
+ game.temp = 87
+ game.state = 'vm_common_european_home'
+ } else {
+ permanently_remove(87)
+ vm_return()
+ }
+
+}
+
+function vm_kremlin_coup() {
+ log('-3 VP')
+ game.vp -= 3
+ check_vp()
+
+ elite_spaces.forEach(space => {
+ if (revolutions[spaces[space].country]) {
+ game.valid_spaces.push(space);
+ }
+ })
+ game.state = 'vm_kremlin_coup_take_control'
+}
+
+function vm_laszlo_tokes() {
+ game.playable_cards[107].playable = 1
+ 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 space of game.pieces) {
+ if (space && (space.comCtrl === 0 && spaces[space.space_id].country === 'Czechoslovakia')) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ vm_next()
+}
+
+function vm_li_peng() {
+ game.persistent_events['li_peng'] = true
+ game.table_cards.push(53)
+ vm_next()
+}
+
+function vm_ligachev() {
+ game.persistent_events['ligachev'] = true
+ vm_next()
+}
+
+function vm_malta_summit() {
+ game.state = 'vm_malta_summit'
+}
+
+function vm_modrow() {
+ game.playable_cards[15].playable = 0
+ game.state = 'vm_modrow'
+}
+
+function vm_national_salvation_front() {
+ game.persistent_events['national_salvation_front'] = true
+ game.table_cards.push(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.pieces[27].demInfl >0) {game.valid_spaces.push(27)}
+ if (game.pieces[29].demInfl > 0) {game.valid_spaces.push(29)}
+ game.remove_opponent_infl = true
+ vm_next()
+}
+
+function vm_peasant_parties_revolt() {
+ game.persistent_events['peasant_parties_revolt'] = true
+ log_msg_gap('C72 in effect')
+ game.table_cards.push(72)
+ vm_next()
+}
+
+function vm_perestroika() {
+ game.persistent_events['perestroika'] = true
+ 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' && game.pieces[space.space_id].demCtrl === 0) {
+ valid_spaces.push(space.space_id);
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
+
+function vm_power_struggle() {
+ game.is_pwr_struggle = true
+
+ //Check if Power Struggle is because of an event
+ if (game.vm_event > 0) {
+ game.pwr_struggle_in = countries[scoring_cards.indexOf(game.vm_event)]
+ }
+
+ //Otherwise set Power Struggle country normally
+ else {
+ game.pwr_struggle_in = countries[scoring_cards.indexOf(game.played_card)]
+ }
+
+ //Check for Securitate
+ if (game.pwr_struggle_in === 'Romania' && game.persistent_events['securitate']) {
+ game.view_opp_hand = true
+ }
+ game.state = 'draw_power_cards'
+}
+
+function vm_presidential_visit() {
+ game.persistent_events['presidential_visit'] = true
+ game.table_cards.push(65)
+ vm_next()
+}
+
+function vm_prudence() {
+ if (game.active === DEM) {
+ game.persistent_events['prudence'] = COM
+ } else {game.persistent_events['prudence'] = DEM}
+ log_msg_gap('C8 in effect')
+ vm_next()
+}
+
+function vm_public_against_violence() {
+ game.valid_spaces = []
+ if (game.pieces[34].comInfl > 0 ) {game.valid_spaces.push(34)}
+ vm_next()
+}
+
+function vm_reformer_rehabilitated () {
+ 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['roundtable_talks'] = true
+ game.table_cards.push(17)
+ log_msg_gap('C17 in effect')
+ vm_next()
+}
+
+function vm_sajudis() {
+ game.playable_cards[81].playable = 1
+ game.stability++
+ log('+1 VP')
+ game.vp++
+ check_vp()
+ vm_next()
+}
+
+function vm_samizdat() {
+ game.state = 'vm_samizdat'
+}
+
+function vm_securitate() {
+ game.persistent_events['securitate'] = true
+ 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[3].playable = 1
+ game.persistent_events['solidarity_legalised'] = true
+ vm_next()
+}
+
+function vm_st_nicholas_church () {
+ game.persistent_events['st_nicholas_church'] = true
+ game.playable_cards[61].playable = 1
+ permanently_remove(24)
+ vm_next()
+}
+
+function vm_stasi() {
+ log_msg_gap('C13 in effect')
+ game.persistent_events['stasi'] = true
+ vm_next()
+}
+
+function vm_stand_fast() {
+ if (game.active === DEM) {
+ game.persistent_events['stand_fast'] = DEM
+ } else {game.persistent_events['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++
+ } else {game.com_tst_position++}
+ vm_next()
+}
+
+function vm_tear_gas () {
+ game.persistent_events['tear_gas']= true
+ game.table_cards.push(30)
+ log_msg_gap('C30 in effect')
+ vm_next()
+}
+
+function vm_the_baltic_way() {
+ game.playable_cards[84].playable = 1
+ game.stability++
+ if (game.pieces[56].demCtrl === 0) {game.valid_spaces.push(56)}
+ if (game.pieces[70].demCtrl === 0) {game.valid_spaces.push(70)}
+ log('+3 VP')
+ game.vp += 3
+ check_vp()
+ vm_next()
+}
+
+function vm_the_chinese_solution() {
+ game.state = 'vm_the_chinese_solution'
+}
+
+function vm_the_crowd_turns_against_ceausescu() {
+ game.persistent_events['the_crowd_turns_against_ceausescu'] = true
+ game.table_cards.push(54)
+ vm_next()
+}
+
+function vm_the_monday_demonstrations() {
+ if (game.pieces[6].demCtrl === 0) {game.valid_spaces.push(6)}
+ if (game.pieces[9].demCtrl === 0) {game.valid_spaces.push(9)}
+ vm_next()
+}
+
+function vm_the_sintra_doctrine() {
+ game.persistent_events['sinatra_doctrine'] = true
+ 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 space of game.pieces) {
+ if (space && space.demInfl === 0 && spaces[space.space_id].country === 'Romania') {
+ if (space.space_id === game.persistent_events['systematization']) {continue}
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ game.playable_cards[107] = 0
+ game.state = 'vm_the_tyrant_is_gone'
+}
+
+function vm_the_wall () {
+ game.persistent_events['the_wall']= true
+ 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
+ game.state = 'vm_warsaw_pact_summit'
+}
+
+function vm_we_are_the_people() {
+ if (game.pieces[6].demInfl > 0) {game.valid_spaces = [6]}
+ game.persistent_events['we_are_the_people'] = true
+ 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[`${country}`] && game.pieces[space.space_id].comInfl > 0 && space.socio === 4) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ } else {
+ for (let space of spaces) {
+ let country = space.country
+ if (game.revolutions[`${country}`] && game.pieces[space.space_id].demInfl > 0 && space.socio === 4) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ }
+ game.state = 'vm_workers_revolt'
+}
+
+function vm_yakovlev_counsels_gorbachev() {
+ game.persistent_events['yakovlev'] = true
+ game.table_cards.push(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
+ if (game.vm_event !== 0) {
+ permanently_remove(game.vm_event)
+ }
+ if (game.played_card !== 21) {
+ permanently_remove(game.played_card)
+ } /*This means the card that called the event being played is also removed. Is there ever a time when this is a problem? Common European Home fix added */
+ 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'
+}
+
+
+/* ================== VM STATES ============================== */
+
+states.vm_take_control = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt () {
+ if (game.valid_spaces.length === 0) {
+ view.prompt = 'All spaces already controlled. Continue.'
+ gen_action('done')
+ } else if (game.vm_available_ops > 0 ) {
+ view.prompt = 'Select a space to take control.'
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) {*/
+ gen_action_infl(spaces[space_id].name_unique);
+ //}
+ }
+ } else {
+ view.prompt = 'Done'
+ gen_action('done')
+ }
+ },
+ infl(space) {
+ vm_take_control(space)
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_add_infl = {
+ inactive: 'add influence.',
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) {
+ view.prompt = 'No available spaces remaining. Add influence: done.'
+ gen_action('done')
+ }
+ else if (game.vm_available_ops > 0 ) {
+ view.prompt = `Add influence. ${game.vm_available_ops} remaining.`
+
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) {*/
+ gen_action_infl(spaces[space_id].name_unique);
+ //}
+ }
+ } else {
+ view.prompt = 'Add influence: done.'
+ gen_action('done')
+ }
+ },
+ infl(space) {
+ vm_do_add_infl(space)
+ },
+ done () {
+ game.vm_event_done = true
+ vm_next()
+ }
+}
+
+states.vm_add_infl_free = {
+ inactive: 'add influence.',
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) {
+ view.prompt = 'No available spaces remaining. Add influence: done.'
+ gen_action('done')
+ }
+ else if (game.vm_available_ops > 0 ) {
+ view.prompt = `Add influence. ${game.vm_available_ops} remaining.`
+
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) {*/
+ gen_action_infl(spaces[space_id].name_unique);
+ //}
+ }
+ } else {
+ view.prompt = 'Add influence: done.'
+ gen_action('done')
+ }
+ },
+ infl(space) {
+ vm_do_add_infl_free(space)
+ },
+ done () {
+ game.vm_event_done = true
+ vm_next()
+ }
+}
+
+states.vm_add_x_infl = {
+ inactive: 'add influence.',
+ prompt () {
+ if (game.vm_available_ops > 0 ) {
+ view.prompt = `Add ${game.vm_available_ops} influence.`
+
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) {*/
+ gen_action_infl(spaces[space_id].name_unique);
+ //}
+ }
+ } else {
+ view.prompt = 'Done'
+ gen_action('done')
+ }
+ },
+ infl(space) {
+ vm_do_add_x_infl(space)
+ },
+ done () {
+ game.vm_event_done = true
+ vm_next()
+ }
+}
+
+states.vm_add_limited_infl = {
+ inactive: 'add influence.',
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) {
+ view.prompt = `Add influence. ${game.vm_available_ops} influence remaining.`
+
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) { */
+ gen_action_infl(spaces[space_id].name_unique);
+ //}
+ }
+ } else {
+ view.prompt = 'Done'
+ gen_action('done')
+ }
+ },
+ infl(space) {
+ vm_do_add_limited_infl(space, game.vm_max_infl)
+ },
+ done () {
+ game.vm_event_done = true
+ vm_next()
+ }
+}
+
+states.vm_remove_infl = {
+ inactive: 'remove influence',
+ prompt () {
+ if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
+ view.prompt = 'Remove influence: done.'
+ gen_action('done')
+ return
+ }
+ view.prompt = 'Select a space to remove influence'
+
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) { */
+ gen_action_infl(spaces[space_id].name_unique);
+ //}
+ }
+ },
+ infl(space) {
+ vm_do_remove_infl(space)
+ const clicked_space = find_space_index(space)
+ game.vm_active_country = spaces[clicked_space].country
+ },
+ done() {
+ vm_next()
+ }
+}
+
+
+states.vm_remove_x_infl = {
+ inactive: 'remove influence.',
+ prompt () {
+ if (game.vm_available_ops > 0 ) {
+ view.prompt = `Remove ${game.vm_available_ops} influence.`
+
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) { */
+ gen_action_infl(spaces[space_id].name_unique);
+ //}
+ }
+ } else {
+ view.prompt = 'Remove influence: done'
+ gen_action('done')
+ }
+ },
+ infl(space) {
+ vm_do_remove_x_infl(space)
+ },
+ done () {
+ game.vm_event_done = true
+ vm_next()
+ }
+}
+
+states.vm_remove_limited_infl = {
+ inactive: 'remove influence.',
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) {
+ view.prompt = `Remove influence.`
+
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) { */
+ gen_action_infl(spaces[space_id].name_unique);
+ //}
+ }
+ } else {
+ view.prompt = 'Done'
+ gen_action('done')
+ }
+ },
+ infl(space) {
+ vm_do_remove_limited_infl(space, game.vm_max_infl)
+ },
+ done () {
+ game.vm_event_done = true
+ vm_next()
+ }
+}
+
+states.vm_remove_all_infl = {
+ inactive: 'remove influence',
+ prompt () {
+ if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
+ view.prompt = 'Remove influence: done.'
+ gen_action('done')
+ return
+ }
+ view.prompt = 'Remove influence'
+
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) {*/
+ gen_action_infl(spaces[space_id].name_unique);
+ // }
+ }
+ },
+ infl(space) {
+ vm_do_remove_all_infl(space)
+ const clicked_space = find_space_index(space)
+ game.vm_active_country = spaces[clicked_space].country
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_support_check_prep = {
+ inactive: 'do support check',
+ prompt () {
+ if (game.vm_available_ops === 0) {
+ view.prompt = 'Support check: done'
+ gen_action('done')
+ } else if (game.valid_spaces.length === 0) {
+ view.prompt = 'No valid targets for support check.'
+ gen_action('done')
+ } else {
+ 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) {
+ 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 = `Target: ${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 ${cards[88].name}.`
+ },
+ prompt() {
+ view.prompt = '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 && game.pieces[space.space_id].demCtrl === 1).length
+ if (worker_spaces > 0) {
+ log(`-${worker_spaces} from Democrat controlled worker spaces`)
+ roll -= worker_spaces
+ }
+ if (roll > 2) {
+ log('Adamec succeeds')
+ vm_next()
+ return
+ }
+ log('Adamec fails: modified 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('done')
+ } else {
+ view.prompt = 'Brought in for Questioning. You must discard a card.'
+ gen_action('discard')
+ }
+ },
+ discard() {
+ game.temp = discard_card(game.democrat_hand)
+ game.phase = 1
+ if (cards[game.temp].side === 'C') {
+ game.return = game.active
+ if (!auto_resolve_events.includes(game.temp)) {
+ next_player()
+ }
+ goto_vm(game.temp)
+ }
+ },
+ done() {
+ vm_return()
+ }
+}
+
+states.vm_central_committee_reshuffle = {
+ get inactive() {
+ return `resolve ${cards[57].name}.`
+ },
+ prompt() {
+ view.prompt = 'Choose a country to add influence.'
+ if (!game.revolutions['East_Germany']) {gen_action('east_germany')}
+ if (!game.revolutions['Poland']) {gen_action('poland')}
+ if (!game.revolutions['Czechoslovakia']) {gen_action('czechoslovakia')}
+ if (!game.revolutions['Hungary']) {gen_action('hungary')}
+ if (!game.revolutions['Romania']) {gen_action('romania')}
+ if (!game.revolutions['Bulgaria']) {gen_action('bulgaria')}
+ },
+ east_germany() {game.valid_spaces = [1,2,3,4,5,6,7,8,9,10,11,12]
+ vm_next()
+ },
+ poland() {game.valid_spaces = [13,14,15,16,17,18,19,20,21,22,23,24,25,26]
+ vm_next()
+ },
+ czechoslovakia() {game.valid_spaces = [27,28,29,30,31,32,33,34,35,36,37]
+ vm_next()
+ },
+ hungary() {game.valid_spaces = [38,39,40,41,42,43,44,45,46,47,48,49]
+ vm_next()
+ },
+ romania() {game.valid_spaces = [50,51,52,53,54,55,56,57,58,59,60,61,62,63]
+ vm_next()
+ },
+ bulgaria () {game.valid_spaces = [64,65,66,67,68,69,70,71,72,73,74,75]
+ vm_next()
+ },
+
+}
+
+states.vm_common_european_home = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.temp === 0) {
+ view.prompt = 'Choose a card to play'
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ } else {
+ view.prompt = `Play ${cards[game.temp].name} for:`
+ gen_action('influence')
+ gen_action('support_check')
+ if (game.active === DEM && game.temp === 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')
+ }
+ }
+ },
+ card(card) {
+ log(`Played with C${cards[card].number}`)
+ game.valid_cards = []
+ discard(card)
+ game.temp = card
+ },
+ influence(){
+ push_undo()
+ game.vm_available_ops = cards[game.temp].ops
+ valid_spaces_infl()
+ 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_dash_for_the_west = {
+ get inactive() {
+ return `resolve ${cards[36].name}.`
+ },
+ prompt() {
+ if (game.phase === 1) {
+ view.prompt = '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
+ log(`Rolled a ${roll}`)
+ let com_control = check_presence('East_Germany').com_spaces
+
+ if (roll > com_control) {
+ log(`More than the ${com_control} controlled spaces in East Germany`)
+ log('+1 VP')
+ game.vp++
+ check_vp()
+ game.discard = true
+ game.state = 'vm_play_event_from_discard'
+ } else {
+ log(`Fail: more than a ${com_control} required`)
+ game.phase++
+ }
+ clear_undo()
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_play_event_from_discard = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.valid_cards.length === 0) {
+ view.prompt = 'No valid cards in discard.'
+ gen_action('done')
+ } else if (game.temp === 0) {view.prompt = 'Choose a card. Event occurs immediately.'
+ for (let card of game.valid_cards) {
+ 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
+ console.log('card:', card)
+ if (switch_events.includes(card)) {next_player()}
+ goto_vm(card)
+ },
+ done(){
+ game.discard = false
+ vm_next()
+ }
+}
+
+states.vm_deutsche_marks_prep = {
+ inactive: 'choose a card.',
+ prompt() {
+ view.prompt = 'Choose a card to give.'
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ },
+ card(card) {
+ log(`Gave C${cards[card].number}`)
+ game.valid_cards = []
+ discard(card)
+ next_player()
+ game.state = 'vm_deutsche_marks'
+ game.temp = card
+ }
+}
+
+states.vm_deutsche_marks = {
+ get inactive() {
+ return `resolve ${cards[20].name}.`
+ },
+ prompt() {
+ if(cards[game.temp].side === 'C' && game.playable_cards[game.temp].playable === 1) {
+ view.prompt = `You must play ${cards[game.temp].name} for the event.`
+ gen_action('event')
+ } else {
+ view.prompt = 'Play card 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.temp].number} for the event`)
+ game.return === game.active
+ goto_vm(game.temp)
+ },
+ influence() {
+ push_undo()
+ log(`Played C${cards[game.temp].number} for influence`)
+ game.vm_available_ops = cards[game.temp].ops
+ if (game.persistent_events['perestroika']) {game.vm_available_ops++ }
+ valid_spaces_infl()
+ game.state = 'vm_add_infl'
+ },
+ support_check() {
+ push_undo()
+ log(`Played C${cards[game.temp].number} for support checks`)
+ game.vm_available_ops = 2
+ game.state='vm_support_check_prep'
+ valid_spaces_sc()
+ },
+ tst() {
+ push_undo()
+ log(`Played C${cards[game.temp].number} to the Tiananmen Square Track`)
+ game.state='vm_tiananmen_square_attempt'
+ }
+}
+
+states.vm_exit_visas = {
+ get inactive() {
+ return `resolve ${cards[75].name}.`
+ },
+ prompt() {
+ view.prompt = 'You may discard cards from your hand and draw replacements.'
+ for (let card of game.democrat_hand) {
+ gen_action_card(card)
+ }
+ gen_action('done')
+ },
+ card(card){
+ push_undo()
+ discard(card)
+ game.temp++
+ },
+ done() {
+ push_undo()
+ game.state = 'vm_exit_visas_finish'
+ }
+}
+
+states.vm_exit_visas_finish = {
+ get inactive() {
+ return `resolve ${cards[75].name}.`
+ },
+ prompt() {
+ if (game.temp > 0 ) {
+ view.prompt = 'Draw replacement cards.'
+ gen_action('draw')
+ } else {
+ view.prompt = 'Discard cards: 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 ${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() {
+ game.persistent_events['foreign_currency_debt_burden'] = 'East_Germany'
+ log('Selected East Germany')
+ vm_next()
+ },
+ poland() {
+ game.persistent_events['foreign_currency_debt_burden'] = 'Poland'
+ log('Selected Poland')
+ vm_next()
+ },
+ czechoslovakia() {
+ game.persistent_events['foreign_currency_debt_burden'] = 'Czechoslovakia'
+ log('Selected Czechoslovakia')
+ vm_next()
+ },
+ hungary() {
+ game.persistent_events['foreign_currency_debt_burden'] = 'Hungary'
+ log('Selected Hungary')
+ vm_next()
+ },
+ bulgaria() {
+ game.persistent_events['foreign_currency_debt_burden'] = 'Bulgaria'
+ log('Selected Bulgaria')
+ vm_next()
+ }
+}
+
+states.vm_goodbye_lenin = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ 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) {
+ log(`Chose to play ${cards[card].name} for the event`)
+ let card_index = game.communist_hand.indexOf(card)
+ game.communist_hand.splice(card_index, 1)
+ goto_vm(card)
+ },
+ ops() {
+ game.state = 'vm_goodbye_lenin_ops'
+ }
+}
+
+states.vm_goodbye_lenin_ops = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ view.prompt = `Play ${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()
+ 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 ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.temp === 0) {view.prompt = 'Choose a card to add to your hand.'
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ } else {
+ view.prompt = '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)
+ },
+ done(){
+ game.discard = false
+ vm_next()
+ }
+
+}
+
+states.vm_inflationary_currency = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ view.prompt = 'Choose a country.'
+ if (game.active === DEM) {
+ if (!game.revolutions['East_Germany']) {gen_action('east_germany')}
+ if (!game.revolutions['Poland']) {gen_action('poland')}
+ if (!game.revolutions['Czechoslovakia']) {gen_action('czechoslovakia')}
+ if (!game.revolutions['Hungary']) {gen_action('hungary')}
+ if (!game.revolutions['Romania']) {gen_action('romania')}
+ if (!game.revolutions['Bulgaria']) {gen_action('bulgaria')}
+ } else {
+ if (game.revolutions['East_Germany']) {gen_action('east_germany')}
+ if (game.revolutions['Poland']) {gen_action('poland')}
+ if (game.revolutions['Czechoslovakia']) {gen_action('czechoslovakia')}
+ if (game.revolutions['Hungary']) {gen_action('hungary')}
+ if (game.revolutions['Romania']) {gen_action('romania')}
+ if (game.revolutions['Bulgaria']) {gen_action('bulgaria')}
+ }
+ },
+ east_germany() {game.vm_active_country = 'East_Germany'
+ vm_next()
+ },
+ poland() { game.vm_active_country = 'Poland'
+ vm_next()
+ },
+ czechoslovakia() { game.vm_active_country = 'Czechoslovakia'
+ vm_next()
+ },
+ hungary() { game.vm_active_country = 'Hungary'
+ vm_next()
+ },
+ romania() { game.vm_active_country = 'Romania'
+ vm_next()
+ },
+ bulgaria () { game.vm_active_country = 'Bulgaria'
+ vm_next()
+ },
+}
+
+states.vm_inflationary_currency_discard = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.valid_cards.length === 0 ) {
+ view.prompt = 'No valid cards to discard. You must pass.'
+ gen_action('pass')
+ } else if (game.temp === 0 ) {
+ view.prompt = '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) {
+ game.temp = discard(card)
+ },
+ pass() {
+ log('Did not discard')
+ next_player()
+ game.vm_available_ops = 1
+ vm_next()
+ //game.state = 'vm_support_check_prep'
+ },
+ done() {
+ vm_next()
+ }
+}
+
+
+states.vm_kiss_of_death = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.temp === 0) {
+ view.prompt = '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'
+ },
+}
+
+states.vm_kiss_of_death_finish = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.vm_event > 0 && (cards[game.vm_event].side === 'D' || cards[game.vm_event].side === 'N')) {
+ view.prompt = `Play ${cards[game.vm_event].name} for the event.`
+ gen_action('event')
+ } else {
+ view.prompt = 'Event does not occur.'
+ gen_action('done')
+ }
+ },
+ event() {
+ game.return = game.active
+ goto_vm(game.vm_event)
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_kremlin_coup_take_control = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.valid_spaces.length === 0){
+ view.prompt = 'No spaces remaining. Kremlin Coup: done.'
+ gen_action('done')
+ } else {
+ view.prompt = `Select a country's elite space.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(spaces[space_id].name_unique);
+ }
+ }
+ },
+ infl(space) {
+ vm_take_control(space)
+ game.vm_active_country = spaces[find_space_index(space)].country
+ if (game.vm_active_country = 'East_Germany') {game.temp = 3 }
+ if (game.vm_active_country = 'Poland') {game.temp = 17}
+ if (game.vm_active_country = 'Czechoslovakia') {game.temp = 29}
+ if (game.vm_active_country = 'Hungary') {game.temp = 45}
+ if (game.vm_active_country = 'Romania') {game.temp = 61}
+ if (game.vm_active_country = 'Bulgaria') {game.temp = 68}
+ game.state = 'vm_kremlin_coup_sc_prep'
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_kremlin_coup_sc_prep = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ view.prompt = `Conduct a support check in ${game.vm_active_country}'s Bureaucratic space.`
+ for (let space_id of game.temp) {
+ gen_action_sc(spaces[space_id].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 = `Target: ${spaces[game.selected_space].name_unique}. Roll a die`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_sc(spaces[game.selected_space].name_unique)
+ game.state = 'vm_kremlin_coup_sc_prep'
+ return
+ }
+}
+
+states.vm_laszlo_tokes = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ view.prompt = `Play Laszlo Tokes for:`
+ gen_action('influence')
+ gen_action('support_check')
+ },
+ influence(){
+ push_undo()
+ if (game.persistent_events['sinatra_doctrine']) {
+ log(`+1 op from C50`)
+ game.vm_available_ops = 3
+ } else {
+ game.vm_available_ops = 2
+ }
+ valid_spaces_infl()
+ game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania')
+ 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')
+ }
+}
+
+states.vm_switch_infl = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.vm_available_ops > 0 ) {
+ view.prompt = 'Select a space to replace opponent influence.'
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) { */
+ gen_action_infl(spaces[space_id].name_unique);
+ //}
+ }
+ } else {
+ view.prompt = 'Inluence replaced.'
+ gen_action('done')
+ }
+ },
+ infl(space) {
+ vm_switch_infl(space)
+ if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ }
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_malta_summit = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.phase === 1) {
+ view.prompt = '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`)
+ }
+ if (roll + game.stability > 3) {
+ log('Summit successful')
+ game.vp += 3
+ log('+3 VP')
+ check_vp()
+ if (game.pieces[12].comInfl > 0 ) {game.valid_spaces.push(12)}
+ if (game.pieces[15].comInfl > 0 ) {game.valid_spaces.push(15)}
+ if (game.pieces[27].comInfl > 0 ) {game.valid_spaces.push(27)}
+ if (game.pieces[43].comInfl > 0 ) {game.valid_spaces.push(43)}
+ if (game.pieces[51].comInfl > 0 ) {game.valid_spaces.push(51)}
+ if (game.pieces[69].comInfl > 0 ) {game.valid_spaces.push(69)}
+ game.vm_available_ops = 5
+ game.remove_opponent_infl = true
+ game.state = 'vm_remove_infl'
+ }
+ else {
+ log('Summit failed')
+ game.phase++
+ }
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_modrow = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ view.prompt = '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' && game.pieces[space.space_id].demCtrl === 1).length
+ if (roll > dem_spaces) {
+ log(`Rolled a ${roll}: success`)
+ 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 ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.phase === 1 ) {
+ view.prompt = '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 influence`)
+ game.vm_available_ops = 4}
+ else if (roll < 5 ) {
+ log(`Rolled a ${roll}: adds 3 influence`)
+ game.vm_available_ops = 3}
+ else {
+ log(`Rolled a ${roll}: adds 1 influence`)
+ game.vm_available_ops = 1}
+ game.phase = 2
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_new_years_eve_party = {
+ get inactive() {
+ return `resolve ${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['new_years_eve_party'] = true
+ log('Chooses to end the game. There will be no final scoring')
+ let power = Object.values(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
+ }
+ check_vp()
+ game.table_cards.push(104)
+ vm_next()
+ },
+ continue() {
+ log('Chooses to continue')
+ permanently_remove(104)
+ }
+}
+
+states.vm_nomenklatura = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ view.prompt = 'Choose: remove Democratic influence from an elite space or add influence to an elite space.'
+ gen_action('remove')
+ gen_action('add')
+ },
+ remove() {
+ push_undo()
+ game.valid_spaces = []
+ for (let i = 0; i < game.pieces.length; i++) {
+ let piece = game.pieces[i]
+ let space = spaces[i]
+
+ if (space.socio === 1 && piece.demInfl > 0) {
+ game.valid_spaces.push(piece.space_id)
+ }
+ }
+ game.vm_available_ops = 1
+ 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 ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.vm_available_ops === 0 || game.valid_spaces.length === 0 ) {
+ view.prompt = 'Remove influence: done.'
+ gen_action('done')
+ } else {
+ view.prompt = 'Remove all Democratic influence from an elite space.'
+
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id); */
+ gen_action_infl(spaces[space_id].name_unique);
+ }
+ }
+ },
+ infl(space) {
+ vm_do_remove_all_infl(space)
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_nomenklatura_add = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.vm_available_ops === 0 || game.valid_spaces.length === 0 ) {
+ view.prompt = 'Add influence: done.'
+ gen_action('done')
+ } else {
+ view.prompt = `Add influence to elite spaces. ${game.vm_available_ops} influence remaining.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(spaces[space_id].name_unique);
+ }
+ }
+ },
+ infl(space) {
+ vm_do_add_infl(space)
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_samizdat = {
+ get inactive() {
+ return `resolve ${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('done')
+ },
+ card(card) {
+ push_undo()
+ game.samizdat_card = card
+ game.democrat_hand = game.democrat_hand.filter(c => c !== card)
+ log('Set aside a card')
+ },
+ done() {
+ if (game.samizdat_card > 0) {game.state = 'vm_samizdat_finish'}
+ else {vm_next()}
+ }
+}
+
+states.vm_samizdat_finish = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.phase === 2) {
+ 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))
+ game.phase ++
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_shock_therapy = {
+ get inactive() {
+ return `resolve ${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['East_Germany']) {gen_action('east_germany')}
+ if (game.revolutions['Poland']) {gen_action('poland')}
+ if (game.revolutions['Czechoslovakia']) {gen_action('czechoslovakia')}
+ if (game.revolutions['Hungary']) {gen_action('hungary')}
+ if (game.revolutions['Romania']) {gen_action('romania')}
+ if (game.revolutions['Bulgaria']) {gen_action('bulgaria')}
+ } else if (game.phase === 2) {
+ view.prompt = 'Shock Therapy: done.'
+ gen_action('done')
+ } else {
+ view.prompt = 'Roll a die.'
+ gen_action('roll')
+ }
+ },
+ east_germany() {game.vm_active_country = 'East_Germany'},
+ poland() { game.vm_active_country = 'Poland'},
+ czechoslovakia() { game.vm_active_country = 'Czechoslovakia'},
+ hungary() { game.vm_active_country = 'Hungary'},
+ romania() { game.vm_active_country = 'Romania'},
+ bulgaria () { game.vm_active_country = 'Bulgaria'},
+ roll() {
+ clear_undo()
+ let roll = Math.floor(Math.random() * 6) + 1
+ log(`Rolled a ${roll}`)
+ for (let space of game.pieces) {
+ if (space && space.country === game.vm_active_country && space.comCtrl === 1 && (space.socio === 3 || space.socio === 4)) {
+ game.temp++
+ }
+ }
+ log(`-${game.temp} from Communist controlled Worker and Farmer spaces`)
+ log(`Modified roll: ${roll - game.temp}`)
+ if ((roll - game.temp) > 2) {
+ log('Shock Therapy is successful. +3 VP')
+ vm_next()
+ } else {
+ log('Shock Therapy is unsuccessful. Required 3 or more')
+ game.phase++
+ }
+ },
+ done() {
+ permanently_remove(93)
+ vm_return()
+ }
+}
+
+states.vm_social_democratic_platform_adopted = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ view.prompt = 'Select a country where the Democrat holds Power.'
+ if (game.revolutions['East_Germany']) {gen_action('east_germany')}
+ if (game.revolutions['Poland']) {gen_action('poland')}
+ if (game.revolutions['Czechoslovakia']) {gen_action('czechoslovakia')}
+ if (game.revolutions['Hungary']) {gen_action('hungary')}
+ if (game.revolutions['Romania']) {gen_action('romania')}
+ if (game.revolutions['Bulgaria']) {gen_action('bulgaria')}
+ },
+ east_germany() {
+ game.vm_active_country = 'East_Germany'
+ vm_next()
+ },
+ poland() {
+ game.vm_active_country = 'Poland'
+ vm_next()},
+ czechoslovakia() {
+ game.vm_active_country = 'Czechoslovakia'
+ vm_next()},
+ hungary() {
+ game.vm_active_country = 'Hungary'
+ vm_next()
+ },
+ romania() {
+ game.vm_active_country = 'Romania'
+ vm_next()
+ },
+ bulgaria () {
+ game.vm_active_country = 'Bulgaria'
+ vm_next()}
+}
+
+states.vm_systematization = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.persistent_events['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.persistent_events['systematization'] = find_space_index(space)
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_the_chinese_solution = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ view.prompt = 'You may give up 3VP to conduct support checks in a country where you hold power.'
+ if (!game.revolutions['East_Germany']) {gen_action('east_germany')}
+ if (!game.revolutions['Poland']) {gen_action('poland')}
+ if (!game.revolutions['Czechoslovakia']) {gen_action('czechoslovakia')}
+ if (!game.revolutions['Hungary']) {gen_action('hungary')}
+ if (!game.revolutions['Romania']) {gen_action('romania')}
+ if (!game.revolutions['Bulgaria']) {gen_action('bulgaria')}
+ gen_action('pass')
+ },
+ east_germany() {game.vm_active_country = 'East_Germany'
+ log('+3 VP')
+ game.vp += 3
+ check_vp()
+ vm_next()
+ },
+ poland() { game.vm_active_country = 'Poland'
+ log('+3 VP')
+ game.vp += 3
+ check_vp()
+ vm_next()
+ },
+ czechoslovakia() { game.vm_active_country = 'Czechoslovakia'
+ log('+3 VP')
+ game.vp += 3
+ check_vp()
+ vm_next()
+ },
+ hungary() { game.vm_active_country = 'Hungary'
+ log('+3 VP')
+ game.vp += 3
+ check_vp()
+ vm_next()
+ },
+ romania() { game.vm_active_country = 'Romania'
+ log('+3 VP')
+ game.vp += 3
+ check_vp()
+ vm_next()
+ },
+ bulgaria () { game.vm_active_country = 'Bulgaria'
+ log('+3 VP')
+ game.vp += 3
+ check_vp()
+ vm_next()
+ },
+ pass() {
+ permanently_remove(96)
+ vm_return()
+ }
+}
+
+states.vm_the_tyrant_is_gone = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.persistent_events['the_tyrant_is_gone']=== 0) {
+ view.prompt = 'Select a space in Romania.'
+ 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()
+ game.persistent_events['the_tyrant_is_gone'] = find_space_index(space)
+ },
+ done () {
+ vm_next()
+ }
+}
+
+states.vm_the_wall_must_go = {
+ get inactive() {
+ return `resolve ${cards[game.played_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 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' && game.pieces[space.space_id].demCtrl === 1).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' && game.pieces[space.space_id].comCtrl === 1).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']++
+ }
+ game.the_wall_must_go['dem_roll'] = 0
+ game.the_wall_must_go['com_roll'] = 0
+ 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 The Wall Must Go!')
+ return
+ }
+ if (game.the_wall_must_go['com_wins'] === 2) {
+ log('The Communist wins The Wall Must Go!')
+ return
+ }
+ next_player()
+ },
+ done() {
+ if (game.the_wall_must_go['dem_wins'] === 2) {
+ game.persistent_events['the_wall_must_go'] = true
+ log('+3 VP')
+ game.vp += 3
+ check_vp()
+ for (let space of game.pieces) {
+ if (space) {console.log('space.space_id', space.space_id)}
+ if (space && spaces[space.space_id].country === 'East_Germany' && space.comInfl > 0){
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ if (game.active === DEM) {next_player()}
+ vm_next ()
+ } else {
+ permanently_remove(86)
+ vm_return()
+ }
+ }
+}
+
+states.vm_warsaw_pact_summit = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ view.prompt = 'Choose to play for support checks or influence.'
+ gen_action('influence')
+ gen_action('support_check')
+ },
+ influence(){
+ push_undo()
+ for (let space of game.pieces) {
+ if (space && space.demInfl === 0) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ game.vm_available_ops = 4
+ game.state = 'vm_add_infl'
+ },
+ support_check(){
+ push_undo()
+ for (let i = 1; i < game.pieces.length; i++) {
+ let gamePiece = game.pieces[i]
+ let space = spaces[i]
+ if (gamePiece.demInfl > 0 && (space.socio === 5 || space.socio === 6)) {
+ game.valid_spaces.push(gamePiece.space_id)
+ }
+ }
+ game.vm_available_ops = 2
+ game.state = 'vm_support_check_prep'
+ }
+}
+
+states.vm_we_are_the_people_remove = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.pieces[6].demInfl === 0) {
+ view.prompt = 'No influence to remove.'
+ gen_action('done')
+ } else if (game.vm_available_ops > 0 ) {
+ view.prompt = 'Remove up to 4 influence 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 influence: done.'
+ gen_action('done')
+ }
+ },
+ infl(space) {
+ vm_do_remove_infl(space)
+ },
+ done() {
+ if (!game.vm_influence_added[6]) {
+ 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 ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (!game.vm_influence_added[6]) {
+ view.prompt = 'Add influence: done.'
+ gen_action('done')
+ return
+ }
+
+ view.prompt = `You must add the ${game.vm_influence_added[6]} influence to spaces in Germany`
+ gen_action('done')
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);*/
+ gen_action_infl(spaces[space_id].name_unique);
+ }
+ },
+ infl(space) {
+ vm_do_add_infl(space)
+ game.vm_influence_added++
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_workers_revolt = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ view.prompt = 'Select a target for the Workers Revolt.'
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) {*/
+ gen_action_infl(spaces[space_id].name_unique);
+ //}
+ }
+ },
+ infl(space) {
+ game.temp = find_space_index(space)
+ game.state = 'vm_workers_revolt_finish'
+ }
+}
+
+
+states.vm_workers_revolt_finish = {
+ get inactive() {
+ return `resolve ${cards[game.played_card].name}.`
+ },
+ prompt() {
+ if (game.temp > 0) {
+ view.prompt = `Target: ${spaces[game.temp].name}. 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.temp].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
+ }
+ if (roll >= 4) {
+ log('Workers Revolt successful')
+ vm_replace_all_infl(game.temp)
+ } else {log('Workers Revolt fails')}
+ game.temp = 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 influence',
+ prompt () {
+ if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
+ view.prompt = 'Remove influence: done.'
+ gen_action('done')
+ return
+ }
+ view.prompt = 'Tiananmen Square Track award: select a space to remove influence'
+
+ for (let space_id of game.valid_spaces) {
+ /*const space = spaces.find(s => s && s.space_id === space_id);
+ if (space) {*/
+ gen_action_infl(spaces[space_id].name_unique);
+ // }
+ }
+ },
+ infl(space) {
+ vm_do_remove_infl(space)
+ },
+ done() {
+ 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 op 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)
+ game.state = 'vm_tst_6_sc'
+ },
+ done () {
+ vm_next()
+ }
+}
+
+/* states.vm_tst_6_prep = {
+ 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 = `Select a space for the 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)
+ game.state = 'vm_tst_6_sc'
+ },
+ done () {
+ vm_next()
+ }
+} */
+
+states.vm_tst_6_sc = {
+ inactive: 'do support check.',
+ prompt () {
+ view.prompt = `Target: ${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.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() {
+ game.vm_event_to_do = false
+ game.return_state = 'vm_tst_8'
+ game.return = game.active
+ goto_vm(game.played_card)
+ },
+ ops() {
+ 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 ${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()
+ 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 = '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.vm_available_ops > 0) {
+ view.prompt = 'Discard a card'
+ gen_action('discard')
+ } else {
+ view.prompt = 'Discard cards: 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 --
+ },
+ done() {
+ log_msg_gap('Takes initiative')
+ game.return = game.active
+ vm_next()
+ }
+}
+
+/* =================== EVENTS ================================ */
+
+const CODE = []
+CODE[1] = [//Legacy of Martial Law*
+ [vm_valid_spaces_country_opp, 'Poland'],
+ [vm_legacy_of_martial_law],
+ [vm_valid_spaces_country_sc, 'Poland'],
+ [vm_support_check, 1],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[2] = [//Solidarity Legalised*
+ [vm_solidarity_legalised],
+ [vm_valid_spaces_solidarity_legalised],
+ [vm_add_limited_infl, 9, 1],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[3] = [//Walesa
+ [vm_valid_spaces_country, 'Poland'],
+ [vm_add_infl_free, 4],
+ [vm_valid_spaces_country_sc, 'Poland'],
+ [vm_support_check, 2],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[4] = [//Michnik
+ [vm_valid_spaces, 26],
+ [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_valid_spaces_country_socio_2, 'Romania', 3, 4],
+ [vm_add_limited_infl, 4, 2],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[11] = [//Dissident arrested
+ [vm_valid_spaces_opponent_socio, 5],
+ [vm_remove_x_opp_infl, 2],
+ [vm_return]
+]
+CODE[12] = [//Apparatchicks
+ [vm_valid_spaces_socio, 2],
+ [vm_add_infl, 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_support_check, 1],
+ [vm_return]
+]
+CODE[15] = [//Honecker
+ [vm_honecker],
+ [vm_permanently_remove],
+ [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_add_limited_infl, 4, 1],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[19] = [// Papal vist
+ [vm_valid_spaces, 20, 35, 38],
+ [vm_add_x_infl, 3],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[20] = [//Deutsche Marks*
+ [vm_deutsche_marks],
+ [vm_permanently_remove],
+ [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_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_remove_opp_infl, 1],
+ [vm_valid_spaces_opponent_socio, 4],
+ [vm_active_country],
+ [vm_support_check, 1],
+ [vm_return]
+]
+CODE[28] = [//Factory Party Cells
+ [vm_valid_spaces_opponent_socio, 4],
+ [vm_remove_limited_opp_infl, 3, 2],
+ [vm_return]
+
+]
+CODE[29] = [//Jan Palach Week*
+ [vm_valid_spaces, 30],
+ [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_add_limited_infl, 4, 2],
+ [vm_return]
+]
+CODE[32] = [//Peasant Parties*
+ [vm_valid_spaces_socio, 3],
+ [vm_add_limited_infl, 4, 2],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[33] = [//Sajudis*
+ [vm_valid_spaces, 56, 70],
+ [vm_take_control_prep, 1],
+ [vm_sajudis],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[34] = [//Fidesz*
+ [vm_valid_spaces, 47],
+ [vm_add_x_infl, 6],
+ [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_dash_for_the_west],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[37] = [//Nagy Reburied*
+ [vm_valid_spaces, 43],
+ [vm_remove_all_infl, 1],
+ [vm_valid_spaces_country, 'Hungary'],
+ [vm_add_limited_infl, 4, 2],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[38] = [// July Concept
+ [vm_valid_spaces_country, 'Bulgaria'],
+ [vm_add_infl, 3],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[39] = [//Eco-Glasnost*
+ [vm_valid_spaces, 66],
+ [vm_add_x_infl, 4],
+ [vm_eco_glasnost],
+ [vm_return]
+]
+CODE[40] = [//Hungarian Democratic Forum
+ [vm_valid_spaces_country, 'Hungary'],
+ [vm_add_infl_free, 3],
+ [vm_valid_spaces_country_sc, 'Hungary'],
+ [vm_support_check, 1],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[41] = [//Ceausescu*
+ [vm_valid_spaces_country_sc, 'Romania'],
+ [vm_remove_opp_infl, 3],
+ [vm_valid_spaces_country_sc, 'Romania'],
+ [vm_support_check, 1],
+ [vm_ceausescu],
+ [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_sc ],
+ [ vm_remove_opp_infl, 2 ],
+ [ vm_inflationary_currency_discard ],
+ [ vm_if, ()=>discarded_card() ],
+ [ vm_valid_spaces_country_sc ],
+ [ vm_support_check, 1 ],
+ [ vm_endif ],
+ [ vm_permanently_remove ],
+ [ vm_return ],
+ [ vm_return ],
+]
+CODE[45] = [//Soviet Troop Withdrawals*
+ [vm_valid_spaces_region_opp, '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_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_return]
+]
+CODE[50] = [//The Sinatra Doctrine*
+ [vm_the_sintra_doctrine],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[51] = [//40th Anniverstary Celebration
+ [vm_40th_anniversary_celebration],
+ [vm_valid_spaces_country, 'East_Germany'],
+ [vm_add_infl_free],
+ [vm_40th_anniversary_celebration_vp],
+ [vm_permanently_remove],
+ [vm_return]
+
+]
+CODE[52] = [//Normalisation
+ [vm_normalisation],
+ [vm_remove_all_infl, 2],
+ [vm_permanently_remove],
+ [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_foreign_television],
+ [vm_remove_limited_opp_infl, 4 ,2],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[57] = [//Central Committee Reshuffle*
+ [vm_central_committee_reshuffle],
+ [vm_add_infl, 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_add_infl, 3],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[61] = [//The Monday Demonstrations*
+ [vm_the_monday_demonstrations],
+ [vm_take_control_prep, 2],
+ [vm_valid_spaces_country_sc, '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_add_limited_infl, 11, 1],
+ [vm_permanently_remove],
+ [vm_return]
+ ]
+CODE[65] = [//Presidential Visit*
+ [vm_presidential_visit],
+ [vm_return]
+]
+CODE[66] = [//New Forum
+ [vm_valid_spaces_country, 'East_Germany'],
+ [vm_add_limited_infl, 3, 1],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[67] = [//Reformer Rehabilitated*
+ [vm_reformer_rehabilitated],
+ [vm_return]
+ ]
+CODE[68] = [//Klaus and Komarek*
+ [vm_klaus_and_komarek],
+ [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_add_limited_infl, 2, 1],
+ [vm_laszlo_tokes],
+ [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_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_add_x_infl, 3],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[80] = [//Nepotism*
+ [vm_nepotism],
+ [vm_valid_spaces_region_socio, 'Balkans', 4],
+ [vm_add_infl],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[81] = [//The Baltic Way*
+ [vm_the_baltic_way],
+ [vm_take_control_prep, 1],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[82] = [//Spitzel*
+ [vm_valid_spaces_country_sc, 'East_Germany'],
+ [vm_remove_opp_infl, 2],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[83] = [//Modrow*
+ [vm_modrow],
+ [vm_valid_spaces_country, 'East_Germany'],
+ [vm_add_limited_infl, 4, 2],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[84] = [//Breakaway Baltic Republics*
+ [vm_breakaway_baltic_republics],
+ [vm_take_control_prep, 1],
+ [vm_valid_spaces_sc],
+ [vm_support_check, 1],
+ [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_add_limited_infl, 4, 2],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[89] = [//Domino Theory*
+ [vm_domino_theory],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[90] = [//Civic Forum*
+ [vm_valid_spaces_country, 'Czechoslovakia'],
+ [vm_add_infl_free, 4],
+ [vm_civic_forum],
+ [vm_valid_spaces_country_sc, 'Czechoslovakia'],
+ [vm_support_check, 2],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[91] = [//My First Banana*
+ [vm_valid_spaces_country_opp, 'East_Germany'],
+ [vm_remove_opp_infl, 2],
+ [vm_valid_spaces_country_sc, 'East_Germany'],
+ [vm_support_check, 2],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[92] = [//vm_betrayal
+ [vm_betrayal],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[93] = [//Shock Therapy*
+ [vm_shock_therapy],
+ [vm_valid_spaces_country],
+ [vm_add_infl, 3],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[94] = [//Union of Democratic Forces*
+ [vm_valid_spaces_country_sc, 'Bulgaria'],
+ [vm_remove_opp_infl, 4],
+ [vm_valid_spaces_country_sc, '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_support_check_modified, 5, 3],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[97] = [//The Tyrant is Gone*
+ [vm_valid_spaces, 51],
+ [vm_remove_opp_infl, 4],
+ [vm_the_tyrant_is_gone],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[98] = [//Politbuto Intrigue*
+ [vm_valid_spaces_country_sc, 'Bulgaria'],
+ [vm_remove_limited_opp_infl, 3, 2],
+ [vm_valid_spaces_country_sc, 'Bulgaria'],
+ [vm_support_check, 1],
+ [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_valid_spaces, 51],
+ [vm_add_infl, 2],
+ [vm_elena],
+ [vm_return]
+]
+CODE[102] = [//National Salvation Front*
+ [vm_national_salvation_front],
+ [vm_return]
+]
+CODE[103] = [//Government Resigns*
+ [vm_government_resigns],
+ [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_add_limited_infl, 4 ,2],
+ [vm_public_against_violence],
+ [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_add_infl, 2],
+ [vm_valid_spaces_country_sc],
+ [vm_support_check, 1],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[107] = [//Massacre in Timisoara*
+ [vm_valid_spaces_country_sc, 'Romania'],
+ [vm_support_check_modified, 2, 2],
+ [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_take_control_prep, 6],
+ [vm_permanently_remove],
+ [vm_return]
+]
+CODE[110] = [//Malta Summit*
+ [vm_malta_summit],
+ [vm_permanently_remove],
+ [vm_return]
+]
+
+// ============= 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_sc],
+ [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_sc],
+ [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]
+]