diff options
-rw-r--r-- | .gitattributes | 3 | ||||
-rw-r--r-- | data.js | 506 | ||||
-rw-r--r-- | play.css | 1482 | ||||
-rw-r--r-- | play.html | 420 | ||||
-rw-r--r-- | play.js | 1628 | ||||
-rw-r--r-- | rules.js | 19784 |
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 @@ -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 } @@ -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)} @@ -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> @@ -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() @@ -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] +] |