summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2024-10-25 12:06:40 +0200
committerTor Andersson <tor@ccxvii.net>2024-10-25 12:07:59 +0200
commitbf856d132261e7ca91ca6f8fbe5cecef6ba939d6 (patch)
tree66ecc7171093bed9981ea2870254ceb952122c76
parentc8b701953f1b0a6349d738895df738d4899ab1f5 (diff)
download1989-dawn-of-freedom-bf856d132261e7ca91ca6f8fbe5cecef6ba939d6.tar.gz
Normalize line endings.
Added .gitattributes with text=auto setting. Ran `git add --renormalize .` to update all the checked in files.
-rw-r--r--.gitattributes3
-rw-r--r--data.js506
-rw-r--r--play.css1482
-rw-r--r--play.html420
-rw-r--r--play.js1628
-rw-r--r--rules.js19784
6 files changed, 11913 insertions, 11910 deletions
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..aee666c
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,3 @@
+* text=auto
+*.jpg binary
+*.png binary
diff --git a/data.js b/data.js
index a4a64a8..17e7530 100644
--- a/data.js
+++ b/data.js
@@ -1,253 +1,253 @@
-const spaces = [
- null,
- {name_unique: 'Schwerin', space_id: 1, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 111, y: 61}, adjacent: [2, 3, , , ]},
- {name_unique: 'Rostock', space_id: 2, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 228, y: 41}, adjacent: [1, 3, , , ]},
- {name_unique: 'Berlin', space_id: 3, socio: 2, stability: 3, battleground: 1, demInfl: 0, comInfl: 2, country: 'East_Germany', region: 'Eastern Europe', box: {x: 251, y: 113}, adjacent: [1, 2, 5, 9, ]},
- {name_unique: 'German Writers', space_id: 4, socio: 5, stability: 2, battleground: 0, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 58, y: 185}, adjacent: [5, , , , ]},
- {name_unique: 'Walter Ulbricht Academy', space_id: 5, socio: 6, stability: 1, battleground: 0, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 175, y: 187}, adjacent: [3, 4, , , ]},
- {name_unique: 'Lutherian Church', space_id: 6, socio: 7, stability: 5, battleground: 1, demInfl: 1, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 300, y: 212}, adjacent: [9, , , , ]},
- {name_unique: 'Magdeburg', space_id: 7, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 58, y: 275}, adjacent: [8, 10, 11, , ]},
- {name_unique: 'Halle', space_id: 8, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 175, y: 278}, adjacent: [7, 9, 11, , ]},
- {name_unique: 'Leipzig', space_id: 9, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 297, y: 297}, adjacent: [3, 6, 8, 11, 12]},
- {name_unique: 'Erfurt', space_id: 10, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 23, y: 356}, adjacent: [7, , , , ]},
- {name_unique: 'Karl-Marx-Stadt', space_id: 11, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 138, y: 385}, adjacent: [7, 8, 9, 12, ]},
- {name_unique: 'Dresden', space_id: 12, socio: 1, stability: 4, battleground: 1, demInfl: 0, comInfl: 2, country: 'East_Germany', region: 'Eastern Europe', box: {x: 262, y: 375}, adjacent: [9, 11, 19, 27, ]},
- {name_unique: 'Szczecin', space_id: 13, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 434, y: 204}, adjacent: [14, 16, , , ]},
- {name_unique: 'Gdańsk', space_id: 14, socio: 4, stability: 3, battleground: 1, demInfl: 1, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 699, y: 215}, adjacent: [13, 15, 16, 17, 18]},
- {name_unique: 'Bydgoszcz', space_id: 15, socio: 1, stability: 4, battleground: 0, demInfl: 0, comInfl: 1, country: 'Poland', region: 'Eastern Europe', box: {x: 679, y: 304}, adjacent: [14, 17, , , ]},
- {name_unique: 'Poznań', space_id: 16, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 521, y: 355}, adjacent: [13, 14, 19, 20, ]},
- {name_unique: 'Warszawa', space_id: 17, socio: 2, stability: 3, battleground: 1, demInfl: 0, comInfl: 1, country: 'Poland', region: 'Eastern Europe', box: {x: 806, y: 383}, adjacent: [14, 15, 18, 21, 24]},
- {name_unique: 'Białystok', space_id: 18, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 940, y: 342}, adjacent: [14, 17, 24, , ]},
- {name_unique: 'Wrocław', space_id: 19, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 462, y: 443}, adjacent: [12, 16, 20, 22, ]},
- {name_unique: 'Catholic Church, Poland', space_id: 20, socio: 7, stability: 5, battleground: 0, demInfl: 5, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 625, y: 437}, adjacent: [16, 19, 21, 22, 23]},
- {name_unique: 'Łódź', space_id: 21, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 749, y: 486}, adjacent: [17, 20, 23, 24, ]},
- {name_unique: 'Katowice', space_id: 22, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 570, y: 569}, adjacent: [19, 20, 23, 33, ]},
- {name_unique: 'Kraków', space_id: 23, socio: 4, stability: 3, battleground: 1, demInfl: 1, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 711, y: 598}, adjacent: [20, 21, 22, 25, ]},
- {name_unique: 'Lublin', space_id: 24, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 1, country: 'Poland', region: 'Eastern Europe', box: {x: 879, y: 603}, adjacent: [17, 18, 21, , ]},
- {name_unique: 'Jagiellian University', space_id: 25, socio: 6, stability: 1, battleground: 0, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 679, y: 681}, adjacent: [23, 26, , , ]},
- {name_unique: 'Polish Writers', space_id: 26, socio: 5, stability: 2, battleground: 0, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 832, y: 694}, adjacent: [25, , , , ]},
- {name_unique: 'Plzeň', space_id: 27, socio: 1, stability: 4, battleground: 0, demInfl: 0, comInfl: 2, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 159, y: 483}, adjacent: [12, 28, 29, , ]},
- {name_unique: 'České Budĕjovice', space_id: 28, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 196, y: 601}, adjacent: [27, 29, , , ]},
- {name_unique: 'Praha', space_id: 29, socio: 2, stability: 3, battleground: 1, demInfl: 0, comInfl: 2, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 317, y: 614}, adjacent: [27, 28, 30, 32, ]},
- {name_unique: 'Charles University', space_id: 30, socio: 6, stability: 1, battleground: 1, demInfl: 0, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 380, y: 532}, adjacent: [29, 31, , , ]},
- {name_unique: 'Czech Writers', space_id: 31, socio: 5, stability: 2, battleground: 1, demInfl: 2, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 444, y: 607}, adjacent: [30, , , , ]},
- {name_unique: 'Brno', space_id: 32, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 1, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 403, y: 711}, adjacent: [29, 33, 34, , ]},
- {name_unique: 'Ostrava', space_id: 33, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 523, y: 681}, adjacent: [22, 32, 34, 35, ]},
- {name_unique: 'Bratislava', space_id: 34, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 417, y: 797}, adjacent: [32, 33, 35, , ]},
- {name_unique: 'Catholic Church, Czechoslovakia', space_id: 35, socio: 7, stability: 5, battleground: 0, demInfl: 1, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 538, y: 794}, adjacent: [33, 34, 36, , ]},
- {name_unique: 'Prešov', space_id: 36, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 658, y: 794}, adjacent: [35, 37, , , ]},
- {name_unique: 'Košice', space_id: 37, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 777, y: 815}, adjacent: [36, 42, , , ]},
- {name_unique: 'Catholic Church, Hungary', space_id: 38, socio: 7, stability: 5, battleground: 0, demInfl: 1, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 314, y: 886}, adjacent: [39, 43, , , ]},
- {name_unique: 'Győr', space_id: 39, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 434, y: 887}, adjacent: [38, 40, 43, 44, ]},
- {name_unique: 'Tatabánya', space_id: 40, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 549, y: 886}, adjacent: [39, 41, 45, , ]},
- {name_unique: 'Miskolc', space_id: 41, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 664, y: 901}, adjacent: [40, 42, 45, , ]},
- {name_unique: 'Debrecen', space_id: 42, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 781, y: 938}, adjacent: [37, 41, , , ]},
- {name_unique: 'Szombathely', space_id: 43, socio: 1, stability: 4, battleground: 0, demInfl: 0, comInfl: 1, country: 'Hungary', region: 'Eastern Europe', box: {x: 316, y: 963}, adjacent: [38, 39, 44, , ]},
- {name_unique: 'Székesfehérvár', space_id: 44, socio: 4, stability: 3, battleground: 0, demInfl: 1, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 442, y: 962}, adjacent: [39, 43, 45, , ]},
- {name_unique: 'Budapest', space_id: 45, socio: 2, stability: 3, battleground: 1, demInfl: 1, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 630, y: 983}, adjacent: [40, 41, 44, 47, 48]},
- {name_unique: 'Hungarian Writers', space_id: 46, socio: 5, stability: 2, battleground: 0, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 348, y: 1040}, adjacent: [47, , , , ]},
- {name_unique: 'Eötvös Loránd University', space_id: 47, socio: 6, stability: 1, battleground: 0, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 512, y: 1034}, adjacent: [46, 45, , , ]},
- {name_unique: 'Szeged', space_id: 48, socio: 3, stability: 4, battleground: 1, demInfl: 1, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 632, y: 1073}, adjacent: [45, 49, 50, , ]},
- {name_unique: 'Pécs', space_id: 49, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 486, y: 1105}, adjacent: [48, , , , ]},
- {name_unique: 'Timişoara', space_id: 50, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 597, y: 1204}, adjacent: [48, 51, 60, , ]},
- {name_unique: 'Cluj-Napoca', space_id: 51, socio: 1, stability: 4, battleground: 1, demInfl: 0, comInfl: 2, country: 'Romania', region: 'Balkans', box: {x: 756, y: 1125}, adjacent: [50, 54, 58, 61, ]},
- {name_unique: 'Târgu Mureş', space_id: 52, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 915, y: 1136}, adjacent: [53, 56, , , ]},
- {name_unique: 'Iaşi', space_id: 53, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 1072, y: 1097}, adjacent: [52, 57, 62, , ]},
- {name_unique: 'Babeş-Bolyai University', space_id: 54, socio: 6, stability: 1, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 746, y: 1203}, adjacent: [51, 55, , , ]},
- {name_unique: 'Romanian Writers', space_id: 55, socio: 5, stability: 2, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 739, y: 1278}, adjacent: [54, , , , ]},
- {name_unique: 'Hargita/Covasna', space_id: 56, socio: 8, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 928, y: 1227}, adjacent: [52, , , , ]},
- {name_unique: 'Braşov', space_id: 57, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 1049, y: 1225}, adjacent: [53, 59, 61, , ]},
- {name_unique: 'Orthodox Church Romania', space_id: 58, socio: 7, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 855, y: 1338}, adjacent: [51, 60, , , ]},
- {name_unique: 'Ploieşti', space_id: 59, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 1061, y: 1316}, adjacent: [57, 61, 62, , ]},
- {name_unique: 'Craiova', space_id: 60, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 763, y: 1411}, adjacent: [50, 58, 61, , ]},
- {name_unique: 'Bucureşti', space_id: 61, socio: 2, stability: 3, battleground: 1, demInfl: 0, comInfl: 2, country: 'Romania', region: 'Balkans', box: {x: 929, y: 1445}, adjacent: [51, 57, 59, 60, 63]},
- {name_unique: 'Galaţi', space_id: 62, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 1104, y: 1399}, adjacent: [53, 59, 63, , ]},
- {name_unique: 'Constanţa', space_id: 63, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 1130, y: 1517}, adjacent: [61, 62, 72, , ]},
- {name_unique: 'Pleven', space_id: 64, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 764, y: 1534}, adjacent: [68, , , , ]},
- {name_unique: 'Orthodox Church Bulgaria', space_id: 65, socio: 7, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 882, y: 1540}, adjacent: [66, 68, , , ]},
- {name_unique: 'Ruse', space_id: 66, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 998, y: 1540}, adjacent: [65, 69, 70, 71, 72]},
- {name_unique: 'Sofia University', space_id: 67, socio: 6, stability: 1, battleground: 0, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 645, y: 1650}, adjacent: [68, 73, , , ]},
- {name_unique: 'Sofia', space_id: 68, socio: 2, stability: 3, battleground: 1, demInfl: 0, comInfl: 2, country: 'Bulgaria', region: 'Balkans', box: {x: 768, y: 1653}, adjacent: [64, 65, 67, 69, 74]},
- {name_unique: 'Stara Zagora', space_id: 69, socio: 1, stability: 4, battleground: 0, demInfl: 0, comInfl: 1, country: 'Bulgaria', region: 'Balkans', box: {x: 886, y: 1694}, adjacent: [66, 68, 71, , ]},
- {name_unique: 'Razgrad', space_id: 70, socio: 8, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 954, y: 1620}, adjacent: [66, , , , ]},
- {name_unique: 'Burgas', space_id: 71, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 1004, y: 1695}, adjacent: [66, 69, 72, , ]},
- {name_unique: 'Varna', space_id: 72, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 1086, y: 1613}, adjacent: [63, 66, 71, , ]},
- {name_unique: 'Bulgarian Writers', space_id: 73, socio: 5, stability: 2, battleground: 0, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 652, y: 1726}, adjacent: [67, , , , ]},
- {name_unique: 'Plovdiv', space_id: 74, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 771, y: 1739}, adjacent: [68, 75, , , ]},
- {name_unique: 'Sliven', space_id: 75, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 894, y: 1768}, adjacent: [74, , , , ]}
-]
-
-const cards = [
- null,
- {number: 1, period: 1, side: 'C', name: 'Legacy of Martial Law*', ops: 2, remove: 1, playable: true, red: false},
- {number: 2, period: 1, side: 'D', name: 'Solidarity Legalized*', ops: 4, remove: 1, playable: true, red: true},
- {number: 3, period: 1, side: 'D', name: 'Walesa*', ops: 3, remove: 1, playable: false, red: false},
- {number: 4, period: 1, side: 'D', name: 'Michnik*', ops: 1, remove: 1, playable: true, red: false},
- {number: 5, period: 1, side: 'D', name: 'General Strike*', ops: 3, remove: 0, playable: true, red: false},
- {number: 6, period: 1, side: 'C', name: 'Brought in for Questioning', ops: 3, remove: 0, playable: true, red: false},
- {number: 7, period: 1, side: 'C', name: 'State Run Media*', ops: 2, remove: 1, playable: true, red: false},
- {number: 8, period: 1, side: 'N', name: 'Prudence', ops: 4, remove: 0, playable: true, red: false},
- {number: 9, period: 1, side: 'C', name: 'The Wall*', ops: 1, remove: 1, playable: true, red: false},
- {number: 10, period: 1, side: 'C', name: 'Cult of Personality*', ops: 3, remove: 1, playable: true, red: false},
- {number: 11, period: 1, side: 'C', name: 'Dissident Arrested', ops: 2, remove: 0, playable: true, red: false},
- {number: 12, period: 1, side: 'C', name: 'Apparatchiks*', ops: 2, remove: 1, playable: true, red: false},
- {number: 13, period: 1, side: 'C', name: 'Stasi*', ops: 1, remove: 1, playable: true, red: false},
- {number: 14, period: 1, side: 'N', name: 'Gorbachev Charms the West', ops: 4, remove: 0, playable: true, red: false},
- {number: 15, period: 1, side: 'C', name: 'Honecker*', ops: 3, remove: 1, playable: true, red: false},
- {number: 16, period: 1, side: 'C', name: 'Nomenklatura*', ops: 2, remove: 1, playable: true, red: false},
- {number: 17, period: 1, side: 'D', name: 'Roundtable Talks', ops: 3, remove: 0, playable: true, red: false},
- {number: 18, period: 1, side: 'C', name: 'Poszgay Defends the Revolution*', ops: 2, remove: 1, playable: true, red: false},
- {number: 19, period: 1, side: 'D', name: 'Papal Visit*', ops: 2, remove: 1, playable: true, red: false},
- {number: 20, period: 1, side: 'C', name: 'Deutsche Marks*', ops: 4, remove: 1, playable: true, red: false},
- {number: 21, period: 1, side: 'N', name: 'Common European Home', ops: 2, remove: 0, playable: true, red: false},
- {number: 22, period: 1, side: 'N', name: 'Power Struggle - Poland', ops: 0, remove: 0, playable: true, red: false},
- {number: 23, period: 1, side: 'N', name: 'Power Struggle - Hungary', ops: 0, remove: 0, playable: true, red: false},
- {number: 24, period: 1, side: 'D', name: 'St. Nicholas Church*', ops: 1, remove: 1, playable: true, red: true},
- {number: 25, period: 1, side: 'C', name: 'Perestroika*', ops: 3, remove: 1, playable: true, red: false},
- {number: 26, period: 1, side: 'D', name: 'Helsinki Final Act*', ops: 1, remove: 1, playable: true, red: true},
- {number: 27, period: 1, side: 'D', name: 'Consumerism', ops: 3, remove: 0, playable: true, red: false},
- {number: 28, period: 1, side: 'C', name: 'Factory Party Cells', ops: 3, remove: 0, playable: true, red: false},
- {number: 29, period: 1, side: 'D', name: 'Jan Palach Week*', ops: 1, remove: 1, playable: true, red: false},
- {number: 30, period: 1, side: 'C', name: 'Tear Gas*', ops: 1, remove: 1, playable: true, red: false},
- {number: 31, period: 1, side: 'D', name: 'Intelligentsia', ops: 2, remove: 0, playable: true, red: false},
- {number: 32, period: 1, side: 'C', name: 'Peasant Parties*', ops: 2, remove: 1, playable: true, red: false},
- {number: 33, period: 1, side: 'D', name: 'Sajudis*', ops: 2, remove: 1, playable: true, red: true},
- {number: 34, period: 1, side: 'D', name: 'Fidesz*', ops: 2, remove: 1, playable: true, red: false},
- {number: 35, period: 1, side: 'C', name: 'Heal Our Bleeding Wound*', ops: 3, remove: 1, playable: true, red: false},
- {number: 36, period: 1, side: 'D', name: 'Dash for the West*', ops: 3, remove: 1, playable: true, red: false},
- {number: 37, period: 1, side: 'C', name: 'Nagy Reburied*', ops: 3, remove: 1, playable: true, red: false},
- {number: 38, period: 1, side: 'C', name: 'The July Concept*', ops: 3, remove: 1, playable: true, red: false},
- {number: 39, period: 1, side: 'D', name: 'Eco-Glasnost*', ops: 2, remove: 1, playable: true, red: false},
- {number: 40, period: 1, side: 'D', name: 'Hungarian Democratic Forum*', ops: 3, remove: 1, playable: true, red: false},
- {number: 41, period: 2, side: 'C', name: 'Ceausescu*', ops: 3, remove: 1, playable: true, red: false},
- {number: 42, period: 2, side: 'N', name: 'Power Struggle - East Germany', ops: 0, remove: 0, playable: true, red: false},
- {number: 43, period: 2, side: 'N', name: 'Power Struggle - Bulgaria', ops: 0, remove: 0, playable: true, red: false},
- {number: 44, period: 2, side: 'N', name: 'Inflationary Currency*', ops: 3, remove: 1, playable: true, red: false},
- {number: 45, period: 2, side: 'D', name: 'Soviet Troop Withdrawals*', ops: 4, remove: 1, playable: true, red: false},
- {number: 46, period: 2, side: 'D', name: 'Goodbye Lenin!*', ops: 3, remove: 1, playable: true, red: false},
- {number: 47, period: 2, side: 'C', name: 'Bulgarian Turks Expelled*', ops: 3, remove: 1, playable: true, red: false},
- {number: 48, period: 2, side: 'D', name: '\"We are the People!\"', ops: 3, remove: 1, playable: true, red: false},
- {number: 49, period: 2, side: 'D', name: 'Foreign Currency Debt Burden', ops: 1, remove: 1, playable: true, red: false},
- {number: 50, period: 2, side: 'D', name: 'The Sinatra Doctrine*', ops: 3, remove: 1, playable: true, red: false},
- {number: 51, period: 2, side: 'C', name: '40th Anniversary Celebration*', ops: 2, remove: 1, playable: true, red: false},
- {number: 52, period: 2, side: 'C', name: 'Normalization*', ops: 3, remove: 1, playable: true, red: false},
- {number: 53, period: 2, side: 'C', name: 'Li Peng*', ops: 2, remove: 1, playable: true, red: false},
- {number: 54, period: 2, side: 'D', name: 'The Crowd Turns Against Ceausescu*', ops: 3, remove: 1, playable: true, red: true},
- {number: 55, period: 2, side: 'N', name: 'Power Struggle - Czechoslovakia', ops: 0, remove: 0, playable: true, red: false},
- {number: 56, period: 2, side: 'D', name: 'Foreign Television*', ops: 2, remove: 1, playable: true, red: false},
- {number: 57, period: 2, side: 'C', name: 'Central Committee Reshuffle*', ops: 2, remove: 1, playable: true, red: false},
- {number: 58, period: 2, side: 'D', name: 'Austria-Hungary Border Reopened*', ops: 2, remove: 1, playable: true, red: false},
- {number: 59, period: 2, side: 'C', name: 'GrenzTruppen*', ops: 2, remove: 1, playable: true, red: false},
- {number: 60, period: 2, side: 'D', name: 'Toxic Waste*', ops: 2, remove: 1, playable: true, red: false},
- {number: 61, period: 2, side: 'D', name: 'The Monday Demonstrations*', ops: 4, remove: 1, playable: false, red: false},
- {number: 62, period: 2, side: 'D', name: 'Yakovlev Counsels Gorbachev*', ops: 2, remove: 1, playable: true, red: false},
- {number: 63, period: 2, side: 'D', name: 'Genscher*', ops: 2, remove: 1, playable: true, red: false},
- {number: 64, period: 2, side: 'D', name: 'Legacy of 1968*', ops: 4, remove: 1, playable: true, red: false},
- {number: 65, period: 2, side: 'D', name: 'Presidential Visit*', ops: 3, remove: 1, playable: true, red: false},
- {number: 66, period: 2, side: 'D', name: 'New Forum*', ops: 1, remove: 1, playable: true, red: false},
- {number: 67, period: 2, side: 'N', name: 'Reformer Rehabilitated*', ops: 2, remove: 1, playable: false, red: false},
- {number: 68, period: 2, side: 'D', name: 'Klaus and Komarek*', ops: 3, remove: 1, playable: true, red: false},
- {number: 69, period: 2, side: 'C', name: 'Systematization*', ops: 3, remove: 1, playable: true, red: false},
- {number: 70, period: 2, side: 'C', name: 'Securitate*', ops: 2, remove: 1, playable: true, red: false},
- {number: 71, period: 2, side: 'D', name: 'Kiss of Death*', ops: 3, remove: 1, playable: true, red: false},
- {number: 72, period: 2, side: 'D', name: 'Peasant Parties Revolt*', ops: 3, remove: 1, playable: true, red: false},
- {number: 73, period: 2, side: 'D', name: 'Laszlo Tokes*', ops: 2, remove: 1, playable: true, red: true},
- {number: 74, period: 2, side: 'D', name: 'FRG Embassies*', ops: 3, remove: 1, playable: true, red: false},
- {number: 75, period: 2, side: 'D', name: 'Exit Visas*', ops: 3, remove: 1, playable: true, red: false},
- {number: 76, period: 2, side: 'C', name: 'Warsaw Pact Summit*', ops: 2, remove: 1, playable: true, red: false},
- {number: 77, period: 2, side: 'D', name: 'Samizdat*', ops: 1, remove: 1, playable: true, red: false},
- {number: 78, period: 2, side: 'N', name: 'Workers Revolt', ops: 2, remove: 0, playable: true, red: false},
- {number: 79, period: 2, side: 'C', name: 'The Third Way*', ops: 2, remove: 1, playable: true, red: false},
- {number: 80, period: 2, side: 'C', name: 'Nepotism*', ops: 3, remove: 1, playable: true, red: false},
- {number: 81, period: 2, side: 'D', name: 'The Baltic Way*', ops: 3, remove: 1, playable: false, red: true},
- {number: 82, period: 3, side: 'C', name: 'Spitzel*', ops: 1, remove: 1, playable: true, red: false},
- {number: 83, period: 3, side: 'C', name: 'Modrow*', ops: 2, remove: 1, playable: true, red: false},
- {number: 84, period: 3, side: 'D', name: 'Breakaway Baltic Republics*', ops: 4, remove: 1, playable: false, red: true},
- {number: 85, period: 3, side: 'N', name: 'Tank Column/Tank Man*', ops: 2, remove: 1, playable: true, red: false},
- {number: 86, period: 3, side: 'D', name: '\"The Wall Must Go!\"*', ops: 3, remove: 1, playable: true, red: false},
- {number: 87, period: 3, side: 'D', name: 'Kohl Proposes Reunification*', ops: 3, remove: 1, playable: true, red: false},
- {number: 88, period: 3, side: 'C', name: 'Adamec*', ops: 2, remove: 1, playable: true, red: false},
- {number: 89, period: 3, side: 'D', name: 'Domino Theory*', ops: 3, remove: 1, playable: true, red: false},
- {number: 90, period: 3, side: 'D', name: 'Civic Forum*', ops: 4, remove: 1, playable: true, red: false},
- {number: 91, period: 3, side: 'D', name: 'My First Banana*', ops: 3, remove: 1, playable: true, red: false},
- {number: 92, period: 3, side: 'C', name: 'Betrayal*', ops: 3, remove: 1, playable: true, red: false},
- {number: 93, period: 3, side: 'D', name: 'Shock Therapy*', ops: 3, remove: 1, playable: true, red: false},
- {number: 94, period: 3, side: 'D', name: 'Union of Democratic Forces*', ops: 4, remove: 1, playable: true, red: false},
- {number: 95, period: 3, side: 'N', name: 'Power Struggle - Romania', ops: 0, remove: 0, playable: true, red: false},
- {number: 96, period: 3, side: 'C', name: 'The Chinese Solution*', ops: 1, remove: 1, playable: false, red: false},
- {number: 97, period: 3, side: 'D', name: 'The Tyrant is Gone*', ops: 2, remove: 1, playable: false, red: false},
- {number: 98, period: 3, side: 'C', name: 'Politburo Intrigue*', ops: 2, remove: 1, playable: true, red: false},
- {number: 99, period: 3, side: 'C', name: 'Ligachev*', ops: 3, remove: 1, playable: true, red: false},
- {number: 100, period: 3, side: 'N', name: 'Stand Fast*', ops: 3, remove: 1, playable: true, red: false},
- {number: 101, period: 3, side: 'C', name: 'Elena*', ops: 1, remove: 1, playable: true, red: false},
- {number: 102, period: 3, side: 'C', name: 'National Salvation Front*', ops: 3, remove: 1, playable: true, red: false},
- {number: 103, period: 3, side: 'D', name: 'Government Resigns*', ops: 1, remove: 1, playable: true, red: false},
- {number: 104, period: 3, side: 'C', name: 'New Year\'s Eve Party*', ops: 2, remove: 1, playable: true, red: false},
- {number: 105, period: 3, side: 'D', name: 'Public Against Violence*', ops: 3, remove: 1, playable: true, red: false},
- {number: 106, period: 3, side: 'C', name: 'Social Democratic Platform Adopted*', ops: 3, remove: 1, playable: true, red: false},
- {number: 107, period: 3, side: 'C', name: 'Massacre in Timisoara*', ops: 3, remove: 1, playable: false, red: false},
- {number: 108, period: 3, side: 'D', name: 'Army Backs Revolution*', ops: 3, remove: 1, playable: true, red: false},
- {number: 109, period: 3, side: 'C', name: 'Kremlin Coup!*', ops: 3, remove: 1, playable: false, red: false},
- {number: 110, period: 3, side: 'D', name: 'Malta Summit*', ops: 3, remove: 1, playable: true, red: false},
-]
-
-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: '', socio: 0, url: 'ps26'},
-{number: 50, name: 'Support Surges', value: '', socio: 0, url: 'ps25'},
-{number: 51, name: 'Support Falters', value: '', socio: 0, url: 'ps24'},
-{number: 52, name: 'Tactic Fails', value: '', 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'},
-]
-
-
-if (typeof module !== 'undefined') module.exports = { spaces, cards, power_cards }
+const spaces = [
+ null,
+ {name_unique: 'Schwerin', space_id: 1, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 111, y: 61}, adjacent: [2, 3, , , ]},
+ {name_unique: 'Rostock', space_id: 2, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 228, y: 41}, adjacent: [1, 3, , , ]},
+ {name_unique: 'Berlin', space_id: 3, socio: 2, stability: 3, battleground: 1, demInfl: 0, comInfl: 2, country: 'East_Germany', region: 'Eastern Europe', box: {x: 251, y: 113}, adjacent: [1, 2, 5, 9, ]},
+ {name_unique: 'German Writers', space_id: 4, socio: 5, stability: 2, battleground: 0, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 58, y: 185}, adjacent: [5, , , , ]},
+ {name_unique: 'Walter Ulbricht Academy', space_id: 5, socio: 6, stability: 1, battleground: 0, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 175, y: 187}, adjacent: [3, 4, , , ]},
+ {name_unique: 'Lutherian Church', space_id: 6, socio: 7, stability: 5, battleground: 1, demInfl: 1, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 300, y: 212}, adjacent: [9, , , , ]},
+ {name_unique: 'Magdeburg', space_id: 7, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 58, y: 275}, adjacent: [8, 10, 11, , ]},
+ {name_unique: 'Halle', space_id: 8, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 175, y: 278}, adjacent: [7, 9, 11, , ]},
+ {name_unique: 'Leipzig', space_id: 9, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 297, y: 297}, adjacent: [3, 6, 8, 11, 12]},
+ {name_unique: 'Erfurt', space_id: 10, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 23, y: 356}, adjacent: [7, , , , ]},
+ {name_unique: 'Karl-Marx-Stadt', space_id: 11, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'East_Germany', region: 'Eastern Europe', box: {x: 138, y: 385}, adjacent: [7, 8, 9, 12, ]},
+ {name_unique: 'Dresden', space_id: 12, socio: 1, stability: 4, battleground: 1, demInfl: 0, comInfl: 2, country: 'East_Germany', region: 'Eastern Europe', box: {x: 262, y: 375}, adjacent: [9, 11, 19, 27, ]},
+ {name_unique: 'Szczecin', space_id: 13, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 434, y: 204}, adjacent: [14, 16, , , ]},
+ {name_unique: 'Gdańsk', space_id: 14, socio: 4, stability: 3, battleground: 1, demInfl: 1, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 699, y: 215}, adjacent: [13, 15, 16, 17, 18]},
+ {name_unique: 'Bydgoszcz', space_id: 15, socio: 1, stability: 4, battleground: 0, demInfl: 0, comInfl: 1, country: 'Poland', region: 'Eastern Europe', box: {x: 679, y: 304}, adjacent: [14, 17, , , ]},
+ {name_unique: 'Poznań', space_id: 16, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 521, y: 355}, adjacent: [13, 14, 19, 20, ]},
+ {name_unique: 'Warszawa', space_id: 17, socio: 2, stability: 3, battleground: 1, demInfl: 0, comInfl: 1, country: 'Poland', region: 'Eastern Europe', box: {x: 806, y: 383}, adjacent: [14, 15, 18, 21, 24]},
+ {name_unique: 'Białystok', space_id: 18, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 940, y: 342}, adjacent: [14, 17, 24, , ]},
+ {name_unique: 'Wrocław', space_id: 19, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 462, y: 443}, adjacent: [12, 16, 20, 22, ]},
+ {name_unique: 'Catholic Church, Poland', space_id: 20, socio: 7, stability: 5, battleground: 0, demInfl: 5, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 625, y: 437}, adjacent: [16, 19, 21, 22, 23]},
+ {name_unique: 'Łódź', space_id: 21, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 749, y: 486}, adjacent: [17, 20, 23, 24, ]},
+ {name_unique: 'Katowice', space_id: 22, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 570, y: 569}, adjacent: [19, 20, 23, 33, ]},
+ {name_unique: 'Kraków', space_id: 23, socio: 4, stability: 3, battleground: 1, demInfl: 1, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 711, y: 598}, adjacent: [20, 21, 22, 25, ]},
+ {name_unique: 'Lublin', space_id: 24, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 1, country: 'Poland', region: 'Eastern Europe', box: {x: 879, y: 603}, adjacent: [17, 18, 21, , ]},
+ {name_unique: 'Jagiellian University', space_id: 25, socio: 6, stability: 1, battleground: 0, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 679, y: 681}, adjacent: [23, 26, , , ]},
+ {name_unique: 'Polish Writers', space_id: 26, socio: 5, stability: 2, battleground: 0, demInfl: 0, comInfl: 0, country: 'Poland', region: 'Eastern Europe', box: {x: 832, y: 694}, adjacent: [25, , , , ]},
+ {name_unique: 'Plzeň', space_id: 27, socio: 1, stability: 4, battleground: 0, demInfl: 0, comInfl: 2, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 159, y: 483}, adjacent: [12, 28, 29, , ]},
+ {name_unique: 'České Budĕjovice', space_id: 28, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 196, y: 601}, adjacent: [27, 29, , , ]},
+ {name_unique: 'Praha', space_id: 29, socio: 2, stability: 3, battleground: 1, demInfl: 0, comInfl: 2, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 317, y: 614}, adjacent: [27, 28, 30, 32, ]},
+ {name_unique: 'Charles University', space_id: 30, socio: 6, stability: 1, battleground: 1, demInfl: 0, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 380, y: 532}, adjacent: [29, 31, , , ]},
+ {name_unique: 'Czech Writers', space_id: 31, socio: 5, stability: 2, battleground: 1, demInfl: 2, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 444, y: 607}, adjacent: [30, , , , ]},
+ {name_unique: 'Brno', space_id: 32, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 1, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 403, y: 711}, adjacent: [29, 33, 34, , ]},
+ {name_unique: 'Ostrava', space_id: 33, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 523, y: 681}, adjacent: [22, 32, 34, 35, ]},
+ {name_unique: 'Bratislava', space_id: 34, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 417, y: 797}, adjacent: [32, 33, 35, , ]},
+ {name_unique: 'Catholic Church, Czechoslovakia', space_id: 35, socio: 7, stability: 5, battleground: 0, demInfl: 1, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 538, y: 794}, adjacent: [33, 34, 36, , ]},
+ {name_unique: 'Prešov', space_id: 36, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 658, y: 794}, adjacent: [35, 37, , , ]},
+ {name_unique: 'Košice', space_id: 37, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Czechoslovakia', region: 'Eastern Europe', box: {x: 777, y: 815}, adjacent: [36, 42, , , ]},
+ {name_unique: 'Catholic Church, Hungary', space_id: 38, socio: 7, stability: 5, battleground: 0, demInfl: 1, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 314, y: 886}, adjacent: [39, 43, , , ]},
+ {name_unique: 'Győr', space_id: 39, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 434, y: 887}, adjacent: [38, 40, 43, 44, ]},
+ {name_unique: 'Tatabánya', space_id: 40, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 549, y: 886}, adjacent: [39, 41, 45, , ]},
+ {name_unique: 'Miskolc', space_id: 41, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 664, y: 901}, adjacent: [40, 42, 45, , ]},
+ {name_unique: 'Debrecen', space_id: 42, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 781, y: 938}, adjacent: [37, 41, , , ]},
+ {name_unique: 'Szombathely', space_id: 43, socio: 1, stability: 4, battleground: 0, demInfl: 0, comInfl: 1, country: 'Hungary', region: 'Eastern Europe', box: {x: 316, y: 963}, adjacent: [38, 39, 44, , ]},
+ {name_unique: 'Székesfehérvár', space_id: 44, socio: 4, stability: 3, battleground: 0, demInfl: 1, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 442, y: 962}, adjacent: [39, 43, 45, , ]},
+ {name_unique: 'Budapest', space_id: 45, socio: 2, stability: 3, battleground: 1, demInfl: 1, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 630, y: 983}, adjacent: [40, 41, 44, 47, 48]},
+ {name_unique: 'Hungarian Writers', space_id: 46, socio: 5, stability: 2, battleground: 0, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 348, y: 1040}, adjacent: [47, , , , ]},
+ {name_unique: 'Eötvös Loránd University', space_id: 47, socio: 6, stability: 1, battleground: 0, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 512, y: 1034}, adjacent: [46, 45, , , ]},
+ {name_unique: 'Szeged', space_id: 48, socio: 3, stability: 4, battleground: 1, demInfl: 1, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 632, y: 1073}, adjacent: [45, 49, 50, , ]},
+ {name_unique: 'Pécs', space_id: 49, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Hungary', region: 'Eastern Europe', box: {x: 486, y: 1105}, adjacent: [48, , , , ]},
+ {name_unique: 'Timişoara', space_id: 50, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 597, y: 1204}, adjacent: [48, 51, 60, , ]},
+ {name_unique: 'Cluj-Napoca', space_id: 51, socio: 1, stability: 4, battleground: 1, demInfl: 0, comInfl: 2, country: 'Romania', region: 'Balkans', box: {x: 756, y: 1125}, adjacent: [50, 54, 58, 61, ]},
+ {name_unique: 'Târgu Mureş', space_id: 52, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 915, y: 1136}, adjacent: [53, 56, , , ]},
+ {name_unique: 'Iaşi', space_id: 53, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 1072, y: 1097}, adjacent: [52, 57, 62, , ]},
+ {name_unique: 'Babeş-Bolyai University', space_id: 54, socio: 6, stability: 1, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 746, y: 1203}, adjacent: [51, 55, , , ]},
+ {name_unique: 'Romanian Writers', space_id: 55, socio: 5, stability: 2, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 739, y: 1278}, adjacent: [54, , , , ]},
+ {name_unique: 'Hargita/Covasna', space_id: 56, socio: 8, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 928, y: 1227}, adjacent: [52, , , , ]},
+ {name_unique: 'Braşov', space_id: 57, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 1049, y: 1225}, adjacent: [53, 59, 61, , ]},
+ {name_unique: 'Orthodox Church Romania', space_id: 58, socio: 7, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 855, y: 1338}, adjacent: [51, 60, , , ]},
+ {name_unique: 'Ploieşti', space_id: 59, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 1061, y: 1316}, adjacent: [57, 61, 62, , ]},
+ {name_unique: 'Craiova', space_id: 60, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 763, y: 1411}, adjacent: [50, 58, 61, , ]},
+ {name_unique: 'Bucureşti', space_id: 61, socio: 2, stability: 3, battleground: 1, demInfl: 0, comInfl: 2, country: 'Romania', region: 'Balkans', box: {x: 929, y: 1445}, adjacent: [51, 57, 59, 60, 63]},
+ {name_unique: 'Galaţi', space_id: 62, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 1104, y: 1399}, adjacent: [53, 59, 63, , ]},
+ {name_unique: 'Constanţa', space_id: 63, socio: 4, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Romania', region: 'Balkans', box: {x: 1130, y: 1517}, adjacent: [61, 62, 72, , ]},
+ {name_unique: 'Pleven', space_id: 64, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 764, y: 1534}, adjacent: [68, , , , ]},
+ {name_unique: 'Orthodox Church Bulgaria', space_id: 65, socio: 7, stability: 3, battleground: 0, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 882, y: 1540}, adjacent: [66, 68, , , ]},
+ {name_unique: 'Ruse', space_id: 66, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 998, y: 1540}, adjacent: [65, 69, 70, 71, 72]},
+ {name_unique: 'Sofia University', space_id: 67, socio: 6, stability: 1, battleground: 0, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 645, y: 1650}, adjacent: [68, 73, , , ]},
+ {name_unique: 'Sofia', space_id: 68, socio: 2, stability: 3, battleground: 1, demInfl: 0, comInfl: 2, country: 'Bulgaria', region: 'Balkans', box: {x: 768, y: 1653}, adjacent: [64, 65, 67, 69, 74]},
+ {name_unique: 'Stara Zagora', space_id: 69, socio: 1, stability: 4, battleground: 0, demInfl: 0, comInfl: 1, country: 'Bulgaria', region: 'Balkans', box: {x: 886, y: 1694}, adjacent: [66, 68, 71, , ]},
+ {name_unique: 'Razgrad', space_id: 70, socio: 8, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 954, y: 1620}, adjacent: [66, , , , ]},
+ {name_unique: 'Burgas', space_id: 71, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 1004, y: 1695}, adjacent: [66, 69, 72, , ]},
+ {name_unique: 'Varna', space_id: 72, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 1086, y: 1613}, adjacent: [63, 66, 71, , ]},
+ {name_unique: 'Bulgarian Writers', space_id: 73, socio: 5, stability: 2, battleground: 0, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 652, y: 1726}, adjacent: [67, , , , ]},
+ {name_unique: 'Plovdiv', space_id: 74, socio: 4, stability: 3, battleground: 1, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 771, y: 1739}, adjacent: [68, 75, , , ]},
+ {name_unique: 'Sliven', space_id: 75, socio: 3, stability: 4, battleground: 0, demInfl: 0, comInfl: 0, country: 'Bulgaria', region: 'Balkans', box: {x: 894, y: 1768}, adjacent: [74, , , , ]}
+]
+
+const cards = [
+ null,
+ {number: 1, period: 1, side: 'C', name: 'Legacy of Martial Law*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 2, period: 1, side: 'D', name: 'Solidarity Legalized*', ops: 4, remove: 1, playable: true, red: true},
+ {number: 3, period: 1, side: 'D', name: 'Walesa*', ops: 3, remove: 1, playable: false, red: false},
+ {number: 4, period: 1, side: 'D', name: 'Michnik*', ops: 1, remove: 1, playable: true, red: false},
+ {number: 5, period: 1, side: 'D', name: 'General Strike*', ops: 3, remove: 0, playable: true, red: false},
+ {number: 6, period: 1, side: 'C', name: 'Brought in for Questioning', ops: 3, remove: 0, playable: true, red: false},
+ {number: 7, period: 1, side: 'C', name: 'State Run Media*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 8, period: 1, side: 'N', name: 'Prudence', ops: 4, remove: 0, playable: true, red: false},
+ {number: 9, period: 1, side: 'C', name: 'The Wall*', ops: 1, remove: 1, playable: true, red: false},
+ {number: 10, period: 1, side: 'C', name: 'Cult of Personality*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 11, period: 1, side: 'C', name: 'Dissident Arrested', ops: 2, remove: 0, playable: true, red: false},
+ {number: 12, period: 1, side: 'C', name: 'Apparatchiks*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 13, period: 1, side: 'C', name: 'Stasi*', ops: 1, remove: 1, playable: true, red: false},
+ {number: 14, period: 1, side: 'N', name: 'Gorbachev Charms the West', ops: 4, remove: 0, playable: true, red: false},
+ {number: 15, period: 1, side: 'C', name: 'Honecker*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 16, period: 1, side: 'C', name: 'Nomenklatura*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 17, period: 1, side: 'D', name: 'Roundtable Talks', ops: 3, remove: 0, playable: true, red: false},
+ {number: 18, period: 1, side: 'C', name: 'Poszgay Defends the Revolution*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 19, period: 1, side: 'D', name: 'Papal Visit*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 20, period: 1, side: 'C', name: 'Deutsche Marks*', ops: 4, remove: 1, playable: true, red: false},
+ {number: 21, period: 1, side: 'N', name: 'Common European Home', ops: 2, remove: 0, playable: true, red: false},
+ {number: 22, period: 1, side: 'N', name: 'Power Struggle - Poland', ops: 0, remove: 0, playable: true, red: false},
+ {number: 23, period: 1, side: 'N', name: 'Power Struggle - Hungary', ops: 0, remove: 0, playable: true, red: false},
+ {number: 24, period: 1, side: 'D', name: 'St. Nicholas Church*', ops: 1, remove: 1, playable: true, red: true},
+ {number: 25, period: 1, side: 'C', name: 'Perestroika*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 26, period: 1, side: 'D', name: 'Helsinki Final Act*', ops: 1, remove: 1, playable: true, red: true},
+ {number: 27, period: 1, side: 'D', name: 'Consumerism', ops: 3, remove: 0, playable: true, red: false},
+ {number: 28, period: 1, side: 'C', name: 'Factory Party Cells', ops: 3, remove: 0, playable: true, red: false},
+ {number: 29, period: 1, side: 'D', name: 'Jan Palach Week*', ops: 1, remove: 1, playable: true, red: false},
+ {number: 30, period: 1, side: 'C', name: 'Tear Gas*', ops: 1, remove: 1, playable: true, red: false},
+ {number: 31, period: 1, side: 'D', name: 'Intelligentsia', ops: 2, remove: 0, playable: true, red: false},
+ {number: 32, period: 1, side: 'C', name: 'Peasant Parties*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 33, period: 1, side: 'D', name: 'Sajudis*', ops: 2, remove: 1, playable: true, red: true},
+ {number: 34, period: 1, side: 'D', name: 'Fidesz*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 35, period: 1, side: 'C', name: 'Heal Our Bleeding Wound*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 36, period: 1, side: 'D', name: 'Dash for the West*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 37, period: 1, side: 'C', name: 'Nagy Reburied*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 38, period: 1, side: 'C', name: 'The July Concept*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 39, period: 1, side: 'D', name: 'Eco-Glasnost*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 40, period: 1, side: 'D', name: 'Hungarian Democratic Forum*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 41, period: 2, side: 'C', name: 'Ceausescu*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 42, period: 2, side: 'N', name: 'Power Struggle - East Germany', ops: 0, remove: 0, playable: true, red: false},
+ {number: 43, period: 2, side: 'N', name: 'Power Struggle - Bulgaria', ops: 0, remove: 0, playable: true, red: false},
+ {number: 44, period: 2, side: 'N', name: 'Inflationary Currency*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 45, period: 2, side: 'D', name: 'Soviet Troop Withdrawals*', ops: 4, remove: 1, playable: true, red: false},
+ {number: 46, period: 2, side: 'D', name: 'Goodbye Lenin!*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 47, period: 2, side: 'C', name: 'Bulgarian Turks Expelled*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 48, period: 2, side: 'D', name: '\"We are the People!\"', ops: 3, remove: 1, playable: true, red: false},
+ {number: 49, period: 2, side: 'D', name: 'Foreign Currency Debt Burden', ops: 1, remove: 1, playable: true, red: false},
+ {number: 50, period: 2, side: 'D', name: 'The Sinatra Doctrine*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 51, period: 2, side: 'C', name: '40th Anniversary Celebration*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 52, period: 2, side: 'C', name: 'Normalization*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 53, period: 2, side: 'C', name: 'Li Peng*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 54, period: 2, side: 'D', name: 'The Crowd Turns Against Ceausescu*', ops: 3, remove: 1, playable: true, red: true},
+ {number: 55, period: 2, side: 'N', name: 'Power Struggle - Czechoslovakia', ops: 0, remove: 0, playable: true, red: false},
+ {number: 56, period: 2, side: 'D', name: 'Foreign Television*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 57, period: 2, side: 'C', name: 'Central Committee Reshuffle*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 58, period: 2, side: 'D', name: 'Austria-Hungary Border Reopened*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 59, period: 2, side: 'C', name: 'GrenzTruppen*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 60, period: 2, side: 'D', name: 'Toxic Waste*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 61, period: 2, side: 'D', name: 'The Monday Demonstrations*', ops: 4, remove: 1, playable: false, red: false},
+ {number: 62, period: 2, side: 'D', name: 'Yakovlev Counsels Gorbachev*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 63, period: 2, side: 'D', name: 'Genscher*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 64, period: 2, side: 'D', name: 'Legacy of 1968*', ops: 4, remove: 1, playable: true, red: false},
+ {number: 65, period: 2, side: 'D', name: 'Presidential Visit*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 66, period: 2, side: 'D', name: 'New Forum*', ops: 1, remove: 1, playable: true, red: false},
+ {number: 67, period: 2, side: 'N', name: 'Reformer Rehabilitated*', ops: 2, remove: 1, playable: false, red: false},
+ {number: 68, period: 2, side: 'D', name: 'Klaus and Komarek*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 69, period: 2, side: 'C', name: 'Systematization*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 70, period: 2, side: 'C', name: 'Securitate*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 71, period: 2, side: 'D', name: 'Kiss of Death*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 72, period: 2, side: 'D', name: 'Peasant Parties Revolt*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 73, period: 2, side: 'D', name: 'Laszlo Tokes*', ops: 2, remove: 1, playable: true, red: true},
+ {number: 74, period: 2, side: 'D', name: 'FRG Embassies*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 75, period: 2, side: 'D', name: 'Exit Visas*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 76, period: 2, side: 'C', name: 'Warsaw Pact Summit*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 77, period: 2, side: 'D', name: 'Samizdat*', ops: 1, remove: 1, playable: true, red: false},
+ {number: 78, period: 2, side: 'N', name: 'Workers Revolt', ops: 2, remove: 0, playable: true, red: false},
+ {number: 79, period: 2, side: 'C', name: 'The Third Way*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 80, period: 2, side: 'C', name: 'Nepotism*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 81, period: 2, side: 'D', name: 'The Baltic Way*', ops: 3, remove: 1, playable: false, red: true},
+ {number: 82, period: 3, side: 'C', name: 'Spitzel*', ops: 1, remove: 1, playable: true, red: false},
+ {number: 83, period: 3, side: 'C', name: 'Modrow*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 84, period: 3, side: 'D', name: 'Breakaway Baltic Republics*', ops: 4, remove: 1, playable: false, red: true},
+ {number: 85, period: 3, side: 'N', name: 'Tank Column/Tank Man*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 86, period: 3, side: 'D', name: '\"The Wall Must Go!\"*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 87, period: 3, side: 'D', name: 'Kohl Proposes Reunification*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 88, period: 3, side: 'C', name: 'Adamec*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 89, period: 3, side: 'D', name: 'Domino Theory*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 90, period: 3, side: 'D', name: 'Civic Forum*', ops: 4, remove: 1, playable: true, red: false},
+ {number: 91, period: 3, side: 'D', name: 'My First Banana*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 92, period: 3, side: 'C', name: 'Betrayal*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 93, period: 3, side: 'D', name: 'Shock Therapy*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 94, period: 3, side: 'D', name: 'Union of Democratic Forces*', ops: 4, remove: 1, playable: true, red: false},
+ {number: 95, period: 3, side: 'N', name: 'Power Struggle - Romania', ops: 0, remove: 0, playable: true, red: false},
+ {number: 96, period: 3, side: 'C', name: 'The Chinese Solution*', ops: 1, remove: 1, playable: false, red: false},
+ {number: 97, period: 3, side: 'D', name: 'The Tyrant is Gone*', ops: 2, remove: 1, playable: false, red: false},
+ {number: 98, period: 3, side: 'C', name: 'Politburo Intrigue*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 99, period: 3, side: 'C', name: 'Ligachev*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 100, period: 3, side: 'N', name: 'Stand Fast*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 101, period: 3, side: 'C', name: 'Elena*', ops: 1, remove: 1, playable: true, red: false},
+ {number: 102, period: 3, side: 'C', name: 'National Salvation Front*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 103, period: 3, side: 'D', name: 'Government Resigns*', ops: 1, remove: 1, playable: true, red: false},
+ {number: 104, period: 3, side: 'C', name: 'New Year\'s Eve Party*', ops: 2, remove: 1, playable: true, red: false},
+ {number: 105, period: 3, side: 'D', name: 'Public Against Violence*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 106, period: 3, side: 'C', name: 'Social Democratic Platform Adopted*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 107, period: 3, side: 'C', name: 'Massacre in Timisoara*', ops: 3, remove: 1, playable: false, red: false},
+ {number: 108, period: 3, side: 'D', name: 'Army Backs Revolution*', ops: 3, remove: 1, playable: true, red: false},
+ {number: 109, period: 3, side: 'C', name: 'Kremlin Coup!*', ops: 3, remove: 1, playable: false, red: false},
+ {number: 110, period: 3, side: 'D', name: 'Malta Summit*', ops: 3, remove: 1, playable: true, red: false},
+]
+
+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: '', socio: 0, url: 'ps26'},
+{number: 50, name: 'Support Surges', value: '', socio: 0, url: 'ps25'},
+{number: 51, name: 'Support Falters', value: '', socio: 0, url: 'ps24'},
+{number: 52, name: 'Tactic Fails', value: '', 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'},
+]
+
+
+if (typeof module !== 'undefined') module.exports = { spaces, cards, power_cards }
diff --git a/play.css b/play.css
index f9ed02e..2a65885 100644
--- a/play.css
+++ b/play.css
@@ -1,741 +1,741 @@
-main { background-color: dimgray; }
-header { background-color: silver; }
-header.your_turn { background-color: orange; }
-#role_Democrat { background-color: hsl(200, 80%, 80%); }
-#role_Communist { background-color: hsl(0, 80%, 80%); }
-#turn_info { background-color: white; }
-/*.aside_events {
- font-family: "Source Sans";
- font-style: normal;
- font-size: 16px;
- line-height: 1.5;
-}*/
-#deck_data {
- font-family: "Source Sans";
- font-style: normal;
- font-size: 16px;
- line-height: 1.5;
-}
-#deck_stat {padding-left: 5px; padding-bottom: 5px;}
-
-
-#log { background-color: whitesmoke; }
-#log .h1 { font-weight: bold; padding-top:2px; padding-bottom:2px; text-align: center; }
-#log .h2 { padding-top:2px; padding-bottom:2px; text-align: center; }
-#log .h3 { text-align: center; }
-#log .h4 { text-decoration: underline; }
-#log .h5 { text-decoration: underline; }
-
-#log .h2 { background-color: hsl(0,0%,80%);}
-#log .h1 { background-color: hsl(0,0%,80%); }
-#log .h2.dem { background-color: hsl(200, 80%, 80%); }
-#log .h2.com { background-color: hsl(0, 80%, 80%); }
-#log .h3.democrat { background-color: hsl(210,30%,90%); }
-#log .h3.h2.communist { background-color: hsl(35,40%,90%); }
-
-#log div { padding-left: 20px; text-indent: -12px; }
-#log div.i { padding-left: 32px; text-indent: -12px; }
-#log div.ii { padding-left: 44px; text-indent: -12px; }
-
-
-#log .card_name { font-style: italic; }
-#log .card_name:hover { text-decoration: underline; }
-#log .space_tip:hover { cursor: pointer; text-decoration: underline; }
-
-#log .die {
- display: inline-block;
- vertical-align: -3px;
- width: 12px;
- height: 12px;
- background-size: 600% 100%;
- background-repeat: no-repeat;
- background-image: url(images/die_black_pips.svg);
- background-color: #fff;
- border: 1px solid #444;
-}
-
-#log .d0 { background-position: -100% 0 }
-#log .d1 { background-position: 0% 0; }
-#log .d2 { background-position: 20% 0; }
-#log .d3 { background-position: 40% 0; }
-#log .d4 { background-position: 60% 0; }
-#log .d5 { background-position: 80% 0; }
-#log .d6 { background-position: 100% 0; }
-
-.selected {
- cursor: pointer;
-}
-
-#log {
- font-variant-numeric: tabular-nums;
-}
-
-/* TOOLBAR */
-
-#toolbar {
- justify-content: space-evenly;
-}
-
-#prompt {
- display: flex;
- margin-left: auto;
-}
-
-#button {
- display: flex;
- margin-left: auto;
-}
-/* MAP */
-
-#map {
- margin: 0 auto ;
- position: relative;
- background-repeat: no-repeat;
- background-size: cover;
- width: 1275px; /* was 1275*/
- height: 2000px;
- /*border: solid black;*/
- overflow: clip;
- box-shadow: 0px 1px 10px #0008;
- /*z-index: 3;*/
-}
-
-#map { background-image: url(1989_map.jpg) }
-
-/* Containers to appear on hover*/
- #overlay {
- position: relative;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- /* background-color: rgba(255, 255, 255, 0.8); /* Semi-transparent overlay */
- /* display: none;*/
- justify-content: center;
- align-items: center;
- text-align: left;
- }
-
-/* SPACES */
-
-.space-area {
- position: absolute;
- box-sizing: border-box;
- border: transparent red 2px;
-}
-
-/* PANELS AND HANDS */
-
-.panel {
- background-color: #555;
- display: inline-block;
-}
-
-.panel_header {
- background-color: #444;
- color: hsl(40, 60%, 90%);
- font-weight: bold;
- text-align: center;
- padding: 3px 1em;
-}
-
-.hide {
- display: none;
-}
-
-#hand_panel, #events_panel, #played_card_panel, #table_panel, #samizdat_panel, #opp_hand_panel, #power_panel, #ceausescu_panel {
- min-width: 200px;
- width: auto;
- /*display: inline-block;*/
- margin: 10px;
- border-radius: 5px;
-}
-
-#events {
- display: flex;
-}
-
-#discard_panel, #removed_panel {
- min-width: 200px;
- width: auto;
- display: inline-block;
- margin: 10px;
- border-radius: 5px;
-}
-
-#discard_panel.hide, #removed_panel.hide {
- display: none;
-}
-
-#hand_panel {
- margin: 10px;
- border-radius: 5px;
-}
-
-/* INFLUENCE MARKERS */
-
-.demInfl {
- position: absolute;
- box-sizing: border-box;
- bottom: 1px;
- left: 6px;
- height: 35px;
- width: 35px;
- border-radius: 5px;
-}
-
-.demInfl.controlled {
- background-image: url(images/US_blank.gif);
- background-size: contain;
-}
-
-
-.demInfl.uncontrolled {
- background-image: url(images/USd_blank.gif);
- background-size: contain;
-}
-/*
-.demInfl:hover {
- cursor: pointer;
-}*/
-
-.comInfl {
- position: absolute;
- box-sizing: border-box;
- bottom: 1px;
- right: 6px;
- height: 35px;
- width: 35px;
-}
-/*
-.comInfl:hover {
- cursor: pointer;
-}*/
-
-.comInfl.controlled {
- background-image: url(images/SV_blank.gif);
- background-size: contain;
-}
-
-
-.comInfl.uncontrolled {
- background-image: url(images/SVd_blank.gif);
- background-size: contain;
-}
-
-.demInflValue {
- position: absolute;
- box-sizing: border-box;
- font-family: 'Open Sans';
- font-size: 20px;
- font-weight: bold;
- top: 10px;
- left: 16px;
-}
-
-.demInflValue_10 {
- position: absolute;
- box-sizing: border-box;
- font-family: 'Open Sans';
- font-size: 20px;
- font-weight: bold;
- top: 10px;
- left: 10px;
-}
-
-.comInflValue {
- position: absolute;
- box-sizing: border-box;
- font-family: 'Open Sans';
- font-size: 20px;
- font-weight: bold;
- top: 12px;
- left: 74px;
-}
-
-.comInflValue_10 {
- position: absolute;
- box-sizing: border-box;
- font-family: 'Open Sans';
- font-size: 20px;
- font-weight: bold;
- top: 12px;
- left: 68px;
-}
-
-.comInflValue.controlled, .held {
- color: whitesmoke;
- text-shadow:
- 1px 1px 0 #c2272d, /* Right bottom */
- -1px 1px 0 #c2272d, /* Left bottom */
- 1px -1px 0 #c2272d, /* Right top */
- -1px -1px 0 #c2272d; /* Left top */
-}
-
-.comInflValue.uncontrolled {
- color: #c2272d;
- text-shadow:
- 1px 1px 0 #ffffff, /* Right bottom */
- -1px 1px 0 #ffffff, /* Left bottom */
- 1px -1px 0 #ffffff, /* Right top */
- -1px -1px 0 #ffffff; /* Left top */
-}
-
-.comInflValue_10.controlled, .held {
- color: whitesmoke;
- text-shadow:
- 1px 1px 0 #c2272d, /* Right bottom */
- -1px 1px 0 #c2272d, /* Left bottom */
- 1px -1px 0 #c2272d, /* Right top */
- -1px -1px 0 #c2272d; /* Left top */
-}
-
-.comInflValue_10.uncontrolled {
- color: #c2272d;
- text-shadow:
- 1px 1px 0 #ffffff, /* Right bottom */
- -1px 1px 0 #ffffff, /* Left bottom */
- 1px -1px 0 #ffffff, /* Right top */
- -1px -1px 0 #ffffff; /* Left top */
-}
-
-
-/* GAME MARKERS */
-
-.t0 {left: 511px}
-.t1 {left: 511px}
-.t2 {left: 553px}
-.t3 {left: 595px}
-.t4 {left: 637px}
-.t5 {left: 679px}
-.t6 {left: 721px}
-.t7 {left: 763px}
-.t8 {left: 805px}
-.t9 {left: 847px}
-.t10 {left: 889px}
-
-#turn-tracker {
- position:absolute;
- top: 65px;
- height: 35px;
- width: 36px;
- /*display: block;*/
-}
-
-.r0 {left: 554px}
-.r1 {left: 554px}
-.r2 {left: 596px}
-.r3 {left: 638px}
-.r4 {left: 680px}
-.r5 {left: 722px}
-.r6 {left: 764px}
-.r7 {left: 806px}
-.r8 {left: 848px}
-
-.dem-action-round-tracker { background-image: url(images/US_Action_Round.gif);}
-.com-action-round-tracker { background-image: url(images/SV_Action_Round.gif);}
-
-#action-round-tracker {
- position: absolute;
- top: 114px;
- height: 30px;
- width: 35px;
- background-size: cover;
-}
-
-
-
-#stability-track {
- position:absolute;
- left: 1085px;
- height: 35px;
- width: 35px;
-}
-
-.s0 {top: 853px}
-.s1 {top: 896px}
-.s2 {top: 939px}
-.s3 {top: 982px}
-.s4 {top: 1025px}
-
-
-.tst0 {left: 0}
-.tst1 {left: 38px}
-.tst2 {left: 93px}
-.tst3 {left: 148px}
-.tst4 {left: 203px}
-.tst5 {left: 258px}
-.tst6 {left: 313px}
-.tst7 {left: 368px}
-.tst8 {left: 436px}
-
-#dem-TST {
- position: absolute;
- top: 1680px;
- height: 35px;
- width: 35px;
-}
-
-#com-TST {
- position: absolute;
- top: 1782px;
- height: 35px;
- width: 35px;
-}
-
-.vp0 {top: 1913px;
-left: 660px}
-
-.vp-20, .vp-18, .vp-16, .vp-14, .vp-12, .vp-10, .vp-8, .vp-6, .vp-4, .vp-2, .vp1, .vp3, .vp5, .vp7, .vp9, .vp11, .vp13, .vp15, .vp17, .vp19 {top: 1889px}
-.vp-19, .vp-17, .vp-15, .vp-13, .vp-11, .vp-9, .vp-7, .vp-5, .vp-3, .vp-1, .vp2, .vp4, .vp6, .vp8, .vp10, .vp12, .vp14, .vp16, .vp18, .vp20 {top: 1938px}
-
-.vp-21 {top: 1912px; left: 117px}
-.vp21 {top: 1912px; left: 1182px}
-
-.vp-20 {left: 165px}
-.vp-19 {left: 189px}
-.vp-18 {left: 214px}
-.vp-17 {left: 238px}
-.vp-16 {left: 263px}
-.vp-15 {left: 287px}
-.vp-14 {left: 312px}
-.vp-13 {left: 336px}
-.vp-12 {left: 361px}
-.vp-11 {left: 385px}
-.vp-10 {left: 410px}
-.vp-9 {left: 434px}
-.vp-8 {left: 459px}
-.vp-7 {left: 483px}
-.vp-6 {left: 508px}
-.vp-5 {left: 532px}
-.vp-4 {left: 557px}
-.vp-3 {left: 581px}
-.vp-2 {left: 606px}
-.vp-1 {left: 630px}
-.vp1 {left: 692px}
-.vp2 {left: 717px}
-.vp3 {left: 741px}
-.vp4 {left: 766px}
-.vp5 {left: 790px}
-.vp6 {left: 815px}
-.vp7 {left: 839px}
-.vp8 {left: 864px}
-.vp9 {left: 888px}
-.vp10 {left: 913px}
-.vp11 {left: 937px}
-.vp12 {left: 962px}
-.vp13 {left: 986px}
-.vp14 {left: 1011px}
-.vp15 {left: 1035px}
-.vp16 {left: 1060px}
-.vp17 {left: 1084px}
-.vp18 {left: 1109px}
-.vp19 {left: 1133px}
-.vp20 {left: 1158px}
-
-#vp {
- position: absolute;
- height: 40px;
- width: 40px;
-}
-
-.marker {
- position: absolute;
- height: 30px;
- width: 30px;
-}
-
-.revolution {background-image: url(images/US_blank.gif); background-size: contain}
-.held {background-image: url(images/SV_blank.gif); background-size: contain}
-
-.germany {top: 127px; left: 439px}
-.poland { top: 232px; left: 934px}
-.czech {top: 494px; left: 362px}
-.hungary {top: 1041px; left: 813px}
-.romania {top: 1063px; left: 1012px}
-.bulgaria {top: 1578px; left: 720px}
-
-.times_held {
- position: absolute;
- font-family: 'Open Sans';
- font-size: 20px;
- font-weight: bold;
- top: -18px;
- left: 8px
-}
-
-.outlined_text {
- text-shadow:
- 1px 1px 0 #ffffff, /* Right bottom */
- -1px 1px 0 #ffffff, /* Left bottom */
- 1px -1px 0 #ffffff, /* Right top */
- -1px -1px 0 #ffffff; /* Left top */
-}
-
-/* ============= EVENT MARKERS ========== */
-
-.event-marker {
- display: none;
- position: absolute;
- height: 30px;
- width: 30px;
- transition: transform 0.3s ease;
-}
-
-.event-marker:hover {
- cursor: pointer;
- transform: scale(2);
- z-index: 1;
-}
-
-.event-marker.aside {
- border: solid black 1.5px;
- margin: 3px;
- position: relative;
-}
-
-#turn_info {
- display: flex;
- flex-direction: column;
- align-items: flex-start;
-}
-
-#turn_info > div {
- display: flex;
- margin-bottom: 8px;
- gap: 4px;
-}
-
-#turn_info > img {
- display: block;
-
-}
-
-/*Solidarity legalised*/
-#event_2 {
- top: 216px;
- left: 612px;
-}
-
-/*Systematisation*/
-#event_69 {
- height: 65px;
- width: 65px;
-}
-
-/*The Tyrant is Gone*/
-#event_97 {
- height: 40px;
- width: 40px;
-}
-
-/*The Wall*/
-#event_9 {
- top: 143px;
- left: 170px;
-}
-
-
-/* =========== CARDS ================= */
-/*
-.playedCard {
- display: flex;
- margin: auto;
- height: 300px;
-}*/
-
-.hand_card {
- background-size: contain;
- height: 250px;
- margin: 10px;
- border-radius: 5px;
- transition: transform .3s ease 0.5s;
-}
-/*
-.hand_card:hover {
- cursor: pointer;
-}*/
-
-.zoom {
- transform: scale(1.75)
-}
-
-.power_card {
- background-size: contain;
- height: 250px;
- margin: 10px;
- border-radius: 5px;
-}
-
-.discard_card, .event_card {
- background-size: contain;
- height: 150px;
- margin: 5px;
- border-radius: 5px;
- transition: transform .3s ease;
-}
-
-.discard_card:hover, .event_card:hover {
- /*cursor: pointer;*/
- transform: scale(2);
-}
-
-.selected.space-area {
- background-color: #0002;
- outline: solid white 2px;
- /*box-shadow: 0 0 4px white; */
- border-radius: 10px 10px 0 0;
-}
-
-.space-area.tip {
- background-color: #ff08;
- outline: solid white 2px;
- box-shadow: 0 0 8px #ff08;
- border-radius: 10px 10px 0 0;
-}
-
-.selected.hand_card {
- outline: solid silver 3px;
- /*box-shadow: 0 0 4px white; */
- border-radius: 18px;
-}
-
-
-.selected.power_card {
- outline: solid silver 3px;
- /*box-shadow: 0 0 4px white; */
- border-radius: 18px;
-}
-
-/* =============== OTHER ===============*/
-#space-characteristics {display: none}
-
-/* =============== CARD IMAGES =========*/
-
-#tooltip {
- position: fixed;
- pointer-events: none;
- z-index: 600;
- right: 240px;
- top: 60px;
-}
-
-.card {
- background-size: cover;
- background-repeat: no-repeat;
- width: 250px;
- height: 350px;
- border-radius: 16px;
- box-shadow: 1px 2px 4px #0004;
-}
-
-.card_1 {background-image: url(cards/e1.gif)}
-.card_2 {background-image: url(cards/e2.gif)}
-.card_3 {background-image: url(cards/e3.gif)}
-.card_4 {background-image: url(cards/e4.gif)}
-.card_5 {background-image: url(cards/e5.gif)}
-.card_6 {background-image: url(cards/e6.gif)}
-.card_7 {background-image: url(cards/e7.gif)}
-.card_8 {background-image: url(cards/e8.gif)}
-.card_9 {background-image: url(cards/e9.gif)}
-.card_10 {background-image: url(cards/e10.gif)}
-.card_11 {background-image: url(cards/e11.gif)}
-.card_12 {background-image: url(cards/e12.gif)}
-.card_13 {background-image: url(cards/e13.gif)}
-.card_14 {background-image: url(cards/e14.gif)}
-.card_15 {background-image: url(cards/e15.gif)}
-.card_16 {background-image: url(cards/e16.gif)}
-.card_17 {background-image: url(cards/e17.gif)}
-.card_18 {background-image: url(cards/e18.gif)}
-.card_19 {background-image: url(cards/e19.gif)}
-.card_20 {background-image: url(cards/e20.gif)}
-.card_21 {background-image: url(cards/e21.gif)}
-.card_22 {background-image: url(cards/e22.gif)}
-.card_23 {background-image: url(cards/e23.gif)}
-.card_24 {background-image: url(cards/e24.gif)}
-.card_25 {background-image: url(cards/e25.gif)}
-.card_26 {background-image: url(cards/e26.gif)}
-.card_27 {background-image: url(cards/e27.gif)}
-.card_28 {background-image: url(cards/e28.gif)}
-.card_29 {background-image: url(cards/e29.gif)}
-.card_30 {background-image: url(cards/e30.gif)}
-.card_31 {background-image: url(cards/e31.gif)}
-.card_32 {background-image: url(cards/e32.gif)}
-.card_33 {background-image: url(cards/e33.gif)}
-.card_34 {background-image: url(cards/e34.gif)}
-.card_35 {background-image: url(cards/e35.gif)}
-.card_36 {background-image: url(cards/e36.gif)}
-.card_37 {background-image: url(cards/e37.gif)}
-.card_38 {background-image: url(cards/e38.gif)}
-.card_39 {background-image: url(cards/e39.gif)}
-.card_40 {background-image: url(cards/e40.gif)}
-.card_41 {background-image: url(cards/e41.gif)}
-.card_42 {background-image: url(cards/e42.gif)}
-.card_43 {background-image: url(cards/e43.gif)}
-.card_44 {background-image: url(cards/e44.gif)}
-.card_45 {background-image: url(cards/e45.gif)}
-.card_46 {background-image: url(cards/e46.gif)}
-.card_47 {background-image: url(cards/e47.gif)}
-.card_48 {background-image: url(cards/e48.gif)}
-.card_49 {background-image: url(cards/e49.gif)}
-.card_50 {background-image: url(cards/e50.gif)}
-.card_51 {background-image: url(cards/e51.gif)}
-.card_52 {background-image: url(cards/e52.gif)}
-.card_53 {background-image: url(cards/e53.gif)}
-.card_54 {background-image: url(cards/e54.gif)}
-.card_55 {background-image: url(cards/e55.gif)}
-.card_56 {background-image: url(cards/e56.gif)}
-.card_57 {background-image: url(cards/e57.gif)}
-.card_58 {background-image: url(cards/e58.gif)}
-.card_59 {background-image: url(cards/e59.gif)}
-.card_60 {background-image: url(cards/e60.gif)}
-.card_61 {background-image: url(cards/e61.gif)}
-.card_62 {background-image: url(cards/e62.gif)}
-.card_63 {background-image: url(cards/e63.gif)}
-.card_64 {background-image: url(cards/e64.gif)}
-.card_65 {background-image: url(cards/e65.gif)}
-.card_66 {background-image: url(cards/e66.gif)}
-.card_67 {background-image: url(cards/e67.gif)}
-.card_68 {background-image: url(cards/e68.gif)}
-.card_69 {background-image: url(cards/e69.gif)}
-.card_70 {background-image: url(cards/e70.gif)}
-.card_71 {background-image: url(cards/e71.gif)}
-.card_72 {background-image: url(cards/e72.gif)}
-.card_73 {background-image: url(cards/e73.gif)}
-.card_74 {background-image: url(cards/e74.gif)}
-.card_75 {background-image: url(cards/e75.gif)}
-.card_76 {background-image: url(cards/e76.gif)}
-.card_77 {background-image: url(cards/e77.gif)}
-.card_78 {background-image: url(cards/e78.gif)}
-.card_79 {background-image: url(cards/e79.gif)}
-.card_80 {background-image: url(cards/e80.gif)}
-.card_81 {background-image: url(cards/e81.gif)}
-.card_82 {background-image: url(cards/e82.gif)}
-.card_83 {background-image: url(cards/e83.gif)}
-.card_84 {background-image: url(cards/e84.gif)}
-.card_85 {background-image: url(cards/e85.gif)}
-.card_86 {background-image: url(cards/e86.gif)}
-.card_87 {background-image: url(cards/e87.gif)}
-.card_88 {background-image: url(cards/e88.gif)}
-.card_89 {background-image: url(cards/e89.gif)}
-.card_90 {background-image: url(cards/e90.gif)}
-.card_91 {background-image: url(cards/e91.gif)}
-.card_92 {background-image: url(cards/e92.gif)}
-.card_93 {background-image: url(cards/e93.gif)}
-.card_94 {background-image: url(cards/e94.gif)}
-.card_95 {background-image: url(cards/e95.gif)}
-.card_96 {background-image: url(cards/e96.gif)}
-.card_97 {background-image: url(cards/e97.gif)}
-.card_98 {background-image: url(cards/e98.gif)}
-.card_99 {background-image: url(cards/e99.gif)}
-.card_100 {background-image: url(cards/e100.gif)}
-.card_101 {background-image: url(cards/e101.gif)}
-.card_102 {background-image: url(cards/e102.gif)}
-.card_103 {background-image: url(cards/e103.gif)}
-.card_104 {background-image: url(cards/e104.gif)}
-.card_105 {background-image: url(cards/e105.gif)}
-.card_106 {background-image: url(cards/e106.gif)}
-.card_107 {background-image: url(cards/e107.gif)}
-.card_108 {background-image: url(cards/e108.gif)}
-.card_109 {background-image: url(cards/e109.gif)}
-.card_110 {background-image: url(cards/e110.gif)}
+main { background-color: dimgray; }
+header { background-color: silver; }
+header.your_turn { background-color: orange; }
+#role_Democrat { background-color: hsl(200, 80%, 80%); }
+#role_Communist { background-color: hsl(0, 80%, 80%); }
+#turn_info { background-color: white; }
+/*.aside_events {
+ font-family: "Source Sans";
+ font-style: normal;
+ font-size: 16px;
+ line-height: 1.5;
+}*/
+#deck_data {
+ font-family: "Source Sans";
+ font-style: normal;
+ font-size: 16px;
+ line-height: 1.5;
+}
+#deck_stat {padding-left: 5px; padding-bottom: 5px;}
+
+
+#log { background-color: whitesmoke; }
+#log .h1 { font-weight: bold; padding-top:2px; padding-bottom:2px; text-align: center; }
+#log .h2 { padding-top:2px; padding-bottom:2px; text-align: center; }
+#log .h3 { text-align: center; }
+#log .h4 { text-decoration: underline; }
+#log .h5 { text-decoration: underline; }
+
+#log .h2 { background-color: hsl(0,0%,80%);}
+#log .h1 { background-color: hsl(0,0%,80%); }
+#log .h2.dem { background-color: hsl(200, 80%, 80%); }
+#log .h2.com { background-color: hsl(0, 80%, 80%); }
+#log .h3.democrat { background-color: hsl(210,30%,90%); }
+#log .h3.h2.communist { background-color: hsl(35,40%,90%); }
+
+#log div { padding-left: 20px; text-indent: -12px; }
+#log div.i { padding-left: 32px; text-indent: -12px; }
+#log div.ii { padding-left: 44px; text-indent: -12px; }
+
+
+#log .card_name { font-style: italic; }
+#log .card_name:hover { text-decoration: underline; }
+#log .space_tip:hover { cursor: pointer; text-decoration: underline; }
+
+#log .die {
+ display: inline-block;
+ vertical-align: -3px;
+ width: 12px;
+ height: 12px;
+ background-size: 600% 100%;
+ background-repeat: no-repeat;
+ background-image: url(images/die_black_pips.svg);
+ background-color: #fff;
+ border: 1px solid #444;
+}
+
+#log .d0 { background-position: -100% 0 }
+#log .d1 { background-position: 0% 0; }
+#log .d2 { background-position: 20% 0; }
+#log .d3 { background-position: 40% 0; }
+#log .d4 { background-position: 60% 0; }
+#log .d5 { background-position: 80% 0; }
+#log .d6 { background-position: 100% 0; }
+
+.selected {
+ cursor: pointer;
+}
+
+#log {
+ font-variant-numeric: tabular-nums;
+}
+
+/* TOOLBAR */
+
+#toolbar {
+ justify-content: space-evenly;
+}
+
+#prompt {
+ display: flex;
+ margin-left: auto;
+}
+
+#button {
+ display: flex;
+ margin-left: auto;
+}
+/* MAP */
+
+#map {
+ margin: 0 auto ;
+ position: relative;
+ background-repeat: no-repeat;
+ background-size: cover;
+ width: 1275px; /* was 1275*/
+ height: 2000px;
+ /*border: solid black;*/
+ overflow: clip;
+ box-shadow: 0px 1px 10px #0008;
+ /*z-index: 3;*/
+}
+
+#map { background-image: url(1989_map.jpg) }
+
+/* Containers to appear on hover*/
+ #overlay {
+ position: relative;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ /* background-color: rgba(255, 255, 255, 0.8); /* Semi-transparent overlay */
+ /* display: none;*/
+ justify-content: center;
+ align-items: center;
+ text-align: left;
+ }
+
+/* SPACES */
+
+.space-area {
+ position: absolute;
+ box-sizing: border-box;
+ border: transparent red 2px;
+}
+
+/* PANELS AND HANDS */
+
+.panel {
+ background-color: #555;
+ display: inline-block;
+}
+
+.panel_header {
+ background-color: #444;
+ color: hsl(40, 60%, 90%);
+ font-weight: bold;
+ text-align: center;
+ padding: 3px 1em;
+}
+
+.hide {
+ display: none;
+}
+
+#hand_panel, #events_panel, #played_card_panel, #table_panel, #samizdat_panel, #opp_hand_panel, #power_panel, #ceausescu_panel {
+ min-width: 200px;
+ width: auto;
+ /*display: inline-block;*/
+ margin: 10px;
+ border-radius: 5px;
+}
+
+#events {
+ display: flex;
+}
+
+#discard_panel, #removed_panel {
+ min-width: 200px;
+ width: auto;
+ display: inline-block;
+ margin: 10px;
+ border-radius: 5px;
+}
+
+#discard_panel.hide, #removed_panel.hide {
+ display: none;
+}
+
+#hand_panel {
+ margin: 10px;
+ border-radius: 5px;
+}
+
+/* INFLUENCE MARKERS */
+
+.demInfl {
+ position: absolute;
+ box-sizing: border-box;
+ bottom: 1px;
+ left: 6px;
+ height: 35px;
+ width: 35px;
+ border-radius: 5px;
+}
+
+.demInfl.controlled {
+ background-image: url(images/US_blank.gif);
+ background-size: contain;
+}
+
+
+.demInfl.uncontrolled {
+ background-image: url(images/USd_blank.gif);
+ background-size: contain;
+}
+/*
+.demInfl:hover {
+ cursor: pointer;
+}*/
+
+.comInfl {
+ position: absolute;
+ box-sizing: border-box;
+ bottom: 1px;
+ right: 6px;
+ height: 35px;
+ width: 35px;
+}
+/*
+.comInfl:hover {
+ cursor: pointer;
+}*/
+
+.comInfl.controlled {
+ background-image: url(images/SV_blank.gif);
+ background-size: contain;
+}
+
+
+.comInfl.uncontrolled {
+ background-image: url(images/SVd_blank.gif);
+ background-size: contain;
+}
+
+.demInflValue {
+ position: absolute;
+ box-sizing: border-box;
+ font-family: 'Open Sans';
+ font-size: 20px;
+ font-weight: bold;
+ top: 10px;
+ left: 16px;
+}
+
+.demInflValue_10 {
+ position: absolute;
+ box-sizing: border-box;
+ font-family: 'Open Sans';
+ font-size: 20px;
+ font-weight: bold;
+ top: 10px;
+ left: 10px;
+}
+
+.comInflValue {
+ position: absolute;
+ box-sizing: border-box;
+ font-family: 'Open Sans';
+ font-size: 20px;
+ font-weight: bold;
+ top: 12px;
+ left: 74px;
+}
+
+.comInflValue_10 {
+ position: absolute;
+ box-sizing: border-box;
+ font-family: 'Open Sans';
+ font-size: 20px;
+ font-weight: bold;
+ top: 12px;
+ left: 68px;
+}
+
+.comInflValue.controlled, .held {
+ color: whitesmoke;
+ text-shadow:
+ 1px 1px 0 #c2272d, /* Right bottom */
+ -1px 1px 0 #c2272d, /* Left bottom */
+ 1px -1px 0 #c2272d, /* Right top */
+ -1px -1px 0 #c2272d; /* Left top */
+}
+
+.comInflValue.uncontrolled {
+ color: #c2272d;
+ text-shadow:
+ 1px 1px 0 #ffffff, /* Right bottom */
+ -1px 1px 0 #ffffff, /* Left bottom */
+ 1px -1px 0 #ffffff, /* Right top */
+ -1px -1px 0 #ffffff; /* Left top */
+}
+
+.comInflValue_10.controlled, .held {
+ color: whitesmoke;
+ text-shadow:
+ 1px 1px 0 #c2272d, /* Right bottom */
+ -1px 1px 0 #c2272d, /* Left bottom */
+ 1px -1px 0 #c2272d, /* Right top */
+ -1px -1px 0 #c2272d; /* Left top */
+}
+
+.comInflValue_10.uncontrolled {
+ color: #c2272d;
+ text-shadow:
+ 1px 1px 0 #ffffff, /* Right bottom */
+ -1px 1px 0 #ffffff, /* Left bottom */
+ 1px -1px 0 #ffffff, /* Right top */
+ -1px -1px 0 #ffffff; /* Left top */
+}
+
+
+/* GAME MARKERS */
+
+.t0 {left: 511px}
+.t1 {left: 511px}
+.t2 {left: 553px}
+.t3 {left: 595px}
+.t4 {left: 637px}
+.t5 {left: 679px}
+.t6 {left: 721px}
+.t7 {left: 763px}
+.t8 {left: 805px}
+.t9 {left: 847px}
+.t10 {left: 889px}
+
+#turn-tracker {
+ position:absolute;
+ top: 65px;
+ height: 35px;
+ width: 36px;
+ /*display: block;*/
+}
+
+.r0 {left: 554px}
+.r1 {left: 554px}
+.r2 {left: 596px}
+.r3 {left: 638px}
+.r4 {left: 680px}
+.r5 {left: 722px}
+.r6 {left: 764px}
+.r7 {left: 806px}
+.r8 {left: 848px}
+
+.dem-action-round-tracker { background-image: url(images/US_Action_Round.gif);}
+.com-action-round-tracker { background-image: url(images/SV_Action_Round.gif);}
+
+#action-round-tracker {
+ position: absolute;
+ top: 114px;
+ height: 30px;
+ width: 35px;
+ background-size: cover;
+}
+
+
+
+#stability-track {
+ position:absolute;
+ left: 1085px;
+ height: 35px;
+ width: 35px;
+}
+
+.s0 {top: 853px}
+.s1 {top: 896px}
+.s2 {top: 939px}
+.s3 {top: 982px}
+.s4 {top: 1025px}
+
+
+.tst0 {left: 0}
+.tst1 {left: 38px}
+.tst2 {left: 93px}
+.tst3 {left: 148px}
+.tst4 {left: 203px}
+.tst5 {left: 258px}
+.tst6 {left: 313px}
+.tst7 {left: 368px}
+.tst8 {left: 436px}
+
+#dem-TST {
+ position: absolute;
+ top: 1680px;
+ height: 35px;
+ width: 35px;
+}
+
+#com-TST {
+ position: absolute;
+ top: 1782px;
+ height: 35px;
+ width: 35px;
+}
+
+.vp0 {top: 1913px;
+left: 660px}
+
+.vp-20, .vp-18, .vp-16, .vp-14, .vp-12, .vp-10, .vp-8, .vp-6, .vp-4, .vp-2, .vp1, .vp3, .vp5, .vp7, .vp9, .vp11, .vp13, .vp15, .vp17, .vp19 {top: 1889px}
+.vp-19, .vp-17, .vp-15, .vp-13, .vp-11, .vp-9, .vp-7, .vp-5, .vp-3, .vp-1, .vp2, .vp4, .vp6, .vp8, .vp10, .vp12, .vp14, .vp16, .vp18, .vp20 {top: 1938px}
+
+.vp-21 {top: 1912px; left: 117px}
+.vp21 {top: 1912px; left: 1182px}
+
+.vp-20 {left: 165px}
+.vp-19 {left: 189px}
+.vp-18 {left: 214px}
+.vp-17 {left: 238px}
+.vp-16 {left: 263px}
+.vp-15 {left: 287px}
+.vp-14 {left: 312px}
+.vp-13 {left: 336px}
+.vp-12 {left: 361px}
+.vp-11 {left: 385px}
+.vp-10 {left: 410px}
+.vp-9 {left: 434px}
+.vp-8 {left: 459px}
+.vp-7 {left: 483px}
+.vp-6 {left: 508px}
+.vp-5 {left: 532px}
+.vp-4 {left: 557px}
+.vp-3 {left: 581px}
+.vp-2 {left: 606px}
+.vp-1 {left: 630px}
+.vp1 {left: 692px}
+.vp2 {left: 717px}
+.vp3 {left: 741px}
+.vp4 {left: 766px}
+.vp5 {left: 790px}
+.vp6 {left: 815px}
+.vp7 {left: 839px}
+.vp8 {left: 864px}
+.vp9 {left: 888px}
+.vp10 {left: 913px}
+.vp11 {left: 937px}
+.vp12 {left: 962px}
+.vp13 {left: 986px}
+.vp14 {left: 1011px}
+.vp15 {left: 1035px}
+.vp16 {left: 1060px}
+.vp17 {left: 1084px}
+.vp18 {left: 1109px}
+.vp19 {left: 1133px}
+.vp20 {left: 1158px}
+
+#vp {
+ position: absolute;
+ height: 40px;
+ width: 40px;
+}
+
+.marker {
+ position: absolute;
+ height: 30px;
+ width: 30px;
+}
+
+.revolution {background-image: url(images/US_blank.gif); background-size: contain}
+.held {background-image: url(images/SV_blank.gif); background-size: contain}
+
+.germany {top: 127px; left: 439px}
+.poland { top: 232px; left: 934px}
+.czech {top: 494px; left: 362px}
+.hungary {top: 1041px; left: 813px}
+.romania {top: 1063px; left: 1012px}
+.bulgaria {top: 1578px; left: 720px}
+
+.times_held {
+ position: absolute;
+ font-family: 'Open Sans';
+ font-size: 20px;
+ font-weight: bold;
+ top: -18px;
+ left: 8px
+}
+
+.outlined_text {
+ text-shadow:
+ 1px 1px 0 #ffffff, /* Right bottom */
+ -1px 1px 0 #ffffff, /* Left bottom */
+ 1px -1px 0 #ffffff, /* Right top */
+ -1px -1px 0 #ffffff; /* Left top */
+}
+
+/* ============= EVENT MARKERS ========== */
+
+.event-marker {
+ display: none;
+ position: absolute;
+ height: 30px;
+ width: 30px;
+ transition: transform 0.3s ease;
+}
+
+.event-marker:hover {
+ cursor: pointer;
+ transform: scale(2);
+ z-index: 1;
+}
+
+.event-marker.aside {
+ border: solid black 1.5px;
+ margin: 3px;
+ position: relative;
+}
+
+#turn_info {
+ display: flex;
+ flex-direction: column;
+ align-items: flex-start;
+}
+
+#turn_info > div {
+ display: flex;
+ margin-bottom: 8px;
+ gap: 4px;
+}
+
+#turn_info > img {
+ display: block;
+
+}
+
+/*Solidarity legalised*/
+#event_2 {
+ top: 216px;
+ left: 612px;
+}
+
+/*Systematisation*/
+#event_69 {
+ height: 65px;
+ width: 65px;
+}
+
+/*The Tyrant is Gone*/
+#event_97 {
+ height: 40px;
+ width: 40px;
+}
+
+/*The Wall*/
+#event_9 {
+ top: 143px;
+ left: 170px;
+}
+
+
+/* =========== CARDS ================= */
+/*
+.playedCard {
+ display: flex;
+ margin: auto;
+ height: 300px;
+}*/
+
+.hand_card {
+ background-size: contain;
+ height: 250px;
+ margin: 10px;
+ border-radius: 5px;
+ transition: transform .3s ease 0.5s;
+}
+/*
+.hand_card:hover {
+ cursor: pointer;
+}*/
+
+.zoom {
+ transform: scale(1.75)
+}
+
+.power_card {
+ background-size: contain;
+ height: 250px;
+ margin: 10px;
+ border-radius: 5px;
+}
+
+.discard_card, .event_card {
+ background-size: contain;
+ height: 150px;
+ margin: 5px;
+ border-radius: 5px;
+ transition: transform .3s ease;
+}
+
+.discard_card:hover, .event_card:hover {
+ /*cursor: pointer;*/
+ transform: scale(2);
+}
+
+.selected.space-area {
+ background-color: #0002;
+ outline: solid white 2px;
+ /*box-shadow: 0 0 4px white; */
+ border-radius: 10px 10px 0 0;
+}
+
+.space-area.tip {
+ background-color: #ff08;
+ outline: solid white 2px;
+ box-shadow: 0 0 8px #ff08;
+ border-radius: 10px 10px 0 0;
+}
+
+.selected.hand_card {
+ outline: solid silver 3px;
+ /*box-shadow: 0 0 4px white; */
+ border-radius: 18px;
+}
+
+
+.selected.power_card {
+ outline: solid silver 3px;
+ /*box-shadow: 0 0 4px white; */
+ border-radius: 18px;
+}
+
+/* =============== OTHER ===============*/
+#space-characteristics {display: none}
+
+/* =============== CARD IMAGES =========*/
+
+#tooltip {
+ position: fixed;
+ pointer-events: none;
+ z-index: 600;
+ right: 240px;
+ top: 60px;
+}
+
+.card {
+ background-size: cover;
+ background-repeat: no-repeat;
+ width: 250px;
+ height: 350px;
+ border-radius: 16px;
+ box-shadow: 1px 2px 4px #0004;
+}
+
+.card_1 {background-image: url(cards/e1.gif)}
+.card_2 {background-image: url(cards/e2.gif)}
+.card_3 {background-image: url(cards/e3.gif)}
+.card_4 {background-image: url(cards/e4.gif)}
+.card_5 {background-image: url(cards/e5.gif)}
+.card_6 {background-image: url(cards/e6.gif)}
+.card_7 {background-image: url(cards/e7.gif)}
+.card_8 {background-image: url(cards/e8.gif)}
+.card_9 {background-image: url(cards/e9.gif)}
+.card_10 {background-image: url(cards/e10.gif)}
+.card_11 {background-image: url(cards/e11.gif)}
+.card_12 {background-image: url(cards/e12.gif)}
+.card_13 {background-image: url(cards/e13.gif)}
+.card_14 {background-image: url(cards/e14.gif)}
+.card_15 {background-image: url(cards/e15.gif)}
+.card_16 {background-image: url(cards/e16.gif)}
+.card_17 {background-image: url(cards/e17.gif)}
+.card_18 {background-image: url(cards/e18.gif)}
+.card_19 {background-image: url(cards/e19.gif)}
+.card_20 {background-image: url(cards/e20.gif)}
+.card_21 {background-image: url(cards/e21.gif)}
+.card_22 {background-image: url(cards/e22.gif)}
+.card_23 {background-image: url(cards/e23.gif)}
+.card_24 {background-image: url(cards/e24.gif)}
+.card_25 {background-image: url(cards/e25.gif)}
+.card_26 {background-image: url(cards/e26.gif)}
+.card_27 {background-image: url(cards/e27.gif)}
+.card_28 {background-image: url(cards/e28.gif)}
+.card_29 {background-image: url(cards/e29.gif)}
+.card_30 {background-image: url(cards/e30.gif)}
+.card_31 {background-image: url(cards/e31.gif)}
+.card_32 {background-image: url(cards/e32.gif)}
+.card_33 {background-image: url(cards/e33.gif)}
+.card_34 {background-image: url(cards/e34.gif)}
+.card_35 {background-image: url(cards/e35.gif)}
+.card_36 {background-image: url(cards/e36.gif)}
+.card_37 {background-image: url(cards/e37.gif)}
+.card_38 {background-image: url(cards/e38.gif)}
+.card_39 {background-image: url(cards/e39.gif)}
+.card_40 {background-image: url(cards/e40.gif)}
+.card_41 {background-image: url(cards/e41.gif)}
+.card_42 {background-image: url(cards/e42.gif)}
+.card_43 {background-image: url(cards/e43.gif)}
+.card_44 {background-image: url(cards/e44.gif)}
+.card_45 {background-image: url(cards/e45.gif)}
+.card_46 {background-image: url(cards/e46.gif)}
+.card_47 {background-image: url(cards/e47.gif)}
+.card_48 {background-image: url(cards/e48.gif)}
+.card_49 {background-image: url(cards/e49.gif)}
+.card_50 {background-image: url(cards/e50.gif)}
+.card_51 {background-image: url(cards/e51.gif)}
+.card_52 {background-image: url(cards/e52.gif)}
+.card_53 {background-image: url(cards/e53.gif)}
+.card_54 {background-image: url(cards/e54.gif)}
+.card_55 {background-image: url(cards/e55.gif)}
+.card_56 {background-image: url(cards/e56.gif)}
+.card_57 {background-image: url(cards/e57.gif)}
+.card_58 {background-image: url(cards/e58.gif)}
+.card_59 {background-image: url(cards/e59.gif)}
+.card_60 {background-image: url(cards/e60.gif)}
+.card_61 {background-image: url(cards/e61.gif)}
+.card_62 {background-image: url(cards/e62.gif)}
+.card_63 {background-image: url(cards/e63.gif)}
+.card_64 {background-image: url(cards/e64.gif)}
+.card_65 {background-image: url(cards/e65.gif)}
+.card_66 {background-image: url(cards/e66.gif)}
+.card_67 {background-image: url(cards/e67.gif)}
+.card_68 {background-image: url(cards/e68.gif)}
+.card_69 {background-image: url(cards/e69.gif)}
+.card_70 {background-image: url(cards/e70.gif)}
+.card_71 {background-image: url(cards/e71.gif)}
+.card_72 {background-image: url(cards/e72.gif)}
+.card_73 {background-image: url(cards/e73.gif)}
+.card_74 {background-image: url(cards/e74.gif)}
+.card_75 {background-image: url(cards/e75.gif)}
+.card_76 {background-image: url(cards/e76.gif)}
+.card_77 {background-image: url(cards/e77.gif)}
+.card_78 {background-image: url(cards/e78.gif)}
+.card_79 {background-image: url(cards/e79.gif)}
+.card_80 {background-image: url(cards/e80.gif)}
+.card_81 {background-image: url(cards/e81.gif)}
+.card_82 {background-image: url(cards/e82.gif)}
+.card_83 {background-image: url(cards/e83.gif)}
+.card_84 {background-image: url(cards/e84.gif)}
+.card_85 {background-image: url(cards/e85.gif)}
+.card_86 {background-image: url(cards/e86.gif)}
+.card_87 {background-image: url(cards/e87.gif)}
+.card_88 {background-image: url(cards/e88.gif)}
+.card_89 {background-image: url(cards/e89.gif)}
+.card_90 {background-image: url(cards/e90.gif)}
+.card_91 {background-image: url(cards/e91.gif)}
+.card_92 {background-image: url(cards/e92.gif)}
+.card_93 {background-image: url(cards/e93.gif)}
+.card_94 {background-image: url(cards/e94.gif)}
+.card_95 {background-image: url(cards/e95.gif)}
+.card_96 {background-image: url(cards/e96.gif)}
+.card_97 {background-image: url(cards/e97.gif)}
+.card_98 {background-image: url(cards/e98.gif)}
+.card_99 {background-image: url(cards/e99.gif)}
+.card_100 {background-image: url(cards/e100.gif)}
+.card_101 {background-image: url(cards/e101.gif)}
+.card_102 {background-image: url(cards/e102.gif)}
+.card_103 {background-image: url(cards/e103.gif)}
+.card_104 {background-image: url(cards/e104.gif)}
+.card_105 {background-image: url(cards/e105.gif)}
+.card_106 {background-image: url(cards/e106.gif)}
+.card_107 {background-image: url(cards/e107.gif)}
+.card_108 {background-image: url(cards/e108.gif)}
+.card_109 {background-image: url(cards/e109.gif)}
+.card_110 {background-image: url(cards/e110.gif)}
diff --git a/play.html b/play.html
index 8e25b8c..e09e214 100644
--- a/play.html
+++ b/play.html
@@ -1,210 +1,210 @@
-<!DOCTYPE html>
-<!-- vim:set nowrap: -->
-<html lang="en">
-<head>
-<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no, interactive-widget=resizes-content, viewport-fit=cover">
-<meta name="theme-color" content="#444">
-<meta charset="utf-8">
-<title>1989</title>
-<link rel="icon" href="favicon.png">
-<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap" rel="stylesheet">
-<link rel="stylesheet" href="/fonts/fonts.css">
-<link rel="stylesheet" href="/common/client.css">
-<link rel="stylesheet" href="play.css">
-<script defer src="/common/client.js"></script>
-<script defer src="data.js"></script>
-<!-- <script defer src="rules.js"></script> -->
-<script defer src="play.js"></script>
-
-</head>
-
-<body>
-<div id="tooltip" class="card hide"></div>
-
-<header>
- <div id="toolbar">
- <details>
- <summary><img src="images/cog.svg" width="50" height="50"></summary> <!-- Not sure why this is so big! -->
- <menu>
- <li>Rules of Play
- <li>Background Book
- <li>Reference Sheets
-
- </menu>
- </details>
- <button onclick="toggle_pieces()"><img src="images/earth-africa-europe.svg"></button>
- <button onclick="toggle_discard()"><img src="images/bin.png"></button>
- <button onclick="toggle_removed()"><img src="images/remove.png"></button>
- </div>
-</header>
-
-<aside>
- <div id="roles">
- <div class="role" id="role_Democrat">
- <div class="role_name">Democrat</div>
- <div class="role_stat" id="role_stat_dem">0 cards in hand</div>
- <div class="role_user">-</div>
- </div>
- <div class="role" id="role_Communist">
- <div class="role_name">Communist</div>
- <div class="role_stat" id="role_stat_com">0 cards in hand</div>
- <div class="role_user">-</div>
- </div>
- <div class="role" id="deck_data">
- <div class="deck_name" id="deck_stat">Strategy deck:</div>
- <div class="role_stat" id="deck_length">0 cards</div>
- </div>
- </div>
- <div id="log"></div>
-</aside>
-
-<main data-min-zoom="0.5" data-max-zoom = "2.0">
-
-<!-- MAP, EVENTS -->
-<section id="sec_map">
-
-<div class="map" id="map">
- <div id="pieces">
- <div id="overlay">
- <h2 id="space-characteristics"></h2>
- <img id="turn-tracker" class="hide" src="images/Turn.gif">
- <div class="us-action-round-tracker hide" id="action-round-tracker"></div>
- <img id="stability-track" class="hide" src="images/SV_Stability.gif">
- <img id="dem-TST" class="hide" src="images/US_Tiananmen_Square.gif">
- <img id="com-TST" class="hide" src="images/SV_Tiananmen_Square.gif">
- <img id="vp" class="hide" src="images/VP.gif">
- <div class="germany marker" id="East_Germany">
- <p class="times_held hide" id="East_Germany_times_held">1</p></div>
- <div class="poland marker" id="Poland">
- <p class="times_held hide" id="Poland_times_held">1</p></div>
- <div class="czech marker" id="Czechoslovakia">
- <p class="times_held hide" id="Czechoslovakia_times_held">1</p></div>
- <div class="hungary marker" id="Hungary">
- <p class="times_held hide" id="Hungary_times_held">1</p></div>
- <div class="romania marker" id="Romania">
- <p class="times_held hide" id="Romania_times_held">1</p></div>
- <div class="bulgaria marker" id="Bulgaria">
- <p class="times_held hide" id="Bulgaria_times_held">1</p></div>
-
- <!-- PERMANENT EVENT MARKERS ON THE BOARD -->
-
-
- <img id="event_2" class="event-marker" src = "images/Event_Marker_Solidarity_Leg.gif">
- <img id="event_69" class="event-marker" src="images/Event_Marker_Systematizatio.gif">
- <img id="event_97" class="event-marker" src="images/Event_Marker_The_Tyrant_Is_.gif">
- <img id="event_9" class="event-marker" src="images/Event_Marker_The_Wall.gif">
-
- </div>
- <div id="counters"></div>
- </div>
-</div>
-</section>
-
-
-<!-- EVENTS IN PLAY -->
-<section id = "sec_events">
- <div id="events_panel" class="panel hide">
- <div id="events_header" class="panel_header">Event Markers</div>
- <div id="events" class="panel_body">
- <img id="event_15" class="event-marker aside" src="images/Event_Marker_Honecker.gif">
- <img id="event_24" class="event-marker aside" src="images/Event_Marker_St_Nicholas.gif">
- <img id="event_26" class="event-marker aside" src="images/Event_Marker_Helsinki.gif">
- <img id="event_39" class="event-marker aside" src = "images/Event_Marker_Eco_Glasnost.gif">
- <img id="event_48" class="event-marker aside" src="images/Event_Marker_We_are_the_Peo.gif">
- <img id="event_49" class="event-marker aside" src="images/Event_Marker_Foreign_Curren.gif">
- <img id="event_53" class="event-marker aside" src="images/Event_Marker_Li_Peng_.gif">
- <img id="event_58" class="event-marker aside" src="images/Event_Marker_Austria_Hungar.gif">
- <img id="event_59" class="event-marker aside" src="images/Event_Marker_Grenz_Truppen.gif">
- <img id="event_65" class="event-marker aside" src="images/Event_Marker_Pres_Visit.gif">
- <img id="event_70" class="event-marker aside" src="images/Event_Marker_Securitate.gif">
- <img id="event_73" class="event-marker aside" src="images/Event_Marker_Laszlo.gif">
- <img id="event_100" class="event-marker aside" src="images/Event_Marker_Stand_Fast.gif">
- <img id="event_101" class="event-marker aside" src="images/Event_Marker_Elena.gif">
- <img id="event_104" class="event-marker aside" src="images/Event_Marker_NYE_Party.gif">
- </div>
- </div>
-</section>
-
-<!-- EVENTS ON THE TABLE -->
-<section id = "sec_table_cards">
- <div id="table_panel" class="panel hide">
- <div id="table_header" class="panel_header">Cards on the Table</div>
- <div id="table_cards" class="panel_body"></div>
- </div>
-</section>
-
-<!-- PLAYED CARD -->
-<section id="sec_played_card">
-<div id="played_card_panel" class="panel hide">
-<div id="played_card_header" class="panel_header">Played Card</div>
-<div id="played_card" class="panel_body"></div>
-</div>
-
-</section>
-
-<!-- DISCARD -->
-<section id = "sec_discard">
- <div id="discard_panel" class="panel">
- <div id="discard_header" class="panel_header">Discard</div>
- <div id="discard" class="panel_body"></div>
- </div>
-</section>
-
-<!-- PERMANENTLY REMOVED -->
-<section id = "sec_removed">
- <div id="removed_panel" class="panel hide">
- <div id="removed_header" class="panel_header">Permanently Removed Events</div>
- <div id="removed" class="panel_body"></div>
- </div>
-</section>
-
-<!-- POWERSTRUGGLE -->
-<section id = "sec_power">
- <div id="ceausescu_panel" class="panel hide">
- <div id="ceausescu_header" class="panel_header">Ceausescu Cards</div>
- <div id="ceausescu_hand" class="panel_body"></div>
- </div>
- <div id="power_panel" class="panel hide">
- <div id="power_header" class="panel_header">Power Struggle Hand</div>
- <div id="power_hand" class="panel_body"></div>
- </div>
-</section>
-
-
-
-<!-- OPPONENT HAND -->
-<section id="sec_opp_hand">
-
- <div id="opp_hand_panel" class="panel hide">
- <div id="opp_hand_header" class="panel_header">Opponent Hand</div>
- <div id="opp_hand" class="panel_body"></div>
- </div>
-
-</section>
-
-<!-- SAMIZDAT CARD -->
-<section id = "sec_samizdat">
- <div id="samizdat_panel" class="panel">
- <div id="samizdat_header" class="panel_header">Set aside card</div>
- <div id="samizdat_card" class="panel_body"></div>
- </div>
-</section>
-
-
-<!-- HAND -->
-<section id="sec_hand">
-
-<div id="hand_panel" class="panel hide">
- <div id="hand_header" class="panel_header">Hand</div>
- <div id="hand" class="panel_body"></div>
-</div>
-
-</section>
-
-</main>
-
-<footer id="status"></footer>
-
-
-
-</html>
+<!DOCTYPE html>
+<!-- vim:set nowrap: -->
+<html lang="en">
+<head>
+<meta name="viewport" content="width=device-width, height=device-height, user-scalable=no, interactive-widget=resizes-content, viewport-fit=cover">
+<meta name="theme-color" content="#444">
+<meta charset="utf-8">
+<title>1989</title>
+<link rel="icon" href="favicon.png">
+<link href="https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600;700&display=swap" rel="stylesheet">
+<link rel="stylesheet" href="/fonts/fonts.css">
+<link rel="stylesheet" href="/common/client.css">
+<link rel="stylesheet" href="play.css">
+<script defer src="/common/client.js"></script>
+<script defer src="data.js"></script>
+<!-- <script defer src="rules.js"></script> -->
+<script defer src="play.js"></script>
+
+</head>
+
+<body>
+<div id="tooltip" class="card hide"></div>
+
+<header>
+ <div id="toolbar">
+ <details>
+ <summary><img src="images/cog.svg" width="50" height="50"></summary> <!-- Not sure why this is so big! -->
+ <menu>
+ <li>Rules of Play
+ <li>Background Book
+ <li>Reference Sheets
+
+ </menu>
+ </details>
+ <button onclick="toggle_pieces()"><img src="images/earth-africa-europe.svg"></button>
+ <button onclick="toggle_discard()"><img src="images/bin.png"></button>
+ <button onclick="toggle_removed()"><img src="images/remove.png"></button>
+ </div>
+</header>
+
+<aside>
+ <div id="roles">
+ <div class="role" id="role_Democrat">
+ <div class="role_name">Democrat</div>
+ <div class="role_stat" id="role_stat_dem">0 cards in hand</div>
+ <div class="role_user">-</div>
+ </div>
+ <div class="role" id="role_Communist">
+ <div class="role_name">Communist</div>
+ <div class="role_stat" id="role_stat_com">0 cards in hand</div>
+ <div class="role_user">-</div>
+ </div>
+ <div class="role" id="deck_data">
+ <div class="deck_name" id="deck_stat">Strategy deck:</div>
+ <div class="role_stat" id="deck_length">0 cards</div>
+ </div>
+ </div>
+ <div id="log"></div>
+</aside>
+
+<main data-min-zoom="0.5" data-max-zoom = "2.0">
+
+<!-- MAP, EVENTS -->
+<section id="sec_map">
+
+<div class="map" id="map">
+ <div id="pieces">
+ <div id="overlay">
+ <h2 id="space-characteristics"></h2>
+ <img id="turn-tracker" class="hide" src="images/Turn.gif">
+ <div class="us-action-round-tracker hide" id="action-round-tracker"></div>
+ <img id="stability-track" class="hide" src="images/SV_Stability.gif">
+ <img id="dem-TST" class="hide" src="images/US_Tiananmen_Square.gif">
+ <img id="com-TST" class="hide" src="images/SV_Tiananmen_Square.gif">
+ <img id="vp" class="hide" src="images/VP.gif">
+ <div class="germany marker" id="East_Germany">
+ <p class="times_held hide" id="East_Germany_times_held">1</p></div>
+ <div class="poland marker" id="Poland">
+ <p class="times_held hide" id="Poland_times_held">1</p></div>
+ <div class="czech marker" id="Czechoslovakia">
+ <p class="times_held hide" id="Czechoslovakia_times_held">1</p></div>
+ <div class="hungary marker" id="Hungary">
+ <p class="times_held hide" id="Hungary_times_held">1</p></div>
+ <div class="romania marker" id="Romania">
+ <p class="times_held hide" id="Romania_times_held">1</p></div>
+ <div class="bulgaria marker" id="Bulgaria">
+ <p class="times_held hide" id="Bulgaria_times_held">1</p></div>
+
+ <!-- PERMANENT EVENT MARKERS ON THE BOARD -->
+
+
+ <img id="event_2" class="event-marker" src = "images/Event_Marker_Solidarity_Leg.gif">
+ <img id="event_69" class="event-marker" src="images/Event_Marker_Systematizatio.gif">
+ <img id="event_97" class="event-marker" src="images/Event_Marker_The_Tyrant_Is_.gif">
+ <img id="event_9" class="event-marker" src="images/Event_Marker_The_Wall.gif">
+
+ </div>
+ <div id="counters"></div>
+ </div>
+</div>
+</section>
+
+
+<!-- EVENTS IN PLAY -->
+<section id = "sec_events">
+ <div id="events_panel" class="panel hide">
+ <div id="events_header" class="panel_header">Event Markers</div>
+ <div id="events" class="panel_body">
+ <img id="event_15" class="event-marker aside" src="images/Event_Marker_Honecker.gif">
+ <img id="event_24" class="event-marker aside" src="images/Event_Marker_St_Nicholas.gif">
+ <img id="event_26" class="event-marker aside" src="images/Event_Marker_Helsinki.gif">
+ <img id="event_39" class="event-marker aside" src = "images/Event_Marker_Eco_Glasnost.gif">
+ <img id="event_48" class="event-marker aside" src="images/Event_Marker_We_are_the_Peo.gif">
+ <img id="event_49" class="event-marker aside" src="images/Event_Marker_Foreign_Curren.gif">
+ <img id="event_53" class="event-marker aside" src="images/Event_Marker_Li_Peng_.gif">
+ <img id="event_58" class="event-marker aside" src="images/Event_Marker_Austria_Hungar.gif">
+ <img id="event_59" class="event-marker aside" src="images/Event_Marker_Grenz_Truppen.gif">
+ <img id="event_65" class="event-marker aside" src="images/Event_Marker_Pres_Visit.gif">
+ <img id="event_70" class="event-marker aside" src="images/Event_Marker_Securitate.gif">
+ <img id="event_73" class="event-marker aside" src="images/Event_Marker_Laszlo.gif">
+ <img id="event_100" class="event-marker aside" src="images/Event_Marker_Stand_Fast.gif">
+ <img id="event_101" class="event-marker aside" src="images/Event_Marker_Elena.gif">
+ <img id="event_104" class="event-marker aside" src="images/Event_Marker_NYE_Party.gif">
+ </div>
+ </div>
+</section>
+
+<!-- EVENTS ON THE TABLE -->
+<section id = "sec_table_cards">
+ <div id="table_panel" class="panel hide">
+ <div id="table_header" class="panel_header">Cards on the Table</div>
+ <div id="table_cards" class="panel_body"></div>
+ </div>
+</section>
+
+<!-- PLAYED CARD -->
+<section id="sec_played_card">
+<div id="played_card_panel" class="panel hide">
+<div id="played_card_header" class="panel_header">Played Card</div>
+<div id="played_card" class="panel_body"></div>
+</div>
+
+</section>
+
+<!-- DISCARD -->
+<section id = "sec_discard">
+ <div id="discard_panel" class="panel">
+ <div id="discard_header" class="panel_header">Discard</div>
+ <div id="discard" class="panel_body"></div>
+ </div>
+</section>
+
+<!-- PERMANENTLY REMOVED -->
+<section id = "sec_removed">
+ <div id="removed_panel" class="panel hide">
+ <div id="removed_header" class="panel_header">Permanently Removed Events</div>
+ <div id="removed" class="panel_body"></div>
+ </div>
+</section>
+
+<!-- POWERSTRUGGLE -->
+<section id = "sec_power">
+ <div id="ceausescu_panel" class="panel hide">
+ <div id="ceausescu_header" class="panel_header">Ceausescu Cards</div>
+ <div id="ceausescu_hand" class="panel_body"></div>
+ </div>
+ <div id="power_panel" class="panel hide">
+ <div id="power_header" class="panel_header">Power Struggle Hand</div>
+ <div id="power_hand" class="panel_body"></div>
+ </div>
+</section>
+
+
+
+<!-- OPPONENT HAND -->
+<section id="sec_opp_hand">
+
+ <div id="opp_hand_panel" class="panel hide">
+ <div id="opp_hand_header" class="panel_header">Opponent Hand</div>
+ <div id="opp_hand" class="panel_body"></div>
+ </div>
+
+</section>
+
+<!-- SAMIZDAT CARD -->
+<section id = "sec_samizdat">
+ <div id="samizdat_panel" class="panel">
+ <div id="samizdat_header" class="panel_header">Set aside card</div>
+ <div id="samizdat_card" class="panel_body"></div>
+ </div>
+</section>
+
+
+<!-- HAND -->
+<section id="sec_hand">
+
+<div id="hand_panel" class="panel hide">
+ <div id="hand_header" class="panel_header">Hand</div>
+ <div id="hand" class="panel_body"></div>
+</div>
+
+</section>
+
+</main>
+
+<footer id="status"></footer>
+
+
+
+</html>
diff --git a/play.js b/play.js
index a98c671..f0f4390 100644
--- a/play.js
+++ b/play.js
@@ -1,814 +1,814 @@
-
-const seed = 'none'
-const scenario = 'standard'
-const options = 'none'
-//const rules = require("./rules")
-
-const last_card = 110
-const last_power_card = 52
-let hover_timeout
-const height = 65
-const width = 105
-const toolbar = document.getElementById('toolbar')
-const vpMarker = document.getElementById('vp')
-const counters = document.getElementById('counters')
-
-const countries= ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania']
-
-/*const aside_events = [
- "honecker",
- "st_nicholas_church",
- "helsinki_final_act",
- "eco_glasnost",
- "we_are_the_people",
- "foreign_currency_debt_burden",
- "li_peng",
- "austria_hungary_border_reopened",
- "grenztruppen",
- "presidential_visit",
- "securitate",
- "laslzo_tokes",
- "stand_fast",
- "elena",
- "new_years_eve_party"
-]*/
-const board_events = [2, 9, 69, 97]
-const box_events = [ 15, 24, 26, 39, 48, 49, 53, 58, 59, 65, 70, 73, 100, 101, 104 ]
-let box_events_showing = false
-let show_discard = false
-
-const overlay = document.getElementById('overlay');
-const spaceNameElement = document.getElementById('space-name');
-const spaceCharacteristicsElement = document.getElementById('space-characteristics');
-
-
-// Event listener to track mouse movement over the map
- document.querySelector('.map').addEventListener('mousemove', function(event) {
- const x = event.offsetX; // X-coordinate of mouse relative to container
- const y = event.offsetY; // Y-coordinate of mouse relative to container
- spaceCharacteristicsElement.innerText = `X: ${x}, Y: ${y}`;
- })
-
-
- // Create map areas dynamically based on coordinates
-
- function create_ui() {
-
-// CREATE MAP
-
- spaces.forEach((space) => {
-
-
- if (space && space.box) {
-
- //CREATE SPACES
- const { x, y} = space.box;
- const spaceArea = document.createElement('div');
- spaceArea.classList.add('space-area', space.country)
- spaceArea.id=`space_${space.space_id}`;
- spaceArea.style.left = x + 'px';
- spaceArea.style.top = y + 'px';
- spaceArea.style.width = width + 'px';
- spaceArea.style.height = height + 'px';
- spaceArea.style.zIndex = 2;
- spaceArea.my_space = space.space_id;
- spaceArea.addEventListener('mousedown', on_click_space);
-
- //CREATE DEMOCRATIC INFLUENCE MARKERS FOR EACH SPACE
- const dem_img = document.createElement('div')
- dem_img.classList.add('demInfl', space.country)
- dem_img.style.display = 'none'
- dem_img.id=`${space.name_unique}_demInfl`
- dem_img.style.zIndex = 1
- dem_img.my_space = space.space_id;
- dem_img.addEventListener('mousedown', on_click_space);
- spaceArea.appendChild(dem_img)
-
- //CREATE DEMOCRATIC INFLUENCE VALUES
- const demInflValue = document.createElement('p')
- demInflValue.className='demInflValue'
- demInflValue.style.display = 'none'
- demInflValue.id=`${space.name_unique}_demInflValue`
- demInflValue.innerText=space.demInfl
- demInflValue.style.zIndex = 1
- demInflValue.my_space = space.space_id;
- demInflValue.addEventListener('mousedown', on_click_space);
- spaceArea.appendChild(demInflValue)
-
- //CREATE COMMUNIST INFLUENCE MARKERS FOR EACH SPACE
- const com_img = document.createElement('div')
- com_img.className='comInfl'
- com_img.style.display='none'
- com_img.id=`${space.name_unique}_comInfl`
- com_img.style.zIndex = 1
- com_img.my_space = space.space_id;
- com_img.addEventListener('mousedown', on_click_space);
- spaceArea.appendChild(com_img)
-
- //CREATE COMMUNIST INFLUENCE VALUES
- const comInflValue = document.createElement('p')
- comInflValue.className='comInflValue'
- comInflValue.style.display='none'
- comInflValue.id=`${space.name_unique}_comInflValue`
- comInflValue.innerText=space.comInfl
- comInflValue.style.zIndex = 1
- comInflValue.my_space = space.space_id;
- comInflValue.addEventListener('mousedown', on_click_space);
- spaceArea.appendChild(comInflValue)
- //}
-
- counters.appendChild(spaceArea);
- }
- });
-
-// CREATE CARDS
-
- const is_mobile = window.matchMedia("(pointer: coarse)").matches
-
- for (let c = 1; c <= last_card; ++c) {
-
- const hand_card = document.createElement('img');
- hand_card.classList.add('hand_card')
- hand_card.id=`card_${c}`;
- hand_card.src = `cards/e${c}.gif`
- hand_card.my_card = c;
- hand_card.addEventListener('click', on_click_card);
-
- if(!is_mobile) {
- hand_card.addEventListener('mouseenter', () => {
- hover_timeout = setTimeout(() => {
- hand_card.classList.add('zoom');
- }, 500) })
- hand_card.addEventListener('mouseleave', () => {
- clearTimeout(hover_timeout);
- hand_card.classList.remove('zoom');
- });
- }
-
- ui.cards.push(hand_card);
- }
-
-
-
- for (let card of power_cards) {
- if (!card) continue;
- const power_card = document.createElement('img');
- power_card.classList.add('power_card');
- power_card.id = `power_card_${card.number}`;
- power_card.src = `cards_2/${card.url}.gif`;
- power_card.my_card = card.number;
- power_card.addEventListener('mousedown', on_click_card);
- ui.power_cards.push(power_card);
- }
-}
-
-
-
-
-function is_card_enabled(card) {
- if (view.actions) {
- if (card_action_menu.some(a => view.actions[a] && view.actions[a].includes(card)))
- return true
- if (view.actions.card_select && view.actions.card_select.includes(card))
- return true
- if (view.actions.card && view.actions.card.includes(card))
- return true
- }
- return false
-}
-
-// SUPPORTING FUNCTIONS
-
-function on_click_space(evt) {
- if (evt.button === 0) {
- const space = evt.target.my_space;
- //console.log('on_click_space_called with space:', space);
- if (send_action('infl', space)) {
- //console.log('send_action with infl:', space);
- evt.stopPropagation();
- } else if (send_action('sc', space)) {
- //console.log('send_action with sc:', space);
- evt.stopPropagation();
- } else {
- // console.log('send_action failed for space:', space);
- }
- }
- //hide_popup_menu();
-}
-
-function on_click_card(evt) {
- if (evt.button === 0) {
- const card = evt.target.my_card;
- //console.log('on_click_card_called with card:', card);
- if (is_action('card', card)) {
- //console.log('in action card')
- if (send_action('card', card)) {
- evt.stopPropagation();
- }
- }
- }
-}
-
-function is_action(action) {
- //console.log('is_action called with: ', action)
- //console.log('view.actions', view.actions)
- if (view.actions && view.actions[action])
- return true
- return false
-}
-
-function is_card_action(action, card) {
- //console.log('is_card_action called with action', action, 'card', card)
- //console.log('view.actions', view.actions, 'view.actions[action]', view.actions[action])
- if (view.actions && view.actions[action] && view.actions[action].includes(card))
- return true
- return false
-}
-
-function on_log(text) { // eslint-disable-line no-unused-vars
-
- let p = document.createElement("div")
-
- if (text.match(/^>/)) {
- text = text.substring(1)
- p.className = 'i'
- }
-
- text = text.replace(/_/g, ' ')
- text = text.replace(/C(\d+)/g, sub_card_name)
- text = text.replace(/P(\d+)/g, sub_power_card_name)
- text = text.replace(/V(\d+)/g, sub_power_card_value)
- text = text.replace(/%(\d+)/g, sub_space_name)
- text = text.replace(/D[1-6]/g, sub_die)
-
-
- if (text.match(/^\.h1/)) {
- text = text.substring(4)
- p.className = 'h1'
- }
- else if (text.match(/^\.h2d/)) {
- text = text.substring(5)
- p.className = 'h2 dem'
- }
- else if (text.match(/^\.h2c/)) {
- text = text.substring(5)
- p.className = 'h2 com'
- }
- else if (text.match(/^\.h2/)) {
- text = text.substring(4)
- p.className = 'h2'
- }
- else if (text.match(/^\.h3/)) {
- text = text.substring(4)
- p.className = 'h3'
- }
-
- p.innerHTML = text
- return p
-}
-
-let ui = {
- favicon: document.getElementById('favicon'),
- player: [
- document.getElementById("role_Democrat"),
- document.getElementById("role_Communist"),
- ],
- cards: [ null ],
- power_cards: [null],
- dem_hand_count: document.getElementById("role_stat_dem"),
- com_hand_count: document.getElementById("role_stat_com"),
- deck_length: document.getElementById("deck_length"),
- played_card: 0,
- table_panel: document.getElementById("table_panel"),
- hand_panel: document.getElementById("hand_panel"),
- turn: document.getElementById("turn-tracker"),
- round: document.getElementById("action-round-tracker"),
- stability: document.getElementById("stability-track"),
- dem_TST: document.getElementById("dem-TST"),
- com_TST: document.getElementById("com-TST"),
- vp: document.getElementById("vp"),
- spaces: document.getElementsByClassName("space-area")
-
-}
-
-
-function on_update() {
- //console.log('on_update called')
- //console.log('view.valid_spaces: ', view.valid_spaces)
- //console.log('view.actions: ', view.actions)
- //console.log('view.power_cards:', view.power_cards)
- document.querySelectorAll('[id^="space_"].selected').forEach(spaceElement => {spaceElement.classList.remove('selected');});
- document.getElementById("power_hand")?.querySelectorAll('.selected').forEach(cardElement => {cardElement.classList.remove('selected');});
- view.valid_spaces.forEach(space_id => {
- const spaceElementId = `space_${space_id}`;
- const spaceElement = document.getElementById(spaceElementId);
-
- if (spaceElement) {
- spaceElement.classList.add('selected');
- }
- });
-
- //Check influence values
-
- for (let i = 1; i < spaces.length; i ++) {
-
- const space = spaces[i]
- const demInfl = view.demInfl[i]
- const comInfl = view.comInfl[i]
- //console.log('piece', piece)
- //console.log('space', space)
- const dem_marker = document.getElementById(`${space.name_unique}_demInfl`);
- const dem_number = document.getElementById(`${space.name_unique}_demInflValue`);
- const com_marker = document.getElementById(`${space.name_unique}_comInfl`);
- const com_number = document.getElementById(`${space.name_unique}_comInflValue`);
-
- dem_number.innerText=demInfl
- if (demInfl > 0) {
- dem_marker.style.display = 'block';
- dem_number.style.display = 'block';
-
- if (demInfl > 9) {
- dem_number.classList.remove('demInflValue')
- dem_number.classList.add('demInflValue_10')
- } else {
- dem_number.classList.add('demInflValue')
- dem_number.classList.remove('demInflValue_10')
- }
-
- if(check_dem_control(demInfl, comInfl, space)){
- dem_marker.classList.add('controlled')
- dem_number.classList.add('outlined_text')
- dem_marker.classList.remove('uncontrolled')
- } else {
- dem_marker.classList.add('uncontrolled')
- dem_marker.classList.remove('controlled')
- dem_number.classList.remove('outlined_text')
- }
- } else {
- dem_marker.style.display = 'none';
- dem_number.style.display = 'none';
- }
- com_number.innerText=comInfl
- if (comInfl > 0) {
- com_marker.style.display = 'block';
- com_number.style.display = 'block';
-
- if (comInfl > 9) {
- com_number.classList.remove('comInflValue')
- com_number.classList.add('comInflValue_10')
- } else {
- com_number.classList.add('comInflValue')
- com_number.classList.remove('comInflValue_10')
- }
-
- if(check_com_control(demInfl, comInfl, space)){
- com_marker.classList.add('controlled')
- com_number.classList.add('controlled')
- com_marker.classList.remove('uncontrolled')
- com_number.classList.remove('uncontrolled')
- } else {
- com_marker.classList.add('uncontrolled')
- com_number.classList.add('uncontrolled')
- com_marker.classList.remove('controlled')
- com_number.classList.remove('controlled')
- }
- } else {
- com_marker.style.display = 'none';
- com_number.style.display = 'none';
- }
-
- }
-
-// UPDATE COUNTRY MARKERS
- for (let i = 0; i < countries.length; i++) {
- const country = countries[i];
- const marker = document.getElementById(country)
- const times_held = document.getElementById(`${country}_times_held`)
-
- if (view.revolutions[find_country_index(country)]) {
- marker.classList.add('revolution')
- marker.classList.remove('held')
- marker.style.display = 'block'
- times_held.classList.add('outlined_text')
- times_held.classList.remove('hide')
- } else if (view.times_held[find_country_index(country)] > 0 ) {
- //console.log('setting ', country)
- marker.classList.add('held')
- marker.style.display = 'block'
- times_held.classList.remove('hide')
- times_held.innerHTML = view.times_held[find_country_index(country)]
- }
- else {marker.style.display = 'none'}
- }
-
-// UPDATE ASIDE
- if (view.is_pwr_struggle) {
- ui.dem_hand_count.innerText = `${view.democrat_power_hand} Power cards`
- ui.com_hand_count.innerText = `${view.communist_power_hand} Power cards`
- } else{
- ui.dem_hand_count.innerText = `${view.democrat_hand} cards`
- ui.com_hand_count.innerText = `${view.communist_hand} cards`
- }
- ui.deck_length.innerText = `${view.strategy_deck} cards`
-
-// UPDATE HAND
- document.getElementById("hand").replaceChildren()
- document.getElementById("played_card").replaceChildren()
-
- if (view.hand.length && view.is_pwr_struggle === false) {
- document.getElementById("hand_panel").classList.remove("hide")
- //console.log('view.actions.card', view.actions.card)
- for (let c of view.hand) {
- let card = ui.cards[c]
- document.getElementById("hand").appendChild(card);
- if (view.actions && view.actions.card && view.actions.card.includes(c)) {
- card.classList.add('action')
- } else {
- card.classList.remove('action')
- }
- if (view.valid_cards.includes(c)) {
- card.classList.add('selected')
- } else {
- card.classList.remove('selected')
- }
- card.classList.remove('discard_card')
- }
- } else {
- document.getElementById("hand_panel").classList.add("hide")
- }
-
-// UPDATE DISCARD
-document.getElementById("discard").replaceChildren()
-if (!view.is_pwr_struggle) {
- for (let c of view.strategy_discard) {
- let discard_card = ui.cards[c]
- document.getElementById("discard").appendChild(discard_card)
- discard_card.classList.add('discard_card')
- discard_card.classList.remove('selected')
- }
-} else if (view.is_pwr_struggle) {
- for (let c of view.strategy_discard) {
- let discard_card = ui.power_cards[c]
- document.getElementById("discard").appendChild(discard_card)
- discard_card.classList.add('discard_card')
- discard_card.classList.remove('selected')
- }
-}
-
-// DISCARD FOR EVENTS
-//console.log('view.discard',view.discard)
-if(view.discard) {
- //document.getElementById("discard").replaceChildren()
- document.getElementById("discard_panel").classList.remove("hide")
- for (let c of view.strategy_discard) {
- let discard_card = ui.cards[c]
- document.getElementById("discard").appendChild(discard_card)
- discard_card.classList.add('discard_card')
- if (view.valid_cards.includes(c)) {
- discard_card.classList.add('selected')
- } else {
- discard_card.classList.remove('selected')
- }
- }
-} else {
- if (!show_discard) {
- document.getElementById("discard_panel").classList.add("hide")
- }
-}
-
-// UPDATE PERMANENTLY REMOVED CARDS
-document.getElementById("removed").replaceChildren()
-for (let c of view.strategy_removed) {
- let discard_card = ui.cards[c]
- document.getElementById("removed").appendChild(discard_card)
- discard_card.classList.add('discard_card')
- discard_card.classList.remove('selected')
-}
-
-
-// PLAYED CARD PANEL
-if (view.played_card > 0) {
- document.getElementById("played_card_panel").classList.remove("hide")
- document.getElementById("played_card").appendChild(ui.cards[view.played_card]);
- document.getElementById("played_card").classList.remove("hand_card")
-} else {
- document.getElementById("played_card_panel").classList.add("hide")
-}
-
-// TABLE CARDS PANEL
-document.getElementById("table_cards").replaceChildren()
-if (view.table_cards.length > 0) {
- document.getElementById("table_panel").classList.remove("hide")
- for (let c of view.table_cards) {
- let card = ui.cards[c]
- document.getElementById("table_cards").appendChild(card);
- card.classList.remove("hand_card")
- card.classList.add('event_card');
- }
- } else {
- document.getElementById("table_panel").classList.add("hide")
-}
-
-// OPPONENT HAND
-document.getElementById("opp_hand").replaceChildren()
-if (!view.is_pwr_struggle) {
- if (view.show_opp_hand && view.opp_hand.length >0) {
- document.getElementById("opp_hand_panel").classList.remove("hide")
- for (let c of view.opp_hand) {
- let card = ui.cards[c]
- document.getElementById("opp_hand").appendChild(card);
- card.classList.remove('discard_card')
- if (!view.is_pwr_struggle) {
- if (view.valid_cards.includes(c)) {
- card.classList.add('selected')
- } else {
- card.classList.remove('selected')
- }
- }
- }
- } else {
- document.getElementById("opp_hand_panel").classList.add("hide")
- }
-} else {
- //console.log('power struggle, show opp hand', view.show_opp_hand, 'view opp hand', view.opp_hand )
- if (view.show_opp_hand && view.opp_hand && view.opp_hand.length > 0) {
- document.getElementById("opp_hand_panel").classList.remove("hide")
- for (let c of view.opp_hand) {
- let card = ui.power_cards[c]
- //console.log('power_card:', power_card)
- document.getElementById("opp_hand").appendChild(card);
- card.classList.remove('discard_card')
- }
- } else {
- document.getElementById("opp_hand_panel").classList.add("hide")
- }
-}
-
-// POWER STRUGGLE HAND
- document.getElementById("power_hand").replaceChildren()
-
- if (view.power_hand.length && view.is_pwr_struggle) {
- document.getElementById("power_panel").classList.remove("hide")
- for (let c of view.power_hand) {
- let power_card = ui.power_cards[c]
- document.getElementById("power_hand").appendChild(power_card);
- power_card.classList.remove('discard_card')
- if (view.valid_cards.includes(c)) {
- power_card.classList.add('selected');
- }
- }
- } else {
- document.getElementById("power_panel").classList.add("hide")
- }
-
-// CEAUSESCU
-
-if (view.ceausescu_cards && view.ceausescu_cards.length > 0 && view.is_pwr_struggle === true) {
- document.getElementById("ceausescu_panel").classList.remove("hide")
- for (let c of view.ceausescu_cards) {
- let power_card = ui.power_cards[c]
- document.getElementById("ceausescu_hand").appendChild(power_card);
- power_card.classList.remove('discard_card')
-
- }
-} else {
- document.getElementById("ceausescu_panel").classList.add("hide")
-}
-
-// SAMIZDAT CARD
-if (view.samizdat > 0 ) {
- let samizdat_card = ui.cards[view.samizdat]
- document.getElementById("samizdat_panel").classList.remove("hide")
- document.getElementById("samizdat_card").appendChild(samizdat_card)
-} else {
- document.getElementById("samizdat_panel").classList.add("hide")
-}
-
-// UPDATE BOARD MARKERS
- ui.turn.className = `t${view.turn}`
- if (view.round_player === 'Democrat') {
- ui.round.className = `dem-action-round-tracker r${view.round}`
- } else {
- ui.round.className = `com-action-round-tracker r${view.round}`
- }
- ui.stability.className = `s${view.stability}`
- ui.dem_TST.className = `tst${view.dem_tst}`
- ui.com_TST.className = `tst${view.com_tst}`
- if (view.vp >= -20 && view.vp <= 20) {
- ui.vp.className = `vp${view.vp}`
- } else if (view.vp > 20) {
- ui.vp.className = `vp21`
- } else if (view.vp < -20) {
- ui.vp.className = `vp-21`
- }
-
-//console.log('strategy discard: ', view.strategy_discard)
-//console.log('valid spaces: ', view.valid_spaces)
-
-//console.log('view.persistent_events', view.persistent_events)
-
-// UPDATE EVENT MARKERS ON THE BOARD
-
-for (let id of board_events) {
- let marker = document.getElementById(`event_${id}`)
- //console.log('event', id, marker)
- if (view.persistent_events.includes(id)) {
- marker.style.display = 'block'
- } else {
- marker.style.display = 'none'
- }
-}
-
-
-// UPDATE EVENT MARKERS BELOW THE BOARD
-
-for (let id of box_events) {
- let marker = document.getElementById(`event_${id}`)
- //console.log('event', id, marker)
- if (view.persistent_events.includes(id)) {
- marker.style.display = 'block'
- } else {
- marker.style.display = 'none'
- }
-}
-
-
-// CHECK WHETHER ANY EVENT MARKERS ARE SHOWING IN THE EVENTS BOX
-box_events_showing = false
-for (let id of box_events) {
- if (view.persistent_events.includes(id)) {
- box_events_showing = true;
- }
-/*
- //Special check for events which are not true/false
- if (view.persistent_events['foreign_currency_debt_burden'] !== '') {
- aside_events_showing = true
- }
- if (view.persistent_events['stand_fast'] !== '') {
- aside_events_showing = true
- }
- */
-}
-
-if (box_events_showing) {
- document.getElementById('events_panel').classList.remove("hide")
-} else {
- document.getElementById('events_panel').classList.add("hide")
-}
-
-let systematization = document.getElementById('event_69')
-if (view.persistent_events.includes(69)) {
- systematization.style.left = (spaces[view.systematization].box.x +20) + 'px';
- systematization.style.top = spaces[view.systematization].box.y + 'px';
-}
-
-let tyrant = document.getElementById('event_97')
-if (view.persistent_events.includes(97)) {
- tyrant.style.left = (spaces[view.the_tyrant_is_gone].box.x - 41) + 'px';
- tyrant.style.top = (spaces[view.the_tyrant_is_gone].box.y + 23) + 'px';
-} else {tyrant.style.display = 'none'}
-
- action_button("yes", "Yes")
- action_button("no", "No")
- action_button("start", "Start")
- action_button("check", "Check held cards")
- action_button("tst_7", "Cancel opponent event")
- action_button("tst_8", "Event and operations")
- action_button("end", "End Game")
- action_button("continue", "Continue playing")
- action_button("east_germany", "East Germany")
- action_button("poland", "Poland")
- action_button("czechoslovakia", "Czechoslovakia")
- action_button("hungary", "Hungary")
- action_button("romania", "Romania")
- action_button("bulgaria", "Bulgaria")
- action_button("extra", "Take action round")
- action_button("pass", "Pass")
- action_button("remove", "Remove SPs")
- action_button("add", "Add SPs")
- action_button("ops", "Operations")
- action_button("discard", "Discard")
- action_button("strike", "Strike")
- action_button("march", "March")
- action_button("rally", "Rally in the Square")
- action_button("petition", "Petition")
- action_button("bonus", "Calculate VP bonus")
- action_button("scoring", "Score country")
- action_button("retain", "Retain Power")
- action_button("surrender", "Surrender Power")
- action_button("take", "Take Power")
- action_button("concede", "Concede")
- action_button("struggle", "Begin power struggle")
- action_button("raise", "Raise the stakes")
- action_button("draw", "Draw")
- action_button("scoring", "Scoring")
- action_button("event", "Event")
- action_button("opp_event", "Resolve opponent event")
- action_button("influence", "Place SPs")
- action_button("support_check", "Support Checks")
- action_button("tst", "Tiananmen Square Track")
- action_button("roll", "Roll a die")
- action_button("done", "Done")
- action_button("end_round", "End Round")
- action_button("undo", "Undo")
-
-console.log('view.actions', view.actions)
-}
-
-// =========================== LOG FUNCTIONS ==============================================
-
-function sub_card_name(match, p1) {
- let x = p1 | 0
- return `<span class="card_name" onmouseenter="on_focus_card_tip(${x})" onmouseleave="on_blur_card_tip()">${cards[x].name}</span>`
-}
-
-function sub_power_card_name(match, p1) {
- let x = p1 | 0
- return `<span class="card_name">${power_cards[x].name}</span>`
-}
-
-function sub_power_card_value(match, p1) {
- let x = p1 | 0
- return `<span class="card_name">${x}</span>`
-}
-
-function sub_space_name(match, p1) {
- let x = p1 | 0
- let id = spaces[x].space_id
- let name = spaces[x].name_unique
- return `<span class="space_tip" onmouseenter="on_focus_space_tip(${id})" onmouseleave="on_blur_space_tip(${id})" onclick="on_click_space_tip(${id})">${name}</span>`
-}
-
-function sub_die(match) {
- return die[match] || match
-}
-
-const die = {
- D1: '<span class="die white d1"></span>',
- D2: '<span class="die white d2"></span>',
- D3: '<span class="die white d3"></span>',
- D4: '<span class="die white d4"></span>',
- D5: '<span class="die white d5"></span>',
- D6: '<span class="die white d6"></span>'
-}
-
-// =========================== VISUAL FUNCTIONS ==========================================#
-
-function on_focus_card_tip(card_number) {
- document.getElementById("tooltip").className = "card card_" + card_number
-}
-
-function on_blur_card_tip() {
- document.getElementById("tooltip").classList = "card hide"
-}
-
-function on_focus_space_tip(id) {
- space = document.getElementById(`space_${id}`)
- space.classList.add("tip")
-}
-
-function on_click_space_tip(id) {
- space = document.getElementById(`space_${id}`)
- scroll_into_view(space)
-}
-
-function on_blur_space_tip(id) {
- space = document.getElementById(`space_${id}`)
- space.classList.remove("tip")
-}
-
-function toggle_pieces() {
- document.getElementById("pieces").classList.toggle("hide")
-}
-
-
-function toggle_discard() {
- if (show_discard) {
- show_discard = false
- } else {
- show_discard = true
- }
- document.getElementById("discard_panel").classList.toggle("hide")
-}
-
-function toggle_removed() {
- document.getElementById("removed_panel").classList.toggle("hide")
-}
-
-function check_dem_control(demInfl, comInfl, space) {
- if ((demInfl - comInfl) >= space.stability) {
- return true
- } else{ false}
-}
-
-function check_com_control(demInfl, comInfl, space) {
- if ((comInfl - demInfl) >= space.stability) {
- return true
- } else{ false}
-}
-
-function find_country_index(country) {
- return countries.indexOf(country)
-}
-
-create_ui()
+
+const seed = 'none'
+const scenario = 'standard'
+const options = 'none'
+//const rules = require("./rules")
+
+const last_card = 110
+const last_power_card = 52
+let hover_timeout
+const height = 65
+const width = 105
+const toolbar = document.getElementById('toolbar')
+const vpMarker = document.getElementById('vp')
+const counters = document.getElementById('counters')
+
+const countries= ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania']
+
+/*const aside_events = [
+ "honecker",
+ "st_nicholas_church",
+ "helsinki_final_act",
+ "eco_glasnost",
+ "we_are_the_people",
+ "foreign_currency_debt_burden",
+ "li_peng",
+ "austria_hungary_border_reopened",
+ "grenztruppen",
+ "presidential_visit",
+ "securitate",
+ "laslzo_tokes",
+ "stand_fast",
+ "elena",
+ "new_years_eve_party"
+]*/
+const board_events = [2, 9, 69, 97]
+const box_events = [ 15, 24, 26, 39, 48, 49, 53, 58, 59, 65, 70, 73, 100, 101, 104 ]
+let box_events_showing = false
+let show_discard = false
+
+const overlay = document.getElementById('overlay');
+const spaceNameElement = document.getElementById('space-name');
+const spaceCharacteristicsElement = document.getElementById('space-characteristics');
+
+
+// Event listener to track mouse movement over the map
+ document.querySelector('.map').addEventListener('mousemove', function(event) {
+ const x = event.offsetX; // X-coordinate of mouse relative to container
+ const y = event.offsetY; // Y-coordinate of mouse relative to container
+ spaceCharacteristicsElement.innerText = `X: ${x}, Y: ${y}`;
+ })
+
+
+ // Create map areas dynamically based on coordinates
+
+ function create_ui() {
+
+// CREATE MAP
+
+ spaces.forEach((space) => {
+
+
+ if (space && space.box) {
+
+ //CREATE SPACES
+ const { x, y} = space.box;
+ const spaceArea = document.createElement('div');
+ spaceArea.classList.add('space-area', space.country)
+ spaceArea.id=`space_${space.space_id}`;
+ spaceArea.style.left = x + 'px';
+ spaceArea.style.top = y + 'px';
+ spaceArea.style.width = width + 'px';
+ spaceArea.style.height = height + 'px';
+ spaceArea.style.zIndex = 2;
+ spaceArea.my_space = space.space_id;
+ spaceArea.addEventListener('mousedown', on_click_space);
+
+ //CREATE DEMOCRATIC INFLUENCE MARKERS FOR EACH SPACE
+ const dem_img = document.createElement('div')
+ dem_img.classList.add('demInfl', space.country)
+ dem_img.style.display = 'none'
+ dem_img.id=`${space.name_unique}_demInfl`
+ dem_img.style.zIndex = 1
+ dem_img.my_space = space.space_id;
+ dem_img.addEventListener('mousedown', on_click_space);
+ spaceArea.appendChild(dem_img)
+
+ //CREATE DEMOCRATIC INFLUENCE VALUES
+ const demInflValue = document.createElement('p')
+ demInflValue.className='demInflValue'
+ demInflValue.style.display = 'none'
+ demInflValue.id=`${space.name_unique}_demInflValue`
+ demInflValue.innerText=space.demInfl
+ demInflValue.style.zIndex = 1
+ demInflValue.my_space = space.space_id;
+ demInflValue.addEventListener('mousedown', on_click_space);
+ spaceArea.appendChild(demInflValue)
+
+ //CREATE COMMUNIST INFLUENCE MARKERS FOR EACH SPACE
+ const com_img = document.createElement('div')
+ com_img.className='comInfl'
+ com_img.style.display='none'
+ com_img.id=`${space.name_unique}_comInfl`
+ com_img.style.zIndex = 1
+ com_img.my_space = space.space_id;
+ com_img.addEventListener('mousedown', on_click_space);
+ spaceArea.appendChild(com_img)
+
+ //CREATE COMMUNIST INFLUENCE VALUES
+ const comInflValue = document.createElement('p')
+ comInflValue.className='comInflValue'
+ comInflValue.style.display='none'
+ comInflValue.id=`${space.name_unique}_comInflValue`
+ comInflValue.innerText=space.comInfl
+ comInflValue.style.zIndex = 1
+ comInflValue.my_space = space.space_id;
+ comInflValue.addEventListener('mousedown', on_click_space);
+ spaceArea.appendChild(comInflValue)
+ //}
+
+ counters.appendChild(spaceArea);
+ }
+ });
+
+// CREATE CARDS
+
+ const is_mobile = window.matchMedia("(pointer: coarse)").matches
+
+ for (let c = 1; c <= last_card; ++c) {
+
+ const hand_card = document.createElement('img');
+ hand_card.classList.add('hand_card')
+ hand_card.id=`card_${c}`;
+ hand_card.src = `cards/e${c}.gif`
+ hand_card.my_card = c;
+ hand_card.addEventListener('click', on_click_card);
+
+ if(!is_mobile) {
+ hand_card.addEventListener('mouseenter', () => {
+ hover_timeout = setTimeout(() => {
+ hand_card.classList.add('zoom');
+ }, 500) })
+ hand_card.addEventListener('mouseleave', () => {
+ clearTimeout(hover_timeout);
+ hand_card.classList.remove('zoom');
+ });
+ }
+
+ ui.cards.push(hand_card);
+ }
+
+
+
+ for (let card of power_cards) {
+ if (!card) continue;
+ const power_card = document.createElement('img');
+ power_card.classList.add('power_card');
+ power_card.id = `power_card_${card.number}`;
+ power_card.src = `cards_2/${card.url}.gif`;
+ power_card.my_card = card.number;
+ power_card.addEventListener('mousedown', on_click_card);
+ ui.power_cards.push(power_card);
+ }
+}
+
+
+
+
+function is_card_enabled(card) {
+ if (view.actions) {
+ if (card_action_menu.some(a => view.actions[a] && view.actions[a].includes(card)))
+ return true
+ if (view.actions.card_select && view.actions.card_select.includes(card))
+ return true
+ if (view.actions.card && view.actions.card.includes(card))
+ return true
+ }
+ return false
+}
+
+// SUPPORTING FUNCTIONS
+
+function on_click_space(evt) {
+ if (evt.button === 0) {
+ const space = evt.target.my_space;
+ //console.log('on_click_space_called with space:', space);
+ if (send_action('infl', space)) {
+ //console.log('send_action with infl:', space);
+ evt.stopPropagation();
+ } else if (send_action('sc', space)) {
+ //console.log('send_action with sc:', space);
+ evt.stopPropagation();
+ } else {
+ // console.log('send_action failed for space:', space);
+ }
+ }
+ //hide_popup_menu();
+}
+
+function on_click_card(evt) {
+ if (evt.button === 0) {
+ const card = evt.target.my_card;
+ //console.log('on_click_card_called with card:', card);
+ if (is_action('card', card)) {
+ //console.log('in action card')
+ if (send_action('card', card)) {
+ evt.stopPropagation();
+ }
+ }
+ }
+}
+
+function is_action(action) {
+ //console.log('is_action called with: ', action)
+ //console.log('view.actions', view.actions)
+ if (view.actions && view.actions[action])
+ return true
+ return false
+}
+
+function is_card_action(action, card) {
+ //console.log('is_card_action called with action', action, 'card', card)
+ //console.log('view.actions', view.actions, 'view.actions[action]', view.actions[action])
+ if (view.actions && view.actions[action] && view.actions[action].includes(card))
+ return true
+ return false
+}
+
+function on_log(text) { // eslint-disable-line no-unused-vars
+
+ let p = document.createElement("div")
+
+ if (text.match(/^>/)) {
+ text = text.substring(1)
+ p.className = 'i'
+ }
+
+ text = text.replace(/_/g, ' ')
+ text = text.replace(/C(\d+)/g, sub_card_name)
+ text = text.replace(/P(\d+)/g, sub_power_card_name)
+ text = text.replace(/V(\d+)/g, sub_power_card_value)
+ text = text.replace(/%(\d+)/g, sub_space_name)
+ text = text.replace(/D[1-6]/g, sub_die)
+
+
+ if (text.match(/^\.h1/)) {
+ text = text.substring(4)
+ p.className = 'h1'
+ }
+ else if (text.match(/^\.h2d/)) {
+ text = text.substring(5)
+ p.className = 'h2 dem'
+ }
+ else if (text.match(/^\.h2c/)) {
+ text = text.substring(5)
+ p.className = 'h2 com'
+ }
+ else if (text.match(/^\.h2/)) {
+ text = text.substring(4)
+ p.className = 'h2'
+ }
+ else if (text.match(/^\.h3/)) {
+ text = text.substring(4)
+ p.className = 'h3'
+ }
+
+ p.innerHTML = text
+ return p
+}
+
+let ui = {
+ favicon: document.getElementById('favicon'),
+ player: [
+ document.getElementById("role_Democrat"),
+ document.getElementById("role_Communist"),
+ ],
+ cards: [ null ],
+ power_cards: [null],
+ dem_hand_count: document.getElementById("role_stat_dem"),
+ com_hand_count: document.getElementById("role_stat_com"),
+ deck_length: document.getElementById("deck_length"),
+ played_card: 0,
+ table_panel: document.getElementById("table_panel"),
+ hand_panel: document.getElementById("hand_panel"),
+ turn: document.getElementById("turn-tracker"),
+ round: document.getElementById("action-round-tracker"),
+ stability: document.getElementById("stability-track"),
+ dem_TST: document.getElementById("dem-TST"),
+ com_TST: document.getElementById("com-TST"),
+ vp: document.getElementById("vp"),
+ spaces: document.getElementsByClassName("space-area")
+
+}
+
+
+function on_update() {
+ //console.log('on_update called')
+ //console.log('view.valid_spaces: ', view.valid_spaces)
+ //console.log('view.actions: ', view.actions)
+ //console.log('view.power_cards:', view.power_cards)
+ document.querySelectorAll('[id^="space_"].selected').forEach(spaceElement => {spaceElement.classList.remove('selected');});
+ document.getElementById("power_hand")?.querySelectorAll('.selected').forEach(cardElement => {cardElement.classList.remove('selected');});
+ view.valid_spaces.forEach(space_id => {
+ const spaceElementId = `space_${space_id}`;
+ const spaceElement = document.getElementById(spaceElementId);
+
+ if (spaceElement) {
+ spaceElement.classList.add('selected');
+ }
+ });
+
+ //Check influence values
+
+ for (let i = 1; i < spaces.length; i ++) {
+
+ const space = spaces[i]
+ const demInfl = view.demInfl[i]
+ const comInfl = view.comInfl[i]
+ //console.log('piece', piece)
+ //console.log('space', space)
+ const dem_marker = document.getElementById(`${space.name_unique}_demInfl`);
+ const dem_number = document.getElementById(`${space.name_unique}_demInflValue`);
+ const com_marker = document.getElementById(`${space.name_unique}_comInfl`);
+ const com_number = document.getElementById(`${space.name_unique}_comInflValue`);
+
+ dem_number.innerText=demInfl
+ if (demInfl > 0) {
+ dem_marker.style.display = 'block';
+ dem_number.style.display = 'block';
+
+ if (demInfl > 9) {
+ dem_number.classList.remove('demInflValue')
+ dem_number.classList.add('demInflValue_10')
+ } else {
+ dem_number.classList.add('demInflValue')
+ dem_number.classList.remove('demInflValue_10')
+ }
+
+ if(check_dem_control(demInfl, comInfl, space)){
+ dem_marker.classList.add('controlled')
+ dem_number.classList.add('outlined_text')
+ dem_marker.classList.remove('uncontrolled')
+ } else {
+ dem_marker.classList.add('uncontrolled')
+ dem_marker.classList.remove('controlled')
+ dem_number.classList.remove('outlined_text')
+ }
+ } else {
+ dem_marker.style.display = 'none';
+ dem_number.style.display = 'none';
+ }
+ com_number.innerText=comInfl
+ if (comInfl > 0) {
+ com_marker.style.display = 'block';
+ com_number.style.display = 'block';
+
+ if (comInfl > 9) {
+ com_number.classList.remove('comInflValue')
+ com_number.classList.add('comInflValue_10')
+ } else {
+ com_number.classList.add('comInflValue')
+ com_number.classList.remove('comInflValue_10')
+ }
+
+ if(check_com_control(demInfl, comInfl, space)){
+ com_marker.classList.add('controlled')
+ com_number.classList.add('controlled')
+ com_marker.classList.remove('uncontrolled')
+ com_number.classList.remove('uncontrolled')
+ } else {
+ com_marker.classList.add('uncontrolled')
+ com_number.classList.add('uncontrolled')
+ com_marker.classList.remove('controlled')
+ com_number.classList.remove('controlled')
+ }
+ } else {
+ com_marker.style.display = 'none';
+ com_number.style.display = 'none';
+ }
+
+ }
+
+// UPDATE COUNTRY MARKERS
+ for (let i = 0; i < countries.length; i++) {
+ const country = countries[i];
+ const marker = document.getElementById(country)
+ const times_held = document.getElementById(`${country}_times_held`)
+
+ if (view.revolutions[find_country_index(country)]) {
+ marker.classList.add('revolution')
+ marker.classList.remove('held')
+ marker.style.display = 'block'
+ times_held.classList.add('outlined_text')
+ times_held.classList.remove('hide')
+ } else if (view.times_held[find_country_index(country)] > 0 ) {
+ //console.log('setting ', country)
+ marker.classList.add('held')
+ marker.style.display = 'block'
+ times_held.classList.remove('hide')
+ times_held.innerHTML = view.times_held[find_country_index(country)]
+ }
+ else {marker.style.display = 'none'}
+ }
+
+// UPDATE ASIDE
+ if (view.is_pwr_struggle) {
+ ui.dem_hand_count.innerText = `${view.democrat_power_hand} Power cards`
+ ui.com_hand_count.innerText = `${view.communist_power_hand} Power cards`
+ } else{
+ ui.dem_hand_count.innerText = `${view.democrat_hand} cards`
+ ui.com_hand_count.innerText = `${view.communist_hand} cards`
+ }
+ ui.deck_length.innerText = `${view.strategy_deck} cards`
+
+// UPDATE HAND
+ document.getElementById("hand").replaceChildren()
+ document.getElementById("played_card").replaceChildren()
+
+ if (view.hand.length && view.is_pwr_struggle === false) {
+ document.getElementById("hand_panel").classList.remove("hide")
+ //console.log('view.actions.card', view.actions.card)
+ for (let c of view.hand) {
+ let card = ui.cards[c]
+ document.getElementById("hand").appendChild(card);
+ if (view.actions && view.actions.card && view.actions.card.includes(c)) {
+ card.classList.add('action')
+ } else {
+ card.classList.remove('action')
+ }
+ if (view.valid_cards.includes(c)) {
+ card.classList.add('selected')
+ } else {
+ card.classList.remove('selected')
+ }
+ card.classList.remove('discard_card')
+ }
+ } else {
+ document.getElementById("hand_panel").classList.add("hide")
+ }
+
+// UPDATE DISCARD
+document.getElementById("discard").replaceChildren()
+if (!view.is_pwr_struggle) {
+ for (let c of view.strategy_discard) {
+ let discard_card = ui.cards[c]
+ document.getElementById("discard").appendChild(discard_card)
+ discard_card.classList.add('discard_card')
+ discard_card.classList.remove('selected')
+ }
+} else if (view.is_pwr_struggle) {
+ for (let c of view.strategy_discard) {
+ let discard_card = ui.power_cards[c]
+ document.getElementById("discard").appendChild(discard_card)
+ discard_card.classList.add('discard_card')
+ discard_card.classList.remove('selected')
+ }
+}
+
+// DISCARD FOR EVENTS
+//console.log('view.discard',view.discard)
+if(view.discard) {
+ //document.getElementById("discard").replaceChildren()
+ document.getElementById("discard_panel").classList.remove("hide")
+ for (let c of view.strategy_discard) {
+ let discard_card = ui.cards[c]
+ document.getElementById("discard").appendChild(discard_card)
+ discard_card.classList.add('discard_card')
+ if (view.valid_cards.includes(c)) {
+ discard_card.classList.add('selected')
+ } else {
+ discard_card.classList.remove('selected')
+ }
+ }
+} else {
+ if (!show_discard) {
+ document.getElementById("discard_panel").classList.add("hide")
+ }
+}
+
+// UPDATE PERMANENTLY REMOVED CARDS
+document.getElementById("removed").replaceChildren()
+for (let c of view.strategy_removed) {
+ let discard_card = ui.cards[c]
+ document.getElementById("removed").appendChild(discard_card)
+ discard_card.classList.add('discard_card')
+ discard_card.classList.remove('selected')
+}
+
+
+// PLAYED CARD PANEL
+if (view.played_card > 0) {
+ document.getElementById("played_card_panel").classList.remove("hide")
+ document.getElementById("played_card").appendChild(ui.cards[view.played_card]);
+ document.getElementById("played_card").classList.remove("hand_card")
+} else {
+ document.getElementById("played_card_panel").classList.add("hide")
+}
+
+// TABLE CARDS PANEL
+document.getElementById("table_cards").replaceChildren()
+if (view.table_cards.length > 0) {
+ document.getElementById("table_panel").classList.remove("hide")
+ for (let c of view.table_cards) {
+ let card = ui.cards[c]
+ document.getElementById("table_cards").appendChild(card);
+ card.classList.remove("hand_card")
+ card.classList.add('event_card');
+ }
+ } else {
+ document.getElementById("table_panel").classList.add("hide")
+}
+
+// OPPONENT HAND
+document.getElementById("opp_hand").replaceChildren()
+if (!view.is_pwr_struggle) {
+ if (view.show_opp_hand && view.opp_hand.length >0) {
+ document.getElementById("opp_hand_panel").classList.remove("hide")
+ for (let c of view.opp_hand) {
+ let card = ui.cards[c]
+ document.getElementById("opp_hand").appendChild(card);
+ card.classList.remove('discard_card')
+ if (!view.is_pwr_struggle) {
+ if (view.valid_cards.includes(c)) {
+ card.classList.add('selected')
+ } else {
+ card.classList.remove('selected')
+ }
+ }
+ }
+ } else {
+ document.getElementById("opp_hand_panel").classList.add("hide")
+ }
+} else {
+ //console.log('power struggle, show opp hand', view.show_opp_hand, 'view opp hand', view.opp_hand )
+ if (view.show_opp_hand && view.opp_hand && view.opp_hand.length > 0) {
+ document.getElementById("opp_hand_panel").classList.remove("hide")
+ for (let c of view.opp_hand) {
+ let card = ui.power_cards[c]
+ //console.log('power_card:', power_card)
+ document.getElementById("opp_hand").appendChild(card);
+ card.classList.remove('discard_card')
+ }
+ } else {
+ document.getElementById("opp_hand_panel").classList.add("hide")
+ }
+}
+
+// POWER STRUGGLE HAND
+ document.getElementById("power_hand").replaceChildren()
+
+ if (view.power_hand.length && view.is_pwr_struggle) {
+ document.getElementById("power_panel").classList.remove("hide")
+ for (let c of view.power_hand) {
+ let power_card = ui.power_cards[c]
+ document.getElementById("power_hand").appendChild(power_card);
+ power_card.classList.remove('discard_card')
+ if (view.valid_cards.includes(c)) {
+ power_card.classList.add('selected');
+ }
+ }
+ } else {
+ document.getElementById("power_panel").classList.add("hide")
+ }
+
+// CEAUSESCU
+
+if (view.ceausescu_cards && view.ceausescu_cards.length > 0 && view.is_pwr_struggle === true) {
+ document.getElementById("ceausescu_panel").classList.remove("hide")
+ for (let c of view.ceausescu_cards) {
+ let power_card = ui.power_cards[c]
+ document.getElementById("ceausescu_hand").appendChild(power_card);
+ power_card.classList.remove('discard_card')
+
+ }
+} else {
+ document.getElementById("ceausescu_panel").classList.add("hide")
+}
+
+// SAMIZDAT CARD
+if (view.samizdat > 0 ) {
+ let samizdat_card = ui.cards[view.samizdat]
+ document.getElementById("samizdat_panel").classList.remove("hide")
+ document.getElementById("samizdat_card").appendChild(samizdat_card)
+} else {
+ document.getElementById("samizdat_panel").classList.add("hide")
+}
+
+// UPDATE BOARD MARKERS
+ ui.turn.className = `t${view.turn}`
+ if (view.round_player === 'Democrat') {
+ ui.round.className = `dem-action-round-tracker r${view.round}`
+ } else {
+ ui.round.className = `com-action-round-tracker r${view.round}`
+ }
+ ui.stability.className = `s${view.stability}`
+ ui.dem_TST.className = `tst${view.dem_tst}`
+ ui.com_TST.className = `tst${view.com_tst}`
+ if (view.vp >= -20 && view.vp <= 20) {
+ ui.vp.className = `vp${view.vp}`
+ } else if (view.vp > 20) {
+ ui.vp.className = `vp21`
+ } else if (view.vp < -20) {
+ ui.vp.className = `vp-21`
+ }
+
+//console.log('strategy discard: ', view.strategy_discard)
+//console.log('valid spaces: ', view.valid_spaces)
+
+//console.log('view.persistent_events', view.persistent_events)
+
+// UPDATE EVENT MARKERS ON THE BOARD
+
+for (let id of board_events) {
+ let marker = document.getElementById(`event_${id}`)
+ //console.log('event', id, marker)
+ if (view.persistent_events.includes(id)) {
+ marker.style.display = 'block'
+ } else {
+ marker.style.display = 'none'
+ }
+}
+
+
+// UPDATE EVENT MARKERS BELOW THE BOARD
+
+for (let id of box_events) {
+ let marker = document.getElementById(`event_${id}`)
+ //console.log('event', id, marker)
+ if (view.persistent_events.includes(id)) {
+ marker.style.display = 'block'
+ } else {
+ marker.style.display = 'none'
+ }
+}
+
+
+// CHECK WHETHER ANY EVENT MARKERS ARE SHOWING IN THE EVENTS BOX
+box_events_showing = false
+for (let id of box_events) {
+ if (view.persistent_events.includes(id)) {
+ box_events_showing = true;
+ }
+/*
+ //Special check for events which are not true/false
+ if (view.persistent_events['foreign_currency_debt_burden'] !== '') {
+ aside_events_showing = true
+ }
+ if (view.persistent_events['stand_fast'] !== '') {
+ aside_events_showing = true
+ }
+ */
+}
+
+if (box_events_showing) {
+ document.getElementById('events_panel').classList.remove("hide")
+} else {
+ document.getElementById('events_panel').classList.add("hide")
+}
+
+let systematization = document.getElementById('event_69')
+if (view.persistent_events.includes(69)) {
+ systematization.style.left = (spaces[view.systematization].box.x +20) + 'px';
+ systematization.style.top = spaces[view.systematization].box.y + 'px';
+}
+
+let tyrant = document.getElementById('event_97')
+if (view.persistent_events.includes(97)) {
+ tyrant.style.left = (spaces[view.the_tyrant_is_gone].box.x - 41) + 'px';
+ tyrant.style.top = (spaces[view.the_tyrant_is_gone].box.y + 23) + 'px';
+} else {tyrant.style.display = 'none'}
+
+ action_button("yes", "Yes")
+ action_button("no", "No")
+ action_button("start", "Start")
+ action_button("check", "Check held cards")
+ action_button("tst_7", "Cancel opponent event")
+ action_button("tst_8", "Event and operations")
+ action_button("end", "End Game")
+ action_button("continue", "Continue playing")
+ action_button("east_germany", "East Germany")
+ action_button("poland", "Poland")
+ action_button("czechoslovakia", "Czechoslovakia")
+ action_button("hungary", "Hungary")
+ action_button("romania", "Romania")
+ action_button("bulgaria", "Bulgaria")
+ action_button("extra", "Take action round")
+ action_button("pass", "Pass")
+ action_button("remove", "Remove SPs")
+ action_button("add", "Add SPs")
+ action_button("ops", "Operations")
+ action_button("discard", "Discard")
+ action_button("strike", "Strike")
+ action_button("march", "March")
+ action_button("rally", "Rally in the Square")
+ action_button("petition", "Petition")
+ action_button("bonus", "Calculate VP bonus")
+ action_button("scoring", "Score country")
+ action_button("retain", "Retain Power")
+ action_button("surrender", "Surrender Power")
+ action_button("take", "Take Power")
+ action_button("concede", "Concede")
+ action_button("struggle", "Begin power struggle")
+ action_button("raise", "Raise the stakes")
+ action_button("draw", "Draw")
+ action_button("scoring", "Scoring")
+ action_button("event", "Event")
+ action_button("opp_event", "Resolve opponent event")
+ action_button("influence", "Place SPs")
+ action_button("support_check", "Support Checks")
+ action_button("tst", "Tiananmen Square Track")
+ action_button("roll", "Roll a die")
+ action_button("done", "Done")
+ action_button("end_round", "End Round")
+ action_button("undo", "Undo")
+
+console.log('view.actions', view.actions)
+}
+
+// =========================== LOG FUNCTIONS ==============================================
+
+function sub_card_name(match, p1) {
+ let x = p1 | 0
+ return `<span class="card_name" onmouseenter="on_focus_card_tip(${x})" onmouseleave="on_blur_card_tip()">${cards[x].name}</span>`
+}
+
+function sub_power_card_name(match, p1) {
+ let x = p1 | 0
+ return `<span class="card_name">${power_cards[x].name}</span>`
+}
+
+function sub_power_card_value(match, p1) {
+ let x = p1 | 0
+ return `<span class="card_name">${x}</span>`
+}
+
+function sub_space_name(match, p1) {
+ let x = p1 | 0
+ let id = spaces[x].space_id
+ let name = spaces[x].name_unique
+ return `<span class="space_tip" onmouseenter="on_focus_space_tip(${id})" onmouseleave="on_blur_space_tip(${id})" onclick="on_click_space_tip(${id})">${name}</span>`
+}
+
+function sub_die(match) {
+ return die[match] || match
+}
+
+const die = {
+ D1: '<span class="die white d1"></span>',
+ D2: '<span class="die white d2"></span>',
+ D3: '<span class="die white d3"></span>',
+ D4: '<span class="die white d4"></span>',
+ D5: '<span class="die white d5"></span>',
+ D6: '<span class="die white d6"></span>'
+}
+
+// =========================== VISUAL FUNCTIONS ==========================================#
+
+function on_focus_card_tip(card_number) {
+ document.getElementById("tooltip").className = "card card_" + card_number
+}
+
+function on_blur_card_tip() {
+ document.getElementById("tooltip").classList = "card hide"
+}
+
+function on_focus_space_tip(id) {
+ space = document.getElementById(`space_${id}`)
+ space.classList.add("tip")
+}
+
+function on_click_space_tip(id) {
+ space = document.getElementById(`space_${id}`)
+ scroll_into_view(space)
+}
+
+function on_blur_space_tip(id) {
+ space = document.getElementById(`space_${id}`)
+ space.classList.remove("tip")
+}
+
+function toggle_pieces() {
+ document.getElementById("pieces").classList.toggle("hide")
+}
+
+
+function toggle_discard() {
+ if (show_discard) {
+ show_discard = false
+ } else {
+ show_discard = true
+ }
+ document.getElementById("discard_panel").classList.toggle("hide")
+}
+
+function toggle_removed() {
+ document.getElementById("removed_panel").classList.toggle("hide")
+}
+
+function check_dem_control(demInfl, comInfl, space) {
+ if ((demInfl - comInfl) >= space.stability) {
+ return true
+ } else{ false}
+}
+
+function check_com_control(demInfl, comInfl, space) {
+ if ((comInfl - demInfl) >= space.stability) {
+ return true
+ } else{ false}
+}
+
+function find_country_index(country) {
+ return countries.indexOf(country)
+}
+
+create_ui()
diff --git a/rules.js b/rules.js
index 91818c9..44bbef6 100644
--- a/rules.js
+++ b/rules.js
@@ -1,9892 +1,9892 @@
-//"use strict"
-
-const { spaces, cards, power_cards } = require("./data.js")
-
-var game, view, states = {}
-
-const DEM = "Democrat"
-const COM = "Communist"
-
-const first_strategy_card = 1
-const last_strategy_card = 110
-
-const dem_tst_req = [5, 5, 6, 6, 7, 8, 9, 10]
-const com_tst_req = [6, 6, 7, 7, 8, 7, 6, 5]
-const scoring_cards = [22, 23, 42, 43, 55, 95]
-const leader_cards = [37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48]
-const leaders = [1, 4, 5, 6, 7]
-const support_loss_roll = [0, 0, 1, 1, 2, 2, 3, 4]
-const vp_roll = [0, 0, 1, 1, 2, 2, 3, 4]
-const countries = ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania']
-const elite_spaces = [12, 15, 27, 43, 51, 69]
-const all_power_cards = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 ]
-const numberless_cards = [25, 26, 27, 28, 29, 30, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52]
-const auto_resolve_events = [5, 8, 9, 13, 17, 25, 26, 30, 35, 50, 53, 54, 58, 59, 62, 63, 65, 70, 72, 74, 86, 99, 102, 108]
-const switch_events = [6, 20, 71]
-
-exports.scenarios = [ "Standard" ]
-
-exports.roles = [ DEM, COM ]
-
-// --- SET UP ---
-
-exports.setup = function (seed, scenario, options) {
- game = {
- seed: seed,
- log: [],
- undo: [],
- summary: [],
- active: null,
- state: "com_init",
- return: '',
- vm: null,
- vm_event: 0,
- vm_event_to_do: false,
- vm_infl_to_do: false,
-
- played_card: 0,
- table_cards: [],
- available_ops: 0,
- vm_available_ops: 0,
- valid_spaces: [],
- valid_cards: [],
-
- vp: 0,
- turn: 0,
- round: 0,
- round_player: COM,
- stability: 0,
- dem_tst_position: 0,
- com_tst_position: 0,
- dem_tst_attempted: 0,
- com_tst_attempted: 0,
- dem_tst_attempted_this_turn: 0,
- com_tst_attempted_this_turn: 0,
-
- demInfl: [],
- comInfl: [],
-
- strategy_deck: [],
- strategy_discard: [],
- discard: false,
- view_opp_hand: false,
- strategy_removed: [],
- persistent_events: [],
- power_struggle_deck: [],
- power_struggle_discard: [],
- dem_hand_limit: 8,
- com_hand_limit: 8,
- democrat_hand: [],
- communist_hand: [],
-
- pwr_struggle_in: [],
- is_pwr_struggle: false,
- dem_pwr_hand_limit: 0,
- com_pwr_hand_limit: 0,
- dem_pwr_hand: [],
- com_pwr_hand: [],
- raised_stakes_discard: 0,
- raised_stakes: 0,
- raised_stakes_round: 0,
- phase: 0,
- times_held: [0, 0, 0, 0, 0, 0],
- revolutions: [false, false, false, false, false, false],
- remove_opponent_infl: false,
- tactics_fails: '',
- }
-
- log_h1("1989 Dawn of Freedom")
-
- game.active = COM
- start_game()
-
- return game
-}
-
-function start_game() {
- //starting influence
-
- // Draw cards
-
- //console.log('start game')
-
- game.strategy_deck = draw_deck(cards)
- reset_power()
-
- //Set starting influence
- spaces.forEach((space, index) => {
- if (space !== null) {
- game.demInfl[index] = space.demInfl
- game.comInfl[index] = space.comInfl
- }
- })
-
- //Set starting placement ops
- game.starting_infl = {
- com_starting_infl: 0,
- dem_starting_infl: 0
- },
-
- // Set variable event cards where event is playable at start of game
-
- game.playable_cards = [14, 15, 21, 70]
-
- //console.log('game.strategy_deck: ', game.strategy_deck[1])
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.dem_hand_limit, game.com_hand_limit)
- //.log('game.strategy_deck: ', game.strategy_deck[1], 'democrat_hand:', game.democrat_hand)
-
- game.valid_spaces = valid_spaces_setup()
- game.available_ops = 2
- game.phase = 0
- log_h1("Place starting Support Points")
- log_side()
-}
-
-
-exports.view = function(state, player) {
- game = state
-
- view = {
- log: game.log,
- active: game.active,
- prompt: null,
- actions: null,
-
- played_card: game.played_card,
- table_cards: game.table_cards,
- valid_spaces: game.valid_spaces,
- valid_cards: game.valid_cards,
-
- demInfl: game.demInfl,
- comInfl: game.comInfl,
- turn: game.turn,
- round: game.round,
- round_player: game.round_player,
- vp: game.vp,
- stability: game.stability,
- dem_tst: game.dem_tst_position,
- com_tst: game.com_tst_position,
- persistent_events: game.persistent_events,
- systematization: game.systematization,
- the_tyrant_is_gone: game.the_tyrant_is_gone,
-
- strategy_deck: game.strategy_deck.length,
- strategy_removed: game.strategy_removed,
- discard: game.discard,
- show_opp_hand: game.view_opp_hand,
-
- democrat_hand: game.democrat_hand.length,
- communist_hand: game.communist_hand.length,
- democrat_power_hand: game.dem_pwr_hand.length,
- communist_power_hand: game.com_pwr_hand.length,
- ceausescu_cards: game.ceausescu_cards,
- is_pwr_struggle: game.is_pwr_struggle,
- times_held: game.times_held,
- revolutions: game.revolutions,
-
- hand: [],
- set_aside: [],
- pwr_hand: [],
-
-
- }
-
- if (game.is_pwr_struggle) {
- view.strategy_discard = game.power_struggle_discard
- } else {
- view.strategy_discard = game.strategy_discard
- }
-
- if (player === game.active && game.vm && game.vm.draw)
- view.drawn = game.vm.draw
-
- if (player === game.active) {
- if (game.selected_space > 0 ) {
- view.valid_spaces = [game.selected_space]
- } else {
- view.valid_spaces = game.valid_spaces
- }
- } else {
- view.valid_spaces = []
- }
-
- if (player === game.active) {
- view.valid_cards = game.valid_cards
- } else {
- view.valid_cards = []
- }
-
- if (player === DEM) {
- view.hand = game.democrat_hand
- if (game.communist_hand_red) {
- view.opp_hand = game.communist_hand_red
- }
- view.set_aside = game.democrat_set_aside /*Is this being used? */
- view.power_hand = [...game.dem_pwr_hand].sort((a, b) => a - b)
-
- } else if (player === COM) {
- view.hand = game.communist_hand
- view.opp_hand = [...game.dem_pwr_hand].sort((a, b) => a - b)
- view.power_hand = [...game.com_pwr_hand].sort((a, b) => a - b)
- }
-
- if (player === DEM) {
- view.samizdat = game.samizdat_card
- }
-
- if (game.state === "game_over") {
- view.prompt = game.victory
- } else if (player === "Observer" || (game.active !== player && game.active !== "Both")) {
- if (states[game.state]) {
- let inactive = states[game.state].inactive
- if (typeof inactive === "function")
- view.prompt = `Waiting for ${game.active} ${inactive()}`
- else
- view.prompt = `Waiting for ${game.active} to ${inactive}`
- } else {
- view.prompt = "A Unknown state: " + game.state
- }
- } else {
- view.actions = {}
-
- if (states[game.state])
- states[game.state].prompt(player)
- else
- view.prompt = "B Unknown state: " + game.state
- if (view.actions.undo === undefined) {
- if (game.undo && game.undo.length > 0)
- view.actions.undo = 1
- else
- view.actions.undo = 0
- }
- }
-
- return view
-}
-
-
-// === ACTIONS ===========
-
-function gen_action(action, argument) {
-//console.log('gen_action called with ', action, ' and ', argument)
- if (argument === undefined) {
- //console.log('argument undefined')
- view.actions[action] = 1
- } else {
- if (!(action in view.actions)) {
- //console.log('push argument')
- view.actions[action] = []
- }
- view.actions[action].push(argument)
- }
- //console.log('view.actions: ', view.actions, 'view.actions[action]: ', view.actions[action])
-}
-
-function gen_action_infl(space){
- gen_action("infl", space)
-}
-
-function gen_action_card(card){
- gen_action("card", card)
-}
-
-function gen_action_sc(space){
- gen_action("sc", space)
-}
-
-function gen_action_scoring(){
- gen_action("scoring")
-}
-
-exports.action = function (state, player, action, arg) {
- //console.log('exports.action called with state:' , state, 'player:', player, 'action: ', action, 'arg: ', arg)
- game = state
- if (states[game.state] && action in states[game.state]) {
- states[game.state][action](arg, player)
- } else {
- if (action === "undo" && game.undo && game.undo.length > 0)
- pop_undo()
- else
- throw new Error("Invalid action: " + action)
- }
- return game
-}
-
-// ============= GAME STATES =======================
-
-states.com_init = {
- inactive: 'place starting SPs.',
- prompt() {
- //console.log('state:', game.state, 'game.valid_spaces', game.valid_spaces)
- if (game.starting_infl.dem_starting_infl === 2 && game.available_ops === 0 ) {
- view.prompt = 'Place starting SPs: done. Start Turn 1.';
- gen_action("start");
- } else if (game.available_ops === 0) {
- view.prompt = 'Place starting SPs: done.';
- gen_action("done");
- return;
- } else if (game.starting_infl.dem_starting_infl === 2) {
- view.prompt = `Place your last ${pluralize(game.available_ops,'starting SP')}.`
- } else {
- view.prompt = `Place ${pluralize(game.available_ops,'starting SP')}.`
- }
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- },
- infl(space) {
- add_infl(space)
-
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- game.starting_infl.com_starting_infl++
- if (game.starting_infl.com_starting_infl == 1){
- game.available_ops = 3
- game.state = 'dem_init'
- valid_spaces_setup()
- next_player()
- } else if (game.starting_infl.com_starting_infl == 2) {
- game.available_ops = 4
- game.state = 'dem_init'
- valid_spaces_setup()
- next_player()
- } else if (game.starting_infl.com_starting_infl == 3) {
- delete game.starting_infl
- game.state = 'start_game'
- }
- },
- start() {
- new_turn()
- clear_undo()
- game.state = 'choose_card'
- }
-}
-
-states.dem_init = {
- inactive: 'place starting SPs.',
- prompt() {
- //console.log('state:', game.state)
- if (game.available_ops == 0) {
- view.prompt = 'Place starting SPs: done.';
- gen_action("done");
- return;
- } else if (game.starting_infl.com_starting_infl === 2) {
- view.prompt = `Place your last ${pluralize(game.available_ops,'starting SP')}.`
- } else {
- view.prompt = `Place ${pluralize(game.available_ops,'starting SP')}.`
- }
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- },
- infl(space) {
- add_infl(space)
- },
-
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- game.starting_infl.dem_starting_infl++
- if (game.starting_infl.dem_starting_infl == 1){
- game.available_ops = 3
- } else if (game.starting_infl.dem_starting_infl == 2) {
- game.available_ops = 2
- }
- game.state = 'com_init'
- valid_spaces_setup()
- next_player()
- }
-}
-
-
-states.choose_card = {
- inactive: 'choose a card.',
- prompt() {
- if ((game.active===DEM && game.democrat_hand.length === 0) || game.active === COM && game.communist_hand.length === 0) {
- view.prompt = 'No cards remaining: you must pass.'
- gen_action('pass')
- } else {
- view.prompt = 'Choose a card.'
- let available_cards
- if (game.active === DEM) {
- available_cards = game.democrat_hand
- } else {
- available_cards = game.communist_hand
- }
- for (let card of available_cards) {
- gen_action_card(card)
- }
- }
- },
- card(card) {
- push_undo()
-
- //Check if player is at risk of losing game due to held scoring card
- if (!scoring_cards.includes(card)) {
- let scoring_cards_count = count_scoring_cards()
-
- if (game.round !== 8 && scoring_cards_count >= (8-game.round)){
- game.temp = card
- game.state = 'confirm_card'
- return
- }
- }
- select_card(card)
- },
- pass() {
- log('No cards remaining. Passed')
- //end_round()
- game.state = 'end_round'
- }
-}
-
-states.confirm_card = {
- inactive: 'choose a card.',
- prompt() {
- let scoring_cards_count = count_scoring_cards()
- view.prompt = `${pluralize(scoring_cards_count,'scoring card')} in hand with ${pluralize(8-game.round,'turn')} remaining. Scoring cards may not be held. Continue?`
- gen_action('continue')
- },
- continue() {
- select_card(game.temp)
- }
-}
-
-states.play_card ={
- get inactive() {
- return `play ${clean_name(cards[game.played_card].name)}.`
- },
- prompt () {
- /*if (game.phase >= 1) { /*Finish here when playing your own event
- console.log('in play card')
- view.prompt = `${clean_name(cards[game.played_card].name)}: done. End the Action Round.`
- gen_action('end_round')
- return
- }*/
-
- view.prompt = `Play ${clean_name(cards[game.played_card].name)} for:`
-
- if (scoring_cards.includes(game.played_card)) {
- /*view.prompt = 'Play for:'*/
- gen_action('event')
- return
- }
-
- // Check for Reformer Rehabilitated
-
- //console.log('game.active', game.active, 'game.playable_cards[67].playable', game.playable_cards[67].playable)
-
-
- if (game.played_card === 67 && game.playable_cards.includes(67)){
- if (game.active === DEM && (game.dem_tst_position > game.com_tst_position)) {
- gen_action('event')
- }
- if (game.active === COM && (game.dem_tst_position < game.com_tst_position)) {
- gen_action('event')
- }
- }
-
- //Check for events
- //console.log('event_is_playable(game.played_card)', event_is_playable(game.played_card))
- if (event_is_playable(game.played_card)) {
- //console.log('card is playable')
- //Check for Tiananmen Square Track awards special abilities
- //console.log('game.tst_7', game.tst_7)
- if ((game.active === DEM && cards[game.played_card].side === 'C' && game.dem_tst_position >= 7 && game.com_tst_position < 7 && !game.tst_7) || (game.active === COM && cards[game.played_card].side === 'D' && game.com_tst_position >= 7 && game.dem_tst_position < 7 && !game.tst_7)){
- gen_action('tst_7')
- }
-
- if ((game.active === DEM && cards[game.played_card].side !== 'C' && game.dem_tst_position >= 8 && game.com_tst_position < 8 && !game.tst_8) || (game.active === COM && cards[game.played_card].side !== 'D' && game.com_tst_position >= 8 && game.dem_tst_position < 8 && !game.tst_8)){
- gen_action('tst_8')
- }
-
- //Continue with normal logic
- get_events(game.played_card)
- }
-
- gen_action('influence')
- gen_action('support_check')
-
- if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 && game.dem_tst_position < 8 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 && game.com_tst_position < 8)) {
- gen_action('tst')
- }
-
- },
- event() {
- push_undo()
- //console.log('played event, game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- game.vm_infl_to_do = false
- if (scoring_cards.includes(game.played_card)) {game.phase = 0}
- else {game.phase = 1}
- game.return = game.active
- if (switch_events.includes(game.played_card)) {next_player()}
- game.vm_event = game.played_card
- //console.log('before event, game.vm_infl_to_do', game.vm_infl_to_do)
- goto_vm(game.vm_event)
- },
- opp_event() {
- push_undo()
- log_gap(`Played C${cards[game.played_card].number} for the event`)
- game.phase = 1 /*Do I still need this?*/
- game.vm_infl_to_do = true
- game.return = game.active
- game.vm_event = game.played_card
- if (is_auto_resolve(game.played_card) || switch_events.includes(game.played_card)) {
- goto_vm(game.vm_event)}
- else {
- next_player()
- log(`C${game.vm_event}`)
- goto_vm(game.vm_event)
- }
- },
- influence() {
- push_undo()
- log_gap(`Played C${cards[game.played_card].number} to place SPs`)
-
-
- // Check if Common European Home played for influence
- if (game.played_card === 21) {
- if (game.active === DEM) {
- game.vp --
- log('-1 VP')
- if (check_vp()) {
- return
- }
- } else {
- game.vp ++
- log('+1 VP')
- if (check_vp()) {
- return
- }
- }
- }
- // Check if card is opponent card with event that needs to be resolved
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- //game.phase = 1 /*Do I need this? */
- game.vm_event_to_do = true
- }
- }
-
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state='add_influence'
- valid_spaces_infl()
- },
- tst() {
- push_undo()
- log_gap(`Played C${cards[game.played_card].number} to the Tiananmen Square Track`)
- game.state='tiananmen_square_attempt'
- },
- support_check() {
- push_undo()
- log_gap(`Played C${cards[game.played_card].number} for support checks`)
-
- // Check if card is opponent card with event that needs to be resolved
-
- if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
- if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
- game.vm_event_to_do = true
- }
- }
-
- game.available_ops = 2
- game.state='support_check_prep'
- valid_spaces_sc()
- },
- tst_7() { /*Cancel opponent event */
- push_undo()
- log(`Played C${game.played_card}. Event cancelled using TST Award`)
- game.tst_7 = true
- game.vm_infl_to_do = true
- game.state = 'resolve_opponent_event'
- },
- tst_8() { /*Play card for ops and event */
- push_undo()
- game.vm_event_to_do = true
- game.vm_infl_to_do = true
- game.tst_8 = true
- log(`Played C${game.played_card} for event and operations`)
- game.state = 'vm_tst_8'
- },
- end_round () {
- end_round()
- }
-
-}
-
-states.resolve_opponent_event = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- //console.log('in resolve opponent event: discard', game.strategy_discard)
- if (game.vm_infl_to_do) {
- view.prompt = 'Event resolved. Choose to play card for:'
- gen_action('influence')
- gen_action('support_check')
- } else if (game.vm_event_to_do) {
- // Check for Tiananmen Square Track ability - play opponent card without triggering event
- if ((game.active === DEM && game.dem_tst_position >= 7 && game.com_tst_position < 7 && !game.tst_7) || (game.active === COM && game.com_tst_position >= 7 && game.dem_tst_position < 7 && !game.tst_7)){
- gen_action('tst_7')
- }
- view.prompt = `${clean_name(cards[game.played_card].name)}: you must resolve the opponent event.`
- gen_action('opp_event')
- } else {
- view.prompt = 'Event resolved. End the action round.'
- gen_action('end_round')
- }
- },
- influence(){
- push_undo()
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'finish_add_infl'
- valid_spaces_infl()
- },
- support_check() {
- push_undo()
- game.available_ops = 2
- game.state = 'finish_support_check_prep'
- valid_spaces_sc()
- },
- opp_event() {
- game.vm_event_to_do = false
- game.return_state = 'resolve_opponent_event'
- if (is_auto_resolve(game.played_card) || switch_events.includes(game.played_card)) {
- game.return = game.active
- log(`Played C${game.played_card} for the event`)
- goto_vm(game.played_card)}
- else {
- if (game.active === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- next_player()
- log(`C${game.played_card}`)
- goto_vm(game.played_card)
- }
- },
- tst_7() {
- push_undo()
- log('Event cancelled using TST Award')
- game.tst_7 = true
- game.vm_event_to_do = false
- },
- end_round() {
- push_undo()
- /*if(game.round_player === COM && game.active === DEM) {
- log_h3('End of Communist Action Round')
- change_player()
- } */
- end_round()
- }
-}
-
-
-states.finish_add_infl = {
- inactive: 'add SPs.',
- prompt () {
- if (game.available_ops === 0) {
- view.prompt = 'Place SPs: done.'
- gen_action("end_round")
- return;
- }
-
- view.prompt = `Add SPs: ${game.available_ops} remaining.`
-
- // Generate actions for valid spaces
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id)
- }
- },
- infl(space) {
- add_infl(space)
- },
- end_round() {
- push_undo()
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- end_round()
- //game.state = 'end_round'
- }
-}
-
-states.finish_support_check_prep = {
- inactive: 'do support checks.',
- prompt () {
- if (game.available_ops === 0) {
- view.prompt = 'Support checks: done.'
- gen_action('end_round')
- //return
- } else {
- view.prompt = `Select a space. ${pluralize(game.available_ops, 'support check')} remaining.`
- for (let space_id of game.valid_spaces) {
- gen_action_sc(space_id)
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = space
- // Check for Austria-Hungary Border Reopened - check on first support check only
- //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
- if (game.persistent_events.includes(58)){
- if (game.active === DEM && game.available_ops > 1) {
- //console.log('in ahb check, country, ', spaces[game.selected_space].country, 'ahb', 'austria_hungary_border_reopened'])
- if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
- game.state = 'finish_austria_hungary_border_reopened_check'
- return
- }
- }
- }
- game.state = 'finish_do_support_check'
- },
- end_round () {
- end_round()
- //game.state = 'end_round'
- }
-}
-
-states.finish_austria_hungary_border_reopened_check = {
- inactive: 'decide Austria-Hungary Border Reopened',
- prompt() {
- view.prompt = 'Austria-Hungary Border Reopened: will both support checks be in East Germany?'
- gen_action('yes')
- gen_action('no')
- },
- yes() {
- game.austria_hungary_border_reopened_tracker = true
- game.state = 'finish_do_support_check'
- },
- no() {
- game.state = 'finish_do_support_check'
- }
-}
-
-states.finish_do_support_check = {
- inactive: 'do support checks',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(game.selected_space)
- game.available_ops--
- if (game.available_ops === 0) {
- game.valid_spaces = []
- }
- game.state = 'finish_support_check_prep'
- return
- }
-}
-
-states.add_influence = {
- inactive: 'add SPs.',
- prompt () {
- if (game.available_ops <= 0) {
- view.prompt = 'Place SPs: done.'
- if (!game.vm_event_to_do) {
- gen_action("end_round")
- } else {
- gen_action('done')
- }
- } else {
-
- view.prompt = `Add SPs: ${game.available_ops} remaining.`
-
- // Generate actions for valid spaces
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- }
- },
- infl(space) {
- add_infl(space)
- },
- end_round() {
- push_undo()
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- end_round()
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- reset_austria_hungary_border_reopened()
- game.state = 'resolve_opponent_event'
- }
-}
-
-states.tiananmen_square_attempt = {
- inactive: 'do Tiananmen Square Attempt.',
- prompt () {
- view.prompt = 'Tiananmen Square Track attempt: Roll a die.'
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_tst_attempt ()
- }
-}
-
-states.tiananmen_square_attempt_success = {
- inactive: 'do Tiananmen Square Attempt.',
- prompt () {
- if (game.vm_event > 200) {
- view.prompt = 'Tiananmen Square Track attempt successful. Go to TST Award.'
- gen_action('done')
- } else {
- view.prompt = 'Tiananmen Square Track attempt successful.'
- gen_action('end_round')
- }
-
- },
- done () {
- push_undo()
- //console.log('going to tst award, game.return_state', game.return_state)
- goto_vm(game.vm_event)
- },
- end_round () {
- push_undo()
- end_round()
- }
-}
-
-states.tiananmen_square_attempt_fail = {
- inactive: 'do Tiananmen Square Attempt.',
- prompt () {
- view.prompt = 'Tiananmen Square Track attempt failed.'
- gen_action('end_round')
- },
- end_round () {
- push_undo()
- end_round()
- //game.state = 'tiananmen_square_attempt_done'
- }
-}
-
-states.tiananmen_square_attempt_done = {
- inactive: 'do Tiananmen Square Attempt.',
- prompt () {
- view.prompt = 'Tiananmen Square Track attempt: done.'
- gen_action('end_round')
- },
- end_round () {
- end_round()
- //game.state = 'end_round'
- }
-}
-
-states.tst_goddess = {
- inactive: 'choose whether to discard a card.',
- prompt() {
- //if (game.phase === 0) {
- view.prompt = 'Tiananmen Square Track award: you may discard a non-Power Struggle Card and draw a replacement.'
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- gen_action('pass')
- /*} else {
- view.prompt = 'Discard a card: done.'
- gen_action('done')
- }*/
- },
- card(card) {
- push_undo()
- discard(card)
- game.valid_cards = []
- game.state = 'tst_goddess_draw'
- //game.phase++
- /*if (game.active === DEM) {
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length +1, game.communist_hand.length)
- } else {
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length +1)
- }*/
- },
- pass() {
- log('Did not discard')
- log_h2("Action Round " + game.round)
- if (game.active === DEM) {
- next_player()
- } else {
- log_side()
- }
- if (game.persistent_events.includes(5)) {
- game.state = 'general_strike'
- } else {
- game.state = 'choose_card'
- }
- },
- done() {
-
- log_h2("Action Round " + game.round)
- if (game.active === DEM) {
- next_player()
- } else {
- log_side()
- }
- game.phase = 0
- if (game.persistent_events.includes(5)) {
- game.state = 'general_strike'
- } else {
- game.state = 'choose_card'
- }
- }
-}
-
-states.tst_goddess_draw = {
- inactive: 'choose whether to discard a card.',
- prompt() {
- view.prompt = 'Draw a replacement card.'
- gen_action('draw')
- },
- draw() {
- if (game.active === DEM) {
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length +1, game.communist_hand.length)
- } else {
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length +1)
- }
- log_h2("Action Round " + game.round)
- if (game.active === DEM) {
- next_player()
- } else {
- log_side()
- }
- game.phase = 0
- if (game.persistent_events.includes(5)) {
- game.state = 'general_strike'
- } else {
- game.state = 'choose_card'
- }
- }
-}
-
-
-
-states.support_check_prep = {
- inactive: 'do support checks',
- prompt () {
- if (game.available_ops === 0) { /*Needs another check for Support Checks done during Crowd Turns against Ceausescu*/
- if (game.is_pwr_struggle) {
- view.prompt = 'The Crowd Turns Against Ceausescu. Support checks: done.'
- gen_action('done')
- } else if (!game.vm_event_to_do) {
- view.prompt = 'Support checks: done.'
- gen_action('end_round')
- } else {
- view.prompt = 'Support checks: done.'
- gen_action('done')
- }
- } else if (game.available_ops > 0) {
- view.prompt = `Select a space. ${pluralize(game.available_ops, 'support check')} remaining.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_sc(space_id)
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = space
-
- // Check for Austria-Hungary Border Reopened - check on first support check only
- //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
- if (game.persistent_events.includes(58)) {
- if (game.active === DEM && game.available_ops > 1) {
- if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
- game.state = 'austria_hungary_border_reopened_check'
- return
- }
- //game.state = 'do_support_check'
- } /*else { */
- }
- game.state = 'do_support_check'
- //}
- },
- end_round() {
- push_undo()
- end_round()
- },
- done() {
- push_undo()
- if (game.is_pwr_struggle) {/*Crowd Turns Against Ceausescu should be the only time you end up here during a power struggle */
- if (game.return !== game.active) {
- next_player()
- }
- log_h2('Raise the Stakes')
- game.state = 'raise_stakes_1'
- return
- }
- reset_austria_hungary_border_reopened()
- game.state = 'resolve_opponent_event'
- }
-}
-
-states.do_support_check = {
- inactive: 'do support checks.',
- prompt () {
- // console.log('in do_support_check')
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(game.selected_space)
- game.available_ops--
- if (game.available_ops === 0) {
- game.valid_spaces = []
- }
- game.state = 'support_check_prep'
- return
- }
-}
-
-states.austria_hungary_border_reopened_check = {
- inactive: 'decide Austria-Hungary Border Reopened.',
- prompt() {
- view.prompt = 'Austria-Hungary Border Reopened: will both support checks be in East Germany?'
- gen_action('yes')
- gen_action('no')
- },
- yes() {
- game.austria_hungary_border_reopened_tracker = true
- game.state = 'do_support_check'
- },
- no() {
- game.state = 'do_support_check'
- }
-}
-
-states.end_round = {
- inactive: 'finish playing a card.',
- prompt() {
- view.prompt = 'End the Action Round.'
- gen_action('end_round')
- },
- end_round() {
- push_undo()
- end_round()
- }
-}
-
-//======================= POWER STRUGGLE ===============================
-
-states.draw_power_cards = {
- inactive: 'draw cards.',
- prompt() {
- view.prompt = `${clean_name(cards[this_card()].name)}: draw cards.`
- gen_action('draw')
- },
- draw() {
- push_undo()
- game.power_struggle_deck = [...all_power_cards]
- // console.log('game.power_struggle_deck.length', game.power_struggle_deck.length)
- //console.log('called draw cards, country', game.pwr_struggle_in, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- //console.log('test3')
- let presence = check_presence(game.pwr_struggle_in)
- //console.log('test2')
- if (presence.dem_spaces > 0) {
- game.dem_pwr_hand_limit = 6 + 2*(presence.dem_spaces - 1)
- } else {
- game.dem_pwr_hand_limit = 0
- }
- if (presence.com_spaces > 0 ) {
- game.com_pwr_hand_limit = 6 + 2*(presence.com_spaces - 1)
- } else {
- game.com_pwr_hand_limit = 0
- }
- // Events which affect cards drawn
- if (game.persistent_events.includes(17) && game.com_pwr_hand_limit >= 2) {
- log('Democrat receives 2 cards from Communist due to C17')
- game.dem_pwr_hand_limit += 2
- game.com_pwr_hand_limit -= 2
- discard_from_table(17)
- game.persistent_events = game.persistent_events.filter(n => n !== 17)
- }
-
- if (game.persistent_events.includes(72)) {
- let farmer_check
- for (let space of spaces) {
- if (space && space.country === game.pwr_struggle_in && space.socio === 3 && check_dem_control(space.space_id)) {
- farmer_check = true
- }
- }
- if (farmer_check && game.com_pwr_hand_limit > 0) {
- log('Democrat receives 1 cards from Communist due to C72')
- game.dem_pwr_hand_limit += 1
- game.com_pwr_hand_limit -= 1
- permanently_remove(72)
- game.persistent_events = game.persistent_events.filter(n => n !== 72)
- }
- }
-
- if (game.persistent_events.includes(102) && game.dem_pwr_hand_limit >=2 && (game.pwr_struggle_in === 'Romania' || game.pwr_struggle_in === 'Bulgaria')) {
- log('Communist receives 2 cards from Democrat due to C102')
- game.dem_pwr_hand_limit -= 2
- game.com_pwr_hand_limit += 2
- permanently_remove(102)
- game.persistent_events = game.persistent_events.filter(n => n !== 102)
- }
-
- //Draw Power Cards
- game.is_pwr_struggle = true
- //console.log('game.dem_pwr_hand_limit', game.dem_pwr_hand_limit, 'game.com_pwr_hand_limit', game.com_pwr_hand_limit)
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand_limit, game.com_pwr_hand_limit)
- if (game.active === DEM) {
- game.valid_cards = [...game.dem_pwr_hand]
- } else {
- game.valid_cards = [...game.com_pwr_hand]
- }
- //game.valid_cards = all_power_cards
-
- log(`Communist: ${game.com_pwr_hand.length} cards`)
- log(`Democrat: ${game.dem_pwr_hand.length} cards`)
-
- //Check if The Crowd Turns Against Ceausescu occurs
- if (game.table_cards.includes(54) && game.pwr_struggle_in === 'Romania') {
- //console.log('draw cards: crowd subcheck, game.active', game.active)
- if (game.active === COM) {
- game.return = COM
- next_player()
- }
- log_h3('C54')
- game.persistent_events.push(54)
- game.state = 'the_crowd_turns_against_ceausescu_prep'
- } else {
- log_h2('Raise the Stakes')
- game.state = 'raise_stakes_1'
- //console.log('game.state', game.state, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- }
- }
-}
-
-states.the_crowd_turns_against_ceausescu_prep = {
- get inactive() {
- return `resolve ${clean_name(cards[54].name)}.`
- },
- prompt() {
- view.prompt = 'The Crowd Turns Against Ceausescu: draw cards.'
- gen_action('draw')
- },
- draw() {
- game.ceausescu_cards = []
- draw_cards(game.power_struggle_deck, game.ceausescu_cards, game.com_pwr_hand, 15, game.com_pwr_hand.length)
- //console.log('game.ceausescu_cards', game.ceausescu_cards)
- game.temp = game.ceausescu_cards.filter(card => card && card >=25 && card <= 30).length
- log(`Drew ${pluralize(game.temp, 'Rally in the Square')}.`)
- game.vm_available_ops = game.temp * 3
- log(`Democrat takes a ${game.vm_available_ops} Action Round`)
- game.state = 'vm_the_crowd_turns_against_ceausescu'
- }
-}
-
-states.vm_the_crowd_turns_against_ceausescu = {
- get inactive() {
- return `resolve ${clean_name(cards[54].name)}.`
- },
- prompt() {
- view.prompt = `You have ${game.vm_available_ops} operations points. Play for:`
- gen_action('influence')
- gen_action('support_check')
- },
- influence() {
- push_undo()
- delete game.ceausescu_cards
- valid_spaces_infl()
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'Romania')
- game.state = 'the_crowd_turns_against_ceausescu_infl' /* Send this to add_infl. Add check at end of add_infl similar to valid_spaces*/
- },
- support_check() {
- push_undo()
- delete game.ceausescu_cards
- valid_spaces_sc()
- game.available_ops = 2
- game.state = 'support_check_prep'
- }
-}
-
-states.the_crowd_turns_against_ceausescu_infl = {
- inactive: 'add SPs.',
- prompt () {
- if (game.vm_available_ops === 0)
- {
- view.prompt = 'Place SPs: done.';
- gen_action("done");
- return;
- }
-
- view.prompt = `Add SPs: ${game.vm_available_ops} remaining`
- for (let space of game.valid_spaces) {
- gen_action_infl(space)
- }
- },
- infl(space) {
- vm_do_add_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- if (game.return !== game.active) {
- next_player()
- }
- log_h2('Raise the Stakes')
- game.state = 'raise_stakes_1'
- }
-}
-
-states.raise_stakes_1 = {
- inactive: 'raise the stakes.',
-
- prompt () {
- // console.log('raise stakes 1 - valid cards', game.valid_cards)
- // console.log('raise the stakes: game.played_power_card', game.played_power_card, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- if ((game.active === DEM && game.dem_pwr_hand < 3) || (game.active === COM && game.com_pwr_hand < 3)) {
- view.prompt = 'Raise the stakes: you must pass.'
- gen_action('pass')
- }
- else if (game.raised_stakes_discard === 3) {
- view.prompt = 'Raise the stakes: done.'
- gen_action('done')
- } else {
- view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes.`
- if (game.raised_stakes_discard === 0) {
- gen_action('pass')
- }
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- }
- },
- card(card) {
- push_undo()
- if (numberless_cards.includes(card)) {
- log(`Discarded: P${card}`)
- } else {
- log(`Discarded: P${card} V${power_cards[card].value}`)
- }
- discard(card)
-
- game.raised_stakes_discard ++
- if (game.raised_stakes_discard === 3) {
- game.raised_stakes++
- game.valid_cards = []
- }
- },
- pass(){
- log('Did not raise the stakes')
- game.raised_stakes_discard = 0
- next_player()
- if (game.active === DEM) {
- game.valid_cards = [...game.dem_pwr_hand]
- } else {
- game.valid_cards = [...game.com_pwr_hand]
- }
- game.state = 'raise_stakes_2'
- },
- done () {
- log_gap('Raised the stakes')
- game.raised_stakes_discard = 0
- next_player()
- //console.log('game.active', game.active)
- if (game.active === DEM) {
- game.valid_cards = [...game.dem_pwr_hand]
- } else {
- game.valid_cards = [...game.com_pwr_hand]
- }
- // console.log('game.valid_cards', game.valid_cards)
- game.state = 'raise_stakes_2'
- }
-}
-
-states.raise_stakes_2 = {
- inactive: 'raise the stakes.',
-
- prompt () {
- if ((game.active === DEM && game.dem_pwr_hand < 3) || (game.active === COM && game.com_pwr_hand < 3)) {
- view.prompt = 'Raise the stakes: you must pass.'
- gen_action('pass')
- return
- }
- if (game.raised_stakes_discard === 3) {
- view.prompt = 'Raise the stakes: done.'
- gen_action('done')
- } else {
- view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes.`
- if (game.raised_stakes_discard === 0) {
- gen_action('pass')
- }
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- }
- },
- card(card) {
- push_undo()
- if (numberless_cards.includes(card)) {
- log(`Discarded: P${card}`)
- } else {
- log(`Discarded: P${card} V${power_cards[card].value}`)
- }
- discard(card)
-
- game.raised_stakes_discard ++
- if (game.raised_stakes_discard === 3) {
- game.raised_stakes++
- game.valid_cards = []
- }
-
- },
- pass() {
- log('Did not raise the stakes')
- game.raised_stakes_discard = 0
- game.valid_cards = []
- log_h2('Play Cards')
- next_player()
- game.state = 'begin_power_struggle'
- },
- done () {
- log_gap('Raised the stakes')
- game.raised_stakes_discard = 0
- game.valid_cards = []
- log_h2('Play Cards')
- next_player()
- game.state = 'begin_power_struggle'
- },
-}
-
-states.begin_power_struggle = {
- inactive: 'begin power struggle.',
- prompt() {
- view.prompt = 'Begin power struggle.'
- gen_action('struggle')
- },
- struggle () {
- do_valid_cards()
- game.state = 'power_struggle'
- }
-}
-
-states.power_struggle = {
- inactive: 'play a card.',
- prompt () {
- console.log('game.vm_event', game.vm_event)
- if (game.phase === 0) {
- if (game.valid_cards.length > 0) {
- view.prompt = "Play a card."
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- } else if ( game.valid_cards.length === 0) {
- view.prompt = 'No valid cards. You must concede.'
- gen_action('concede')
- }
- }
- if (game.phase === 1) {
- if (game.valid_cards.length > 0) {
- view.prompt = `${power_cards[game.played_power_card].name} played. You must match or concede.`
- gen_action('concede')
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- } else if (game.valid_cards.length === 0) {
- view.prompt = `${power_cards[game.played_power_card].name} played. You must concede.`
- gen_action('concede')
- }
- }
- else if (game.phase === 2) {
- view.prompt = 'You matched. Roll a die.'
- gen_action('roll')
- }
- else if (game.phase === 3) {
- view.prompt = 'Play leader as:'
- if (game.tactics_fails !== "Strike") {gen_action('strike')}
- if (game.tactics_fails !== "March") {gen_action('march')}
- if (game.tactics_fails !== "Rally in the Square") {gen_action('rally')}
- if (game.tactics_fails !== "Petition") {gen_action('petition')}
- }
- },
- card(card) {
- push_undo()
- discard(card)
- game.valid_cards=[]
- game.return_state = 'power_struggle'
- if (card === 52) {
- log_gap(`Played P52: P${power_cards[game.played_power_card].number} no longer playable`)
-
- } else {
- if (game.phase === 0 && leader_cards.includes(card)) {} /* Log nothing. Probably a better way to do this */
- else if (numberless_cards.includes(card)) {
- log_gap(`Played: P${card}`)
- } else {
- log_gap(`Played: P${card} V${power_cards[card].value}`)
- }
- }
- if (game.phase === 0) {
- if (card >= 37 && card <= 48) { /*When a leader is played */
- game.played_power_card = card
- game.phase = 3
- } else if (card === 49){ /*Scare Tactics */
- game.return = ''
- goto_vm(349) /*Can I combine these 3 into a single stage where you goto_vm(300 + card) ? */
- } else if (card === 50) { /*Support Surges */
- if (game.active === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- goto_vm(350)
- } else if (game.phase === 0 && card === 51) { /*Support Falters */
- next_player()
- goto_vm(351)
- } else {
- game.played_power_card = card
- game.phase = 1
- next_player()
- do_valid_cards()
- }
- } else if (game.phase === 1) {
- if (card === 52) {
- game.tactics_fails = power_cards[game.played_power_card].name
- game.phase = 0
- next_player()
- do_valid_cards()
- } else if (power_cards[game.played_power_card].value === 1) {
- log('Takes initiative')
- game.phase = 0
- do_valid_cards()
- } else {
- game.phase = 2
- }
- }
- },
- roll () {
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Roll: D${roll}`)
- if (roll >= power_cards[game.played_power_card].value) {
- log('Initiative roll successful')
- game.phase = 0
- do_valid_cards()
- } else {
- log(`Initiative roll failed. Required ${power_cards[game.played_power_card].value} or more`)
- game.phase = 0
- next_player()
- do_valid_cards()
- }
- },
- concede () {
- push_undo()
- game.valid_cards = []
- log('Conceded')
- log_h2('Aftermath')
- log_h3('Support Loss')
- //if ((game.played_power_card >= 25 && game.played_power_card <= 30) || game.played_power_card === 53) {game.rally_win = 2}
- //if ((game.played_power_card >= 31 && game.played_power_card <= 36) || game.played_power_card === 54) {game.petition_win = 2}
- if (game.phase === 0) {
- game.played_power_card = 0 /*If conceded when held the initiative but had no playable cards, ignore the last played card */
- }
- game.phase = 0
- game.state = 'support_loss'
- },
- strike () {
- log(`Played: P${power_cards[game.played_power_card].number} as a Strike`)
- game.played_power_card = 9
- game.phase = 1
- next_player()
- do_valid_cards()
- },
- march () {
- log(`Played: P${power_cards[game.played_power_card].number} as a March`)
- game.played_power_card = 21
- game.phase = 1
- next_player()
- do_valid_cards()
- },
- rally () {
- log(`Played: P${power_cards[game.played_power_card].number} as a Rally in the Square`)
- game.played_power_card = 53
- game.phase = 1
- next_player()
- do_valid_cards()
- },
- petition () {
- log(`Played: P${power_cards[game.played_power_card].number} as a Petition`)
- game.played_power_card = 54
- game.phase = 1
- next_player()
- do_valid_cards()
- },
- /*draw () {
- if (game.active === DEM) {
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+2, game.com_pwr_hand.length)
- } else {draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+2)}
- game.phase = 0
- next_player()
- do_valid_cards()
- },*/
- /*infl(space) {
- game.remove_opponent_infl = true
- remove_infl(space)
- game.phase = 6
- },
- discard () { /*Is this still needed?
- if (game.active === DEM) {discard_card(game.dem_pwr_hand)}
- else {discard_card(game.com_pwr_hand)}
- game.available_ops --
- }, */
- done () {
- if (game.phase === 7) { /*Is this ever called anymore? */
- game.phase = 0
- log_msg_gap('Takes initiative')
- do_valid_cards()
- } else {
- game.phase = 0
- next_player()
- do_valid_cards()
- }
- }
-}
-
-states.support_loss ={
- inactive: 'do Support Loss.',
- prompt () {
- if (!game.persistent_events.includes(111)) {
- if (game.phase === 0) {
- view.prompt = 'You lost the Power Struggle. Roll a die for Support Loss.'
- gen_action('roll')
- } else if (game.phase === 1 && game.available_ops > 0 && game.valid_spaces.length > 0) {
- view.prompt = `Power Struggle - ${country_name(game.pwr_struggle_in)}. Support Loss: remove ${pluralize(game.available_ops,'SP')}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id)
- }
- } else if (game.phase === 1 && game.available_ops === 0 ) {
- view.prompt = `Power Struggle - ${country_name(game.pwr_struggle_in)}. Support Loss: finished.`
- gen_action('done')
- } else if (game.phase === 1 && game.valid_spaces.length === 0) {
- view.prompt = `Power Struggle - ${country_name(game.pwr_struggle_in)}. Support Loss: no remaining SPs to remove.`
- gen_action('done')
- }
- } else {
- if (game.phase === 0) {
- view.prompt = 'You lost the Power Struggle. Roll a die for Support Loss.'
- gen_action('roll')
- } else if (game.phase === 1 && game.available_ops > 0 && game.valid_spaces.length > 0) {
- view.prompt = `New Year's Eve Party - ${country_name(game.pwr_struggle_in)}. Support Loss: remove ${pluralize(game.available_ops,'SP')}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id)
- }
- } else if (game.phase === 1 && game.available_ops === 0 ) {
- view.prompt = `New Year's Eve Party - ${country_name(game.pwr_struggle_in)}. Support Loss: finished.`
- gen_action('done')
- } else if (game.phase === 1 && game.valid_spaces.length === 0) {
- view.prompt = `New Year's Eve Party - ${country_name(game.pwr_struggle_in)}. Support Loss: no remaining SPs to remove.`
- gen_action('done')
- }
- }
- },
- roll () {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- let rally_win = 0
- let petition_win = 0
- log(`Roll: D${roll}`)
- if ((game.played_power_card >= 25 && game.played_power_card <= 30) || game.played_power_card === 53) { rally_win = 2}
- if ((game.played_power_card >= 31 && game.played_power_card <= 36) || game.played_power_card === 54) { petition_win = 2}
- let modified_roll = roll + game.raised_stakes + rally_win - petition_win
-
- // Roll modifiers
- if (game.active === COM && game.persistent_events.includes(62)) {
- log('+1 from C62')
- modified_roll ++
- }
-
- if (modified_roll < 0) {modified_roll = 0}
- else if (modified_roll > 7) {modified_roll = 7}
-
-
- if (game.raised_stakes !== 0) {
- log(`+${game.raised_stakes} from Raising the Stakes`)
- }
- if (rally_win !== 0) {
- log('+2 from winning on a P25')
- }
- if (petition_win !== 0) {
- log('-2 from winning on a P31')
- }
- if (modified_roll !== roll) {
- log(`Modified roll: ${modified_roll}`)
- }
- game.available_ops = support_loss_roll[modified_roll]
- if (game.available_ops === 0) {
- log('Does not remove SPs')
- }
- game.phase++
- if (game.available_ops > 0) {
- valid_spaces_support_loss()
- }
- },
- infl (space) {
- game.remove_opponent_infl = false /* Don't know why this is needed... */
- remove_infl(space)
- if (game.available_ops === 0 ) {
- game.valid_spaces = []
- }
- },
- done () {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- next_player()
- log_h3('Victory Point')
- game.phase = 0
- game.state = 'vp_roll'
- }
-}
-
-states.vp_roll = {
- inactive: 'do VP Roll.',
- prompt () {
- if (!game.persistent_events.includes(111)) {
- if (game.phase === 0) {
- view.prompt = `Power Struggle - ${country_name(game.pwr_struggle_in)}: roll a die for Victory.`
- gen_action('roll')
- } else if (game.phase === 1) {
- view.prompt = `Power Struggle - ${country_name(game.pwr_struggle_in)}: take power.`
- gen_action('take')
- } else if (game.phase === 2) {
- view.prompt = `Power Struggle - ${country_name(game.pwr_struggle_in)}: proceed to scoring.`
- gen_action('scoring')
- }
- } else {
- if (game.phase === 0) {
- view.prompt = `New Year's Eve Party - ${country_name(game.pwr_struggle_in)}: roll a die for Victory.`
- gen_action('roll')
- } else if (game.phase === 1) {
- view.prompt = `New Year's Eve Party - ${country_name(game.pwr_struggle_in)}: take power.`
- gen_action('take')
- } else if (game.phase === 2) {
- view.prompt = `New Year's Eve Party - ${country_name(game.pwr_struggle_in)}: proceed to scoring.`
- gen_action('scoring')
- }
- }
- },
- roll () {
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Roll: D${roll}`)
- let rally_win = 0
- let petition_win = 0
- if ((game.played_power_card >= 25 && game.played_power_card <= 30) || game.played_power_card === 53) {rally_win = 2}
- if ((game.played_power_card >= 31 && game.played_power_card <= 36) || game.played_power_card === 54) {petition_win = 2}
- let modified_roll = roll + game.raised_stakes + rally_win - petition_win
- if (game.active === DEM && game.persistent_events.includes(62)) {
- log('+1 from C62')
- modified_roll ++
- }
- if (modified_roll < 0) {modified_roll = 0}
- else if (modified_roll > 7) {modified_roll = 7}
-
- if (game.raised_stakes !== 0) {
- log(`+${game.raised_stakes} from Raising the Stakes`)
- }
- if (rally_win !== 0) {
- log('+2 from winning on a P25')
- }
- if (petition_win !== 0) {
- log('-2 from winning on a P31')
- }
- if (modified_roll !== roll) {
- log(`Modified roll: ${modified_roll}`)
- }
- let vp_change = vp_roll[modified_roll]
- if (game.active === DEM) {
- log(`+${vp_change} VP`)
- } else {
- log(`-${vp_change} VP`)
- }
- if (roll >= 4)
- //console.log('VP before', game.vp)
- if (game.active === DEM) {game.vp += vp_change}
- else {game.vp -= vp_change}
- //console.log('VP after', game.vp)
- if (game.active === DEM && modified_roll >= 4) {
- game.phase = 1
- } else {
- game.phase = 0
- if (game.active === DEM) {next_player()}
- game.state = 'choose_power'
- }
- },
- take () {
- push_undo()
- //Find name of scoring card
- let scoring_card = scoring_cards[countries.indexOf(game.pwr_struggle_in)]
- permanently_remove(scoring_card)
- take_power(game.pwr_struggle_in)
- game.phase = 2
- },
- scoring () {
- push_undo()
- log_h2('Scoring')
- score_country(game.pwr_struggle_in)
-
- //Check if The Tyrant is Gone occurs
- if (game.table_cards.includes(97) && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(54)) {
- game.return_state = 'finish_scoring'
- if (game.active !== DEM) {
- next_player()
- }
- game.state = 'the_tyrant_is_gone'
- } else {
- game.state = 'finish_scoring'
- }
- },
-}
-
-states.choose_power = {
- inactive: 'choose whether to remain in power.',
- prompt () {
- if (game.phase === 0) {
- view.prompt = 'Choose whether to remain in power.'
- gen_action('retain')
- gen_action('surrender')
- } else if (game.phase === 1) {
- view.prompt = 'Proceed to scoring.'
- gen_action('scoring')
- }
- },
- retain() {
- push_undo()
- retain_power(game.pwr_struggle_in)
- game.phase = 1
- },
- surrender () {
- push_undo()
- take_power(game.pwr_struggle_in)
- permanently_remove(game.played_card)
- game.phase = 1
- },
- scoring () {
- push_undo()
- score_country(game.pwr_struggle_in)
-
- //Check if The Tyrant is Gone occurs
- if (game.table_cards.includes(97) && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(54)) {
- game.return_state = 'finish_scoring'
- if (game.active !== DEM) {
- next_player()
- }
- game.state = 'the_tyrant_is_gone'
- } else {
- game.state = 'finish_scoring'
- }
- }
-}
-/*
-states.score_country = {
- inactive: `score country`,
- prompt () {
- view.prompt = 'Scoring: done.'
- gen_action('done')
- },
- done () {
- reset_power()
- /*if (game.return !== game.active) {
- next_player()}
- game.state = 'finish_scoring'
- }
-}
-*/
-
-states.the_tyrant_is_gone ={
- inactive: 'resolve The Tyrant is Gone.',
- prompt() {
- view.prompt = 'Play The Tyrant is Gone for the event.'
- gen_action('event')
- },
- event() {
- if (game.active !== DEM) {
- next_player()
- }
- if (game.round_player === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- log_h3(`C97`)
- game.vm_event = 97
- goto_vm(game.vm_event)
- }
-}
-
-states.finish_scoring ={
- inactive: 'finish scoring.',
- prompt() {
- view.prompt = 'End power struggle.'
- gen_action('done')
- } ,
- done() {
- //console.log('game.return_state', game.return_state)
- log_msg_gap('Power Struggle resolved') /*At this point log card dicarded or permanently removed? */
- if (game.persistent_events.includes(111)) {
- game.state = 'new_years_eve_party'
- return
- }
- if (check_vp()) {
- return
- }
- reset_power()
- end_round()
- //game.state = 'end_round'
- }
-}
-
-// ======================================= END TURN STATES ==========================================
-
-states.end_turn_4_5_4 = {
- inactive: 'verify held cards.',
- prompt() {
- view.prompt = 'End Turn: verify held cards.'
- gen_action('check')
- },
- check() {
- log_h2('Verify held cards')
- const dem_has_scoring_card = game.democrat_hand.some(card => scoring_cards.includes(card))
- const com_has_scoring_card = game.communist_hand.some(card => scoring_cards.includes(card))
- if (!dem_has_scoring_card && !com_has_scoring_card) {
- log('No held scoring cards')
- }
-
- if (dem_has_scoring_card && com_has_scoring_card) {
- log('Both players have held scoring cards')
- game.state = 'game_end_tie'
- }
- else if (dem_has_scoring_card) {
- log('Democrat player has a held scoring card')
- goto_game_over(COM, `${COM} won by held scoring card!`)
- }
- else if (com_has_scoring_card) {
- log('Communist player has a held scoring card')
- goto_game_over(DEM, `${DEM} won by held scoring card!`)
- }
- else if (game.persistent_events.includes(104)) {
- log_h1(`New Year's Eve Party`)
- game.vm_event = 104
- //Check if the Communist receives VP from The Tyrant is Gone
- if (game.persistent_events.includes(97)) {
- game.vp -= 2
- log(`Communist receives 2 VP from C97`)
- }
- game.persistent_events.push(111)
- if (game.active !== DEM) {
- next_player()
- }
- game.state = 'new_years_eve_party'
- }
- else if(game.turn === 10) {
- clear_undo()
- log_h2('Final Scoring')
-
- //Check if the Communist receives VP from The Tyrant is Gone
- if (game.persistent_events.includes(97)) {
- game.vp -= 2
- log(`Communist receives 2 VP from C97`)
- }
- game.state = 'final_scoring_held'
-
- } else {
- game.return_state = ''
- game.state = 'end_turn'
- }
- }
-}
-
-states.end_turn = {
- inactive: 'end the turn.',
- prompt() {
- view.prompt = 'End Turn: done.'
- gen_action('done')
- },
- done() {
- new_turn()
- }
-}
-
-states.final_scoring_held = {
- inactive: 'resolve final scoring.',
- prompt() {
- view.prompt = 'Final Scoring: Communist scores VP bonus for the number of countries they retain power.'
- gen_action('bonus')
- },
- bonus() {
- // console.log('game.revolutions: ', game.revolutions)
- const held_countries = game.revolutions.filter(value => value === false).length
- let vp_gain = 4*held_countries
- log(`Communist holds ${held_countries} countries: -${vp_gain} VP`)
- game.vp -= 4*held_countries
- game.temp = {'East_Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false}
- game.state = 'final_scoring'
- }
-}
-
-states.final_scoring = {
- inactive: 'score countries.',
- prompt() {
- if (game.temp['East_Germany'] && game.temp['Poland'] && game.temp['Czechoslovakia'] && game.temp['Hungary'] && game.temp['Romania'] && game.temp['Bulgaria']) {
- view.prompt = 'Final scoring: done.'
- gen_action('end')
- } else {
- view.prompt = 'Choose a country to score:'
- if (!game.temp['East_Germany']) {gen_action('east_germany')}
- if (!game.temp['Poland']) {gen_action('poland')}
- if (!game.temp['Czechoslovakia']) {gen_action('czechoslovakia')}
- if (!game.temp['Hungary']) {gen_action('hungary')}
- if (!game.temp['Romania']) {gen_action('romania')}
- if (!game.temp['Bulgaria']) {gen_action('bulgaria')}
- }
- },
- east_germany() {
- score_country('East_Germany')
- game.temp['East_Germany'] = true
- },
- poland() {
- score_country('Poland')
- game.temp['Poland'] = true
- },
- czechoslovakia() {
- score_country('Czechoslovakia')
- game.temp['Czechoslovakia'] = true
- },
- hungary() {
- score_country('Hungary')
- game.temp['Hungary'] = true
- },
- romania() {
- score_country('Romania')
- game.temp['Romania'] = true
- },
- bulgaria() {
- score_country('Bulgaria')
- game.temp['Bulgaria'] = true
- },
- end() {
- delete game.temp
- if (game.vp > 0) {
- goto_game_over(DEM, `${DEM} wins on Victory Point Track!`)
- } else if (game.vp < 0) {
- goto_game_over(COM, `${COM} wins on Victory Point Track!`)
- } else if (game.vp === 0) {
- goto_game_over('', `The game is tied!`) /*Not sure what to pass for result */
- }
- }
-}
-
-states.game_over = {
- get inactive() {
- return game.victory
- },
- prompt() {
- view.prompt = game.victory
- },
-}
-
-// ========================== EVENT SPECIFIC STATES =================================
-
-states.general_strike = {
- inactive: 'discard a card.',
- prompt() {
- if (game.played_card === 0 ) {
- view.prompt = 'General Strike: you must discard a card or play a Scoring Card.'
- available_cards = game.communist_hand
- for (let card of available_cards) {
- gen_action_card(card)
- }
- } /*else if (game.phase >= 1) {
- view.prompt = 'General Strike: done.'
- gen_action('done')
- } */ else if (game.played_card > 0 ) {
- view.prompt = 'General Strike: roll a die.'
- gen_action('roll')
- }
- },
- card (card) {
- push_undo()
- game.played_card = card
- let find_card
- find_card = game.communist_hand.indexOf(card)
- game.communist_hand.splice(find_card, 1)
- game.available_ops = get_card_ops(card)
- if (scoring_cards.includes(card)) {
- game.vm_event = card
- log(`Played C${card} for the event`)
- game.return_state = 'general_strike'
- goto_vm(game.vm_event)
- } else {
- log(`Discarded C${cards[card].number}`)
- }
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Roll: D${roll}`)
-
- logi(`+${game.available_ops} ops`)
-
- let total = roll + game.available_ops
- log(`Total: ${total}`)
-
- if (total > 5) {
- log('The strike is over.')
- permanently_remove(5)
- game.persistent_events = game.persistent_events.filter(n => n !== 5)
- } else {
- log('The strike continues. Required 6 or more')
- }
- //game.phase = 1
- game.state = 'end_round'
- }, /*
- done () {
- //end_round()
- game.state = 'end_round'
- }*/
-}
-
-states.honecker ={
- inactive: 'resolve Honecker.',
- prompt() {
- view.prompt = 'Honecker: you may take an extra action round.'
- gen_action('extra')
- gen_action('pass')
- },
- extra() {
- push_undo()
- game.round++
- game.round_player = COM
- game.persistent_events = game.persistent_events.filter(n => n !== 15)
- game.state = 'choose_card'
- },
- pass() {
- log('C15: passed')
- game.persistent_events = game.persistent_events.filter(n => n !== 15)
- //end_round()
- game.state = 'end_round'
- }
-}
-
-states.new_years_eve_party = {
- get inactive() {
- return `resolve ${clean_name(cards[104].name)}.`
- },
- prompt() {
- if (!game.is_pwr_struggle) {
- view.prompt = `New Year's Eve Party: you may choose a country to have a final power struggle.`
- if (!game.revolutions[0]) {gen_action('poland')}
- if (!game.revolutions[1]) {gen_action('hungary')}
- if (!game.revolutions[2]) {gen_action('east_germany')}
- if (!game.revolutions[3]) {gen_action('bulgaria')}
- if (!game.revolutions[4]) {gen_action('czechoslovakia')}
- if (!game.revolutions[5]) {gen_action('romania')}
- gen_action('pass')
- } else {
- view.prompt = `New Year's Eve Party: done.`
- gen_action('end')
- }
- },
- east_germany() {
- push_undo()
- log('Chose to score East Germany')
- game.vm_event = 42
- goto_vm(42)
- },
- poland() {
- push_undo()
- log('Chose to score Poland')
- game.vm_event = 22
- goto_vm(22)
- },
- czechoslovakia() {
- push_undo()
- log('Chose to score Czechoslovakia')
- game.vm_event = 55
- goto_vm(55)
- },
- hungary() {
- push_undo()
- log('Chose to score Hungary')
- game.vm_event = 23
- goto_vm(23)
- },
- romania() {
- push_undo()
- log('Chose to score Romania')
- game.vm_event = 95
- goto_vm(95)
- },
- bulgaria () {
- push_undo()
- log('Chose to score Bulgaria')
- game.vm_event = 43
- goto_vm(43)
- },
- pass() {
- push_undo()
- log('No final power struggle')
- if (game.vp > 0) {
- goto_game_over(DEM, `New Year's Eve Party: ${DEM} wins on Victory Point Track!`)
- } else if (game.vp < 0) {
- goto_game_over(COM, `New Year's Eve Party: ${COM} wins on Victory Point Track!`)
- } else if (game.vp === 0) {
- goto_game_over('', `New Year's Eve Party: The game is tied!`) /*Not sure what to pass for result */
- }
- },
- end() {
- if (game.vp > 0) {
- goto_game_over(DEM, `New Year's Eve Party: ${DEM} wins on Victory Point Track!`)
- } else if (game.vp < 0) {
- goto_game_over(COM, `New Year's Eve Party: ${COM} wins on Victory Point Track!`)
- } else if (game.vp === 0) {
- goto_game_over('', `CNew 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() {
- //console.log('game.stasi_card', game.stasi_card)
- let available_cards = game.democrat_hand
- if (available_cards.length === 0) {
- view.prompt = 'Stasi: no cards remaining.'
- gen_action('pass')
- return
- }
- view.prompt = 'Stasi: you must select your next card to play.'
-
- for (let card of available_cards) {
- gen_action_card(card)
- }
- },
- card(card) {
- push_undo()
- log_gap(`Democrat selected C${cards[card].number} as next card.`)
- game.stasi_card = card
- game.state = 'stasi_finish'
- },
- pass() {
- log('Stasi: Democrat has no remaining cards')
- game.stasi_card = 0
- end_stasi_choose_card()
- },
- end_round() {
- push_undo()
- if (game.stasi_card === 21) {
- game.state = 'stasi_confirm'
- } else {
- end_stasi_choose_card()
- }
- }
-}
-
-states.stasi_finish = {
- inactive: 'choose next card due to Stasi.',
- prompt() {
- view.prompt = 'Stasi. Choose card: done.'
- gen_action('done')
- },
- done() {
- push_undo()
- if (game.stasi_card === 21) {
- game.state = 'stasi_confirm'
- } else {
- end_stasi_choose_card()
- }
- }
-}
-
-states.stasi_confirm = {
- inactive: 'choose next card due to Stasi.',
- prompt() {
- if (game.stasi_card === 21 ) {
- view.prompt = `If Common European Home selected, it must be played for Operations. Otherwise select the opponent's card instead.`
- gen_action('done')
- }
- },
- done() {
- game.playable_cards = game.playable_cards.filter( n => n !== 21)
- end_stasi_choose_card()
- }
-}
-
-states.stasi_play_card = {
- inactive: 'play a card.',
- prompt () { /*Should get rid of the play card 'done' prompt for consistency with general play */
- /*if (game.played_card > 0) {
- game.state = 'play_card'
- view.prompt = 'Play card: done.'
- gen_action("done");
- return;*/
- //} else
- if (game.democrat_hand.length === 0) {
- view.prompt = 'Stasi: you must pass.'
- gen_action('pass')
- } else {
- view.prompt = `Stasi: you must play ${clean_name(cards[game.stasi_card].name)}.`
- 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${card}`)
- game.played_card = card
- let find_card
- find_card = game.democrat_hand.indexOf(card);
- game.democrat_hand.splice(find_card, 1);
- game.available_ops = get_card_ops(card)
-
- if (game.democrat_hand.includes(21) && cards[card].side === "C") {
- game.state = 'stasi_resolve_common_european_home'
- } else {
- game.state = 'play_card'
- }
-
- },
- pass () {
- log('No cards remaining. Passed')
- //end_round()
- game.state = 'end_round'
- },
- done () {
- //game.stasi_card = 0
- if (game.democrat_hand.includes(21)) {
- game.state = 'stasi_resolve_common_european_home'
- } else {
- game.state = 'play_card'
- }
- }
-}
-
-states.stasi_resolve_common_european_home = {
- inactive: 'play a card.',
- prompt () {
- view.prompt = `Do you wish to play ${clean_name(cards[game.played_card].name)} with Common European Home?`
- gen_action('yes')
- gen_action('no')
- },
- yes() {
- log(`Played with Common European Home`)
- silent_discard(21)
- game.vm_infl_to_do = true
- game.vm_event_to_do = false
- game.state = 'resolve_opponent_event'
- },
- no() {
- game.state = 'play_card'
- }
-}
-
-
-// ==================== SUPPORTING STATE FUNCTIONS =============================
-
-
-function add_infl(space) {
- push_undo()
- //console.log('adding infl to', space)
- //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 %${space}`)
- log_summary(`Added £ SP in %${space}`)
-
- //If AHBR - check AHBR conditions
- if (game.persistent_events.includes(58)) {
- if (spaces[space].country !== 'East_Germany'){
- game.austria_hungary_border_reopened_tracker = false
- }
- }
-
- // Check Genscher
- if (game.persistent_events.includes(63) && game.active === DEM && spaces[space].country === 'East_Germany' && check_com_control(space)) {
- game.available_ops--
- log_summary(`(-1 op due to C63)`)
- } else if (check_opp_control(space)) {
- game.available_ops -= 2
- //Check if Austria Hungary Border Reopened was used to place last SP in a controlled space in East Germany. If so, game.available_op will be negative
- if (game.available_ops < 0) {
- log_summary(`(Used +1 op from C58)`)
- }
- } else {
- game.available_ops--
- }
-
- // Update influence values
- if (game.active === COM) {
- game.comInfl[space]++
- } else {
- game.demInfl[space]++
- }
-
- // Check whether spaces are controlled
- check_control_change(space)
-
- // Check Austria Hungary Border Reopened is true and condition has been met
- if (game.available_ops === 0 && game.active === DEM && game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker) {
- game.available_ops ++
- log('+1 op from C58')
- game.austria_hungary_border_reopened_tracker = false
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
- }
-
- // If only 1 IP remaining, may not place in opponent controlled spaces
-
- // Check for Genscher & Austria Hungary Border Reopened
-
- if (game.available_ops === 1) {
- //console.log(`in Genscher / AHBR check, game.persistent_events['genscher']`, game.persistent_events['genscher'])
- if (game.active === DEM) {
- if (game.persistent_events.includes(63) || (game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker)) {
- //console.log('in gensher subcheck - remove non-East German controlled ')
- game.valid_spaces = game.valid_spaces.filter(n => !(check_opp_control(n) && spaces[n].country !== 'East_Germany'))
- } else {
- //console.log('remove all controlled spaces')
- game.valid_spaces = game.valid_spaces.filter(n => !check_opp_control(n))
- }
- } else {
- //console.log('remove all dem controlled spaces')
- game.valid_spaces = game.valid_spaces.filter(n => !check_opp_control(n))
- }
- }
-
- //Clear valid spaces if no IP remaining.
- if (game.available_ops <= 0 ) {
- game.valid_spaces = []
- }
-}
-
-function remove_infl(space) {
- push_undo()
- //log(`Removed 1 influence from %${space}.`)
- log_summary(`Removed £ SP from %${space}.`)
-
- if (game.remove_opponent_infl === true) {
- if (game.active === COM) {
- game.demInfl[space]--
- if (game.demInfl[space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space);
- }
- } else {
- game.comInfl[space]--
- if (game.comInfl[space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space);
- }
- }
- check_control_change(space)
-
- } else {
- if (game.active === COM) {
- game.comInfl[space]--
- if (game.comInfl[space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space);
- }
- } else {
- game.demInfl[space]--
- if (game.demInfl[space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space);
- }
- }
- check_control_change(space)
- }
- game.available_ops--
-}
-
-function do_sc(space) {
- clear_undo()
- log_gap(`Support check: %${space}`)
-
- //Check Helsinki Final Act
-
- if (game.active === COM && game.persistent_events.includes(26) && (spaces[space].socio === 5 || spaces[space].socio === 6) ) {
- log('+1 VP from C26')
- game.vp ++
- if (check_vp()) {
- game.state = 'game.over'
- //console.log('after check_vp, game.state', game.state)
- return
- }
- }
-
- // Continue with Support Check Logic
-
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Roll: D${roll}`)
-
- /*
- //Check if support check is being done with game.played_card or a subsequent card (e.g. Common European Home, Dash for the West, etc)
- if (game.vm_event > 0) {
- roll+= cards[game.vm_event].ops
- log(`+${cards[game.vm_event].ops} from card ops`)
- }
- */
- // Check for the Crowd Turns Against Ceausescu
-
- //else
- if (game.is_pwr_struggle) {
- roll += game.vm_available_ops
- logi(`+${game.vm_available_ops} from Ceausescu`)
- }
-
- // Check if in Tiananmen Square Track Award
-
- else if (game.state === 'vm_tst_6_sc') {
- roll += get_tst_6_ops()
- roll += 2
- logi('+2 TST award')
- }
- else {
- //let modifier = 0
- let card_ops = get_card_ops(this_card())
-
- roll += card_ops
- logi(`+${card_ops} from card ops`)
- }
-
- if (game.support_check_modifier > 0) {
- roll += game.support_check_modifier
- logi(`+${game.support_check_modifier} from event`)
- }
-
- // Events which modify SC rolls
- //Tear Gas
- if (game.active === COM && game.persistent_events.includes(30) && spaces[space].socio === 6) {
- roll ++
- logi('+1 from C30')
- permanently_remove(30)
- game.persistent_events = game.persistent_events.filter(n => n !== 30)
- }
- //FRG Embassies
- if (game.active === DEM && spaces[space].region === 'Eastern Europe' && game.persistent_events.includes(74)) {
- roll++
- logi('+1 from C74')
- }
- //GrenzTruppen
- if (game.active === DEM && spaces[space].country === 'East_Germany' && game.persistent_events.includes(59)) {
- roll--
- logi('-1 from C59')
- }
- //Stand Fast
- if ((game.active === COM && game.stand_fast === DEM && check_dem_control(space)) || (game.active === DEM && game.stand_fast === COM && check_com_control(space))){
- roll--
- logi('-1 from C100')
- }
- //Elena
- if (game.active === DEM && game.persistent_events.includes(101) && spaces[space].country === 'Romania') {
- roll--
- logi('-1 from C101')
- }
- //Austria Hungary Border Reopened
- if (game.active === DEM && game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker) {
- roll++
- logi(`+1 from C58`)
- }
-
- // Continue with logic - check for adjacency
-
- // Events which affect adjacency - The Wall
-
- const adj = count_adj(space)
- //console.log('adj', adj)
- if (game.active === COM && game.persistent_events.includes(9) && spaces[space].country === 'East_Germany') {
- logi('No adjacency for Democrats due to C9')
- logi('C9 no longer in effect')
- roll += adj.com_adj
- if (adj.com_adj > 0) {
- logi(`+${adj.com_adj} adjacency`)
- }
- game.persistent_events = game.persistent_events.filter(n => n !== 9)
-
- // Standard adjacency
- } else {
- if (adj.dem_adj > 0 || adj.com_adj > 0 ){
- if (game.active === DEM) {
- roll += adj.dem_adj
- roll -= adj.com_adj
- if (adj.dem_adj > 0) {
- logi(`+${adj.dem_adj} from adjacency`)
- }
- if (adj.com_adj > 0) {
- logi(`-${adj.com_adj} from opponent adjacency`)
- }
- } else {
- roll += adj.com_adj
- roll -= adj.dem_adj
- if (adj.com_adj > 0) {
- logi(`+${adj.com_adj} from adjacency`)
- }
- if (adj.dem_adj > 0) {
- logi(`-${adj.dem_adj} from opponent adjacency`)
- }
- }
- }
-
- }
-
- // Support check calcs
- log(`Modified total: ${roll}`)
- const stability = spaces[space].stability
- logi(`-${stability*2} (stability * 2)`)
- const change_infl = Math.max(0, roll - stability*2)
- if (change_infl > 0) {
- log_msg_gap(`Change influence: ${change_infl} SP`)
- if(game.active === DEM) {
- if (change_infl > game.comInfl[space]) {
- const residual = change_infl - game.comInfl[space]
- game.comInfl[space] = 0
- game.demInfl[space] += residual
- } else {
- game.comInfl[space] -= change_infl
- }
- if (game.comInfl[space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space)
- }
- } else {
- if (change_infl > game.demInfl[space]) {
- const residual = change_infl - game.demInfl[space]
- game.demInfl[space] = 0
- game.comInfl[space] += residual
- } else {
- game.demInfl[space] -= change_infl
- }
- if (game.demInfl[space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space)
- }
- }
- check_control_change(space)
-
- } else {
- log_msg_gap('Change influence: 0 SP')
- }
- if (game.active === COM && game.persistent_events.includes(39) && spaces[space].space_id === 66) {
- log_msg_gap('+1 VP from C39')
- game.vp++
- if (check_vp()) {
- return
- }
- }
-
- // If Austria-Hungary Border Reopened used, all future support checks must be in East Germany
- if (game.persistent_events.includes(58)){
- if (game.austria_hungary_border_reopened_tracker) {
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
- }
- }
- game.selected_space = 0
-
-}
-
-function valid_spaces_setup() {
- game.valid_spaces = []
- let valid_spaces_set = new Set();
- //console.log('in vs setup, state', game.state)
- for (let i =1 ; i <= 75 ; i++) {
- space = spaces[i]
-
- if (game.state === 'com_init') {
- infl = game.demInfl[i]
-
- if (infl === 0) {
- valid_spaces_set.add(space.space_id);
- }
- } else if (game.state === 'dem_init') {
- infl = game.comInfl[i]
- if (infl === 0) {
- valid_spaces_set.add(space.space_id);
- }
- }
- }
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
-}
-
-function valid_spaces_sc() {
- let valid_spaces_set = new Set();
- //console.log('valid spaces sc, persistent events', game.persistent_events)
-
- for (let i = 1 ; i <= 75; i++) {
- space = spaces[i]
-
- if (game.active === DEM) {
- infl = game.comInfl[i]
- if (infl !== 0 ) {
- valid_spaces_set.add(space.space_id);
- }
- } else {
- infl = game.demInfl[i]
- if (infl !== 0 ) {
- // Check Solidarity Legalised
- if (game.persistent_events.includes(2) && space.space_id === 14) {continue}
-
- // Check Civic Forum
- if (game.persistent_events.includes(90) && space.space_id === 30) {continue}
-
- // Check We Are the People
- if (game.persistent_events.includes(48) && space.space_id === 9) {continue}
-
- //Check for Foreign Currency Debt Burden
- if (game.persistent_events.includes(49) && space.country === game.foreign_currency_debt_burden) {continue} {
-
- valid_spaces_set.add(space.space_id);
-
- }
- }
- }
- }
-
-
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
-
- //Check for the Crown Turns Against Ceausescu
- if (game.is_pwr_struggle && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(54)) {
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'Romania')
- }
- return game.valid_spaces;
-}
-
-function valid_spaces_support_loss() {
- let valid_spaces_set = new Set();
- for (let i = 1; i < game.demInfl.length; i++) {
- //console.log('spaces.length', game.demInfl.length, 'i', i)
- space = spaces[i]
- if (game.active === DEM) {
- infl = game.demInfl[i]
- if (infl > 0 && space.country === game.pwr_struggle_in) {
- valid_spaces_set.add(space.space_id);
- }
- } else {
- infl = game.comInfl[i]
- if (infl > 0 && space.country === game.pwr_struggle_in) {
- valid_spaces_set.add(space.space_id);
- }
- }
- }
-
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
-}
-/*
-function valid_spaces_support_falters() {
- let valid_spaces_set = new Set();
- if (game.active === DEM) {
- for (let piece of game.pieces) {
- if (!piece) continue
- let space = spaces.find(s => s && s.space_id === piece.space_id);
- if (space && piece.comInfl > 0 && space.country === game.pwr_struggle_in) {
- valid_spaces_set.add(space.space_id);
- }
- }
- } else {
- for (let piece of game.pieces) {
- if (!piece) continue
- let space = spaces.find(s => s && s.space_id === piece.space_id);
- if (space && piece.demInfl > 0 && space.country === game.pwr_struggle_in) {
- valid_spaces_set.add(space.space_id);
- }
- }
- }
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
-}
- */
-
-function valid_spaces_infl() {
- /*if (game.state.startsWith('vm')) {
- console.log('valid_spaces_infl called from VM')
- } else {
- console.log('valid_spaces_infl called not from VM')
- }*/
- // Check if function is called from the VM or not, take relevant ops variable
- let ops = game.state.startsWith('vm') ? game.vm_available_ops : game.available_ops;
-
- let valid_spaces_set = new Set();
- // Iterate over all spaces to find the ones with the player's influence
- for (let i = 1; i < game.demInfl.length; i++) {
- //piece = game.pieces[i]
- space = spaces[i]
-
- let player_influence = game.active === COM ? game.comInfl[i] : game.demInfl[i];
-
- // If the piece has the player's influence, add it and its adjacent spaces to the set
- if (player_influence > 0) {
- valid_spaces_set.add(space.space_id);
-
- // Check adjacency information
- let adjacent_spaces = get_adjusted_adjacency(space.space_id)
-
- for (let adj_space_id of adjacent_spaces) {
- //console.log('adj_space_id', adj_space_id)
- if (adj_space_id) {
-
- const adj_piece = spaces[adj_space_id];
- //console.log('adjacent piece name', adj_piece.name_unique)
-
- // Check if the adjacent space is controlled by the opponent
- const opponent_control = check_opp_control(adj_piece.space_id)
- //console.log('controlled?', opponent_control)
-
- //Check for Genscher. Can always place in East Germany even with 1 op
- if (game.active === DEM && adj_piece.country === 'East_Germany' && game.persistent_events.includes(63)){
- // console.log('space added with genscher')
- valid_spaces_set.add(adj_piece.space_id)
- }
-
- // Otherwise, only add the adjacent space if the available_ops >= 2 or the space is not controlled by the opponent
- if (ops >= 2 || !opponent_control) {
- valid_spaces_set.add(adj_piece.space_id)
- }
- }
- }
- }
- }
- // Convert the set to an array before returning
- game.valid_spaces = Array.from(valid_spaces_set);
- return game.valid_spaces;
-}
-
-function valid_cards(player_hand, presence) {
- const valid_cards_set= new Set();
- if (game.phase === 0) {
- for (let c of player_hand) {
- let card = power_cards.find(card => card && card.number === c);
- if (card.number === 52) {continue} // Never add tactics fails
- if (card.name === game.tactics_fails) {continue} //Cannot play the suit of Tactics Fails
- if (card.socio === 0) {
- valid_cards_set.add(card.number);
- } else if (leaders.includes(card.socio) && presence[card.socio]) {
- valid_cards_set.add(card.number);
- }
- }
- } else if (game.phase === 1) {
- for (let c of player_hand) {
- let card = power_cards.find(card => card && card.number === c);
- if (card.name === power_cards[game.played_power_card].name) {
- valid_cards_set.add(card.number);
- } else if (leaders.includes(card.socio) && presence[card.socio]) {
- valid_cards_set.add(card.number);
- } else if (card.number === 52) {valid_cards_set.add(card.number)}
- }
- }
- game.valid_cards = Array.from(valid_cards_set);
- return game.valid_cards;
-}
-
-function do_valid_cards() {
- let presence = check_presence(game.pwr_struggle_in)
- if (game.active === DEM) {
- valid_cards(game.dem_pwr_hand, presence.dem_leaders)
-
- } else {
- valid_cards(game.com_pwr_hand, presence.com_leaders)}
-}
-
-function count_adj(id) {
- const space = spaces[id]
- let dem_adj = 0
- let com_adj = 0
-
- let adjacent_spaces = get_adjusted_adjacency(space.space_id)
-
- for (let adj_space_id of adjacent_spaces) {
- if (adj_space_id) {
- const adj_piece = spaces.find(piece => piece && piece.space_id === adj_space_id);
- //console.log('adj_piece.space_id', adj_piece.space_id, 'space', space)
- if (adj_piece && adj_piece.space_id !== space.space_id) {
- if (check_dem_control(adj_piece.space_id)) {
- //console.log('added DEM space', spaces[adj_piece.space_id].name)
- dem_adj++
- }
- if (check_com_control(adj_piece.space_id)) {
- //console.log('added COM space', spaces[adj_piece.space_id].name)
- com_adj++
- }
- }
- }
- }
- //console.log('dem_adj: ', dem_adj, 'com_adj: ', com_adj)
- return {dem_adj, com_adj}
-}
-
-/*function count_adj_worker(space_id) {
- const space = spaces[space_id]
- let dem_adj = 0
- let com_adj = 0
-
- for (let adj_space_id of space.adjacent) {
- if (adj_space_id) {
- const adj_space = spaces[adj_space_id]
- if (adj_space && adj_space.socio === 4) {
- const adj_piece = game.pieces.find(piece => piece && piece.space_id === adj_space_id );
- if (adj_piece) {
- if (adj_piece.demCtrl === 1 ) {
- dem_adj++
- }
- if (adj_piece.comCtrl === 1 ) {
- com_adj++
- }
- }
- }
- }
- }
- return {dem_adj, com_adj}
-} */
-
-function check_control(space_id) {
- //console.log('in check control, space', spaces[space_id].name_unique)
- if ( (game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) {
- return true;
- } else if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) {
- //console.log('true')
- return true;
- } else {
- //console.log('false')
- return false;
- }
-}
-
-function check_opp_control(space_id) {
- if (spaces[space_id].country === 'Romania') {
- //console.log('in check opp control, space', spaces[space_id].name_unique)
- }
- if (game.active === DEM && ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability)) {
- if (spaces[space_id].country === 'Romania') {
- //console.log('control true')
- }
- return true;
- } else if (game.active === COM && ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability)) {
- //console.log('true')
- return true;
- } else {
- //console.log('false')
- return false;
- }
-}
-
-function check_dem_control(space_id) {
- if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) {
- return true;
- } else {
- return false;
- }
-}
-
-function check_com_control(space_id) {
- if ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) {
- return true;
- } else {
- return false;
- }
-}
-
-function do_tst_attempt() {
- let roll = Math.floor(Math.random() * 6) + 1;
- log(`Roll: D${roll}`);
-
- roll += game.available_ops
- logi(`+${game.available_ops} from card ops`)
-
- // TIANANMEN SQUARE MODIFIERS
-
- if (game.active === DEM && game.dem_tst_attempted === 1 || game.active === COM && game.com_tst_attempted === 1) {
- roll ++;
- logi('+1 from previous TST attempts')
- }
- if (game.active === DEM && game.dem_tst_position >= 1 && game.com_tst_position === 0) {
- roll ++
- logi('+1 from TST award')
- }
- if (game.active === COM && game.com_tst_position >= 1 && game.dem_tst_position === 0) {
- roll ++
- logi('+1 from TST award')
- }
- if ((game.active === DEM && cards[game.played_card].side === 'D') || (game.active === COM && cards[game.played_card].side === 'C')) {
- roll ++;
- logi('+1 for playing own card');
- }
- if (game.active === COM && game.persistent_events.includes(53)) {
- roll ++
- logi('+1 from C53')
- }
- log(`Modified total: ${roll}`)
-
- // TIANANMEN SQUARE ATTEMPT
- game.return = game.active
- game.return_state = 'tiananmen_square_attempt_done'
- if (game.active === DEM) {
- game.dem_tst_attempted_this_turn = 1
- if (roll >= dem_tst_req[game.dem_tst_position]) {
- log(`${dem_tst_req[game.dem_tst_position]} required: success`)
- game.dem_tst_position++
- game.dem_tst_attempted = 0
-
- //Check if they have reached box 7 or 8 first
- if (game.dem_tst_position === 7 && game.com_tst_position < 7) {
- game.tst_7 = false
- }
- if (game.dem_tst_position === 8 && game.com_tst_position < 8) {
- game.tst_8 = false
- }
-
- //Check if they have caught up to box 7 or 8
- if (game.dem_tst_position >= 7 && game.com_tst_position >= 7) {
- delete game.tst_7
- }
- if (game.dem_tst_position >= 8 && game.com_tst_position >= 8) {
- delete game.tst_8
- }
-
- //Check if TST events occur
- if (game.dem_tst_position === 3 && game.com_tst_position < 3) {game.vm_event = 203}
- else if (game.dem_tst_position === 4 && game.com_tst_position < 4) {game.vm_event = 204}
- game.state = 'tiananmen_square_attempt_success'
- } else {
- log(`${dem_tst_req[game.dem_tst_position]} required: fail`)
- game.dem_tst_attempted = 1
- game.state = 'tiananmen_square_attempt_fail'
- }
- } else {
- game.com_tst_attempted_this_turn = 1
- if (roll >= com_tst_req[game.com_tst_position]) {
- log(`${com_tst_req[game.com_tst_position]} required: success`)
- game.com_tst_position++
- game.com_tst_attempted = 0
-
- //Check if they have reached box 7 or 8 first
- if (game.com_tst_position === 7 && game.dem_tst_position < 7) {
- game.tst_7 = false
- }
- if (game.com_tst_position === 8 && game.dem_tst_position < 8) {
- game.tst_8 = false
- }
-
- //Check if they have caught up to box 7 or 8
- if (game.com_tst_position >= 7 && game.dem_tst_position >= 7) {
- delete game.tst_7
- }
- if (game.com_tst_position >= 8 && game.dem_tst_position >= 8) {
- delete game.tst_8
- }
-
- //Check if TST events occur
- if (game.com_tst_position === 3 && game.dem_tst_position < 3) {game.vm_event = 203}
- else if (game.com_tst_position === 4 && game.dem_tst_position < 4) {game.vm_event = 204}
- game.state = 'tiananmen_square_attempt_success'
- } else {
- log(`${com_tst_req[game.com_tst_position]} required: fail`)
- game.com_tst_attempted = 1
- game.state = 'tiananmen_square_attempt_fail'
- }
- }
-}
-
-function check_presence(country) {
-
- let dem_spaces = 0;
- let com_spaces = 0;
- let dem_battlegrounds = 0;
- let com_battlegrounds = 0;
- let dem_leaders = {1: false, 4: false, 5: false, 6: false, 7: false};
- let com_leaders = {1: false, 4: false, 5: false, 6: false, 7: false};
-
-
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (space.country === country) {
-
- if (check_dem_control(i)) {
- dem_spaces++;
- if (space.battleground === 1) {
- dem_battlegrounds++;
- }
- if (leaders.includes(space.socio)) {
- dem_leaders[space.socio] = true;
- }
- }
- if (check_com_control(i)) {
- com_spaces++;
- if (space.battleground === 1) {
- com_battlegrounds++;
- }
- if (leaders.includes(space.socio)) {
- com_leaders[space.socio] = true;
- }
- }
- }
- }
-
- // Determine domination
- let dem_domination = dem_battlegrounds > com_battlegrounds && dem_spaces > com_spaces && dem_spaces - dem_battlegrounds > 0;
- let com_domination = com_battlegrounds > dem_battlegrounds && com_spaces > dem_spaces && com_spaces - com_battlegrounds > 0;
-
- // Determine control
- let total_battlegrounds = battlegrounds(country);
- let dem_control = dem_battlegrounds === total_battlegrounds && dem_spaces > com_spaces;
- let com_control = com_battlegrounds === total_battlegrounds && com_spaces > dem_spaces;
-
- return {
- dem_spaces: dem_spaces,
- com_spaces: com_spaces,
- dem_battlegrounds: dem_battlegrounds,
- com_battlegrounds: com_battlegrounds,
- dem_domination: dem_domination,
- com_domination: com_domination,
- dem_control: dem_control,
- com_control: com_control,
- dem_leaders: dem_leaders,
- com_leaders: com_leaders
- };
-}
-
-function battlegrounds(country) {
- let battlegrounds = 0;
- if (country === "Hungary") {
- battlegrounds = 4
- } else if (country === "Bulgaria") {
- battlegrounds = 5
- } else {
- battlegrounds = 6
- }
- return battlegrounds;
-}
-
-function take_power(country) {
-
- log(`Democrat takes power in ${game.pwr_struggle_in}`)
- game.revolutions[find_country_index(country)] = true
- game.times_held[find_country_index(country)] = 1
-
-}
-
-function retain_power(country){
- game.times_held[find_country_index(country)]++
- let vp_gain = get_value(country)*game.times_held[find_country_index(country)]
- log(`Chooses to retain power`)
- log(`-${vp_gain} VP`)
- game.vp -= vp_gain
-}
-
-function score_country(country) {
- log_h3(`Scoring: ${country}`)
-
-//Get scoring values
- let value_presence = get_value(country)
- let value_domination = value_presence*2
- let value_control
- if (country !== "Hungary") {
- value_control = value_presence*3
- } else {
- value_control = 4
- }
-//Log for scoring
-
- let dem_vp = 0
- let com_vp = 0
- //Check for presence
- let presence = check_presence(country)
-// console.log('presence: ', presence)
-
- //If one side has domination or control
- if (presence.dem_control || presence.dem_domination) {
- log(`Democrat:`)
- if (presence.dem_control) {
- log(`Control: +${value_control} VP`)
- dem_vp += value_control
- }
- else {
- log(`Domination: +${value_domination} VP`)
- dem_vp += value_domination
- }
- log(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
- dem_vp += presence.dem_battlegrounds
- log(`Total: +${dem_vp} VP`)
-
- log_gap('Communist:')
- if (presence.com_spaces > 0) {
- log(`Presence: -${value_presence} VP`)
- com_vp -= value_presence
- if (presence.com_battlegrounds >0) {
- log(`Battlegrounds: -${presence.com_battlegrounds} VP`)
- com_vp -= presence.com_battlegrounds
- }
- log(`Total: ${com_vp} VP`)
- } else {
- log('No presence: 0 VP')
- }
-
- }
- else if (presence.com_control || presence.com_domination) {
- log('Communist:')
- if (presence.com_control) {
- log(`Control: -${value_control} VP`)
- com_vp -= value_control
- }
- else {
- log(`Domination: -${value_domination} VP`)
- com_vp -= value_domination
- }
- log(`Battlegrounds: -${presence.com_battlegrounds} VP`)
- com_vp -= presence.com_battlegrounds
- log(`Total: ${com_vp} VP`)
-
- log_gap('Democrat:')
- if (presence.dem_spaces > 0) {
- log(`Presence: +${value_presence} VP`)
- dem_vp += value_presence
- if (presence.dem_battlegrounds > 0) {
- log(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
- dem_vp += presence.dem_battlegrounds
- }
- log (`Total: +${dem_vp} VP`)
- } else {
- log('No presence: 0 VP')
- }
-
- }
-
- //Otherwise, presence and battlegrounds
- else {
- log("No domination or control")
- log_gap(`Communist:`)
- if (presence.com_spaces > 0) {
- log(`Presence: -${value_presence} VP`)
- com_vp -= value_presence
- if (presence.com_battlegrounds > 0) {
- log(`Battlegrounds: -${presence.com_battlegrounds} VP`)
- com_vp -= presence.com_battlegrounds
- } else {
- log('No battlegrounds')
- }
- log(`Total: ${com_vp} VP`)
- } else {
- log('No presence: 0 VP')
- }
- log_gap('Democrat:')
- if (presence.dem_spaces > 0) {
- log(`Presence: +${value_presence} VP`)
- dem_vp += value_presence
- if (presence.dem_battlegrounds > 0) {
- log(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
- dem_vp += presence.dem_battlegrounds
- } else {
- log('No battlegrounds')
- }
- log(`Total: +${dem_vp} VP`)
- } else {
- log('No presence: 0 VP')
- }
- }
-
-
-//Calculate change VP
- /*let dem_vp = 0
- if (presence.dem_spaces > 0) {dem_vp += value_presence}
- if (presence.dem_domination) {dem_vp += value_presence}
- if (presence.dem_control && country !== "Hungary") {
- dem_vp += value_control
- }
- else if (presence.dem_control && country === "Hungary") {dem_vp += 2}
- dem_vp += presence.dem_battlegrounds
-
- let com_vp = 0
- if (presence.com_spaces > 0) {com_vp += value_presence}
- if (presence.com_domination) {com_vp += value_presence}
- if (presence.com_control && country !== "Hungary") {com_vp += value_presence}
- else if (presence.com_control && country === "Hungary") {com_vp += 2}
- com_vp += presence.com_battlegrounds */
- let change_vp = dem_vp + com_vp
- game.vp += change_vp
- if (change_vp > 0 ) {
- log_gap(`Final change VP: +${change_vp} VP`)
- } else {
- log_gap(`Final change VP: ${change_vp} VP`)
- }
-}
-
-function get_value(country) {
- let value
- if (country === "East_Germany" || country === "Poland") {value = 3}
- else if (country === "Czechoslovakia" || country === "Romania") {value = 2}
- else value = 1
- return value
-}
-
-function get_end_infl_prompt() {
- view.prompt = `${clean_name(cards[this_card()].name)}. Add SPs: done.`
- if (!game.vm_infl_to_do) {
- gen_action('end_round')
- } else {
- gen_action('done')
- }
-}
-
-function permanently_remove(card) {
- //console.log('permanently removing card:', card)
- if (game.strategy_removed.includes(card)) {return}
- //log_msg_gap(`C${cards[card].number} permanently removed`)
- remove_from_discard(card)
-
- card_index = game.table_cards.indexOf(card)
- if (card_index !== -1) {
- //console.log('sub 2 called')
- game.table_cards.splice(card_index, 1)
- }
- game.strategy_removed.push(card)
- //console.log('game.strategy_removed', game.strategy_removed)
-}
-
-function check_vp() {
- if (game.vp >= 20) {
- goto_game_over(DEM, `${DEM} won an Automatic Victory!`)
- //console.log('after goto_game_over, game.state', game.state)
- return true
- } else if(game.vp <= -20) {
- goto_game_over(COM, `${COM} won an Automatic Victory!`)
- return true
- }
- return false
-}
-
-function game_over() {
- if (game.vp >= 20 || game.vp <= -20) {
- return true
- } else { return false}
-}
-
-function goto_game_over(result, victory) {
- game.state = "game_over"
- game.active = "None"
- game.result = result
- game.victory = victory
- log_h1("Game Over")
- log(game.victory)
- //console.log('game over, game.state', game.state)
- return
-
-}
-
-function reset_austria_hungary_border_reopened() {
- //game.austria_hungary_border_reopened_checked = false
- game.austria_hungary_border_reopened_tracker = false
-}
-
-function end_stasi_choose_card() {
- game.round_player = COM
- game.round ++
- log_h2(`Action Round ${game.round}`)
- next_player()
- game.valid_spaces = []
- if (game.persistent_events.includes(5)) {
- log_h3('C5')
- game.state = 'general_strike'
- } else {
- game.state = 'choose_card'
- }
-}
-
-function check_reformer() {
- if (game.dem_tst_position !== game.com_tst_position) {
- if (!game.playable_cards.includes(67)) {
- game.playable_cards.push(67)
- }
- } else {
- game.playable_cards = game.playable_cards.filter(n => n !== 67)
- }
-
-}
-
-function count_scoring_cards() {
- let scoring_check
- if (game.active === DEM) {
- scoring_check = game.democrat_hand.filter(card => scoring_cards.includes(card)).length
- } else {
- scoring_check = game.communist_hand.filter(card => scoring_cards.includes(card)).length
- }
- return scoring_check
-}
-
-function select_card(card){
- game.played_card = card
- game.temp = 0
- let find_card
- if (game.active === COM) {
- find_card = game.communist_hand.indexOf(card)
- game.communist_hand.splice(find_card, 1)
- } else {
- find_card = game.democrat_hand.indexOf(card)
- game.democrat_hand.splice(find_card, 1)
- }
- game.available_ops = get_card_ops(card)
-
- //Check Ligachev
- if (game.active === DEM && game.persistent_events.includes(99) && card !== 14) {
- log('-3 VP from C99')
- game.vp -= 3
- if (check_vp()) {
- return
- }
- game.persistent_events = game.persistent_events.filter(n => n !== 99)
- }
- game.state = 'play_card'
- //console.log('game.state', game.state)
-}
-
-function find_event(card) {
- return variable_events.indexOf(card)
-}
-
-function is_auto_resolve(card) {
-
- let ceausecu_events = [10, 41, 101, 107]
-
- if (card === 97) {
- if (!game.persistent_events.includes(54)) {
- return true
- }
- }
- else if (ceausecu_events.includes(card) && game.persistent_events.includes(97)) {
- return true
- }
- else if (card === 87 && !game.persistent_events.includes(86)) {
- return true
- }
- else if (auto_resolve_events.includes(card)) {
- return true
- } else {
- return false
- }
-}
-
-function get_events(card){
- if (event_is_playable(card)) {
- if (cards[card].side === 'D') {
- if (game.active === DEM) {gen_action('event')}
- if (game.active === COM) {gen_action('opp_event')}
- }
- else if (cards[card].side === 'C') {
- if (game.active === COM) {gen_action('event')}
- if (game.active === DEM) {gen_action('opp_event')}
- }
- else {
- gen_action('event')
- }
- }
-}
-
-function event_is_playable(card) {
-// console.log('game.stasi_card', game.stasi_card, 'card', card)
- //Reformer never playable here
- if (card === 67) {
- return false
- }
- //Check for Common European Hmme under Stasi
- else if (game.stasi_card === 21 && card === 21 && game.active === DEM) {
- return false
- }
- //Check for The Chinese Solution
- else if (game.com_tst_position === 8 && card === 96) {
- return true
- }
- //Then check normally
- else if (cards[card].playable) {
- return true
- } else if (game.playable_cards.includes(card)) {
- return true
- } else {
- return false
- }
-}
-
-function get_card_ops(card) {
- let ops = 0
-
- if (card) {
- ops = cards[card].ops
- }
- if (game.persistent_events.includes(25) && game.active === COM) {
- if(game.state === 'choose_card' || game.state === 'stasi_play_card') {
- log('+1 op from C25')
- }
- ops ++
- }
- if (game.persistent_events.includes(50) && game.active === DEM) {
- if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_laszlo_tokes') {
- log('+1 op from C50')
- }
- ops ++
- }
-
- if ((game.active === DEM && game.dem_tst_position >= 2 && game.com_tst_position <= 1 && cards[card].ops === 1) || (game.active === COM && game.com_tst_position >=2 && game.dem_tst_position <= 1 && cards[card].ops === 1)) {
- if(game.state === 'choose_card' || game.state === 'stasi_play_card') {
- log('+1 op from Tiananmen Square Track')
- }
- ops ++
- }
-
- if ((game.active === DEM && game.prudence && game.prudence.DEM !== 0)) {
- if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_laszlo_tokes') {
- if (ops > 2) {
- log(`${pluralize(game.prudence.DEM,'op')} from C8`)
- } else {
- if (ops > 1) {
- log(`-1 op from C8`)
- }
- }
- }
- ops += game.prudence.DEM
-
- if (ops < 1) {
- ops = 1
- }
- }
-
- if (game.active === COM && game.prudence && game.prudence.COM < 0) {
- if(game.state === 'choose_card') {
- if (ops > 2) {
- log(`${pluralize(game.prudence.COM,'op')} from C8`)
- } else if (ops > 1) {
- log(`-1 op from C8`)
- }
- }
- ops += game.prudence.COM
- if (ops < 1) {
- ops = 1
- }
- } return ops
-}
-
-function get_tst_6_ops() {
- let ops = 0
-
- if (game.persistent_events.includes(25) && game.active === COM) {
- log('+1 op from C25')
- ops ++
- }
- if (game.persistent_events.includes(50) && game.active === DEM) {
- log('+1 op from C50')
- ops ++
- }
-
- if ((game.active === DEM && game.prudence && game.prudence.DEM !== 0)) {
- if (ops > 0) {
- log(`${pluralize(game.prudence.DEM,'op')} from C8`)
- } else {
- log(`-1 op from C8`)
- }
-
- ops += game.prudence.DEM
-
- if (ops < -1) {
- ops = -1
- }
- }
-
- if (game.active === COM && game.prudence && game.prudence.COM < 0) {
-
- if (ops > 0) {
- log(`${pluralize(game.prudence.COM,'op')} from C8`)
- } else {
- log(`-1 op from C8`)
- }
-
- ops += game.prudence.COM
- if (ops < -1) {
- ops = -1
- }
- }
- return ops
-}
-
-function finish_the_wall() {
- if (game.the_wall_must_go['dem_wins'] === 2) {
- game.persistent_events.push(86)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (space.country === 'East_Germany' && game.comInfl[i] > 0){
- game.valid_spaces.push(space.space_id)
- }
- }
- if (!game.vm_infl_to_do) {
- if (game.round_player === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- }
- if (game.active === DEM) {next_player()}
- vm_next ()
- } else {
- permanently_remove(86)
- delete game.the_wall_must_go
- vm_return()
- }
-}
-
-
-// =========== MOVING THROUGH TURNS ============
-
-function end_round() {
-// console.log('end round, game.persistent_events.includes(13)', game.persistent_events.includes(13))
- //Check if the game is over!
- if (game.state === 'game_over') {
- // console.log('in end')
- return}
-
- //Check if the card has been removed or played to table, and if a card has been not been played. If not, discard.
- if (!game.strategy_removed.includes(game.played_card) && !game.table_cards.includes(game.played_card) && game.played_card > 0) {
- game.strategy_discard.push(game.played_card)
- }
-
- //Reset
- game.played_card = 0
- game.temp = 0
- game.vm_event = 0
- game.phase = 0
- game.remove_opponent_infl = false
- game.is_pwr_struggle = false
- game.vm_infl_to_do = false /*Can get rid of this and use game.return_state? */
- game.vm_event_to_do = false
- game.vm_active_country = ''
- game.return_state = ''
- game.discard = false
- game.return = ''
- game.valid_cards = []
- game.valid_spaces = []
- check_common_european_home()
- //game.playable_cards[find_event(21)] = true
- reset_austria_hungary_border_reopened() /*This should be redundant! */
-
-
- // Check for duplicate card entries
- let card_check
- if (game.samizdat_card > 0) {
- card_check = [...game.strategy_deck, ...game.strategy_discard, ...game.strategy_removed, ...game.table_cards, ...game.communist_hand, ... game.democrat_hand, game.samizdat_card];
- } else {
- card_check = [...game.strategy_deck, ...game.strategy_discard, ...game.strategy_removed, ...game.table_cards, ...game.communist_hand, ... game.democrat_hand];
- }
-
- function check_duplicates(array) {
- return new Set(array).size !== array.length;
- }
-
- function find_duplicates(array) {
- const duplicates = array.filter((item, index) => array.indexOf(item) !== index);
- return [...new Set(duplicates)];
- }
-
- //console.log('game.strategy_deck', game.strategy_deck, 'game.strategy_discard', game.strategy_discard, 'game.strategy_removed', game.strategy_removed, 'game.table_cards', game.table_cards, 'game.communist_hand', game.communist_hand, 'game.democrat_hand', game.democrat_hand)
-
- if (check_duplicates(card_check)) {
- console.log('card check', card_check)
- const duplicates = find_duplicates(card_check)
- console.log('game.strategy_deck', game.strategy_deck, 'game.strategy_discard', game.strategy_discard, 'game.strategy_removed', game.strategy_removed, 'game.table_cards', game.table_cards, 'game.communist_hand', game.communist_hand, 'game.democrat_hand', game.democrat_hand)
- throw new Error(`Duplicate cards detected: ${duplicates.join(', ')}`)
- }
- //console.log('cards in game', card_check.length)
- card_check = card_check.sort((a, b) => a - b)
- //console.log('cards in game', card_check)
- if (game.turn <= 3) {
- if (card_check.length !== 40) {
- throw new Error(`Wrong number of cards: ${card_check.length}`)
- }
- } else if (game.turn <=7) {
- if (card_check.length !== 81) {
- throw new Error(`Wrong number of cards: ${card_check.length}`)
- }
- } else if (card_check.length !== 110) {
- throw new Error(`Wrong number of cards: ${card_check.length}`)
- }
-
-
-
- //console.log('game.dem_tst_position ', game.dem_tst_position , 'game.com_tst_position ', game.com_tst_position )
- //Check if the Reformer is playable
- check_reformer()
-
- // Check if last round and if so resolve end turn events
- if (game.round_player === DEM && game.round === 7) {
- if(game.persistent_events.includes(15)) {
- if (game.active !== COM) {
- next_player()
- }
- game.state = 'honecker'
- return
- }
- else if (game.dem_tst_position >= 6 && game.com_tst_position <= 5) {
- log_h2('Tiananmen Square Track Award')
- if (game.active !== DEM) {
- next_player()
- }
- game.return = game.active
- clear_undo()
- game.return_state = 'end_turn_4_5_4'
- goto_vm(206)
- return
- } else if (game.com_tst_position >= 6 && game.dem_tst_position <= 5) {
- log_h2('Tiananmen Square Track Award')
- if (game.active !== COM) {
- next_player()
- }
- game.return = game.active
- clear_undo()
- game.return_state = 'end_turn_4_5_4'
- goto_vm(206)
- return
- }
- else {
- clear_undo()
- game.state = 'end_turn_4_5_4'
- return
- }
- }
-
- // Resolve end action round
- //Stasi check
- if(game.round_player === COM && game.persistent_events.includes(13)) {
- //If in Honecker, turn ends
- if (game.round === 8) {
- clear_undo()
- game.state = 'end_turn_4_5_4'
- return
- }
- //Otherwise go to Stasi
- game.round_player = DEM
- if (game.active !== DEM) {
- next_player()
- } else {
- log_h3('Democratic Action Round')
-
- }
- if (game.democrat_hand.includes(game.stasi_card)) {
- log_h3('C13')
- game.state = 'stasi_play_card'
- } else {
- game.stasi_card = 0
- game.state = 'choose_card'
- }
- return
- }
- //Check if in extra Action Round
- else if (game.round_player === COM && game.round === 8) {
- clear_undo()
- game.state = 'end_turn_4_5_4'
- return
- }
- //Normal round end
- else if (game.round_player===COM) {
- game.round_player = DEM
- if (game.active !== DEM) {
- next_player()
- } else {
- log_h3('Democratic Action Round')
- }
- game.state = 'choose_card'
- return
- }
- if (game.round_player === DEM) {
- // console.log('checking stasi', game.persistent_events.includes(13))
- if(game.persistent_events.includes(13)) {
- // console.log('stasi sub function')
- if (game.active !== DEM) {
- next_player()
- }
- log_h3('C13')
- game.state = 'stasi_end_round'
- return
- } else if(game.round_player === DEM && game.persistent_events.includes(5)){
- game.state = 'general_strike'
- game.round ++
- log_h2(`Action Round ${game.round}`)
- game.round_player = COM
- if (game.active !== COM) {
- next_player()
- }
- log_h3('C5')
- return
- } else {
- game.state = 'choose_card'
- game.round_player = COM
- game.round ++
- log_h2(`Action Round ${game.round}`)
- if (game.active !== COM) {
- next_player()
- }
- }
- }
- //game.state = 'choose_card' Does this do anything any more?
-}
-
-/*
-function end_turn(){
- /*End Turn sequence
- TST support check
- Verify held cards
- New Year's Eve Party
- Advance Turn Marker
-
-// CHECK FOR OPTIONAL SUPPORT CHECK
- if (game.dem_tst_position >=6 && game.com_tst_position <= 5) {
- if (game.active !== DEM) {
- next_player_()
- }
- game.state = 'tst_support_check'
- }
- if (game.com_tst_position >=6 && game.dem_tst_position <= 5) {
- if (game.active !== COM) {
- next_player_()
- }
- game.state = 'tst_support_check'
- }
-
-
-//CHECK HELD CARDS
-
-} */
-
-function new_turn() {
- clear_undo()
- game.turn ++
- game.round = 1
- game.valid_spaces=[]
- game.active = COM
- game.round_player = COM
- game.dem_tst_attempted_this_turn = 0
- game.com_tst_attempted_this_turn = 0
- if (game.tst_7) {game.tst_7 = false}
- if (game.tst_8) {game.tst_8 = false}
-
- //Remove events that only last one turn
- game.persistent_events = game.persistent_events.filter(n => n !== 25) /*Perestroika*/
- game.persistent_events = game.persistent_events.filter(n => n !== 50) /*Sinatra Doctrine*/
- game.persistent_events = game.persistent_events.filter(n => n !== 13) /*Stasi*/
- game.persistent_events = game.persistent_events.filter(n => n !== 15) /*Honecker*/
- delete game.prudence
- delete game.stasi_card
-
- //Austria Hungary Border Reopened
- if (game.persistent_events.includes(58)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 58)
- delete game.austria_hungary_border_reopened_tracker
- log(`C58 no longer in effect`)
- //permanently_remove(58)
- }
- //Elena
- if (game.persistent_events.includes(101)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 101)
- log(`C101 no longer in effect`)
- //permanently_remove(101)
- }
- //GrenzTruppen
- if (game.persistent_events.includes(59)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 59)
- log(`C59 no longer in effect`)
- //permanently_remove(59)
- }
- //Foreign Currency Debt Burden
- if (game.persistent_events.includes(49)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 49)
- delete game.foreign_currency_debt_burden
- log(`C49 no longer in effect`)
- //permanently_remove(49)
- }
- //FRG Embassies
- if (game.persistent_events.includes(74)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 74)
- log(`C74 no longer in effect`)
- discard_from_table(74)
- permanently_remove(74)
- }
- //Genscher
- if (game.persistent_events.includes(63)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 63)
- log(`C63 no longer in effect`)
- discard_from_table(63)
- permanently_remove(63)
- }
- //Stand Fast
- if (game.persistent_events.includes(100)) {
- game.persistent_events = game.persistent_events.filter(n => n !== 100)
- delete game.stand_fast
- log(`C100 no longer in effect`)
- //permanently_remove(100)
- }
-
- if (game.samizdat_card > 0 ) {
- game.democrat_hand.push(game.samizdat_card)
- delete game.samizdat_card
- }
-
- log_h1("Turn " + game.turn)
-
- if (game.turn === 4) {
- add_midyear()
- }
- if (game.turn === 8) {
- add_lateyear()
- }
- if (game.turn > 1) {
- if (game.persistent_events.includes(65)) {
- game.com_hand_limit = 7
- log('Communist draws 7 cards due to C65')
- //permanently_remove(65)
- game.persistent_events = game.persistent_events.filter(n => n !== 65)
- }
- //console.log('deck', game.strategy_deck)
- //console.log('game.com_hand_limit', game.com_hand_limit, 'communist hand before draw', game.communist_hand)
- draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.dem_hand_limit, game.com_hand_limit)
- game.com_hand_limit = 8
- //console.log('communist hand after draw', game.communist_hand)
-
- }
-
- //Check if TST effects need to be resolved
- if (game.dem_tst_position >=5 && game.com_tst_position <= 4) {
- log_h2('Tiananmen Square Track award')
- if(game.active !== DEM) { next_player() }
- for (let card of game.democrat_hand) {
- if (scoring_cards.includes(card)) continue
- game.valid_cards.push(card)
- }
- game.state = 'tst_goddess' /* Goddess only name of Democrat bonus, not Communist*/
- return
- }
- else if (game.com_tst_position >=5 && game.dem_tst_position <= 4) {
- log_h2('Tiananmen Square Track award')
- if(game.active !== COM) { next_player() }
- for (let card of game.communist_hand) {
- if (scoring_cards.includes(card)) continue
- game.valid_cards.push(card)
- }
- game.state = 'tst_goddess'
- } else {
- log_h2("Action Round " + game.round)
- log_side()
- //console.log('in start new AR call, game.active', game.active)
- if (game.persistent_events.includes(5)) {
- log_h3('C5')
- game.state = 'general_strike'
- }
- else {
- game.state = 'choose_card'
- }
- }
-}
-
-function next_player() {
- clear_undo()
- //console.log('next player called')
- if (game.active === DEM)
- game.active = COM
- else
- game.active = DEM
-
- log_side()
-}
-
-function change_player() {
- clear_undo()
- //console.log('next player called')
- if (game.active === DEM)
- game.active = COM
- else
- game.active = DEM
-}
-
-function find_space_index(name_unique) {
- return spaces.findIndex(space => space && space.name_unique === name_unique)
-}
-
-function find_country_index(country) {
- return countries.indexOf(country)
-}
-
-function draw_deck(deck) {
- return deck.filter(card => card && card.period === 1).map(card => card.number)
-}
-
-function draw_cards(deck, democrat_hand, communist_hand, dem_hand_limit, com_hand_limit) {
- //console.log('game.valid_cards at start of draw cards: ', game.valid_cards)
- let turn = 'communist'; // Start with the communist player
- //console.log('game.strategy_deck', game.strategy_deck)
- //console.log('deck', deck, 'democrat_hand', democrat_hand, 'communist_hand', communist_hand, 'dem_hand_limit', dem_hand_limit, 'com_hand_limit', com_hand_limit)
- while (democrat_hand.length < dem_hand_limit || communist_hand.length < com_hand_limit) {
- //console.log('deck.length: ', deck.length)
- //console.log('discard.length', game.strategy_discard )
- if (deck.length === 0) {
- log_h3('--- Reshuffle ---')
-
- deck.push(...game.strategy_discard)
- game.strategy_discard = []
- }
-
- else if (turn === 'communist' && communist_hand.length < com_hand_limit) {
- communist_hand.push(draw_card(deck));
- //console.log('game.valid_cards after communist draw: ', JSON.stringify(game.valid_cards));
- turn = 'democrat';
- } else if(turn === 'communist' && communist_hand.length === com_hand_limit) {
- turn = 'democrat';
- }
- else if (turn === 'democrat' && democrat_hand.length < dem_hand_limit) {
- democrat_hand.push(draw_card(deck));
- //console.log('democrat_hand: ', democrat_hand)
-
- //console.log('game.valid_cards after democrat draw: ', JSON.stringify(game.valid_cards));
- turn = 'communist';
- }
- else if (turn === 'democrat' && democrat_hand.length === dem_hand_limit) {
- turn = 'communist';
- }
- }
-
- clear_undo()
-}
-
-function draw_card(deck) {
- //console.log('draw card called with:', deck)
- //console.log('game.strategy_deck before', game.strategy_deck)
- if (deck.length === 0) {
- log_h3('--- Reshuffle ---')
-
- deck.push(...game.strategy_discard)
- game.strategy_discard = []
- }
- const randomIndex = Math.floor(Math.random() * deck.length)
- //console.log('card chosen:', randomIndex)
- //console.log('game.strategy_deck after', game.strategy_deck)
- return deck.splice(randomIndex, 1)[0];
-}
-
-function discard(card) {
- //console.log('in discard(card)')
- let find_card
- if (!game.is_pwr_struggle) {
-
- if (game.active === COM) {
- find_card = game.communist_hand.indexOf(card)
- game.communist_hand.splice(find_card, 1)
- } else {
- find_card = game.democrat_hand.indexOf(card)
- game.democrat_hand.splice(find_card, 1)
- }
- if (!game.strategy_discard.includes(card)) {
- game.strategy_discard.push(card)
- log(`Discarded C${cards[card].number}`)
- }
- } else if (game.is_pwr_struggle) {
- if (game.active === COM) {
- find_card = game.com_pwr_hand.indexOf(card);
- game.com_pwr_hand.splice(find_card, 1);
- } else {
- find_card = game.dem_pwr_hand.indexOf(card);
- game.dem_pwr_hand.splice(find_card, 1);
- }
-
- game.power_struggle_discard.push(card)
- //log(`Discarded P${power_cards[card].number}`)
- }
-}
-function silent_discard(card) {
- //console.log('in discard(card)')
- let find_card
- if (!game.is_pwr_struggle) {
- if (game.active === COM) {
- find_card = game.communist_hand.indexOf(card)
- game.communist_hand.splice(find_card, 1)
- } else {
- find_card = game.democrat_hand.indexOf(card)
- game.democrat_hand.splice(find_card, 1)
- }
- if (!game.strategy_discard.includes(card)) {
- game.strategy_discard.push(card)
- }
- } else if (game.is_pwr_struggle) {
- if (game.active === COM) {
- find_card = game.com_pwr_hand.indexOf(card);
- game.com_pwr_hand.splice(find_card, 1);
- } else {
- find_card = game.dem_pwr_hand.indexOf(card);
- game.dem_pwr_hand.splice(find_card, 1);
- }
- game.power_struggle_discard.push(card)
- }
-}
-
-function remove_from_discard(card) {
- let card_index = game.strategy_discard.indexOf(card)
- if (card_index !== -1) {
- game.strategy_discard.splice(card_index, 1)
- }
-}
-
-function discard_card(hand) {
- //let find_card
- let card = Math.floor(Math.random()*hand.length)
- let discarded_card = hand.splice(card, 1)[0]
- if (game.is_pwr_struggle) {
- if (numberless_cards.includes(discarded_card)) {
- log_gap(`Discarded: P${discarded_card}`)
- } else {
- log_gap(`Discarded: P${discarded_card} V${power_cards[discarded_card].value}`)
- }
- } else {
- log(`Discarded C${cards[discarded_card].number}`)
- game.strategy_discard.push(discarded_card)
- }
- return discarded_card
-}
-
-function discard_from_table(card) {
- find_card = game.table_cards.indexOf(card)
- game.table_cards.splice(find_card, 1)
- game.strategy_discard.push(card)
-}
-
-
-function add_midyear() {
- const mid_year = cards.filter(card => card && card.period === 2).map(card => card.number);
- game.strategy_deck.push(...mid_year);
- log_h3('Mid-year cards added to draw deck')
-}
-
-
-function add_lateyear() {
- const late_year = cards.filter(card => card && card.period === 3).map(card => card.number)
- game.strategy_deck.push(...late_year)
- log_h3('Late-year cards added to draw deck')
-}
-
-function reset_power() {
- game.power_struggle_deck = []
- game.power_struggle_discard = []
- game.dem_pwr_hand = []
- game.com_pwr_hand = []
- game.phase = 1
- game.raised_stakes_round = 0
- game.raised_stakes = 0
- game.played_power_card = 0
- game.tactics_fails = ''
- game.view_opp_hand = false
-
- if (game.persistent_events.includes(72)){
- permanently_remove(72)
- game.table_cards = game.table_cards.filter(card => card !== 72)
- game.persistent_events = game.persistent_events.filter(n => n !== 72)
- }
- if (game.persistent_events.includes(62)) {
- permanently_remove(62)
- game.table_cards = game.table_cards.filter(card => card !== 62)
- game.persistent_events = game.persistent_events.filter(n => n !== 62)
- }
- if (game.persistent_events.includes(54) && game.pwr_struggle_in === 'Romania'){
- permanently_remove(54)
- //game.table_cards = game.table_cards.filter(card => card !== 54)
-
- }
- if (game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(70)){
- //permanently_remove(70)
- //game.table_cards = game.table_cards.filter(card => card !== 70)
- game.persistent_events = game.persistent_events.filter(n => n !== 70)
- }
-}
-
-function check_control_change(space_id) {
-
- // Check if the Tyrant is Gone has been fulfilled
-
- if (game.the_tyrant_is_gone > 0 && check_dem_control(game.the_tyrant_is_gone)) {
- log('+2 VP from C97')
- game.vp += 2
- if (check_vp()) {
- return
- }
- game.persistent_events = game.persistent_events.filter(n => n !== 97)
- delete game.the_tyrant_is_gone
- }
-}
-
-function check_systematization() {
- // Check for Systematization - may not use this space
- if (game.systematization > 0) {
- game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
- }
-}
-
-function check_common_european_home() {
- if (!game.playable_cards.includes(21)) {
- game.playable_cards.push(21)
- }
-}
-
-function this_card() {
- return game.vm_event > 0 ? game.vm_event : game.played_card
-}
-/*
-function get_ops(card) {
- let ops = cards[card].ops
- if (game.active === COM) {
- //Check TST op bonus
- if (ops === 1 && game.com_tst_position >=2 && game.dem_tst_position <=1) {
- ops++
- }
- //Events that influence ops
- if (game.persistent_events.includes(25)) {
- ops++
- }
- if (game.prudence.COM && game.prudence.COM <0) {
- ops += game.prudence.COM
- }
-
- } else {
- //Check TST op bonus
- if (ops === 1 && game.dem_tst_position >=2 && game.com_tst_position <=1) {
- ops++
- }
- //Events that influence ops
- if (game.persistent_events.includes(50)) {
- ops++
- }
- if (game.prudence.DEM && game.prudence.DEM <0) {
- ops += game.prudence.DEM
- }
- }
- //Ops can never be less than one
- if (ops <1) { ops = 1 }
- return ops
-}
- */
-
-const pluralize = (count, noun, suffix = 's') =>
- `${count} ${noun}${Math.abs(count) !== 1 ? suffix : ''}`
-
-function clean_name(str) {
- if (str && str.slice(-1) === '*') {
- return str.slice(0, -1)
- } else {
- return str;
- }
-}
-
-function country_name(country) {
- return country.replace(/_/g, ' ')
-}
-
-// ======== LOG FUNCTIONS =============
-
-function log(msg) {
- game.log.push(msg)
-}
-
-function log_br() {
- if (game.log.length > 0 && game.log[game.log.length - 1] !== "")
- game.log.push("")
-}
-
-function logi(msg) {
- game.log.push(">" + msg)
-}
-
-function log_h1(msg) {
- log_br()
- log(".h1 " + msg)
- log_br()
-}
-
-function log_h2(msg) {
- log_br()
- log(".h2 " + msg)
- log_br()
-}
-
-function log_h3(msg) {
- log_br()
- log(".h3 " + msg)
-}
-
-function log_gap(msg) {
- log_br()
- game.log.push(msg)
-}
-
-function log_msg_gap(msg) {
- game.log.push(msg)
- log_br()
-}
-
-
-function log_side() {
- log_br()
- if (game.active === DEM)
- log(".h2d " + game.active)
- else
- log(".h2c " + game.active)
- log_br()
-}
-
-function log_sep() {
- log(".hr")
-}
-
-function log_action(msg) {
- log_br()
- log(msg)
-}
-
-// ============= SUMMARY FUNCTIONS =============
-
-function push_summary() {
- if (game.summary)
- throw "TOO MANY SUMMARIES"
- game.summary = []
-}
-
-function log_summary(msg) {
-
- if (msg.startsWith('Added') || msg.startsWith('Removed')) {
- for (let item of game.summary) {
- if (item[1] === msg) {
- item[0]++
- return
- }
- }
- }
- game.summary.push([1, msg])
-}
-
-function pop_summary() {
- if (game.summary.length > 0) {
- for (let [n, msg] of game.summary) {
- if (n > 1) {
- log(msg.replace("£ SP", `${n} SPs`));
- } else {
- log(msg.replace("£ SP", `${n} SP`));
- }
- }
- }
- game.summary = []
-}
-
-function log_summary_place(p) {
- let from = piece_space(p)
- if (from !== AVAILABLE)
- log_summary("% " + piece_name(p) + " from S" + from)
- else
- log_summary("% " + piece_name(p))
-}
-
-function log_summary_move_to_from(p, to) {
- log_summary("% " + piece_name(p) + " to S" + to + " from S" + piece_space(p))
-}
-
-function log_summary_remove(p) {
- log_summary("Removed % " + piece_name(p))
-}
-
-function log_summary_activated(p) {
- log_summary("Activated % " + piece_faction_name(p))
-}
-
-// ============ UNDO FUNCTIONS ==================
-
-function clear_undo() {
- if (game.undo.length > 0)
- game.undo = []
-}
-
-function push_undo() {
- let copy = {}
- for (let k in game) {
- let v = game[k]
- if (k === "undo")
- continue
- else if (k === "log")
- v = v.length
- else if (typeof v === "object" && v !== null)
- v = object_copy(v)
- copy[k] = v
- }
- game.undo.push(copy)
-}
-
-function pop_undo() {
- let save_log = game.log
- let save_undo = game.undo
- game = save_undo.pop()
- save_log.length = game.log
- game.log = save_log
- game.undo = save_undo
-}
-
-// Fast deep copy for objects without cycles
-function object_copy(original) {
- if (Array.isArray(original)) {
- let n = original.length
- let copy = new Array(n)
- for (let i = 0; i < n; ++i) {
- let v = original[i]
- if (typeof v === "object" && v !== null)
- copy[i] = object_copy(v)
- else
- copy[i] = v
- }
- return copy
- } else {
- let copy = {}
- for (let i in original) {
- let v = original[i]
- if (typeof v === "object" && v !== null)
- copy[i] = object_copy(v)
- else
- copy[i] = v
- }
- return copy
- }
-}
-
-
-/* =================== VM FUNCTIONS ========================== */
-
-function goto_vm(proc) {
- let old_vm = game.vm;
-
- game.state = "vm";
- game.vm = {
- prompt: 0,
- fp: proc,
- ip: 0,
- };
-
- if (old_vm) {
- game.vm.return_vm = old_vm;
- }
-
- vm_exec();
-}
-
-function vm_exec() {
- vm_inst(0)();
-}
-
-function vm_inst(a) {
- //console.log('game.vm.fp', game.vm.fp, 'game.vm.ip', game.vm.ip)
- return CODE[game.vm.fp][game.vm.ip][a]
-}
-
-function vm_next() {
- game.vm.ip++;
- //console.log('vm_next called, game.vm.ip', game.vm.ip)
- vm_exec();
-}
-
-function vm_operand(a) {
- let x = CODE[game.vm.fp][game.vm.ip][a]
- if (a > 0 && typeof x === "function")
- return x()
- return x
-}
-
-function vm_assert_argcount(n) {
- const argcount = CODE[game.vm.fp][game.vm.ip].length - 1
- if (argcount !== n)
- throw Error(`ASSERT Invalid number of arguments on event ${game.vm.fp}: ${argcount} instead of ${n}`)
-}
-
-function vm_log() {
- log(vm_operand(1));
- vm_next();
-}
-
-function vm_if() {
- //console.log('game.temp', game.temp)
-// console.log('vm_operand(1)', vm_operand(1))
- if (!vm_operand(1)) {
- let balance = 1
- while (balance > 0) {
- ++game.vm.ip
- switch (vm_operand(0)) {
- case vm_if:
- ++balance
- break
- case vm_endif:
- --balance
- break
- case vm_else:
- if (balance === 1)
- --balance
- break
- }
- if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length)
- throw "ERROR"
- }
- }
- vm_next()
-}
-
-function vm_else() {
- vm_goto(vm_endif, vm_if, 1, 1)
-}
-
-function vm_endif() {
- vm_next()
-}
-
-function vm_goto_step(step) {
- // console.log('vm_goto_step called, target:', step)
- //console.log('game.vm.ip', game.vp.ip)
- for (let i = game.vm.ip; i < CODE[game.vm.fp].length; i++) {
- //console.log('i', i)
- //console.log('step', CODE[game.vm.fp][i][0])
- if (CODE[game.vm.fp][i][0] === step) {
- game.vm.ip = i;
- vm_exec();
- return;
- }
- }
-
- console.log("ERROR: Target operation not found in the current procedure.");
-}
-
-
-function vm_goto(op, nop, dir, step) {
- //console.log('vm_inst(0)', vm_inst(0), op, nop)
-// console.log('vm_inst(0)', vm_inst(1), op, nop)
- let balance = 1
- while (balance > 0) {
- game.vm.ip += dir
- if (vm_inst(0) === op)
- --balance
- if (vm_inst(0) === nop)
- ++balance
- if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length)
- throw "ERROR"
- }
- game.vm.ip += step
- vm_exec()
-}
-
-function event_prompt(str) {
- //console.log('event_prompt called with', str)
- if (typeof str === "undefined")
- str = CODE[game.vm.fp][game.vm.prompt][1]
- if (typeof str === "function")
- str = str()
- //console.log('str:', str)
- if (!str) {
- str = ""
- }
- return str
-}
-
-function vm_prompt() {
- if (game.vm.prompt)
- game.vm._prompt = game.vm.prompt
- game.vm.prompt = game.vm.ip
- vm_next()
-}
-
-function pop_vm_prompt() {
- if (game.vm._prompt) {
- game.vm.prompt = game.vm._prompt
- delete game.vm._prompt
- } else {
- game.vm.prompt = 0
- }
-}
-
-function vm_return() {
-
- //console.log('in vm_return, game.vm_infl_to_do', game.vm_infl_to_do, 'return state', game.return_state)
-
- //Remove temporary vm variables
- delete game.support_check_modifier
- delete game.vm_max_infl
- delete game.vm_influence_added
- delete game.communist_hand_red
-
- game.vm_event = 0 /*Reset to 0 now that event has been completed. Hopefully this doesn't cause issues! */
- if (game.persistent_events.includes(58)) {
- reset_austria_hungary_border_reopened()
- }
-
- //Check if end event state is needed
- if (game.is_pwr_struggle || game.state === 'vm_tst_6' || game.return_state === 'tiananmen_square_attempt_done') {
- vm_end_event()
- }
- //Check if auto-resolve opponent event
- else if (is_auto_resolve(game.played_card) && ((cards[game.played_card].side === 'C' && game.active === DEM) || (cards[game.played_card].side === 'D' && game.active === COM) )) {
- vm_end_event()
- }
- else {
-
- game.state = 'vm_end_event'
- /*if (!game.vm_infl_to_do) {
- /*if ((game.active === DEM && game.round_player !==DEM) || (game.active === COM && game.round_player !== COM)) {
- game.state = 'vm_end_event'
- } else {
- game.state = 'vm_end_event'
- //end_round()
- //}
- } else {
- console.log('vm_infl_to_do true')
- vm_end_event()
- }*/
- }
-}
-
-function vm_end_event() {
- //game.view_opp_hand = false
-// console.log('in vm_return, game.return:', game.return, 'game.return_state:', game.return_state, 'game.vm_infl_to_do', game.vm_infl_to_do, 'game.vm_event_to_do', game.vm_event_to_do)
- /*if (!game.vm_infl_to_do && !game.vm_event_to_do) {
- if (game.round_player !== game.active) {
- change_player()
- log_h2('End of Action Round')
- }
- end_round()
- return
- } /*Go direct to end round if card fully resolved */
- if (game.return !== game.active) {
- next_player()}
- if (game.return_state === 'power_struggle') {
- do_valid_cards()
- }
- if (game.return_state && game.return_state !== '') {
- game.state = game.return_state
- //console.log( 'game.state', game.state)
- }
- else if (game.vm_infl_to_do) {
- game.state = 'resolve_opponent_event'} /*Can use game.return state for this? */
- //else {game.state = "play_card"}
- else{
- end_round()}
-}
-
-/* ================== VM ACTIONS =========================== */
-
-function vm_opp_hand_false() {
- game.view_opp_hand = false
- vm_next()
-}
-
-function vm_valid_spaces() {
- let space_1 = vm_operand(1)
- let space_2 = vm_operand(2)
- let space_3 = vm_operand(3)
- let space_4 = vm_operand(4)
- let space_5 = vm_operand(5)
- let space_6 = vm_operand(6)
- game.valid_spaces = [space_1, space_2, space_3, space_4, space_5, space_6]
- game.valid_spaces = game.valid_spaces.filter( n => n )
-
- // Check for Systematization - may not use this space
- check_systematization()
-
- vm_next()
-}
-
-function vm_valid_spaces_opponent () {
- let valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
-
- if (game.active === DEM) {
- let infl = game.comInfl[i]
- if (infl > 0) {
- valid_spaces.push(space.space_id)
- }
- } else {
- infl = game.demInfl[i]
- if (infl > 0) {
- valid_spaces.push(space.space_id)
- }
- }
- }
- game.valid_spaces = valid_spaces
-// console.log('game.valid_spaces', game.valid_spaces)
- vm_next()
-}
-
-function vm_valid_spaces_socio () {
- let valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
-
- if (space.socio === vm_operand(1)) {
- valid_spaces.push(space.space_id)
- }
- }
- game.valid_spaces = valid_spaces
-
- // Check for Systematization - may not use this space
- if (game.systematization && game.systematization > 0) {
- game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
- }
- vm_next()
-}
-
-function vm_valid_spaces_opponent_socio () {
- let valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
-
- if (game.active === DEM) {
- let infl = game.comInfl[i]
- if (infl > 0 && space.socio === vm_operand(1)) {
- valid_spaces.push(space.space_id)
- }
- } else {
- let infl = game.demInfl[i]
- if (infl > 0 && space.socio === vm_operand(1)) {
- valid_spaces.push(space.space_id)
- }
- }
- }
- game.valid_spaces = valid_spaces
- // Check for Systematization - may not use this space
- if (game.systematization && game.systematization > 0) {
- game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
- }
- vm_next()
-}
-
-function vm_valid_spaces_country () {
- let country
- if (vm_operand(1)) {country = vm_operand(1)}
- else {country = game.vm_active_country}
- for (let space of spaces) {
- if (!space) continue
- if (space.country === country) {
- game.valid_spaces.push(space.space_id);
- }
- }
- // Check for Systematization - may not use this space
- if (game.systematization && game.systematization > 0) {
- game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
- }
- vm_next()
-}
-
-function vm_valid_spaces_sc () {
- valid_spaces_sc()
- vm_next()
-}
-
-function vm_valid_spaces_country_opp () {
- let country = ''
-
- if (vm_operand(1)) {
- country = vm_operand(1) }
- else {
- country = game.vm_active_country
- }
- for (let space of spaces) {
- if (!space) continue
- if (game.active === DEM) {
- if (space.country === country && game.comInfl[space.space_id] >0) {
- game.valid_spaces.push(space.space_id);
- }
- } else {
- if (space.country === country && game.demInfl[space.space_id]>0) {
- game.valid_spaces.push(space.space_id);
- }
- }
- }
- vm_next()
-}
-
-function vm_valid_spaces_country_sc () {
- let valid_spaces = []
- let country = ''
- //console.log('in vm_valid_spaces_country_sc')
- if (vm_operand(1)) {
- country = vm_operand(1) }
- else {
- country = game.vm_active_country
- }
- for (let space of spaces) {
- if (!space) continue
- if (game.active === DEM) {
- if (space.country === country && game.comInfl[space.space_id] >0) {
- valid_spaces.push(space.space_id);
- }
- } else {
- if (space.country === country && game.demInfl[space.space_id] >0) {
- //Check Solidarity Legalised
- if (game.persistent_events.includes(2) && space.space_id === 14) {continue}
-
- //Check Civic Forum
- if (game.persistent_events.includes(90) && space.space_id === 30) {continue}
-
- //Check We are the People
- if (game.persistent_events.includes(48) && space.space_id === 9) {continue}
- valid_spaces.push(space.space_id);
-
- //Check Foreign Currency Debt Burden
- if (game.persistent_events.includes(49) && space.country === game.foreign_currency_debt_burden) {continue}
- }
- }
- }
- game.valid_spaces = valid_spaces
-
- //Check for Foreign Currency Debt Burden
- /*if (game.persistent_events.includes(49) && game.active === COM) {
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country !== game.foreign_currency_debt_burden)
- }*/
- vm_next()
-}
-
-function vm_valid_spaces_country_socio_2() {
- for (let space of spaces) {
- if (!space) continue
- if (space.space_id === game.systematization) continue
- if ((space.country === vm_operand(1) && space.socio === vm_operand(2)) || (space.country === vm_operand(1) && space.socio === vm_operand(3))) {
- game.valid_spaces.push(space.space_id);
- }
- }
- vm_next()
-}
-
-function vm_valid_spaces_region_socio() {
- let valid_spaces = []
- for (let space of spaces) {
- if (!space) continue
- if (space.space_id === game.systematization) continue
- if (space.region === vm_operand(1) && space.socio === vm_operand(2)) {
- valid_spaces.push(space.space_id);
- }
- }
- game.valid_spaces = valid_spaces
- vm_next()
-}
-
-function vm_valid_spaces_region_opp() {
- let valid_spaces = []
- for (let space of spaces) {
- if (!space) continue
- let s = space.space_id
- if ((game.active === DEM && space.region === vm_operand(1) && game.comInfl[s] > 0 ) || (game.active === COM && space.region === vm_operand(1) && game.demInfl[s] > 0 )) {
- valid_spaces.push(space.space_id);
- }
- }
- game.valid_spaces = valid_spaces
- vm_next()
-}
-
-function vm_valid_spaces_solidarity_legalised() {
- let valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- let uncontrolled = (!check_control(i) && !check_opp_control(i))
- if ((space.country === 'Poland' && uncontrolled && space.socio === 3) || (space.country === 'Poland' && uncontrolled && space.socio === 4)) {
- valid_spaces.push(space.space_id);
- }
- }
- game.valid_spaces = valid_spaces
- vm_next()
-}
-
-function vm_active_country () {
- game.valid_spaces = game.valid_spaces.filter(space_id => {
- let space = spaces.find(s => s && s.space_id === space_id);
- return space && space.country === game.vm_active_country;
- });
- vm_next()
-}
-
-function vm_take_control_prep() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_take_control'
-}
-
-function vm_take_control(space) {
- if (game.active === DEM) {
- let current_infl = game.demInfl[space]
- let opponent_infl = game.comInfl[space]
- let stability = spaces[space].stability
-
- if ((current_infl - opponent_infl) < stability) {
- game.demInfl[space] += stability - current_infl + opponent_infl
- //game.pieces[space].demCtrl = 1
- //game.pieces[space].comCtrl = 0
- }
- } else if (game.active === COM) {
- let current_infl = game.comInfl[space]
- let opponent_infl = game.demInfl[space]
- let stability = spaces[space].stability
-
- if ((current_infl - opponent_infl) < stability) {
- game.comInfl[space] += stability - current_infl + opponent_infl
- //game.pieces[space].comCtrl = 1
- //game.pieces[space].demCtrl = 0
- }
- }
- game.valid_spaces = game.valid_spaces.filter(id => id !== space)
- log(`Took control of %${space}`)
-}
-
-
-function vm_do_add_infl(space) {
- push_undo()
- //console.log('in vm_do_add_infl, space', space, 'ops', game.vm_available_ops, 'ahbr tracker', game.austria_hungary_border_reopened_tracker, 'ahbr in events', game.persistent_events.includes(58))
-
- //log(`Added 1 influence in %${space}.`)
-
- log_summary(`Added £ SP in %${space}.`)
-
- //If AHBR - check AHBR condition
- if (game.persistent_events.includes(58)) {
- if (spaces[space].country !== 'East_Germany'){
- game.austria_hungary_border_reopened_tracker = false
- }
- }
-
- // Check Genscher
- if (game.persistent_events.includes(63) && game.active === DEM && spaces[space].country === 'East_Germany') {
- game.vm_available_ops--
- log_summary(`(-1 op due to C63)`)
- } else if (check_opp_control(space)) {
- game.vm_available_ops -= 2
- //Check if Austria Hungary Border Reopened was used to place last SP in a controlled space in East Germany. If so, game.vm_available_op will be negative
- if (game.vm_available_ops < 0) {
- log_summary(`(Used +1 op from C58)`)
- }
- } else {
- game.vm_available_ops--
- }
-
- // Update influence values
- if (game.active === COM) {
- game.comInfl[space]++
- } else {
- game.demInfl[space]++
- }
-
- // Check whether spaces are controlled
- check_control_change(space)
-
- // Check Austria Hungary Border Reopened is true and condition has been met
- if (game.vm_available_ops === 0 && game.active === DEM && game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker) {
- //console.log('in award extra op')
- game.vm_available_ops ++
- log('+1 Op from C58')
- game.austria_hungary_border_reopened_tracker = false
- game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
- }
-
- // If only 1 IP remaining, may not place in opponent controlled spaces
-
- // Check for Genscher & Austria Hungary Border Reopened
-
- if (game.vm_available_ops === 1) {
-
- if (game.active === DEM) {
- //Check Genscher and AHBR
- if (game.persistent_events.includes(63) || (game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker)) {
- game.valid_spaces = game.valid_spaces.filter(n => !(check_com_control(n) && spaces[n].country !== 'East_Germany'))
- } else {
- game.valid_spaces = game.valid_spaces.filter(n => !check_com_control(n))
- }
- } else {
- game.valid_spaces = game.valid_spaces.filter(n => !check_dem_control(n))
- }
- }
-
- //Clear valid spaces if no IP remaining.
- if (game.vm_available_ops <= 0 ) {
- game.valid_spaces = []
- }
-}
-
-function vm_do_add_infl_free(space) {
- push_undo()
- //log(`Added 1 influence in %${space}.`)
-
- log_summary(`Added £ SP in %${space}.`)
-
- // Update influence values
- if (game.active === COM) {
- game.comInfl[space]++
- } else {
- game.demInfl[space]++
- }
- game.vm_available_ops--
- // Check whether spaces are controlled
- check_control_change(space)
-
-
- //console.log('game pieces:', game.pieces[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()
- log(`Added ${game.vm_available_ops} SPs in %${space}.`)
-
-
- if (game.active === COM) {
- game.comInfl[space] += game.vm_available_ops
- } else {
- game.demInfl[space] += game.vm_available_ops
- }
- check_control_change(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()
- //log(`Added 1 influence in %${space}.`)
-
- log_summary(`Added £ SP in %${space}.`)
- game.vm_available_ops --
-
- if (!game.vm_influence_added) {
- game.vm_influence_added = {};
- }
-
- if (!game.vm_influence_added[space]) {
- game.vm_influence_added[space] = 0;
- }
-
- if (game.active === COM) {
- game.comInfl[space] ++
- } else {
- game.demInfl[space] ++
- }
-
- game.vm_influence_added[space] ++
-
- //console.log('valid_spaces before update', game.valid_spaces)
- //console.log('influence added:', game.vm_influence_added[space], 'max infl', max_infl)
- if (game.vm_influence_added[space] === max_infl) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space);
- }
- check_control_change(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
- if (game.is_pwr_struggle) {
- game.state = 'vm_scare_tactics'
- } else {
- game.state = 'vm_remove_infl'
- }
-}
-
-function vm_remove_x_opp_infl() {
- game.vm_available_ops = vm_operand(1)
- game.remove_opponent_infl = true
- game.state = 'vm_remove_x_infl'
-}
-
-function vm_do_remove_infl(space) {
- push_undo()
- //log(`Removed 1 influence from %${space}.`)
- log_summary(`Removed £ SP from %${space}.`)
-
- if (!game.vm_influence_added) {
- game.vm_influence_added = {};
- }
-
- if (!game.vm_influence_added[space]) {
- game.vm_influence_added[space] = 0;
- }
- if (game.remove_opponent_infl === true) {
- if (game.active === COM) {
- game.demInfl[space]--
- if (game.demInfl[space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space);
- }
- } else {
- game.comInfl[space]--
- if (game.comInfl[space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space);
- }
- }
-
-
- } else {
- if (game.active === COM) {
- game.comInfl[space]--
- if (game.comInfl[space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space);
- }
- } else {
- game.demInfl[space]--
- if (game.demInfl[space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space);
- }
- }
- }
- check_control_change(space)
- game.vm_influence_added[space]++
- game.vm_available_ops--
- if (game.vm_available_ops===0) {game.valid_spaces = []}
-}
-
-function vm_do_remove_x_infl(space) {
- push_undo()
-
- if (game.remove_opponent_infl) {
- if (game.active === COM) {
- if (game.demInfl[space] >= game.vm_available_ops) {
- game.demInfl[space] -= game.vm_available_ops
- } else {
- game.vm_available_ops = game.demInfl[space]
- game.demInfl[space] -= game.vm_available_ops
- }
- } else {
- if (game.comInfl[space] >= game.vm_available_ops) {
- game.comInfl[space] -= game.vm_available_ops
- } else {
- game.vm_available_ops = game.comInfl[space]
- game.comInfl[space] -= game.vm_available_ops
- }
- }
- } else {
- if (game.active === COM) {
- if (game.comInfl[space] >= game.vm_available_ops) {
- game.comInfl[space] -= game.vm_available_ops
- } else {
- game.vm_available_ops = game.comInfl[space]
- game.comInfl[space] -= game.vm_available_ops
- }
- } else {
- if (game.demInfl[space] >= game.vm_available_ops) {
- game.demInfl[space] -= game.vm_available_ops
- } else {
- game.vm_available_ops = game.demInfl[space]
- game.demInfl[space] -= game.vm_available_ops
- }
- }
- }
-
- log(`Removed ${game.vm_available_ops} SPs from %${space}`)
- check_control_change(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()
- log(`Removed SP from %${space}.`)
- game.vm_available_ops --
-
-
- if (!game.vm_influence_added) {
- game.vm_influence_added = {};
- }
-
- if (!game.vm_influence_added[space]) {
- game.vm_influence_added[space] = 0;
- }
-
- if (game.active === COM) {
- game.demInfl[space] --
- if (game.demInfl[space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space)
- }
- } else {
- game.comInfl[space] --
- if (game.comInfl[space] === 0) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space)
- }
- }
-
- game.vm_influence_added[space] ++
-
- if (game.vm_influence_added[space] === max_infl) {
- game.valid_spaces = game.valid_spaces.filter(id => id !== space);
- }
-
- check_control_change(space)
- if (game.vm_available_ops === 0) {game.valid_spaces = []}
-}
-
-function vm_remove_all_infl() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_remove_all_infl'
-}
-
-function vm_do_remove_all_infl(space) {
- push_undo()
- log(`Removed all SP from %${space}.`)
-
- if (game.remove_opponent_infl === true) {
- if (game.active === COM) {
- game.demInfl[space] = 0
- } else {
- game.comInfl[space] = 0
- }
- check_control_change(space)
-
- } else {
- if (game.active === COM) {
- game.comInfl[space] = 0
- } else {
- game.demInfl[space] = 0
- }
- check_control_change(space)
- }
- game.vm_available_ops --
- game.valid_spaces = game.valid_spaces.filter(id => id !== space)
-}
-
-function vm_replace_all_infl(space_id) {
- if (game.active === DEM) {
- game.demInfl[space_id] += game.comInfl[space_id]
- game.comInfl[space_id] = 0
- } else {
- game.comInfl[space_id] += game.demInfl[space_id]
- game.demInfl[space_id] = 0
- }
- check_control_change(space_id)
-}
-
-function vm_1_support_check() {
- game.vm_available_ops = 1
- game.state = 'vm_1_support_check_prep'
-}
-
-function vm_support_check() {
- game.vm_available_ops = vm_operand(1)
- game.state = 'vm_support_check_prep'
-}
-
-function vm_support_check_modified() {
- game.vm_available_ops = vm_operand(1)
- game.support_check_modifier = vm_operand(2)
- game.state = 'vm_support_check_prep'
-}
-
-function vm_switch_infl(id){
- push_undo()
-
- game.demInfl[id] -= game.vm_available_ops
- game.comInfl[id] += game.vm_available_ops
- log(`Replaced ${pluralize(game.vm_available_ops,'SP')} in %${id}`)
- game.vm_available_ops = 0
- check_control_change(id)
-}
-
-/* ===================== EVENT SPECIFIC FUNCTIONS ========== */
-
-function vm_40th_anniversary_celebration() {
- if (game.vp < 0 ) {game.vm_available_ops = 4}
- else {game.vm_available_ops = 2}
- vm_next()
-}
-
-function vm_40th_anniversary_celebration_vp() {
- game.vp --
- log('-1VP')
- if (check_vp()) {
- return
- }
- vm_next()
-}
-
-function vm_adamec() {
- game.state = 'vm_adamec'
-}
-
-function vm_army_backs_revolution() {
- game.persistent_events = game.persistent_events.filter(n => n !== 70)
- game.playable_cards = game.playable_cards.filter(n => n !== 70)
- /*if (game.table_cards.includes(70)) {
- permanently_remove(70)
- }*/
- vm_next()
-}
-
-function vm_austria_hungary_border_reopened() {
- game.persistent_events.push(58)
- permanently_remove(58)
- game.austria_hungary_border_reopened_tracker = false
- //game.table_cards.push(58)
- //remove_from_discard(58)
- vm_next()
-}
-
-function vm_betrayal() {
- if (game.demInfl[58] > 0 ) { game.valid_spaces.push(58) }
- if (game.demInfl[65] >0 ) { game.valid_spaces.push(65) }
- game.vm_available_ops = Math.max(game.demInfl[58], game.demInfl[65])
- game.state = 'vm_switch_infl'
-}
-
-function vm_breakaway_baltic_republics() {
- log('+5 VP')
- game.vp += 5
- game.stability++
- if (check_vp()) {
- return
- }
- game.playable_cards.push(109)
- game.playable_cards = game.playable_cards.filter(n => n !== 14)
- if (!check_dem_control(56) && game.systematization !== 56) {game.valid_spaces.push(56)}
- if (!check_dem_control(70)) {game.valid_spaces.push(70)}
- vm_next()
-}
-
-function vm_brought_in_for_questioning() {
- if (game.active === COM) {
- game.active = DEM
- }
- //game.return = game.active
- game.phase = 0
- game.state = 'vm_brought_in_for_questioning'
-}
-
-function vm_bulgarian_turks_expelled(){
- game.remove_opponent_infl = true
- game.vp -= 2
- log('-2VP')
- if (check_vp()) {
- return
- }
- if (game.demInfl[70] > 0) {game.valid_spaces = [70]}
- vm_next()
-}
-
-function vm_ceausescu() {
- let adj_cluj = false
- if (game.demInfl[50] > 0 ) {adj_cluj = true}
- if (game.demInfl[54] > 0 ) {adj_cluj = true}
- if (game.demInfl[58] > 0 ) {adj_cluj = true}
- if (game.demInfl[61] > 0 ) {adj_cluj = true}
-
- if (adj_cluj && game.comInfl[61]>0) {
- game.valid_spaces = [61]
- game.vm_available_ops = 1
- //next_player()
- game.remove_opponent_infl = false
- game.state = 'vm_remove_infl'
- }
- else {vm_next()}
-}
-
-function vm_central_committee_reshuffle() {
- game.state = 'vm_central_committee_reshuffle'
-}
-
-function vm_civic_forum() {
- log('+1 VP')
- game.vp++
- if (check_vp()) {
- return
- }
- game.persistent_events.push(90)
- if (check_dem_control(31)) {
- vm_next()
- } else {
- permanently_remove(90)
- vm_return()
- }
-}
-
-function vm_common_european_home() {
- let valid_cards = [];
- for (let c of cards) {
- //if (c === null) {continue}
- if (game.active === DEM) {
- if (c && c.side === 'C') {
- valid_cards.push(c.number)
- }
- } else {
- if (c && c.side === 'D') {
- valid_cards.push(c.number)
- }
- }
- }
- game.valid_cards = valid_cards
- game.state = 'vm_common_european_home_choose'
-}
-
-function vm_dash_for_the_west() {
- game.valid_cards = []
- for (let c of game.strategy_discard) {
- if (cards[c].side === 'D' && cards[c].remove === 1 && (cards[c].playable || game.playable_cards.includes(c))) {
- game.valid_cards.push(c)
- }
- }
- game.state = 'vm_dash_for_the_west'
-}
-
-function vm_deutsche_marks() {
- let max_value = 1;
- for (let c of game.democrat_hand) {
- if (cards[c].ops > max_value) {
- max_value = cards[c].ops
- }
- }
- let valid_cards = [];
- for (let c of game.democrat_hand) {
- if (cards[c].ops === max_value) {
- valid_cards.push(c);
- }
- }
- game.valid_cards = valid_cards
- game.state = 'vm_deutsche_marks_prep'
-}
-
-function vm_domino_theory() {
- game.discard = true
- for (let card of game.strategy_discard) {
- if (scoring_cards.includes(card)) {game.valid_cards.push(card) }
- }
- game.phase = 0
- game.state = 'vm_play_event_from_discard'
-}
-
-function vm_eco_glasnost() {
- game.persistent_events.push(39)
- vm_next()
-}
-
-function vm_elena(){
- game.persistent_events.push(101)
- vm_next()
-}
-
-function vm_eliminate(space_id) {
- log(`Eliminated %${space_id}`)
- const adjacent_spaces = spaces[space_id].adjacent.filter(Number.isInteger);
-
- //console.log('adjacency before: Iasi', game.pieces[53].adjacent, 'Ploesti:', game.pieces[59].adjacent, 'Bucharesti:', game.pieces[61].adjacent)
-
- // Eliminate the democrat influence and move the communist influence to Bucuresti
- if (space_id === 61) {
- game.demInfl[space_id] = 0
- game.comInfl[space_id] = 0
- } else {
- game.demInfl[space_id] = 0
- game.comInfl[61] += game.comInfl[space_id]
- if (game.comInfl[space_id] > 0 ) {
- log(`${pluralize(game.comInfl[space_id],'Communist SP')} relocated to %61`)
- }
- game.comInfl[space_id] = 0
- }
- //Update control in the eliminated space and in Bucuresti
- check_control_change(space_id)
- check_control_change(61)
-
-}
-
-function get_adjusted_adjacency(space_id) {
- let adjacent_spaces = spaces[space_id].adjacent;
- if (adjacent_spaces.includes(game.systematization)) {
- //console.log('in get adjusted adjacency, systemization',game.systematization)
- //console.log('adjacent_spaces', adjacent_spaces)
- }
- if (game.systematization !== 0) {
- //console.log('in systematization check')
- let eliminated_space_id = game.systematization;
-
- return adjacent_spaces.map(adj_space_id => {
- if (adj_space_id === eliminated_space_id) {
- // Replace the eliminated space with its adjacencies
- //console.log('in map check, return', spaces[eliminated_space_id].adjacent)
- return spaces[eliminated_space_id].adjacent;
- }
- //console.log('2nd check, return', adj_space_id)
- return adj_space_id;
- }).flat(); // Flatten in case the eliminated space has multiple adjacencies
- }
- //console.log('final adjacent spaces', adjacent_spaces)
- return adjacent_spaces;
-}
-
-function vm_exit_visas() {
- game.state = 'vm_exit_visas'
-}
-
-function vm_foreign_currency_debt_burden() {
- log('+1VP')
- game.vp++
- if (check_vp()) {
- return
- }
- //game.table_cards.push(49)
- //remove_from_discard(49)
- game.persistent_events.push(49)
- game.state = 'vm_foreign_currency_debt_burden'
-}
-
-function vm_foreign_television() {
- for (let i = 1 ; i < spaces.length; i++) {
- if (i === 12) {continue} /*Does not apply to Dresden*/
- if (game.comInfl[i] > 0 ) {
- game.valid_spaces.push(i)
- }
- }
- vm_next()
-}
-function vm_frg_embassies() {
- game.persistent_events.push(74)
- game.table_cards.push(74)
- remove_from_discard(74)
- log('C74 in effect')
- vm_next()
-}
-
-function vm_general_strike() {
- game.persistent_events.push(5)
- game.table_cards.push(5)
- remove_from_discard(5)
- log('C5 in effect')
- vm_next()
-}
-
-function vm_genscher() {
- game.persistent_events.push(63)
- game.table_cards.push(63)
- remove_from_discard(63)
- log(`C63 in effect`)
- vm_next()
-}
-
-function vm_goodbye_lenin() {
- game.view_opp_hand = true
- game.communist_hand_red = []
- // Select Red cards to show
- for (let card of game.communist_hand) {
- if (cards[card].red) {
- game.communist_hand_red.push(card)
- }
- }
- //Check if these cards are playabl
- for (let card of game.communist_hand_red) {
- if (cards[card].playable || game.playable_cards.includes(card)) {
- game.valid_cards.push(card)
- }
- }
- game.state = 'vm_goodbye_lenin'
-}
-
-function vm_government_resigns() {
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (space.socio === 1 && game.comInfl[i] > 0 && !check_control(i)) {
- game.valid_spaces.push(i)
- }
- }
- game.remove_opponent_infl = true
- vm_next()
-}
-
-function vm_grenztruppen() {
- game.persistent_events.push(59)
- permanently_remove(59)
- //game.table_cards.push(59)
- //remove_from_discard(59)
- vm_next()
-}
-
-function vm_heal_our_bleeding_wounds() {
- let change_vp = 0
- if (game.turn <= 3) {change_vp = -3 }
- else if (game.turn <= 7) {change_vp = -1}
- else change_vp = 3
- if (change_vp >0) {
- log(`+${change_vp} VP`)
- } else {
- log(`-${change_vp} VP`)
- }
- game.vp += change_vp
- if (check_vp()) {
- return
- }
- vm_next()
-}
-
-function vm_helsinki_final_act() {
- game.persistent_events.push(26)
- vm_next()
-}
-
-function vm_honecker() {
- game.persistent_events.push(15)
- game.valid_cards = []
- for (let c of game.strategy_discard) {
- if (scoring_cards.includes(c)) {
- continue}
- else {
- game.valid_cards.push(c)
- }
- }
- game.discard = true
- game.state = 'vm_honecker'
-}
-
-function vm_inflationary_currency() {
- game.state = 'vm_inflationary_currency'
-}
-
-function vm_inflationary_currency_discard() {
- // This function starts with the player who is playing Inflationary Currency for the Event
- // Switch player and check the hand of their opponent to see if the have cards with ops > 3 to discard
- next_player()
- if (game.active === COM) {
- for (let card of game.communist_hand){
- if (get_card_ops(card) >= 3) {
- game.valid_cards.push(card)
- }
- }
- } else {
- for (let card of game.democrat_hand){
- if (get_card_ops(card) >= 3) {
- game.valid_cards.push(card)
- }
- }
- }
- game.state = 'vm_inflationary_currency_discard'
-}
-
-function vm_kiss_of_death() {
- game.state = 'vm_kiss_of_death'
-}
-
-function vm_klaus_and_komarek() {
- if (game.comInfl[29] > 0 ) {game.valid_spaces = [29]}
- vm_next()
-}
-
-function vm_kohl_proposes_reunification() {
- log('+2 VP')
- game.vp += 2
- if (check_vp()) {
- return
- }
- if (game.persistent_events.includes(86)) {
- game.vm_event = 87
- game.state = 'vm_common_european_home_play'
- } else {
- permanently_remove(87)
- vm_return()
- }
-
-}
-
-function vm_kremlin_coup() {
- log('-3 VP')
- game.vp -= 3
- game.stability ++
- if (check_vp()) {
- return
- }
- game.support_check_modifier = 1
- //countries = ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania']
- //revolutions: {'East_Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false}
- game.temp = []
- countries.forEach(country => {
- if (!game.revolutions[find_country_index(country)]) {
- game.temp.push(country)
- }
- })
- game.state = 'vm_kremlin_coup_choose_country'
-}
-
-function vm_laszlo_tokes() {
- game.persistent_events.push(73)
- game.playable_cards.push(107)
- game.state = 'vm_laszlo_tokes'
-}
-
-function vm_legacy_of_martial_law() {
- game.vm_available_ops = 1
- game.state = 'vm_switch_infl'
-}
-
-function vm_legacy_of_1968() {
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if ((!check_com_control(i) && space.country === 'Czechoslovakia')) {
- game.valid_spaces.push(space.space_id);
- }
- }
- vm_next()
-}
-
-function vm_li_peng() {
- game.persistent_events.push(53)
- //game.table_cards.push(53)
- remove_from_discard(53)
- vm_next()
-}
-
-function vm_ligachev() {
- game.persistent_events.push(99)
- vm_next()
-}
-
-function vm_malta_summit() {
- game.state = 'vm_malta_summit'
-}
-
-function vm_massacre_in_timisoara() {
- game.persistent_events = game.persistent_events.filter(n => n !== 73)
- vm_next()
-}
-
-function vm_modrow() {
- game.playable_cards.push(15)
- game.state = 'vm_modrow'
-}
-
-function vm_nagy_reburied(){
- if (game.comInfl[43] > 0) {
- game.valid_spaces.push(43)
- }
- vm_next()
-}
-
-function vm_national_salvation_front() {
- game.persistent_events.push(102)
- game.table_cards.push(102)
- remove_from_discard(102)
- vm_next()
-}
-
-function vm_nepotism() {
- game.state = 'vm_nepotism'
-}
-
-function vm_new_years_eve_party() {
- game.state = 'vm_new_years_eve_party'
-}
-
-function vm_nomenklatura() {
- game.state = 'vm_nomenklatura'
-}
-
-function vm_normalisation() {
- if (game.demInfl[27] >0) {game.valid_spaces.push(27)}
- if (game.demInfl[29] > 0) {game.valid_spaces.push(29)}
- game.remove_opponent_infl = true
- vm_next()
-}
-
-function vm_peasant_parties_revolt() {
- game.persistent_events.push(72)
- log_msg_gap('C72 in effect')
- game.table_cards.push(72)
- remove_from_discard(72)
- vm_next()
-}
-
-function vm_perestroika() {
- game.persistent_events.push(25)
- log_msg_gap('C25 in effect')
- vm_next()
-}
-
-function vm_poszgay() {
- let valid_spaces = []
- for (let space of spaces) {
- if (space && space.country === 'Hungary' && !check_dem_control(space.space_id)) {
- valid_spaces.push(space.space_id);
- }
- }
- game.valid_spaces = valid_spaces
- vm_next()
-}
-
-function vm_power_struggle() {
- //console.log('in vm_power_struggle. game.vm_event', game.vm_event, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
- game.is_pwr_struggle = true
-
- /* TO DELETE?
- //Check if Power Struggle is because of an event
- */
-
- if (game.vm_event > 0) {
- game.pwr_struggle_in = countries[scoring_cards.indexOf(game.vm_event)]
- log_h2(`C${game.vm_event}`)
- }
-/*
- //Otherwise set Power Struggle country normally
- else {
- console.log('vm_power_struggle, country set normally')
- game.pwr_struggle_in = countries[scoring_cards.indexOf(game.played_card)]
- log_h2(`C${game.played_card}`)
- }*/
-
-
- //Check for Securitate
- if (game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(70)) {
- log('C70: Democrat reveals Power Struggle cards')
- game.view_opp_hand = true
- }
- log_h2('Deal Cards')
- game.state = 'draw_power_cards'
-}
-
-function vm_presidential_visit() {
- game.persistent_events.push(65)
- //game.table_cards.push(65)
- //remove_from_discard(65)
- log_msg_gap('C65 in effect')
- vm_next()
-}
-
-function vm_prudence() {
- if (!game.prudence) {
- game.prudence = {DEM: 0, COM: 0}
- }
- if (game.active === DEM) {
- game.prudence.COM --
- log(`${game.prudence.COM} to Communist ops this turn`)
- } else {
- game.prudence.DEM --
- log(`${game.prudence.DEM} to Democrat ops this turn`)}
- vm_next()
-}
-
-function vm_public_against_violence() {
- game.valid_spaces = []
- if (game.comInfl[34] > 0 ) {game.valid_spaces.push(34)}
- vm_next()
-}
-
-function vm_reformer_rehabilitated () {
- permanently_remove(67)
- game.discard = true
- for (let card of game.strategy_discard) {
- if (!event_is_playable(card)) continue
- if (card === game.played_card) continue
- if (game.table_cards.includes(card)) continue
- if (scoring_cards.includes(card)) continue
-
- game.valid_cards.push(card)
- }
- game.state = 'vm_play_event_from_discard'
-}
-
-function vm_roundtable_talks() {
- game.persistent_events.push(17)
- game.table_cards.push(17)
- remove_from_discard(17)
- log_msg_gap('C17 in effect')
- vm_next()
-}
-
-function vm_sajudis_check() {
- if (!check_dem_control(56)) {
- game.valid_spaces.push(56)
- }
- if (!check_dem_control(70)) {
- game.valid_spaces.push(70)
- }
- vm_next()
-}
-
-function vm_sajudis() {
- game.playable_cards.push(81)
- game.stability++
- log('+1 VP')
- game.vp++
- if (check_vp()) {
- return
- }
- vm_next()
-}
-
-function vm_samizdat() {
- game.state = 'vm_samizdat'
-}
-
-function vm_securitate() {
- game.persistent_events.push(70)
- permanently_remove(70)
- //game.table_cards.push(70)
- vm_next()
-}
-
-function vm_shock_therapy() {
- game.state = 'vm_shock_therapy'
-}
-
-function vm_social_democratic_platform_adopted() {
- game.state = 'vm_social_democratic_platform_adopted'
-}
-
-function vm_solidarity_legalised() {
- log_msg_gap(`C2 in effect`)
- game.playable_cards.push(3)
- game.persistent_events.push(2)
- vm_next()
-}
-
-function vm_st_nicholas_church () {
- game.persistent_events.push(24)
- game.playable_cards.push(61)
- vm_next()
-}
-
-function vm_stasi() {
- log_msg_gap('C13 in effect')
- game.persistent_events.push(13)
- vm_next()
-}
-
-function vm_stand_fast() {
- game.persistent_events.push(100)
- if (game.active === DEM) {
- game.stand_fast = DEM
- } else {game.stand_fast = COM}
- //game.table_cards.push(100)
- vm_next()
-}
-
-function vm_systematization() {
- game.state = 'vm_systematization'
-}
-
-function vm_tank_column() {
- if (game.active === DEM) {
- game.dem_tst_position++
- game.dem_tst_attempted = 0
- } else {
- game.com_tst_position++
- game.com_tst_attempted = 0
- }
- vm_next()
-}
-
-function vm_tear_gas () {
- game.persistent_events.push(30)
- game.table_cards.push(30)
- remove_from_discard(30)
- log_msg_gap('C30 in effect')
- vm_next()
-}
-
-function vm_the_baltic_way() {
- game.playable_cards.push(84)
- game.stability++
- if (!check_dem_control(56) && game.systematization !== 56) {game.valid_spaces.push(56)}
- if (!check_dem_control(70) && game.systematization !== 70) {game.valid_spaces.push(70)}
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
-}
-
-function vm_the_chinese_solution() {
- game.state = 'vm_the_chinese_solution'
-}
-
-function vm_the_crowd_turns_against_ceausescu() {
- game.table_cards.push(54)
- remove_from_discard(54)
- game.playable_cards.push(97)
- vm_next()
-}
-
-function vm_the_monday_demonstrations() {
- if (!check_dem_control(6)) {game.valid_spaces.push(6)}
- if (!check_dem_control(9)) {game.valid_spaces.push(9)}
- vm_next()
-}
-
-function vm_the_sinatra_doctrine() {
- game.persistent_events.push(50)
- log_msg_gap('C50 in effect')
- vm_next()
-}
-
-function vm_the_third_way() {
- log('-2VP')
- vm_next()
-}
-
-function vm_the_tyrant_is_gone() {
- game.valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (game.demInfl[i] === 0 && space.country === 'Romania') {
- if (space.space_id === game.systematization) {continue}
- game.valid_spaces.push(space.space_id)
- }
- }
- game.state = 'vm_the_tyrant_is_gone'
-}
-
-
-function vm_the_tyrant_is_gone_prep() {
- game.table_cards.push(97)
- remove_from_discard(97)
- vm_next()
-}
-
-function vm_tyrant_block() {
- logi(`Has no effect after C97`)
- vm_next()
- //game.state = 'vm_tyrant_block'
-}
-
-function vm_the_wall () {
- game.persistent_events.push(9)
- //game.strategy_removed.push(9)
- //game.table_cards.push(9)
- log_msg_gap('C9 in effect')
- vm_next()
-}
-
-function vm_the_wall_must_go() {
- game.the_wall_must_go = {}
- game.the_wall_must_go['dem_wins'] = 0
- game.the_wall_must_go['com_wins'] = 0
- game.the_wall_must_go['dem_roll'] = 0
- game.the_wall_must_go['com_roll'] = 0
- game.state = 'vm_the_wall_must_go'
-}
-
-function vm_warsaw_pact_summit() {
- game.warsaw_pact_summit = true /*What does this do? */
- game.state = 'vm_warsaw_pact_summit'
-}
-
-function vm_we_are_the_people() {
- if (game.demInfl[6] > 0) {game.valid_spaces = [6]}
- game.persistent_events.push(48)
- if (!game.vm_influence_added) {
- game.vm_influence_added = {};
- }
- game.vm_influence_added[6] = 0
- game.vm_available_ops = 4
- game.state = 'vm_we_are_the_people_remove'
-}
-
-function vm_workers_revolt() {
- if (game.active === DEM) {
- for (let space of spaces) {
- if (!space) continue
- let country = space.country
- if (!game.revolutions[find_country_index(country)] && game.comInfl[space.space_id] > 0 && space.socio === 4) {
- game.valid_spaces.push(space.space_id);
- }
- }
- } else {
- for (let space of spaces) {
- if (!space) continue
- let country = space.country
- if (game.revolutions[find_country_index(country)] && game.demInfl[space.space_id] > 0 && space.socio === 4) {
- game.valid_spaces.push(space.space_id);
- }
- }
- }
- game.state = 'vm_workers_revolt'
-}
-
-function vm_yakovlev_counsels_gorbachev() {
- game.persistent_events.push(62)
- log_msg_gap('C62 in effect')
- game.table_cards.push(62)
- remove_from_discard(62)
- vm_next()
-}
-
-function vm_permanently_remove () {
- // Check if the event is being played as the result of another card, e.g. Dash for the West, is a card which should be removed, and which hasn't already been removed!
- if (game.vm_event !== 0 && cards[game.vm_event].remove === 1 && !game.strategy_removed.includes(game.vm_event)) {
- permanently_remove(game.vm_event)
- }
- if (cards[game.played_card].remove ===1 && !game.strategy_removed.includes(game.played_card)) {
- permanently_remove(game.played_card)
- } /*This means the card that called the event being played is also removed if relevant. Think this makes sense */
- vm_next()
-}
-
-function discarded_card() {
- return game.temp > 0
-}
-
-// =================== TIANANMEN SQUARE TRACK FUNCTIONS ====================
-
-function vm_tst_3() {
- log_gap('Tiananmen Square Track award')
- game.state = 'vm_tst_3_prep'
-}
-
-function vm_tst_4() {
- log_gap('Tiananmen Square Track award')
- game.vm_available_ops = 2
- game.remove_opponent_infl = true
- game.state = 'vm_tst_4'
-}
-function vm_tst_6() {
- log_h3('Tiananmen Square Track award')
- game.vm_available_ops = 1
- game.temp = 1 //Set temp to 1, so that Card 1 is called during the support check, which has 2 ops
- game.state = 'vm_tst_6'
-}
-
-function vm_tst_8() {
- game.state = 'vm_goodbye_lenin_ops' // Use this to resolve ops.
-}
-
-// ==================== POWER STRUGGLE FUNCTIONS ======================
-
-function vm_scare_tactics() {
- game.vm_active_country = game.pwr_struggle_in
- vm_next()
-}
-function vm_support_surges() {
- game.state = 'vm_support_surges_1'
-}
-
-function vm_support_falters() {
- game.vm_available_ops = 2
- game.return === game.active
- game.state = 'vm_support_falters'
-}
-
-function vm_kremlin_coup_elite() {
- game.valid_spaces=[]
- elite_spaces.forEach(space => {
- if (spaces[space].country === game.vm_active_country && !check_com_control(space)) {
- game.valid_spaces.push(space);
- }
- })
- game.state = 'vm_kremlin_coup_take_control'
-}
-
-/* ================== VM STATES ============================== */
-
-states.vm_end_event = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt () {
- view.prompt = `${clean_name(cards[this_card()].name)}: done.`
- if (game.vm_infl_to_do || game.return_state === 'vm_tst_8') {
- gen_action('done')
- } else {
- gen_action('end_round')
- }
- },
- done() {
- push_undo()
- vm_end_event()
- },
- end_round() {
- push_undo()
- game.return_state = ''
- vm_end_event()
- }
-}
-
-states.vm_take_control = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt () {
- if (game.vm_available_ops > 0 && game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: all spaces controlled. Continue.`
- gen_action('done')
- } else if (game.vm_available_ops > 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}: take control of ${event_prompt()}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Take control: done.`
- if (game.vm_infl_to_do) {
- gen_action('done')
- } else {
- gen_action('end_round')
- }
- }
- },
- infl(space) {
- push_undo()
- vm_take_control(space)
- game.vm_available_ops--
- if (game.vm_available_ops === 0) {
- game.valid_spaces = []
- vm_next()
- }
- },
- done() {
- push_undo()
- vm_next()
- },
- end_round() {
- push_undo()
- vm_next()
- }
-}
-
-states.vm_add_infl = {
- inactive: 'add Support Points.',
- prompt () {
- if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}. No available spaces remaining. Add SPs: done.`
- gen_action('done')
- }
- else if (game.vm_available_ops > 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id)
- }
- } else {
- get_end_infl_prompt()
- }
- },
- infl(space) {
- vm_do_add_infl(space)
- if (game.vm_available_ops === 0) {
- game.valid_spaces = []
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- game.vm_event_done = true
- vm_next()
- }
- },
- done () {
- push_undo()
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- game.vm_event_done = true
- vm_next()
- },
- end_round() {
- push_undo()
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- game.vm_event_done = true
- vm_next()
- }
-}
-
-states.vm_add_infl_free = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}: add SPs.`
- },
- prompt () {
- if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}. No available spaces remaining. Add SPs: done.`
- gen_action('done')
- } else if (game.vm_available_ops > 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}: add ${game.vm_available_ops} SPs to ${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- } else {
- get_end_infl_prompt()
- }
- },
- infl(space) {
- vm_do_add_infl_free(space)
- if (game.vm_available_ops === 0) {
- game.valid_spaces = []
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
-
- game.vm_event_done = true
- vm_next()
- }
- },
- done () {
- push_undo()
- game.valid_spaces = []
- game.vm_event_done = true
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- },
- end_round () {
- push_undo()
- game.valid_spaces = []
- game.vm_event_done = true
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_add_x_infl = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}: add Support Points.`
- },
-// inactive: `resolve ${cards[this_card()].name}: add influence.`,
- prompt () {
- if (game.vm_event === 101 && game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: the Romanian Elite space no longer exists.`
- gen_action('done')
- }
- else if (game.vm_available_ops > 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}: Add ${game.vm_available_ops} SPs to ${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id)
- }
- } /*else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Add SPs: done.`
- gen_action('done')
- }*/
- },
- infl(space) {
- push_undo()
- vm_do_add_x_infl(space)
- if (game.vm_available_ops === 0) {
- game.vm_event_done = true
- vm_next()
- }
- /*if (game.vm_event === (105 || 68) {
- vm_next()
- return
- } */
-
-
- //game.vm_event_done = true
- //vm_next()
- },
- done () {
- push_undo()
- game.vm_event_done = true
- vm_next()
- }
-}
-
-states.vm_add_limited_infl = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}: add Support Points.`
- },
- prompt () {
- if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) {
- if (game.vm_max_infl === 1) {
- view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_max_infl,'SP')} ${event_prompt()}.`
- }
- else {
- view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_available_ops,'SP')} to ${event_prompt()}.`
- }
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- } /*else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Add SPs: done.`
- gen_action('done')
- }*/
- },
- infl(space) {
- vm_do_add_limited_infl(space, game.vm_max_infl)
- if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
- game.valid_spaces = []
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- game.vm_event_done = true
- vm_next()
- }
- },
- /*done () {
- push_undo()
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- game.vm_event_done = true
- vm_next()
- }*/
-}
-
-states.vm_remove_infl = {
- inactive: 'remove Support Points.',
- prompt () {
- // Keep this so that there is an undo option in, e.g., Scare Tactics
- if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no further SPs to remove.`
- gen_action('done')
- return
- }
- if (game.vm_available_ops === 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
- gen_action('done')
- return
- }
- if (game.remove_opponent_infl) {
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops, 'opponent SP')}${event_prompt()}.`
- }
- else {
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}.`
- }
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- },
- infl(space) {
- push_undo()
- vm_do_remove_infl(space)
- game.vm_active_country = spaces[space].country
- if (game.vm_event !== 44) {
- if (game.vm_available_ops === 0 ) {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
- }
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-
-states.vm_remove_x_infl = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}: remove SP from ${event_prompt()}.`
- },
- prompt () {
- if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
- gen_action('done')
- } else if (game.vm_available_ops > 0) {
-
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')} from ${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- } /*else {
- if (game.vm_infl_to_do) {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done. Return control to phasing player.`
- gen_action('done')
- return
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
- gen_action('done')
- return
- }
- }*/
- },
- infl(space) {
- vm_do_remove_x_infl(space)
- /*if (game.vm_event === 68) {
- vm_next()
- return
- }*/
- if (game.vm_available_ops === 0) {
- game.vm_event_done = true
- vm_next()
- }
- /*game.vm_event_done = true
- vm_next()*/
- },
- done () {
- game.vm_event_done = true
- vm_next()
- }
-}
-
-states.vm_remove_limited_infl = {
- inactive: 'remove SP.',
- prompt () {
- if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}, no more than ${game.vm_max_infl} per space.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- } else if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no further SP to remove.`
- gen_action('done')
- } /*else {
- if (game.vm_infl_to_do) {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done. Return control to phasing player.`
- gen_action('done')
- return
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
- gen_action('done')
- return
- }
- }*/
- },
- infl(space) {
- vm_do_remove_limited_infl(space, game.vm_max_infl)
- if (game.vm_available_ops === 0) {
- game.vm_event_done = true
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
- },
- done () {
- game.vm_event_done = true
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_remove_all_infl = {
- inactive: 'remove Support Points',
- prompt () {
- if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
- gen_action('pass')
- } else if (game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: remove all SPs from ${event_prompt()}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- } /*else {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
- gen_action('done')
- }*/
- },
- infl(space) {
- vm_do_remove_all_infl(space)
- game.vm_active_country = spaces[space].country
- if (game.vm_available_ops === 0) {
- vm_next()
- }
- },
- pass() {
- push_undo()
- vm_next()
- }
-}
-
-states.vm_support_check_prep = {
- inactive: 'do support checks.',
- prompt () {
- /*if (game.vm_available_ops === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}. Support check: done.`
- gen_action('done')
- } else */
- if (game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no valid targets for support check.`
- gen_action('done')
- } else {
- //if (game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: ${event_prompt()}. ${pluralize(game.vm_available_ops, 'support check')} remaining.`
- //}
- for (let space_id of game.valid_spaces) {
- if (!space_id) continue
- gen_action_sc(space_id);
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = space
-
- // Check for Austria-Hungary Border Reopened - check on first support check only
- //First check for Monday Demonstrations - support checks will always be in East Germany
- if (game.vm_event === 61 && game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- game.state = 'vm_do_support_check'
- return
- }
-
- //Then check Austria-Hungary Border Reopened normally
- //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
- if (game.persistent_events.includes(58)) {
- if (game.active === DEM && game.vm_available_ops > 1) {
- if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
- game.state = 'vm_austria_hungary_border_reopened_check'
- return
- }
- //game.state = 'do_support_check'
- } /*else { */
- }
- game.state = 'vm_do_support_check'
- },
- done () {
- push_undo()
- game.vm_available_ops = 0
- vm_next ()
- }
-}
-
-states.vm_ceh_support_check_prep = {
- inactive: 'do support checks.',
- prompt () {
- /*if (game.vm_available_ops === 0) {
- view.prompt = 'Support checks: done.'
- gen_action('done')
- return
- }*/
- if (game.vm_available_ops > 0) {
- view.prompt = `Select a space. ${pluralize(game.vm_available_ops, 'support check')} remaining.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_sc(space_id)
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = space
-
- //Then check Austria-Hungary Border Reopened normally
- //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
- if (game.persistent_events.includes(58)) {
- if (game.active === DEM && game.vm_available_ops > 1) {
-
- if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
- game.state = 'vm_austria_hungary_border_reopened_check'
- return
- }
- //game.state = 'do_support_check'
- } /*else { */
- }
- game.state = 'vm_ceh_do_support_check'
- },
- /*done () {
- vm_next ()
- }*/
-}
-
-
-states.vm_ceh_do_support_check = {
- inactive: 'do support checks.',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(game.selected_space)
-
- game.vm_available_ops--
- if (game.vm_available_ops === 0) {
- game.valid_spaces = []
- vm_next()
- } else {
- game.state = 'vm_ceh_support_check_prep'
- return
- }
- }
-}
-
-states.vm_austria_hungary_border_reopened_check = {
- inactive: 'decide Austria-Hungary Border Reopened',
- prompt() {
- view.prompt = 'Austria-Hungary Border Reopened: will all support checks be in East Germany?'
- gen_action('yes')
- gen_action('no')
- },
- yes() {
- game.austria_hungary_border_reopened_tracker = true
- game.state = 'vm_do_support_check'
- },
- no() {
- game.state = 'vm_do_support_check'
- }
-}
-
-states.vm_1_support_check_prep = {
- inactive: 'do support checks.',
- prompt () {
- /*if (game.vm_available_ops === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}. Support check: done.`
- gen_action('done')
- } else */if (game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no valid targets for support check.`
- gen_action('done')
- } else {
- view.prompt = `${clean_name(cards[this_card()].name)}: ${event_prompt()}.`
-
- for (let space_id of game.valid_spaces) {
- if (!space_id) continue
- gen_action_sc(space_id);
- }
- }
- },
- sc(space) {
- push_undo()
- game.selected_space = space
- game.state = 'vm_do_support_check'
- },
- done () {
- push_undo()
- game.vm_available_ops = 0
- vm_next ()
- }
-}
-
-states.vm_do_support_check = {
- inactive: 'do support checks.',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(game.selected_space)
- game.vm_available_ops--
- if (game.vm_available_ops === 0) {
- game.valid_spaces = []
- vm_next()
- return
- } else {
- game.state = 'vm_support_check_prep'
- return
- }
- }
-}
-
-states.vm_tiananmen_square_attempt = {
- inactive: 'do Tiananmen Square',
- prompt () {
- /*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 = 'Tiananmen Square: roll a die'
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_tst_attempt ()
- },
- /*done () {
- vm_next()
- }*/
-}
-
-//================================== EVENT SPECIFIC STATES ======================================
-
-states.vm_adamec = {
- get inactive() {
- return `resolve ${clean_name(cards[88].name)}.`
- },
- prompt() {
- view.prompt = 'Adamec: roll a die.'
- gen_action('roll')
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Roll: D${roll}`)
- let worker_spaces = spaces.filter(space => space && space.country === 'Czechoslovakia' && space.socio === 4 && check_dem_control(space.space_id)).length
- if (worker_spaces > 0) {
- log(`-${worker_spaces} from Democrat controlled worker spaces`)
- roll -= worker_spaces
- }
- log(`Modified roll: ${roll}`)
- if (roll > 2) {
- log('Adamec succeeds')
- vm_next()
- return
- }
- log('Adamec fails: 3 or more required')
- permanently_remove(88)
- vm_return()
- }
-}
-
-states.vm_brought_in_for_questioning = {
- inactive: 'discard a card.',
- prompt() {
- /*if (game.phase === 1) {
- view.prompt = 'Discard a card: done.'
- gen_action('done')
- } else */
- if (game.democrat_hand.length === 0) {
- view.prompt = 'Brought in for Questioning. No cards to discard.'
- gen_action('pass')
- } else {
- view.prompt = 'Brought in for Questioning: you must discard a random card.'
- gen_action('discard')
- }
- },
- discard() {
- clear_undo()
- game.vm_event = discard_card(game.democrat_hand)
- game.phase = 1
- if (cards[game.vm_event].side === 'C' && (cards[game.vm_event].playable || game.playable_cards.includes(game.vm_event))) {
- //game.return = game.active
- if (!game.vm_infl_to_do) {
- if(game.round_player === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- }
- if (!is_auto_resolve(game.vm_event) && !switch_events.includes(game.vm_event)) {
- next_player()
- }
- goto_vm(game.vm_event)
- } else {
- game.return = DEM
- vm_return()
- }
- },
- pass() {
- log('No cards to discard')
- vm_return()
- },
- /*done() {
- vm_return()
- }*/
-}
-
-states.vm_central_committee_reshuffle = {
- get inactive() {
- return `resolve ${clean_name(cards[57].name)}.`
- },
- prompt() {
- if (game.revolutions.every(n => n === true)) {
- view.prompt = 'Central Committee Reshuffle: no countries to choose.'
- gen_action('pass')
- } else {
- view.prompt = 'Central Committee Reshuffle: choose a country to add SPs.'
- if (!game.revolutions[0]) {gen_action('poland')}
- if (!game.revolutions[1]) {gen_action('hungary')}
- if (!game.revolutions[2]) {gen_action('east_germany')}
- if (!game.revolutions[3]) {gen_action('bulgaria')}
- if (!game.revolutions[4]) {gen_action('czechoslovakia')}
- if (!game.revolutions[5]) {gen_action('romania')}
- }
- },
- east_germany() {
- push_undo()
- game.vm_active_country = "East_Germany"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [1,2,3,4,5,6,7,8,9,10,11,12]
- vm_next()
- },
- poland() {
- push_undo()
- game.vm_active_country = "Poland"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [13,14,15,16,17,18,19,20,21,22,23,24,25,26]
- vm_next()
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = "Czechoslovakia"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [27,28,29,30,31,32,33,34,35,36,37]
- vm_next()
- },
- hungary() {
- push_undo()
- game.vm_active_country = "Hungary"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [38,39,40,41,42,43,44,45,46,47,48,49]
- vm_next()
- },
- romania() {
- push_undo()
- game.vm_active_country = "Romania"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [50,51,52,53,54,55,56,57,58,59,60,61,62,63]
- game.valid_spaces = game.valid_spaces.filter(space => space !== game.systematization)
- vm_next()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = "Bulgaria"
- log(`Chose ${country_name(game.vm_active_country)}`)
- game.valid_spaces = [64,65,66,67,68,69,70,71,72,73,74,75]
- vm_next()
- },
- pass() {
- log('Passed')
- vm_return()
- }
-
-}
-
-states.vm_common_european_home_choose = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = `Common European Home: play an opponent's card, event does not occur.`
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- },
- card(card) {
- push_undo()
- //log(`Played with C${cards[card].number}`)
- game.valid_cards = []
- silent_discard(card)
- game.vm_event = card
- game.state = 'vm_common_european_home_play'
- }
-}
-
-states.vm_common_european_home_play = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- view.prompt = `Play ${clean_name(cards[this_card()].name)} for:`
- gen_action('influence')
- gen_action('support_check')
- if (game.active === DEM && game.vm_event === 87 ) {
- return /*Special condition if card is actually Kohl Proposes Reunification*/
- }
- /*if (game.active === DEM && game.dem_tst_attempted_this_turn === 0 || game.active === COM && game.com_tst_attempted_this_turn === 0) {
- gen_action('tst')
- } */
- },
- influence(){
- push_undo()
- log_gap(`Played C${cards[game.vm_event].number} to place SPs`)
- game.vm_available_ops = cards[game.vm_event].ops
- valid_spaces_infl()
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- log_gap(`Played C${cards[game.vm_event].number} for support checks`)
- game.vm_available_ops = 2
- game.state = 'vm_ceh_support_check_prep'
- valid_spaces_sc()
- },
- tst() {
- push_undo()
- log_gap(`Played C${cards[game.vm_event].number} to the Tiananmen Square Track`)
- game.state = 'vm_tiananmen_square_attempt'
- }
-}
-
-states.vm_dash_for_the_west = {
- get inactive() {
- return `resolve ${clean_name(cards[36].name)}.`
- },
- prompt() {
- /* if (game.phase === 1) {*/
- view.prompt = 'Dash for the West: roll a die'
- gen_action('roll')
- /*} else {
- view.prompt = 'Dash for the West: roll a die. Done.'
- gen_action('done')
- }*/
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Roll: D${roll}`)
- let com_control = check_presence('East_Germany').com_spaces
-
- if (roll > com_control) {
- log(`Success. More than the ${com_control} Communist controlled spaces in East Germany`)
- log('+1 VP')
- game.vp++
- if (check_vp()) {
- return
- }
- game.discard = true
- game.state = 'vm_play_event_from_discard'
- } else {
- log(`Fail: more than a ${com_control} required`)
- //game.phase++
- vm_next()
- }
- },/*
- done() {
- vm_next()
- }*/
-}
-
-states.vm_play_event_from_discard = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_cards.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no valid cards in discard.`
- gen_action('pass')
- } else if (game.temp === 0) {
- view.prompt = `${event_prompt()}.`
- for (let card of game.valid_cards) {
- gen_action('pass')
- gen_action_card(card)
- }
- } /*else {
- view.prompt = 'Choose a card: done.'
- gen_action('done')
- }*/
- },
- card(card) {
- push_undo()
- log(`Chose C${cards[card].number}`)
- game.vm_event = card
- game.vm_available_ops = cards[card].ops
- game.discard = false
- //game.return = game.active Does turning this off cause problems?
- if (switch_events.includes(card)) {next_player()}
- goto_vm(card)
- },
- pass(){
- push_undo()
- if (game.valid_cards.length === 0) {
- log('No valid cards to choose')
- } else{
- log('Did not choose a card')
- }
- vm_next()
- },
-/* done(){
- push_undo()
- game.discard = false
- vm_next()
- }*/
-}
-
-states.vm_deutsche_marks_prep = {
- inactive: 'choose a card.',
- prompt() {
- if (game.valid_cards.length === 0) {
- view.prompt = 'Deutsche Marks: no cards to give.'
- gen_action('pass')
- } else {
- view.prompt = 'Deutsche Marks: choose a card to give.'
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- }
- },
- card(card) {
- push_undo()
- log(`Gave C${cards[card].number}`)
- game.valid_cards = []
- silent_discard(card)
- //next_player()
- game.state = 'vm_deutsche_marks_confirm'
- game.vm_event = card
- },
- pass() {
- push_undo()
- vm_next()
- }
-}
-
-states.vm_deutsche_marks_confirm = {
- inactive: 'choose a card.',
- prompt() {
- view.prompt = `Deutsche Marks: gave ${cards[game.vm_event].name}.`
- gen_action('done')
- },
- done() {
- next_player()
- game.state = 'vm_deutsche_marks'
- }
-}
-
-states.vm_deutsche_marks = {
- get inactive() {
- return `resolve ${clean_name(cards[20].name)}.`
- },
- prompt() {
- if(cards[game.vm_event].side === 'C' && (cards[game.vm_event].playable || game.playable_cards.includes(game.vm_event))) {
- view.prompt = `Deutsche Marks: you must play ${clean_name(cards[this_card()].name)} for the event.`
- gen_action('event')
- } else {
- view.prompt = `Deutsche Marks: play ${clean_name(cards[this_card()].name)} for:`
- gen_action('influence')
- gen_action('support_check')
- if (game.com_tst_attempted_this_turn === 0) {
- gen_action('tst')
- }
- }
- },
- event() {
- push_undo()
- log(`Played C${cards[game.vm_event].number} for the event`)
- if (!game.vm_infl_to_do) {
- game.return = game.active
- }
- goto_vm(game.vm_event)
- },
- influence() {
- push_undo()
- log(`Played C${cards[game.vm_event].number} to place SPs`)
- game.vm_available_ops = get_card_ops(game.vm_event)
-
- /*cards[game.vm_event].ops
- if (game.persistent_events.includes(25)) {game.vm_available_ops++ }
- if (game.prudence.COM && game.prudence.COM < 0 ) {
- game.vm_available_ops += game.prudence.COM
- }*/
- valid_spaces_infl()
- game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- log_gap(`Played C${cards[game.vm_event].number} for support checks`)
- game.vm_available_ops = 2
- game.state='vm_support_check_prep'
- valid_spaces_sc()
- },
- tst() {
- push_undo()
- log_gap(`Played C${cards[game.vm_event].number} to the Tiananmen Square Track`)
- game.state='vm_tiananmen_square_attempt'
- }
-}
-
-states.vm_exit_visas = {
- get inactive() {
- return `resolve ${clean_name(cards[75].name)}.`
- },
- prompt() {
- view.prompt = 'Exit Visas: you may discard cards from your hand and draw replacements.'
- for (let card of game.democrat_hand) {
- gen_action_card(card)
- }
- if (game.temp === 0) {
- gen_action('pass')
- } else {
- gen_action('done')
- }
- },
- card(card){
- push_undo()
- discard(card)
- game.temp++
- },
- pass() {
- push_undo()
- game.state = 'vm_exit_visas_finish'
- },
- done() {
- push_undo()
- game.state = 'vm_exit_visas_finish'
- }
-}
-
-states.vm_exit_visas_finish = {
- get inactive() {
- return `resolve ${clean_name(cards[75].name)}.`
- },
- prompt() {
- if (game.temp > 0 ) {
- view.prompt = 'Exit Visas: draw replacement cards.'
- gen_action('draw')
- } /*else {
- view.prompt = 'Exit Visas. Draw 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
- vm_next()
- },
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_foreign_currency_debt_burden = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Choose a country. The Communist may not make support checks there for the rest of the turn.'
- gen_action('east_germany')
- gen_action('poland')
- gen_action('czechoslovakia')
- gen_action('hungary')
- gen_action('bulgaria')
- },
- east_germany() {
- push_undo()
- game.foreign_currency_debt_burden = 'East_Germany'
- log('Selected East Germany')
- vm_next()
- },
- poland() {
- push_undo()
- game.foreign_currency_debt_burden = 'Poland'
- log('Selected Poland')
- vm_next()
- },
- czechoslovakia() {
- push_undo()
- game.foreign_currency_debt_burden = 'Czechoslovakia'
- log('Selected Czechoslovakia')
- vm_next()
- },
- hungary() {
- push_undo()
- game.foreign_currency_debt_burden = 'Hungary'
- log('Selected Hungary')
- vm_next()
- },
- bulgaria() {
- push_undo()
- game.foreign_currency_debt_burden = 'Bulgaria'
- log('Selected Bulgaria')
- vm_next()
- }
-}
-
-states.vm_goodbye_lenin = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_cards.length > 0 ) {
- view.prompt = `Play a red event from your opponent's hand, or play Goodbye Lenin for operations.`
- for (let card of game.valid_cards) {
- gen_action_card(card)
- gen_action('ops')
- }
- } else {
- view.prompt = 'Communist has no red events. Play Goodbye Lenin for operations.'
- gen_action('ops')
- }
- },
- card(card) {
- push_undo()
- log(`Chose to play C${card} for the event`)
- let card_index = game.communist_hand.indexOf(card)
- game.communist_hand.splice(card_index, 1)
- game.vm_event = card
- game.view_opp_hand = false
- goto_vm(card)
- },
- ops() {
- push_undo()
- if (game.valid_cards.length === 0) {
- logi('No red events')
- }
- log('C46 played for operations')
- game.view_opp_hand = false
- game.state = 'vm_goodbye_lenin_ops'
- }
-}
-
-states.vm_goodbye_lenin_ops = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- view.prompt = `Play ${clean_name(cards[this_card()].name)} for:`
- gen_action('influence')
- gen_action('support_check')
- if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 )) {
- gen_action('tst')
- }
- },
- influence(){
- push_undo()
- game.vm_available_ops = get_card_ops(this_card())
- /*if (game.persistent_events.includes(50)) {
- log(`+1 from C50`)
- game.vm_available_ops++
- }*/
- valid_spaces_infl()
-
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- game.vm_available_ops = 2
- game.state = 'vm_support_check_prep'
- valid_spaces_sc()
- },
- tst() {
- push_undo()
- game.state = 'vm_tiananmen_square_attempt'
- }
-}
-
-states.vm_honecker = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_cards.length === 0 && game.temp === 0) {
- view.prompt = 'Honecker: no valid cards to choose.'
- gen_action('pass')
- } else
- if (game.temp === 0) {view.prompt = 'Honecker: choose a card to add to your hand.'
- for (let card of game.valid_cards) {
- gen_action_card(card)
- gen_action('pass')
- }
- } /*else {
- view.prompt = 'Honecker. Choose a card: done.'
- gen_action('done')
- }*/
- },
- card(card) {
- push_undo()
- game.valid_cards = []
- log(`Took C${cards[card].number} into hand`)
- game.temp = card
- let card_index = game.strategy_discard.indexOf(card)
- game.strategy_discard.splice(card_index, 1)
- game.communist_hand.push(card)
- vm_next()
- },
- pass(){
- log('Did not take a card')
- game.discard = false
- vm_next()
- },
- /*done(){
- if (game.temp === 0) {
- log('Did not take a card')
- }
- game.discard = false
- vm_next()
- } */
-
-}
-
-states.vm_inflationary_currency = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if ((game.active === COM && game.revolutions.every(n => n === false)) || (game.active === DEM && game.revolutions.every(n => n === true))) {
- view.prompt = 'Inflationary Currency: no countries to choose.'
- gen_action('pass')
- } else {
- view.prompt = 'Inflationary Currency: choose a country where your opponent has power.'
- if (game.active === DEM) {
- if (!game.revolutions[0]) {gen_action('poland')}
- if (!game.revolutions[1]) {gen_action('hungary')}
- if (!game.revolutions[2]) {gen_action('east_germany')}
- if (!game.revolutions[3]) {gen_action('bulgaria')}
- if (!game.revolutions[4]) {gen_action('czechoslovakia')}
- if (!game.revolutions[5]) {gen_action('romania')}
- } else {
- if (game.revolutions[0]) {gen_action('poland')}
- if (game.revolutions[1]) {gen_action('hungary')}
- if (game.revolutions[2]) {gen_action('east_germany')}
- if (game.revolutions[3]) {gen_action('bulgaria')}
- if (game.revolutions[4]) {gen_action('czechoslovakia')}
- if (game.revolutions[5]) {gen_action('romania')}
- }
- }
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`Chose ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- pass() {
- log('Passed')
- vm_return()
- }
-}
-
-states.vm_inflationary_currency_discard = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_cards.length === 0 ) {
- view.prompt = 'Inflationary Currency: no valid cards to discard. You must pass.'
- gen_action('pass')
- } else if (game.temp === 0 ) {
- view.prompt = 'Inflationary Currency: you may discard a 3 op or higher value card to cancel the support check.'
- gen_action('pass')
- for (let card of game.valid_cards) {
- gen_action_card(card)
- }
- } /*else {
- view.prompt = 'Inflationary Currency. Discard a card: done.'
- gen_action('done')
- } */
- },
- card(card) {
- push_undo()
- discard(card)
- game.temp = card
- if (!game.vm_infl_to_do) {
- if(game.round_player === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- }
- vm_next()
- },
- pass() {
- push_undo()
- log('Did not discard')
- next_player()
- game.vm_available_ops = 1
- vm_next()
- //game.state = 'vm_support_check_prep'
- },
- done() {
- if (!game.vm_infl_to_do) {
- if(game.round_player === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- }
- vm_next()
- }
-}
-
-
-states.vm_kiss_of_death = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.communist_hand.length === 0) {
- view.prompt = 'Kiss of Death. No cards to discard.'
- gen_action('pass')
- } else {
- view.prompt = 'Kiss of Death: you must randomly discard a card.'
- gen_action('discard')
- }
- },
- discard() {
- clear_undo()
- game.vm_event = discard_card(game.communist_hand)
- //Only switch player if a playable non-communist event. Common European Home is not playable here
- if (cards[game.vm_event].side !== "C" && event_is_playable(game.vm_event) && game.vm_event !== 21) {
- next_player()
- game.state = 'vm_kiss_of_death_finish'
- } else {
- log('Event does not occur')
- vm_next()
- }
- },
- pass() {
- log('No card to discard')
- vm_next()
- }
-}
-
-states.vm_kiss_of_death_finish = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.vm_event > 0 && game.vm_event !== 21 && (cards[game.vm_event].side === 'D' || cards[game.vm_event].side === 'N')) {
- view.prompt = `Play ${clean_name(cards[game.vm_event].name)} for the event.`
- console.log('kiss of death before event button: game.stategy_discard', game.strategy_discard)
- gen_action('event')
- } else {
- view.prompt = 'Event does not occur.'
- gen_action('done')
- }
- },
- event() {
- //game.return = game.active
- // Remove game.vm_event from the discard
- //game.strategy_discard = game.strategy_discard.filter(n => n !== game.vm_event)
-
- goto_vm(game.vm_event)
- },
- done() {
- vm_next()
- }
-}
-
-states.vm_kremlin_coup_choose_country = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- if (game.temp.length > 0) {
- view.prompt = 'Kremlin Coup! Select a country where the Communist retains power.'
- for (let country of countries) {
- if (game.temp.includes(country)) {
- gen_action(`${country.toLowerCase()}`)
- }
- }
- } else {
- view.prompt = 'Kremlin Coup! There are no countries where the Communist retains power.'
- gen_action('done')
- }
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- log(`${country_name(game.vm_active_country)}:`)
- vm_kremlin_coup_elite()
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`${country_name(game.vm_active_country)}:`)
- game.temp = game.temp.filter(country => country !== game.vm_active_country)
- vm_kremlin_coup_elite()
- },
- done() {
- game.temp = 0
- vm_next()
- }
-}
-
-states.vm_kremlin_coup_take_control = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_spaces.includes(game.systematization)) {
- view.prompt = `Kremlin Coup! ${country_name(game.vm_active_country)}'s Elite space no longer exists.`
- gen_action('done')
- }
- else if (game.valid_spaces.length === 0){
- view.prompt = `Kremlin Coup! ${country_name(game.vm_active_country)}'s Elite space is already controlled.`
- gen_action('done')
- } else {
- view.prompt = `Kremlin Coup! Take control of the Elite space in ${country_name(game.vm_active_country)}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- }
- },
- infl(space) {
- push_undo()
- vm_take_control(space)
- if (game.vm_active_country === 'East_Germany') {game.selected_space = 3 }
- if (game.vm_active_country === 'Poland') {game.selected_space = 17}
- if (game.vm_active_country === 'Czechoslovakia') {game.selected_space = 29}
- if (game.vm_active_country === 'Hungary') {game.selected_space = 45}
- if (game.vm_active_country === 'Romania') {game.selected_space = 61}
- if (game.vm_active_country === 'Bulgaria') {game.selected_space = 68}
- game.state = 'vm_kremlin_coup_sc_prep'
- },
- done() {
- push_undo()
- if (game.vm_active_country === 'East_Germany') {game.selected_space = 3 }
- if (game.vm_active_country === 'Poland') {game.selected_space = 17}
- if (game.vm_active_country === 'Czechoslovakia') {game.selected_space = 29}
- if (game.vm_active_country === 'Hungary') {game.selected_space = 45}
- if (game.vm_active_country === 'Romania') {game.selected_space = 61}
- if (game.vm_active_country === 'Bulgaria') {game.selected_space = 68}
- game.state = 'vm_kremlin_coup_sc_prep'
- }
-}
-
-states.vm_kremlin_coup_sc_prep = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = `Kremlin Coup! Conduct a support check in ${country_name(game.vm_active_country)}'s Bureaucratic space.`
- gen_action_sc(game.selected_space);
- },
- sc(space) {
- //game.selected_space = space
- push_undo()
- game.state = 'vm_kremlin_coup_sc'
- }
-}
-
-states.vm_kremlin_coup_sc = {
- inactive: 'do support checks',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(game.selected_space)
- if (game.temp.length > 0 ){
- game.state = 'vm_kremlin_coup_choose_country'
- } else {
- //game.state = 'vm_kremlin_coup_end'
- vm_next()
- }
- }
-}
-/*
-states.vm_kremlin_coup_end = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- view.prompt = `${clean_name(cards[this_card()].name)} Support checks: done.`
- gen_action('done')
- },
- done() {
- vm_next()
- }
-}
-*/
-states.vm_laszlo_tokes = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = `Laszlo Tokes. Choose to:`
- gen_action('influence')
- gen_action('support_check')
- },
- influence(){
- push_undo()
- game.vm_available_ops = get_card_ops(73)
- valid_spaces_infl()
- game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania')
- game.phase = 3
- vm_next()
- //game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- game.vm_available_ops = 2
- //game.state = 'vm_support_check_prep'
- valid_spaces_sc()
- game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania')
- vm_next()
- }
-}
-
-states.vm_switch_infl = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_spaces.length === 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: No SPs to remove.`
- gen_action('pass')
- } else {
- /*if (game.vm_available_ops > 0 ) {*/
- view.prompt = `${clean_name(cards[game.played_card].name)}: ${event_prompt()}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- } /*else {
- view.prompt = 'Influence replaced.'
- gen_action('done')
- }*/
- },
- infl(space) {
- push_undo()
- vm_switch_infl(space)
- if (game.vm_available_ops === 0) {
- game.valid_spaces = []
- }
- vm_next()
- },
- pass() {
- vm_next()
- }
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_malta_summit = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- /*if (game.phase === 1) {*/
- view.prompt = 'Malta Summit: roll a die.'
- gen_action('roll')
- /*} else {
- view.prompt = 'Done.'
- gen_action('done')
- }*/
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Roll: D${roll}`)
- if (game.stability > 0) {
- log(`+${game.stability} from USSR Stability Track`)
- log(`Modified roll: ${roll + game.stability}`)
- }
- if (roll + game.stability > 3) {
- log('Summit successful')
- game.vp += 3
- log('+3 VP')
- if (check_vp()) {
- return
- }
- if (game.comInfl[12] > 0 ) {game.valid_spaces.push(12)}
- if (game.comInfl[15] > 0 ) {game.valid_spaces.push(15)}
- if (game.comInfl[27] > 0 ) {game.valid_spaces.push(27)}
- if (game.comInfl[43] > 0 ) {game.valid_spaces.push(43)}
- if (game.comInfl[51] > 0 ) {game.valid_spaces.push(51)}
- if (game.comInfl[69] > 0 ) {game.valid_spaces.push(69)}
- //game.vm_available_ops = 5
- game.remove_opponent_infl = true
- vm_next()
- }
- else {
- log('Summit failed. Required 4 or more')
- //game.phase++
- vm_goto_step(vm_permanently_remove)
- }
- },
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_modrow = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = `Modrow: roll a die.`
- gen_action('roll')
- },
- roll(){
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- let dem_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_dem_control(space.space_id)).length
- if (roll > dem_spaces) {
- log(`Roll: D${roll}`)
- log(`Success. More than the ${dem_spaces} Democratically controlled spaces`)
- vm_next()
- } else {
- log(`Roll: D${roll}`)
- log(`Fail. More than ${dem_spaces} required`)
- permanently_remove(83)
- vm_return()
- }
- }
-}
-
-states.vm_nepotism = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- //if (game.phase === 1 ) {
- view.prompt = 'Nepotism: roll a die.'
- gen_action('roll')
- /*} else {
- view.prompt = 'Roll a die: done.'
- gen_action('done')
- }*/
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- if (roll < 3) {
- log(`Roll: D${roll} adds 4 SPs`)
- game.vm_available_ops = 4}
- else if (roll < 5 ) {
- log(`Roll: D${roll} adds 3 SPs`)
- game.vm_available_ops = 3}
- else {
- log(`Roll: D${roll} adds 1 SP`)
- game.vm_available_ops = 1}
- //game.phase = 2
- vm_next()
- },
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_new_years_eve_party = {
- get inactive() {
- return `resolve ${clean_name(cards[104].name)}.`
- },
- prompt() {
- view.prompt = 'Choose whether the game ends at the end of this turn.'
- gen_action('end')
- gen_action('continue')
- },
- end() {
- push_undo()
- game.persistent_events.push(104)
- log('Chooses to end the game. There will be no final scoring')
- let power = game.revolutions.filter(value => value === false).length
- if (power > 3) {
- log(`Communist holds power in ${power} countries. -3 VP`)
- game.vp -= 3
- } else {
- log(`Communist holds power in ${power} countries. +3 VP`)
- game.vp += 3
- }
- if (check_vp()) {
- return
- }
- //game.table_cards.push(104)
- permanently_remove(104)
- vm_next()
- },
- continue() {
- push_undo()
- log('Chooses to continue')
- permanently_remove(104)
- vm_next()
- }
-}
-
-states.vm_nomenklatura = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Nomenklatura: choose to remove all Democratic SPs from Elite spaces or add 3 SPs to any Elite space(s).'
- gen_action('remove')
- gen_action('add')
- },
- remove() {
- push_undo()
- game.valid_spaces = []
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
-
- if (space.socio === 1 && game.demInfl[i] > 0) {
- game.valid_spaces.push(space.space_id)
- }
- }
- game.vm_available_ops = game.valid_spaces.length
- game.remove_opponent_infl = true
- game.state = 'vm_nomenklatura_remove'
- },
- add() {
- push_undo()
- game.valid_spaces = []
- for (let space of spaces) {
- if (!space) continue
- if (space.socio === 1) {
- game.valid_spaces.push(space.space_id)
- }
- }
- check_systematization()
- game.vm_available_ops = 3
- game.state = 'vm_nomenklatura_add'
- }
-}
-
-states.vm_nomenklatura_remove = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_spaces.length === 0 ) {
- view.prompt = 'Nomenklatura. No SPs to remove: pass.'
- gen_action('pass')
- } else {
- view.prompt = 'Nomenklatura: remove all Democratic SPs from Elite spaces.'
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- }
- },
- infl(space) {
- push_undo()
- vm_do_remove_all_infl(space)
- if (game.valid_spaces.length === 0) {
- vm_next()
- }
- },
- pass() {
- push_undo()
- vm_next()
- }
-}
-
-states.vm_nomenklatura_add = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- /*if (game.vm_available_ops === 0 || game.valid_spaces.length === 0 ) {
- view.prompt = 'Nomenklatura. Add SPs: done.'
- gen_action('done')
- } else { */
- view.prompt = `Nomenklatura: add 3 SPs to any Elite space(s). ${pluralize(game.vm_available_ops, 'SP')} remaining.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- //}
- },
- infl(space) {
- push_undo()
- vm_do_add_infl_free(space)
- if (game.vm_available_ops === 0 ) {
- game.valid_spaces = []
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
- },
-/* done() {
- push_undo()
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }*/
-}
-
-states.vm_samizdat = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Samizdat: you may set aside a card from your hand and draw a replacement.'
- for (let card of game.democrat_hand) {
- gen_action_card(card)
- }
- gen_action('pass')
- },
- card(card) {
- push_undo()
- game.samizdat_card = card
- game.democrat_hand = game.democrat_hand.filter(c => c !== card)
- log('Set aside a card')
- game.state = 'vm_samizdat_finish'
- },
- pass() {
- push_undo()
- //if (game.samizdat_card > 0) {game.state = 'vm_samizdat_finish'}
- /*else { */
- log('Did not set aside a card')
- vm_next()
- //}
- }
-}
-
-states.vm_samizdat_finish = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- /*if (game.phase ) {
- view.prompt = 'Samizdat: done.'
- gen_action('done')
- } else {*/
- view.prompt = 'Draw a replacement card.'
- gen_action('draw')
- //}
- },
- draw() {
- clear_undo()
- game.democrat_hand.push(draw_card(game.strategy_deck))
- vm_next()
- //game.phase ++
- },
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_shock_therapy = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.revolutions.every(n => n === false)) {
- view.prompt = 'Shock Therapy: no countries to choose.'
- gen_action('pass')
- } else {
- if (game.vm_active_country === '' ) {
- view.prompt = 'Shock Therapy: choose a country where you hold Power:'
- if (game.revolutions[0]) {gen_action('poland')}
- if (game.revolutions[1]) {gen_action('hungary')}
- if (game.revolutions[2]) {gen_action('east_germany')}
- if (game.revolutions[3]) {gen_action('bulgaria')}
- if (game.revolutions[4]) {gen_action('czechoslovakia')}
- if (game.revolutions[5]) {gen_action('romania')}
- } /*else if (game.phase === 2) {
- view.prompt = 'Shock Therapy: done.'
- gen_action('done')
- } */
- else {
- view.prompt = 'Shock Therapy: roll a die.'
- gen_action('roll')
- }
- }
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`Chose ${country_name(game.vm_active_country)}`)
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- let worker_farmer = 0
- for (let space of spaces) {
- if (space && space.country === game.vm_active_country && check_com_control(space.space_id) && (space.socio === 3 || space.socio === 4)) {
- worker_farmer++
- }
- }
- log(`Roll: D${roll}`)
- log(`-${worker_farmer} from Communist controlled Worker and Farmer spaces`)
- log(`Modified roll: ${roll - worker_farmer}`)
- if ((roll - worker_farmer) > 2) {
- log('C93 is successful. +3 VP')
- vm_next()
- } else {
- log('C93 is unsuccessful. Required 3 or more')
- //game.phase++
- permanently_remove(93)
- vm_return()
- }
- },
- pass() {
- log('Passed')
- vm_return()
- }
- /*done() {
- permanently_remove(93)
- vm_return()
- }*/
-}
-
-states.vm_social_democratic_platform_adopted = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.revolutions.every(n => n === false)) {
- view.prompt = 'Social Democratic Platform Adopted: no countries to choose.'
- gen_action('pass')
- } else {
- view.prompt = 'Select a country where the Democrat holds Power.'
- if (game.revolutions[0]) {gen_action('poland')}
- if (game.revolutions[1]) {gen_action('hungary')}
- if (game.revolutions[2]) {gen_action('east_germany')}
- if (game.revolutions[3]) {gen_action('bulgaria')}
- if (game.revolutions[4]) {gen_action('czechoslovakia')}
- if (game.revolutions[5]) {gen_action('romania')}
- }
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()},
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()},
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`Selected ${country_name(game.vm_active_country)}`)
- vm_next()
- },
- pass() {
- log('Passed')
- vm_return()
- }
-}
-
-states.vm_systematization = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- /*if (game.systematization === 0) { */
- view.prompt = 'Systematization: eliminate a space in Romania.'
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- /*} else {
- view.prompt = 'Systematization: done.'
- gen_action('done')
- }*/
- },
- infl(space) {
- push_undo()
- vm_eliminate(space)
- game.valid_spaces = []
- game.systematization = space
- game.persistent_events.push(69)
- vm_next()
- },
-/* done() {
- vm_next()
- } */
-}
-
-states.vm_the_chinese_solution = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'The Chinese Solution: you may give up 3 VP to conduct support checks in a country where you hold power.'
- if (!game.revolutions[0]) {gen_action('poland')}
- if (!game.revolutions[1]) {gen_action('hungary')}
- if (!game.revolutions[2]) {gen_action('east_germany')}
- if (!game.revolutions[3]) {gen_action('bulgaria')}
- if (!game.revolutions[4]) {gen_action('czechoslovakia')}
- if (!game.revolutions[5]) {gen_action('romania')}
- gen_action('pass')
- },
- east_germany() {
- push_undo()
- game.vm_active_country = 'East_Germany'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- poland() {
- push_undo()
- game.vm_active_country = 'Poland'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- czechoslovakia() {
- push_undo()
- game.vm_active_country = 'Czechoslovakia'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- hungary() {
- push_undo()
- game.vm_active_country = 'Hungary'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- romania() {
- push_undo()
- game.vm_active_country = 'Romania'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- bulgaria () {
- push_undo()
- game.vm_active_country = 'Bulgaria'
- log(`Chose ${country_name(game.vm_active_country)}`)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- vm_next()
- },
- pass() {
- push_undo()
- permanently_remove(96)
- vm_return()
- }
-}
-
-states.vm_the_tyrant_is_gone = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (!game.the_tyrant_is_gone) {
- view.prompt = 'The Tyrant is Gone: Select a space in Romania for the Ceausescus to flee to.'
- for (let space_id of game.valid_spaces) {
- if (!space_id) continue
- gen_action_infl(space_id);
- }
- } else {
- view.prompt = 'The Tyrant is Gone: done.'
- gen_action('done')
- }
- },
- infl(space) {
- push_undo()
- log(`The Ceausescus flee to %${space}`)
- game.the_tyrant_is_gone = space
- game.valid_spaces = []
- game.persistent_events.push(97)
-
- // vm_next()
- },
- done () {
- vm_next()
- }
-}
-/*
-states.vm_tyrant_block ={
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- view.prompt = `${clean_name(cards[this_card()].name)} has no effect after The Tyrant Has Gone.`
- gen_action('done')
- },
- done() {
- push_undo()
- vm_next()
- }
-}*/
-
-
-states.vm_the_wall_must_go = {
- get inactive() {
- return `resolve ${clean_name(cards[this_card()].name)}.`
- },
- prompt() {
- /*if (game.the_wall_must_go['dem_wins'] === 2 || game.the_wall_must_go['com_wins'] === 2) {
- view.prompt = '"The Wall Must Go!" Rolls: done.'
- gen_action('done')
- } else { */
- view.prompt = ('The Wall Must Go! Roll a die.')
- gen_action('roll')
- //}
- },
- roll() {
- clear_undo()
- let attempt = game.the_wall_must_go['dem_wins'] + game.the_wall_must_go['com_wins']
- if (game.the_wall_must_go['dem_roll'] === 0 && game.the_wall_must_go['com_roll'] === 0) {
- log_h3(`Round ${attempt+1}`)
- }
-
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Roll: D${roll}`)
- if (game.active === DEM) {
- let controlled_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_dem_control(space.space_id)).length
- if (controlled_spaces > 0) {
- log(`+${controlled_spaces} from controlled spaces in East Germany`)
- log(`Modified roll: ${roll + controlled_spaces}`)
- roll += controlled_spaces
- }
- game.the_wall_must_go['dem_roll'] = roll
- } else {
- let controlled_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_com_control(space.space_id)).length
- if (controlled_spaces > 0) {
- log(`+${controlled_spaces} from controlled spaces in East Germany`)
- log(`Modified roll: ${roll + controlled_spaces}`)
- roll += controlled_spaces
- }
- game.the_wall_must_go['com_roll'] = roll
-
- }
- if (game.the_wall_must_go['dem_roll'] > 0 && game.the_wall_must_go['com_roll'] > 0) {
- if (game.the_wall_must_go['dem_roll'] > game.the_wall_must_go['com_roll'] ) {
- log('Democrat wins')
- game.the_wall_must_go['dem_wins']++
- } else if (game.the_wall_must_go['dem_roll'] === game.the_wall_must_go['com_roll'] ) {
- log('Tie. Re-roll')
- } else {
- log('Communist wins')
- game.the_wall_must_go['com_wins']++
- }
-
- log(`Democrat: ${game.the_wall_must_go['dem_wins']}, Communist: ${game.the_wall_must_go['com_wins']}`)
- }
- if (game.the_wall_must_go['dem_wins'] === 2) {
- log('The Democrat wins C86')
- finish_the_wall()
- return
- }
- if (game.the_wall_must_go['com_wins'] === 2) {
- log('The Communist wins C86')
- finish_the_wall()
- return
- }
- if (game.the_wall_must_go['dem_roll'] === 0 || game.the_wall_must_go['com_roll'] === 0) {
- next_player()
- } else {
- game.the_wall_must_go['dem_roll'] = 0
- game.the_wall_must_go['com_roll'] = 0
- }
- },
- /*done() {
- if (game.the_wall_must_go['dem_wins'] === 2) {
- game.persistent_events.push(86)
- log('+3 VP')
- game.vp += 3
- if (check_vp()) {
- return
- }
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (space.country === 'East_Germany' && game.comInfl[i] > 0){
- game.valid_spaces.push(space.space_id)
- }
- }
- if (!game.vm_infl_to_do) {
- if (game.round_player === DEM) {
- game.return = COM
- } else {
- game.return = DEM
- }
- }
- if (game.active === DEM) {next_player()}
- vm_next ()
- } else {
- permanently_remove(86)
- delete game.the_wall_must_go
- vm_return()
- }
- }*/
-}
-
-states.vm_warsaw_pact_summit = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- view.prompt = 'Choose to play for support checks or place SPs.'
- gen_action('influence')
- gen_action('support_check')
- },
- influence(){
- push_undo()
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (game.demInfl[i] === 0) {
- game.valid_spaces.push(space.space_id);
- }
- }
- game.vm_available_ops = 4
- game.phase = 3
- //game.state = 'vm_add_infl'
- vm_next()
- },
- support_check(){
- push_undo()
- for (let i = 1; i < spaces.length; i++) {
- let space = spaces[i]
- if (game.demInfl[i] > 0 && (space.socio === 5 || space.socio === 6)) {
- game.valid_spaces.push(space.space_id)
- }
- }
- game.vm_available_ops = 2
- //game.state = 'vm_support_check_prep'
- vm_next()
- }
-}
-
-states.vm_we_are_the_people_remove = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.demInfl[6] === 0 && game.vm_available_ops > 0) {
- view.prompt = '"We are the People!": no SPs to remove.'
- gen_action('done')
- } else if (game.vm_available_ops > 0 ) {
- view.prompt = '"We are the People!": remove up to 4 SPs from the Lutherian Church.'
- gen_action('done')
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- } else {
- view.prompt = '"We are the People!" Remove SPs: done.'
- gen_action('done')
- }
- },
- infl(space) {
- vm_do_remove_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- if (!game.vm_influence_added[6]) {
- log('No SPs removed')
- vm_next()
- } else {
- game.valid_spaces = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
- game.state = 'vm_we_are_the_people_add'
- }
- }
-}
-states.vm_we_are_the_people_add = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- /* if (!game.vm_influence_added[6]) {
- view.prompt = '"We are the People!" Add SPs: done.'
- gen_action('done')
- return
- }*/
-
- view.prompt = `"We are the People!": you must add the ${pluralize(game.vm_influence_added[6],'SP')} to spaces in Germany.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- },
- infl(space) {
- vm_do_add_infl_free(space)
- game.vm_influence_added[6]--
- if (game.vm_influence_added[6] === 0 ) {
- game.valid_spaces = []
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
- },
- /*done() {
- push_undo()
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }*/
-}
-
-states.vm_workers_revolt = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- if (game.valid_spaces.length === 0 ) {
- view.prompt = 'Workers Revolt: no valid spaces to select.'
- gen_action('pass')
- return
- }
- view.prompt = 'Workers Revolt: select a Worker Space in a country your opponent has power.'
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id)
- }
- },
- pass() {
- push_undo()
- vm_next()
- },
- infl(space) {
- push_undo()
- game.selected_space = space
- log(`Chose %${game.selected_space}`)
- game.state = 'vm_workers_revolt_finish'
- }
-}
-
-
-states.vm_workers_revolt_finish = {
- get inactive() {
- return `resolve ${clean_name(cards[game.played_card].name)}.`
- },
- prompt() {
- //if (game.selected_space > 0) {
- view.prompt = `Target: ${spaces[game.selected_space].name_unique}. Roll a die.`
- gen_action('roll')
- /* } else {
- view.prompt = 'Workers Revolt: done.'
- gen_action('done')
- }*/
-
- },
- roll() {
- clear_undo()
- let roll = Math.floor(Math.random() * 6) + 1
- log(`Roll: D${roll}`)
- let adj = count_adj(game.selected_space)
- if (game.active === DEM) {
- log(`-${adj.com_adj} from opponent controlled spaces`)
- roll -= adj.com_adj
- } else {
- log(`-${adj.dem_adj} from opponent controlled spaces`)
- roll -= adj.dem_adj
- }
- log(`Modified roll: ${roll}`)
- if (roll >= 4) {
- log('Workers Revolt successful')
- vm_replace_all_infl(game.temp)
- } else {log('Workers Revolt fails. Required 4 or more')}
- game.selected_space = 0
- vm_next()
- },
- /*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 = []
- vm_next()
- }
- },
- /*done() {
- vm_next()
- }*/
-}
-
-states.vm_tst_4 = {
- inactive: 'remove SPs',
- prompt () {
- if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
- view.prompt = 'Tiananmen Square Track award. Remove SPs: done.'
- gen_action('done')
- return
- }
- view.prompt = `Tiananmen Square Track award: remove ${pluralize(game.vm_available_ops,'SP')}.`
-
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- },
- infl(space) {
- vm_do_remove_infl(space)
- if (game.vm_available_ops === 0) {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_tst_6 = {
- inactive: 'make their free support check.',
- prompt() {
- /* if (game.vm_available_ops === 0) {
- view.prompt = 'Tiananmen Square Track award support check: done.'
- gen_action('done')
- return
- } else {*/
- view.prompt = 'Tiananmen Square Track award: you have a free 2 Ops support check.'
- for (let space_id of game.valid_spaces) {
- if (space_id) {
- gen_action_sc(space_id);
- }
- }
- //}
- },
- sc(space) {
- push_undo()
- game.selected_space = space
- if (game.active === DEM && game.persistent_events.includes(58) && spaces[space].country === "East_Germany") {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'vm_tst_6_sc'
- },
- /*done () {
- push_undo()
- vm_next()
- }*/
-}
-
-states.vm_tst_6_sc = {
- inactive: 'do support check.',
- prompt () {
- view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die`
- gen_action('roll')
- },
- roll() {
- clear_undo()
- do_sc(game.selected_space)
- game.vm_available_ops--
- game.valid_spaces = []
- game.state = 'vm_tst_6'
- vm_next()
- return
- }
-}
-
-states.vm_tst_8 = {
- inactive: 'use Tiananmen Square Track award.',
- prompt() {
- if (game.vm_event_to_do && game.vm_infl_to_do) {
- view.prompt = 'Choose whether to play for event or operations first.'
- gen_action('event')
- gen_action('ops')
- }
- else if (!game.vm_event_to_do && game.vm_infl_to_do) {
- view.prompt = 'Event resolved. Use card for operations.'
- gen_action('ops')
- }
- else if (game.vm_event_to_do && !game.vm_infl_to_do) {
- view.prompt = 'Operations resolved. Use card for event.'
- gen_action('event')
- }
- else if (!game.vm_event_to_do && !game.vm_infl_to_do) {
- view.prompt = 'Event and operations: done.'
- gen_action('end_round')
- }
- },
- event() {
- push_undo()
- log('Event')
- game.vm_event_to_do = false
- game.return_state = 'vm_tst_8'
- game.return = game.active
- game.vm_event = game.played_card
- goto_vm(game.vm_event)
- },
- ops() {
- push_undo()
- log('Operations')
- game.vm_infl_to_do = false
- game.return = game.active
- game.return_state = 'vm_tst_8'
- goto_vm(208)
- },
- end_round() {
- push_undo()
- game.tst_8 = true
- end_round()
- }
-}
-
-
-states.vm_tst_8_ops = {
- inactive: 'play card for operations.',
- prompt() {
- view.prompt = `Play ${clean_name(cards[game.played_card].name)} for:`
- gen_action('influence')
- gen_action('support_check')
- if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 )) {
- gen_action('tst')
- }
- },
- influence(){
- push_undo()
- game.vm_available_ops = cards[game.played_card].ops
- valid_spaces_infl()
- // If ABHR - Set AHBR tracker to true
- if (game.persistent_events.includes(58)) {
- game.austria_hungary_border_reopened_tracker = true
- }
- game.state = 'vm_add_infl'
- },
- support_check() {
- push_undo()
- game.vm_available_ops = 2
- game.state = 'vm_support_check_prep'
- },
- tst() {
- push_undo()
- game.state = 'vm_tiananmen_square_attempt'
- }
-}
-
-// ========================= POWER STRUGGLE STATES ========================
-
-states.vm_scare_tactics = {
- inactive: 'remove a Support Point.',
- prompt () {
- if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
- view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
- gen_action('done')
- return
- }
- if (game.vm_available_ops === 0 ) {
- view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
- gen_action('done')
- return
- }
- view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops, 'opponent SP')}${event_prompt()}.`
- for (let space_id of game.valid_spaces) {
- gen_action_infl(space_id);
- }
- },
- infl(space) {
- push_undo()
- vm_do_remove_infl(space)
- },
- done() {
- if (game.summary.length > 0) {
- pop_summary()
- log_br()
- }
- vm_next()
- }
-}
-
-states.vm_support_surges_1 = {
- inactive: 'draw cards.',
- prompt() {
- view.prompt = 'Support Surges: draw a card.'
- gen_action('draw')
- },
- draw() {
- if (game.active === DEM) {
- //console.log('hand before', game.dem_pwr_hand)
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+1, game.com_pwr_hand.length)
- game.temp = game.dem_pwr_hand[game.dem_pwr_hand.length-1]
- //console.log('hand after', game.dem_pwr_hand, 'game.temp', game.temp)
- } else {
- //console.log('hand before', game.com_pwr_hand)
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+1)
- game.temp = game.com_pwr_hand[game.com_pwr_hand.length-1]
- //console.log('hand after', game.com_pwr_hand, 'game.temp', game.temp)
- }
- game.state = 'vm_support_surges_2'
-
- //game.phase = 0
- //log('Drew 2 cards')
- //log('Surrenders initiative')
- //vm_next()
- }
-}
-
-states.vm_support_surges_2 = {
- inactive: 'draw cards.',
- prompt() {
- let special = [49,50,51,52]
- let elite_leader = [37,38,39,40]
- if (special.includes(game.temp)) {
- view.prompt = `Support Surges: you drew ${power_cards[game.temp].name}. Draw a second card.`
- }
- else if (elite_leader.includes(game.temp)) {
- view.prompt = `Support Surges: you drew an ${power_cards[game.temp].name}. Draw a second card.`
- }
- else if (numberless_cards.includes(game.temp)) {
- view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name}. Draw a second card.`
- } else {
- view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name} ${power_cards[game.temp].value}. Draw a second card.`
- }
- gen_action('draw')
- },
- draw() {
- if (game.active === DEM) {
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+1, game.com_pwr_hand.length)
- game.temp = game.dem_pwr_hand[game.dem_pwr_hand.length - 1]
- } else {
- draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+1)
- game.temp = game.com_pwr_hand[game.com_pwr_hand.length - 1]
- }
- game.state = 'vm_support_surges_3'
- /*game.phase = 0
- log('Drew 2 cards')
- log('Surrenders initiative')
- vm_next()*/
- }
-}
-
-states.vm_support_surges_3 = {
- inactive: 'draw cards.',
- prompt() {
- if (numberless_cards.includes(game.temp)) {
- view.prompt = `Support Surges: you drew ${power_cards[game.temp].name}. Done.`
- } else {
- view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name} ${power_cards[game.temp].value}. Done.`
- }
- gen_action('done')
- },
- done() {
- game.phase = 0
- delete game.temp
- log('Drew 2 cards')
- log('Surrenders initiative')
- vm_next()
- }
-}
-
-states.vm_support_falters = {
- inactive: 'discard cards.',
- prompt() {
- if ((game.active === DEM && game.dem_pwr_hand.length === 0) || (game.active === COM && game.com_pwr_hand.length === 0)) {
- view.prompt = 'Support Falters: no remaining cards to discard.'
- gen_action('pass')
- } else if (game.vm_available_ops > 0) {
- view.prompt = 'Support Falters: discard a card.'
- gen_action('discard')
- } else {
- view.prompt = 'Support Falters: done.'
- gen_action('done')
- }
- },
- discard() {
- if (game.active === DEM) {discard_card(game.dem_pwr_hand)}
- else {discard_card(game.com_pwr_hand)}
- game.vm_available_ops --
- },
- pass() {
- log_msg_gap('Takes initiative')
- game.return = game.active
- vm_next()
- },
- done() {
- log_gap('Takes initiative')
- game.return = game.active
- vm_next()
- }
-}
-
-/* =================== EVENTS ================================ */
-
-// #region GENERATED EVENT CODE
-const CODE = []
-
-CODE[1] = [ // Legacy of Martial Law*
- [ vm_permanently_remove ],
- [ vm_valid_spaces_country_opp, 'Poland' ],
- [ vm_prompt, 'replace 1 Democratic SP in Poland with a Communist SP' ],
- [ vm_legacy_of_martial_law ],
- [ vm_valid_spaces_country_sc, 'Poland' ],
- [ vm_prompt, 'make a Support Check in Poland' ],
- [ vm_1_support_check ],
- [ vm_return ],
-]
-
-CODE[2] = [ // Solidarity Legalised*
- [ vm_permanently_remove ],
- [ vm_solidarity_legalised ],
- [ vm_valid_spaces_solidarity_legalised ],
- [ vm_prompt, 'to every uncontrolled Worker and Farmer space in Poland' ],
- [ vm_add_limited_infl, 9, 1 ],
- [ vm_return ],
-]
-
-CODE[3] = [ // Walesa
- [ vm_permanently_remove ],
- [ vm_valid_spaces_country, 'Poland' ],
- [ vm_prompt, 'any space(s) in Poland' ],
- [ vm_add_infl_free, 4 ],
- [ vm_valid_spaces_country_sc, 'Poland' ],
- [ vm_prompt, 'make Support Checks in Poland' ],
- [ vm_support_check, 2 ],
- [ vm_return ],
-]
-
-CODE[4] = [ // Michnik
- [ vm_permanently_remove ],
- [ vm_valid_spaces, 26 ],
- [ vm_prompt, 'the Polish Intellectuals space' ],
- [ vm_add_x_infl, 3 ],
- [ vm_return ],
-]
-
-CODE[5] = [ // General strike
- [ vm_general_strike ],
- [ vm_return ],
-]
-
-CODE[6] = [ // Brought in for Questioning
- [ vm_brought_in_for_questioning ],
- [ vm_return ],
-]
-
-CODE[7] = [ // State Run Media*
- [ vm_permanently_remove ],
- [ vm_valid_spaces_opponent ],
- [ vm_remove_limited_opp_infl, 4, 2 ],
- [ vm_return ],
-]
-
-CODE[8] = [ // Prudence
- [ vm_prudence ],
- [ vm_return ],
-]
-
-CODE[9] = [ // The Wall*
- [ vm_permanently_remove ],
- [ vm_the_wall ],
- [ vm_return ],
-]
-
-CODE[10] = [ // Cult of Personality
- [ vm_permanently_remove ],
- [ vm_if, ()=>!game.the_tyrant_is_gone ],
- [ vm_valid_spaces_country_socio_2, 'Romania', 3, 4 ],
- [ vm_prompt, 'Worker or Farmer spaces in Romania, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_else ],
- [ vm_tyrant_block ],
- [ vm_endif ],
- [ vm_return ],
-]
-
-CODE[11] = [ // Dissident arrested
- [ vm_valid_spaces_opponent_socio, 5 ],
- [ vm_prompt, 'any Intellectuals space' ],
- [ vm_remove_x_opp_infl, 2 ],
- [ vm_return ],
-]
-
-CODE[12] = [ // Apparatchicks
- [ vm_permanently_remove ],
- [ vm_valid_spaces_socio, 2 ],
- [ vm_prompt, ' to any Bureaucratic space(s)' ],
- [ vm_add_infl_free, 3 ],
- [ vm_return ],
-]
-
-CODE[13] = [ // Stasi
- [ vm_permanently_remove ],
- [ vm_stasi ],
- [ vm_return ],
-]
-
-CODE[14] = [ // Gorbachev Charms the West
- [ vm_valid_spaces_opponent ],
- [ vm_remove_opp_infl, 2 ],
- [ vm_valid_spaces_sc ],
- [ vm_prompt, 'select a space for the Support Check' ],
- [ vm_1_support_check ],
- [ vm_return ],
-]
-
-CODE[15] = [ // Honecker
- [ vm_permanently_remove ],
- [ vm_honecker ],
- [ vm_return ],
-]
-
-CODE[16] = [ // Nomenklatura*
- [ vm_permanently_remove ],
- [ vm_nomenklatura ],
- [ vm_return ],
-]
-
-CODE[17] = [ // Roundtable talks
- [ vm_roundtable_talks ],
- [ vm_return ],
-]
-
-CODE[18] = [ // Poszgay Defends the Revolution
- [ vm_permanently_remove ],
- [ vm_poszgay ],
- [ vm_prompt, 'to 4 spaces in Hungary not under Democratic control' ],
- [ vm_add_limited_infl, 4, 1 ],
- [ vm_return ],
-]
-
-CODE[19] = [ // Papal vist
- [ vm_permanently_remove ],
- [ vm_valid_spaces, 20, 35, 38 ],
- [ vm_prompt, 'any Catholic Church space' ],
- [ vm_add_x_infl, 3 ],
- [ vm_return ],
-]
-
-CODE[20] = [ // Deutsche Marks*
- [ vm_permanently_remove ],
- [ vm_deutsche_marks ],
- [ vm_return ],
-]
-
-CODE[21] = [ // Common European Home
- [ vm_common_european_home ],
- [ vm_return ],
-]
-
-CODE[22] = [ // Power Struggle - Poland
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[23] = [ // Power Struggle - Hungary
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[24] = [ // St Nicolas Church
- [ vm_permanently_remove ],
- [ vm_valid_spaces, 6 ],
- [ vm_prompt, 'the Lutheran Church' ],
- [ vm_take_control_prep, 1 ],
- [ vm_st_nicholas_church ],
- [ vm_return ],
-]
-
-CODE[25] = [ // Perestroika
- [ vm_permanently_remove ],
- [ vm_perestroika ],
- [ vm_return ],
-]
-
-CODE[26] = [ // Helsinki Final Act*
- [ vm_permanently_remove ],
- [ vm_helsinki_final_act ],
- [ vm_return ],
-]
-
-CODE[27] = [ // Consumerism
- [ vm_valid_spaces_opponent_socio, 4 ],
- [ vm_prompt, ' from a Worker space' ],
- [ vm_remove_opp_infl, 1 ],
- [ vm_valid_spaces_opponent_socio, 4 ],
- [ vm_active_country ],
- [ vm_prompt, ()=>`make a support check in a Worker space in ${country_name(game.vm_active_country)}` ],
- [ vm_1_support_check ],
- [ vm_return ],
-]
-
-CODE[28] = [ // Factory Party Cells
- [ vm_valid_spaces_opponent_socio, 4 ],
- [ vm_prompt, ' from Worker spaces' ],
- [ vm_remove_limited_opp_infl, 3, 2 ],
- [ vm_return ],
-]
-
-CODE[29] = [ // Jan Palach Week*
- [ vm_permanently_remove ],
- [ vm_valid_spaces, 30 ],
- [ vm_prompt, 'the Charles University space' ],
- [ vm_add_x_infl, 6 ],
- [ vm_return ],
-]
-
-CODE[30] = [ // Tear Gas
- [ vm_tear_gas ],
- [ vm_return ],
-]
-
-CODE[31] = [ // Intelligentsia
- [ vm_valid_spaces, 4, 26, 31, 46, 55, 73 ],
- [ vm_prompt, 'Intellectual spaces, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_return ],
-]
-
-CODE[32] = [ // Peasant Parties*
- [ vm_permanently_remove ],
- [ vm_valid_spaces_socio, 3 ],
- [ vm_prompt, 'Farmer spaces, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_return ],
-]
-
-CODE[33] = [ // Sajudis*
- [ vm_permanently_remove ],
- [ vm_sajudis_check ],
- [ vm_prompt, 'any Minorities space' ],
- [ vm_take_control_prep, 1 ],
- [ vm_sajudis ],
- [ vm_return ],
-]
-
-CODE[34] = [ // Fidesz*
- [ vm_permanently_remove ],
- [ vm_valid_spaces, 47 ],
- [ vm_prompt, 'the Hungary students space' ],
- [ vm_add_x_infl, 5 ],
- [ vm_return ],
-]
-
-CODE[35] = [ // Heal our Bleeding Wounds*
- [ vm_permanently_remove ],
- [ vm_heal_our_bleeding_wounds ],
- [ vm_return ],
-]
-
-CODE[36] = [ // Dash for the West*
- [ vm_permanently_remove ],
- [ vm_prompt, 'Dash for the West: select any Democratic event with an asterix(*) from the discard pile. Event occurs immediately' ],
- [ vm_dash_for_the_west ],
- [ vm_return ],
-]
-
-CODE[37] = [ // Nagy Reburied*
- [ vm_permanently_remove ],
- [ vm_nagy_reburied ],
- [ vm_prompt, 'the Hungary Elite space' ],
- [ vm_remove_all_infl, 1 ],
- [ vm_valid_spaces_country, 'Hungary' ],
- [ vm_prompt, 'Hungary, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_return ],
-]
-
-CODE[38] = [ // July Concept
- [ vm_permanently_remove ],
- [ vm_valid_spaces_country, 'Bulgaria' ],
- [ vm_prompt, 'Bulgaria' ],
- [ vm_add_infl_free, 3 ],
- [ vm_return ],
-]
-
-CODE[39] = [ // Eco-Glasnost*
- [ vm_permanently_remove ],
- [ vm_valid_spaces, 66 ],
- [ vm_prompt, 'Ruse' ],
- [ vm_add_x_infl, 4 ],
- [ vm_eco_glasnost ],
- [ vm_return ],
-]
-
-CODE[40] = [ // Hungarian Democratic Forum
- [ vm_permanently_remove ],
- [ vm_valid_spaces_country, 'Hungary' ],
- [ vm_prompt, 'Hungary' ],
- [ vm_add_infl_free, 3 ],
- [ vm_valid_spaces_country_sc, 'Hungary' ],
- [ vm_prompt, 'make a Support Check in Hungary' ],
- [ vm_1_support_check ],
- [ vm_return ],
-]
-
-CODE[41] = [ // Ceausescu*
- [ vm_permanently_remove ],
- [ vm_if, ()=>!game.the_tyrant_is_gone ],
- [ vm_valid_spaces_country_opp, 'Romania' ],
- [ vm_prompt, ' from Romania' ],
- [ vm_remove_opp_infl, 3 ],
- [ vm_valid_spaces_country_sc, 'Romania' ],
- [ vm_prompt, 'make a support check in Romania' ],
- [ vm_1_support_check ],
- [ vm_prompt, ' from Bucharesti' ],
- [ vm_ceausescu ],
- [ vm_else ],
- [ vm_tyrant_block ],
- [ vm_endif ],
- [ vm_return ],
-]
-
-CODE[42] = [ // Power Struggle - East Germany
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[43] = [ // Power Struggle - Bulgaria
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[44] = [ // Inflationary Currency
- [ vm_permanently_remove ],
- [ vm_inflationary_currency ],
- [ vm_valid_spaces_country_opp ],
- [ vm_prompt, ()=>` from ${country_name(game.vm_active_country)}` ],
- [ vm_remove_opp_infl, 2 ],
- [ vm_inflationary_currency_discard ],
- [ vm_if, ()=>!discarded_card() ],
- [ vm_valid_spaces_country_sc ],
- [ vm_prompt, ()=>`make a Support Check in ${country_name(game.vm_active_country)}` ],
- [ vm_1_support_check ],
- [ vm_endif ],
- [ vm_return ],
-]
-
-CODE[45] = [ // Soviet Troop Withdrawals*
- [ vm_permanently_remove ],
- [ vm_valid_spaces_region_opp, 'Eastern Europe' ],
- [ vm_prompt, ' from Eastern Europe' ],
- [ vm_remove_limited_opp_infl, 5, 2 ],
- [ vm_return ],
-]
-
-CODE[46] = [ // Goodbye Lenin!*
- [ vm_permanently_remove ],
- [ vm_goodbye_lenin ],
- [ vm_return ],
-]
-
-CODE[47] = [ // Bulgarian Turks Expelled*
- [ vm_permanently_remove ],
- [ vm_bulgarian_turks_expelled ],
- [ vm_prompt, 'Razgrad' ],
- [ vm_remove_all_infl, 1 ],
- [ vm_return ],
-]
-
-CODE[48] = [ // We are the People!*
- [ vm_permanently_remove ],
- [ vm_we_are_the_people ],
- [ vm_return ],
-]
-
-CODE[49] = [ // Foreign Currency Debt Burden*
- [ vm_permanently_remove ],
- [ vm_foreign_currency_debt_burden ],
- [ vm_return ],
-]
-
-CODE[50] = [ // The Sinatra Doctrine*
- [ vm_permanently_remove ],
- [ vm_the_sinatra_doctrine ],
- [ vm_return ],
-]
-
-CODE[51] = [ // 40th Anniversary Celebration*
- [ vm_permanently_remove ],
- [ vm_40th_anniversary_celebration ],
- [ vm_valid_spaces_country, 'East_Germany' ],
- [ vm_prompt, 'East Germany' ],
- [ vm_add_infl_free ],
- [ vm_40th_anniversary_celebration_vp ],
- [ vm_return ],
-]
-
-CODE[52] = [ // Normalisation
- [ vm_permanently_remove ],
- [ vm_normalisation ],
- [ vm_prompt, 'the Czechoslovakia Elite and Bureaucrat Spaces' ],
- [ vm_remove_all_infl, 2 ],
- [ vm_return ],
-]
-
-CODE[53] = [ // Li Peng*
- [ vm_permanently_remove ],
- [ vm_li_peng ],
- [ vm_return ],
-]
-
-CODE[54] = [ // The Crowd Turns Against Ceausescu*
- [ vm_the_crowd_turns_against_ceausescu ],
- [ vm_return ],
-]
-
-CODE[55] = [ // Power Struggle - Czechoslovakia
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[56] = [ // Foreign Television
- [ vm_permanently_remove ],
- [ vm_foreign_television ],
- [ vm_remove_limited_opp_infl, 4, 2 ],
- [ vm_return ],
-]
-
-CODE[57] = [ // Central Committee Reshuffle*
- [ vm_permanently_remove ],
- [ vm_central_committee_reshuffle ],
- [ vm_prompt, ()=>`${country_name(game.vm_active_country)}` ],
- [ vm_add_infl_free, 3 ],
- [ vm_return ],
-]
-
-CODE[58] = [ // Austria-Hungary Border Reopened*
- [ vm_austria_hungary_border_reopened ],
- [ vm_return ],
-]
-
-CODE[59] = [ // GrenzTruppen*
- [ vm_grenztruppen ],
- [ vm_return ],
-]
-
-CODE[60] = [ // Toxic Waste*
- [ vm_permanently_remove ],
- [ vm_valid_spaces_socio, 4 ],
- [ vm_prompt, 'any Worker space(s)' ],
- [ vm_add_infl_free, 3 ],
- [ vm_return ],
-]
-
-CODE[61] = [ // The Monday Demonstrations*
- [ vm_permanently_remove ],
- [ vm_the_monday_demonstrations ],
- [ vm_prompt, 'the Lutheran Church Space and Leipzig' ],
- [ vm_take_control_prep, 2 ],
- [ vm_valid_spaces_country_sc, 'East_Germany' ],
- [ vm_prompt, 'make 5 Support Checks in East Germany' ],
- [ vm_support_check, 5 ],
- [ vm_return ],
-]
-
-CODE[62] = [ // Yakovlev Counsels Gorbachev*
- [ vm_yakovlev_counsels_gorbachev ],
- [ vm_return ],
-]
-
-CODE[63] = [ // Genscher*
- [ vm_genscher ],
- [ vm_return ],
-]
-
-CODE[64] = [ // Legacy of 1968*
- [ vm_permanently_remove ],
- [ vm_legacy_of_1968 ],
- [ vm_prompt, 'all spaces in Czechoslovakia not controlled by the Communist Player' ],
- [ vm_add_limited_infl, 11, 1 ],
- [ vm_return ],
-]
-
-CODE[65] = [ // Presidential Visit*
- [ vm_permanently_remove ],
- [ vm_presidential_visit ],
- [ vm_return ],
-]
-
-CODE[66] = [ // New Forum
- [ vm_permanently_remove ],
- [ vm_valid_spaces_country, 'East_Germany' ],
- [ vm_prompt, '3 spaces in East Germany' ],
- [ vm_add_limited_infl, 3, 1 ],
- [ vm_return ],
-]
-
-CODE[67] = [ // Reformer Rehabilitated*
- [ vm_prompt, 'Reformer Rehabilitated: chose any non-scoring card in the discard pile. Event takes place immediately' ],
- [ vm_reformer_rehabilitated ],
- [ vm_return ],
-]
-
-CODE[68] = [ // Klaus and Komarek*
- [ vm_permanently_remove ],
- [ vm_klaus_and_komarek ],
- [ vm_prompt, 'Prague' ],
- [ vm_remove_x_opp_infl, 2 ],
- [ vm_valid_spaces, 29 ],
- [ vm_add_x_infl, 2 ],
- [ vm_return ],
-]
-
-CODE[69] = [ // Systematization*
- [ vm_permanently_remove ],
- [ vm_valid_spaces_country, 'Romania' ],
- [ vm_systematization ],
- [ 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_permanently_remove ],
- [ vm_valid_spaces, 50, 56 ],
- [ vm_prompt, 'in Timisoara and Harghita/Covasna' ],
- [ vm_add_limited_infl, 2, 1 ],
- [ vm_laszlo_tokes ],
- [ vm_if, ()=>game.phase === 3 ],
- [ vm_prompt, ' in Romania' ],
- [ vm_add_infl ],
- [ vm_else ],
- [ vm_prompt, 'make 2 Support Checks in Romania' ],
- [ vm_support_check, 2 ],
- [ vm_endif ],
- [ vm_return ],
-]
-
-CODE[74] = [ // FRG Embassies
- [ vm_frg_embassies ],
- [ vm_return ],
-]
-
-CODE[75] = [ // Exit Visas*
- [ vm_permanently_remove ],
- [ vm_exit_visas ],
- [ vm_return ],
-]
-
-CODE[76] = [ // Warsaw Pact Summit
- [ vm_permanently_remove ],
- [ vm_warsaw_pact_summit ],
- [ vm_if, ()=>game.phase === 3 ],
- [ vm_prompt, ' spaces with no Democratic SPs' ],
- [ vm_add_infl_free, 4 ],
- [ vm_else ],
- [ vm_prompt, 'Select a Student or Intellectual space' ],
- [ vm_valid_spaces_country_socio_2, 3,, 4 ],
- [ vm_support_check_modified, 2, 2 ],
- [ vm_endif ],
- [ vm_return ],
-]
-
-CODE[77] = [ // Samizdat
- [ vm_permanently_remove ],
- [ vm_samizdat ],
- [ vm_return ],
-]
-
-CODE[78] = [ // Workers Revolt
- [ vm_workers_revolt ],
- [ vm_return ],
-]
-
-CODE[79] = [ // The Third Way*
- [ vm_permanently_remove ],
- [ vm_the_third_way ],
- [ vm_valid_spaces, 4 ],
- [ vm_prompt, 'the East German Writers space' ],
- [ vm_add_x_infl, 3 ],
- [ vm_return ],
-]
-
-CODE[80] = [ // Nepotism*
- [ vm_permanently_remove ],
- [ vm_nepotism ],
- [ vm_valid_spaces_region_socio, 'Balkans', 4 ],
- [ vm_prompt, 'Worker spaces in the Balkans' ],
- [ vm_add_infl_free ],
- [ vm_return ],
-]
-
-CODE[81] = [ // The Baltic Way*
- [ vm_permanently_remove ],
- [ vm_the_baltic_way ],
- [ vm_prompt, 'any Minorities space' ],
- [ vm_take_control_prep, 1 ],
- [ vm_return ],
-]
-
-CODE[82] = [ // Spitzel*
- [ vm_permanently_remove ],
- [ vm_valid_spaces_country_opp, 'East_Germany' ],
- [ vm_prompt, ' from East Germany' ],
- [ vm_remove_opp_infl, 2 ],
- [ vm_return ],
-]
-
-CODE[83] = [ // Modrow*
- [ vm_permanently_remove ],
- [ vm_modrow ],
- [ vm_valid_spaces_country, 'East_Germany' ],
- [ vm_prompt, 'East Germany, no more than 2 per space' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_return ],
-]
-
-CODE[84] = [ // Breakaway Baltic Republics*
- [ vm_permanently_remove ],
- [ vm_breakaway_baltic_republics ],
- [ vm_prompt, 'any Minorities space' ],
- [ vm_take_control_prep, 1 ],
- [ vm_valid_spaces_sc ],
- [ vm_prompt, 'select a space for the support check' ],
- [ vm_1_support_check ],
- [ vm_return ],
-]
-
-CODE[85] = [ // Tank Column/Tank Man*
- [ vm_permanently_remove ],
- [ vm_tank_column ],
- [ vm_return ],
-]
-
-CODE[86] = [ // The Wall Must Go!*
- [ vm_permanently_remove ],
- [ vm_the_wall_must_go ],
- [ vm_remove_infl, 3 ],
- [ vm_return ],
-]
-
-CODE[87] = [ // Kohl Proposes Reunification*
- [ vm_permanently_remove ],
- [ vm_kohl_proposes_reunification ],
- [ vm_return ],
-]
-
-CODE[88] = [ // Adamec*
- [ vm_permanently_remove ],
- [ vm_adamec ],
- [ vm_valid_spaces_country, 'Czechoslovakia' ],
- [ vm_prompt, 'Czechoslovakia' ],
- [ vm_add_limited_infl, 4, 2 ],
- [ vm_return ],
-]
-
-CODE[89] = [ // Domino Theory*
- [ vm_prompt, 'Domino Theory: choose a Power Struggle card to play from the discard pile' ],
- [ vm_permanently_remove ],
- [ vm_domino_theory ],
- [ vm_return ],
-]
-
-CODE[90] = [ // Civic Forum*
- [ vm_permanently_remove ],
- [ vm_valid_spaces_country, 'Czechoslovakia' ],
- [ vm_prompt, 'Czechoslovakia' ],
- [ vm_add_infl_free, 4 ],
- [ vm_civic_forum ],
- [ vm_valid_spaces_country_sc, 'Czechoslovakia' ],
- [ vm_prompt, 'Select a space in Czechoslovakia' ],
- [ vm_support_check, 2 ],
- [ vm_return ],
-]
-
-CODE[91] = [ // My First Banana*
- [ vm_permanently_remove ],
- [ vm_valid_spaces_country_opp, 'East_Germany' ],
- [ vm_prompt, ' from East Germany' ],
- [ vm_remove_opp_infl, 2 ],
- [ vm_valid_spaces_country_sc, 'East_Germany' ],
- [ vm_prompt, 'select a space in East Germany' ],
- [ vm_support_check, 2 ],
- [ vm_return ],
-]
-
-CODE[92] = [ // Betrayal
- [ vm_permanently_remove ],
- [ vm_prompt, 'choose any Orthodox Church space. Replace all Democratic SPs with Communist SPs' ],
- [ vm_betrayal ],
- [ vm_return ],
-]
-
-CODE[93] = [ // Shock Therapy*
- [ vm_permanently_remove ],
- [ vm_shock_therapy ],
- [ vm_valid_spaces_country ],
- [ vm_prompt, ()=>` ${country_name(game.vm_active_country)}` ],
- [ vm_add_infl_free, 3 ],
- [ vm_return ],
-]
-
-CODE[94] = [ // Union of Democratic Forces*
- [ vm_permanently_remove ],
- [ vm_valid_spaces_country_opp, 'Bulgaria' ],
- [ vm_prompt, ' from Bulgaria' ],
- [ vm_remove_opp_infl, 4 ],
- [ vm_valid_spaces_country_sc, 'Bulgaria' ],
- [ vm_prompt, 'Make 2 Support Checks in Bulgaria' ],
- [ vm_support_check, 2 ],
- [ vm_return ],
-]
-
-CODE[95] = [ // Power Struggle - Romania
- [ vm_power_struggle ],
- [ vm_return ],
-]
-
-CODE[96] = [ // The Chinese Solution*
- [ vm_permanently_remove ],
- [ vm_the_chinese_solution ],
- [ vm_valid_spaces_country_sc ],
- [ vm_prompt, ()=>`make 5 Support Checks in ${country_name(game.vm_active_country)}` ],
- [ vm_support_check_modified, 5, 3 ],
- [ vm_return ],
-]
-
-CODE[97] = [ // The Tyrant is Gone*
- [ vm_if, ()=>game.persistent_events.includes(54) ],
- [ vm_valid_spaces, 51 ],
- [ vm_prompt, 'the Romanian Elite Space' ],
- [ vm_remove_x_opp_infl, 4 ],
- [ vm_the_tyrant_is_gone ],
- [ vm_permanently_remove ],
- [ vm_else ],
- [ vm_the_tyrant_is_gone_prep ],
- [ vm_endif ],
- [ vm_return ],
-]
-
-CODE[98] = [ // Politburo Intrigue*
- [ vm_permanently_remove ],
- [ vm_valid_spaces_country_opp, 'Bulgaria' ],
- [ vm_prompt, ' from Bulgaria' ],
- [ vm_remove_limited_opp_infl, 3, 2 ],
- [ vm_valid_spaces_country_sc, 'Bulgaria' ],
- [ vm_prompt, 'make a support check in Bulgaria' ],
- [ vm_1_support_check ],
- [ vm_return ],
-]
-
-CODE[99] = [ // Ligachev*
- [ vm_permanently_remove ],
- [ vm_ligachev ],
- [ vm_return ],
-]
-
-CODE[100] = [ // Stand Fast*
- [ vm_permanently_remove ],
- [ vm_stand_fast ],
- [ vm_return ],
-]
-
-CODE[101] = [ // Elena*
- [ vm_permanently_remove ],
- [ vm_if, ()=>!game.the_tyrant_is_gone ],
- [ vm_valid_spaces, 51 ],
- [ vm_prompt, 'the Romania Elite Space' ],
- [ vm_add_x_infl, 2 ],
- [ vm_elena ],
- [ vm_else ],
- [ vm_tyrant_block ],
- [ vm_endif ],
- [ vm_return ],
-]
-
-CODE[102] = [ // National Salvation Front*
- [ vm_national_salvation_front ],
- [ vm_return ],
-]
-
-CODE[103] = [ // Government Resigns*
- [ vm_government_resigns ],
- [ vm_prompt, 'any uncontrolled Elite space' ],
- [ vm_remove_all_infl, 1 ],
- [ vm_permanently_remove ],
- [ vm_return ],
-]
-
-CODE[104] = [ // New Year's Eve Party*
- [ vm_new_years_eve_party ],
- [ vm_return ],
-]
-
-CODE[105] = [ // Public Against Violence*
- [ vm_permanently_remove ],
- [ vm_valid_spaces, 36 ],
- [ vm_prompt, 'Kosice' ],
- [ vm_add_x_infl, 2 ],
- [ vm_valid_spaces, 37 ],
- [ vm_prompt, 'Presov' ],
- [ vm_add_x_infl, 2 ],
- [ vm_public_against_violence ],
- [ vm_prompt, 'Make a Support Check in Bratislava' ],
- [ vm_support_check_modified, 1, 2 ],
- [ vm_return ],
-]
-
-CODE[106] = [ // Social Democratic Platform Adopted*
- [ vm_permanently_remove ],
- [ vm_social_democratic_platform_adopted ],
- [ vm_valid_spaces_country ],
- [ vm_prompt, ()=>`${country_name(game.vm_active_country)}` ],
- [ vm_add_infl_free, 2 ],
- [ vm_valid_spaces_country_sc ],
- [ vm_prompt, ()=>`make a Support Check in ${country_name(game.vm_active_country)}` ],
- [ vm_1_support_check ],
- [ vm_return ],
-]
-
-CODE[107] = [ // Massacre in Timisoara*
- [ vm_permanently_remove ],
- [ vm_if, ()=>!game.the_tyrant_is_gone ],
- [ vm_massacre_in_timisoara ],
- [ vm_valid_spaces_country_sc, 'Romania' ],
- [ vm_prompt, 'Make Support Checks in Romania' ],
- [ vm_support_check_modified, 2, 2 ],
- [ vm_else ],
- [ vm_tyrant_block ],
- [ vm_endif ],
- [ vm_return ],
-]
-
-CODE[108] = [ // Army Backs Revolution*
- [ vm_permanently_remove ],
- [ vm_army_backs_revolution ],
- [ vm_return ],
-]
-
-CODE[109] = [ // Kremlin Coup*
- [ vm_permanently_remove ],
- [ vm_kremlin_coup ],
- [ vm_return ],
-]
-
-CODE[110] = [ // Malta Summit*
- [ vm_permanently_remove ],
- [ vm_malta_summit ],
- [ vm_prompt, ' from Elite spaces' ],
- [ vm_remove_opp_infl, 5 ],
- [ vm_return ],
-]
-// #endregion
-
-
-// ============= TIANANMEN SQUARE TRACK AWARDS ====================
-CODE[203] = [//Tiananmen Square space 3 award
- [vm_tst_3],
- [vm_return]
-]
-CODE[204] = [//Tiananmen Square space 4 award
- [vm_valid_spaces_opponent],
- [vm_tst_4],
- [vm_return]
-]
-CODE[206] = [//Tiananmen Square space 6
- [vm_valid_spaces_sc],
- [vm_tst_6],
- [vm_return]
-]
-CODE[208] = [//Tiananmen Square space 8 event
- [vm_tst_8],
- [vm_return]
-]
-
-// ============= POWER STRUGGLE WILDCARDS =========================
-
-CODE[349] = [//Scare Tactics
- [vm_scare_tactics],
- [vm_valid_spaces_country_opp],
- [vm_prompt, ()=>` from ${country_name(game.vm_active_country)}`],
- [vm_remove_opp_infl, 1],
- [vm_return]
-]
-CODE[350] = [//Support Surges
- [vm_support_surges],
- [vm_return]
-]
-CODE[351] = [//Support Falters
- [vm_support_falters],
- [vm_return]
-]
+//"use strict"
+
+const { spaces, cards, power_cards } = require("./data.js")
+
+var game, view, states = {}
+
+const DEM = "Democrat"
+const COM = "Communist"
+
+const first_strategy_card = 1
+const last_strategy_card = 110
+
+const dem_tst_req = [5, 5, 6, 6, 7, 8, 9, 10]
+const com_tst_req = [6, 6, 7, 7, 8, 7, 6, 5]
+const scoring_cards = [22, 23, 42, 43, 55, 95]
+const leader_cards = [37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48]
+const leaders = [1, 4, 5, 6, 7]
+const support_loss_roll = [0, 0, 1, 1, 2, 2, 3, 4]
+const vp_roll = [0, 0, 1, 1, 2, 2, 3, 4]
+const countries = ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania']
+const elite_spaces = [12, 15, 27, 43, 51, 69]
+const all_power_cards = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 ]
+const numberless_cards = [25, 26, 27, 28, 29, 30, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52]
+const auto_resolve_events = [5, 8, 9, 13, 17, 25, 26, 30, 35, 50, 53, 54, 58, 59, 62, 63, 65, 70, 72, 74, 86, 99, 102, 108]
+const switch_events = [6, 20, 71]
+
+exports.scenarios = [ "Standard" ]
+
+exports.roles = [ DEM, COM ]
+
+// --- SET UP ---
+
+exports.setup = function (seed, scenario, options) {
+ game = {
+ seed: seed,
+ log: [],
+ undo: [],
+ summary: [],
+ active: null,
+ state: "com_init",
+ return: '',
+ vm: null,
+ vm_event: 0,
+ vm_event_to_do: false,
+ vm_infl_to_do: false,
+
+ played_card: 0,
+ table_cards: [],
+ available_ops: 0,
+ vm_available_ops: 0,
+ valid_spaces: [],
+ valid_cards: [],
+
+ vp: 0,
+ turn: 0,
+ round: 0,
+ round_player: COM,
+ stability: 0,
+ dem_tst_position: 0,
+ com_tst_position: 0,
+ dem_tst_attempted: 0,
+ com_tst_attempted: 0,
+ dem_tst_attempted_this_turn: 0,
+ com_tst_attempted_this_turn: 0,
+
+ demInfl: [],
+ comInfl: [],
+
+ strategy_deck: [],
+ strategy_discard: [],
+ discard: false,
+ view_opp_hand: false,
+ strategy_removed: [],
+ persistent_events: [],
+ power_struggle_deck: [],
+ power_struggle_discard: [],
+ dem_hand_limit: 8,
+ com_hand_limit: 8,
+ democrat_hand: [],
+ communist_hand: [],
+
+ pwr_struggle_in: [],
+ is_pwr_struggle: false,
+ dem_pwr_hand_limit: 0,
+ com_pwr_hand_limit: 0,
+ dem_pwr_hand: [],
+ com_pwr_hand: [],
+ raised_stakes_discard: 0,
+ raised_stakes: 0,
+ raised_stakes_round: 0,
+ phase: 0,
+ times_held: [0, 0, 0, 0, 0, 0],
+ revolutions: [false, false, false, false, false, false],
+ remove_opponent_infl: false,
+ tactics_fails: '',
+ }
+
+ log_h1("1989 Dawn of Freedom")
+
+ game.active = COM
+ start_game()
+
+ return game
+}
+
+function start_game() {
+ //starting influence
+
+ // Draw cards
+
+ //console.log('start game')
+
+ game.strategy_deck = draw_deck(cards)
+ reset_power()
+
+ //Set starting influence
+ spaces.forEach((space, index) => {
+ if (space !== null) {
+ game.demInfl[index] = space.demInfl
+ game.comInfl[index] = space.comInfl
+ }
+ })
+
+ //Set starting placement ops
+ game.starting_infl = {
+ com_starting_infl: 0,
+ dem_starting_infl: 0
+ },
+
+ // Set variable event cards where event is playable at start of game
+
+ game.playable_cards = [14, 15, 21, 70]
+
+ //console.log('game.strategy_deck: ', game.strategy_deck[1])
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.dem_hand_limit, game.com_hand_limit)
+ //.log('game.strategy_deck: ', game.strategy_deck[1], 'democrat_hand:', game.democrat_hand)
+
+ game.valid_spaces = valid_spaces_setup()
+ game.available_ops = 2
+ game.phase = 0
+ log_h1("Place starting Support Points")
+ log_side()
+}
+
+
+exports.view = function(state, player) {
+ game = state
+
+ view = {
+ log: game.log,
+ active: game.active,
+ prompt: null,
+ actions: null,
+
+ played_card: game.played_card,
+ table_cards: game.table_cards,
+ valid_spaces: game.valid_spaces,
+ valid_cards: game.valid_cards,
+
+ demInfl: game.demInfl,
+ comInfl: game.comInfl,
+ turn: game.turn,
+ round: game.round,
+ round_player: game.round_player,
+ vp: game.vp,
+ stability: game.stability,
+ dem_tst: game.dem_tst_position,
+ com_tst: game.com_tst_position,
+ persistent_events: game.persistent_events,
+ systematization: game.systematization,
+ the_tyrant_is_gone: game.the_tyrant_is_gone,
+
+ strategy_deck: game.strategy_deck.length,
+ strategy_removed: game.strategy_removed,
+ discard: game.discard,
+ show_opp_hand: game.view_opp_hand,
+
+ democrat_hand: game.democrat_hand.length,
+ communist_hand: game.communist_hand.length,
+ democrat_power_hand: game.dem_pwr_hand.length,
+ communist_power_hand: game.com_pwr_hand.length,
+ ceausescu_cards: game.ceausescu_cards,
+ is_pwr_struggle: game.is_pwr_struggle,
+ times_held: game.times_held,
+ revolutions: game.revolutions,
+
+ hand: [],
+ set_aside: [],
+ pwr_hand: [],
+
+
+ }
+
+ if (game.is_pwr_struggle) {
+ view.strategy_discard = game.power_struggle_discard
+ } else {
+ view.strategy_discard = game.strategy_discard
+ }
+
+ if (player === game.active && game.vm && game.vm.draw)
+ view.drawn = game.vm.draw
+
+ if (player === game.active) {
+ if (game.selected_space > 0 ) {
+ view.valid_spaces = [game.selected_space]
+ } else {
+ view.valid_spaces = game.valid_spaces
+ }
+ } else {
+ view.valid_spaces = []
+ }
+
+ if (player === game.active) {
+ view.valid_cards = game.valid_cards
+ } else {
+ view.valid_cards = []
+ }
+
+ if (player === DEM) {
+ view.hand = game.democrat_hand
+ if (game.communist_hand_red) {
+ view.opp_hand = game.communist_hand_red
+ }
+ view.set_aside = game.democrat_set_aside /*Is this being used? */
+ view.power_hand = [...game.dem_pwr_hand].sort((a, b) => a - b)
+
+ } else if (player === COM) {
+ view.hand = game.communist_hand
+ view.opp_hand = [...game.dem_pwr_hand].sort((a, b) => a - b)
+ view.power_hand = [...game.com_pwr_hand].sort((a, b) => a - b)
+ }
+
+ if (player === DEM) {
+ view.samizdat = game.samizdat_card
+ }
+
+ if (game.state === "game_over") {
+ view.prompt = game.victory
+ } else if (player === "Observer" || (game.active !== player && game.active !== "Both")) {
+ if (states[game.state]) {
+ let inactive = states[game.state].inactive
+ if (typeof inactive === "function")
+ view.prompt = `Waiting for ${game.active} ${inactive()}`
+ else
+ view.prompt = `Waiting for ${game.active} to ${inactive}`
+ } else {
+ view.prompt = "A Unknown state: " + game.state
+ }
+ } else {
+ view.actions = {}
+
+ if (states[game.state])
+ states[game.state].prompt(player)
+ else
+ view.prompt = "B Unknown state: " + game.state
+ if (view.actions.undo === undefined) {
+ if (game.undo && game.undo.length > 0)
+ view.actions.undo = 1
+ else
+ view.actions.undo = 0
+ }
+ }
+
+ return view
+}
+
+
+// === ACTIONS ===========
+
+function gen_action(action, argument) {
+//console.log('gen_action called with ', action, ' and ', argument)
+ if (argument === undefined) {
+ //console.log('argument undefined')
+ view.actions[action] = 1
+ } else {
+ if (!(action in view.actions)) {
+ //console.log('push argument')
+ view.actions[action] = []
+ }
+ view.actions[action].push(argument)
+ }
+ //console.log('view.actions: ', view.actions, 'view.actions[action]: ', view.actions[action])
+}
+
+function gen_action_infl(space){
+ gen_action("infl", space)
+}
+
+function gen_action_card(card){
+ gen_action("card", card)
+}
+
+function gen_action_sc(space){
+ gen_action("sc", space)
+}
+
+function gen_action_scoring(){
+ gen_action("scoring")
+}
+
+exports.action = function (state, player, action, arg) {
+ //console.log('exports.action called with state:' , state, 'player:', player, 'action: ', action, 'arg: ', arg)
+ game = state
+ if (states[game.state] && action in states[game.state]) {
+ states[game.state][action](arg, player)
+ } else {
+ if (action === "undo" && game.undo && game.undo.length > 0)
+ pop_undo()
+ else
+ throw new Error("Invalid action: " + action)
+ }
+ return game
+}
+
+// ============= GAME STATES =======================
+
+states.com_init = {
+ inactive: 'place starting SPs.',
+ prompt() {
+ //console.log('state:', game.state, 'game.valid_spaces', game.valid_spaces)
+ if (game.starting_infl.dem_starting_infl === 2 && game.available_ops === 0 ) {
+ view.prompt = 'Place starting SPs: done. Start Turn 1.';
+ gen_action("start");
+ } else if (game.available_ops === 0) {
+ view.prompt = 'Place starting SPs: done.';
+ gen_action("done");
+ return;
+ } else if (game.starting_infl.dem_starting_infl === 2) {
+ view.prompt = `Place your last ${pluralize(game.available_ops,'starting SP')}.`
+ } else {
+ view.prompt = `Place ${pluralize(game.available_ops,'starting SP')}.`
+ }
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ },
+ infl(space) {
+ add_infl(space)
+
+ },
+ done() {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+
+ game.starting_infl.com_starting_infl++
+ if (game.starting_infl.com_starting_infl == 1){
+ game.available_ops = 3
+ game.state = 'dem_init'
+ valid_spaces_setup()
+ next_player()
+ } else if (game.starting_infl.com_starting_infl == 2) {
+ game.available_ops = 4
+ game.state = 'dem_init'
+ valid_spaces_setup()
+ next_player()
+ } else if (game.starting_infl.com_starting_infl == 3) {
+ delete game.starting_infl
+ game.state = 'start_game'
+ }
+ },
+ start() {
+ new_turn()
+ clear_undo()
+ game.state = 'choose_card'
+ }
+}
+
+states.dem_init = {
+ inactive: 'place starting SPs.',
+ prompt() {
+ //console.log('state:', game.state)
+ if (game.available_ops == 0) {
+ view.prompt = 'Place starting SPs: done.';
+ gen_action("done");
+ return;
+ } else if (game.starting_infl.com_starting_infl === 2) {
+ view.prompt = `Place your last ${pluralize(game.available_ops,'starting SP')}.`
+ } else {
+ view.prompt = `Place ${pluralize(game.available_ops,'starting SP')}.`
+ }
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ },
+ infl(space) {
+ add_infl(space)
+ },
+
+ done() {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+
+ game.starting_infl.dem_starting_infl++
+ if (game.starting_infl.dem_starting_infl == 1){
+ game.available_ops = 3
+ } else if (game.starting_infl.dem_starting_infl == 2) {
+ game.available_ops = 2
+ }
+ game.state = 'com_init'
+ valid_spaces_setup()
+ next_player()
+ }
+}
+
+
+states.choose_card = {
+ inactive: 'choose a card.',
+ prompt() {
+ if ((game.active===DEM && game.democrat_hand.length === 0) || game.active === COM && game.communist_hand.length === 0) {
+ view.prompt = 'No cards remaining: you must pass.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Choose a card.'
+ let available_cards
+ if (game.active === DEM) {
+ available_cards = game.democrat_hand
+ } else {
+ available_cards = game.communist_hand
+ }
+ for (let card of available_cards) {
+ gen_action_card(card)
+ }
+ }
+ },
+ card(card) {
+ push_undo()
+
+ //Check if player is at risk of losing game due to held scoring card
+ if (!scoring_cards.includes(card)) {
+ let scoring_cards_count = count_scoring_cards()
+
+ if (game.round !== 8 && scoring_cards_count >= (8-game.round)){
+ game.temp = card
+ game.state = 'confirm_card'
+ return
+ }
+ }
+ select_card(card)
+ },
+ pass() {
+ log('No cards remaining. Passed')
+ //end_round()
+ game.state = 'end_round'
+ }
+}
+
+states.confirm_card = {
+ inactive: 'choose a card.',
+ prompt() {
+ let scoring_cards_count = count_scoring_cards()
+ view.prompt = `${pluralize(scoring_cards_count,'scoring card')} in hand with ${pluralize(8-game.round,'turn')} remaining. Scoring cards may not be held. Continue?`
+ gen_action('continue')
+ },
+ continue() {
+ select_card(game.temp)
+ }
+}
+
+states.play_card ={
+ get inactive() {
+ return `play ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt () {
+ /*if (game.phase >= 1) { /*Finish here when playing your own event
+ console.log('in play card')
+ view.prompt = `${clean_name(cards[game.played_card].name)}: done. End the Action Round.`
+ gen_action('end_round')
+ return
+ }*/
+
+ view.prompt = `Play ${clean_name(cards[game.played_card].name)} for:`
+
+ if (scoring_cards.includes(game.played_card)) {
+ /*view.prompt = 'Play for:'*/
+ gen_action('event')
+ return
+ }
+
+ // Check for Reformer Rehabilitated
+
+ //console.log('game.active', game.active, 'game.playable_cards[67].playable', game.playable_cards[67].playable)
+
+
+ if (game.played_card === 67 && game.playable_cards.includes(67)){
+ if (game.active === DEM && (game.dem_tst_position > game.com_tst_position)) {
+ gen_action('event')
+ }
+ if (game.active === COM && (game.dem_tst_position < game.com_tst_position)) {
+ gen_action('event')
+ }
+ }
+
+ //Check for events
+ //console.log('event_is_playable(game.played_card)', event_is_playable(game.played_card))
+ if (event_is_playable(game.played_card)) {
+ //console.log('card is playable')
+ //Check for Tiananmen Square Track awards special abilities
+ //console.log('game.tst_7', game.tst_7)
+ if ((game.active === DEM && cards[game.played_card].side === 'C' && game.dem_tst_position >= 7 && game.com_tst_position < 7 && !game.tst_7) || (game.active === COM && cards[game.played_card].side === 'D' && game.com_tst_position >= 7 && game.dem_tst_position < 7 && !game.tst_7)){
+ gen_action('tst_7')
+ }
+
+ if ((game.active === DEM && cards[game.played_card].side !== 'C' && game.dem_tst_position >= 8 && game.com_tst_position < 8 && !game.tst_8) || (game.active === COM && cards[game.played_card].side !== 'D' && game.com_tst_position >= 8 && game.dem_tst_position < 8 && !game.tst_8)){
+ gen_action('tst_8')
+ }
+
+ //Continue with normal logic
+ get_events(game.played_card)
+ }
+
+ gen_action('influence')
+ gen_action('support_check')
+
+ if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 && game.dem_tst_position < 8 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 && game.com_tst_position < 8)) {
+ gen_action('tst')
+ }
+
+ },
+ event() {
+ push_undo()
+ //console.log('played event, game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
+ log_gap(`Played C${cards[game.played_card].number} for the event`)
+ game.vm_infl_to_do = false
+ if (scoring_cards.includes(game.played_card)) {game.phase = 0}
+ else {game.phase = 1}
+ game.return = game.active
+ if (switch_events.includes(game.played_card)) {next_player()}
+ game.vm_event = game.played_card
+ //console.log('before event, game.vm_infl_to_do', game.vm_infl_to_do)
+ goto_vm(game.vm_event)
+ },
+ opp_event() {
+ push_undo()
+ log_gap(`Played C${cards[game.played_card].number} for the event`)
+ game.phase = 1 /*Do I still need this?*/
+ game.vm_infl_to_do = true
+ game.return = game.active
+ game.vm_event = game.played_card
+ if (is_auto_resolve(game.played_card) || switch_events.includes(game.played_card)) {
+ goto_vm(game.vm_event)}
+ else {
+ next_player()
+ log(`C${game.vm_event}`)
+ goto_vm(game.vm_event)
+ }
+ },
+ influence() {
+ push_undo()
+ log_gap(`Played C${cards[game.played_card].number} to place SPs`)
+
+
+ // Check if Common European Home played for influence
+ if (game.played_card === 21) {
+ if (game.active === DEM) {
+ game.vp --
+ log('-1 VP')
+ if (check_vp()) {
+ return
+ }
+ } else {
+ game.vp ++
+ log('+1 VP')
+ if (check_vp()) {
+ return
+ }
+ }
+ }
+ // Check if card is opponent card with event that needs to be resolved
+
+ if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
+ if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
+ //game.phase = 1 /*Do I need this? */
+ game.vm_event_to_do = true
+ }
+ }
+
+ // If ABHR - Set AHBR tracker to true
+ if (game.persistent_events.includes(58)) {
+ game.austria_hungary_border_reopened_tracker = true
+ }
+ game.state='add_influence'
+ valid_spaces_infl()
+ },
+ tst() {
+ push_undo()
+ log_gap(`Played C${cards[game.played_card].number} to the Tiananmen Square Track`)
+ game.state='tiananmen_square_attempt'
+ },
+ support_check() {
+ push_undo()
+ log_gap(`Played C${cards[game.played_card].number} for support checks`)
+
+ // Check if card is opponent card with event that needs to be resolved
+
+ if (cards[game.played_card].playable || game.playable_cards.includes(game.played_card)) {
+ if ((game.active === DEM && cards[game.played_card].side === "C" ) || (game.active === COM && cards[game.played_card].side === "D")) {
+ game.vm_event_to_do = true
+ }
+ }
+
+ game.available_ops = 2
+ game.state='support_check_prep'
+ valid_spaces_sc()
+ },
+ tst_7() { /*Cancel opponent event */
+ push_undo()
+ log(`Played C${game.played_card}. Event cancelled using TST Award`)
+ game.tst_7 = true
+ game.vm_infl_to_do = true
+ game.state = 'resolve_opponent_event'
+ },
+ tst_8() { /*Play card for ops and event */
+ push_undo()
+ game.vm_event_to_do = true
+ game.vm_infl_to_do = true
+ game.tst_8 = true
+ log(`Played C${game.played_card} for event and operations`)
+ game.state = 'vm_tst_8'
+ },
+ end_round () {
+ end_round()
+ }
+
+}
+
+states.resolve_opponent_event = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ //console.log('in resolve opponent event: discard', game.strategy_discard)
+ if (game.vm_infl_to_do) {
+ view.prompt = 'Event resolved. Choose to play card for:'
+ gen_action('influence')
+ gen_action('support_check')
+ } else if (game.vm_event_to_do) {
+ // Check for Tiananmen Square Track ability - play opponent card without triggering event
+ if ((game.active === DEM && game.dem_tst_position >= 7 && game.com_tst_position < 7 && !game.tst_7) || (game.active === COM && game.com_tst_position >= 7 && game.dem_tst_position < 7 && !game.tst_7)){
+ gen_action('tst_7')
+ }
+ view.prompt = `${clean_name(cards[game.played_card].name)}: you must resolve the opponent event.`
+ gen_action('opp_event')
+ } else {
+ view.prompt = 'Event resolved. End the action round.'
+ gen_action('end_round')
+ }
+ },
+ influence(){
+ push_undo()
+ // If ABHR - Set AHBR tracker to true
+ if (game.persistent_events.includes(58)) {
+ game.austria_hungary_border_reopened_tracker = true
+ }
+ game.state = 'finish_add_infl'
+ valid_spaces_infl()
+ },
+ support_check() {
+ push_undo()
+ game.available_ops = 2
+ game.state = 'finish_support_check_prep'
+ valid_spaces_sc()
+ },
+ opp_event() {
+ game.vm_event_to_do = false
+ game.return_state = 'resolve_opponent_event'
+ if (is_auto_resolve(game.played_card) || switch_events.includes(game.played_card)) {
+ game.return = game.active
+ log(`Played C${game.played_card} for the event`)
+ goto_vm(game.played_card)}
+ else {
+ if (game.active === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ next_player()
+ log(`C${game.played_card}`)
+ goto_vm(game.played_card)
+ }
+ },
+ tst_7() {
+ push_undo()
+ log('Event cancelled using TST Award')
+ game.tst_7 = true
+ game.vm_event_to_do = false
+ },
+ end_round() {
+ push_undo()
+ /*if(game.round_player === COM && game.active === DEM) {
+ log_h3('End of Communist Action Round')
+ change_player()
+ } */
+ end_round()
+ }
+}
+
+
+states.finish_add_infl = {
+ inactive: 'add SPs.',
+ prompt () {
+ if (game.available_ops === 0) {
+ view.prompt = 'Place SPs: done.'
+ gen_action("end_round")
+ return;
+ }
+
+ view.prompt = `Add SPs: ${game.available_ops} remaining.`
+
+ // Generate actions for valid spaces
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id)
+ }
+ },
+ infl(space) {
+ add_infl(space)
+ },
+ end_round() {
+ push_undo()
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+
+ end_round()
+ //game.state = 'end_round'
+ }
+}
+
+states.finish_support_check_prep = {
+ inactive: 'do support checks.',
+ prompt () {
+ if (game.available_ops === 0) {
+ view.prompt = 'Support checks: done.'
+ gen_action('end_round')
+ //return
+ } else {
+ view.prompt = `Select a space. ${pluralize(game.available_ops, 'support check')} remaining.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_sc(space_id)
+ }
+ }
+ },
+ sc(space) {
+ push_undo()
+ game.selected_space = space
+ // Check for Austria-Hungary Border Reopened - check on first support check only
+ //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
+ if (game.persistent_events.includes(58)){
+ if (game.active === DEM && game.available_ops > 1) {
+ //console.log('in ahb check, country, ', spaces[game.selected_space].country, 'ahb', 'austria_hungary_border_reopened'])
+ if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
+ game.state = 'finish_austria_hungary_border_reopened_check'
+ return
+ }
+ }
+ }
+ game.state = 'finish_do_support_check'
+ },
+ end_round () {
+ end_round()
+ //game.state = 'end_round'
+ }
+}
+
+states.finish_austria_hungary_border_reopened_check = {
+ inactive: 'decide Austria-Hungary Border Reopened',
+ prompt() {
+ view.prompt = 'Austria-Hungary Border Reopened: will both support checks be in East Germany?'
+ gen_action('yes')
+ gen_action('no')
+ },
+ yes() {
+ game.austria_hungary_border_reopened_tracker = true
+ game.state = 'finish_do_support_check'
+ },
+ no() {
+ game.state = 'finish_do_support_check'
+ }
+}
+
+states.finish_do_support_check = {
+ inactive: 'do support checks',
+ prompt () {
+ view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_sc(game.selected_space)
+ game.available_ops--
+ if (game.available_ops === 0) {
+ game.valid_spaces = []
+ }
+ game.state = 'finish_support_check_prep'
+ return
+ }
+}
+
+states.add_influence = {
+ inactive: 'add SPs.',
+ prompt () {
+ if (game.available_ops <= 0) {
+ view.prompt = 'Place SPs: done.'
+ if (!game.vm_event_to_do) {
+ gen_action("end_round")
+ } else {
+ gen_action('done')
+ }
+ } else {
+
+ view.prompt = `Add SPs: ${game.available_ops} remaining.`
+
+ // Generate actions for valid spaces
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ }
+ },
+ infl(space) {
+ add_infl(space)
+ },
+ end_round() {
+ push_undo()
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ end_round()
+ },
+ done() {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ reset_austria_hungary_border_reopened()
+ game.state = 'resolve_opponent_event'
+ }
+}
+
+states.tiananmen_square_attempt = {
+ inactive: 'do Tiananmen Square Attempt.',
+ prompt () {
+ view.prompt = 'Tiananmen Square Track attempt: Roll a die.'
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_tst_attempt ()
+ }
+}
+
+states.tiananmen_square_attempt_success = {
+ inactive: 'do Tiananmen Square Attempt.',
+ prompt () {
+ if (game.vm_event > 200) {
+ view.prompt = 'Tiananmen Square Track attempt successful. Go to TST Award.'
+ gen_action('done')
+ } else {
+ view.prompt = 'Tiananmen Square Track attempt successful.'
+ gen_action('end_round')
+ }
+
+ },
+ done () {
+ push_undo()
+ //console.log('going to tst award, game.return_state', game.return_state)
+ goto_vm(game.vm_event)
+ },
+ end_round () {
+ push_undo()
+ end_round()
+ }
+}
+
+states.tiananmen_square_attempt_fail = {
+ inactive: 'do Tiananmen Square Attempt.',
+ prompt () {
+ view.prompt = 'Tiananmen Square Track attempt failed.'
+ gen_action('end_round')
+ },
+ end_round () {
+ push_undo()
+ end_round()
+ //game.state = 'tiananmen_square_attempt_done'
+ }
+}
+
+states.tiananmen_square_attempt_done = {
+ inactive: 'do Tiananmen Square Attempt.',
+ prompt () {
+ view.prompt = 'Tiananmen Square Track attempt: done.'
+ gen_action('end_round')
+ },
+ end_round () {
+ end_round()
+ //game.state = 'end_round'
+ }
+}
+
+states.tst_goddess = {
+ inactive: 'choose whether to discard a card.',
+ prompt() {
+ //if (game.phase === 0) {
+ view.prompt = 'Tiananmen Square Track award: you may discard a non-Power Struggle Card and draw a replacement.'
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ gen_action('pass')
+ /*} else {
+ view.prompt = 'Discard a card: done.'
+ gen_action('done')
+ }*/
+ },
+ card(card) {
+ push_undo()
+ discard(card)
+ game.valid_cards = []
+ game.state = 'tst_goddess_draw'
+ //game.phase++
+ /*if (game.active === DEM) {
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length +1, game.communist_hand.length)
+ } else {
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length +1)
+ }*/
+ },
+ pass() {
+ log('Did not discard')
+ log_h2("Action Round " + game.round)
+ if (game.active === DEM) {
+ next_player()
+ } else {
+ log_side()
+ }
+ if (game.persistent_events.includes(5)) {
+ game.state = 'general_strike'
+ } else {
+ game.state = 'choose_card'
+ }
+ },
+ done() {
+
+ log_h2("Action Round " + game.round)
+ if (game.active === DEM) {
+ next_player()
+ } else {
+ log_side()
+ }
+ game.phase = 0
+ if (game.persistent_events.includes(5)) {
+ game.state = 'general_strike'
+ } else {
+ game.state = 'choose_card'
+ }
+ }
+}
+
+states.tst_goddess_draw = {
+ inactive: 'choose whether to discard a card.',
+ prompt() {
+ view.prompt = 'Draw a replacement card.'
+ gen_action('draw')
+ },
+ draw() {
+ if (game.active === DEM) {
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length +1, game.communist_hand.length)
+ } else {
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.democrat_hand.length, game.communist_hand.length +1)
+ }
+ log_h2("Action Round " + game.round)
+ if (game.active === DEM) {
+ next_player()
+ } else {
+ log_side()
+ }
+ game.phase = 0
+ if (game.persistent_events.includes(5)) {
+ game.state = 'general_strike'
+ } else {
+ game.state = 'choose_card'
+ }
+ }
+}
+
+
+
+states.support_check_prep = {
+ inactive: 'do support checks',
+ prompt () {
+ if (game.available_ops === 0) { /*Needs another check for Support Checks done during Crowd Turns against Ceausescu*/
+ if (game.is_pwr_struggle) {
+ view.prompt = 'The Crowd Turns Against Ceausescu. Support checks: done.'
+ gen_action('done')
+ } else if (!game.vm_event_to_do) {
+ view.prompt = 'Support checks: done.'
+ gen_action('end_round')
+ } else {
+ view.prompt = 'Support checks: done.'
+ gen_action('done')
+ }
+ } else if (game.available_ops > 0) {
+ view.prompt = `Select a space. ${pluralize(game.available_ops, 'support check')} remaining.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_sc(space_id)
+ }
+ }
+ },
+ sc(space) {
+ push_undo()
+ game.selected_space = space
+
+ // Check for Austria-Hungary Border Reopened - check on first support check only
+ //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
+ if (game.persistent_events.includes(58)) {
+ if (game.active === DEM && game.available_ops > 1) {
+ if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
+ game.state = 'austria_hungary_border_reopened_check'
+ return
+ }
+ //game.state = 'do_support_check'
+ } /*else { */
+ }
+ game.state = 'do_support_check'
+ //}
+ },
+ end_round() {
+ push_undo()
+ end_round()
+ },
+ done() {
+ push_undo()
+ if (game.is_pwr_struggle) {/*Crowd Turns Against Ceausescu should be the only time you end up here during a power struggle */
+ if (game.return !== game.active) {
+ next_player()
+ }
+ log_h2('Raise the Stakes')
+ game.state = 'raise_stakes_1'
+ return
+ }
+ reset_austria_hungary_border_reopened()
+ game.state = 'resolve_opponent_event'
+ }
+}
+
+states.do_support_check = {
+ inactive: 'do support checks.',
+ prompt () {
+ // console.log('in do_support_check')
+ view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_sc(game.selected_space)
+ game.available_ops--
+ if (game.available_ops === 0) {
+ game.valid_spaces = []
+ }
+ game.state = 'support_check_prep'
+ return
+ }
+}
+
+states.austria_hungary_border_reopened_check = {
+ inactive: 'decide Austria-Hungary Border Reopened.',
+ prompt() {
+ view.prompt = 'Austria-Hungary Border Reopened: will both support checks be in East Germany?'
+ gen_action('yes')
+ gen_action('no')
+ },
+ yes() {
+ game.austria_hungary_border_reopened_tracker = true
+ game.state = 'do_support_check'
+ },
+ no() {
+ game.state = 'do_support_check'
+ }
+}
+
+states.end_round = {
+ inactive: 'finish playing a card.',
+ prompt() {
+ view.prompt = 'End the Action Round.'
+ gen_action('end_round')
+ },
+ end_round() {
+ push_undo()
+ end_round()
+ }
+}
+
+//======================= POWER STRUGGLE ===============================
+
+states.draw_power_cards = {
+ inactive: 'draw cards.',
+ prompt() {
+ view.prompt = `${clean_name(cards[this_card()].name)}: draw cards.`
+ gen_action('draw')
+ },
+ draw() {
+ push_undo()
+ game.power_struggle_deck = [...all_power_cards]
+ // console.log('game.power_struggle_deck.length', game.power_struggle_deck.length)
+ //console.log('called draw cards, country', game.pwr_struggle_in, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
+ //console.log('test3')
+ let presence = check_presence(game.pwr_struggle_in)
+ //console.log('test2')
+ if (presence.dem_spaces > 0) {
+ game.dem_pwr_hand_limit = 6 + 2*(presence.dem_spaces - 1)
+ } else {
+ game.dem_pwr_hand_limit = 0
+ }
+ if (presence.com_spaces > 0 ) {
+ game.com_pwr_hand_limit = 6 + 2*(presence.com_spaces - 1)
+ } else {
+ game.com_pwr_hand_limit = 0
+ }
+ // Events which affect cards drawn
+ if (game.persistent_events.includes(17) && game.com_pwr_hand_limit >= 2) {
+ log('Democrat receives 2 cards from Communist due to C17')
+ game.dem_pwr_hand_limit += 2
+ game.com_pwr_hand_limit -= 2
+ discard_from_table(17)
+ game.persistent_events = game.persistent_events.filter(n => n !== 17)
+ }
+
+ if (game.persistent_events.includes(72)) {
+ let farmer_check
+ for (let space of spaces) {
+ if (space && space.country === game.pwr_struggle_in && space.socio === 3 && check_dem_control(space.space_id)) {
+ farmer_check = true
+ }
+ }
+ if (farmer_check && game.com_pwr_hand_limit > 0) {
+ log('Democrat receives 1 cards from Communist due to C72')
+ game.dem_pwr_hand_limit += 1
+ game.com_pwr_hand_limit -= 1
+ permanently_remove(72)
+ game.persistent_events = game.persistent_events.filter(n => n !== 72)
+ }
+ }
+
+ if (game.persistent_events.includes(102) && game.dem_pwr_hand_limit >=2 && (game.pwr_struggle_in === 'Romania' || game.pwr_struggle_in === 'Bulgaria')) {
+ log('Communist receives 2 cards from Democrat due to C102')
+ game.dem_pwr_hand_limit -= 2
+ game.com_pwr_hand_limit += 2
+ permanently_remove(102)
+ game.persistent_events = game.persistent_events.filter(n => n !== 102)
+ }
+
+ //Draw Power Cards
+ game.is_pwr_struggle = true
+ //console.log('game.dem_pwr_hand_limit', game.dem_pwr_hand_limit, 'game.com_pwr_hand_limit', game.com_pwr_hand_limit)
+ draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand_limit, game.com_pwr_hand_limit)
+ if (game.active === DEM) {
+ game.valid_cards = [...game.dem_pwr_hand]
+ } else {
+ game.valid_cards = [...game.com_pwr_hand]
+ }
+ //game.valid_cards = all_power_cards
+
+ log(`Communist: ${game.com_pwr_hand.length} cards`)
+ log(`Democrat: ${game.dem_pwr_hand.length} cards`)
+
+ //Check if The Crowd Turns Against Ceausescu occurs
+ if (game.table_cards.includes(54) && game.pwr_struggle_in === 'Romania') {
+ //console.log('draw cards: crowd subcheck, game.active', game.active)
+ if (game.active === COM) {
+ game.return = COM
+ next_player()
+ }
+ log_h3('C54')
+ game.persistent_events.push(54)
+ game.state = 'the_crowd_turns_against_ceausescu_prep'
+ } else {
+ log_h2('Raise the Stakes')
+ game.state = 'raise_stakes_1'
+ //console.log('game.state', game.state, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
+ }
+ }
+}
+
+states.the_crowd_turns_against_ceausescu_prep = {
+ get inactive() {
+ return `resolve ${clean_name(cards[54].name)}.`
+ },
+ prompt() {
+ view.prompt = 'The Crowd Turns Against Ceausescu: draw cards.'
+ gen_action('draw')
+ },
+ draw() {
+ game.ceausescu_cards = []
+ draw_cards(game.power_struggle_deck, game.ceausescu_cards, game.com_pwr_hand, 15, game.com_pwr_hand.length)
+ //console.log('game.ceausescu_cards', game.ceausescu_cards)
+ game.temp = game.ceausescu_cards.filter(card => card && card >=25 && card <= 30).length
+ log(`Drew ${pluralize(game.temp, 'Rally in the Square')}.`)
+ game.vm_available_ops = game.temp * 3
+ log(`Democrat takes a ${game.vm_available_ops} Action Round`)
+ game.state = 'vm_the_crowd_turns_against_ceausescu'
+ }
+}
+
+states.vm_the_crowd_turns_against_ceausescu = {
+ get inactive() {
+ return `resolve ${clean_name(cards[54].name)}.`
+ },
+ prompt() {
+ view.prompt = `You have ${game.vm_available_ops} operations points. Play for:`
+ gen_action('influence')
+ gen_action('support_check')
+ },
+ influence() {
+ push_undo()
+ delete game.ceausescu_cards
+ valid_spaces_infl()
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'Romania')
+ game.state = 'the_crowd_turns_against_ceausescu_infl' /* Send this to add_infl. Add check at end of add_infl similar to valid_spaces*/
+ },
+ support_check() {
+ push_undo()
+ delete game.ceausescu_cards
+ valid_spaces_sc()
+ game.available_ops = 2
+ game.state = 'support_check_prep'
+ }
+}
+
+states.the_crowd_turns_against_ceausescu_infl = {
+ inactive: 'add SPs.',
+ prompt () {
+ if (game.vm_available_ops === 0)
+ {
+ view.prompt = 'Place SPs: done.';
+ gen_action("done");
+ return;
+ }
+
+ view.prompt = `Add SPs: ${game.vm_available_ops} remaining`
+ for (let space of game.valid_spaces) {
+ gen_action_infl(space)
+ }
+ },
+ infl(space) {
+ vm_do_add_infl(space)
+ },
+ done() {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+
+ if (game.return !== game.active) {
+ next_player()
+ }
+ log_h2('Raise the Stakes')
+ game.state = 'raise_stakes_1'
+ }
+}
+
+states.raise_stakes_1 = {
+ inactive: 'raise the stakes.',
+
+ prompt () {
+ // console.log('raise stakes 1 - valid cards', game.valid_cards)
+ // console.log('raise the stakes: game.played_power_card', game.played_power_card, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
+ if ((game.active === DEM && game.dem_pwr_hand < 3) || (game.active === COM && game.com_pwr_hand < 3)) {
+ view.prompt = 'Raise the stakes: you must pass.'
+ gen_action('pass')
+ }
+ else if (game.raised_stakes_discard === 3) {
+ view.prompt = 'Raise the stakes: done.'
+ gen_action('done')
+ } else {
+ view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes.`
+ if (game.raised_stakes_discard === 0) {
+ gen_action('pass')
+ }
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ }
+ },
+ card(card) {
+ push_undo()
+ if (numberless_cards.includes(card)) {
+ log(`Discarded: P${card}`)
+ } else {
+ log(`Discarded: P${card} V${power_cards[card].value}`)
+ }
+ discard(card)
+
+ game.raised_stakes_discard ++
+ if (game.raised_stakes_discard === 3) {
+ game.raised_stakes++
+ game.valid_cards = []
+ }
+ },
+ pass(){
+ log('Did not raise the stakes')
+ game.raised_stakes_discard = 0
+ next_player()
+ if (game.active === DEM) {
+ game.valid_cards = [...game.dem_pwr_hand]
+ } else {
+ game.valid_cards = [...game.com_pwr_hand]
+ }
+ game.state = 'raise_stakes_2'
+ },
+ done () {
+ log_gap('Raised the stakes')
+ game.raised_stakes_discard = 0
+ next_player()
+ //console.log('game.active', game.active)
+ if (game.active === DEM) {
+ game.valid_cards = [...game.dem_pwr_hand]
+ } else {
+ game.valid_cards = [...game.com_pwr_hand]
+ }
+ // console.log('game.valid_cards', game.valid_cards)
+ game.state = 'raise_stakes_2'
+ }
+}
+
+states.raise_stakes_2 = {
+ inactive: 'raise the stakes.',
+
+ prompt () {
+ if ((game.active === DEM && game.dem_pwr_hand < 3) || (game.active === COM && game.com_pwr_hand < 3)) {
+ view.prompt = 'Raise the stakes: you must pass.'
+ gen_action('pass')
+ return
+ }
+ if (game.raised_stakes_discard === 3) {
+ view.prompt = 'Raise the stakes: done.'
+ gen_action('done')
+ } else {
+ view.prompt = `Discard ${3-game.raised_stakes_discard} cards to raise the stakes.`
+ if (game.raised_stakes_discard === 0) {
+ gen_action('pass')
+ }
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ }
+ },
+ card(card) {
+ push_undo()
+ if (numberless_cards.includes(card)) {
+ log(`Discarded: P${card}`)
+ } else {
+ log(`Discarded: P${card} V${power_cards[card].value}`)
+ }
+ discard(card)
+
+ game.raised_stakes_discard ++
+ if (game.raised_stakes_discard === 3) {
+ game.raised_stakes++
+ game.valid_cards = []
+ }
+
+ },
+ pass() {
+ log('Did not raise the stakes')
+ game.raised_stakes_discard = 0
+ game.valid_cards = []
+ log_h2('Play Cards')
+ next_player()
+ game.state = 'begin_power_struggle'
+ },
+ done () {
+ log_gap('Raised the stakes')
+ game.raised_stakes_discard = 0
+ game.valid_cards = []
+ log_h2('Play Cards')
+ next_player()
+ game.state = 'begin_power_struggle'
+ },
+}
+
+states.begin_power_struggle = {
+ inactive: 'begin power struggle.',
+ prompt() {
+ view.prompt = 'Begin power struggle.'
+ gen_action('struggle')
+ },
+ struggle () {
+ do_valid_cards()
+ game.state = 'power_struggle'
+ }
+}
+
+states.power_struggle = {
+ inactive: 'play a card.',
+ prompt () {
+ console.log('game.vm_event', game.vm_event)
+ if (game.phase === 0) {
+ if (game.valid_cards.length > 0) {
+ view.prompt = "Play a card."
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ } else if ( game.valid_cards.length === 0) {
+ view.prompt = 'No valid cards. You must concede.'
+ gen_action('concede')
+ }
+ }
+ if (game.phase === 1) {
+ if (game.valid_cards.length > 0) {
+ view.prompt = `${power_cards[game.played_power_card].name} played. You must match or concede.`
+ gen_action('concede')
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ } else if (game.valid_cards.length === 0) {
+ view.prompt = `${power_cards[game.played_power_card].name} played. You must concede.`
+ gen_action('concede')
+ }
+ }
+ else if (game.phase === 2) {
+ view.prompt = 'You matched. Roll a die.'
+ gen_action('roll')
+ }
+ else if (game.phase === 3) {
+ view.prompt = 'Play leader as:'
+ if (game.tactics_fails !== "Strike") {gen_action('strike')}
+ if (game.tactics_fails !== "March") {gen_action('march')}
+ if (game.tactics_fails !== "Rally in the Square") {gen_action('rally')}
+ if (game.tactics_fails !== "Petition") {gen_action('petition')}
+ }
+ },
+ card(card) {
+ push_undo()
+ discard(card)
+ game.valid_cards=[]
+ game.return_state = 'power_struggle'
+ if (card === 52) {
+ log_gap(`Played P52: P${power_cards[game.played_power_card].number} no longer playable`)
+
+ } else {
+ if (game.phase === 0 && leader_cards.includes(card)) {} /* Log nothing. Probably a better way to do this */
+ else if (numberless_cards.includes(card)) {
+ log_gap(`Played: P${card}`)
+ } else {
+ log_gap(`Played: P${card} V${power_cards[card].value}`)
+ }
+ }
+ if (game.phase === 0) {
+ if (card >= 37 && card <= 48) { /*When a leader is played */
+ game.played_power_card = card
+ game.phase = 3
+ } else if (card === 49){ /*Scare Tactics */
+ game.return = ''
+ goto_vm(349) /*Can I combine these 3 into a single stage where you goto_vm(300 + card) ? */
+ } else if (card === 50) { /*Support Surges */
+ if (game.active === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ goto_vm(350)
+ } else if (game.phase === 0 && card === 51) { /*Support Falters */
+ next_player()
+ goto_vm(351)
+ } else {
+ game.played_power_card = card
+ game.phase = 1
+ next_player()
+ do_valid_cards()
+ }
+ } else if (game.phase === 1) {
+ if (card === 52) {
+ game.tactics_fails = power_cards[game.played_power_card].name
+ game.phase = 0
+ next_player()
+ do_valid_cards()
+ } else if (power_cards[game.played_power_card].value === 1) {
+ log('Takes initiative')
+ game.phase = 0
+ do_valid_cards()
+ } else {
+ game.phase = 2
+ }
+ }
+ },
+ roll () {
+ let roll = Math.floor(Math.random() * 6) + 1
+ log(`Roll: D${roll}`)
+ if (roll >= power_cards[game.played_power_card].value) {
+ log('Initiative roll successful')
+ game.phase = 0
+ do_valid_cards()
+ } else {
+ log(`Initiative roll failed. Required ${power_cards[game.played_power_card].value} or more`)
+ game.phase = 0
+ next_player()
+ do_valid_cards()
+ }
+ },
+ concede () {
+ push_undo()
+ game.valid_cards = []
+ log('Conceded')
+ log_h2('Aftermath')
+ log_h3('Support Loss')
+ //if ((game.played_power_card >= 25 && game.played_power_card <= 30) || game.played_power_card === 53) {game.rally_win = 2}
+ //if ((game.played_power_card >= 31 && game.played_power_card <= 36) || game.played_power_card === 54) {game.petition_win = 2}
+ if (game.phase === 0) {
+ game.played_power_card = 0 /*If conceded when held the initiative but had no playable cards, ignore the last played card */
+ }
+ game.phase = 0
+ game.state = 'support_loss'
+ },
+ strike () {
+ log(`Played: P${power_cards[game.played_power_card].number} as a Strike`)
+ game.played_power_card = 9
+ game.phase = 1
+ next_player()
+ do_valid_cards()
+ },
+ march () {
+ log(`Played: P${power_cards[game.played_power_card].number} as a March`)
+ game.played_power_card = 21
+ game.phase = 1
+ next_player()
+ do_valid_cards()
+ },
+ rally () {
+ log(`Played: P${power_cards[game.played_power_card].number} as a Rally in the Square`)
+ game.played_power_card = 53
+ game.phase = 1
+ next_player()
+ do_valid_cards()
+ },
+ petition () {
+ log(`Played: P${power_cards[game.played_power_card].number} as a Petition`)
+ game.played_power_card = 54
+ game.phase = 1
+ next_player()
+ do_valid_cards()
+ },
+ /*draw () {
+ if (game.active === DEM) {
+ draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+2, game.com_pwr_hand.length)
+ } else {draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+2)}
+ game.phase = 0
+ next_player()
+ do_valid_cards()
+ },*/
+ /*infl(space) {
+ game.remove_opponent_infl = true
+ remove_infl(space)
+ game.phase = 6
+ },
+ discard () { /*Is this still needed?
+ if (game.active === DEM) {discard_card(game.dem_pwr_hand)}
+ else {discard_card(game.com_pwr_hand)}
+ game.available_ops --
+ }, */
+ done () {
+ if (game.phase === 7) { /*Is this ever called anymore? */
+ game.phase = 0
+ log_msg_gap('Takes initiative')
+ do_valid_cards()
+ } else {
+ game.phase = 0
+ next_player()
+ do_valid_cards()
+ }
+ }
+}
+
+states.support_loss ={
+ inactive: 'do Support Loss.',
+ prompt () {
+ if (!game.persistent_events.includes(111)) {
+ if (game.phase === 0) {
+ view.prompt = 'You lost the Power Struggle. Roll a die for Support Loss.'
+ gen_action('roll')
+ } else if (game.phase === 1 && game.available_ops > 0 && game.valid_spaces.length > 0) {
+ view.prompt = `Power Struggle - ${country_name(game.pwr_struggle_in)}. Support Loss: remove ${pluralize(game.available_ops,'SP')}.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id)
+ }
+ } else if (game.phase === 1 && game.available_ops === 0 ) {
+ view.prompt = `Power Struggle - ${country_name(game.pwr_struggle_in)}. Support Loss: finished.`
+ gen_action('done')
+ } else if (game.phase === 1 && game.valid_spaces.length === 0) {
+ view.prompt = `Power Struggle - ${country_name(game.pwr_struggle_in)}. Support Loss: no remaining SPs to remove.`
+ gen_action('done')
+ }
+ } else {
+ if (game.phase === 0) {
+ view.prompt = 'You lost the Power Struggle. Roll a die for Support Loss.'
+ gen_action('roll')
+ } else if (game.phase === 1 && game.available_ops > 0 && game.valid_spaces.length > 0) {
+ view.prompt = `New Year's Eve Party - ${country_name(game.pwr_struggle_in)}. Support Loss: remove ${pluralize(game.available_ops,'SP')}.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id)
+ }
+ } else if (game.phase === 1 && game.available_ops === 0 ) {
+ view.prompt = `New Year's Eve Party - ${country_name(game.pwr_struggle_in)}. Support Loss: finished.`
+ gen_action('done')
+ } else if (game.phase === 1 && game.valid_spaces.length === 0) {
+ view.prompt = `New Year's Eve Party - ${country_name(game.pwr_struggle_in)}. Support Loss: no remaining SPs to remove.`
+ gen_action('done')
+ }
+ }
+ },
+ roll () {
+ clear_undo()
+ let roll = Math.floor(Math.random() * 6) + 1
+ let rally_win = 0
+ let petition_win = 0
+ log(`Roll: D${roll}`)
+ if ((game.played_power_card >= 25 && game.played_power_card <= 30) || game.played_power_card === 53) { rally_win = 2}
+ if ((game.played_power_card >= 31 && game.played_power_card <= 36) || game.played_power_card === 54) { petition_win = 2}
+ let modified_roll = roll + game.raised_stakes + rally_win - petition_win
+
+ // Roll modifiers
+ if (game.active === COM && game.persistent_events.includes(62)) {
+ log('+1 from C62')
+ modified_roll ++
+ }
+
+ if (modified_roll < 0) {modified_roll = 0}
+ else if (modified_roll > 7) {modified_roll = 7}
+
+
+ if (game.raised_stakes !== 0) {
+ log(`+${game.raised_stakes} from Raising the Stakes`)
+ }
+ if (rally_win !== 0) {
+ log('+2 from winning on a P25')
+ }
+ if (petition_win !== 0) {
+ log('-2 from winning on a P31')
+ }
+ if (modified_roll !== roll) {
+ log(`Modified roll: ${modified_roll}`)
+ }
+ game.available_ops = support_loss_roll[modified_roll]
+ if (game.available_ops === 0) {
+ log('Does not remove SPs')
+ }
+ game.phase++
+ if (game.available_ops > 0) {
+ valid_spaces_support_loss()
+ }
+ },
+ infl (space) {
+ game.remove_opponent_infl = false /* Don't know why this is needed... */
+ remove_infl(space)
+ if (game.available_ops === 0 ) {
+ game.valid_spaces = []
+ }
+ },
+ done () {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ next_player()
+ log_h3('Victory Point')
+ game.phase = 0
+ game.state = 'vp_roll'
+ }
+}
+
+states.vp_roll = {
+ inactive: 'do VP Roll.',
+ prompt () {
+ if (!game.persistent_events.includes(111)) {
+ if (game.phase === 0) {
+ view.prompt = `Power Struggle - ${country_name(game.pwr_struggle_in)}: roll a die for Victory.`
+ gen_action('roll')
+ } else if (game.phase === 1) {
+ view.prompt = `Power Struggle - ${country_name(game.pwr_struggle_in)}: take power.`
+ gen_action('take')
+ } else if (game.phase === 2) {
+ view.prompt = `Power Struggle - ${country_name(game.pwr_struggle_in)}: proceed to scoring.`
+ gen_action('scoring')
+ }
+ } else {
+ if (game.phase === 0) {
+ view.prompt = `New Year's Eve Party - ${country_name(game.pwr_struggle_in)}: roll a die for Victory.`
+ gen_action('roll')
+ } else if (game.phase === 1) {
+ view.prompt = `New Year's Eve Party - ${country_name(game.pwr_struggle_in)}: take power.`
+ gen_action('take')
+ } else if (game.phase === 2) {
+ view.prompt = `New Year's Eve Party - ${country_name(game.pwr_struggle_in)}: proceed to scoring.`
+ gen_action('scoring')
+ }
+ }
+ },
+ roll () {
+ let roll = Math.floor(Math.random() * 6) + 1
+ log(`Roll: D${roll}`)
+ let rally_win = 0
+ let petition_win = 0
+ if ((game.played_power_card >= 25 && game.played_power_card <= 30) || game.played_power_card === 53) {rally_win = 2}
+ if ((game.played_power_card >= 31 && game.played_power_card <= 36) || game.played_power_card === 54) {petition_win = 2}
+ let modified_roll = roll + game.raised_stakes + rally_win - petition_win
+ if (game.active === DEM && game.persistent_events.includes(62)) {
+ log('+1 from C62')
+ modified_roll ++
+ }
+ if (modified_roll < 0) {modified_roll = 0}
+ else if (modified_roll > 7) {modified_roll = 7}
+
+ if (game.raised_stakes !== 0) {
+ log(`+${game.raised_stakes} from Raising the Stakes`)
+ }
+ if (rally_win !== 0) {
+ log('+2 from winning on a P25')
+ }
+ if (petition_win !== 0) {
+ log('-2 from winning on a P31')
+ }
+ if (modified_roll !== roll) {
+ log(`Modified roll: ${modified_roll}`)
+ }
+ let vp_change = vp_roll[modified_roll]
+ if (game.active === DEM) {
+ log(`+${vp_change} VP`)
+ } else {
+ log(`-${vp_change} VP`)
+ }
+ if (roll >= 4)
+ //console.log('VP before', game.vp)
+ if (game.active === DEM) {game.vp += vp_change}
+ else {game.vp -= vp_change}
+ //console.log('VP after', game.vp)
+ if (game.active === DEM && modified_roll >= 4) {
+ game.phase = 1
+ } else {
+ game.phase = 0
+ if (game.active === DEM) {next_player()}
+ game.state = 'choose_power'
+ }
+ },
+ take () {
+ push_undo()
+ //Find name of scoring card
+ let scoring_card = scoring_cards[countries.indexOf(game.pwr_struggle_in)]
+ permanently_remove(scoring_card)
+ take_power(game.pwr_struggle_in)
+ game.phase = 2
+ },
+ scoring () {
+ push_undo()
+ log_h2('Scoring')
+ score_country(game.pwr_struggle_in)
+
+ //Check if The Tyrant is Gone occurs
+ if (game.table_cards.includes(97) && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(54)) {
+ game.return_state = 'finish_scoring'
+ if (game.active !== DEM) {
+ next_player()
+ }
+ game.state = 'the_tyrant_is_gone'
+ } else {
+ game.state = 'finish_scoring'
+ }
+ },
+}
+
+states.choose_power = {
+ inactive: 'choose whether to remain in power.',
+ prompt () {
+ if (game.phase === 0) {
+ view.prompt = 'Choose whether to remain in power.'
+ gen_action('retain')
+ gen_action('surrender')
+ } else if (game.phase === 1) {
+ view.prompt = 'Proceed to scoring.'
+ gen_action('scoring')
+ }
+ },
+ retain() {
+ push_undo()
+ retain_power(game.pwr_struggle_in)
+ game.phase = 1
+ },
+ surrender () {
+ push_undo()
+ take_power(game.pwr_struggle_in)
+ permanently_remove(game.played_card)
+ game.phase = 1
+ },
+ scoring () {
+ push_undo()
+ score_country(game.pwr_struggle_in)
+
+ //Check if The Tyrant is Gone occurs
+ if (game.table_cards.includes(97) && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(54)) {
+ game.return_state = 'finish_scoring'
+ if (game.active !== DEM) {
+ next_player()
+ }
+ game.state = 'the_tyrant_is_gone'
+ } else {
+ game.state = 'finish_scoring'
+ }
+ }
+}
+/*
+states.score_country = {
+ inactive: `score country`,
+ prompt () {
+ view.prompt = 'Scoring: done.'
+ gen_action('done')
+ },
+ done () {
+ reset_power()
+ /*if (game.return !== game.active) {
+ next_player()}
+ game.state = 'finish_scoring'
+ }
+}
+*/
+
+states.the_tyrant_is_gone ={
+ inactive: 'resolve The Tyrant is Gone.',
+ prompt() {
+ view.prompt = 'Play The Tyrant is Gone for the event.'
+ gen_action('event')
+ },
+ event() {
+ if (game.active !== DEM) {
+ next_player()
+ }
+ if (game.round_player === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ log_h3(`C97`)
+ game.vm_event = 97
+ goto_vm(game.vm_event)
+ }
+}
+
+states.finish_scoring ={
+ inactive: 'finish scoring.',
+ prompt() {
+ view.prompt = 'End power struggle.'
+ gen_action('done')
+ } ,
+ done() {
+ //console.log('game.return_state', game.return_state)
+ log_msg_gap('Power Struggle resolved') /*At this point log card dicarded or permanently removed? */
+ if (game.persistent_events.includes(111)) {
+ game.state = 'new_years_eve_party'
+ return
+ }
+ if (check_vp()) {
+ return
+ }
+ reset_power()
+ end_round()
+ //game.state = 'end_round'
+ }
+}
+
+// ======================================= END TURN STATES ==========================================
+
+states.end_turn_4_5_4 = {
+ inactive: 'verify held cards.',
+ prompt() {
+ view.prompt = 'End Turn: verify held cards.'
+ gen_action('check')
+ },
+ check() {
+ log_h2('Verify held cards')
+ const dem_has_scoring_card = game.democrat_hand.some(card => scoring_cards.includes(card))
+ const com_has_scoring_card = game.communist_hand.some(card => scoring_cards.includes(card))
+ if (!dem_has_scoring_card && !com_has_scoring_card) {
+ log('No held scoring cards')
+ }
+
+ if (dem_has_scoring_card && com_has_scoring_card) {
+ log('Both players have held scoring cards')
+ game.state = 'game_end_tie'
+ }
+ else if (dem_has_scoring_card) {
+ log('Democrat player has a held scoring card')
+ goto_game_over(COM, `${COM} won by held scoring card!`)
+ }
+ else if (com_has_scoring_card) {
+ log('Communist player has a held scoring card')
+ goto_game_over(DEM, `${DEM} won by held scoring card!`)
+ }
+ else if (game.persistent_events.includes(104)) {
+ log_h1(`New Year's Eve Party`)
+ game.vm_event = 104
+ //Check if the Communist receives VP from The Tyrant is Gone
+ if (game.persistent_events.includes(97)) {
+ game.vp -= 2
+ log(`Communist receives 2 VP from C97`)
+ }
+ game.persistent_events.push(111)
+ if (game.active !== DEM) {
+ next_player()
+ }
+ game.state = 'new_years_eve_party'
+ }
+ else if(game.turn === 10) {
+ clear_undo()
+ log_h2('Final Scoring')
+
+ //Check if the Communist receives VP from The Tyrant is Gone
+ if (game.persistent_events.includes(97)) {
+ game.vp -= 2
+ log(`Communist receives 2 VP from C97`)
+ }
+ game.state = 'final_scoring_held'
+
+ } else {
+ game.return_state = ''
+ game.state = 'end_turn'
+ }
+ }
+}
+
+states.end_turn = {
+ inactive: 'end the turn.',
+ prompt() {
+ view.prompt = 'End Turn: done.'
+ gen_action('done')
+ },
+ done() {
+ new_turn()
+ }
+}
+
+states.final_scoring_held = {
+ inactive: 'resolve final scoring.',
+ prompt() {
+ view.prompt = 'Final Scoring: Communist scores VP bonus for the number of countries they retain power.'
+ gen_action('bonus')
+ },
+ bonus() {
+ // console.log('game.revolutions: ', game.revolutions)
+ const held_countries = game.revolutions.filter(value => value === false).length
+ let vp_gain = 4*held_countries
+ log(`Communist holds ${held_countries} countries: -${vp_gain} VP`)
+ game.vp -= 4*held_countries
+ game.temp = {'East_Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false}
+ game.state = 'final_scoring'
+ }
+}
+
+states.final_scoring = {
+ inactive: 'score countries.',
+ prompt() {
+ if (game.temp['East_Germany'] && game.temp['Poland'] && game.temp['Czechoslovakia'] && game.temp['Hungary'] && game.temp['Romania'] && game.temp['Bulgaria']) {
+ view.prompt = 'Final scoring: done.'
+ gen_action('end')
+ } else {
+ view.prompt = 'Choose a country to score:'
+ if (!game.temp['East_Germany']) {gen_action('east_germany')}
+ if (!game.temp['Poland']) {gen_action('poland')}
+ if (!game.temp['Czechoslovakia']) {gen_action('czechoslovakia')}
+ if (!game.temp['Hungary']) {gen_action('hungary')}
+ if (!game.temp['Romania']) {gen_action('romania')}
+ if (!game.temp['Bulgaria']) {gen_action('bulgaria')}
+ }
+ },
+ east_germany() {
+ score_country('East_Germany')
+ game.temp['East_Germany'] = true
+ },
+ poland() {
+ score_country('Poland')
+ game.temp['Poland'] = true
+ },
+ czechoslovakia() {
+ score_country('Czechoslovakia')
+ game.temp['Czechoslovakia'] = true
+ },
+ hungary() {
+ score_country('Hungary')
+ game.temp['Hungary'] = true
+ },
+ romania() {
+ score_country('Romania')
+ game.temp['Romania'] = true
+ },
+ bulgaria() {
+ score_country('Bulgaria')
+ game.temp['Bulgaria'] = true
+ },
+ end() {
+ delete game.temp
+ if (game.vp > 0) {
+ goto_game_over(DEM, `${DEM} wins on Victory Point Track!`)
+ } else if (game.vp < 0) {
+ goto_game_over(COM, `${COM} wins on Victory Point Track!`)
+ } else if (game.vp === 0) {
+ goto_game_over('', `The game is tied!`) /*Not sure what to pass for result */
+ }
+ }
+}
+
+states.game_over = {
+ get inactive() {
+ return game.victory
+ },
+ prompt() {
+ view.prompt = game.victory
+ },
+}
+
+// ========================== EVENT SPECIFIC STATES =================================
+
+states.general_strike = {
+ inactive: 'discard a card.',
+ prompt() {
+ if (game.played_card === 0 ) {
+ view.prompt = 'General Strike: you must discard a card or play a Scoring Card.'
+ available_cards = game.communist_hand
+ for (let card of available_cards) {
+ gen_action_card(card)
+ }
+ } /*else if (game.phase >= 1) {
+ view.prompt = 'General Strike: done.'
+ gen_action('done')
+ } */ else if (game.played_card > 0 ) {
+ view.prompt = 'General Strike: roll a die.'
+ gen_action('roll')
+ }
+ },
+ card (card) {
+ push_undo()
+ game.played_card = card
+ let find_card
+ find_card = game.communist_hand.indexOf(card)
+ game.communist_hand.splice(find_card, 1)
+ game.available_ops = get_card_ops(card)
+ if (scoring_cards.includes(card)) {
+ game.vm_event = card
+ log(`Played C${card} for the event`)
+ game.return_state = 'general_strike'
+ goto_vm(game.vm_event)
+ } else {
+ log(`Discarded C${cards[card].number}`)
+ }
+ },
+ roll() {
+ clear_undo()
+ let roll = Math.floor(Math.random() * 6) + 1
+ log(`Roll: D${roll}`)
+
+ logi(`+${game.available_ops} ops`)
+
+ let total = roll + game.available_ops
+ log(`Total: ${total}`)
+
+ if (total > 5) {
+ log('The strike is over.')
+ permanently_remove(5)
+ game.persistent_events = game.persistent_events.filter(n => n !== 5)
+ } else {
+ log('The strike continues. Required 6 or more')
+ }
+ //game.phase = 1
+ game.state = 'end_round'
+ }, /*
+ done () {
+ //end_round()
+ game.state = 'end_round'
+ }*/
+}
+
+states.honecker ={
+ inactive: 'resolve Honecker.',
+ prompt() {
+ view.prompt = 'Honecker: you may take an extra action round.'
+ gen_action('extra')
+ gen_action('pass')
+ },
+ extra() {
+ push_undo()
+ game.round++
+ game.round_player = COM
+ game.persistent_events = game.persistent_events.filter(n => n !== 15)
+ game.state = 'choose_card'
+ },
+ pass() {
+ log('C15: passed')
+ game.persistent_events = game.persistent_events.filter(n => n !== 15)
+ //end_round()
+ game.state = 'end_round'
+ }
+}
+
+states.new_years_eve_party = {
+ get inactive() {
+ return `resolve ${clean_name(cards[104].name)}.`
+ },
+ prompt() {
+ if (!game.is_pwr_struggle) {
+ view.prompt = `New Year's Eve Party: you may choose a country to have a final power struggle.`
+ if (!game.revolutions[0]) {gen_action('poland')}
+ if (!game.revolutions[1]) {gen_action('hungary')}
+ if (!game.revolutions[2]) {gen_action('east_germany')}
+ if (!game.revolutions[3]) {gen_action('bulgaria')}
+ if (!game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (!game.revolutions[5]) {gen_action('romania')}
+ gen_action('pass')
+ } else {
+ view.prompt = `New Year's Eve Party: done.`
+ gen_action('end')
+ }
+ },
+ east_germany() {
+ push_undo()
+ log('Chose to score East Germany')
+ game.vm_event = 42
+ goto_vm(42)
+ },
+ poland() {
+ push_undo()
+ log('Chose to score Poland')
+ game.vm_event = 22
+ goto_vm(22)
+ },
+ czechoslovakia() {
+ push_undo()
+ log('Chose to score Czechoslovakia')
+ game.vm_event = 55
+ goto_vm(55)
+ },
+ hungary() {
+ push_undo()
+ log('Chose to score Hungary')
+ game.vm_event = 23
+ goto_vm(23)
+ },
+ romania() {
+ push_undo()
+ log('Chose to score Romania')
+ game.vm_event = 95
+ goto_vm(95)
+ },
+ bulgaria () {
+ push_undo()
+ log('Chose to score Bulgaria')
+ game.vm_event = 43
+ goto_vm(43)
+ },
+ pass() {
+ push_undo()
+ log('No final power struggle')
+ if (game.vp > 0) {
+ goto_game_over(DEM, `New Year's Eve Party: ${DEM} wins on Victory Point Track!`)
+ } else if (game.vp < 0) {
+ goto_game_over(COM, `New Year's Eve Party: ${COM} wins on Victory Point Track!`)
+ } else if (game.vp === 0) {
+ goto_game_over('', `New Year's Eve Party: The game is tied!`) /*Not sure what to pass for result */
+ }
+ },
+ end() {
+ if (game.vp > 0) {
+ goto_game_over(DEM, `New Year's Eve Party: ${DEM} wins on Victory Point Track!`)
+ } else if (game.vp < 0) {
+ goto_game_over(COM, `New Year's Eve Party: ${COM} wins on Victory Point Track!`)
+ } else if (game.vp === 0) {
+ goto_game_over('', `CNew 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() {
+ //console.log('game.stasi_card', game.stasi_card)
+ let available_cards = game.democrat_hand
+ if (available_cards.length === 0) {
+ view.prompt = 'Stasi: no cards remaining.'
+ gen_action('pass')
+ return
+ }
+ view.prompt = 'Stasi: you must select your next card to play.'
+
+ for (let card of available_cards) {
+ gen_action_card(card)
+ }
+ },
+ card(card) {
+ push_undo()
+ log_gap(`Democrat selected C${cards[card].number} as next card.`)
+ game.stasi_card = card
+ game.state = 'stasi_finish'
+ },
+ pass() {
+ log('Stasi: Democrat has no remaining cards')
+ game.stasi_card = 0
+ end_stasi_choose_card()
+ },
+ end_round() {
+ push_undo()
+ if (game.stasi_card === 21) {
+ game.state = 'stasi_confirm'
+ } else {
+ end_stasi_choose_card()
+ }
+ }
+}
+
+states.stasi_finish = {
+ inactive: 'choose next card due to Stasi.',
+ prompt() {
+ view.prompt = 'Stasi. Choose card: done.'
+ gen_action('done')
+ },
+ done() {
+ push_undo()
+ if (game.stasi_card === 21) {
+ game.state = 'stasi_confirm'
+ } else {
+ end_stasi_choose_card()
+ }
+ }
+}
+
+states.stasi_confirm = {
+ inactive: 'choose next card due to Stasi.',
+ prompt() {
+ if (game.stasi_card === 21 ) {
+ view.prompt = `If Common European Home selected, it must be played for Operations. Otherwise select the opponent's card instead.`
+ gen_action('done')
+ }
+ },
+ done() {
+ game.playable_cards = game.playable_cards.filter( n => n !== 21)
+ end_stasi_choose_card()
+ }
+}
+
+states.stasi_play_card = {
+ inactive: 'play a card.',
+ prompt () { /*Should get rid of the play card 'done' prompt for consistency with general play */
+ /*if (game.played_card > 0) {
+ game.state = 'play_card'
+ view.prompt = 'Play card: done.'
+ gen_action("done");
+ return;*/
+ //} else
+ if (game.democrat_hand.length === 0) {
+ view.prompt = 'Stasi: you must pass.'
+ gen_action('pass')
+ } else {
+ view.prompt = `Stasi: you must play ${clean_name(cards[game.stasi_card].name)}.`
+ 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${card}`)
+ game.played_card = card
+ let find_card
+ find_card = game.democrat_hand.indexOf(card);
+ game.democrat_hand.splice(find_card, 1);
+ game.available_ops = get_card_ops(card)
+
+ if (game.democrat_hand.includes(21) && cards[card].side === "C") {
+ game.state = 'stasi_resolve_common_european_home'
+ } else {
+ game.state = 'play_card'
+ }
+
+ },
+ pass () {
+ log('No cards remaining. Passed')
+ //end_round()
+ game.state = 'end_round'
+ },
+ done () {
+ //game.stasi_card = 0
+ if (game.democrat_hand.includes(21)) {
+ game.state = 'stasi_resolve_common_european_home'
+ } else {
+ game.state = 'play_card'
+ }
+ }
+}
+
+states.stasi_resolve_common_european_home = {
+ inactive: 'play a card.',
+ prompt () {
+ view.prompt = `Do you wish to play ${clean_name(cards[game.played_card].name)} with Common European Home?`
+ gen_action('yes')
+ gen_action('no')
+ },
+ yes() {
+ log(`Played with Common European Home`)
+ silent_discard(21)
+ game.vm_infl_to_do = true
+ game.vm_event_to_do = false
+ game.state = 'resolve_opponent_event'
+ },
+ no() {
+ game.state = 'play_card'
+ }
+}
+
+
+// ==================== SUPPORTING STATE FUNCTIONS =============================
+
+
+function add_infl(space) {
+ push_undo()
+ //console.log('adding infl to', space)
+ //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 %${space}`)
+ log_summary(`Added £ SP in %${space}`)
+
+ //If AHBR - check AHBR conditions
+ if (game.persistent_events.includes(58)) {
+ if (spaces[space].country !== 'East_Germany'){
+ game.austria_hungary_border_reopened_tracker = false
+ }
+ }
+
+ // Check Genscher
+ if (game.persistent_events.includes(63) && game.active === DEM && spaces[space].country === 'East_Germany' && check_com_control(space)) {
+ game.available_ops--
+ log_summary(`(-1 op due to C63)`)
+ } else if (check_opp_control(space)) {
+ game.available_ops -= 2
+ //Check if Austria Hungary Border Reopened was used to place last SP in a controlled space in East Germany. If so, game.available_op will be negative
+ if (game.available_ops < 0) {
+ log_summary(`(Used +1 op from C58)`)
+ }
+ } else {
+ game.available_ops--
+ }
+
+ // Update influence values
+ if (game.active === COM) {
+ game.comInfl[space]++
+ } else {
+ game.demInfl[space]++
+ }
+
+ // Check whether spaces are controlled
+ check_control_change(space)
+
+ // Check Austria Hungary Border Reopened is true and condition has been met
+ if (game.available_ops === 0 && game.active === DEM && game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker) {
+ game.available_ops ++
+ log('+1 op from C58')
+ game.austria_hungary_border_reopened_tracker = false
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
+ }
+
+ // If only 1 IP remaining, may not place in opponent controlled spaces
+
+ // Check for Genscher & Austria Hungary Border Reopened
+
+ if (game.available_ops === 1) {
+ //console.log(`in Genscher / AHBR check, game.persistent_events['genscher']`, game.persistent_events['genscher'])
+ if (game.active === DEM) {
+ if (game.persistent_events.includes(63) || (game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker)) {
+ //console.log('in gensher subcheck - remove non-East German controlled ')
+ game.valid_spaces = game.valid_spaces.filter(n => !(check_opp_control(n) && spaces[n].country !== 'East_Germany'))
+ } else {
+ //console.log('remove all controlled spaces')
+ game.valid_spaces = game.valid_spaces.filter(n => !check_opp_control(n))
+ }
+ } else {
+ //console.log('remove all dem controlled spaces')
+ game.valid_spaces = game.valid_spaces.filter(n => !check_opp_control(n))
+ }
+ }
+
+ //Clear valid spaces if no IP remaining.
+ if (game.available_ops <= 0 ) {
+ game.valid_spaces = []
+ }
+}
+
+function remove_infl(space) {
+ push_undo()
+ //log(`Removed 1 influence from %${space}.`)
+ log_summary(`Removed £ SP from %${space}.`)
+
+ if (game.remove_opponent_infl === true) {
+ if (game.active === COM) {
+ game.demInfl[space]--
+ if (game.demInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ } else {
+ game.comInfl[space]--
+ if (game.comInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ }
+ check_control_change(space)
+
+ } else {
+ if (game.active === COM) {
+ game.comInfl[space]--
+ if (game.comInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ } else {
+ game.demInfl[space]--
+ if (game.demInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ }
+ check_control_change(space)
+ }
+ game.available_ops--
+}
+
+function do_sc(space) {
+ clear_undo()
+ log_gap(`Support check: %${space}`)
+
+ //Check Helsinki Final Act
+
+ if (game.active === COM && game.persistent_events.includes(26) && (spaces[space].socio === 5 || spaces[space].socio === 6) ) {
+ log('+1 VP from C26')
+ game.vp ++
+ if (check_vp()) {
+ game.state = 'game.over'
+ //console.log('after check_vp, game.state', game.state)
+ return
+ }
+ }
+
+ // Continue with Support Check Logic
+
+ let roll = Math.floor(Math.random() * 6) + 1
+ log(`Roll: D${roll}`)
+
+ /*
+ //Check if support check is being done with game.played_card or a subsequent card (e.g. Common European Home, Dash for the West, etc)
+ if (game.vm_event > 0) {
+ roll+= cards[game.vm_event].ops
+ log(`+${cards[game.vm_event].ops} from card ops`)
+ }
+ */
+ // Check for the Crowd Turns Against Ceausescu
+
+ //else
+ if (game.is_pwr_struggle) {
+ roll += game.vm_available_ops
+ logi(`+${game.vm_available_ops} from Ceausescu`)
+ }
+
+ // Check if in Tiananmen Square Track Award
+
+ else if (game.state === 'vm_tst_6_sc') {
+ roll += get_tst_6_ops()
+ roll += 2
+ logi('+2 TST award')
+ }
+ else {
+ //let modifier = 0
+ let card_ops = get_card_ops(this_card())
+
+ roll += card_ops
+ logi(`+${card_ops} from card ops`)
+ }
+
+ if (game.support_check_modifier > 0) {
+ roll += game.support_check_modifier
+ logi(`+${game.support_check_modifier} from event`)
+ }
+
+ // Events which modify SC rolls
+ //Tear Gas
+ if (game.active === COM && game.persistent_events.includes(30) && spaces[space].socio === 6) {
+ roll ++
+ logi('+1 from C30')
+ permanently_remove(30)
+ game.persistent_events = game.persistent_events.filter(n => n !== 30)
+ }
+ //FRG Embassies
+ if (game.active === DEM && spaces[space].region === 'Eastern Europe' && game.persistent_events.includes(74)) {
+ roll++
+ logi('+1 from C74')
+ }
+ //GrenzTruppen
+ if (game.active === DEM && spaces[space].country === 'East_Germany' && game.persistent_events.includes(59)) {
+ roll--
+ logi('-1 from C59')
+ }
+ //Stand Fast
+ if ((game.active === COM && game.stand_fast === DEM && check_dem_control(space)) || (game.active === DEM && game.stand_fast === COM && check_com_control(space))){
+ roll--
+ logi('-1 from C100')
+ }
+ //Elena
+ if (game.active === DEM && game.persistent_events.includes(101) && spaces[space].country === 'Romania') {
+ roll--
+ logi('-1 from C101')
+ }
+ //Austria Hungary Border Reopened
+ if (game.active === DEM && game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker) {
+ roll++
+ logi(`+1 from C58`)
+ }
+
+ // Continue with logic - check for adjacency
+
+ // Events which affect adjacency - The Wall
+
+ const adj = count_adj(space)
+ //console.log('adj', adj)
+ if (game.active === COM && game.persistent_events.includes(9) && spaces[space].country === 'East_Germany') {
+ logi('No adjacency for Democrats due to C9')
+ logi('C9 no longer in effect')
+ roll += adj.com_adj
+ if (adj.com_adj > 0) {
+ logi(`+${adj.com_adj} adjacency`)
+ }
+ game.persistent_events = game.persistent_events.filter(n => n !== 9)
+
+ // Standard adjacency
+ } else {
+ if (adj.dem_adj > 0 || adj.com_adj > 0 ){
+ if (game.active === DEM) {
+ roll += adj.dem_adj
+ roll -= adj.com_adj
+ if (adj.dem_adj > 0) {
+ logi(`+${adj.dem_adj} from adjacency`)
+ }
+ if (adj.com_adj > 0) {
+ logi(`-${adj.com_adj} from opponent adjacency`)
+ }
+ } else {
+ roll += adj.com_adj
+ roll -= adj.dem_adj
+ if (adj.com_adj > 0) {
+ logi(`+${adj.com_adj} from adjacency`)
+ }
+ if (adj.dem_adj > 0) {
+ logi(`-${adj.dem_adj} from opponent adjacency`)
+ }
+ }
+ }
+
+ }
+
+ // Support check calcs
+ log(`Modified total: ${roll}`)
+ const stability = spaces[space].stability
+ logi(`-${stability*2} (stability * 2)`)
+ const change_infl = Math.max(0, roll - stability*2)
+ if (change_infl > 0) {
+ log_msg_gap(`Change influence: ${change_infl} SP`)
+ if(game.active === DEM) {
+ if (change_infl > game.comInfl[space]) {
+ const residual = change_infl - game.comInfl[space]
+ game.comInfl[space] = 0
+ game.demInfl[space] += residual
+ } else {
+ game.comInfl[space] -= change_infl
+ }
+ if (game.comInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space)
+ }
+ } else {
+ if (change_infl > game.demInfl[space]) {
+ const residual = change_infl - game.demInfl[space]
+ game.demInfl[space] = 0
+ game.comInfl[space] += residual
+ } else {
+ game.demInfl[space] -= change_infl
+ }
+ if (game.demInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space)
+ }
+ }
+ check_control_change(space)
+
+ } else {
+ log_msg_gap('Change influence: 0 SP')
+ }
+ if (game.active === COM && game.persistent_events.includes(39) && spaces[space].space_id === 66) {
+ log_msg_gap('+1 VP from C39')
+ game.vp++
+ if (check_vp()) {
+ return
+ }
+ }
+
+ // If Austria-Hungary Border Reopened used, all future support checks must be in East Germany
+ if (game.persistent_events.includes(58)){
+ if (game.austria_hungary_border_reopened_tracker) {
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
+ }
+ }
+ game.selected_space = 0
+
+}
+
+function valid_spaces_setup() {
+ game.valid_spaces = []
+ let valid_spaces_set = new Set();
+ //console.log('in vs setup, state', game.state)
+ for (let i =1 ; i <= 75 ; i++) {
+ space = spaces[i]
+
+ if (game.state === 'com_init') {
+ infl = game.demInfl[i]
+
+ if (infl === 0) {
+ valid_spaces_set.add(space.space_id);
+ }
+ } else if (game.state === 'dem_init') {
+ infl = game.comInfl[i]
+ if (infl === 0) {
+ valid_spaces_set.add(space.space_id);
+ }
+ }
+ }
+ // Convert the set to an array before returning
+ game.valid_spaces = Array.from(valid_spaces_set);
+ return game.valid_spaces;
+}
+
+function valid_spaces_sc() {
+ let valid_spaces_set = new Set();
+ //console.log('valid spaces sc, persistent events', game.persistent_events)
+
+ for (let i = 1 ; i <= 75; i++) {
+ space = spaces[i]
+
+ if (game.active === DEM) {
+ infl = game.comInfl[i]
+ if (infl !== 0 ) {
+ valid_spaces_set.add(space.space_id);
+ }
+ } else {
+ infl = game.demInfl[i]
+ if (infl !== 0 ) {
+ // Check Solidarity Legalised
+ if (game.persistent_events.includes(2) && space.space_id === 14) {continue}
+
+ // Check Civic Forum
+ if (game.persistent_events.includes(90) && space.space_id === 30) {continue}
+
+ // Check We Are the People
+ if (game.persistent_events.includes(48) && space.space_id === 9) {continue}
+
+ //Check for Foreign Currency Debt Burden
+ if (game.persistent_events.includes(49) && space.country === game.foreign_currency_debt_burden) {continue} {
+
+ valid_spaces_set.add(space.space_id);
+
+ }
+ }
+ }
+ }
+
+
+ // Convert the set to an array before returning
+ game.valid_spaces = Array.from(valid_spaces_set);
+
+ //Check for the Crown Turns Against Ceausescu
+ if (game.is_pwr_struggle && game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(54)) {
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'Romania')
+ }
+ return game.valid_spaces;
+}
+
+function valid_spaces_support_loss() {
+ let valid_spaces_set = new Set();
+ for (let i = 1; i < game.demInfl.length; i++) {
+ //console.log('spaces.length', game.demInfl.length, 'i', i)
+ space = spaces[i]
+ if (game.active === DEM) {
+ infl = game.demInfl[i]
+ if (infl > 0 && space.country === game.pwr_struggle_in) {
+ valid_spaces_set.add(space.space_id);
+ }
+ } else {
+ infl = game.comInfl[i]
+ if (infl > 0 && space.country === game.pwr_struggle_in) {
+ valid_spaces_set.add(space.space_id);
+ }
+ }
+ }
+
+ // Convert the set to an array before returning
+ game.valid_spaces = Array.from(valid_spaces_set);
+ return game.valid_spaces;
+}
+/*
+function valid_spaces_support_falters() {
+ let valid_spaces_set = new Set();
+ if (game.active === DEM) {
+ for (let piece of game.pieces) {
+ if (!piece) continue
+ let space = spaces.find(s => s && s.space_id === piece.space_id);
+ if (space && piece.comInfl > 0 && space.country === game.pwr_struggle_in) {
+ valid_spaces_set.add(space.space_id);
+ }
+ }
+ } else {
+ for (let piece of game.pieces) {
+ if (!piece) continue
+ let space = spaces.find(s => s && s.space_id === piece.space_id);
+ if (space && piece.demInfl > 0 && space.country === game.pwr_struggle_in) {
+ valid_spaces_set.add(space.space_id);
+ }
+ }
+ }
+ // Convert the set to an array before returning
+ game.valid_spaces = Array.from(valid_spaces_set);
+ return game.valid_spaces;
+}
+ */
+
+function valid_spaces_infl() {
+ /*if (game.state.startsWith('vm')) {
+ console.log('valid_spaces_infl called from VM')
+ } else {
+ console.log('valid_spaces_infl called not from VM')
+ }*/
+ // Check if function is called from the VM or not, take relevant ops variable
+ let ops = game.state.startsWith('vm') ? game.vm_available_ops : game.available_ops;
+
+ let valid_spaces_set = new Set();
+ // Iterate over all spaces to find the ones with the player's influence
+ for (let i = 1; i < game.demInfl.length; i++) {
+ //piece = game.pieces[i]
+ space = spaces[i]
+
+ let player_influence = game.active === COM ? game.comInfl[i] : game.demInfl[i];
+
+ // If the piece has the player's influence, add it and its adjacent spaces to the set
+ if (player_influence > 0) {
+ valid_spaces_set.add(space.space_id);
+
+ // Check adjacency information
+ let adjacent_spaces = get_adjusted_adjacency(space.space_id)
+
+ for (let adj_space_id of adjacent_spaces) {
+ //console.log('adj_space_id', adj_space_id)
+ if (adj_space_id) {
+
+ const adj_piece = spaces[adj_space_id];
+ //console.log('adjacent piece name', adj_piece.name_unique)
+
+ // Check if the adjacent space is controlled by the opponent
+ const opponent_control = check_opp_control(adj_piece.space_id)
+ //console.log('controlled?', opponent_control)
+
+ //Check for Genscher. Can always place in East Germany even with 1 op
+ if (game.active === DEM && adj_piece.country === 'East_Germany' && game.persistent_events.includes(63)){
+ // console.log('space added with genscher')
+ valid_spaces_set.add(adj_piece.space_id)
+ }
+
+ // Otherwise, only add the adjacent space if the available_ops >= 2 or the space is not controlled by the opponent
+ if (ops >= 2 || !opponent_control) {
+ valid_spaces_set.add(adj_piece.space_id)
+ }
+ }
+ }
+ }
+ }
+ // Convert the set to an array before returning
+ game.valid_spaces = Array.from(valid_spaces_set);
+ return game.valid_spaces;
+}
+
+function valid_cards(player_hand, presence) {
+ const valid_cards_set= new Set();
+ if (game.phase === 0) {
+ for (let c of player_hand) {
+ let card = power_cards.find(card => card && card.number === c);
+ if (card.number === 52) {continue} // Never add tactics fails
+ if (card.name === game.tactics_fails) {continue} //Cannot play the suit of Tactics Fails
+ if (card.socio === 0) {
+ valid_cards_set.add(card.number);
+ } else if (leaders.includes(card.socio) && presence[card.socio]) {
+ valid_cards_set.add(card.number);
+ }
+ }
+ } else if (game.phase === 1) {
+ for (let c of player_hand) {
+ let card = power_cards.find(card => card && card.number === c);
+ if (card.name === power_cards[game.played_power_card].name) {
+ valid_cards_set.add(card.number);
+ } else if (leaders.includes(card.socio) && presence[card.socio]) {
+ valid_cards_set.add(card.number);
+ } else if (card.number === 52) {valid_cards_set.add(card.number)}
+ }
+ }
+ game.valid_cards = Array.from(valid_cards_set);
+ return game.valid_cards;
+}
+
+function do_valid_cards() {
+ let presence = check_presence(game.pwr_struggle_in)
+ if (game.active === DEM) {
+ valid_cards(game.dem_pwr_hand, presence.dem_leaders)
+
+ } else {
+ valid_cards(game.com_pwr_hand, presence.com_leaders)}
+}
+
+function count_adj(id) {
+ const space = spaces[id]
+ let dem_adj = 0
+ let com_adj = 0
+
+ let adjacent_spaces = get_adjusted_adjacency(space.space_id)
+
+ for (let adj_space_id of adjacent_spaces) {
+ if (adj_space_id) {
+ const adj_piece = spaces.find(piece => piece && piece.space_id === adj_space_id);
+ //console.log('adj_piece.space_id', adj_piece.space_id, 'space', space)
+ if (adj_piece && adj_piece.space_id !== space.space_id) {
+ if (check_dem_control(adj_piece.space_id)) {
+ //console.log('added DEM space', spaces[adj_piece.space_id].name)
+ dem_adj++
+ }
+ if (check_com_control(adj_piece.space_id)) {
+ //console.log('added COM space', spaces[adj_piece.space_id].name)
+ com_adj++
+ }
+ }
+ }
+ }
+ //console.log('dem_adj: ', dem_adj, 'com_adj: ', com_adj)
+ return {dem_adj, com_adj}
+}
+
+/*function count_adj_worker(space_id) {
+ const space = spaces[space_id]
+ let dem_adj = 0
+ let com_adj = 0
+
+ for (let adj_space_id of space.adjacent) {
+ if (adj_space_id) {
+ const adj_space = spaces[adj_space_id]
+ if (adj_space && adj_space.socio === 4) {
+ const adj_piece = game.pieces.find(piece => piece && piece.space_id === adj_space_id );
+ if (adj_piece) {
+ if (adj_piece.demCtrl === 1 ) {
+ dem_adj++
+ }
+ if (adj_piece.comCtrl === 1 ) {
+ com_adj++
+ }
+ }
+ }
+ }
+ }
+ return {dem_adj, com_adj}
+} */
+
+function check_control(space_id) {
+ //console.log('in check control, space', spaces[space_id].name_unique)
+ if ( (game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) {
+ return true;
+ } else if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) {
+ //console.log('true')
+ return true;
+ } else {
+ //console.log('false')
+ return false;
+ }
+}
+
+function check_opp_control(space_id) {
+ if (spaces[space_id].country === 'Romania') {
+ //console.log('in check opp control, space', spaces[space_id].name_unique)
+ }
+ if (game.active === DEM && ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability)) {
+ if (spaces[space_id].country === 'Romania') {
+ //console.log('control true')
+ }
+ return true;
+ } else if (game.active === COM && ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability)) {
+ //console.log('true')
+ return true;
+ } else {
+ //console.log('false')
+ return false;
+ }
+}
+
+function check_dem_control(space_id) {
+ if ((game.demInfl[space_id] - game.comInfl[space_id]) >= spaces[space_id].stability) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+function check_com_control(space_id) {
+ if ((game.comInfl[space_id] - game.demInfl[space_id]) >= spaces[space_id].stability) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+function do_tst_attempt() {
+ let roll = Math.floor(Math.random() * 6) + 1;
+ log(`Roll: D${roll}`);
+
+ roll += game.available_ops
+ logi(`+${game.available_ops} from card ops`)
+
+ // TIANANMEN SQUARE MODIFIERS
+
+ if (game.active === DEM && game.dem_tst_attempted === 1 || game.active === COM && game.com_tst_attempted === 1) {
+ roll ++;
+ logi('+1 from previous TST attempts')
+ }
+ if (game.active === DEM && game.dem_tst_position >= 1 && game.com_tst_position === 0) {
+ roll ++
+ logi('+1 from TST award')
+ }
+ if (game.active === COM && game.com_tst_position >= 1 && game.dem_tst_position === 0) {
+ roll ++
+ logi('+1 from TST award')
+ }
+ if ((game.active === DEM && cards[game.played_card].side === 'D') || (game.active === COM && cards[game.played_card].side === 'C')) {
+ roll ++;
+ logi('+1 for playing own card');
+ }
+ if (game.active === COM && game.persistent_events.includes(53)) {
+ roll ++
+ logi('+1 from C53')
+ }
+ log(`Modified total: ${roll}`)
+
+ // TIANANMEN SQUARE ATTEMPT
+ game.return = game.active
+ game.return_state = 'tiananmen_square_attempt_done'
+ if (game.active === DEM) {
+ game.dem_tst_attempted_this_turn = 1
+ if (roll >= dem_tst_req[game.dem_tst_position]) {
+ log(`${dem_tst_req[game.dem_tst_position]} required: success`)
+ game.dem_tst_position++
+ game.dem_tst_attempted = 0
+
+ //Check if they have reached box 7 or 8 first
+ if (game.dem_tst_position === 7 && game.com_tst_position < 7) {
+ game.tst_7 = false
+ }
+ if (game.dem_tst_position === 8 && game.com_tst_position < 8) {
+ game.tst_8 = false
+ }
+
+ //Check if they have caught up to box 7 or 8
+ if (game.dem_tst_position >= 7 && game.com_tst_position >= 7) {
+ delete game.tst_7
+ }
+ if (game.dem_tst_position >= 8 && game.com_tst_position >= 8) {
+ delete game.tst_8
+ }
+
+ //Check if TST events occur
+ if (game.dem_tst_position === 3 && game.com_tst_position < 3) {game.vm_event = 203}
+ else if (game.dem_tst_position === 4 && game.com_tst_position < 4) {game.vm_event = 204}
+ game.state = 'tiananmen_square_attempt_success'
+ } else {
+ log(`${dem_tst_req[game.dem_tst_position]} required: fail`)
+ game.dem_tst_attempted = 1
+ game.state = 'tiananmen_square_attempt_fail'
+ }
+ } else {
+ game.com_tst_attempted_this_turn = 1
+ if (roll >= com_tst_req[game.com_tst_position]) {
+ log(`${com_tst_req[game.com_tst_position]} required: success`)
+ game.com_tst_position++
+ game.com_tst_attempted = 0
+
+ //Check if they have reached box 7 or 8 first
+ if (game.com_tst_position === 7 && game.dem_tst_position < 7) {
+ game.tst_7 = false
+ }
+ if (game.com_tst_position === 8 && game.dem_tst_position < 8) {
+ game.tst_8 = false
+ }
+
+ //Check if they have caught up to box 7 or 8
+ if (game.com_tst_position >= 7 && game.dem_tst_position >= 7) {
+ delete game.tst_7
+ }
+ if (game.com_tst_position >= 8 && game.dem_tst_position >= 8) {
+ delete game.tst_8
+ }
+
+ //Check if TST events occur
+ if (game.com_tst_position === 3 && game.dem_tst_position < 3) {game.vm_event = 203}
+ else if (game.com_tst_position === 4 && game.dem_tst_position < 4) {game.vm_event = 204}
+ game.state = 'tiananmen_square_attempt_success'
+ } else {
+ log(`${com_tst_req[game.com_tst_position]} required: fail`)
+ game.com_tst_attempted = 1
+ game.state = 'tiananmen_square_attempt_fail'
+ }
+ }
+}
+
+function check_presence(country) {
+
+ let dem_spaces = 0;
+ let com_spaces = 0;
+ let dem_battlegrounds = 0;
+ let com_battlegrounds = 0;
+ let dem_leaders = {1: false, 4: false, 5: false, 6: false, 7: false};
+ let com_leaders = {1: false, 4: false, 5: false, 6: false, 7: false};
+
+
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (space.country === country) {
+
+ if (check_dem_control(i)) {
+ dem_spaces++;
+ if (space.battleground === 1) {
+ dem_battlegrounds++;
+ }
+ if (leaders.includes(space.socio)) {
+ dem_leaders[space.socio] = true;
+ }
+ }
+ if (check_com_control(i)) {
+ com_spaces++;
+ if (space.battleground === 1) {
+ com_battlegrounds++;
+ }
+ if (leaders.includes(space.socio)) {
+ com_leaders[space.socio] = true;
+ }
+ }
+ }
+ }
+
+ // Determine domination
+ let dem_domination = dem_battlegrounds > com_battlegrounds && dem_spaces > com_spaces && dem_spaces - dem_battlegrounds > 0;
+ let com_domination = com_battlegrounds > dem_battlegrounds && com_spaces > dem_spaces && com_spaces - com_battlegrounds > 0;
+
+ // Determine control
+ let total_battlegrounds = battlegrounds(country);
+ let dem_control = dem_battlegrounds === total_battlegrounds && dem_spaces > com_spaces;
+ let com_control = com_battlegrounds === total_battlegrounds && com_spaces > dem_spaces;
+
+ return {
+ dem_spaces: dem_spaces,
+ com_spaces: com_spaces,
+ dem_battlegrounds: dem_battlegrounds,
+ com_battlegrounds: com_battlegrounds,
+ dem_domination: dem_domination,
+ com_domination: com_domination,
+ dem_control: dem_control,
+ com_control: com_control,
+ dem_leaders: dem_leaders,
+ com_leaders: com_leaders
+ };
+}
+
+function battlegrounds(country) {
+ let battlegrounds = 0;
+ if (country === "Hungary") {
+ battlegrounds = 4
+ } else if (country === "Bulgaria") {
+ battlegrounds = 5
+ } else {
+ battlegrounds = 6
+ }
+ return battlegrounds;
+}
+
+function take_power(country) {
+
+ log(`Democrat takes power in ${game.pwr_struggle_in}`)
+ game.revolutions[find_country_index(country)] = true
+ game.times_held[find_country_index(country)] = 1
+
+}
+
+function retain_power(country){
+ game.times_held[find_country_index(country)]++
+ let vp_gain = get_value(country)*game.times_held[find_country_index(country)]
+ log(`Chooses to retain power`)
+ log(`-${vp_gain} VP`)
+ game.vp -= vp_gain
+}
+
+function score_country(country) {
+ log_h3(`Scoring: ${country}`)
+
+//Get scoring values
+ let value_presence = get_value(country)
+ let value_domination = value_presence*2
+ let value_control
+ if (country !== "Hungary") {
+ value_control = value_presence*3
+ } else {
+ value_control = 4
+ }
+//Log for scoring
+
+ let dem_vp = 0
+ let com_vp = 0
+ //Check for presence
+ let presence = check_presence(country)
+// console.log('presence: ', presence)
+
+ //If one side has domination or control
+ if (presence.dem_control || presence.dem_domination) {
+ log(`Democrat:`)
+ if (presence.dem_control) {
+ log(`Control: +${value_control} VP`)
+ dem_vp += value_control
+ }
+ else {
+ log(`Domination: +${value_domination} VP`)
+ dem_vp += value_domination
+ }
+ log(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
+ dem_vp += presence.dem_battlegrounds
+ log(`Total: +${dem_vp} VP`)
+
+ log_gap('Communist:')
+ if (presence.com_spaces > 0) {
+ log(`Presence: -${value_presence} VP`)
+ com_vp -= value_presence
+ if (presence.com_battlegrounds >0) {
+ log(`Battlegrounds: -${presence.com_battlegrounds} VP`)
+ com_vp -= presence.com_battlegrounds
+ }
+ log(`Total: ${com_vp} VP`)
+ } else {
+ log('No presence: 0 VP')
+ }
+
+ }
+ else if (presence.com_control || presence.com_domination) {
+ log('Communist:')
+ if (presence.com_control) {
+ log(`Control: -${value_control} VP`)
+ com_vp -= value_control
+ }
+ else {
+ log(`Domination: -${value_domination} VP`)
+ com_vp -= value_domination
+ }
+ log(`Battlegrounds: -${presence.com_battlegrounds} VP`)
+ com_vp -= presence.com_battlegrounds
+ log(`Total: ${com_vp} VP`)
+
+ log_gap('Democrat:')
+ if (presence.dem_spaces > 0) {
+ log(`Presence: +${value_presence} VP`)
+ dem_vp += value_presence
+ if (presence.dem_battlegrounds > 0) {
+ log(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
+ dem_vp += presence.dem_battlegrounds
+ }
+ log (`Total: +${dem_vp} VP`)
+ } else {
+ log('No presence: 0 VP')
+ }
+
+ }
+
+ //Otherwise, presence and battlegrounds
+ else {
+ log("No domination or control")
+ log_gap(`Communist:`)
+ if (presence.com_spaces > 0) {
+ log(`Presence: -${value_presence} VP`)
+ com_vp -= value_presence
+ if (presence.com_battlegrounds > 0) {
+ log(`Battlegrounds: -${presence.com_battlegrounds} VP`)
+ com_vp -= presence.com_battlegrounds
+ } else {
+ log('No battlegrounds')
+ }
+ log(`Total: ${com_vp} VP`)
+ } else {
+ log('No presence: 0 VP')
+ }
+ log_gap('Democrat:')
+ if (presence.dem_spaces > 0) {
+ log(`Presence: +${value_presence} VP`)
+ dem_vp += value_presence
+ if (presence.dem_battlegrounds > 0) {
+ log(`Battlegrounds: +${presence.dem_battlegrounds} VP`)
+ dem_vp += presence.dem_battlegrounds
+ } else {
+ log('No battlegrounds')
+ }
+ log(`Total: +${dem_vp} VP`)
+ } else {
+ log('No presence: 0 VP')
+ }
+ }
+
+
+//Calculate change VP
+ /*let dem_vp = 0
+ if (presence.dem_spaces > 0) {dem_vp += value_presence}
+ if (presence.dem_domination) {dem_vp += value_presence}
+ if (presence.dem_control && country !== "Hungary") {
+ dem_vp += value_control
+ }
+ else if (presence.dem_control && country === "Hungary") {dem_vp += 2}
+ dem_vp += presence.dem_battlegrounds
+
+ let com_vp = 0
+ if (presence.com_spaces > 0) {com_vp += value_presence}
+ if (presence.com_domination) {com_vp += value_presence}
+ if (presence.com_control && country !== "Hungary") {com_vp += value_presence}
+ else if (presence.com_control && country === "Hungary") {com_vp += 2}
+ com_vp += presence.com_battlegrounds */
+ let change_vp = dem_vp + com_vp
+ game.vp += change_vp
+ if (change_vp > 0 ) {
+ log_gap(`Final change VP: +${change_vp} VP`)
+ } else {
+ log_gap(`Final change VP: ${change_vp} VP`)
+ }
+}
+
+function get_value(country) {
+ let value
+ if (country === "East_Germany" || country === "Poland") {value = 3}
+ else if (country === "Czechoslovakia" || country === "Romania") {value = 2}
+ else value = 1
+ return value
+}
+
+function get_end_infl_prompt() {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Add SPs: done.`
+ if (!game.vm_infl_to_do) {
+ gen_action('end_round')
+ } else {
+ gen_action('done')
+ }
+}
+
+function permanently_remove(card) {
+ //console.log('permanently removing card:', card)
+ if (game.strategy_removed.includes(card)) {return}
+ //log_msg_gap(`C${cards[card].number} permanently removed`)
+ remove_from_discard(card)
+
+ card_index = game.table_cards.indexOf(card)
+ if (card_index !== -1) {
+ //console.log('sub 2 called')
+ game.table_cards.splice(card_index, 1)
+ }
+ game.strategy_removed.push(card)
+ //console.log('game.strategy_removed', game.strategy_removed)
+}
+
+function check_vp() {
+ if (game.vp >= 20) {
+ goto_game_over(DEM, `${DEM} won an Automatic Victory!`)
+ //console.log('after goto_game_over, game.state', game.state)
+ return true
+ } else if(game.vp <= -20) {
+ goto_game_over(COM, `${COM} won an Automatic Victory!`)
+ return true
+ }
+ return false
+}
+
+function game_over() {
+ if (game.vp >= 20 || game.vp <= -20) {
+ return true
+ } else { return false}
+}
+
+function goto_game_over(result, victory) {
+ game.state = "game_over"
+ game.active = "None"
+ game.result = result
+ game.victory = victory
+ log_h1("Game Over")
+ log(game.victory)
+ //console.log('game over, game.state', game.state)
+ return
+
+}
+
+function reset_austria_hungary_border_reopened() {
+ //game.austria_hungary_border_reopened_checked = false
+ game.austria_hungary_border_reopened_tracker = false
+}
+
+function end_stasi_choose_card() {
+ game.round_player = COM
+ game.round ++
+ log_h2(`Action Round ${game.round}`)
+ next_player()
+ game.valid_spaces = []
+ if (game.persistent_events.includes(5)) {
+ log_h3('C5')
+ game.state = 'general_strike'
+ } else {
+ game.state = 'choose_card'
+ }
+}
+
+function check_reformer() {
+ if (game.dem_tst_position !== game.com_tst_position) {
+ if (!game.playable_cards.includes(67)) {
+ game.playable_cards.push(67)
+ }
+ } else {
+ game.playable_cards = game.playable_cards.filter(n => n !== 67)
+ }
+
+}
+
+function count_scoring_cards() {
+ let scoring_check
+ if (game.active === DEM) {
+ scoring_check = game.democrat_hand.filter(card => scoring_cards.includes(card)).length
+ } else {
+ scoring_check = game.communist_hand.filter(card => scoring_cards.includes(card)).length
+ }
+ return scoring_check
+}
+
+function select_card(card){
+ game.played_card = card
+ game.temp = 0
+ let find_card
+ if (game.active === COM) {
+ find_card = game.communist_hand.indexOf(card)
+ game.communist_hand.splice(find_card, 1)
+ } else {
+ find_card = game.democrat_hand.indexOf(card)
+ game.democrat_hand.splice(find_card, 1)
+ }
+ game.available_ops = get_card_ops(card)
+
+ //Check Ligachev
+ if (game.active === DEM && game.persistent_events.includes(99) && card !== 14) {
+ log('-3 VP from C99')
+ game.vp -= 3
+ if (check_vp()) {
+ return
+ }
+ game.persistent_events = game.persistent_events.filter(n => n !== 99)
+ }
+ game.state = 'play_card'
+ //console.log('game.state', game.state)
+}
+
+function find_event(card) {
+ return variable_events.indexOf(card)
+}
+
+function is_auto_resolve(card) {
+
+ let ceausecu_events = [10, 41, 101, 107]
+
+ if (card === 97) {
+ if (!game.persistent_events.includes(54)) {
+ return true
+ }
+ }
+ else if (ceausecu_events.includes(card) && game.persistent_events.includes(97)) {
+ return true
+ }
+ else if (card === 87 && !game.persistent_events.includes(86)) {
+ return true
+ }
+ else if (auto_resolve_events.includes(card)) {
+ return true
+ } else {
+ return false
+ }
+}
+
+function get_events(card){
+ if (event_is_playable(card)) {
+ if (cards[card].side === 'D') {
+ if (game.active === DEM) {gen_action('event')}
+ if (game.active === COM) {gen_action('opp_event')}
+ }
+ else if (cards[card].side === 'C') {
+ if (game.active === COM) {gen_action('event')}
+ if (game.active === DEM) {gen_action('opp_event')}
+ }
+ else {
+ gen_action('event')
+ }
+ }
+}
+
+function event_is_playable(card) {
+// console.log('game.stasi_card', game.stasi_card, 'card', card)
+ //Reformer never playable here
+ if (card === 67) {
+ return false
+ }
+ //Check for Common European Hmme under Stasi
+ else if (game.stasi_card === 21 && card === 21 && game.active === DEM) {
+ return false
+ }
+ //Check for The Chinese Solution
+ else if (game.com_tst_position === 8 && card === 96) {
+ return true
+ }
+ //Then check normally
+ else if (cards[card].playable) {
+ return true
+ } else if (game.playable_cards.includes(card)) {
+ return true
+ } else {
+ return false
+ }
+}
+
+function get_card_ops(card) {
+ let ops = 0
+
+ if (card) {
+ ops = cards[card].ops
+ }
+ if (game.persistent_events.includes(25) && game.active === COM) {
+ if(game.state === 'choose_card' || game.state === 'stasi_play_card') {
+ log('+1 op from C25')
+ }
+ ops ++
+ }
+ if (game.persistent_events.includes(50) && game.active === DEM) {
+ if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_laszlo_tokes') {
+ log('+1 op from C50')
+ }
+ ops ++
+ }
+
+ if ((game.active === DEM && game.dem_tst_position >= 2 && game.com_tst_position <= 1 && cards[card].ops === 1) || (game.active === COM && game.com_tst_position >=2 && game.dem_tst_position <= 1 && cards[card].ops === 1)) {
+ if(game.state === 'choose_card' || game.state === 'stasi_play_card') {
+ log('+1 op from Tiananmen Square Track')
+ }
+ ops ++
+ }
+
+ if ((game.active === DEM && game.prudence && game.prudence.DEM !== 0)) {
+ if(game.state === 'choose_card' || game.state === 'stasi_play_card' || game.state === 'vm_laszlo_tokes') {
+ if (ops > 2) {
+ log(`${pluralize(game.prudence.DEM,'op')} from C8`)
+ } else {
+ if (ops > 1) {
+ log(`-1 op from C8`)
+ }
+ }
+ }
+ ops += game.prudence.DEM
+
+ if (ops < 1) {
+ ops = 1
+ }
+ }
+
+ if (game.active === COM && game.prudence && game.prudence.COM < 0) {
+ if(game.state === 'choose_card') {
+ if (ops > 2) {
+ log(`${pluralize(game.prudence.COM,'op')} from C8`)
+ } else if (ops > 1) {
+ log(`-1 op from C8`)
+ }
+ }
+ ops += game.prudence.COM
+ if (ops < 1) {
+ ops = 1
+ }
+ } return ops
+}
+
+function get_tst_6_ops() {
+ let ops = 0
+
+ if (game.persistent_events.includes(25) && game.active === COM) {
+ log('+1 op from C25')
+ ops ++
+ }
+ if (game.persistent_events.includes(50) && game.active === DEM) {
+ log('+1 op from C50')
+ ops ++
+ }
+
+ if ((game.active === DEM && game.prudence && game.prudence.DEM !== 0)) {
+ if (ops > 0) {
+ log(`${pluralize(game.prudence.DEM,'op')} from C8`)
+ } else {
+ log(`-1 op from C8`)
+ }
+
+ ops += game.prudence.DEM
+
+ if (ops < -1) {
+ ops = -1
+ }
+ }
+
+ if (game.active === COM && game.prudence && game.prudence.COM < 0) {
+
+ if (ops > 0) {
+ log(`${pluralize(game.prudence.COM,'op')} from C8`)
+ } else {
+ log(`-1 op from C8`)
+ }
+
+ ops += game.prudence.COM
+ if (ops < -1) {
+ ops = -1
+ }
+ }
+ return ops
+}
+
+function finish_the_wall() {
+ if (game.the_wall_must_go['dem_wins'] === 2) {
+ game.persistent_events.push(86)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (space.country === 'East_Germany' && game.comInfl[i] > 0){
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ if (!game.vm_infl_to_do) {
+ if (game.round_player === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ }
+ if (game.active === DEM) {next_player()}
+ vm_next ()
+ } else {
+ permanently_remove(86)
+ delete game.the_wall_must_go
+ vm_return()
+ }
+}
+
+
+// =========== MOVING THROUGH TURNS ============
+
+function end_round() {
+// console.log('end round, game.persistent_events.includes(13)', game.persistent_events.includes(13))
+ //Check if the game is over!
+ if (game.state === 'game_over') {
+ // console.log('in end')
+ return}
+
+ //Check if the card has been removed or played to table, and if a card has been not been played. If not, discard.
+ if (!game.strategy_removed.includes(game.played_card) && !game.table_cards.includes(game.played_card) && game.played_card > 0) {
+ game.strategy_discard.push(game.played_card)
+ }
+
+ //Reset
+ game.played_card = 0
+ game.temp = 0
+ game.vm_event = 0
+ game.phase = 0
+ game.remove_opponent_infl = false
+ game.is_pwr_struggle = false
+ game.vm_infl_to_do = false /*Can get rid of this and use game.return_state? */
+ game.vm_event_to_do = false
+ game.vm_active_country = ''
+ game.return_state = ''
+ game.discard = false
+ game.return = ''
+ game.valid_cards = []
+ game.valid_spaces = []
+ check_common_european_home()
+ //game.playable_cards[find_event(21)] = true
+ reset_austria_hungary_border_reopened() /*This should be redundant! */
+
+
+ // Check for duplicate card entries
+ let card_check
+ if (game.samizdat_card > 0) {
+ card_check = [...game.strategy_deck, ...game.strategy_discard, ...game.strategy_removed, ...game.table_cards, ...game.communist_hand, ... game.democrat_hand, game.samizdat_card];
+ } else {
+ card_check = [...game.strategy_deck, ...game.strategy_discard, ...game.strategy_removed, ...game.table_cards, ...game.communist_hand, ... game.democrat_hand];
+ }
+
+ function check_duplicates(array) {
+ return new Set(array).size !== array.length;
+ }
+
+ function find_duplicates(array) {
+ const duplicates = array.filter((item, index) => array.indexOf(item) !== index);
+ return [...new Set(duplicates)];
+ }
+
+ //console.log('game.strategy_deck', game.strategy_deck, 'game.strategy_discard', game.strategy_discard, 'game.strategy_removed', game.strategy_removed, 'game.table_cards', game.table_cards, 'game.communist_hand', game.communist_hand, 'game.democrat_hand', game.democrat_hand)
+
+ if (check_duplicates(card_check)) {
+ console.log('card check', card_check)
+ const duplicates = find_duplicates(card_check)
+ console.log('game.strategy_deck', game.strategy_deck, 'game.strategy_discard', game.strategy_discard, 'game.strategy_removed', game.strategy_removed, 'game.table_cards', game.table_cards, 'game.communist_hand', game.communist_hand, 'game.democrat_hand', game.democrat_hand)
+ throw new Error(`Duplicate cards detected: ${duplicates.join(', ')}`)
+ }
+ //console.log('cards in game', card_check.length)
+ card_check = card_check.sort((a, b) => a - b)
+ //console.log('cards in game', card_check)
+ if (game.turn <= 3) {
+ if (card_check.length !== 40) {
+ throw new Error(`Wrong number of cards: ${card_check.length}`)
+ }
+ } else if (game.turn <=7) {
+ if (card_check.length !== 81) {
+ throw new Error(`Wrong number of cards: ${card_check.length}`)
+ }
+ } else if (card_check.length !== 110) {
+ throw new Error(`Wrong number of cards: ${card_check.length}`)
+ }
+
+
+
+ //console.log('game.dem_tst_position ', game.dem_tst_position , 'game.com_tst_position ', game.com_tst_position )
+ //Check if the Reformer is playable
+ check_reformer()
+
+ // Check if last round and if so resolve end turn events
+ if (game.round_player === DEM && game.round === 7) {
+ if(game.persistent_events.includes(15)) {
+ if (game.active !== COM) {
+ next_player()
+ }
+ game.state = 'honecker'
+ return
+ }
+ else if (game.dem_tst_position >= 6 && game.com_tst_position <= 5) {
+ log_h2('Tiananmen Square Track Award')
+ if (game.active !== DEM) {
+ next_player()
+ }
+ game.return = game.active
+ clear_undo()
+ game.return_state = 'end_turn_4_5_4'
+ goto_vm(206)
+ return
+ } else if (game.com_tst_position >= 6 && game.dem_tst_position <= 5) {
+ log_h2('Tiananmen Square Track Award')
+ if (game.active !== COM) {
+ next_player()
+ }
+ game.return = game.active
+ clear_undo()
+ game.return_state = 'end_turn_4_5_4'
+ goto_vm(206)
+ return
+ }
+ else {
+ clear_undo()
+ game.state = 'end_turn_4_5_4'
+ return
+ }
+ }
+
+ // Resolve end action round
+ //Stasi check
+ if(game.round_player === COM && game.persistent_events.includes(13)) {
+ //If in Honecker, turn ends
+ if (game.round === 8) {
+ clear_undo()
+ game.state = 'end_turn_4_5_4'
+ return
+ }
+ //Otherwise go to Stasi
+ game.round_player = DEM
+ if (game.active !== DEM) {
+ next_player()
+ } else {
+ log_h3('Democratic Action Round')
+
+ }
+ if (game.democrat_hand.includes(game.stasi_card)) {
+ log_h3('C13')
+ game.state = 'stasi_play_card'
+ } else {
+ game.stasi_card = 0
+ game.state = 'choose_card'
+ }
+ return
+ }
+ //Check if in extra Action Round
+ else if (game.round_player === COM && game.round === 8) {
+ clear_undo()
+ game.state = 'end_turn_4_5_4'
+ return
+ }
+ //Normal round end
+ else if (game.round_player===COM) {
+ game.round_player = DEM
+ if (game.active !== DEM) {
+ next_player()
+ } else {
+ log_h3('Democratic Action Round')
+ }
+ game.state = 'choose_card'
+ return
+ }
+ if (game.round_player === DEM) {
+ // console.log('checking stasi', game.persistent_events.includes(13))
+ if(game.persistent_events.includes(13)) {
+ // console.log('stasi sub function')
+ if (game.active !== DEM) {
+ next_player()
+ }
+ log_h3('C13')
+ game.state = 'stasi_end_round'
+ return
+ } else if(game.round_player === DEM && game.persistent_events.includes(5)){
+ game.state = 'general_strike'
+ game.round ++
+ log_h2(`Action Round ${game.round}`)
+ game.round_player = COM
+ if (game.active !== COM) {
+ next_player()
+ }
+ log_h3('C5')
+ return
+ } else {
+ game.state = 'choose_card'
+ game.round_player = COM
+ game.round ++
+ log_h2(`Action Round ${game.round}`)
+ if (game.active !== COM) {
+ next_player()
+ }
+ }
+ }
+ //game.state = 'choose_card' Does this do anything any more?
+}
+
+/*
+function end_turn(){
+ /*End Turn sequence
+ TST support check
+ Verify held cards
+ New Year's Eve Party
+ Advance Turn Marker
+
+// CHECK FOR OPTIONAL SUPPORT CHECK
+ if (game.dem_tst_position >=6 && game.com_tst_position <= 5) {
+ if (game.active !== DEM) {
+ next_player_()
+ }
+ game.state = 'tst_support_check'
+ }
+ if (game.com_tst_position >=6 && game.dem_tst_position <= 5) {
+ if (game.active !== COM) {
+ next_player_()
+ }
+ game.state = 'tst_support_check'
+ }
+
+
+//CHECK HELD CARDS
+
+} */
+
+function new_turn() {
+ clear_undo()
+ game.turn ++
+ game.round = 1
+ game.valid_spaces=[]
+ game.active = COM
+ game.round_player = COM
+ game.dem_tst_attempted_this_turn = 0
+ game.com_tst_attempted_this_turn = 0
+ if (game.tst_7) {game.tst_7 = false}
+ if (game.tst_8) {game.tst_8 = false}
+
+ //Remove events that only last one turn
+ game.persistent_events = game.persistent_events.filter(n => n !== 25) /*Perestroika*/
+ game.persistent_events = game.persistent_events.filter(n => n !== 50) /*Sinatra Doctrine*/
+ game.persistent_events = game.persistent_events.filter(n => n !== 13) /*Stasi*/
+ game.persistent_events = game.persistent_events.filter(n => n !== 15) /*Honecker*/
+ delete game.prudence
+ delete game.stasi_card
+
+ //Austria Hungary Border Reopened
+ if (game.persistent_events.includes(58)) {
+ game.persistent_events = game.persistent_events.filter(n => n !== 58)
+ delete game.austria_hungary_border_reopened_tracker
+ log(`C58 no longer in effect`)
+ //permanently_remove(58)
+ }
+ //Elena
+ if (game.persistent_events.includes(101)) {
+ game.persistent_events = game.persistent_events.filter(n => n !== 101)
+ log(`C101 no longer in effect`)
+ //permanently_remove(101)
+ }
+ //GrenzTruppen
+ if (game.persistent_events.includes(59)) {
+ game.persistent_events = game.persistent_events.filter(n => n !== 59)
+ log(`C59 no longer in effect`)
+ //permanently_remove(59)
+ }
+ //Foreign Currency Debt Burden
+ if (game.persistent_events.includes(49)) {
+ game.persistent_events = game.persistent_events.filter(n => n !== 49)
+ delete game.foreign_currency_debt_burden
+ log(`C49 no longer in effect`)
+ //permanently_remove(49)
+ }
+ //FRG Embassies
+ if (game.persistent_events.includes(74)) {
+ game.persistent_events = game.persistent_events.filter(n => n !== 74)
+ log(`C74 no longer in effect`)
+ discard_from_table(74)
+ permanently_remove(74)
+ }
+ //Genscher
+ if (game.persistent_events.includes(63)) {
+ game.persistent_events = game.persistent_events.filter(n => n !== 63)
+ log(`C63 no longer in effect`)
+ discard_from_table(63)
+ permanently_remove(63)
+ }
+ //Stand Fast
+ if (game.persistent_events.includes(100)) {
+ game.persistent_events = game.persistent_events.filter(n => n !== 100)
+ delete game.stand_fast
+ log(`C100 no longer in effect`)
+ //permanently_remove(100)
+ }
+
+ if (game.samizdat_card > 0 ) {
+ game.democrat_hand.push(game.samizdat_card)
+ delete game.samizdat_card
+ }
+
+ log_h1("Turn " + game.turn)
+
+ if (game.turn === 4) {
+ add_midyear()
+ }
+ if (game.turn === 8) {
+ add_lateyear()
+ }
+ if (game.turn > 1) {
+ if (game.persistent_events.includes(65)) {
+ game.com_hand_limit = 7
+ log('Communist draws 7 cards due to C65')
+ //permanently_remove(65)
+ game.persistent_events = game.persistent_events.filter(n => n !== 65)
+ }
+ //console.log('deck', game.strategy_deck)
+ //console.log('game.com_hand_limit', game.com_hand_limit, 'communist hand before draw', game.communist_hand)
+ draw_cards(game.strategy_deck, game.democrat_hand, game.communist_hand, game.dem_hand_limit, game.com_hand_limit)
+ game.com_hand_limit = 8
+ //console.log('communist hand after draw', game.communist_hand)
+
+ }
+
+ //Check if TST effects need to be resolved
+ if (game.dem_tst_position >=5 && game.com_tst_position <= 4) {
+ log_h2('Tiananmen Square Track award')
+ if(game.active !== DEM) { next_player() }
+ for (let card of game.democrat_hand) {
+ if (scoring_cards.includes(card)) continue
+ game.valid_cards.push(card)
+ }
+ game.state = 'tst_goddess' /* Goddess only name of Democrat bonus, not Communist*/
+ return
+ }
+ else if (game.com_tst_position >=5 && game.dem_tst_position <= 4) {
+ log_h2('Tiananmen Square Track award')
+ if(game.active !== COM) { next_player() }
+ for (let card of game.communist_hand) {
+ if (scoring_cards.includes(card)) continue
+ game.valid_cards.push(card)
+ }
+ game.state = 'tst_goddess'
+ } else {
+ log_h2("Action Round " + game.round)
+ log_side()
+ //console.log('in start new AR call, game.active', game.active)
+ if (game.persistent_events.includes(5)) {
+ log_h3('C5')
+ game.state = 'general_strike'
+ }
+ else {
+ game.state = 'choose_card'
+ }
+ }
+}
+
+function next_player() {
+ clear_undo()
+ //console.log('next player called')
+ if (game.active === DEM)
+ game.active = COM
+ else
+ game.active = DEM
+
+ log_side()
+}
+
+function change_player() {
+ clear_undo()
+ //console.log('next player called')
+ if (game.active === DEM)
+ game.active = COM
+ else
+ game.active = DEM
+}
+
+function find_space_index(name_unique) {
+ return spaces.findIndex(space => space && space.name_unique === name_unique)
+}
+
+function find_country_index(country) {
+ return countries.indexOf(country)
+}
+
+function draw_deck(deck) {
+ return deck.filter(card => card && card.period === 1).map(card => card.number)
+}
+
+function draw_cards(deck, democrat_hand, communist_hand, dem_hand_limit, com_hand_limit) {
+ //console.log('game.valid_cards at start of draw cards: ', game.valid_cards)
+ let turn = 'communist'; // Start with the communist player
+ //console.log('game.strategy_deck', game.strategy_deck)
+ //console.log('deck', deck, 'democrat_hand', democrat_hand, 'communist_hand', communist_hand, 'dem_hand_limit', dem_hand_limit, 'com_hand_limit', com_hand_limit)
+ while (democrat_hand.length < dem_hand_limit || communist_hand.length < com_hand_limit) {
+ //console.log('deck.length: ', deck.length)
+ //console.log('discard.length', game.strategy_discard )
+ if (deck.length === 0) {
+ log_h3('--- Reshuffle ---')
+
+ deck.push(...game.strategy_discard)
+ game.strategy_discard = []
+ }
+
+ else if (turn === 'communist' && communist_hand.length < com_hand_limit) {
+ communist_hand.push(draw_card(deck));
+ //console.log('game.valid_cards after communist draw: ', JSON.stringify(game.valid_cards));
+ turn = 'democrat';
+ } else if(turn === 'communist' && communist_hand.length === com_hand_limit) {
+ turn = 'democrat';
+ }
+ else if (turn === 'democrat' && democrat_hand.length < dem_hand_limit) {
+ democrat_hand.push(draw_card(deck));
+ //console.log('democrat_hand: ', democrat_hand)
+
+ //console.log('game.valid_cards after democrat draw: ', JSON.stringify(game.valid_cards));
+ turn = 'communist';
+ }
+ else if (turn === 'democrat' && democrat_hand.length === dem_hand_limit) {
+ turn = 'communist';
+ }
+ }
+
+ clear_undo()
+}
+
+function draw_card(deck) {
+ //console.log('draw card called with:', deck)
+ //console.log('game.strategy_deck before', game.strategy_deck)
+ if (deck.length === 0) {
+ log_h3('--- Reshuffle ---')
+
+ deck.push(...game.strategy_discard)
+ game.strategy_discard = []
+ }
+ const randomIndex = Math.floor(Math.random() * deck.length)
+ //console.log('card chosen:', randomIndex)
+ //console.log('game.strategy_deck after', game.strategy_deck)
+ return deck.splice(randomIndex, 1)[0];
+}
+
+function discard(card) {
+ //console.log('in discard(card)')
+ let find_card
+ if (!game.is_pwr_struggle) {
+
+ if (game.active === COM) {
+ find_card = game.communist_hand.indexOf(card)
+ game.communist_hand.splice(find_card, 1)
+ } else {
+ find_card = game.democrat_hand.indexOf(card)
+ game.democrat_hand.splice(find_card, 1)
+ }
+ if (!game.strategy_discard.includes(card)) {
+ game.strategy_discard.push(card)
+ log(`Discarded C${cards[card].number}`)
+ }
+ } else if (game.is_pwr_struggle) {
+ if (game.active === COM) {
+ find_card = game.com_pwr_hand.indexOf(card);
+ game.com_pwr_hand.splice(find_card, 1);
+ } else {
+ find_card = game.dem_pwr_hand.indexOf(card);
+ game.dem_pwr_hand.splice(find_card, 1);
+ }
+
+ game.power_struggle_discard.push(card)
+ //log(`Discarded P${power_cards[card].number}`)
+ }
+}
+function silent_discard(card) {
+ //console.log('in discard(card)')
+ let find_card
+ if (!game.is_pwr_struggle) {
+ if (game.active === COM) {
+ find_card = game.communist_hand.indexOf(card)
+ game.communist_hand.splice(find_card, 1)
+ } else {
+ find_card = game.democrat_hand.indexOf(card)
+ game.democrat_hand.splice(find_card, 1)
+ }
+ if (!game.strategy_discard.includes(card)) {
+ game.strategy_discard.push(card)
+ }
+ } else if (game.is_pwr_struggle) {
+ if (game.active === COM) {
+ find_card = game.com_pwr_hand.indexOf(card);
+ game.com_pwr_hand.splice(find_card, 1);
+ } else {
+ find_card = game.dem_pwr_hand.indexOf(card);
+ game.dem_pwr_hand.splice(find_card, 1);
+ }
+ game.power_struggle_discard.push(card)
+ }
+}
+
+function remove_from_discard(card) {
+ let card_index = game.strategy_discard.indexOf(card)
+ if (card_index !== -1) {
+ game.strategy_discard.splice(card_index, 1)
+ }
+}
+
+function discard_card(hand) {
+ //let find_card
+ let card = Math.floor(Math.random()*hand.length)
+ let discarded_card = hand.splice(card, 1)[0]
+ if (game.is_pwr_struggle) {
+ if (numberless_cards.includes(discarded_card)) {
+ log_gap(`Discarded: P${discarded_card}`)
+ } else {
+ log_gap(`Discarded: P${discarded_card} V${power_cards[discarded_card].value}`)
+ }
+ } else {
+ log(`Discarded C${cards[discarded_card].number}`)
+ game.strategy_discard.push(discarded_card)
+ }
+ return discarded_card
+}
+
+function discard_from_table(card) {
+ find_card = game.table_cards.indexOf(card)
+ game.table_cards.splice(find_card, 1)
+ game.strategy_discard.push(card)
+}
+
+
+function add_midyear() {
+ const mid_year = cards.filter(card => card && card.period === 2).map(card => card.number);
+ game.strategy_deck.push(...mid_year);
+ log_h3('Mid-year cards added to draw deck')
+}
+
+
+function add_lateyear() {
+ const late_year = cards.filter(card => card && card.period === 3).map(card => card.number)
+ game.strategy_deck.push(...late_year)
+ log_h3('Late-year cards added to draw deck')
+}
+
+function reset_power() {
+ game.power_struggle_deck = []
+ game.power_struggle_discard = []
+ game.dem_pwr_hand = []
+ game.com_pwr_hand = []
+ game.phase = 1
+ game.raised_stakes_round = 0
+ game.raised_stakes = 0
+ game.played_power_card = 0
+ game.tactics_fails = ''
+ game.view_opp_hand = false
+
+ if (game.persistent_events.includes(72)){
+ permanently_remove(72)
+ game.table_cards = game.table_cards.filter(card => card !== 72)
+ game.persistent_events = game.persistent_events.filter(n => n !== 72)
+ }
+ if (game.persistent_events.includes(62)) {
+ permanently_remove(62)
+ game.table_cards = game.table_cards.filter(card => card !== 62)
+ game.persistent_events = game.persistent_events.filter(n => n !== 62)
+ }
+ if (game.persistent_events.includes(54) && game.pwr_struggle_in === 'Romania'){
+ permanently_remove(54)
+ //game.table_cards = game.table_cards.filter(card => card !== 54)
+
+ }
+ if (game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(70)){
+ //permanently_remove(70)
+ //game.table_cards = game.table_cards.filter(card => card !== 70)
+ game.persistent_events = game.persistent_events.filter(n => n !== 70)
+ }
+}
+
+function check_control_change(space_id) {
+
+ // Check if the Tyrant is Gone has been fulfilled
+
+ if (game.the_tyrant_is_gone > 0 && check_dem_control(game.the_tyrant_is_gone)) {
+ log('+2 VP from C97')
+ game.vp += 2
+ if (check_vp()) {
+ return
+ }
+ game.persistent_events = game.persistent_events.filter(n => n !== 97)
+ delete game.the_tyrant_is_gone
+ }
+}
+
+function check_systematization() {
+ // Check for Systematization - may not use this space
+ if (game.systematization > 0) {
+ game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
+ }
+}
+
+function check_common_european_home() {
+ if (!game.playable_cards.includes(21)) {
+ game.playable_cards.push(21)
+ }
+}
+
+function this_card() {
+ return game.vm_event > 0 ? game.vm_event : game.played_card
+}
+/*
+function get_ops(card) {
+ let ops = cards[card].ops
+ if (game.active === COM) {
+ //Check TST op bonus
+ if (ops === 1 && game.com_tst_position >=2 && game.dem_tst_position <=1) {
+ ops++
+ }
+ //Events that influence ops
+ if (game.persistent_events.includes(25)) {
+ ops++
+ }
+ if (game.prudence.COM && game.prudence.COM <0) {
+ ops += game.prudence.COM
+ }
+
+ } else {
+ //Check TST op bonus
+ if (ops === 1 && game.dem_tst_position >=2 && game.com_tst_position <=1) {
+ ops++
+ }
+ //Events that influence ops
+ if (game.persistent_events.includes(50)) {
+ ops++
+ }
+ if (game.prudence.DEM && game.prudence.DEM <0) {
+ ops += game.prudence.DEM
+ }
+ }
+ //Ops can never be less than one
+ if (ops <1) { ops = 1 }
+ return ops
+}
+ */
+
+const pluralize = (count, noun, suffix = 's') =>
+ `${count} ${noun}${Math.abs(count) !== 1 ? suffix : ''}`
+
+function clean_name(str) {
+ if (str && str.slice(-1) === '*') {
+ return str.slice(0, -1)
+ } else {
+ return str;
+ }
+}
+
+function country_name(country) {
+ return country.replace(/_/g, ' ')
+}
+
+// ======== LOG FUNCTIONS =============
+
+function log(msg) {
+ game.log.push(msg)
+}
+
+function log_br() {
+ if (game.log.length > 0 && game.log[game.log.length - 1] !== "")
+ game.log.push("")
+}
+
+function logi(msg) {
+ game.log.push(">" + msg)
+}
+
+function log_h1(msg) {
+ log_br()
+ log(".h1 " + msg)
+ log_br()
+}
+
+function log_h2(msg) {
+ log_br()
+ log(".h2 " + msg)
+ log_br()
+}
+
+function log_h3(msg) {
+ log_br()
+ log(".h3 " + msg)
+}
+
+function log_gap(msg) {
+ log_br()
+ game.log.push(msg)
+}
+
+function log_msg_gap(msg) {
+ game.log.push(msg)
+ log_br()
+}
+
+
+function log_side() {
+ log_br()
+ if (game.active === DEM)
+ log(".h2d " + game.active)
+ else
+ log(".h2c " + game.active)
+ log_br()
+}
+
+function log_sep() {
+ log(".hr")
+}
+
+function log_action(msg) {
+ log_br()
+ log(msg)
+}
+
+// ============= SUMMARY FUNCTIONS =============
+
+function push_summary() {
+ if (game.summary)
+ throw "TOO MANY SUMMARIES"
+ game.summary = []
+}
+
+function log_summary(msg) {
+
+ if (msg.startsWith('Added') || msg.startsWith('Removed')) {
+ for (let item of game.summary) {
+ if (item[1] === msg) {
+ item[0]++
+ return
+ }
+ }
+ }
+ game.summary.push([1, msg])
+}
+
+function pop_summary() {
+ if (game.summary.length > 0) {
+ for (let [n, msg] of game.summary) {
+ if (n > 1) {
+ log(msg.replace("£ SP", `${n} SPs`));
+ } else {
+ log(msg.replace("£ SP", `${n} SP`));
+ }
+ }
+ }
+ game.summary = []
+}
+
+function log_summary_place(p) {
+ let from = piece_space(p)
+ if (from !== AVAILABLE)
+ log_summary("% " + piece_name(p) + " from S" + from)
+ else
+ log_summary("% " + piece_name(p))
+}
+
+function log_summary_move_to_from(p, to) {
+ log_summary("% " + piece_name(p) + " to S" + to + " from S" + piece_space(p))
+}
+
+function log_summary_remove(p) {
+ log_summary("Removed % " + piece_name(p))
+}
+
+function log_summary_activated(p) {
+ log_summary("Activated % " + piece_faction_name(p))
+}
+
+// ============ UNDO FUNCTIONS ==================
+
+function clear_undo() {
+ if (game.undo.length > 0)
+ game.undo = []
+}
+
+function push_undo() {
+ let copy = {}
+ for (let k in game) {
+ let v = game[k]
+ if (k === "undo")
+ continue
+ else if (k === "log")
+ v = v.length
+ else if (typeof v === "object" && v !== null)
+ v = object_copy(v)
+ copy[k] = v
+ }
+ game.undo.push(copy)
+}
+
+function pop_undo() {
+ let save_log = game.log
+ let save_undo = game.undo
+ game = save_undo.pop()
+ save_log.length = game.log
+ game.log = save_log
+ game.undo = save_undo
+}
+
+// Fast deep copy for objects without cycles
+function object_copy(original) {
+ if (Array.isArray(original)) {
+ let n = original.length
+ let copy = new Array(n)
+ for (let i = 0; i < n; ++i) {
+ let v = original[i]
+ if (typeof v === "object" && v !== null)
+ copy[i] = object_copy(v)
+ else
+ copy[i] = v
+ }
+ return copy
+ } else {
+ let copy = {}
+ for (let i in original) {
+ let v = original[i]
+ if (typeof v === "object" && v !== null)
+ copy[i] = object_copy(v)
+ else
+ copy[i] = v
+ }
+ return copy
+ }
+}
+
+
+/* =================== VM FUNCTIONS ========================== */
+
+function goto_vm(proc) {
+ let old_vm = game.vm;
+
+ game.state = "vm";
+ game.vm = {
+ prompt: 0,
+ fp: proc,
+ ip: 0,
+ };
+
+ if (old_vm) {
+ game.vm.return_vm = old_vm;
+ }
+
+ vm_exec();
+}
+
+function vm_exec() {
+ vm_inst(0)();
+}
+
+function vm_inst(a) {
+ //console.log('game.vm.fp', game.vm.fp, 'game.vm.ip', game.vm.ip)
+ return CODE[game.vm.fp][game.vm.ip][a]
+}
+
+function vm_next() {
+ game.vm.ip++;
+ //console.log('vm_next called, game.vm.ip', game.vm.ip)
+ vm_exec();
+}
+
+function vm_operand(a) {
+ let x = CODE[game.vm.fp][game.vm.ip][a]
+ if (a > 0 && typeof x === "function")
+ return x()
+ return x
+}
+
+function vm_assert_argcount(n) {
+ const argcount = CODE[game.vm.fp][game.vm.ip].length - 1
+ if (argcount !== n)
+ throw Error(`ASSERT Invalid number of arguments on event ${game.vm.fp}: ${argcount} instead of ${n}`)
+}
+
+function vm_log() {
+ log(vm_operand(1));
+ vm_next();
+}
+
+function vm_if() {
+ //console.log('game.temp', game.temp)
+// console.log('vm_operand(1)', vm_operand(1))
+ if (!vm_operand(1)) {
+ let balance = 1
+ while (balance > 0) {
+ ++game.vm.ip
+ switch (vm_operand(0)) {
+ case vm_if:
+ ++balance
+ break
+ case vm_endif:
+ --balance
+ break
+ case vm_else:
+ if (balance === 1)
+ --balance
+ break
+ }
+ if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length)
+ throw "ERROR"
+ }
+ }
+ vm_next()
+}
+
+function vm_else() {
+ vm_goto(vm_endif, vm_if, 1, 1)
+}
+
+function vm_endif() {
+ vm_next()
+}
+
+function vm_goto_step(step) {
+ // console.log('vm_goto_step called, target:', step)
+ //console.log('game.vm.ip', game.vp.ip)
+ for (let i = game.vm.ip; i < CODE[game.vm.fp].length; i++) {
+ //console.log('i', i)
+ //console.log('step', CODE[game.vm.fp][i][0])
+ if (CODE[game.vm.fp][i][0] === step) {
+ game.vm.ip = i;
+ vm_exec();
+ return;
+ }
+ }
+
+ console.log("ERROR: Target operation not found in the current procedure.");
+}
+
+
+function vm_goto(op, nop, dir, step) {
+ //console.log('vm_inst(0)', vm_inst(0), op, nop)
+// console.log('vm_inst(0)', vm_inst(1), op, nop)
+ let balance = 1
+ while (balance > 0) {
+ game.vm.ip += dir
+ if (vm_inst(0) === op)
+ --balance
+ if (vm_inst(0) === nop)
+ ++balance
+ if (game.vm.ip < 0 || game.vm.ip > CODE[game.vm.fp].length)
+ throw "ERROR"
+ }
+ game.vm.ip += step
+ vm_exec()
+}
+
+function event_prompt(str) {
+ //console.log('event_prompt called with', str)
+ if (typeof str === "undefined")
+ str = CODE[game.vm.fp][game.vm.prompt][1]
+ if (typeof str === "function")
+ str = str()
+ //console.log('str:', str)
+ if (!str) {
+ str = ""
+ }
+ return str
+}
+
+function vm_prompt() {
+ if (game.vm.prompt)
+ game.vm._prompt = game.vm.prompt
+ game.vm.prompt = game.vm.ip
+ vm_next()
+}
+
+function pop_vm_prompt() {
+ if (game.vm._prompt) {
+ game.vm.prompt = game.vm._prompt
+ delete game.vm._prompt
+ } else {
+ game.vm.prompt = 0
+ }
+}
+
+function vm_return() {
+
+ //console.log('in vm_return, game.vm_infl_to_do', game.vm_infl_to_do, 'return state', game.return_state)
+
+ //Remove temporary vm variables
+ delete game.support_check_modifier
+ delete game.vm_max_infl
+ delete game.vm_influence_added
+ delete game.communist_hand_red
+
+ game.vm_event = 0 /*Reset to 0 now that event has been completed. Hopefully this doesn't cause issues! */
+ if (game.persistent_events.includes(58)) {
+ reset_austria_hungary_border_reopened()
+ }
+
+ //Check if end event state is needed
+ if (game.is_pwr_struggle || game.state === 'vm_tst_6' || game.return_state === 'tiananmen_square_attempt_done') {
+ vm_end_event()
+ }
+ //Check if auto-resolve opponent event
+ else if (is_auto_resolve(game.played_card) && ((cards[game.played_card].side === 'C' && game.active === DEM) || (cards[game.played_card].side === 'D' && game.active === COM) )) {
+ vm_end_event()
+ }
+ else {
+
+ game.state = 'vm_end_event'
+ /*if (!game.vm_infl_to_do) {
+ /*if ((game.active === DEM && game.round_player !==DEM) || (game.active === COM && game.round_player !== COM)) {
+ game.state = 'vm_end_event'
+ } else {
+ game.state = 'vm_end_event'
+ //end_round()
+ //}
+ } else {
+ console.log('vm_infl_to_do true')
+ vm_end_event()
+ }*/
+ }
+}
+
+function vm_end_event() {
+ //game.view_opp_hand = false
+// console.log('in vm_return, game.return:', game.return, 'game.return_state:', game.return_state, 'game.vm_infl_to_do', game.vm_infl_to_do, 'game.vm_event_to_do', game.vm_event_to_do)
+ /*if (!game.vm_infl_to_do && !game.vm_event_to_do) {
+ if (game.round_player !== game.active) {
+ change_player()
+ log_h2('End of Action Round')
+ }
+ end_round()
+ return
+ } /*Go direct to end round if card fully resolved */
+ if (game.return !== game.active) {
+ next_player()}
+ if (game.return_state === 'power_struggle') {
+ do_valid_cards()
+ }
+ if (game.return_state && game.return_state !== '') {
+ game.state = game.return_state
+ //console.log( 'game.state', game.state)
+ }
+ else if (game.vm_infl_to_do) {
+ game.state = 'resolve_opponent_event'} /*Can use game.return state for this? */
+ //else {game.state = "play_card"}
+ else{
+ end_round()}
+}
+
+/* ================== VM ACTIONS =========================== */
+
+function vm_opp_hand_false() {
+ game.view_opp_hand = false
+ vm_next()
+}
+
+function vm_valid_spaces() {
+ let space_1 = vm_operand(1)
+ let space_2 = vm_operand(2)
+ let space_3 = vm_operand(3)
+ let space_4 = vm_operand(4)
+ let space_5 = vm_operand(5)
+ let space_6 = vm_operand(6)
+ game.valid_spaces = [space_1, space_2, space_3, space_4, space_5, space_6]
+ game.valid_spaces = game.valid_spaces.filter( n => n )
+
+ // Check for Systematization - may not use this space
+ check_systematization()
+
+ vm_next()
+}
+
+function vm_valid_spaces_opponent () {
+ let valid_spaces = []
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+
+ if (game.active === DEM) {
+ let infl = game.comInfl[i]
+ if (infl > 0) {
+ valid_spaces.push(space.space_id)
+ }
+ } else {
+ infl = game.demInfl[i]
+ if (infl > 0) {
+ valid_spaces.push(space.space_id)
+ }
+ }
+ }
+ game.valid_spaces = valid_spaces
+// console.log('game.valid_spaces', game.valid_spaces)
+ vm_next()
+}
+
+function vm_valid_spaces_socio () {
+ let valid_spaces = []
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+
+ if (space.socio === vm_operand(1)) {
+ valid_spaces.push(space.space_id)
+ }
+ }
+ game.valid_spaces = valid_spaces
+
+ // Check for Systematization - may not use this space
+ if (game.systematization && game.systematization > 0) {
+ game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
+ }
+ vm_next()
+}
+
+function vm_valid_spaces_opponent_socio () {
+ let valid_spaces = []
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+
+ if (game.active === DEM) {
+ let infl = game.comInfl[i]
+ if (infl > 0 && space.socio === vm_operand(1)) {
+ valid_spaces.push(space.space_id)
+ }
+ } else {
+ let infl = game.demInfl[i]
+ if (infl > 0 && space.socio === vm_operand(1)) {
+ valid_spaces.push(space.space_id)
+ }
+ }
+ }
+ game.valid_spaces = valid_spaces
+ // Check for Systematization - may not use this space
+ if (game.systematization && game.systematization > 0) {
+ game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
+ }
+ vm_next()
+}
+
+function vm_valid_spaces_country () {
+ let country
+ if (vm_operand(1)) {country = vm_operand(1)}
+ else {country = game.vm_active_country}
+ for (let space of spaces) {
+ if (!space) continue
+ if (space.country === country) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ // Check for Systematization - may not use this space
+ if (game.systematization && game.systematization > 0) {
+ game.valid_spaces = game.valid_spaces.filter(n => n !== game.systematization)
+ }
+ vm_next()
+}
+
+function vm_valid_spaces_sc () {
+ valid_spaces_sc()
+ vm_next()
+}
+
+function vm_valid_spaces_country_opp () {
+ let country = ''
+
+ if (vm_operand(1)) {
+ country = vm_operand(1) }
+ else {
+ country = game.vm_active_country
+ }
+ for (let space of spaces) {
+ if (!space) continue
+ if (game.active === DEM) {
+ if (space.country === country && game.comInfl[space.space_id] >0) {
+ game.valid_spaces.push(space.space_id);
+ }
+ } else {
+ if (space.country === country && game.demInfl[space.space_id]>0) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ }
+ vm_next()
+}
+
+function vm_valid_spaces_country_sc () {
+ let valid_spaces = []
+ let country = ''
+ //console.log('in vm_valid_spaces_country_sc')
+ if (vm_operand(1)) {
+ country = vm_operand(1) }
+ else {
+ country = game.vm_active_country
+ }
+ for (let space of spaces) {
+ if (!space) continue
+ if (game.active === DEM) {
+ if (space.country === country && game.comInfl[space.space_id] >0) {
+ valid_spaces.push(space.space_id);
+ }
+ } else {
+ if (space.country === country && game.demInfl[space.space_id] >0) {
+ //Check Solidarity Legalised
+ if (game.persistent_events.includes(2) && space.space_id === 14) {continue}
+
+ //Check Civic Forum
+ if (game.persistent_events.includes(90) && space.space_id === 30) {continue}
+
+ //Check We are the People
+ if (game.persistent_events.includes(48) && space.space_id === 9) {continue}
+ valid_spaces.push(space.space_id);
+
+ //Check Foreign Currency Debt Burden
+ if (game.persistent_events.includes(49) && space.country === game.foreign_currency_debt_burden) {continue}
+ }
+ }
+ }
+ game.valid_spaces = valid_spaces
+
+ //Check for Foreign Currency Debt Burden
+ /*if (game.persistent_events.includes(49) && game.active === COM) {
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country !== game.foreign_currency_debt_burden)
+ }*/
+ vm_next()
+}
+
+function vm_valid_spaces_country_socio_2() {
+ for (let space of spaces) {
+ if (!space) continue
+ if (space.space_id === game.systematization) continue
+ if ((space.country === vm_operand(1) && space.socio === vm_operand(2)) || (space.country === vm_operand(1) && space.socio === vm_operand(3))) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ vm_next()
+}
+
+function vm_valid_spaces_region_socio() {
+ let valid_spaces = []
+ for (let space of spaces) {
+ if (!space) continue
+ if (space.space_id === game.systematization) continue
+ if (space.region === vm_operand(1) && space.socio === vm_operand(2)) {
+ valid_spaces.push(space.space_id);
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
+
+function vm_valid_spaces_region_opp() {
+ let valid_spaces = []
+ for (let space of spaces) {
+ if (!space) continue
+ let s = space.space_id
+ if ((game.active === DEM && space.region === vm_operand(1) && game.comInfl[s] > 0 ) || (game.active === COM && space.region === vm_operand(1) && game.demInfl[s] > 0 )) {
+ valid_spaces.push(space.space_id);
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
+
+function vm_valid_spaces_solidarity_legalised() {
+ let valid_spaces = []
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+ let uncontrolled = (!check_control(i) && !check_opp_control(i))
+ if ((space.country === 'Poland' && uncontrolled && space.socio === 3) || (space.country === 'Poland' && uncontrolled && space.socio === 4)) {
+ valid_spaces.push(space.space_id);
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
+
+function vm_active_country () {
+ game.valid_spaces = game.valid_spaces.filter(space_id => {
+ let space = spaces.find(s => s && s.space_id === space_id);
+ return space && space.country === game.vm_active_country;
+ });
+ vm_next()
+}
+
+function vm_take_control_prep() {
+ game.vm_available_ops = vm_operand(1)
+ game.state = 'vm_take_control'
+}
+
+function vm_take_control(space) {
+ if (game.active === DEM) {
+ let current_infl = game.demInfl[space]
+ let opponent_infl = game.comInfl[space]
+ let stability = spaces[space].stability
+
+ if ((current_infl - opponent_infl) < stability) {
+ game.demInfl[space] += stability - current_infl + opponent_infl
+ //game.pieces[space].demCtrl = 1
+ //game.pieces[space].comCtrl = 0
+ }
+ } else if (game.active === COM) {
+ let current_infl = game.comInfl[space]
+ let opponent_infl = game.demInfl[space]
+ let stability = spaces[space].stability
+
+ if ((current_infl - opponent_infl) < stability) {
+ game.comInfl[space] += stability - current_infl + opponent_infl
+ //game.pieces[space].comCtrl = 1
+ //game.pieces[space].demCtrl = 0
+ }
+ }
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space)
+ log(`Took control of %${space}`)
+}
+
+
+function vm_do_add_infl(space) {
+ push_undo()
+ //console.log('in vm_do_add_infl, space', space, 'ops', game.vm_available_ops, 'ahbr tracker', game.austria_hungary_border_reopened_tracker, 'ahbr in events', game.persistent_events.includes(58))
+
+ //log(`Added 1 influence in %${space}.`)
+
+ log_summary(`Added £ SP in %${space}.`)
+
+ //If AHBR - check AHBR condition
+ if (game.persistent_events.includes(58)) {
+ if (spaces[space].country !== 'East_Germany'){
+ game.austria_hungary_border_reopened_tracker = false
+ }
+ }
+
+ // Check Genscher
+ if (game.persistent_events.includes(63) && game.active === DEM && spaces[space].country === 'East_Germany') {
+ game.vm_available_ops--
+ log_summary(`(-1 op due to C63)`)
+ } else if (check_opp_control(space)) {
+ game.vm_available_ops -= 2
+ //Check if Austria Hungary Border Reopened was used to place last SP in a controlled space in East Germany. If so, game.vm_available_op will be negative
+ if (game.vm_available_ops < 0) {
+ log_summary(`(Used +1 op from C58)`)
+ }
+ } else {
+ game.vm_available_ops--
+ }
+
+ // Update influence values
+ if (game.active === COM) {
+ game.comInfl[space]++
+ } else {
+ game.demInfl[space]++
+ }
+
+ // Check whether spaces are controlled
+ check_control_change(space)
+
+ // Check Austria Hungary Border Reopened is true and condition has been met
+ if (game.vm_available_ops === 0 && game.active === DEM && game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker) {
+ //console.log('in award extra op')
+ game.vm_available_ops ++
+ log('+1 Op from C58')
+ game.austria_hungary_border_reopened_tracker = false
+ game.valid_spaces = game.valid_spaces.filter(n => spaces[n].country === 'East_Germany')
+ }
+
+ // If only 1 IP remaining, may not place in opponent controlled spaces
+
+ // Check for Genscher & Austria Hungary Border Reopened
+
+ if (game.vm_available_ops === 1) {
+
+ if (game.active === DEM) {
+ //Check Genscher and AHBR
+ if (game.persistent_events.includes(63) || (game.persistent_events.includes(58) && game.austria_hungary_border_reopened_tracker)) {
+ game.valid_spaces = game.valid_spaces.filter(n => !(check_com_control(n) && spaces[n].country !== 'East_Germany'))
+ } else {
+ game.valid_spaces = game.valid_spaces.filter(n => !check_com_control(n))
+ }
+ } else {
+ game.valid_spaces = game.valid_spaces.filter(n => !check_dem_control(n))
+ }
+ }
+
+ //Clear valid spaces if no IP remaining.
+ if (game.vm_available_ops <= 0 ) {
+ game.valid_spaces = []
+ }
+}
+
+function vm_do_add_infl_free(space) {
+ push_undo()
+ //log(`Added 1 influence in %${space}.`)
+
+ log_summary(`Added £ SP in %${space}.`)
+
+ // Update influence values
+ if (game.active === COM) {
+ game.comInfl[space]++
+ } else {
+ game.demInfl[space]++
+ }
+ game.vm_available_ops--
+ // Check whether spaces are controlled
+ check_control_change(space)
+
+
+ //console.log('game pieces:', game.pieces[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()
+ log(`Added ${game.vm_available_ops} SPs in %${space}.`)
+
+
+ if (game.active === COM) {
+ game.comInfl[space] += game.vm_available_ops
+ } else {
+ game.demInfl[space] += game.vm_available_ops
+ }
+ check_control_change(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()
+ //log(`Added 1 influence in %${space}.`)
+
+ log_summary(`Added £ SP in %${space}.`)
+ game.vm_available_ops --
+
+ if (!game.vm_influence_added) {
+ game.vm_influence_added = {};
+ }
+
+ if (!game.vm_influence_added[space]) {
+ game.vm_influence_added[space] = 0;
+ }
+
+ if (game.active === COM) {
+ game.comInfl[space] ++
+ } else {
+ game.demInfl[space] ++
+ }
+
+ game.vm_influence_added[space] ++
+
+ //console.log('valid_spaces before update', game.valid_spaces)
+ //console.log('influence added:', game.vm_influence_added[space], 'max infl', max_infl)
+ if (game.vm_influence_added[space] === max_infl) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ check_control_change(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
+ if (game.is_pwr_struggle) {
+ game.state = 'vm_scare_tactics'
+ } else {
+ game.state = 'vm_remove_infl'
+ }
+}
+
+function vm_remove_x_opp_infl() {
+ game.vm_available_ops = vm_operand(1)
+ game.remove_opponent_infl = true
+ game.state = 'vm_remove_x_infl'
+}
+
+function vm_do_remove_infl(space) {
+ push_undo()
+ //log(`Removed 1 influence from %${space}.`)
+ log_summary(`Removed £ SP from %${space}.`)
+
+ if (!game.vm_influence_added) {
+ game.vm_influence_added = {};
+ }
+
+ if (!game.vm_influence_added[space]) {
+ game.vm_influence_added[space] = 0;
+ }
+ if (game.remove_opponent_infl === true) {
+ if (game.active === COM) {
+ game.demInfl[space]--
+ if (game.demInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ } else {
+ game.comInfl[space]--
+ if (game.comInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ }
+
+
+ } else {
+ if (game.active === COM) {
+ game.comInfl[space]--
+ if (game.comInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ } else {
+ game.demInfl[space]--
+ if (game.demInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+ }
+ }
+ check_control_change(space)
+ game.vm_influence_added[space]++
+ game.vm_available_ops--
+ if (game.vm_available_ops===0) {game.valid_spaces = []}
+}
+
+function vm_do_remove_x_infl(space) {
+ push_undo()
+
+ if (game.remove_opponent_infl) {
+ if (game.active === COM) {
+ if (game.demInfl[space] >= game.vm_available_ops) {
+ game.demInfl[space] -= game.vm_available_ops
+ } else {
+ game.vm_available_ops = game.demInfl[space]
+ game.demInfl[space] -= game.vm_available_ops
+ }
+ } else {
+ if (game.comInfl[space] >= game.vm_available_ops) {
+ game.comInfl[space] -= game.vm_available_ops
+ } else {
+ game.vm_available_ops = game.comInfl[space]
+ game.comInfl[space] -= game.vm_available_ops
+ }
+ }
+ } else {
+ if (game.active === COM) {
+ if (game.comInfl[space] >= game.vm_available_ops) {
+ game.comInfl[space] -= game.vm_available_ops
+ } else {
+ game.vm_available_ops = game.comInfl[space]
+ game.comInfl[space] -= game.vm_available_ops
+ }
+ } else {
+ if (game.demInfl[space] >= game.vm_available_ops) {
+ game.demInfl[space] -= game.vm_available_ops
+ } else {
+ game.vm_available_ops = game.demInfl[space]
+ game.demInfl[space] -= game.vm_available_ops
+ }
+ }
+ }
+
+ log(`Removed ${game.vm_available_ops} SPs from %${space}`)
+ check_control_change(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()
+ log(`Removed SP from %${space}.`)
+ game.vm_available_ops --
+
+
+ if (!game.vm_influence_added) {
+ game.vm_influence_added = {};
+ }
+
+ if (!game.vm_influence_added[space]) {
+ game.vm_influence_added[space] = 0;
+ }
+
+ if (game.active === COM) {
+ game.demInfl[space] --
+ if (game.demInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space)
+ }
+ } else {
+ game.comInfl[space] --
+ if (game.comInfl[space] === 0) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space)
+ }
+ }
+
+ game.vm_influence_added[space] ++
+
+ if (game.vm_influence_added[space] === max_infl) {
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space);
+ }
+
+ check_control_change(space)
+ if (game.vm_available_ops === 0) {game.valid_spaces = []}
+}
+
+function vm_remove_all_infl() {
+ game.vm_available_ops = vm_operand(1)
+ game.state = 'vm_remove_all_infl'
+}
+
+function vm_do_remove_all_infl(space) {
+ push_undo()
+ log(`Removed all SP from %${space}.`)
+
+ if (game.remove_opponent_infl === true) {
+ if (game.active === COM) {
+ game.demInfl[space] = 0
+ } else {
+ game.comInfl[space] = 0
+ }
+ check_control_change(space)
+
+ } else {
+ if (game.active === COM) {
+ game.comInfl[space] = 0
+ } else {
+ game.demInfl[space] = 0
+ }
+ check_control_change(space)
+ }
+ game.vm_available_ops --
+ game.valid_spaces = game.valid_spaces.filter(id => id !== space)
+}
+
+function vm_replace_all_infl(space_id) {
+ if (game.active === DEM) {
+ game.demInfl[space_id] += game.comInfl[space_id]
+ game.comInfl[space_id] = 0
+ } else {
+ game.comInfl[space_id] += game.demInfl[space_id]
+ game.demInfl[space_id] = 0
+ }
+ check_control_change(space_id)
+}
+
+function vm_1_support_check() {
+ game.vm_available_ops = 1
+ game.state = 'vm_1_support_check_prep'
+}
+
+function vm_support_check() {
+ game.vm_available_ops = vm_operand(1)
+ game.state = 'vm_support_check_prep'
+}
+
+function vm_support_check_modified() {
+ game.vm_available_ops = vm_operand(1)
+ game.support_check_modifier = vm_operand(2)
+ game.state = 'vm_support_check_prep'
+}
+
+function vm_switch_infl(id){
+ push_undo()
+
+ game.demInfl[id] -= game.vm_available_ops
+ game.comInfl[id] += game.vm_available_ops
+ log(`Replaced ${pluralize(game.vm_available_ops,'SP')} in %${id}`)
+ game.vm_available_ops = 0
+ check_control_change(id)
+}
+
+/* ===================== EVENT SPECIFIC FUNCTIONS ========== */
+
+function vm_40th_anniversary_celebration() {
+ if (game.vp < 0 ) {game.vm_available_ops = 4}
+ else {game.vm_available_ops = 2}
+ vm_next()
+}
+
+function vm_40th_anniversary_celebration_vp() {
+ game.vp --
+ log('-1VP')
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+}
+
+function vm_adamec() {
+ game.state = 'vm_adamec'
+}
+
+function vm_army_backs_revolution() {
+ game.persistent_events = game.persistent_events.filter(n => n !== 70)
+ game.playable_cards = game.playable_cards.filter(n => n !== 70)
+ /*if (game.table_cards.includes(70)) {
+ permanently_remove(70)
+ }*/
+ vm_next()
+}
+
+function vm_austria_hungary_border_reopened() {
+ game.persistent_events.push(58)
+ permanently_remove(58)
+ game.austria_hungary_border_reopened_tracker = false
+ //game.table_cards.push(58)
+ //remove_from_discard(58)
+ vm_next()
+}
+
+function vm_betrayal() {
+ if (game.demInfl[58] > 0 ) { game.valid_spaces.push(58) }
+ if (game.demInfl[65] >0 ) { game.valid_spaces.push(65) }
+ game.vm_available_ops = Math.max(game.demInfl[58], game.demInfl[65])
+ game.state = 'vm_switch_infl'
+}
+
+function vm_breakaway_baltic_republics() {
+ log('+5 VP')
+ game.vp += 5
+ game.stability++
+ if (check_vp()) {
+ return
+ }
+ game.playable_cards.push(109)
+ game.playable_cards = game.playable_cards.filter(n => n !== 14)
+ if (!check_dem_control(56) && game.systematization !== 56) {game.valid_spaces.push(56)}
+ if (!check_dem_control(70)) {game.valid_spaces.push(70)}
+ vm_next()
+}
+
+function vm_brought_in_for_questioning() {
+ if (game.active === COM) {
+ game.active = DEM
+ }
+ //game.return = game.active
+ game.phase = 0
+ game.state = 'vm_brought_in_for_questioning'
+}
+
+function vm_bulgarian_turks_expelled(){
+ game.remove_opponent_infl = true
+ game.vp -= 2
+ log('-2VP')
+ if (check_vp()) {
+ return
+ }
+ if (game.demInfl[70] > 0) {game.valid_spaces = [70]}
+ vm_next()
+}
+
+function vm_ceausescu() {
+ let adj_cluj = false
+ if (game.demInfl[50] > 0 ) {adj_cluj = true}
+ if (game.demInfl[54] > 0 ) {adj_cluj = true}
+ if (game.demInfl[58] > 0 ) {adj_cluj = true}
+ if (game.demInfl[61] > 0 ) {adj_cluj = true}
+
+ if (adj_cluj && game.comInfl[61]>0) {
+ game.valid_spaces = [61]
+ game.vm_available_ops = 1
+ //next_player()
+ game.remove_opponent_infl = false
+ game.state = 'vm_remove_infl'
+ }
+ else {vm_next()}
+}
+
+function vm_central_committee_reshuffle() {
+ game.state = 'vm_central_committee_reshuffle'
+}
+
+function vm_civic_forum() {
+ log('+1 VP')
+ game.vp++
+ if (check_vp()) {
+ return
+ }
+ game.persistent_events.push(90)
+ if (check_dem_control(31)) {
+ vm_next()
+ } else {
+ permanently_remove(90)
+ vm_return()
+ }
+}
+
+function vm_common_european_home() {
+ let valid_cards = [];
+ for (let c of cards) {
+ //if (c === null) {continue}
+ if (game.active === DEM) {
+ if (c && c.side === 'C') {
+ valid_cards.push(c.number)
+ }
+ } else {
+ if (c && c.side === 'D') {
+ valid_cards.push(c.number)
+ }
+ }
+ }
+ game.valid_cards = valid_cards
+ game.state = 'vm_common_european_home_choose'
+}
+
+function vm_dash_for_the_west() {
+ game.valid_cards = []
+ for (let c of game.strategy_discard) {
+ if (cards[c].side === 'D' && cards[c].remove === 1 && (cards[c].playable || game.playable_cards.includes(c))) {
+ game.valid_cards.push(c)
+ }
+ }
+ game.state = 'vm_dash_for_the_west'
+}
+
+function vm_deutsche_marks() {
+ let max_value = 1;
+ for (let c of game.democrat_hand) {
+ if (cards[c].ops > max_value) {
+ max_value = cards[c].ops
+ }
+ }
+ let valid_cards = [];
+ for (let c of game.democrat_hand) {
+ if (cards[c].ops === max_value) {
+ valid_cards.push(c);
+ }
+ }
+ game.valid_cards = valid_cards
+ game.state = 'vm_deutsche_marks_prep'
+}
+
+function vm_domino_theory() {
+ game.discard = true
+ for (let card of game.strategy_discard) {
+ if (scoring_cards.includes(card)) {game.valid_cards.push(card) }
+ }
+ game.phase = 0
+ game.state = 'vm_play_event_from_discard'
+}
+
+function vm_eco_glasnost() {
+ game.persistent_events.push(39)
+ vm_next()
+}
+
+function vm_elena(){
+ game.persistent_events.push(101)
+ vm_next()
+}
+
+function vm_eliminate(space_id) {
+ log(`Eliminated %${space_id}`)
+ const adjacent_spaces = spaces[space_id].adjacent.filter(Number.isInteger);
+
+ //console.log('adjacency before: Iasi', game.pieces[53].adjacent, 'Ploesti:', game.pieces[59].adjacent, 'Bucharesti:', game.pieces[61].adjacent)
+
+ // Eliminate the democrat influence and move the communist influence to Bucuresti
+ if (space_id === 61) {
+ game.demInfl[space_id] = 0
+ game.comInfl[space_id] = 0
+ } else {
+ game.demInfl[space_id] = 0
+ game.comInfl[61] += game.comInfl[space_id]
+ if (game.comInfl[space_id] > 0 ) {
+ log(`${pluralize(game.comInfl[space_id],'Communist SP')} relocated to %61`)
+ }
+ game.comInfl[space_id] = 0
+ }
+ //Update control in the eliminated space and in Bucuresti
+ check_control_change(space_id)
+ check_control_change(61)
+
+}
+
+function get_adjusted_adjacency(space_id) {
+ let adjacent_spaces = spaces[space_id].adjacent;
+ if (adjacent_spaces.includes(game.systematization)) {
+ //console.log('in get adjusted adjacency, systemization',game.systematization)
+ //console.log('adjacent_spaces', adjacent_spaces)
+ }
+ if (game.systematization !== 0) {
+ //console.log('in systematization check')
+ let eliminated_space_id = game.systematization;
+
+ return adjacent_spaces.map(adj_space_id => {
+ if (adj_space_id === eliminated_space_id) {
+ // Replace the eliminated space with its adjacencies
+ //console.log('in map check, return', spaces[eliminated_space_id].adjacent)
+ return spaces[eliminated_space_id].adjacent;
+ }
+ //console.log('2nd check, return', adj_space_id)
+ return adj_space_id;
+ }).flat(); // Flatten in case the eliminated space has multiple adjacencies
+ }
+ //console.log('final adjacent spaces', adjacent_spaces)
+ return adjacent_spaces;
+}
+
+function vm_exit_visas() {
+ game.state = 'vm_exit_visas'
+}
+
+function vm_foreign_currency_debt_burden() {
+ log('+1VP')
+ game.vp++
+ if (check_vp()) {
+ return
+ }
+ //game.table_cards.push(49)
+ //remove_from_discard(49)
+ game.persistent_events.push(49)
+ game.state = 'vm_foreign_currency_debt_burden'
+}
+
+function vm_foreign_television() {
+ for (let i = 1 ; i < spaces.length; i++) {
+ if (i === 12) {continue} /*Does not apply to Dresden*/
+ if (game.comInfl[i] > 0 ) {
+ game.valid_spaces.push(i)
+ }
+ }
+ vm_next()
+}
+function vm_frg_embassies() {
+ game.persistent_events.push(74)
+ game.table_cards.push(74)
+ remove_from_discard(74)
+ log('C74 in effect')
+ vm_next()
+}
+
+function vm_general_strike() {
+ game.persistent_events.push(5)
+ game.table_cards.push(5)
+ remove_from_discard(5)
+ log('C5 in effect')
+ vm_next()
+}
+
+function vm_genscher() {
+ game.persistent_events.push(63)
+ game.table_cards.push(63)
+ remove_from_discard(63)
+ log(`C63 in effect`)
+ vm_next()
+}
+
+function vm_goodbye_lenin() {
+ game.view_opp_hand = true
+ game.communist_hand_red = []
+ // Select Red cards to show
+ for (let card of game.communist_hand) {
+ if (cards[card].red) {
+ game.communist_hand_red.push(card)
+ }
+ }
+ //Check if these cards are playabl
+ for (let card of game.communist_hand_red) {
+ if (cards[card].playable || game.playable_cards.includes(card)) {
+ game.valid_cards.push(card)
+ }
+ }
+ game.state = 'vm_goodbye_lenin'
+}
+
+function vm_government_resigns() {
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (space.socio === 1 && game.comInfl[i] > 0 && !check_control(i)) {
+ game.valid_spaces.push(i)
+ }
+ }
+ game.remove_opponent_infl = true
+ vm_next()
+}
+
+function vm_grenztruppen() {
+ game.persistent_events.push(59)
+ permanently_remove(59)
+ //game.table_cards.push(59)
+ //remove_from_discard(59)
+ vm_next()
+}
+
+function vm_heal_our_bleeding_wounds() {
+ let change_vp = 0
+ if (game.turn <= 3) {change_vp = -3 }
+ else if (game.turn <= 7) {change_vp = -1}
+ else change_vp = 3
+ if (change_vp >0) {
+ log(`+${change_vp} VP`)
+ } else {
+ log(`-${change_vp} VP`)
+ }
+ game.vp += change_vp
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+}
+
+function vm_helsinki_final_act() {
+ game.persistent_events.push(26)
+ vm_next()
+}
+
+function vm_honecker() {
+ game.persistent_events.push(15)
+ game.valid_cards = []
+ for (let c of game.strategy_discard) {
+ if (scoring_cards.includes(c)) {
+ continue}
+ else {
+ game.valid_cards.push(c)
+ }
+ }
+ game.discard = true
+ game.state = 'vm_honecker'
+}
+
+function vm_inflationary_currency() {
+ game.state = 'vm_inflationary_currency'
+}
+
+function vm_inflationary_currency_discard() {
+ // This function starts with the player who is playing Inflationary Currency for the Event
+ // Switch player and check the hand of their opponent to see if the have cards with ops > 3 to discard
+ next_player()
+ if (game.active === COM) {
+ for (let card of game.communist_hand){
+ if (get_card_ops(card) >= 3) {
+ game.valid_cards.push(card)
+ }
+ }
+ } else {
+ for (let card of game.democrat_hand){
+ if (get_card_ops(card) >= 3) {
+ game.valid_cards.push(card)
+ }
+ }
+ }
+ game.state = 'vm_inflationary_currency_discard'
+}
+
+function vm_kiss_of_death() {
+ game.state = 'vm_kiss_of_death'
+}
+
+function vm_klaus_and_komarek() {
+ if (game.comInfl[29] > 0 ) {game.valid_spaces = [29]}
+ vm_next()
+}
+
+function vm_kohl_proposes_reunification() {
+ log('+2 VP')
+ game.vp += 2
+ if (check_vp()) {
+ return
+ }
+ if (game.persistent_events.includes(86)) {
+ game.vm_event = 87
+ game.state = 'vm_common_european_home_play'
+ } else {
+ permanently_remove(87)
+ vm_return()
+ }
+
+}
+
+function vm_kremlin_coup() {
+ log('-3 VP')
+ game.vp -= 3
+ game.stability ++
+ if (check_vp()) {
+ return
+ }
+ game.support_check_modifier = 1
+ //countries = ['Poland', 'Hungary', 'East_Germany', 'Bulgaria', 'Czechoslovakia', 'Romania']
+ //revolutions: {'East_Germany': false, 'Poland': false, 'Czechoslovakia': false, 'Hungary': false, 'Romania': false, 'Bulgaria': false}
+ game.temp = []
+ countries.forEach(country => {
+ if (!game.revolutions[find_country_index(country)]) {
+ game.temp.push(country)
+ }
+ })
+ game.state = 'vm_kremlin_coup_choose_country'
+}
+
+function vm_laszlo_tokes() {
+ game.persistent_events.push(73)
+ game.playable_cards.push(107)
+ game.state = 'vm_laszlo_tokes'
+}
+
+function vm_legacy_of_martial_law() {
+ game.vm_available_ops = 1
+ game.state = 'vm_switch_infl'
+}
+
+function vm_legacy_of_1968() {
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+ if ((!check_com_control(i) && space.country === 'Czechoslovakia')) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ vm_next()
+}
+
+function vm_li_peng() {
+ game.persistent_events.push(53)
+ //game.table_cards.push(53)
+ remove_from_discard(53)
+ vm_next()
+}
+
+function vm_ligachev() {
+ game.persistent_events.push(99)
+ vm_next()
+}
+
+function vm_malta_summit() {
+ game.state = 'vm_malta_summit'
+}
+
+function vm_massacre_in_timisoara() {
+ game.persistent_events = game.persistent_events.filter(n => n !== 73)
+ vm_next()
+}
+
+function vm_modrow() {
+ game.playable_cards.push(15)
+ game.state = 'vm_modrow'
+}
+
+function vm_nagy_reburied(){
+ if (game.comInfl[43] > 0) {
+ game.valid_spaces.push(43)
+ }
+ vm_next()
+}
+
+function vm_national_salvation_front() {
+ game.persistent_events.push(102)
+ game.table_cards.push(102)
+ remove_from_discard(102)
+ vm_next()
+}
+
+function vm_nepotism() {
+ game.state = 'vm_nepotism'
+}
+
+function vm_new_years_eve_party() {
+ game.state = 'vm_new_years_eve_party'
+}
+
+function vm_nomenklatura() {
+ game.state = 'vm_nomenklatura'
+}
+
+function vm_normalisation() {
+ if (game.demInfl[27] >0) {game.valid_spaces.push(27)}
+ if (game.demInfl[29] > 0) {game.valid_spaces.push(29)}
+ game.remove_opponent_infl = true
+ vm_next()
+}
+
+function vm_peasant_parties_revolt() {
+ game.persistent_events.push(72)
+ log_msg_gap('C72 in effect')
+ game.table_cards.push(72)
+ remove_from_discard(72)
+ vm_next()
+}
+
+function vm_perestroika() {
+ game.persistent_events.push(25)
+ log_msg_gap('C25 in effect')
+ vm_next()
+}
+
+function vm_poszgay() {
+ let valid_spaces = []
+ for (let space of spaces) {
+ if (space && space.country === 'Hungary' && !check_dem_control(space.space_id)) {
+ valid_spaces.push(space.space_id);
+ }
+ }
+ game.valid_spaces = valid_spaces
+ vm_next()
+}
+
+function vm_power_struggle() {
+ //console.log('in vm_power_struggle. game.vm_event', game.vm_event, 'game.active', game.active, 'game.view_opp_hand', game.view_opp_hand)
+ game.is_pwr_struggle = true
+
+ /* TO DELETE?
+ //Check if Power Struggle is because of an event
+ */
+
+ if (game.vm_event > 0) {
+ game.pwr_struggle_in = countries[scoring_cards.indexOf(game.vm_event)]
+ log_h2(`C${game.vm_event}`)
+ }
+/*
+ //Otherwise set Power Struggle country normally
+ else {
+ console.log('vm_power_struggle, country set normally')
+ game.pwr_struggle_in = countries[scoring_cards.indexOf(game.played_card)]
+ log_h2(`C${game.played_card}`)
+ }*/
+
+
+ //Check for Securitate
+ if (game.pwr_struggle_in === 'Romania' && game.persistent_events.includes(70)) {
+ log('C70: Democrat reveals Power Struggle cards')
+ game.view_opp_hand = true
+ }
+ log_h2('Deal Cards')
+ game.state = 'draw_power_cards'
+}
+
+function vm_presidential_visit() {
+ game.persistent_events.push(65)
+ //game.table_cards.push(65)
+ //remove_from_discard(65)
+ log_msg_gap('C65 in effect')
+ vm_next()
+}
+
+function vm_prudence() {
+ if (!game.prudence) {
+ game.prudence = {DEM: 0, COM: 0}
+ }
+ if (game.active === DEM) {
+ game.prudence.COM --
+ log(`${game.prudence.COM} to Communist ops this turn`)
+ } else {
+ game.prudence.DEM --
+ log(`${game.prudence.DEM} to Democrat ops this turn`)}
+ vm_next()
+}
+
+function vm_public_against_violence() {
+ game.valid_spaces = []
+ if (game.comInfl[34] > 0 ) {game.valid_spaces.push(34)}
+ vm_next()
+}
+
+function vm_reformer_rehabilitated () {
+ permanently_remove(67)
+ game.discard = true
+ for (let card of game.strategy_discard) {
+ if (!event_is_playable(card)) continue
+ if (card === game.played_card) continue
+ if (game.table_cards.includes(card)) continue
+ if (scoring_cards.includes(card)) continue
+
+ game.valid_cards.push(card)
+ }
+ game.state = 'vm_play_event_from_discard'
+}
+
+function vm_roundtable_talks() {
+ game.persistent_events.push(17)
+ game.table_cards.push(17)
+ remove_from_discard(17)
+ log_msg_gap('C17 in effect')
+ vm_next()
+}
+
+function vm_sajudis_check() {
+ if (!check_dem_control(56)) {
+ game.valid_spaces.push(56)
+ }
+ if (!check_dem_control(70)) {
+ game.valid_spaces.push(70)
+ }
+ vm_next()
+}
+
+function vm_sajudis() {
+ game.playable_cards.push(81)
+ game.stability++
+ log('+1 VP')
+ game.vp++
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+}
+
+function vm_samizdat() {
+ game.state = 'vm_samizdat'
+}
+
+function vm_securitate() {
+ game.persistent_events.push(70)
+ permanently_remove(70)
+ //game.table_cards.push(70)
+ vm_next()
+}
+
+function vm_shock_therapy() {
+ game.state = 'vm_shock_therapy'
+}
+
+function vm_social_democratic_platform_adopted() {
+ game.state = 'vm_social_democratic_platform_adopted'
+}
+
+function vm_solidarity_legalised() {
+ log_msg_gap(`C2 in effect`)
+ game.playable_cards.push(3)
+ game.persistent_events.push(2)
+ vm_next()
+}
+
+function vm_st_nicholas_church () {
+ game.persistent_events.push(24)
+ game.playable_cards.push(61)
+ vm_next()
+}
+
+function vm_stasi() {
+ log_msg_gap('C13 in effect')
+ game.persistent_events.push(13)
+ vm_next()
+}
+
+function vm_stand_fast() {
+ game.persistent_events.push(100)
+ if (game.active === DEM) {
+ game.stand_fast = DEM
+ } else {game.stand_fast = COM}
+ //game.table_cards.push(100)
+ vm_next()
+}
+
+function vm_systematization() {
+ game.state = 'vm_systematization'
+}
+
+function vm_tank_column() {
+ if (game.active === DEM) {
+ game.dem_tst_position++
+ game.dem_tst_attempted = 0
+ } else {
+ game.com_tst_position++
+ game.com_tst_attempted = 0
+ }
+ vm_next()
+}
+
+function vm_tear_gas () {
+ game.persistent_events.push(30)
+ game.table_cards.push(30)
+ remove_from_discard(30)
+ log_msg_gap('C30 in effect')
+ vm_next()
+}
+
+function vm_the_baltic_way() {
+ game.playable_cards.push(84)
+ game.stability++
+ if (!check_dem_control(56) && game.systematization !== 56) {game.valid_spaces.push(56)}
+ if (!check_dem_control(70) && game.systematization !== 70) {game.valid_spaces.push(70)}
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+}
+
+function vm_the_chinese_solution() {
+ game.state = 'vm_the_chinese_solution'
+}
+
+function vm_the_crowd_turns_against_ceausescu() {
+ game.table_cards.push(54)
+ remove_from_discard(54)
+ game.playable_cards.push(97)
+ vm_next()
+}
+
+function vm_the_monday_demonstrations() {
+ if (!check_dem_control(6)) {game.valid_spaces.push(6)}
+ if (!check_dem_control(9)) {game.valid_spaces.push(9)}
+ vm_next()
+}
+
+function vm_the_sinatra_doctrine() {
+ game.persistent_events.push(50)
+ log_msg_gap('C50 in effect')
+ vm_next()
+}
+
+function vm_the_third_way() {
+ log('-2VP')
+ vm_next()
+}
+
+function vm_the_tyrant_is_gone() {
+ game.valid_spaces = []
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (game.demInfl[i] === 0 && space.country === 'Romania') {
+ if (space.space_id === game.systematization) {continue}
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ game.state = 'vm_the_tyrant_is_gone'
+}
+
+
+function vm_the_tyrant_is_gone_prep() {
+ game.table_cards.push(97)
+ remove_from_discard(97)
+ vm_next()
+}
+
+function vm_tyrant_block() {
+ logi(`Has no effect after C97`)
+ vm_next()
+ //game.state = 'vm_tyrant_block'
+}
+
+function vm_the_wall () {
+ game.persistent_events.push(9)
+ //game.strategy_removed.push(9)
+ //game.table_cards.push(9)
+ log_msg_gap('C9 in effect')
+ vm_next()
+}
+
+function vm_the_wall_must_go() {
+ game.the_wall_must_go = {}
+ game.the_wall_must_go['dem_wins'] = 0
+ game.the_wall_must_go['com_wins'] = 0
+ game.the_wall_must_go['dem_roll'] = 0
+ game.the_wall_must_go['com_roll'] = 0
+ game.state = 'vm_the_wall_must_go'
+}
+
+function vm_warsaw_pact_summit() {
+ game.warsaw_pact_summit = true /*What does this do? */
+ game.state = 'vm_warsaw_pact_summit'
+}
+
+function vm_we_are_the_people() {
+ if (game.demInfl[6] > 0) {game.valid_spaces = [6]}
+ game.persistent_events.push(48)
+ if (!game.vm_influence_added) {
+ game.vm_influence_added = {};
+ }
+ game.vm_influence_added[6] = 0
+ game.vm_available_ops = 4
+ game.state = 'vm_we_are_the_people_remove'
+}
+
+function vm_workers_revolt() {
+ if (game.active === DEM) {
+ for (let space of spaces) {
+ if (!space) continue
+ let country = space.country
+ if (!game.revolutions[find_country_index(country)] && game.comInfl[space.space_id] > 0 && space.socio === 4) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ } else {
+ for (let space of spaces) {
+ if (!space) continue
+ let country = space.country
+ if (game.revolutions[find_country_index(country)] && game.demInfl[space.space_id] > 0 && space.socio === 4) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ }
+ game.state = 'vm_workers_revolt'
+}
+
+function vm_yakovlev_counsels_gorbachev() {
+ game.persistent_events.push(62)
+ log_msg_gap('C62 in effect')
+ game.table_cards.push(62)
+ remove_from_discard(62)
+ vm_next()
+}
+
+function vm_permanently_remove () {
+ // Check if the event is being played as the result of another card, e.g. Dash for the West, is a card which should be removed, and which hasn't already been removed!
+ if (game.vm_event !== 0 && cards[game.vm_event].remove === 1 && !game.strategy_removed.includes(game.vm_event)) {
+ permanently_remove(game.vm_event)
+ }
+ if (cards[game.played_card].remove ===1 && !game.strategy_removed.includes(game.played_card)) {
+ permanently_remove(game.played_card)
+ } /*This means the card that called the event being played is also removed if relevant. Think this makes sense */
+ vm_next()
+}
+
+function discarded_card() {
+ return game.temp > 0
+}
+
+// =================== TIANANMEN SQUARE TRACK FUNCTIONS ====================
+
+function vm_tst_3() {
+ log_gap('Tiananmen Square Track award')
+ game.state = 'vm_tst_3_prep'
+}
+
+function vm_tst_4() {
+ log_gap('Tiananmen Square Track award')
+ game.vm_available_ops = 2
+ game.remove_opponent_infl = true
+ game.state = 'vm_tst_4'
+}
+function vm_tst_6() {
+ log_h3('Tiananmen Square Track award')
+ game.vm_available_ops = 1
+ game.temp = 1 //Set temp to 1, so that Card 1 is called during the support check, which has 2 ops
+ game.state = 'vm_tst_6'
+}
+
+function vm_tst_8() {
+ game.state = 'vm_goodbye_lenin_ops' // Use this to resolve ops.
+}
+
+// ==================== POWER STRUGGLE FUNCTIONS ======================
+
+function vm_scare_tactics() {
+ game.vm_active_country = game.pwr_struggle_in
+ vm_next()
+}
+function vm_support_surges() {
+ game.state = 'vm_support_surges_1'
+}
+
+function vm_support_falters() {
+ game.vm_available_ops = 2
+ game.return === game.active
+ game.state = 'vm_support_falters'
+}
+
+function vm_kremlin_coup_elite() {
+ game.valid_spaces=[]
+ elite_spaces.forEach(space => {
+ if (spaces[space].country === game.vm_active_country && !check_com_control(space)) {
+ game.valid_spaces.push(space);
+ }
+ })
+ game.state = 'vm_kremlin_coup_take_control'
+}
+
+/* ================== VM STATES ============================== */
+
+states.vm_end_event = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt () {
+ view.prompt = `${clean_name(cards[this_card()].name)}: done.`
+ if (game.vm_infl_to_do || game.return_state === 'vm_tst_8') {
+ gen_action('done')
+ } else {
+ gen_action('end_round')
+ }
+ },
+ done() {
+ push_undo()
+ vm_end_event()
+ },
+ end_round() {
+ push_undo()
+ game.return_state = ''
+ vm_end_event()
+ }
+}
+
+states.vm_take_control = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: all spaces controlled. Continue.`
+ gen_action('done')
+ } else if (game.vm_available_ops > 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: take control of ${event_prompt()}.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ } else {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Take control: done.`
+ if (game.vm_infl_to_do) {
+ gen_action('done')
+ } else {
+ gen_action('end_round')
+ }
+ }
+ },
+ infl(space) {
+ push_undo()
+ vm_take_control(space)
+ game.vm_available_ops--
+ if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ vm_next()
+ }
+ },
+ done() {
+ push_undo()
+ vm_next()
+ },
+ end_round() {
+ push_undo()
+ vm_next()
+ }
+}
+
+states.vm_add_infl = {
+ inactive: 'add Support Points.',
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}. No available spaces remaining. Add SPs: done.`
+ gen_action('done')
+ }
+ else if (game.vm_available_ops > 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id)
+ }
+ } else {
+ get_end_infl_prompt()
+ }
+ },
+ infl(space) {
+ vm_do_add_infl(space)
+ if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+
+ game.vm_event_done = true
+ vm_next()
+ }
+ },
+ done () {
+ push_undo()
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+
+ game.vm_event_done = true
+ vm_next()
+ },
+ end_round() {
+ push_undo()
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+
+ game.vm_event_done = true
+ vm_next()
+ }
+}
+
+states.vm_add_infl_free = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}: add SPs.`
+ },
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length === 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}. No available spaces remaining. Add SPs: done.`
+ gen_action('done')
+ } else if (game.vm_available_ops > 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: add ${game.vm_available_ops} SPs to ${event_prompt()}.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ } else {
+ get_end_infl_prompt()
+ }
+ },
+ infl(space) {
+ vm_do_add_infl_free(space)
+ if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+
+ game.vm_event_done = true
+ vm_next()
+ }
+ },
+ done () {
+ push_undo()
+ game.valid_spaces = []
+ game.vm_event_done = true
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ },
+ end_round () {
+ push_undo()
+ game.valid_spaces = []
+ game.vm_event_done = true
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ }
+}
+
+states.vm_add_x_infl = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}: add Support Points.`
+ },
+// inactive: `resolve ${cards[this_card()].name}: add influence.`,
+ prompt () {
+ if (game.vm_event === 101 && game.valid_spaces.length === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: the Romanian Elite space no longer exists.`
+ gen_action('done')
+ }
+ else if (game.vm_available_ops > 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: Add ${game.vm_available_ops} SPs to ${event_prompt()}.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id)
+ }
+ } /*else {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Add SPs: done.`
+ gen_action('done')
+ }*/
+ },
+ infl(space) {
+ push_undo()
+ vm_do_add_x_infl(space)
+ if (game.vm_available_ops === 0) {
+ game.vm_event_done = true
+ vm_next()
+ }
+ /*if (game.vm_event === (105 || 68) {
+ vm_next()
+ return
+ } */
+
+
+ //game.vm_event_done = true
+ //vm_next()
+ },
+ done () {
+ push_undo()
+ game.vm_event_done = true
+ vm_next()
+ }
+}
+
+states.vm_add_limited_infl = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}: add Support Points.`
+ },
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) {
+ if (game.vm_max_infl === 1) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_max_infl,'SP')} ${event_prompt()}.`
+ }
+ else {
+ view.prompt = `${clean_name(cards[this_card()].name)}: add ${pluralize(game.vm_available_ops,'SP')} to ${event_prompt()}.`
+ }
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ } /*else {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Add SPs: done.`
+ gen_action('done')
+ }*/
+ },
+ infl(space) {
+ vm_do_add_limited_infl(space, game.vm_max_infl)
+ if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
+ game.valid_spaces = []
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ game.vm_event_done = true
+ vm_next()
+ }
+ },
+ /*done () {
+ push_undo()
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ game.vm_event_done = true
+ vm_next()
+ }*/
+}
+
+states.vm_remove_infl = {
+ inactive: 'remove Support Points.',
+ prompt () {
+ // Keep this so that there is an undo option in, e.g., Scare Tactics
+ if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no further SPs to remove.`
+ gen_action('done')
+ return
+ }
+ if (game.vm_available_ops === 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
+ gen_action('done')
+ return
+ }
+ if (game.remove_opponent_infl) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops, 'opponent SP')}${event_prompt()}.`
+ }
+ else {
+ view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}.`
+ }
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ },
+ infl(space) {
+ push_undo()
+ vm_do_remove_infl(space)
+ game.vm_active_country = spaces[space].country
+ if (game.vm_event !== 44) {
+ if (game.vm_available_ops === 0 ) {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ }
+ }
+ },
+ done() {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ }
+}
+
+
+states.vm_remove_x_infl = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}: remove SP from ${event_prompt()}.`
+ },
+ prompt () {
+ if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
+ gen_action('done')
+ } else if (game.vm_available_ops > 0) {
+
+ view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')} from ${event_prompt()}.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ } /*else {
+ if (game.vm_infl_to_do) {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done. Return control to phasing player.`
+ gen_action('done')
+ return
+ } else {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
+ gen_action('done')
+ return
+ }
+ }*/
+ },
+ infl(space) {
+ vm_do_remove_x_infl(space)
+ /*if (game.vm_event === 68) {
+ vm_next()
+ return
+ }*/
+ if (game.vm_available_ops === 0) {
+ game.vm_event_done = true
+ vm_next()
+ }
+ /*game.vm_event_done = true
+ vm_next()*/
+ },
+ done () {
+ game.vm_event_done = true
+ vm_next()
+ }
+}
+
+states.vm_remove_limited_infl = {
+ inactive: 'remove SP.',
+ prompt () {
+ if (game.vm_available_ops > 0 && game.valid_spaces.length > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops,'SP')}${event_prompt()}, no more than ${game.vm_max_infl} per space.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ } else if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no further SP to remove.`
+ gen_action('done')
+ } /*else {
+ if (game.vm_infl_to_do) {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done. Return control to phasing player.`
+ gen_action('done')
+ return
+ } else {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
+ gen_action('done')
+ return
+ }
+ }*/
+ },
+ infl(space) {
+ vm_do_remove_limited_infl(space, game.vm_max_infl)
+ if (game.vm_available_ops === 0) {
+ game.vm_event_done = true
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ }
+ },
+ done () {
+ game.vm_event_done = true
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ }
+}
+
+states.vm_remove_all_infl = {
+ inactive: 'remove Support Points',
+ prompt () {
+ if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
+ gen_action('pass')
+ } else if (game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: remove all SPs from ${event_prompt()}.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ } /*else {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
+ gen_action('done')
+ }*/
+ },
+ infl(space) {
+ vm_do_remove_all_infl(space)
+ game.vm_active_country = spaces[space].country
+ if (game.vm_available_ops === 0) {
+ vm_next()
+ }
+ },
+ pass() {
+ push_undo()
+ vm_next()
+ }
+}
+
+states.vm_support_check_prep = {
+ inactive: 'do support checks.',
+ prompt () {
+ /*if (game.vm_available_ops === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Support check: done.`
+ gen_action('done')
+ } else */
+ if (game.valid_spaces.length === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no valid targets for support check.`
+ gen_action('done')
+ } else {
+ //if (game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: ${event_prompt()}. ${pluralize(game.vm_available_ops, 'support check')} remaining.`
+ //}
+ for (let space_id of game.valid_spaces) {
+ if (!space_id) continue
+ gen_action_sc(space_id);
+ }
+ }
+ },
+ sc(space) {
+ push_undo()
+ game.selected_space = space
+
+ // Check for Austria-Hungary Border Reopened - check on first support check only
+ //First check for Monday Demonstrations - support checks will always be in East Germany
+ if (game.vm_event === 61 && game.persistent_events.includes(58)) {
+ game.austria_hungary_border_reopened_tracker = true
+ game.state = 'vm_do_support_check'
+ return
+ }
+
+ //Then check Austria-Hungary Border Reopened normally
+ //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
+ if (game.persistent_events.includes(58)) {
+ if (game.active === DEM && game.vm_available_ops > 1) {
+ if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
+ game.state = 'vm_austria_hungary_border_reopened_check'
+ return
+ }
+ //game.state = 'do_support_check'
+ } /*else { */
+ }
+ game.state = 'vm_do_support_check'
+ },
+ done () {
+ push_undo()
+ game.vm_available_ops = 0
+ vm_next ()
+ }
+}
+
+states.vm_ceh_support_check_prep = {
+ inactive: 'do support checks.',
+ prompt () {
+ /*if (game.vm_available_ops === 0) {
+ view.prompt = 'Support checks: done.'
+ gen_action('done')
+ return
+ }*/
+ if (game.vm_available_ops > 0) {
+ view.prompt = `Select a space. ${pluralize(game.vm_available_ops, 'support check')} remaining.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_sc(space_id)
+ }
+ }
+ },
+ sc(space) {
+ push_undo()
+ game.selected_space = space
+
+ //Then check Austria-Hungary Border Reopened normally
+ //console.log('game.austria_hungary_border_reopened_checked', game.austria_hungary_border_reopened_checked)
+ if (game.persistent_events.includes(58)) {
+ if (game.active === DEM && game.vm_available_ops > 1) {
+
+ if (spaces[game.selected_space].country === 'East_Germany' && game.persistent_events.includes(58) && game.active === DEM) {
+ game.state = 'vm_austria_hungary_border_reopened_check'
+ return
+ }
+ //game.state = 'do_support_check'
+ } /*else { */
+ }
+ game.state = 'vm_ceh_do_support_check'
+ },
+ /*done () {
+ vm_next ()
+ }*/
+}
+
+
+states.vm_ceh_do_support_check = {
+ inactive: 'do support checks.',
+ prompt () {
+ view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_sc(game.selected_space)
+
+ game.vm_available_ops--
+ if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ vm_next()
+ } else {
+ game.state = 'vm_ceh_support_check_prep'
+ return
+ }
+ }
+}
+
+states.vm_austria_hungary_border_reopened_check = {
+ inactive: 'decide Austria-Hungary Border Reopened',
+ prompt() {
+ view.prompt = 'Austria-Hungary Border Reopened: will all support checks be in East Germany?'
+ gen_action('yes')
+ gen_action('no')
+ },
+ yes() {
+ game.austria_hungary_border_reopened_tracker = true
+ game.state = 'vm_do_support_check'
+ },
+ no() {
+ game.state = 'vm_do_support_check'
+ }
+}
+
+states.vm_1_support_check_prep = {
+ inactive: 'do support checks.',
+ prompt () {
+ /*if (game.vm_available_ops === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Support check: done.`
+ gen_action('done')
+ } else */if (game.valid_spaces.length === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no valid targets for support check.`
+ gen_action('done')
+ } else {
+ view.prompt = `${clean_name(cards[this_card()].name)}: ${event_prompt()}.`
+
+ for (let space_id of game.valid_spaces) {
+ if (!space_id) continue
+ gen_action_sc(space_id);
+ }
+ }
+ },
+ sc(space) {
+ push_undo()
+ game.selected_space = space
+ game.state = 'vm_do_support_check'
+ },
+ done () {
+ push_undo()
+ game.vm_available_ops = 0
+ vm_next ()
+ }
+}
+
+states.vm_do_support_check = {
+ inactive: 'do support checks.',
+ prompt () {
+ view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_sc(game.selected_space)
+ game.vm_available_ops--
+ if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ vm_next()
+ return
+ } else {
+ game.state = 'vm_support_check_prep'
+ return
+ }
+ }
+}
+
+states.vm_tiananmen_square_attempt = {
+ inactive: 'do Tiananmen Square',
+ prompt () {
+ /*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 = 'Tiananmen Square: roll a die'
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_tst_attempt ()
+ },
+ /*done () {
+ vm_next()
+ }*/
+}
+
+//================================== EVENT SPECIFIC STATES ======================================
+
+states.vm_adamec = {
+ get inactive() {
+ return `resolve ${clean_name(cards[88].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Adamec: roll a die.'
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ let roll = Math.floor(Math.random() * 6) + 1
+ log(`Roll: D${roll}`)
+ let worker_spaces = spaces.filter(space => space && space.country === 'Czechoslovakia' && space.socio === 4 && check_dem_control(space.space_id)).length
+ if (worker_spaces > 0) {
+ log(`-${worker_spaces} from Democrat controlled worker spaces`)
+ roll -= worker_spaces
+ }
+ log(`Modified roll: ${roll}`)
+ if (roll > 2) {
+ log('Adamec succeeds')
+ vm_next()
+ return
+ }
+ log('Adamec fails: 3 or more required')
+ permanently_remove(88)
+ vm_return()
+ }
+}
+
+states.vm_brought_in_for_questioning = {
+ inactive: 'discard a card.',
+ prompt() {
+ /*if (game.phase === 1) {
+ view.prompt = 'Discard a card: done.'
+ gen_action('done')
+ } else */
+ if (game.democrat_hand.length === 0) {
+ view.prompt = 'Brought in for Questioning. No cards to discard.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Brought in for Questioning: you must discard a random card.'
+ gen_action('discard')
+ }
+ },
+ discard() {
+ clear_undo()
+ game.vm_event = discard_card(game.democrat_hand)
+ game.phase = 1
+ if (cards[game.vm_event].side === 'C' && (cards[game.vm_event].playable || game.playable_cards.includes(game.vm_event))) {
+ //game.return = game.active
+ if (!game.vm_infl_to_do) {
+ if(game.round_player === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ }
+ if (!is_auto_resolve(game.vm_event) && !switch_events.includes(game.vm_event)) {
+ next_player()
+ }
+ goto_vm(game.vm_event)
+ } else {
+ game.return = DEM
+ vm_return()
+ }
+ },
+ pass() {
+ log('No cards to discard')
+ vm_return()
+ },
+ /*done() {
+ vm_return()
+ }*/
+}
+
+states.vm_central_committee_reshuffle = {
+ get inactive() {
+ return `resolve ${clean_name(cards[57].name)}.`
+ },
+ prompt() {
+ if (game.revolutions.every(n => n === true)) {
+ view.prompt = 'Central Committee Reshuffle: no countries to choose.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Central Committee Reshuffle: choose a country to add SPs.'
+ if (!game.revolutions[0]) {gen_action('poland')}
+ if (!game.revolutions[1]) {gen_action('hungary')}
+ if (!game.revolutions[2]) {gen_action('east_germany')}
+ if (!game.revolutions[3]) {gen_action('bulgaria')}
+ if (!game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (!game.revolutions[5]) {gen_action('romania')}
+ }
+ },
+ east_germany() {
+ push_undo()
+ game.vm_active_country = "East_Germany"
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ game.valid_spaces = [1,2,3,4,5,6,7,8,9,10,11,12]
+ vm_next()
+ },
+ poland() {
+ push_undo()
+ game.vm_active_country = "Poland"
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ game.valid_spaces = [13,14,15,16,17,18,19,20,21,22,23,24,25,26]
+ vm_next()
+ },
+ czechoslovakia() {
+ push_undo()
+ game.vm_active_country = "Czechoslovakia"
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ game.valid_spaces = [27,28,29,30,31,32,33,34,35,36,37]
+ vm_next()
+ },
+ hungary() {
+ push_undo()
+ game.vm_active_country = "Hungary"
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ game.valid_spaces = [38,39,40,41,42,43,44,45,46,47,48,49]
+ vm_next()
+ },
+ romania() {
+ push_undo()
+ game.vm_active_country = "Romania"
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ game.valid_spaces = [50,51,52,53,54,55,56,57,58,59,60,61,62,63]
+ game.valid_spaces = game.valid_spaces.filter(space => space !== game.systematization)
+ vm_next()
+ },
+ bulgaria () {
+ push_undo()
+ game.vm_active_country = "Bulgaria"
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ game.valid_spaces = [64,65,66,67,68,69,70,71,72,73,74,75]
+ vm_next()
+ },
+ pass() {
+ log('Passed')
+ vm_return()
+ }
+
+}
+
+states.vm_common_european_home_choose = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = `Common European Home: play an opponent's card, event does not occur.`
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ },
+ card(card) {
+ push_undo()
+ //log(`Played with C${cards[card].number}`)
+ game.valid_cards = []
+ silent_discard(card)
+ game.vm_event = card
+ game.state = 'vm_common_european_home_play'
+ }
+}
+
+states.vm_common_european_home_play = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt() {
+ view.prompt = `Play ${clean_name(cards[this_card()].name)} for:`
+ gen_action('influence')
+ gen_action('support_check')
+ if (game.active === DEM && game.vm_event === 87 ) {
+ return /*Special condition if card is actually Kohl Proposes Reunification*/
+ }
+ /*if (game.active === DEM && game.dem_tst_attempted_this_turn === 0 || game.active === COM && game.com_tst_attempted_this_turn === 0) {
+ gen_action('tst')
+ } */
+ },
+ influence(){
+ push_undo()
+ log_gap(`Played C${cards[game.vm_event].number} to place SPs`)
+ game.vm_available_ops = cards[game.vm_event].ops
+ valid_spaces_infl()
+ // If ABHR - Set AHBR tracker to true
+ if (game.persistent_events.includes(58)) {
+ game.austria_hungary_border_reopened_tracker = true
+ }
+ game.state = 'vm_add_infl'
+ },
+ support_check() {
+ push_undo()
+ log_gap(`Played C${cards[game.vm_event].number} for support checks`)
+ game.vm_available_ops = 2
+ game.state = 'vm_ceh_support_check_prep'
+ valid_spaces_sc()
+ },
+ tst() {
+ push_undo()
+ log_gap(`Played C${cards[game.vm_event].number} to the Tiananmen Square Track`)
+ game.state = 'vm_tiananmen_square_attempt'
+ }
+}
+
+states.vm_dash_for_the_west = {
+ get inactive() {
+ return `resolve ${clean_name(cards[36].name)}.`
+ },
+ prompt() {
+ /* if (game.phase === 1) {*/
+ view.prompt = 'Dash for the West: roll a die'
+ gen_action('roll')
+ /*} else {
+ view.prompt = 'Dash for the West: roll a die. Done.'
+ gen_action('done')
+ }*/
+ },
+ roll() {
+ clear_undo()
+ let roll = Math.floor(Math.random() * 6) + 1
+ log(`Roll: D${roll}`)
+ let com_control = check_presence('East_Germany').com_spaces
+
+ if (roll > com_control) {
+ log(`Success. More than the ${com_control} Communist controlled spaces in East Germany`)
+ log('+1 VP')
+ game.vp++
+ if (check_vp()) {
+ return
+ }
+ game.discard = true
+ game.state = 'vm_play_event_from_discard'
+ } else {
+ log(`Fail: more than a ${com_control} required`)
+ //game.phase++
+ vm_next()
+ }
+ },/*
+ done() {
+ vm_next()
+ }*/
+}
+
+states.vm_play_event_from_discard = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_cards.length === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no valid cards in discard.`
+ gen_action('pass')
+ } else if (game.temp === 0) {
+ view.prompt = `${event_prompt()}.`
+ for (let card of game.valid_cards) {
+ gen_action('pass')
+ gen_action_card(card)
+ }
+ } /*else {
+ view.prompt = 'Choose a card: done.'
+ gen_action('done')
+ }*/
+ },
+ card(card) {
+ push_undo()
+ log(`Chose C${cards[card].number}`)
+ game.vm_event = card
+ game.vm_available_ops = cards[card].ops
+ game.discard = false
+ //game.return = game.active Does turning this off cause problems?
+ if (switch_events.includes(card)) {next_player()}
+ goto_vm(card)
+ },
+ pass(){
+ push_undo()
+ if (game.valid_cards.length === 0) {
+ log('No valid cards to choose')
+ } else{
+ log('Did not choose a card')
+ }
+ vm_next()
+ },
+/* done(){
+ push_undo()
+ game.discard = false
+ vm_next()
+ }*/
+}
+
+states.vm_deutsche_marks_prep = {
+ inactive: 'choose a card.',
+ prompt() {
+ if (game.valid_cards.length === 0) {
+ view.prompt = 'Deutsche Marks: no cards to give.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Deutsche Marks: choose a card to give.'
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ }
+ },
+ card(card) {
+ push_undo()
+ log(`Gave C${cards[card].number}`)
+ game.valid_cards = []
+ silent_discard(card)
+ //next_player()
+ game.state = 'vm_deutsche_marks_confirm'
+ game.vm_event = card
+ },
+ pass() {
+ push_undo()
+ vm_next()
+ }
+}
+
+states.vm_deutsche_marks_confirm = {
+ inactive: 'choose a card.',
+ prompt() {
+ view.prompt = `Deutsche Marks: gave ${cards[game.vm_event].name}.`
+ gen_action('done')
+ },
+ done() {
+ next_player()
+ game.state = 'vm_deutsche_marks'
+ }
+}
+
+states.vm_deutsche_marks = {
+ get inactive() {
+ return `resolve ${clean_name(cards[20].name)}.`
+ },
+ prompt() {
+ if(cards[game.vm_event].side === 'C' && (cards[game.vm_event].playable || game.playable_cards.includes(game.vm_event))) {
+ view.prompt = `Deutsche Marks: you must play ${clean_name(cards[this_card()].name)} for the event.`
+ gen_action('event')
+ } else {
+ view.prompt = `Deutsche Marks: play ${clean_name(cards[this_card()].name)} for:`
+ gen_action('influence')
+ gen_action('support_check')
+ if (game.com_tst_attempted_this_turn === 0) {
+ gen_action('tst')
+ }
+ }
+ },
+ event() {
+ push_undo()
+ log(`Played C${cards[game.vm_event].number} for the event`)
+ if (!game.vm_infl_to_do) {
+ game.return = game.active
+ }
+ goto_vm(game.vm_event)
+ },
+ influence() {
+ push_undo()
+ log(`Played C${cards[game.vm_event].number} to place SPs`)
+ game.vm_available_ops = get_card_ops(game.vm_event)
+
+ /*cards[game.vm_event].ops
+ if (game.persistent_events.includes(25)) {game.vm_available_ops++ }
+ if (game.prudence.COM && game.prudence.COM < 0 ) {
+ game.vm_available_ops += game.prudence.COM
+ }*/
+ valid_spaces_infl()
+ game.state = 'vm_add_infl'
+ },
+ support_check() {
+ push_undo()
+ log_gap(`Played C${cards[game.vm_event].number} for support checks`)
+ game.vm_available_ops = 2
+ game.state='vm_support_check_prep'
+ valid_spaces_sc()
+ },
+ tst() {
+ push_undo()
+ log_gap(`Played C${cards[game.vm_event].number} to the Tiananmen Square Track`)
+ game.state='vm_tiananmen_square_attempt'
+ }
+}
+
+states.vm_exit_visas = {
+ get inactive() {
+ return `resolve ${clean_name(cards[75].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Exit Visas: you may discard cards from your hand and draw replacements.'
+ for (let card of game.democrat_hand) {
+ gen_action_card(card)
+ }
+ if (game.temp === 0) {
+ gen_action('pass')
+ } else {
+ gen_action('done')
+ }
+ },
+ card(card){
+ push_undo()
+ discard(card)
+ game.temp++
+ },
+ pass() {
+ push_undo()
+ game.state = 'vm_exit_visas_finish'
+ },
+ done() {
+ push_undo()
+ game.state = 'vm_exit_visas_finish'
+ }
+}
+
+states.vm_exit_visas_finish = {
+ get inactive() {
+ return `resolve ${clean_name(cards[75].name)}.`
+ },
+ prompt() {
+ if (game.temp > 0 ) {
+ view.prompt = 'Exit Visas: draw replacement cards.'
+ gen_action('draw')
+ } /*else {
+ view.prompt = 'Exit Visas. Draw 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
+ vm_next()
+ },
+ /*done() {
+ vm_next()
+ }*/
+}
+
+states.vm_foreign_currency_debt_burden = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Choose a country. The Communist may not make support checks there for the rest of the turn.'
+ gen_action('east_germany')
+ gen_action('poland')
+ gen_action('czechoslovakia')
+ gen_action('hungary')
+ gen_action('bulgaria')
+ },
+ east_germany() {
+ push_undo()
+ game.foreign_currency_debt_burden = 'East_Germany'
+ log('Selected East Germany')
+ vm_next()
+ },
+ poland() {
+ push_undo()
+ game.foreign_currency_debt_burden = 'Poland'
+ log('Selected Poland')
+ vm_next()
+ },
+ czechoslovakia() {
+ push_undo()
+ game.foreign_currency_debt_burden = 'Czechoslovakia'
+ log('Selected Czechoslovakia')
+ vm_next()
+ },
+ hungary() {
+ push_undo()
+ game.foreign_currency_debt_burden = 'Hungary'
+ log('Selected Hungary')
+ vm_next()
+ },
+ bulgaria() {
+ push_undo()
+ game.foreign_currency_debt_burden = 'Bulgaria'
+ log('Selected Bulgaria')
+ vm_next()
+ }
+}
+
+states.vm_goodbye_lenin = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_cards.length > 0 ) {
+ view.prompt = `Play a red event from your opponent's hand, or play Goodbye Lenin for operations.`
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ gen_action('ops')
+ }
+ } else {
+ view.prompt = 'Communist has no red events. Play Goodbye Lenin for operations.'
+ gen_action('ops')
+ }
+ },
+ card(card) {
+ push_undo()
+ log(`Chose to play C${card} for the event`)
+ let card_index = game.communist_hand.indexOf(card)
+ game.communist_hand.splice(card_index, 1)
+ game.vm_event = card
+ game.view_opp_hand = false
+ goto_vm(card)
+ },
+ ops() {
+ push_undo()
+ if (game.valid_cards.length === 0) {
+ logi('No red events')
+ }
+ log('C46 played for operations')
+ game.view_opp_hand = false
+ game.state = 'vm_goodbye_lenin_ops'
+ }
+}
+
+states.vm_goodbye_lenin_ops = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt() {
+ view.prompt = `Play ${clean_name(cards[this_card()].name)} for:`
+ gen_action('influence')
+ gen_action('support_check')
+ if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 )) {
+ gen_action('tst')
+ }
+ },
+ influence(){
+ push_undo()
+ game.vm_available_ops = get_card_ops(this_card())
+ /*if (game.persistent_events.includes(50)) {
+ log(`+1 from C50`)
+ game.vm_available_ops++
+ }*/
+ valid_spaces_infl()
+
+ // If ABHR - Set AHBR tracker to true
+ if (game.persistent_events.includes(58)) {
+ game.austria_hungary_border_reopened_tracker = true
+ }
+ game.state = 'vm_add_infl'
+ },
+ support_check() {
+ push_undo()
+ game.vm_available_ops = 2
+ game.state = 'vm_support_check_prep'
+ valid_spaces_sc()
+ },
+ tst() {
+ push_undo()
+ game.state = 'vm_tiananmen_square_attempt'
+ }
+}
+
+states.vm_honecker = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_cards.length === 0 && game.temp === 0) {
+ view.prompt = 'Honecker: no valid cards to choose.'
+ gen_action('pass')
+ } else
+ if (game.temp === 0) {view.prompt = 'Honecker: choose a card to add to your hand.'
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ gen_action('pass')
+ }
+ } /*else {
+ view.prompt = 'Honecker. Choose a card: done.'
+ gen_action('done')
+ }*/
+ },
+ card(card) {
+ push_undo()
+ game.valid_cards = []
+ log(`Took C${cards[card].number} into hand`)
+ game.temp = card
+ let card_index = game.strategy_discard.indexOf(card)
+ game.strategy_discard.splice(card_index, 1)
+ game.communist_hand.push(card)
+ vm_next()
+ },
+ pass(){
+ log('Did not take a card')
+ game.discard = false
+ vm_next()
+ },
+ /*done(){
+ if (game.temp === 0) {
+ log('Did not take a card')
+ }
+ game.discard = false
+ vm_next()
+ } */
+
+}
+
+states.vm_inflationary_currency = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if ((game.active === COM && game.revolutions.every(n => n === false)) || (game.active === DEM && game.revolutions.every(n => n === true))) {
+ view.prompt = 'Inflationary Currency: no countries to choose.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Inflationary Currency: choose a country where your opponent has power.'
+ if (game.active === DEM) {
+ if (!game.revolutions[0]) {gen_action('poland')}
+ if (!game.revolutions[1]) {gen_action('hungary')}
+ if (!game.revolutions[2]) {gen_action('east_germany')}
+ if (!game.revolutions[3]) {gen_action('bulgaria')}
+ if (!game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (!game.revolutions[5]) {gen_action('romania')}
+ } else {
+ if (game.revolutions[0]) {gen_action('poland')}
+ if (game.revolutions[1]) {gen_action('hungary')}
+ if (game.revolutions[2]) {gen_action('east_germany')}
+ if (game.revolutions[3]) {gen_action('bulgaria')}
+ if (game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (game.revolutions[5]) {gen_action('romania')}
+ }
+ }
+ },
+ east_germany() {
+ push_undo()
+ game.vm_active_country = 'East_Germany'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ poland() {
+ push_undo()
+ game.vm_active_country = 'Poland'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ czechoslovakia() {
+ push_undo()
+ game.vm_active_country = 'Czechoslovakia'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ hungary() {
+ push_undo()
+ game.vm_active_country = 'Hungary'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ romania() {
+ push_undo()
+ game.vm_active_country = 'Romania'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ bulgaria () {
+ push_undo()
+ game.vm_active_country = 'Bulgaria'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ pass() {
+ log('Passed')
+ vm_return()
+ }
+}
+
+states.vm_inflationary_currency_discard = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_cards.length === 0 ) {
+ view.prompt = 'Inflationary Currency: no valid cards to discard. You must pass.'
+ gen_action('pass')
+ } else if (game.temp === 0 ) {
+ view.prompt = 'Inflationary Currency: you may discard a 3 op or higher value card to cancel the support check.'
+ gen_action('pass')
+ for (let card of game.valid_cards) {
+ gen_action_card(card)
+ }
+ } /*else {
+ view.prompt = 'Inflationary Currency. Discard a card: done.'
+ gen_action('done')
+ } */
+ },
+ card(card) {
+ push_undo()
+ discard(card)
+ game.temp = card
+ if (!game.vm_infl_to_do) {
+ if(game.round_player === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ }
+ vm_next()
+ },
+ pass() {
+ push_undo()
+ log('Did not discard')
+ next_player()
+ game.vm_available_ops = 1
+ vm_next()
+ //game.state = 'vm_support_check_prep'
+ },
+ done() {
+ if (!game.vm_infl_to_do) {
+ if(game.round_player === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ }
+ vm_next()
+ }
+}
+
+
+states.vm_kiss_of_death = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.communist_hand.length === 0) {
+ view.prompt = 'Kiss of Death. No cards to discard.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Kiss of Death: you must randomly discard a card.'
+ gen_action('discard')
+ }
+ },
+ discard() {
+ clear_undo()
+ game.vm_event = discard_card(game.communist_hand)
+ //Only switch player if a playable non-communist event. Common European Home is not playable here
+ if (cards[game.vm_event].side !== "C" && event_is_playable(game.vm_event) && game.vm_event !== 21) {
+ next_player()
+ game.state = 'vm_kiss_of_death_finish'
+ } else {
+ log('Event does not occur')
+ vm_next()
+ }
+ },
+ pass() {
+ log('No card to discard')
+ vm_next()
+ }
+}
+
+states.vm_kiss_of_death_finish = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.vm_event > 0 && game.vm_event !== 21 && (cards[game.vm_event].side === 'D' || cards[game.vm_event].side === 'N')) {
+ view.prompt = `Play ${clean_name(cards[game.vm_event].name)} for the event.`
+ console.log('kiss of death before event button: game.stategy_discard', game.strategy_discard)
+ gen_action('event')
+ } else {
+ view.prompt = 'Event does not occur.'
+ gen_action('done')
+ }
+ },
+ event() {
+ //game.return = game.active
+ // Remove game.vm_event from the discard
+ //game.strategy_discard = game.strategy_discard.filter(n => n !== game.vm_event)
+
+ goto_vm(game.vm_event)
+ },
+ done() {
+ vm_next()
+ }
+}
+
+states.vm_kremlin_coup_choose_country = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt() {
+ if (game.temp.length > 0) {
+ view.prompt = 'Kremlin Coup! Select a country where the Communist retains power.'
+ for (let country of countries) {
+ if (game.temp.includes(country)) {
+ gen_action(`${country.toLowerCase()}`)
+ }
+ }
+ } else {
+ view.prompt = 'Kremlin Coup! There are no countries where the Communist retains power.'
+ gen_action('done')
+ }
+ },
+ east_germany() {
+ push_undo()
+ game.vm_active_country = 'East_Germany'
+ game.temp = game.temp.filter(country => country !== game.vm_active_country)
+ log(`${country_name(game.vm_active_country)}:`)
+ vm_kremlin_coup_elite()
+ },
+ poland() {
+ push_undo()
+ game.vm_active_country = 'Poland'
+ log(`${country_name(game.vm_active_country)}:`)
+ game.temp = game.temp.filter(country => country !== game.vm_active_country)
+ vm_kremlin_coup_elite()
+ },
+ czechoslovakia() {
+ push_undo()
+ game.vm_active_country = 'Czechoslovakia'
+ log(`${country_name(game.vm_active_country)}:`)
+ game.temp = game.temp.filter(country => country !== game.vm_active_country)
+ vm_kremlin_coup_elite()
+ },
+ hungary() {
+ push_undo()
+ game.vm_active_country = 'Hungary'
+ log(`${country_name(game.vm_active_country)}:`)
+ game.temp = game.temp.filter(country => country !== game.vm_active_country)
+ vm_kremlin_coup_elite()
+ },
+ romania() {
+ push_undo()
+ game.vm_active_country = 'Romania'
+ log(`${country_name(game.vm_active_country)}:`)
+ game.temp = game.temp.filter(country => country !== game.vm_active_country)
+ vm_kremlin_coup_elite()
+ },
+ bulgaria () {
+ push_undo()
+ game.vm_active_country = 'Bulgaria'
+ log(`${country_name(game.vm_active_country)}:`)
+ game.temp = game.temp.filter(country => country !== game.vm_active_country)
+ vm_kremlin_coup_elite()
+ },
+ done() {
+ game.temp = 0
+ vm_next()
+ }
+}
+
+states.vm_kremlin_coup_take_control = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_spaces.includes(game.systematization)) {
+ view.prompt = `Kremlin Coup! ${country_name(game.vm_active_country)}'s Elite space no longer exists.`
+ gen_action('done')
+ }
+ else if (game.valid_spaces.length === 0){
+ view.prompt = `Kremlin Coup! ${country_name(game.vm_active_country)}'s Elite space is already controlled.`
+ gen_action('done')
+ } else {
+ view.prompt = `Kremlin Coup! Take control of the Elite space in ${country_name(game.vm_active_country)}.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ }
+ },
+ infl(space) {
+ push_undo()
+ vm_take_control(space)
+ if (game.vm_active_country === 'East_Germany') {game.selected_space = 3 }
+ if (game.vm_active_country === 'Poland') {game.selected_space = 17}
+ if (game.vm_active_country === 'Czechoslovakia') {game.selected_space = 29}
+ if (game.vm_active_country === 'Hungary') {game.selected_space = 45}
+ if (game.vm_active_country === 'Romania') {game.selected_space = 61}
+ if (game.vm_active_country === 'Bulgaria') {game.selected_space = 68}
+ game.state = 'vm_kremlin_coup_sc_prep'
+ },
+ done() {
+ push_undo()
+ if (game.vm_active_country === 'East_Germany') {game.selected_space = 3 }
+ if (game.vm_active_country === 'Poland') {game.selected_space = 17}
+ if (game.vm_active_country === 'Czechoslovakia') {game.selected_space = 29}
+ if (game.vm_active_country === 'Hungary') {game.selected_space = 45}
+ if (game.vm_active_country === 'Romania') {game.selected_space = 61}
+ if (game.vm_active_country === 'Bulgaria') {game.selected_space = 68}
+ game.state = 'vm_kremlin_coup_sc_prep'
+ }
+}
+
+states.vm_kremlin_coup_sc_prep = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = `Kremlin Coup! Conduct a support check in ${country_name(game.vm_active_country)}'s Bureaucratic space.`
+ gen_action_sc(game.selected_space);
+ },
+ sc(space) {
+ //game.selected_space = space
+ push_undo()
+ game.state = 'vm_kremlin_coup_sc'
+ }
+}
+
+states.vm_kremlin_coup_sc = {
+ inactive: 'do support checks',
+ prompt () {
+ view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die.`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_sc(game.selected_space)
+ if (game.temp.length > 0 ){
+ game.state = 'vm_kremlin_coup_choose_country'
+ } else {
+ //game.state = 'vm_kremlin_coup_end'
+ vm_next()
+ }
+ }
+}
+/*
+states.vm_kremlin_coup_end = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt() {
+ view.prompt = `${clean_name(cards[this_card()].name)} Support checks: done.`
+ gen_action('done')
+ },
+ done() {
+ vm_next()
+ }
+}
+*/
+states.vm_laszlo_tokes = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = `Laszlo Tokes. Choose to:`
+ gen_action('influence')
+ gen_action('support_check')
+ },
+ influence(){
+ push_undo()
+ game.vm_available_ops = get_card_ops(73)
+ valid_spaces_infl()
+ game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania')
+ game.phase = 3
+ vm_next()
+ //game.state = 'vm_add_infl'
+ },
+ support_check() {
+ push_undo()
+ game.vm_available_ops = 2
+ //game.state = 'vm_support_check_prep'
+ valid_spaces_sc()
+ game.valid_spaces = game.valid_spaces.filter(space_id => spaces[space_id].country === 'Romania')
+ vm_next()
+ }
+}
+
+states.vm_switch_infl = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_spaces.length === 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: No SPs to remove.`
+ gen_action('pass')
+ } else {
+ /*if (game.vm_available_ops > 0 ) {*/
+ view.prompt = `${clean_name(cards[game.played_card].name)}: ${event_prompt()}.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ } /*else {
+ view.prompt = 'Influence replaced.'
+ gen_action('done')
+ }*/
+ },
+ infl(space) {
+ push_undo()
+ vm_switch_infl(space)
+ if (game.vm_available_ops === 0) {
+ game.valid_spaces = []
+ }
+ vm_next()
+ },
+ pass() {
+ vm_next()
+ }
+ /*done() {
+ vm_next()
+ }*/
+}
+
+states.vm_malta_summit = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ /*if (game.phase === 1) {*/
+ view.prompt = 'Malta Summit: roll a die.'
+ gen_action('roll')
+ /*} else {
+ view.prompt = 'Done.'
+ gen_action('done')
+ }*/
+ },
+ roll() {
+ clear_undo()
+ let roll = Math.floor(Math.random() * 6) + 1
+ log(`Roll: D${roll}`)
+ if (game.stability > 0) {
+ log(`+${game.stability} from USSR Stability Track`)
+ log(`Modified roll: ${roll + game.stability}`)
+ }
+ if (roll + game.stability > 3) {
+ log('Summit successful')
+ game.vp += 3
+ log('+3 VP')
+ if (check_vp()) {
+ return
+ }
+ if (game.comInfl[12] > 0 ) {game.valid_spaces.push(12)}
+ if (game.comInfl[15] > 0 ) {game.valid_spaces.push(15)}
+ if (game.comInfl[27] > 0 ) {game.valid_spaces.push(27)}
+ if (game.comInfl[43] > 0 ) {game.valid_spaces.push(43)}
+ if (game.comInfl[51] > 0 ) {game.valid_spaces.push(51)}
+ if (game.comInfl[69] > 0 ) {game.valid_spaces.push(69)}
+ //game.vm_available_ops = 5
+ game.remove_opponent_infl = true
+ vm_next()
+ }
+ else {
+ log('Summit failed. Required 4 or more')
+ //game.phase++
+ vm_goto_step(vm_permanently_remove)
+ }
+ },
+ /*done() {
+ vm_next()
+ }*/
+}
+
+states.vm_modrow = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = `Modrow: roll a die.`
+ gen_action('roll')
+ },
+ roll(){
+ clear_undo()
+ let roll = Math.floor(Math.random() * 6) + 1
+ let dem_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_dem_control(space.space_id)).length
+ if (roll > dem_spaces) {
+ log(`Roll: D${roll}`)
+ log(`Success. More than the ${dem_spaces} Democratically controlled spaces`)
+ vm_next()
+ } else {
+ log(`Roll: D${roll}`)
+ log(`Fail. More than ${dem_spaces} required`)
+ permanently_remove(83)
+ vm_return()
+ }
+ }
+}
+
+states.vm_nepotism = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ //if (game.phase === 1 ) {
+ view.prompt = 'Nepotism: roll a die.'
+ gen_action('roll')
+ /*} else {
+ view.prompt = 'Roll a die: done.'
+ gen_action('done')
+ }*/
+ },
+ roll() {
+ clear_undo()
+ let roll = Math.floor(Math.random() * 6) + 1
+ if (roll < 3) {
+ log(`Roll: D${roll} adds 4 SPs`)
+ game.vm_available_ops = 4}
+ else if (roll < 5 ) {
+ log(`Roll: D${roll} adds 3 SPs`)
+ game.vm_available_ops = 3}
+ else {
+ log(`Roll: D${roll} adds 1 SP`)
+ game.vm_available_ops = 1}
+ //game.phase = 2
+ vm_next()
+ },
+ /*done() {
+ vm_next()
+ }*/
+}
+
+states.vm_new_years_eve_party = {
+ get inactive() {
+ return `resolve ${clean_name(cards[104].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Choose whether the game ends at the end of this turn.'
+ gen_action('end')
+ gen_action('continue')
+ },
+ end() {
+ push_undo()
+ game.persistent_events.push(104)
+ log('Chooses to end the game. There will be no final scoring')
+ let power = game.revolutions.filter(value => value === false).length
+ if (power > 3) {
+ log(`Communist holds power in ${power} countries. -3 VP`)
+ game.vp -= 3
+ } else {
+ log(`Communist holds power in ${power} countries. +3 VP`)
+ game.vp += 3
+ }
+ if (check_vp()) {
+ return
+ }
+ //game.table_cards.push(104)
+ permanently_remove(104)
+ vm_next()
+ },
+ continue() {
+ push_undo()
+ log('Chooses to continue')
+ permanently_remove(104)
+ vm_next()
+ }
+}
+
+states.vm_nomenklatura = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Nomenklatura: choose to remove all Democratic SPs from Elite spaces or add 3 SPs to any Elite space(s).'
+ gen_action('remove')
+ gen_action('add')
+ },
+ remove() {
+ push_undo()
+ game.valid_spaces = []
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+
+ if (space.socio === 1 && game.demInfl[i] > 0) {
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ game.vm_available_ops = game.valid_spaces.length
+ game.remove_opponent_infl = true
+ game.state = 'vm_nomenklatura_remove'
+ },
+ add() {
+ push_undo()
+ game.valid_spaces = []
+ for (let space of spaces) {
+ if (!space) continue
+ if (space.socio === 1) {
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ check_systematization()
+ game.vm_available_ops = 3
+ game.state = 'vm_nomenklatura_add'
+ }
+}
+
+states.vm_nomenklatura_remove = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_spaces.length === 0 ) {
+ view.prompt = 'Nomenklatura. No SPs to remove: pass.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Nomenklatura: remove all Democratic SPs from Elite spaces.'
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ }
+ },
+ infl(space) {
+ push_undo()
+ vm_do_remove_all_infl(space)
+ if (game.valid_spaces.length === 0) {
+ vm_next()
+ }
+ },
+ pass() {
+ push_undo()
+ vm_next()
+ }
+}
+
+states.vm_nomenklatura_add = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ /*if (game.vm_available_ops === 0 || game.valid_spaces.length === 0 ) {
+ view.prompt = 'Nomenklatura. Add SPs: done.'
+ gen_action('done')
+ } else { */
+ view.prompt = `Nomenklatura: add 3 SPs to any Elite space(s). ${pluralize(game.vm_available_ops, 'SP')} remaining.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ //}
+ },
+ infl(space) {
+ push_undo()
+ vm_do_add_infl_free(space)
+ if (game.vm_available_ops === 0 ) {
+ game.valid_spaces = []
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ }
+ },
+/* done() {
+ push_undo()
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ }*/
+}
+
+states.vm_samizdat = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Samizdat: you may set aside a card from your hand and draw a replacement.'
+ for (let card of game.democrat_hand) {
+ gen_action_card(card)
+ }
+ gen_action('pass')
+ },
+ card(card) {
+ push_undo()
+ game.samizdat_card = card
+ game.democrat_hand = game.democrat_hand.filter(c => c !== card)
+ log('Set aside a card')
+ game.state = 'vm_samizdat_finish'
+ },
+ pass() {
+ push_undo()
+ //if (game.samizdat_card > 0) {game.state = 'vm_samizdat_finish'}
+ /*else { */
+ log('Did not set aside a card')
+ vm_next()
+ //}
+ }
+}
+
+states.vm_samizdat_finish = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ /*if (game.phase ) {
+ view.prompt = 'Samizdat: done.'
+ gen_action('done')
+ } else {*/
+ view.prompt = 'Draw a replacement card.'
+ gen_action('draw')
+ //}
+ },
+ draw() {
+ clear_undo()
+ game.democrat_hand.push(draw_card(game.strategy_deck))
+ vm_next()
+ //game.phase ++
+ },
+ /*done() {
+ vm_next()
+ }*/
+}
+
+states.vm_shock_therapy = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.revolutions.every(n => n === false)) {
+ view.prompt = 'Shock Therapy: no countries to choose.'
+ gen_action('pass')
+ } else {
+ if (game.vm_active_country === '' ) {
+ view.prompt = 'Shock Therapy: choose a country where you hold Power:'
+ if (game.revolutions[0]) {gen_action('poland')}
+ if (game.revolutions[1]) {gen_action('hungary')}
+ if (game.revolutions[2]) {gen_action('east_germany')}
+ if (game.revolutions[3]) {gen_action('bulgaria')}
+ if (game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (game.revolutions[5]) {gen_action('romania')}
+ } /*else if (game.phase === 2) {
+ view.prompt = 'Shock Therapy: done.'
+ gen_action('done')
+ } */
+ else {
+ view.prompt = 'Shock Therapy: roll a die.'
+ gen_action('roll')
+ }
+ }
+ },
+ east_germany() {
+ push_undo()
+ game.vm_active_country = 'East_Germany'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ },
+ poland() {
+ push_undo()
+ game.vm_active_country = 'Poland'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ },
+ czechoslovakia() {
+ push_undo()
+ game.vm_active_country = 'Czechoslovakia'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ },
+ hungary() {
+ push_undo()
+ game.vm_active_country = 'Hungary'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ },
+ romania() {
+ push_undo()
+ game.vm_active_country = 'Romania'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ },
+ bulgaria () {
+ push_undo()
+ game.vm_active_country = 'Bulgaria'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ },
+ roll() {
+ clear_undo()
+ let roll = Math.floor(Math.random() * 6) + 1
+ let worker_farmer = 0
+ for (let space of spaces) {
+ if (space && space.country === game.vm_active_country && check_com_control(space.space_id) && (space.socio === 3 || space.socio === 4)) {
+ worker_farmer++
+ }
+ }
+ log(`Roll: D${roll}`)
+ log(`-${worker_farmer} from Communist controlled Worker and Farmer spaces`)
+ log(`Modified roll: ${roll - worker_farmer}`)
+ if ((roll - worker_farmer) > 2) {
+ log('C93 is successful. +3 VP')
+ vm_next()
+ } else {
+ log('C93 is unsuccessful. Required 3 or more')
+ //game.phase++
+ permanently_remove(93)
+ vm_return()
+ }
+ },
+ pass() {
+ log('Passed')
+ vm_return()
+ }
+ /*done() {
+ permanently_remove(93)
+ vm_return()
+ }*/
+}
+
+states.vm_social_democratic_platform_adopted = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.revolutions.every(n => n === false)) {
+ view.prompt = 'Social Democratic Platform Adopted: no countries to choose.'
+ gen_action('pass')
+ } else {
+ view.prompt = 'Select a country where the Democrat holds Power.'
+ if (game.revolutions[0]) {gen_action('poland')}
+ if (game.revolutions[1]) {gen_action('hungary')}
+ if (game.revolutions[2]) {gen_action('east_germany')}
+ if (game.revolutions[3]) {gen_action('bulgaria')}
+ if (game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (game.revolutions[5]) {gen_action('romania')}
+ }
+ },
+ east_germany() {
+ push_undo()
+ game.vm_active_country = 'East_Germany'
+ log(`Selected ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ poland() {
+ push_undo()
+ game.vm_active_country = 'Poland'
+ log(`Selected ${country_name(game.vm_active_country)}`)
+ vm_next()},
+ czechoslovakia() {
+ push_undo()
+ game.vm_active_country = 'Czechoslovakia'
+ log(`Selected ${country_name(game.vm_active_country)}`)
+ vm_next()},
+ hungary() {
+ push_undo()
+ game.vm_active_country = 'Hungary'
+ log(`Selected ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ romania() {
+ push_undo()
+ game.vm_active_country = 'Romania'
+ log(`Selected ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ bulgaria () {
+ push_undo()
+ game.vm_active_country = 'Bulgaria'
+ log(`Selected ${country_name(game.vm_active_country)}`)
+ vm_next()
+ },
+ pass() {
+ log('Passed')
+ vm_return()
+ }
+}
+
+states.vm_systematization = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ /*if (game.systematization === 0) { */
+ view.prompt = 'Systematization: eliminate a space in Romania.'
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ /*} else {
+ view.prompt = 'Systematization: done.'
+ gen_action('done')
+ }*/
+ },
+ infl(space) {
+ push_undo()
+ vm_eliminate(space)
+ game.valid_spaces = []
+ game.systematization = space
+ game.persistent_events.push(69)
+ vm_next()
+ },
+/* done() {
+ vm_next()
+ } */
+}
+
+states.vm_the_chinese_solution = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'The Chinese Solution: you may give up 3 VP to conduct support checks in a country where you hold power.'
+ if (!game.revolutions[0]) {gen_action('poland')}
+ if (!game.revolutions[1]) {gen_action('hungary')}
+ if (!game.revolutions[2]) {gen_action('east_germany')}
+ if (!game.revolutions[3]) {gen_action('bulgaria')}
+ if (!game.revolutions[4]) {gen_action('czechoslovakia')}
+ if (!game.revolutions[5]) {gen_action('romania')}
+ gen_action('pass')
+ },
+ east_germany() {
+ push_undo()
+ game.vm_active_country = 'East_Germany'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ poland() {
+ push_undo()
+ game.vm_active_country = 'Poland'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ czechoslovakia() {
+ push_undo()
+ game.vm_active_country = 'Czechoslovakia'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ hungary() {
+ push_undo()
+ game.vm_active_country = 'Hungary'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ romania() {
+ push_undo()
+ game.vm_active_country = 'Romania'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ bulgaria () {
+ push_undo()
+ game.vm_active_country = 'Bulgaria'
+ log(`Chose ${country_name(game.vm_active_country)}`)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ vm_next()
+ },
+ pass() {
+ push_undo()
+ permanently_remove(96)
+ vm_return()
+ }
+}
+
+states.vm_the_tyrant_is_gone = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (!game.the_tyrant_is_gone) {
+ view.prompt = 'The Tyrant is Gone: Select a space in Romania for the Ceausescus to flee to.'
+ for (let space_id of game.valid_spaces) {
+ if (!space_id) continue
+ gen_action_infl(space_id);
+ }
+ } else {
+ view.prompt = 'The Tyrant is Gone: done.'
+ gen_action('done')
+ }
+ },
+ infl(space) {
+ push_undo()
+ log(`The Ceausescus flee to %${space}`)
+ game.the_tyrant_is_gone = space
+ game.valid_spaces = []
+ game.persistent_events.push(97)
+
+ // vm_next()
+ },
+ done () {
+ vm_next()
+ }
+}
+/*
+states.vm_tyrant_block ={
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt() {
+ view.prompt = `${clean_name(cards[this_card()].name)} has no effect after The Tyrant Has Gone.`
+ gen_action('done')
+ },
+ done() {
+ push_undo()
+ vm_next()
+ }
+}*/
+
+
+states.vm_the_wall_must_go = {
+ get inactive() {
+ return `resolve ${clean_name(cards[this_card()].name)}.`
+ },
+ prompt() {
+ /*if (game.the_wall_must_go['dem_wins'] === 2 || game.the_wall_must_go['com_wins'] === 2) {
+ view.prompt = '"The Wall Must Go!" Rolls: done.'
+ gen_action('done')
+ } else { */
+ view.prompt = ('The Wall Must Go! Roll a die.')
+ gen_action('roll')
+ //}
+ },
+ roll() {
+ clear_undo()
+ let attempt = game.the_wall_must_go['dem_wins'] + game.the_wall_must_go['com_wins']
+ if (game.the_wall_must_go['dem_roll'] === 0 && game.the_wall_must_go['com_roll'] === 0) {
+ log_h3(`Round ${attempt+1}`)
+ }
+
+ let roll = Math.floor(Math.random() * 6) + 1
+ log(`Roll: D${roll}`)
+ if (game.active === DEM) {
+ let controlled_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_dem_control(space.space_id)).length
+ if (controlled_spaces > 0) {
+ log(`+${controlled_spaces} from controlled spaces in East Germany`)
+ log(`Modified roll: ${roll + controlled_spaces}`)
+ roll += controlled_spaces
+ }
+ game.the_wall_must_go['dem_roll'] = roll
+ } else {
+ let controlled_spaces = spaces.filter(space => space && space.country === 'East_Germany' && check_com_control(space.space_id)).length
+ if (controlled_spaces > 0) {
+ log(`+${controlled_spaces} from controlled spaces in East Germany`)
+ log(`Modified roll: ${roll + controlled_spaces}`)
+ roll += controlled_spaces
+ }
+ game.the_wall_must_go['com_roll'] = roll
+
+ }
+ if (game.the_wall_must_go['dem_roll'] > 0 && game.the_wall_must_go['com_roll'] > 0) {
+ if (game.the_wall_must_go['dem_roll'] > game.the_wall_must_go['com_roll'] ) {
+ log('Democrat wins')
+ game.the_wall_must_go['dem_wins']++
+ } else if (game.the_wall_must_go['dem_roll'] === game.the_wall_must_go['com_roll'] ) {
+ log('Tie. Re-roll')
+ } else {
+ log('Communist wins')
+ game.the_wall_must_go['com_wins']++
+ }
+
+ log(`Democrat: ${game.the_wall_must_go['dem_wins']}, Communist: ${game.the_wall_must_go['com_wins']}`)
+ }
+ if (game.the_wall_must_go['dem_wins'] === 2) {
+ log('The Democrat wins C86')
+ finish_the_wall()
+ return
+ }
+ if (game.the_wall_must_go['com_wins'] === 2) {
+ log('The Communist wins C86')
+ finish_the_wall()
+ return
+ }
+ if (game.the_wall_must_go['dem_roll'] === 0 || game.the_wall_must_go['com_roll'] === 0) {
+ next_player()
+ } else {
+ game.the_wall_must_go['dem_roll'] = 0
+ game.the_wall_must_go['com_roll'] = 0
+ }
+ },
+ /*done() {
+ if (game.the_wall_must_go['dem_wins'] === 2) {
+ game.persistent_events.push(86)
+ log('+3 VP')
+ game.vp += 3
+ if (check_vp()) {
+ return
+ }
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (space.country === 'East_Germany' && game.comInfl[i] > 0){
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ if (!game.vm_infl_to_do) {
+ if (game.round_player === DEM) {
+ game.return = COM
+ } else {
+ game.return = DEM
+ }
+ }
+ if (game.active === DEM) {next_player()}
+ vm_next ()
+ } else {
+ permanently_remove(86)
+ delete game.the_wall_must_go
+ vm_return()
+ }
+ }*/
+}
+
+states.vm_warsaw_pact_summit = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ view.prompt = 'Choose to play for support checks or place SPs.'
+ gen_action('influence')
+ gen_action('support_check')
+ },
+ influence(){
+ push_undo()
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (game.demInfl[i] === 0) {
+ game.valid_spaces.push(space.space_id);
+ }
+ }
+ game.vm_available_ops = 4
+ game.phase = 3
+ //game.state = 'vm_add_infl'
+ vm_next()
+ },
+ support_check(){
+ push_undo()
+ for (let i = 1; i < spaces.length; i++) {
+ let space = spaces[i]
+ if (game.demInfl[i] > 0 && (space.socio === 5 || space.socio === 6)) {
+ game.valid_spaces.push(space.space_id)
+ }
+ }
+ game.vm_available_ops = 2
+ //game.state = 'vm_support_check_prep'
+ vm_next()
+ }
+}
+
+states.vm_we_are_the_people_remove = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.demInfl[6] === 0 && game.vm_available_ops > 0) {
+ view.prompt = '"We are the People!": no SPs to remove.'
+ gen_action('done')
+ } else if (game.vm_available_ops > 0 ) {
+ view.prompt = '"We are the People!": remove up to 4 SPs from the Lutherian Church.'
+ gen_action('done')
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ } else {
+ view.prompt = '"We are the People!" Remove SPs: done.'
+ gen_action('done')
+ }
+ },
+ infl(space) {
+ vm_do_remove_infl(space)
+ },
+ done() {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ if (!game.vm_influence_added[6]) {
+ log('No SPs removed')
+ vm_next()
+ } else {
+ game.valid_spaces = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
+ game.state = 'vm_we_are_the_people_add'
+ }
+ }
+}
+states.vm_we_are_the_people_add = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ /* if (!game.vm_influence_added[6]) {
+ view.prompt = '"We are the People!" Add SPs: done.'
+ gen_action('done')
+ return
+ }*/
+
+ view.prompt = `"We are the People!": you must add the ${pluralize(game.vm_influence_added[6],'SP')} to spaces in Germany.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ },
+ infl(space) {
+ vm_do_add_infl_free(space)
+ game.vm_influence_added[6]--
+ if (game.vm_influence_added[6] === 0 ) {
+ game.valid_spaces = []
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ }
+ },
+ /*done() {
+ push_undo()
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ }*/
+}
+
+states.vm_workers_revolt = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ if (game.valid_spaces.length === 0 ) {
+ view.prompt = 'Workers Revolt: no valid spaces to select.'
+ gen_action('pass')
+ return
+ }
+ view.prompt = 'Workers Revolt: select a Worker Space in a country your opponent has power.'
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id)
+ }
+ },
+ pass() {
+ push_undo()
+ vm_next()
+ },
+ infl(space) {
+ push_undo()
+ game.selected_space = space
+ log(`Chose %${game.selected_space}`)
+ game.state = 'vm_workers_revolt_finish'
+ }
+}
+
+
+states.vm_workers_revolt_finish = {
+ get inactive() {
+ return `resolve ${clean_name(cards[game.played_card].name)}.`
+ },
+ prompt() {
+ //if (game.selected_space > 0) {
+ view.prompt = `Target: ${spaces[game.selected_space].name_unique}. Roll a die.`
+ gen_action('roll')
+ /* } else {
+ view.prompt = 'Workers Revolt: done.'
+ gen_action('done')
+ }*/
+
+ },
+ roll() {
+ clear_undo()
+ let roll = Math.floor(Math.random() * 6) + 1
+ log(`Roll: D${roll}`)
+ let adj = count_adj(game.selected_space)
+ if (game.active === DEM) {
+ log(`-${adj.com_adj} from opponent controlled spaces`)
+ roll -= adj.com_adj
+ } else {
+ log(`-${adj.dem_adj} from opponent controlled spaces`)
+ roll -= adj.dem_adj
+ }
+ log(`Modified roll: ${roll}`)
+ if (roll >= 4) {
+ log('Workers Revolt successful')
+ vm_replace_all_infl(game.temp)
+ } else {log('Workers Revolt fails. Required 4 or more')}
+ game.selected_space = 0
+ vm_next()
+ },
+ /*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 = []
+ vm_next()
+ }
+ },
+ /*done() {
+ vm_next()
+ }*/
+}
+
+states.vm_tst_4 = {
+ inactive: 'remove SPs',
+ prompt () {
+ if (game.vm_available_ops === 0 || game.valid_spaces.length === 0) {
+ view.prompt = 'Tiananmen Square Track award. Remove SPs: done.'
+ gen_action('done')
+ return
+ }
+ view.prompt = `Tiananmen Square Track award: remove ${pluralize(game.vm_available_ops,'SP')}.`
+
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ },
+ infl(space) {
+ vm_do_remove_infl(space)
+ if (game.vm_available_ops === 0) {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ }
+ },
+ done() {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ }
+}
+
+states.vm_tst_6 = {
+ inactive: 'make their free support check.',
+ prompt() {
+ /* if (game.vm_available_ops === 0) {
+ view.prompt = 'Tiananmen Square Track award support check: done.'
+ gen_action('done')
+ return
+ } else {*/
+ view.prompt = 'Tiananmen Square Track award: you have a free 2 Ops support check.'
+ for (let space_id of game.valid_spaces) {
+ if (space_id) {
+ gen_action_sc(space_id);
+ }
+ }
+ //}
+ },
+ sc(space) {
+ push_undo()
+ game.selected_space = space
+ if (game.active === DEM && game.persistent_events.includes(58) && spaces[space].country === "East_Germany") {
+ game.austria_hungary_border_reopened_tracker = true
+ }
+ game.state = 'vm_tst_6_sc'
+ },
+ /*done () {
+ push_undo()
+ vm_next()
+ }*/
+}
+
+states.vm_tst_6_sc = {
+ inactive: 'do support check.',
+ prompt () {
+ view.prompt = `Support check: ${spaces[game.selected_space].name_unique}. Roll a die`
+ gen_action('roll')
+ },
+ roll() {
+ clear_undo()
+ do_sc(game.selected_space)
+ game.vm_available_ops--
+ game.valid_spaces = []
+ game.state = 'vm_tst_6'
+ vm_next()
+ return
+ }
+}
+
+states.vm_tst_8 = {
+ inactive: 'use Tiananmen Square Track award.',
+ prompt() {
+ if (game.vm_event_to_do && game.vm_infl_to_do) {
+ view.prompt = 'Choose whether to play for event or operations first.'
+ gen_action('event')
+ gen_action('ops')
+ }
+ else if (!game.vm_event_to_do && game.vm_infl_to_do) {
+ view.prompt = 'Event resolved. Use card for operations.'
+ gen_action('ops')
+ }
+ else if (game.vm_event_to_do && !game.vm_infl_to_do) {
+ view.prompt = 'Operations resolved. Use card for event.'
+ gen_action('event')
+ }
+ else if (!game.vm_event_to_do && !game.vm_infl_to_do) {
+ view.prompt = 'Event and operations: done.'
+ gen_action('end_round')
+ }
+ },
+ event() {
+ push_undo()
+ log('Event')
+ game.vm_event_to_do = false
+ game.return_state = 'vm_tst_8'
+ game.return = game.active
+ game.vm_event = game.played_card
+ goto_vm(game.vm_event)
+ },
+ ops() {
+ push_undo()
+ log('Operations')
+ game.vm_infl_to_do = false
+ game.return = game.active
+ game.return_state = 'vm_tst_8'
+ goto_vm(208)
+ },
+ end_round() {
+ push_undo()
+ game.tst_8 = true
+ end_round()
+ }
+}
+
+
+states.vm_tst_8_ops = {
+ inactive: 'play card for operations.',
+ prompt() {
+ view.prompt = `Play ${clean_name(cards[game.played_card].name)} for:`
+ gen_action('influence')
+ gen_action('support_check')
+ if ((game.active === DEM && game.dem_tst_attempted_this_turn === 0 ) || (game.active === COM && game.com_tst_attempted_this_turn === 0 )) {
+ gen_action('tst')
+ }
+ },
+ influence(){
+ push_undo()
+ game.vm_available_ops = cards[game.played_card].ops
+ valid_spaces_infl()
+ // If ABHR - Set AHBR tracker to true
+ if (game.persistent_events.includes(58)) {
+ game.austria_hungary_border_reopened_tracker = true
+ }
+ game.state = 'vm_add_infl'
+ },
+ support_check() {
+ push_undo()
+ game.vm_available_ops = 2
+ game.state = 'vm_support_check_prep'
+ },
+ tst() {
+ push_undo()
+ game.state = 'vm_tiananmen_square_attempt'
+ }
+}
+
+// ========================= POWER STRUGGLE STATES ========================
+
+states.vm_scare_tactics = {
+ inactive: 'remove a Support Point.',
+ prompt () {
+ if (game.valid_spaces.length === 0 && game.vm_available_ops > 0) {
+ view.prompt = `${clean_name(cards[this_card()].name)}: no SPs to remove.`
+ gen_action('done')
+ return
+ }
+ if (game.vm_available_ops === 0 ) {
+ view.prompt = `${clean_name(cards[this_card()].name)}. Remove SPs: done.`
+ gen_action('done')
+ return
+ }
+ view.prompt = `${clean_name(cards[this_card()].name)}: remove ${pluralize(game.vm_available_ops, 'opponent SP')}${event_prompt()}.`
+ for (let space_id of game.valid_spaces) {
+ gen_action_infl(space_id);
+ }
+ },
+ infl(space) {
+ push_undo()
+ vm_do_remove_infl(space)
+ },
+ done() {
+ if (game.summary.length > 0) {
+ pop_summary()
+ log_br()
+ }
+ vm_next()
+ }
+}
+
+states.vm_support_surges_1 = {
+ inactive: 'draw cards.',
+ prompt() {
+ view.prompt = 'Support Surges: draw a card.'
+ gen_action('draw')
+ },
+ draw() {
+ if (game.active === DEM) {
+ //console.log('hand before', game.dem_pwr_hand)
+ draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+1, game.com_pwr_hand.length)
+ game.temp = game.dem_pwr_hand[game.dem_pwr_hand.length-1]
+ //console.log('hand after', game.dem_pwr_hand, 'game.temp', game.temp)
+ } else {
+ //console.log('hand before', game.com_pwr_hand)
+ draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+1)
+ game.temp = game.com_pwr_hand[game.com_pwr_hand.length-1]
+ //console.log('hand after', game.com_pwr_hand, 'game.temp', game.temp)
+ }
+ game.state = 'vm_support_surges_2'
+
+ //game.phase = 0
+ //log('Drew 2 cards')
+ //log('Surrenders initiative')
+ //vm_next()
+ }
+}
+
+states.vm_support_surges_2 = {
+ inactive: 'draw cards.',
+ prompt() {
+ let special = [49,50,51,52]
+ let elite_leader = [37,38,39,40]
+ if (special.includes(game.temp)) {
+ view.prompt = `Support Surges: you drew ${power_cards[game.temp].name}. Draw a second card.`
+ }
+ else if (elite_leader.includes(game.temp)) {
+ view.prompt = `Support Surges: you drew an ${power_cards[game.temp].name}. Draw a second card.`
+ }
+ else if (numberless_cards.includes(game.temp)) {
+ view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name}. Draw a second card.`
+ } else {
+ view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name} ${power_cards[game.temp].value}. Draw a second card.`
+ }
+ gen_action('draw')
+ },
+ draw() {
+ if (game.active === DEM) {
+ draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length+1, game.com_pwr_hand.length)
+ game.temp = game.dem_pwr_hand[game.dem_pwr_hand.length - 1]
+ } else {
+ draw_cards(game.power_struggle_deck, game.dem_pwr_hand, game.com_pwr_hand, game.dem_pwr_hand.length, game.com_pwr_hand.length+1)
+ game.temp = game.com_pwr_hand[game.com_pwr_hand.length - 1]
+ }
+ game.state = 'vm_support_surges_3'
+ /*game.phase = 0
+ log('Drew 2 cards')
+ log('Surrenders initiative')
+ vm_next()*/
+ }
+}
+
+states.vm_support_surges_3 = {
+ inactive: 'draw cards.',
+ prompt() {
+ if (numberless_cards.includes(game.temp)) {
+ view.prompt = `Support Surges: you drew ${power_cards[game.temp].name}. Done.`
+ } else {
+ view.prompt = `Support Surges: you drew a ${power_cards[game.temp].name} ${power_cards[game.temp].value}. Done.`
+ }
+ gen_action('done')
+ },
+ done() {
+ game.phase = 0
+ delete game.temp
+ log('Drew 2 cards')
+ log('Surrenders initiative')
+ vm_next()
+ }
+}
+
+states.vm_support_falters = {
+ inactive: 'discard cards.',
+ prompt() {
+ if ((game.active === DEM && game.dem_pwr_hand.length === 0) || (game.active === COM && game.com_pwr_hand.length === 0)) {
+ view.prompt = 'Support Falters: no remaining cards to discard.'
+ gen_action('pass')
+ } else if (game.vm_available_ops > 0) {
+ view.prompt = 'Support Falters: discard a card.'
+ gen_action('discard')
+ } else {
+ view.prompt = 'Support Falters: done.'
+ gen_action('done')
+ }
+ },
+ discard() {
+ if (game.active === DEM) {discard_card(game.dem_pwr_hand)}
+ else {discard_card(game.com_pwr_hand)}
+ game.vm_available_ops --
+ },
+ pass() {
+ log_msg_gap('Takes initiative')
+ game.return = game.active
+ vm_next()
+ },
+ done() {
+ log_gap('Takes initiative')
+ game.return = game.active
+ vm_next()
+ }
+}
+
+/* =================== EVENTS ================================ */
+
+// #region GENERATED EVENT CODE
+const CODE = []
+
+CODE[1] = [ // Legacy of Martial Law*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country_opp, 'Poland' ],
+ [ vm_prompt, 'replace 1 Democratic SP in Poland with a Communist SP' ],
+ [ vm_legacy_of_martial_law ],
+ [ vm_valid_spaces_country_sc, 'Poland' ],
+ [ vm_prompt, 'make a Support Check in Poland' ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[2] = [ // Solidarity Legalised*
+ [ vm_permanently_remove ],
+ [ vm_solidarity_legalised ],
+ [ vm_valid_spaces_solidarity_legalised ],
+ [ vm_prompt, 'to every uncontrolled Worker and Farmer space in Poland' ],
+ [ vm_add_limited_infl, 9, 1 ],
+ [ vm_return ],
+]
+
+CODE[3] = [ // Walesa
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country, 'Poland' ],
+ [ vm_prompt, 'any space(s) in Poland' ],
+ [ vm_add_infl_free, 4 ],
+ [ vm_valid_spaces_country_sc, 'Poland' ],
+ [ vm_prompt, 'make Support Checks in Poland' ],
+ [ vm_support_check, 2 ],
+ [ vm_return ],
+]
+
+CODE[4] = [ // Michnik
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces, 26 ],
+ [ vm_prompt, 'the Polish Intellectuals space' ],
+ [ vm_add_x_infl, 3 ],
+ [ vm_return ],
+]
+
+CODE[5] = [ // General strike
+ [ vm_general_strike ],
+ [ vm_return ],
+]
+
+CODE[6] = [ // Brought in for Questioning
+ [ vm_brought_in_for_questioning ],
+ [ vm_return ],
+]
+
+CODE[7] = [ // State Run Media*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_opponent ],
+ [ vm_remove_limited_opp_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[8] = [ // Prudence
+ [ vm_prudence ],
+ [ vm_return ],
+]
+
+CODE[9] = [ // The Wall*
+ [ vm_permanently_remove ],
+ [ vm_the_wall ],
+ [ vm_return ],
+]
+
+CODE[10] = [ // Cult of Personality
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!game.the_tyrant_is_gone ],
+ [ vm_valid_spaces_country_socio_2, 'Romania', 3, 4 ],
+ [ vm_prompt, 'Worker or Farmer spaces in Romania, no more than 2 per space' ],
+ [ vm_add_limited_infl, 4, 2 ],
+ [ vm_else ],
+ [ vm_tyrant_block ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[11] = [ // Dissident arrested
+ [ vm_valid_spaces_opponent_socio, 5 ],
+ [ vm_prompt, 'any Intellectuals space' ],
+ [ vm_remove_x_opp_infl, 2 ],
+ [ vm_return ],
+]
+
+CODE[12] = [ // Apparatchicks
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_socio, 2 ],
+ [ vm_prompt, ' to any Bureaucratic space(s)' ],
+ [ vm_add_infl_free, 3 ],
+ [ vm_return ],
+]
+
+CODE[13] = [ // Stasi
+ [ vm_permanently_remove ],
+ [ vm_stasi ],
+ [ vm_return ],
+]
+
+CODE[14] = [ // Gorbachev Charms the West
+ [ vm_valid_spaces_opponent ],
+ [ vm_remove_opp_infl, 2 ],
+ [ vm_valid_spaces_sc ],
+ [ vm_prompt, 'select a space for the Support Check' ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[15] = [ // Honecker
+ [ vm_permanently_remove ],
+ [ vm_honecker ],
+ [ vm_return ],
+]
+
+CODE[16] = [ // Nomenklatura*
+ [ vm_permanently_remove ],
+ [ vm_nomenklatura ],
+ [ vm_return ],
+]
+
+CODE[17] = [ // Roundtable talks
+ [ vm_roundtable_talks ],
+ [ vm_return ],
+]
+
+CODE[18] = [ // Poszgay Defends the Revolution
+ [ vm_permanently_remove ],
+ [ vm_poszgay ],
+ [ vm_prompt, 'to 4 spaces in Hungary not under Democratic control' ],
+ [ vm_add_limited_infl, 4, 1 ],
+ [ vm_return ],
+]
+
+CODE[19] = [ // Papal vist
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces, 20, 35, 38 ],
+ [ vm_prompt, 'any Catholic Church space' ],
+ [ vm_add_x_infl, 3 ],
+ [ vm_return ],
+]
+
+CODE[20] = [ // Deutsche Marks*
+ [ vm_permanently_remove ],
+ [ vm_deutsche_marks ],
+ [ vm_return ],
+]
+
+CODE[21] = [ // Common European Home
+ [ vm_common_european_home ],
+ [ vm_return ],
+]
+
+CODE[22] = [ // Power Struggle - Poland
+ [ vm_power_struggle ],
+ [ vm_return ],
+]
+
+CODE[23] = [ // Power Struggle - Hungary
+ [ vm_power_struggle ],
+ [ vm_return ],
+]
+
+CODE[24] = [ // St Nicolas Church
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces, 6 ],
+ [ vm_prompt, 'the Lutheran Church' ],
+ [ vm_take_control_prep, 1 ],
+ [ vm_st_nicholas_church ],
+ [ vm_return ],
+]
+
+CODE[25] = [ // Perestroika
+ [ vm_permanently_remove ],
+ [ vm_perestroika ],
+ [ vm_return ],
+]
+
+CODE[26] = [ // Helsinki Final Act*
+ [ vm_permanently_remove ],
+ [ vm_helsinki_final_act ],
+ [ vm_return ],
+]
+
+CODE[27] = [ // Consumerism
+ [ vm_valid_spaces_opponent_socio, 4 ],
+ [ vm_prompt, ' from a Worker space' ],
+ [ vm_remove_opp_infl, 1 ],
+ [ vm_valid_spaces_opponent_socio, 4 ],
+ [ vm_active_country ],
+ [ vm_prompt, ()=>`make a support check in a Worker space in ${country_name(game.vm_active_country)}` ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[28] = [ // Factory Party Cells
+ [ vm_valid_spaces_opponent_socio, 4 ],
+ [ vm_prompt, ' from Worker spaces' ],
+ [ vm_remove_limited_opp_infl, 3, 2 ],
+ [ vm_return ],
+]
+
+CODE[29] = [ // Jan Palach Week*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces, 30 ],
+ [ vm_prompt, 'the Charles University space' ],
+ [ vm_add_x_infl, 6 ],
+ [ vm_return ],
+]
+
+CODE[30] = [ // Tear Gas
+ [ vm_tear_gas ],
+ [ vm_return ],
+]
+
+CODE[31] = [ // Intelligentsia
+ [ vm_valid_spaces, 4, 26, 31, 46, 55, 73 ],
+ [ vm_prompt, 'Intellectual spaces, no more than 2 per space' ],
+ [ vm_add_limited_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[32] = [ // Peasant Parties*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_socio, 3 ],
+ [ vm_prompt, 'Farmer spaces, no more than 2 per space' ],
+ [ vm_add_limited_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[33] = [ // Sajudis*
+ [ vm_permanently_remove ],
+ [ vm_sajudis_check ],
+ [ vm_prompt, 'any Minorities space' ],
+ [ vm_take_control_prep, 1 ],
+ [ vm_sajudis ],
+ [ vm_return ],
+]
+
+CODE[34] = [ // Fidesz*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces, 47 ],
+ [ vm_prompt, 'the Hungary students space' ],
+ [ vm_add_x_infl, 5 ],
+ [ vm_return ],
+]
+
+CODE[35] = [ // Heal our Bleeding Wounds*
+ [ vm_permanently_remove ],
+ [ vm_heal_our_bleeding_wounds ],
+ [ vm_return ],
+]
+
+CODE[36] = [ // Dash for the West*
+ [ vm_permanently_remove ],
+ [ vm_prompt, 'Dash for the West: select any Democratic event with an asterix(*) from the discard pile. Event occurs immediately' ],
+ [ vm_dash_for_the_west ],
+ [ vm_return ],
+]
+
+CODE[37] = [ // Nagy Reburied*
+ [ vm_permanently_remove ],
+ [ vm_nagy_reburied ],
+ [ vm_prompt, 'the Hungary Elite space' ],
+ [ vm_remove_all_infl, 1 ],
+ [ vm_valid_spaces_country, 'Hungary' ],
+ [ vm_prompt, 'Hungary, no more than 2 per space' ],
+ [ vm_add_limited_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[38] = [ // July Concept
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country, 'Bulgaria' ],
+ [ vm_prompt, 'Bulgaria' ],
+ [ vm_add_infl_free, 3 ],
+ [ vm_return ],
+]
+
+CODE[39] = [ // Eco-Glasnost*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces, 66 ],
+ [ vm_prompt, 'Ruse' ],
+ [ vm_add_x_infl, 4 ],
+ [ vm_eco_glasnost ],
+ [ vm_return ],
+]
+
+CODE[40] = [ // Hungarian Democratic Forum
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country, 'Hungary' ],
+ [ vm_prompt, 'Hungary' ],
+ [ vm_add_infl_free, 3 ],
+ [ vm_valid_spaces_country_sc, 'Hungary' ],
+ [ vm_prompt, 'make a Support Check in Hungary' ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[41] = [ // Ceausescu*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!game.the_tyrant_is_gone ],
+ [ vm_valid_spaces_country_opp, 'Romania' ],
+ [ vm_prompt, ' from Romania' ],
+ [ vm_remove_opp_infl, 3 ],
+ [ vm_valid_spaces_country_sc, 'Romania' ],
+ [ vm_prompt, 'make a support check in Romania' ],
+ [ vm_1_support_check ],
+ [ vm_prompt, ' from Bucharesti' ],
+ [ vm_ceausescu ],
+ [ vm_else ],
+ [ vm_tyrant_block ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[42] = [ // Power Struggle - East Germany
+ [ vm_power_struggle ],
+ [ vm_return ],
+]
+
+CODE[43] = [ // Power Struggle - Bulgaria
+ [ vm_power_struggle ],
+ [ vm_return ],
+]
+
+CODE[44] = [ // Inflationary Currency
+ [ vm_permanently_remove ],
+ [ vm_inflationary_currency ],
+ [ vm_valid_spaces_country_opp ],
+ [ vm_prompt, ()=>` from ${country_name(game.vm_active_country)}` ],
+ [ vm_remove_opp_infl, 2 ],
+ [ vm_inflationary_currency_discard ],
+ [ vm_if, ()=>!discarded_card() ],
+ [ vm_valid_spaces_country_sc ],
+ [ vm_prompt, ()=>`make a Support Check in ${country_name(game.vm_active_country)}` ],
+ [ vm_1_support_check ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[45] = [ // Soviet Troop Withdrawals*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_region_opp, 'Eastern Europe' ],
+ [ vm_prompt, ' from Eastern Europe' ],
+ [ vm_remove_limited_opp_infl, 5, 2 ],
+ [ vm_return ],
+]
+
+CODE[46] = [ // Goodbye Lenin!*
+ [ vm_permanently_remove ],
+ [ vm_goodbye_lenin ],
+ [ vm_return ],
+]
+
+CODE[47] = [ // Bulgarian Turks Expelled*
+ [ vm_permanently_remove ],
+ [ vm_bulgarian_turks_expelled ],
+ [ vm_prompt, 'Razgrad' ],
+ [ vm_remove_all_infl, 1 ],
+ [ vm_return ],
+]
+
+CODE[48] = [ // We are the People!*
+ [ vm_permanently_remove ],
+ [ vm_we_are_the_people ],
+ [ vm_return ],
+]
+
+CODE[49] = [ // Foreign Currency Debt Burden*
+ [ vm_permanently_remove ],
+ [ vm_foreign_currency_debt_burden ],
+ [ vm_return ],
+]
+
+CODE[50] = [ // The Sinatra Doctrine*
+ [ vm_permanently_remove ],
+ [ vm_the_sinatra_doctrine ],
+ [ vm_return ],
+]
+
+CODE[51] = [ // 40th Anniversary Celebration*
+ [ vm_permanently_remove ],
+ [ vm_40th_anniversary_celebration ],
+ [ vm_valid_spaces_country, 'East_Germany' ],
+ [ vm_prompt, 'East Germany' ],
+ [ vm_add_infl_free ],
+ [ vm_40th_anniversary_celebration_vp ],
+ [ vm_return ],
+]
+
+CODE[52] = [ // Normalisation
+ [ vm_permanently_remove ],
+ [ vm_normalisation ],
+ [ vm_prompt, 'the Czechoslovakia Elite and Bureaucrat Spaces' ],
+ [ vm_remove_all_infl, 2 ],
+ [ vm_return ],
+]
+
+CODE[53] = [ // Li Peng*
+ [ vm_permanently_remove ],
+ [ vm_li_peng ],
+ [ vm_return ],
+]
+
+CODE[54] = [ // The Crowd Turns Against Ceausescu*
+ [ vm_the_crowd_turns_against_ceausescu ],
+ [ vm_return ],
+]
+
+CODE[55] = [ // Power Struggle - Czechoslovakia
+ [ vm_power_struggle ],
+ [ vm_return ],
+]
+
+CODE[56] = [ // Foreign Television
+ [ vm_permanently_remove ],
+ [ vm_foreign_television ],
+ [ vm_remove_limited_opp_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[57] = [ // Central Committee Reshuffle*
+ [ vm_permanently_remove ],
+ [ vm_central_committee_reshuffle ],
+ [ vm_prompt, ()=>`${country_name(game.vm_active_country)}` ],
+ [ vm_add_infl_free, 3 ],
+ [ vm_return ],
+]
+
+CODE[58] = [ // Austria-Hungary Border Reopened*
+ [ vm_austria_hungary_border_reopened ],
+ [ vm_return ],
+]
+
+CODE[59] = [ // GrenzTruppen*
+ [ vm_grenztruppen ],
+ [ vm_return ],
+]
+
+CODE[60] = [ // Toxic Waste*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_socio, 4 ],
+ [ vm_prompt, 'any Worker space(s)' ],
+ [ vm_add_infl_free, 3 ],
+ [ vm_return ],
+]
+
+CODE[61] = [ // The Monday Demonstrations*
+ [ vm_permanently_remove ],
+ [ vm_the_monday_demonstrations ],
+ [ vm_prompt, 'the Lutheran Church Space and Leipzig' ],
+ [ vm_take_control_prep, 2 ],
+ [ vm_valid_spaces_country_sc, 'East_Germany' ],
+ [ vm_prompt, 'make 5 Support Checks in East Germany' ],
+ [ vm_support_check, 5 ],
+ [ vm_return ],
+]
+
+CODE[62] = [ // Yakovlev Counsels Gorbachev*
+ [ vm_yakovlev_counsels_gorbachev ],
+ [ vm_return ],
+]
+
+CODE[63] = [ // Genscher*
+ [ vm_genscher ],
+ [ vm_return ],
+]
+
+CODE[64] = [ // Legacy of 1968*
+ [ vm_permanently_remove ],
+ [ vm_legacy_of_1968 ],
+ [ vm_prompt, 'all spaces in Czechoslovakia not controlled by the Communist Player' ],
+ [ vm_add_limited_infl, 11, 1 ],
+ [ vm_return ],
+]
+
+CODE[65] = [ // Presidential Visit*
+ [ vm_permanently_remove ],
+ [ vm_presidential_visit ],
+ [ vm_return ],
+]
+
+CODE[66] = [ // New Forum
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country, 'East_Germany' ],
+ [ vm_prompt, '3 spaces in East Germany' ],
+ [ vm_add_limited_infl, 3, 1 ],
+ [ vm_return ],
+]
+
+CODE[67] = [ // Reformer Rehabilitated*
+ [ vm_prompt, 'Reformer Rehabilitated: chose any non-scoring card in the discard pile. Event takes place immediately' ],
+ [ vm_reformer_rehabilitated ],
+ [ vm_return ],
+]
+
+CODE[68] = [ // Klaus and Komarek*
+ [ vm_permanently_remove ],
+ [ vm_klaus_and_komarek ],
+ [ vm_prompt, 'Prague' ],
+ [ vm_remove_x_opp_infl, 2 ],
+ [ vm_valid_spaces, 29 ],
+ [ vm_add_x_infl, 2 ],
+ [ vm_return ],
+]
+
+CODE[69] = [ // Systematization*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country, 'Romania' ],
+ [ vm_systematization ],
+ [ 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_permanently_remove ],
+ [ vm_valid_spaces, 50, 56 ],
+ [ vm_prompt, 'in Timisoara and Harghita/Covasna' ],
+ [ vm_add_limited_infl, 2, 1 ],
+ [ vm_laszlo_tokes ],
+ [ vm_if, ()=>game.phase === 3 ],
+ [ vm_prompt, ' in Romania' ],
+ [ vm_add_infl ],
+ [ vm_else ],
+ [ vm_prompt, 'make 2 Support Checks in Romania' ],
+ [ vm_support_check, 2 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[74] = [ // FRG Embassies
+ [ vm_frg_embassies ],
+ [ vm_return ],
+]
+
+CODE[75] = [ // Exit Visas*
+ [ vm_permanently_remove ],
+ [ vm_exit_visas ],
+ [ vm_return ],
+]
+
+CODE[76] = [ // Warsaw Pact Summit
+ [ vm_permanently_remove ],
+ [ vm_warsaw_pact_summit ],
+ [ vm_if, ()=>game.phase === 3 ],
+ [ vm_prompt, ' spaces with no Democratic SPs' ],
+ [ vm_add_infl_free, 4 ],
+ [ vm_else ],
+ [ vm_prompt, 'Select a Student or Intellectual space' ],
+ [ vm_valid_spaces_country_socio_2, 3,, 4 ],
+ [ vm_support_check_modified, 2, 2 ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[77] = [ // Samizdat
+ [ vm_permanently_remove ],
+ [ vm_samizdat ],
+ [ vm_return ],
+]
+
+CODE[78] = [ // Workers Revolt
+ [ vm_workers_revolt ],
+ [ vm_return ],
+]
+
+CODE[79] = [ // The Third Way*
+ [ vm_permanently_remove ],
+ [ vm_the_third_way ],
+ [ vm_valid_spaces, 4 ],
+ [ vm_prompt, 'the East German Writers space' ],
+ [ vm_add_x_infl, 3 ],
+ [ vm_return ],
+]
+
+CODE[80] = [ // Nepotism*
+ [ vm_permanently_remove ],
+ [ vm_nepotism ],
+ [ vm_valid_spaces_region_socio, 'Balkans', 4 ],
+ [ vm_prompt, 'Worker spaces in the Balkans' ],
+ [ vm_add_infl_free ],
+ [ vm_return ],
+]
+
+CODE[81] = [ // The Baltic Way*
+ [ vm_permanently_remove ],
+ [ vm_the_baltic_way ],
+ [ vm_prompt, 'any Minorities space' ],
+ [ vm_take_control_prep, 1 ],
+ [ vm_return ],
+]
+
+CODE[82] = [ // Spitzel*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country_opp, 'East_Germany' ],
+ [ vm_prompt, ' from East Germany' ],
+ [ vm_remove_opp_infl, 2 ],
+ [ vm_return ],
+]
+
+CODE[83] = [ // Modrow*
+ [ vm_permanently_remove ],
+ [ vm_modrow ],
+ [ vm_valid_spaces_country, 'East_Germany' ],
+ [ vm_prompt, 'East Germany, no more than 2 per space' ],
+ [ vm_add_limited_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[84] = [ // Breakaway Baltic Republics*
+ [ vm_permanently_remove ],
+ [ vm_breakaway_baltic_republics ],
+ [ vm_prompt, 'any Minorities space' ],
+ [ vm_take_control_prep, 1 ],
+ [ vm_valid_spaces_sc ],
+ [ vm_prompt, 'select a space for the support check' ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[85] = [ // Tank Column/Tank Man*
+ [ vm_permanently_remove ],
+ [ vm_tank_column ],
+ [ vm_return ],
+]
+
+CODE[86] = [ // The Wall Must Go!*
+ [ vm_permanently_remove ],
+ [ vm_the_wall_must_go ],
+ [ vm_remove_infl, 3 ],
+ [ vm_return ],
+]
+
+CODE[87] = [ // Kohl Proposes Reunification*
+ [ vm_permanently_remove ],
+ [ vm_kohl_proposes_reunification ],
+ [ vm_return ],
+]
+
+CODE[88] = [ // Adamec*
+ [ vm_permanently_remove ],
+ [ vm_adamec ],
+ [ vm_valid_spaces_country, 'Czechoslovakia' ],
+ [ vm_prompt, 'Czechoslovakia' ],
+ [ vm_add_limited_infl, 4, 2 ],
+ [ vm_return ],
+]
+
+CODE[89] = [ // Domino Theory*
+ [ vm_prompt, 'Domino Theory: choose a Power Struggle card to play from the discard pile' ],
+ [ vm_permanently_remove ],
+ [ vm_domino_theory ],
+ [ vm_return ],
+]
+
+CODE[90] = [ // Civic Forum*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country, 'Czechoslovakia' ],
+ [ vm_prompt, 'Czechoslovakia' ],
+ [ vm_add_infl_free, 4 ],
+ [ vm_civic_forum ],
+ [ vm_valid_spaces_country_sc, 'Czechoslovakia' ],
+ [ vm_prompt, 'Select a space in Czechoslovakia' ],
+ [ vm_support_check, 2 ],
+ [ vm_return ],
+]
+
+CODE[91] = [ // My First Banana*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country_opp, 'East_Germany' ],
+ [ vm_prompt, ' from East Germany' ],
+ [ vm_remove_opp_infl, 2 ],
+ [ vm_valid_spaces_country_sc, 'East_Germany' ],
+ [ vm_prompt, 'select a space in East Germany' ],
+ [ vm_support_check, 2 ],
+ [ vm_return ],
+]
+
+CODE[92] = [ // Betrayal
+ [ vm_permanently_remove ],
+ [ vm_prompt, 'choose any Orthodox Church space. Replace all Democratic SPs with Communist SPs' ],
+ [ vm_betrayal ],
+ [ vm_return ],
+]
+
+CODE[93] = [ // Shock Therapy*
+ [ vm_permanently_remove ],
+ [ vm_shock_therapy ],
+ [ vm_valid_spaces_country ],
+ [ vm_prompt, ()=>` ${country_name(game.vm_active_country)}` ],
+ [ vm_add_infl_free, 3 ],
+ [ vm_return ],
+]
+
+CODE[94] = [ // Union of Democratic Forces*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country_opp, 'Bulgaria' ],
+ [ vm_prompt, ' from Bulgaria' ],
+ [ vm_remove_opp_infl, 4 ],
+ [ vm_valid_spaces_country_sc, 'Bulgaria' ],
+ [ vm_prompt, 'Make 2 Support Checks in Bulgaria' ],
+ [ vm_support_check, 2 ],
+ [ vm_return ],
+]
+
+CODE[95] = [ // Power Struggle - Romania
+ [ vm_power_struggle ],
+ [ vm_return ],
+]
+
+CODE[96] = [ // The Chinese Solution*
+ [ vm_permanently_remove ],
+ [ vm_the_chinese_solution ],
+ [ vm_valid_spaces_country_sc ],
+ [ vm_prompt, ()=>`make 5 Support Checks in ${country_name(game.vm_active_country)}` ],
+ [ vm_support_check_modified, 5, 3 ],
+ [ vm_return ],
+]
+
+CODE[97] = [ // The Tyrant is Gone*
+ [ vm_if, ()=>game.persistent_events.includes(54) ],
+ [ vm_valid_spaces, 51 ],
+ [ vm_prompt, 'the Romanian Elite Space' ],
+ [ vm_remove_x_opp_infl, 4 ],
+ [ vm_the_tyrant_is_gone ],
+ [ vm_permanently_remove ],
+ [ vm_else ],
+ [ vm_the_tyrant_is_gone_prep ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[98] = [ // Politburo Intrigue*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces_country_opp, 'Bulgaria' ],
+ [ vm_prompt, ' from Bulgaria' ],
+ [ vm_remove_limited_opp_infl, 3, 2 ],
+ [ vm_valid_spaces_country_sc, 'Bulgaria' ],
+ [ vm_prompt, 'make a support check in Bulgaria' ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[99] = [ // Ligachev*
+ [ vm_permanently_remove ],
+ [ vm_ligachev ],
+ [ vm_return ],
+]
+
+CODE[100] = [ // Stand Fast*
+ [ vm_permanently_remove ],
+ [ vm_stand_fast ],
+ [ vm_return ],
+]
+
+CODE[101] = [ // Elena*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!game.the_tyrant_is_gone ],
+ [ vm_valid_spaces, 51 ],
+ [ vm_prompt, 'the Romania Elite Space' ],
+ [ vm_add_x_infl, 2 ],
+ [ vm_elena ],
+ [ vm_else ],
+ [ vm_tyrant_block ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[102] = [ // National Salvation Front*
+ [ vm_national_salvation_front ],
+ [ vm_return ],
+]
+
+CODE[103] = [ // Government Resigns*
+ [ vm_government_resigns ],
+ [ vm_prompt, 'any uncontrolled Elite space' ],
+ [ vm_remove_all_infl, 1 ],
+ [ vm_permanently_remove ],
+ [ vm_return ],
+]
+
+CODE[104] = [ // New Year's Eve Party*
+ [ vm_new_years_eve_party ],
+ [ vm_return ],
+]
+
+CODE[105] = [ // Public Against Violence*
+ [ vm_permanently_remove ],
+ [ vm_valid_spaces, 36 ],
+ [ vm_prompt, 'Kosice' ],
+ [ vm_add_x_infl, 2 ],
+ [ vm_valid_spaces, 37 ],
+ [ vm_prompt, 'Presov' ],
+ [ vm_add_x_infl, 2 ],
+ [ vm_public_against_violence ],
+ [ vm_prompt, 'Make a Support Check in Bratislava' ],
+ [ vm_support_check_modified, 1, 2 ],
+ [ vm_return ],
+]
+
+CODE[106] = [ // Social Democratic Platform Adopted*
+ [ vm_permanently_remove ],
+ [ vm_social_democratic_platform_adopted ],
+ [ vm_valid_spaces_country ],
+ [ vm_prompt, ()=>`${country_name(game.vm_active_country)}` ],
+ [ vm_add_infl_free, 2 ],
+ [ vm_valid_spaces_country_sc ],
+ [ vm_prompt, ()=>`make a Support Check in ${country_name(game.vm_active_country)}` ],
+ [ vm_1_support_check ],
+ [ vm_return ],
+]
+
+CODE[107] = [ // Massacre in Timisoara*
+ [ vm_permanently_remove ],
+ [ vm_if, ()=>!game.the_tyrant_is_gone ],
+ [ vm_massacre_in_timisoara ],
+ [ vm_valid_spaces_country_sc, 'Romania' ],
+ [ vm_prompt, 'Make Support Checks in Romania' ],
+ [ vm_support_check_modified, 2, 2 ],
+ [ vm_else ],
+ [ vm_tyrant_block ],
+ [ vm_endif ],
+ [ vm_return ],
+]
+
+CODE[108] = [ // Army Backs Revolution*
+ [ vm_permanently_remove ],
+ [ vm_army_backs_revolution ],
+ [ vm_return ],
+]
+
+CODE[109] = [ // Kremlin Coup*
+ [ vm_permanently_remove ],
+ [ vm_kremlin_coup ],
+ [ vm_return ],
+]
+
+CODE[110] = [ // Malta Summit*
+ [ vm_permanently_remove ],
+ [ vm_malta_summit ],
+ [ vm_prompt, ' from Elite spaces' ],
+ [ vm_remove_opp_infl, 5 ],
+ [ vm_return ],
+]
+// #endregion
+
+
+// ============= TIANANMEN SQUARE TRACK AWARDS ====================
+CODE[203] = [//Tiananmen Square space 3 award
+ [vm_tst_3],
+ [vm_return]
+]
+CODE[204] = [//Tiananmen Square space 4 award
+ [vm_valid_spaces_opponent],
+ [vm_tst_4],
+ [vm_return]
+]
+CODE[206] = [//Tiananmen Square space 6
+ [vm_valid_spaces_sc],
+ [vm_tst_6],
+ [vm_return]
+]
+CODE[208] = [//Tiananmen Square space 8 event
+ [vm_tst_8],
+ [vm_return]
+]
+
+// ============= POWER STRUGGLE WILDCARDS =========================
+
+CODE[349] = [//Scare Tactics
+ [vm_scare_tactics],
+ [vm_valid_spaces_country_opp],
+ [vm_prompt, ()=>` from ${country_name(game.vm_active_country)}`],
+ [vm_remove_opp_infl, 1],
+ [vm_return]
+]
+CODE[350] = [//Support Surges
+ [vm_support_surges],
+ [vm_return]
+]
+CODE[351] = [//Support Falters
+ [vm_support_falters],
+ [vm_return]
+]