diff options
-rw-r--r-- | data.js | 584 | ||||
-rw-r--r-- | data.ts | 663 | ||||
-rw-r--r-- | play.ts | 6 | ||||
-rw-r--r-- | rules.js | 163 | ||||
-rw-r--r-- | rules.ts | 223 | ||||
-rw-r--r-- | types.d.ts | 46 |
6 files changed, 1002 insertions, 683 deletions
@@ -30,329 +30,601 @@ const CLOSEST_TO_VICTORY = 'v'; const TOWARDS_CENTER = 10; const AWAY_FROM_CENTER = 11; const ANY = 'any'; +const SELF = 'self'; +const OTHER_PLAYERS = 'other'; +const TRASH = 'trash'; +function create_effect(type, target, value) { + return { + type, + target, + value, + }; +} const data = { cards: [ {}, { id: 1, + effects: [ + create_effect('track', FOREIGN_AID, 2), + create_effect('track', SOVIET_SUPPORT, -1), + ], strength: 1, title: 'CLANDESTINE FRENCH ARMS', type: 'pc', }, { id: 2, + effects: [ + create_effect('track', FOREIGN_AID, 1), + create_effect('front', ANY, 3), + create_effect('track', LIBERTY, -2), + ], strength: 2, title: 'POPULAR ARMY OF THE REPUBLIC', type: 'pc', }, { id: 3, + effects: [ + create_effect('front', CLOSEST_TO_DEFEAT, 3), + create_effect('draw_card', SELF, 1), + ], strength: 2, title: 'MEXICAN GUNS', type: 'pc', }, { id: 4, + effects: [ + create_effect('front', MADRID, 3), + create_effect('track', FOREIGN_AID, 1), + create_effect('swap_card_tableau_hand', ANY, 1), + ], strength: 1, title: 'BATTLE OF GUADALAJARA', type: 'pc', }, { id: 5, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('front', CLOSEST_TO_DEFEAT, 2), + create_effect('draw_card', SELF, 3), + create_effect('draw_card', OTHER_PLAYERS, 1), + ], strength: 1, title: '"SI ME OUIERES ESCRIBIR"', type: 'pc', }, { id: 6, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('track', GOVERNMENT, 1), + create_effect('draw_card', SELF, 1), + ], strength: 2, title: 'XYZ LINE', type: 'pc', }, { id: 7, + effects: [ + create_effect('front', ANY, 1), + create_effect('track', FOREIGN_AID, 2), + create_effect('track', COLLECTIVIZATION, -1), + create_effect('track', GOVERNMENT, 2), + create_effect('hero_points', SELF, 1), + ], strength: 3, title: 'INDALECIO PRIETO', type: 'pc', }, { id: 8, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('front', ANY, 3), + ], strength: 1, title: "PEOPLE'S OLYMPIAD", type: 'pc', }, { id: 9, + effects: [ + create_effect('track', LIBERTY, -2), + create_effect('track', COLLECTIVIZATION, -2), + create_effect('track', SOVIET_SUPPORT, -2), + create_effect('draw_card', SELF, 3), + ], strength: 1, title: 'FOUR ANARCHIST MINISTERS', type: 'pc', }, { id: 10, + effects: [ + create_effect('track', FOREIGN_AID, 4), + create_effect('add_to_tableau', SELF, 1), + ], strength: 1, title: 'GUERNICA', type: 'pc', }, { id: 11, + effects: [ + create_effect('front', CLOSEST_TO_DEFEAT, 1), + create_effect('remove_blank_marker', ANY, 1), + create_effect('track', FOREIGN_AID, 2), + ], strength: 1, title: 'ERNEST HEMINGWAY', type: 'pc', }, { id: 12, + effects: [ + create_effect('track', SOVIET_SUPPORT, -3), + create_effect('track', COLLECTIVIZATION, -3), + ], strength: 1, title: 'HUESCA OFFENSIVE', type: 'pc', }, { id: 13, + effects: [ + create_effect('track', FOREIGN_AID, 1), + create_effect('track', SOVIET_SUPPORT, -1), + create_effect('track', GOVERNMENT, 2), + create_effect('hero_points', SELF, 1), + ], strength: 1, title: 'PABLO NERUDA', type: 'pc', }, { id: 14, + effects: [ + create_effect('front', NORTHERN, 2), + create_effect('track', COLLECTIVIZATION, -1), + create_effect('track', GOVERNMENT, 1), + ], strength: 1, title: 'EUSKO GUDAROSTEA', type: 'pc', }, { id: 15, + effects: [ + create_effect('track', FOREIGN_AID, 2), + create_effect('return_card', TRASH, 1), + ], strength: 2, title: 'JUAN NEGRÍN', type: 'pc', }, { id: 16, + effects: [], strength: 1, title: 'PUBLICIZE FASCIST WAR CRIMES', type: 'pc', }, { id: 17, + effects: [ + create_effect('track', FOREIGN_AID, 1), + create_effect('track', GOVERNMENT, 1), + ], strength: 1, title: 'AGRARIAN REFORM', type: 'pc', }, { id: 18, + effects: [ + create_effect('track', COLLECTIVIZATION, -3), + create_effect('track', GOVERNMENT, 2), + create_effect('draw_card', SELF, 2), + ], strength: 1, title: 'IMPOSE FACTORY MANAGERS', type: 'pc', }, { id: 19, + effects: [ + create_effect('front', CLOSEST_TO_DEFEAT, 2), + create_effect('track', GOVERNMENT, -1), + create_effect('return_card', TRASH, 1), + ], strength: 2, title: '¡NO PASARÁN!', type: 'pc', }, { id: 20, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('track', SOVIET_SUPPORT, 2), + ], strength: 2, title: 'RUSSIAN FIGHTERS', type: 'pc', }, { id: 21, + effects: [ + create_effect('front', ANY, 1), + create_effect('track', LIBERTY, -2), + create_effect('track', COLLECTIVIZATION, -2), + create_effect('hero_points', SELF, 1), + ], strength: 1, title: 'ENRIQUE LÍSTER', type: 'pc', }, { id: 22, + effects: [ + create_effect('track', LIBERTY, -2), + create_effect('track', SOVIET_SUPPORT, 1), + ], strength: 2, title: 'LARGO CABALLERO', type: 'pc', }, { id: 23, + effects: [ + create_effect('track', FOREIGN_AID, -2), + create_effect('draw_card', SELF, 2), + ], strength: 2, title: 'SOVIET TANKS', type: 'pc', }, { id: 24, + effects: [ + create_effect('front', ANY, 1), + create_effect('track', SOVIET_SUPPORT, 2), + create_effect('track', LIBERTY, -1), + create_effect('track', GOVERNMENT, -2), + create_effect('hero_points', SELF, 1), + ], strength: 3, title: 'DOLORES IBÁRRURI', type: 'pc', }, { id: 25, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('front', CLOSEST_TO_DEFEAT, 2), + create_effect('draw_card', SELF, 3), + create_effect('draw_card', OTHER_PLAYERS, 1), + ], strength: 1, title: 'PAUL ROBESON', type: 'pc', }, { id: 26, + effects: [ + create_effect('track', LIBERTY, -2), + create_effect('track', GOVERNMENT, -1), + ], strength: 1, title: 'MADRID DEFENSE COUNCIL', type: 'pc', }, { id: 27, + effects: [ + create_effect('remove_blank_marker', ANY, 1), + create_effect('track', SOVIET_SUPPORT, 3), + create_effect('track', FOREIGN_AID, -1), + create_effect('draw_card', SELF, 1), + ], strength: 1, title: "STALIN GETS THE REPUBLIC'S GOLD", type: 'pc', }, { id: 28, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('front', SOUTHERN, 3), + create_effect('track', FOREIGN_AID, -1), + create_effect('draw_card', SELF, 1), + ], strength: 1, title: 'INTERNATIONAL BRIGADES', type: 'pc', }, { id: 29, + effects: [ + create_effect('track', GOVERNMENT, -2), + ], strength: 1, title: 'BAN WOMEN FROM THE FRONT', type: 'pc', }, { id: 30, + effects: [ + create_effect('front', ANY, 1), + create_effect('track', SOVIET_SUPPORT, 2), + create_effect('track', FOREIGN_AID, -3), + ], strength: 1, title: 'ABRAHAM LINCOLN BRIGADE', type: 'pc', }, { id: 31, + effects: [ + create_effect('attack', ANY, -2), + create_effect('track', SOVIET_SUPPORT, 3), + create_effect('track', GOVERNMENT, -2), + ], strength: 2, title: 'OUTLAW THE POUM', type: 'pc', }, { id: 32, + effects: [ + create_effect('front', ANY, 1), + create_effect('track', SOVIET_SUPPORT, 1), + ], strength: 1, title: 'DISBAND THE CONTROL PATROLS', type: 'pc', }, { id: 33, + effects: [ + create_effect('attack', ARAGON, -1), + create_effect('track', SOVIET_SUPPORT, 1), + create_effect('track', LIBERTY, -4), + create_effect('swap_card_tableau_hand', ANY, 1), + ], strength: 1, title: 'MAY DAYS', type: 'pc', }, { id: 34, + effects: [ + create_effect('front', SOUTHERN, 2), + create_effect('track', GOVERNMENT, -1), + create_effect('draw_card', SELF, 1), + ], strength: 1, title: 'FIFTH REGIMENT', type: 'pc', }, { id: 35, + effects: [ + create_effect('front', ANY, 2), + create_effect('draw_card', SELF, 2), + ], strength: 1, title: 'THÄLMANN BATTALION', type: 'pc', }, { id: 36, + effects: [ + create_effect('track', SOVIET_SUPPORT, 2), + create_effect('track', COLLECTIVIZATION, -3), + create_effect('draw_card', SELF, 2), + create_effect('add_to_tableau', ANY, 1), + ], strength: 1, title: 'DE-COLLECTIVIZE AGRICULTURE', type: 'pc', }, { id: 37, + effects: [ + create_effect('front', ANY, 1), + create_effect('track', COLLECTIVIZATION, 2), + create_effect('track', LIBERTY, 2), + create_effect('track', GOVERNMENT, TOWARDS_CENTER), + create_effect('hero_points', SELF, 1), + ], strength: 3, title: 'BUENAVENTURA DURRUTI', type: 'pc', }, { id: 38, + effects: [ + create_effect('track', LIBERTY, 3), + create_effect('track', SOVIET_SUPPORT, -2), + create_effect('draw_card', SELF, 1), + create_effect('swap_card_tableau_hand', ANY, 1), + ], strength: 2, title: 'MUJERES LIBRES', type: 'pc', }, { id: 39, + effects: [ + create_effect('track', COLLECTIVIZATION, 1), + create_effect('draw_card', SELF, 2), + ], strength: 1, title: 'IRON COLUMN', type: 'pc', }, { id: 40, + effects: [ + create_effect('front', CLOSEST_TO_DEFEAT, 3), + create_effect('track', COLLECTIVIZATION, 2), + create_effect('draw_card', SELF, 1), + ], strength: 2, title: 'ASTURIAN MINERS', type: 'pc', }, { id: 41, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('track', COLLECTIVIZATION, 3), + create_effect('return_card', TRASH, 1), + ], strength: 2, title: 'CNT-FAI', type: 'pc', }, { id: 42, + effects: [ + create_effect('track', LIBERTY, 2), + create_effect('front', ARAGON, 2), + create_effect('front', MADRID, 1), + ], strength: 2, title: 'DURRUTI COLUMN', type: 'pc', }, { id: 43, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('front', ARAGON, 1), + create_effect('track', SOVIET_SUPPORT, -2), + create_effect('draw_card', SELF, 3), + create_effect('draw_card', OTHER_PLAYERS, 1), + ], strength: 1, title: 'GEORGE ORWELL', type: 'pc', }, { id: 44, + effects: [ + create_effect('front', MADRID, 2), + create_effect('track', LIBERTY, 1), + create_effect('track', FOREIGN_AID, -1), + ], strength: 1, title: 'F.I.J.L.', type: 'pc', }, { id: 45, + effects: [ + create_effect('front', ANY, 2), + create_effect('track', FOREIGN_AID, -3) + ], strength: 1, title: 'ARM THE UNIONS', type: 'pc', }, { id: 46, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('track', LIBERTY, 2), + ], strength: 1, title: 'GUERRILLAS', type: 'pc', }, { id: 47, + effects: [ + create_effect('remove_blank_marker', ANY, 1), + create_effect('track', LIBERTY, 2), + create_effect('track', GOVERNMENT, TOWARDS_CENTER), + create_effect('draw_card', SELF, 1), + ], strength: 1, title: 'RADICAL EDUCATION', type: 'pc', }, { id: 48, + effects: [ + create_effect('front', CLOSEST_TO_DEFEAT, 2), + create_effect('track', SOVIET_SUPPORT, -2), + create_effect('draw_card', SELF, 3), + ], strength: 1, title: 'MATTEOTTI BATTALION', type: 'pc', }, { id: 49, + effects: [ + create_effect('track', COLLECTIVIZATION, 4), + create_effect('draw_card', SELF, 1), + ], strength: 1, title: 'COLLECTIVIZE AGRICULTURE', type: 'pc', }, { id: 50, + effects: [ + create_effect('track', COLLECTIVIZATION, 1), + create_effect('track', FOREIGN_AID, -1), + ], strength: 1, title: 'ARMORED VEHICLES', type: 'pc', }, { id: 51, + effects: [ + create_effect('track', COLLECTIVIZATION, 3), + create_effect('track', FOREIGN_AID, -2), + create_effect('track', GOVERNMENT, TOWARDS_CENTER), + ], strength: 1, title: 'INDUSTRIAL DEMOCRACY', type: 'pc', }, { id: 52, + effects: [ + create_effect('front', ANY, 1), + create_effect('track', GOVERNMENT, TOWARDS_CENTER), + ], strength: 2, title: 'AFFINITY GROUPS', type: 'pc', }, { id: 53, + effects: [ + create_effect('track', LIBERTY, 1), + create_effect('hero_points', SELF, 1), + ], strength: 1, title: 'GENDER-INCLUSIVE MILITIA', type: 'pc', }, { id: 54, + effects: [ + create_effect('track', SOVIET_SUPPORT, -1), + create_effect('add_to_tableau', ANY, 1), + ], strength: 1, title: 'FEDERICA MONTSENY', type: 'pc', @@ -360,21 +632,9 @@ const data = { { id: 55, effects: [ - { - target: SOUTHERN, - type: 'attack', - value: 4, - }, - { - target: ARAGON, - type: 'attack', - value: 1, - }, - { - target: SOVIET_SUPPORT, - type: 'track', - value: -2, - }, + create_effect('attack', SOUTHERN, -4), + create_effect('attack', ARAGON, -1), + create_effect('track', SOVIET_SUPPORT, -2), ], title: 'SPANISH LEGION', type: 'ec', @@ -383,21 +643,9 @@ const data = { { id: 56, effects: [ - { - target: SOUTHERN, - type: 'attack', - value: 3, - }, - { - target: CLOSEST_TO_VICTORY, - type: 'attack', - value: 2, - }, - { - target: MORALE_BONUS, - type: 'bonus', - value: OFF, - }, + create_effect('attack', SOUTHERN, -3), + create_effect('attack', CLOSEST_TO_VICTORY, -2), + create_effect('bonus', MORALE_BONUS, OFF), ], title: 'BRITISH TREACHERY AT GIBRALTAR', type: 'ec', @@ -406,21 +654,9 @@ const data = { { id: 57, effects: [ - { - target: MADRID, - type: 'attack', - value: -5, - }, - { - target: FOREIGN_AID, - type: 'track', - value: -2, - }, - { - target: PLAYER_WITH_MOST_HERO_POINTS, - type: 'hero_points', - value: -1, - }, + create_effect('attack', MADRID, -5), + create_effect('track', FOREIGN_AID, -2), + create_effect('hero_points', PLAYER_WITH_MOST_HERO_POINTS, -1), ], title: 'PARACUELLOS MASSACRES', type: 'ec', @@ -429,21 +665,9 @@ const data = { { id: 58, effects: [ - { - target: 'n', - type: 'attack', - value: -5, - }, - { - target: 'v', - type: 'attack', - value: -1, - }, - { - target: COLLECTIVIZATION, - type: 'track', - value: -1, - }, + create_effect('attack', NORTHERN, -5), + create_effect('attack', CLOSEST_TO_VICTORY, -1), + create_effect('track', COLLECTIVIZATION, -1), ], title: 'CARLISTS', type: 'ec', @@ -452,21 +676,9 @@ const data = { { id: 59, effects: [ - { - target: MADRID, - type: 'attack', - value: -4, - }, - { - target: CLOSEST_TO_VICTORY, - type: 'attack', - value: -2, - }, - { - target: LIBERTY, - type: 'track', - value: -1, - }, + create_effect('attack', MADRID, -4), + create_effect('attack', CLOSEST_TO_VICTORY, -2), + create_effect('track', LIBERTY, -1), ], title: 'ASSASSINATION OF GARCIA LORCA', type: 'ec', @@ -475,21 +687,9 @@ const data = { { id: 60, effects: [ - { - target: NORTHERN, - type: 'attack', - value: -3, - }, - { - target: CLOSEST_TO_VICTORY, - type: 'attack', - value: -3, - }, - { - target: LIBERTY, - type: 'track', - value: -1, - }, + create_effect('attack', NORTHERN, -3), + create_effect('attack', CLOSEST_TO_VICTORY, -3), + create_effect('track', LIBERTY, -1), ], title: 'GENERAL SANJURIO', type: 'ec', @@ -498,21 +698,9 @@ const data = { { id: 61, effects: [ - { - target: ARAGON, - type: 'attack', - value: -4, - }, - { - target: CLOSEST_TO_VICTORY, - type: 'attack', - value: -2, - }, - { - target: PLAYER_WITH_MOST_HERO_POINTS, - type: 'hero_points', - value: -1, - }, + create_effect('attack', ARAGON, -2), + create_effect('attack', CLOSEST_TO_VICTORY, -2), + create_effect('hero_points', PLAYER_WITH_MOST_HERO_POINTS, -1), ], title: 'FAILED INVASION OF MALLORCA', type: 'ec', @@ -521,21 +709,9 @@ const data = { { id: 62, effects: [ - { - target: SOUTHERN, - type: 'attack', - value: -5, - }, - { - target: MORALE_BONUS, - type: 'bonus', - value: OFF, - }, - { - target: PLAYER_WITH_MOST_HERO_POINTS, - type: 'hero_points', - value: -1, - }, + create_effect('attack', SOUTHERN, -5), + create_effect('bonus', MORALE_BONUS, OFF), + create_effect('hero_points', PLAYER_WITH_MOST_HERO_POINTS, -1), ], title: 'AIRLIFT OF THE ARMY OF AFRICA', type: 'ec', @@ -611,82 +787,34 @@ const data = { id: LIBERTY, name: 'Liberty', triggers: [ - { - type: 'bonus', - target: MORALE_BONUS, - value: OFF, - }, - { - type: 'attack', - target: MADRID, - value: -1, - }, + create_effect('bonus', MORALE_BONUS, OFF), + create_effect('attack', MADRID, -1), null, - { - type: 'track', - target: SOVIET_SUPPORT, - value: 1, - }, + create_effect('track', SOVIET_SUPPORT, 1), null, null, null, - { - type: 'track', - target: GOVERNMENT, - value: TOWARDS_CENTER, - }, - { - type: 'front', - target: ANY, - value: 1, - }, + create_effect('track', GOVERNMENT, TOWARDS_CENTER), + create_effect('front', ANY, 1), null, - { - type: 'medaillon', - target: ANY, - value: 1, - }, + create_effect('medaillon', ANY, 1), ], }, { id: COLLECTIVIZATION, name: 'Collectivization', triggers: [ - { - type: 'bonus', - target: MORALE_BONUS, - value: OFF, - }, - { - type: 'attack', - target: ARAGON, - value: -1, - }, + create_effect('bonus', MORALE_BONUS, OFF), + create_effect('attack', ARAGON, -1), null, - { - type: 'track', - target: FOREIGN_AID, - value: 1, - }, + create_effect('track', FOREIGN_AID, 1), null, null, null, - { - type: 'front', - target: ANY, - value: 1, - }, - { - type: 'track', - target: LIBERTY, - value: 1, - }, + create_effect('front', ANY, 1), + create_effect('track', LIBERTY, 1), null, - { - type: 'medaillon', - target: ANY, - value: 1, - }, + create_effect('medaillon', ANY, 1), ], }, { @@ -694,114 +822,50 @@ const data = { name: 'Government', triggers: [ null, - { - type: 'medaillon', - target: ANY, - value: 1, - }, + create_effect('medaillon', ANY, 1), null, null, - { - type: 'track', - target: SOVIET_SUPPORT, - value: 1, - }, + create_effect('track', SOVIET_SUPPORT, 1), null, null, - { - type: 'track', - target: FOREIGN_AID, - value: 1, - }, + create_effect('track', FOREIGN_AID, 1), null, null, - { - type: 'medaillon', - target: ANY, - value: 1, - }, + create_effect('medaillon', ANY, 1), ], }, { id: SOVIET_SUPPORT, name: 'Soviet Support', triggers: [ - { - type: 'bonus', - target: MORALE_BONUS, - value: OFF, - }, - { - type: 'attack', - target: SOUTHERN, - value: -1, - }, + create_effect('bonus', MORALE_BONUS, OFF), + create_effect('attack', SOUTHERN, -1), null, null, null, - { - type: 'track', - target: LIBERTY, - value: -1, - }, + create_effect('track', LIBERTY, -1), null, - { - type: 'front', - target: ANY, - value: 1, - }, - { - type: 'track', - target: GOVERNMENT, - value: -1, - }, + create_effect('front', ANY, 1), + create_effect('track', GOVERNMENT, -1), null, - { - type: 'medaillon', - target: ANY, - value: 1, - }, + create_effect('medaillon', ANY, 1), ], }, { id: FOREIGN_AID, name: 'Foreign Aid', triggers: [ - { - type: 'bonus', - target: MORALE_BONUS, - value: OFF, - }, - { - type: 'attack', - target: NORTHERN, - value: -1, - }, + create_effect('bonus', MORALE_BONUS, OFF), + create_effect('attack', NORTHERN, -1), null, null, null, - { - type: 'track', - target: LIBERTY, - value: -1, - }, + create_effect('track', LIBERTY, -1), null, - { - type: 'front', - target: ANY, - value: 1, - }, - { - type: 'track', - target: GOVERNMENT, - value: 1, - }, + create_effect('front', ANY, 1), + create_effect('track', GOVERNMENT, 1), null, - { - type: 'medaillon', - target: ANY, - value: 1, - }, + create_effect('medaillon', ANY, 1), ], }, ], @@ -1,49 +1,4 @@ -export interface CardBase { - id: number; - title: string; -} - -export interface CardEffect { - type: 'attack' | 'track' | 'bonus' | 'hero_points'; - target: string | number; - value: number; -} - -export interface EventCard extends CardBase { - type: 'ec'; - year: number; - effects: CardEffect[]; -} - -export interface PlayerCard extends CardBase { - type: 'pc'; - strength: number; -} - -export type Card = EventCard | PlayerCard; - -export interface StaticData { - cards: Card[]; - fronts: Array<{ - id: string; - name: string; - left: number; - top: number; - }>; - medaillons: Array<{ - id: number; - name: string; - }>; - tracks: Array<{ - id: number; - name: string; - triggers: Array<null | { - type: 'attack' | 'track' | 'bonus' | 'front' | 'medaillon'; - target: string | number; - value: number; - }>; - }>; -} +import { Card, Effect, StaticData } from './types'; const LIBERTY = 0; const COLLECTIVIZATION = 1; @@ -70,6 +25,9 @@ const TOWARDS_CENTER = 10; const AWAY_FROM_CENTER = 11; const ANY = 'any'; +const SELF = 'self'; +const OTHER_PLAYERS = 'other'; +const TRASH = 'trash'; export { LIBERTY, @@ -84,329 +42,630 @@ export { PLAYER_WITH_MOST_HERO_POINTS, }; +function create_effect( + type: Effect['type'], + target: Effect['target'], + value: Effect['value'] +): Effect { + return { + type, + target, + value, + }; +} + const data: StaticData = { cards: [ {} as Card, { id: 1, + effects: [ + create_effect('track', FOREIGN_AID, 2), + // create_effect('track', FOREIGN_AID, 2), // Conditional support + create_effect('track', SOVIET_SUPPORT, -1), + ], strength: 1, title: 'CLANDESTINE FRENCH ARMS', type: 'pc', }, { id: 2, + effects: [ + create_effect('track', FOREIGN_AID, 1), + create_effect('front', ANY, 3), + create_effect('track', LIBERTY, -2), + ], strength: 2, title: 'POPULAR ARMY OF THE REPUBLIC', type: 'pc', }, { id: 3, + effects: [ + create_effect('front', CLOSEST_TO_DEFEAT, 3), + // create_effect('track', FOREIGN_AID, 2), // conditional effect + create_effect('draw_card', SELF, 1), + ], strength: 2, title: 'MEXICAN GUNS', type: 'pc', }, { id: 4, + effects: [ + create_effect('front', MADRID, 3), + create_effect('track', FOREIGN_AID, 1), + create_effect('swap_card_tableau_hand', ANY, 1), + ], strength: 1, title: 'BATTLE OF GUADALAJARA', type: 'pc', }, { id: 5, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('front', CLOSEST_TO_DEFEAT, 2), + create_effect('draw_card', SELF, 3), + create_effect('draw_card', OTHER_PLAYERS, 1), + ], strength: 1, title: '"SI ME OUIERES ESCRIBIR"', type: 'pc', }, { id: 6, + effects: [ + create_effect('bonus', ANY, ON), + // create_effect('front', ANY, ON), // REMOVE attacks from front + create_effect('track', GOVERNMENT, 1), + create_effect('draw_card', SELF, 1), + ], strength: 2, title: 'XYZ LINE', type: 'pc', }, { id: 7, + effects: [ + create_effect('front', ANY, 1), + create_effect('track', FOREIGN_AID, 2), + create_effect('track', COLLECTIVIZATION, -1), + create_effect('track', GOVERNMENT, 2), + create_effect('hero_points', SELF, 1), + ], strength: 3, title: 'INDALECIO PRIETO', type: 'pc', }, { id: 8, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('front', ANY, 3), + ], strength: 1, title: "PEOPLE'S OLYMPIAD", type: 'pc', }, { id: 9, + effects: [ + create_effect('track', LIBERTY, -2), + create_effect('track', COLLECTIVIZATION, -2), + create_effect('track', SOVIET_SUPPORT, -2), + create_effect('draw_card', SELF, 3), + ], strength: 1, title: 'FOUR ANARCHIST MINISTERS', type: 'pc', }, { id: 10, + effects: [ + create_effect('track', FOREIGN_AID, 4), + // create_effect('track', FOREIGN_AID, 3) // conditional draw cards + create_effect('add_to_tableau', SELF, 1), + ], strength: 1, title: 'GUERNICA', type: 'pc', }, { id: 11, + effects: [ + create_effect('front', CLOSEST_TO_DEFEAT, 1), + create_effect('remove_blank_marker', ANY, 1), + create_effect('track', FOREIGN_AID, 2), + ], strength: 1, title: 'ERNEST HEMINGWAY', type: 'pc', }, { id: 12, + effects: [ + // create_effect('hero_points', OTHER_PLAYERS, -2), // take from other player + create_effect('track', SOVIET_SUPPORT, -3), + create_effect('track', COLLECTIVIZATION, -3), + ], strength: 1, title: 'HUESCA OFFENSIVE', type: 'pc', }, { id: 13, + effects: [ + create_effect('track', FOREIGN_AID, 1), + create_effect('track', SOVIET_SUPPORT, -1), + create_effect('track', GOVERNMENT, 2), + create_effect('hero_points', SELF, 1), + ], strength: 1, title: 'PABLO NERUDA', type: 'pc', }, { id: 14, + effects: [ + create_effect('front', NORTHERN, 2), + create_effect('track', COLLECTIVIZATION, -1), + create_effect('track', GOVERNMENT, 1), + ], strength: 1, title: 'EUSKO GUDAROSTEA', type: 'pc', }, { id: 15, + effects: [ + // create_effect('track', ) Choose track, + create_effect('track', FOREIGN_AID, 2), + create_effect('return_card', TRASH, 1), + ], strength: 2, title: 'JUAN NEGRÍN', type: 'pc', }, { id: 16, + effects: [ + // create_effect('front', ANY, -2) // move attacks + // create_effect('track', FOREIGN_AID, 4) // conditional + ], strength: 1, title: 'PUBLICIZE FASCIST WAR CRIMES', type: 'pc', }, { id: 17, + effects: [ + create_effect('track', FOREIGN_AID, 1), + create_effect('track', GOVERNMENT, 1), + // create_effect('track', COLLECTIVIZATION,-4) // conditional + ], strength: 1, title: 'AGRARIAN REFORM', type: 'pc', }, { id: 18, + effects: [ + create_effect('track', COLLECTIVIZATION, -3), + create_effect('track', GOVERNMENT, 2), + create_effect('draw_card', SELF, 2), + ], strength: 1, title: 'IMPOSE FACTORY MANAGERS', type: 'pc', }, { id: 19, + effects: [ + create_effect('front', CLOSEST_TO_DEFEAT, 2), + create_effect('track', GOVERNMENT, -1), + create_effect('return_card', TRASH, 1), + ], strength: 2, title: '¡NO PASARÁN!', type: 'pc', }, { id: 20, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('track', SOVIET_SUPPORT, 2), + // create_effect('front') // conditional on track + ], strength: 2, title: 'RUSSIAN FIGHTERS', type: 'pc', }, { id: 21, + effects: [ + create_effect('front', ANY, 1), + create_effect('track', LIBERTY, -2), + create_effect('track', COLLECTIVIZATION, -2), + create_effect('hero_points', SELF, 1), + ], strength: 1, title: 'ENRIQUE LÍSTER', type: 'pc', }, { id: 22, + effects: [ + create_effect('track', LIBERTY, -2), + create_effect('track', SOVIET_SUPPORT, 1), + // create_effect('track', GOVERNMENT, -2) // conditional + ], strength: 2, title: 'LARGO CABALLERO', type: 'pc', }, { id: 23, + effects: [ + // create_effect('front', ANY, 4) // conditional on track + create_effect('track', FOREIGN_AID, -2), + create_effect('draw_card', SELF, 2), + ], strength: 2, title: 'SOVIET TANKS', type: 'pc', }, { id: 24, + effects: [ + create_effect('front', ANY, 1), + create_effect('track', SOVIET_SUPPORT, 2), + create_effect('track', LIBERTY, -1), + create_effect('track', GOVERNMENT, -2), + create_effect('hero_points', SELF, 1), + ], strength: 3, title: 'DOLORES IBÁRRURI', type: 'pc', }, { id: 25, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('front', CLOSEST_TO_DEFEAT, 2), + create_effect('draw_card', SELF, 3), + create_effect('draw_card', OTHER_PLAYERS, 1), + ], strength: 1, title: 'PAUL ROBESON', type: 'pc', }, { id: 26, + effects: [ + // create_effect('front', MADRID, 1), // ability active + create_effect('track', LIBERTY, -2), + create_effect('track', GOVERNMENT, -1), + ], strength: 1, title: 'MADRID DEFENSE COUNCIL', type: 'pc', }, { id: 27, + effects: [ + create_effect('remove_blank_marker', ANY, 1), + create_effect('track', SOVIET_SUPPORT, 3), + create_effect('track', FOREIGN_AID, -1), + create_effect('draw_card', SELF, 1), + ], strength: 1, title: "STALIN GETS THE REPUBLIC'S GOLD", type: 'pc', }, { id: 28, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('front', SOUTHERN, 3), + create_effect('track', FOREIGN_AID, -1), + create_effect('draw_card', SELF, 1), + ], strength: 1, title: 'INTERNATIONAL BRIGADES', type: 'pc', }, { id: 29, + effects: [ + create_effect('track', GOVERNMENT, -2), + // create_effect('track', LIBERTY, -3) // conditional + ], strength: 1, title: 'BAN WOMEN FROM THE FRONT', type: 'pc', }, { id: 30, + effects: [ + create_effect('front', ANY, 1), + create_effect('track', SOVIET_SUPPORT, 2), + create_effect('track', FOREIGN_AID, -3), + ], strength: 1, title: 'ABRAHAM LINCOLN BRIGADE', type: 'pc', }, { id: 31, + effects: [ + create_effect('attack', ANY, -2), + create_effect('track', SOVIET_SUPPORT, 3), + create_effect('track', GOVERNMENT, -2), + ], strength: 2, title: 'OUTLAW THE POUM', type: 'pc', }, { id: 32, + effects: [ + // create_effect('hero_points', OTHER_PLAYERS, 1) // take 1 from others + create_effect('front', ANY, 1), + create_effect('track', SOVIET_SUPPORT, 1), + // create_effect('track') // choose one of two tracks + ], strength: 1, title: 'DISBAND THE CONTROL PATROLS', type: 'pc', }, { id: 33, + effects: [ + create_effect('attack', ARAGON, -1), + create_effect('track', SOVIET_SUPPORT, 1), + create_effect('track', LIBERTY, -4), + create_effect('swap_card_tableau_hand', ANY, 1), + ], strength: 1, title: 'MAY DAYS', type: 'pc', }, { id: 34, + effects: [ + create_effect('front', SOUTHERN, 2), + create_effect('track', GOVERNMENT, -1), + create_effect('draw_card', SELF, 1), + ], strength: 1, title: 'FIFTH REGIMENT', type: 'pc', }, { id: 35, + effects: [ + create_effect('front', ANY, 2), + // create_effect('track', SOVIET_SUPPORT,2) // conditional + create_effect('draw_card', SELF, 2), + ], strength: 1, title: 'THÄLMANN BATTALION', type: 'pc', }, { id: 36, + effects: [ + create_effect('track', SOVIET_SUPPORT, 2), + create_effect('track', COLLECTIVIZATION, -3), + create_effect('draw_card', SELF, 2), + create_effect('add_to_tableau', ANY, 1), + ], strength: 1, title: 'DE-COLLECTIVIZE AGRICULTURE', type: 'pc', }, { id: 37, + effects: [ + create_effect('front', ANY, 1), + create_effect('track', COLLECTIVIZATION,2), + create_effect('track', LIBERTY, 2), + create_effect('track', GOVERNMENT, TOWARDS_CENTER), + create_effect('hero_points', SELF, 1), + ], strength: 3, title: 'BUENAVENTURA DURRUTI', type: 'pc', }, { id: 38, + effects: [ + create_effect('track', LIBERTY, 3), + create_effect('track', SOVIET_SUPPORT, -2), + create_effect('draw_card', SELF, 1), + create_effect('swap_card_tableau_hand', ANY, 1), + ], strength: 2, title: 'MUJERES LIBRES', type: 'pc', }, { id: 39, + effects: [ + // create_effect('move attacks ') + create_effect('track', COLLECTIVIZATION, 1), + create_effect('draw_card', SELF, 2), + ], strength: 1, title: 'IRON COLUMN', type: 'pc', }, { id: 40, + effects: [ + create_effect('front', CLOSEST_TO_DEFEAT, 3), + create_effect('track', COLLECTIVIZATION, 2), + create_effect('draw_card', SELF, 1), + ], strength: 2, title: 'ASTURIAN MINERS', type: 'pc', }, { id: 41, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('track', COLLECTIVIZATION, 3), + create_effect('return_card', TRASH, 1), + ], strength: 2, title: 'CNT-FAI', type: 'pc', }, { id: 42, + effects: [ + create_effect('track', LIBERTY, 2), + create_effect('front', ARAGON, 2), + create_effect('front', MADRID, 1), + // create_effect('ability') // activate ability + ], strength: 2, title: 'DURRUTI COLUMN', type: 'pc', }, { id: 43, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('front', ARAGON, 1), + create_effect('track', SOVIET_SUPPORT, -2), + create_effect('draw_card', SELF, 3), + create_effect('draw_card', OTHER_PLAYERS, 1), + ], strength: 1, title: 'GEORGE ORWELL', type: 'pc', }, { id: 44, + effects: [ + // create_effect('hero_points', OTHER_PLAYERS, -1) // take from other player + create_effect('front', MADRID, 2), + create_effect('track', LIBERTY, 1), + create_effect('track', FOREIGN_AID, -1), + ], strength: 1, title: 'F.I.J.L.', type: 'pc', }, { id: 45, + effects: [ + create_effect('front', ANY, 2), + // create_effect('track', COLLECTIVIZATION, 1) // conditional + create_effect('track', FOREIGN_AID, -3) + ], strength: 1, title: 'ARM THE UNIONS', type: 'pc', }, { id: 46, + effects: [ + create_effect('bonus', ANY, ON), + create_effect('track', LIBERTY, 2), + // create_effect('special') // Peek at Fascist cards + ], strength: 1, title: 'GUERRILLAS', type: 'pc', }, { id: 47, + effects: [ + create_effect('remove_blank_marker', ANY, 1), + create_effect('track', LIBERTY, 2), + create_effect('track', GOVERNMENT, TOWARDS_CENTER), + create_effect('draw_card', SELF, 1), + ], strength: 1, title: 'RADICAL EDUCATION', type: 'pc', }, { id: 48, + effects: [ + create_effect('front', CLOSEST_TO_DEFEAT, 2), + create_effect('track', SOVIET_SUPPORT, -2), + create_effect('draw_card', SELF, 3), + ], strength: 1, title: 'MATTEOTTI BATTALION', type: 'pc', }, { id: 49, + effects: [ + create_effect('track', COLLECTIVIZATION, 4), + create_effect('draw_card', SELF, 1), + ], strength: 1, title: 'COLLECTIVIZE AGRICULTURE', type: 'pc', }, { id: 50, + effects: [ + create_effect('track', COLLECTIVIZATION, 1), + // create_effect('front', ARAGON, 3) // conditional + create_effect('track', FOREIGN_AID, -1), + ], strength: 1, title: 'ARMORED VEHICLES', type: 'pc', }, { id: 51, + effects: [ + create_effect('track', COLLECTIVIZATION, 3), + create_effect('track', FOREIGN_AID, -2), + create_effect('track', GOVERNMENT, TOWARDS_CENTER), + ], strength: 1, title: 'INDUSTRIAL DEMOCRACY', type: 'pc', }, { id: 52, + effects: [ + create_effect('front', ANY, 1), + // create_effect('track') // choose + create_effect('track', GOVERNMENT, TOWARDS_CENTER), + ], strength: 2, title: 'AFFINITY GROUPS', type: 'pc', }, { id: 53, + effects: [ + create_effect('track', LIBERTY, 1), + // create_effect('front', ANY, 3) // conditional + create_effect('hero_points', SELF, 1), + ], strength: 1, title: 'GENDER-INCLUSIVE MILITIA', type: 'pc', }, { id: 54, + effects: [ + // create_effect('track', LIBERTY, 3) // conditional + create_effect('track', SOVIET_SUPPORT, -1), + create_effect('add_to_tableau', ANY, 1), + ], strength: 1, title: 'FEDERICA MONTSENY', type: 'pc', @@ -414,21 +673,9 @@ const data: StaticData = { { id: 55, effects: [ - { - target: SOUTHERN, - type: 'attack', - value: 4, - }, - { - target: ARAGON, - type: 'attack', - value: 1, - }, - { - target: SOVIET_SUPPORT, - type: 'track', - value: -2, - }, + create_effect('attack', SOUTHERN, -4), + create_effect('attack', ARAGON, -1), + create_effect('track', SOVIET_SUPPORT, -2), ], title: 'SPANISH LEGION', type: 'ec', @@ -437,21 +684,9 @@ const data: StaticData = { { id: 56, effects: [ - { - target: SOUTHERN, - type: 'attack', - value: 3, - }, - { - target: CLOSEST_TO_VICTORY, - type: 'attack', - value: 2, - }, - { - target: MORALE_BONUS, - type: 'bonus', - value: OFF, - }, + create_effect('attack', SOUTHERN, -3), + create_effect('attack', CLOSEST_TO_VICTORY, -2), + create_effect('bonus', MORALE_BONUS, OFF), ], title: 'BRITISH TREACHERY AT GIBRALTAR', type: 'ec', @@ -460,21 +695,9 @@ const data: StaticData = { { id: 57, effects: [ - { - target: MADRID, - type: 'attack', - value: -5, - }, - { - target: FOREIGN_AID, - type: 'track', - value: -2, - }, - { - target: PLAYER_WITH_MOST_HERO_POINTS, - type: 'hero_points', - value: -1, - }, + create_effect('attack', MADRID, -5), + create_effect('track', FOREIGN_AID, -2), + create_effect('hero_points', PLAYER_WITH_MOST_HERO_POINTS, -1), ], title: 'PARACUELLOS MASSACRES', type: 'ec', @@ -483,21 +706,9 @@ const data: StaticData = { { id: 58, effects: [ - { - target: 'n', - type: 'attack', - value: -5, - }, - { - target: 'v', - type: 'attack', - value: -1, - }, - { - target: COLLECTIVIZATION, - type: 'track', - value: -1, - }, + create_effect('attack', NORTHERN, -5), + create_effect('attack', CLOSEST_TO_VICTORY, -1), + create_effect('track', COLLECTIVIZATION, -1), ], title: 'CARLISTS', type: 'ec', @@ -506,21 +717,9 @@ const data: StaticData = { { id: 59, effects: [ - { - target: MADRID, - type: 'attack', - value: -4, - }, - { - target: CLOSEST_TO_VICTORY, - type: 'attack', - value: -2, - }, - { - target: LIBERTY, - type: 'track', - value: -1, - }, + create_effect('attack', MADRID, -4), + create_effect('attack', CLOSEST_TO_VICTORY, -2), + create_effect('track', LIBERTY, -1), ], title: 'ASSASSINATION OF GARCIA LORCA', type: 'ec', @@ -529,21 +728,9 @@ const data: StaticData = { { id: 60, effects: [ - { - target: NORTHERN, - type: 'attack', - value: -3, - }, - { - target: CLOSEST_TO_VICTORY, - type: 'attack', - value: -3, - }, - { - target: LIBERTY, - type: 'track', - value: -1, - }, + create_effect('attack', NORTHERN, -3), + create_effect('attack', CLOSEST_TO_VICTORY, -3), + create_effect('track', LIBERTY, -1), ], title: 'GENERAL SANJURIO', type: 'ec', @@ -552,21 +739,9 @@ const data: StaticData = { { id: 61, effects: [ - { - target: ARAGON, - type: 'attack', - value: -4, - }, - { - target: CLOSEST_TO_VICTORY, - type: 'attack', - value: -2, - }, - { - target: PLAYER_WITH_MOST_HERO_POINTS, - type: 'hero_points', - value: -1, - }, + create_effect('attack', ARAGON, -2), + create_effect('attack', CLOSEST_TO_VICTORY, -2), + create_effect('hero_points', PLAYER_WITH_MOST_HERO_POINTS, -1), ], title: 'FAILED INVASION OF MALLORCA', type: 'ec', @@ -575,21 +750,9 @@ const data: StaticData = { { id: 62, effects: [ - { - target: SOUTHERN, - type: 'attack', - value: -5, - }, - { - target: MORALE_BONUS, - type: 'bonus', - value: OFF, - }, - { - target: PLAYER_WITH_MOST_HERO_POINTS, - type: 'hero_points', - value: -1, - }, + create_effect('attack', SOUTHERN, -5), + create_effect('bonus', MORALE_BONUS, OFF), + create_effect('hero_points', PLAYER_WITH_MOST_HERO_POINTS, -1), ], title: 'AIRLIFT OF THE ARMY OF AFRICA', type: 'ec', @@ -665,82 +828,34 @@ const data: StaticData = { id: LIBERTY, name: 'Liberty', triggers: [ - { - type: 'bonus', - target: MORALE_BONUS, - value: OFF, - }, - { - type: 'attack', - target: MADRID, - value: -1, - }, + create_effect('bonus', MORALE_BONUS, OFF), + create_effect('attack', MADRID, -1), null, - { - type: 'track', - target: SOVIET_SUPPORT, - value: 1, - }, + create_effect('track', SOVIET_SUPPORT, 1), null, null, null, - { - type: 'track', - target: GOVERNMENT, - value: TOWARDS_CENTER, - }, - { - type: 'front', - target: ANY, - value: 1, - }, + create_effect('track', GOVERNMENT, TOWARDS_CENTER), + create_effect('front', ANY, 1), null, - { - type: 'medaillon', - target: ANY, - value: 1, - }, + create_effect('medaillon', ANY, 1), ], }, { id: COLLECTIVIZATION, name: 'Collectivization', triggers: [ - { - type: 'bonus', - target: MORALE_BONUS, - value: OFF, - }, - { - type: 'attack', - target: ARAGON, - value: -1, - }, + create_effect('bonus', MORALE_BONUS, OFF), + create_effect('attack', ARAGON, -1), null, - { - type: 'track', - target: FOREIGN_AID, - value: 1, - }, + create_effect('track', FOREIGN_AID, 1), null, null, null, - { - type: 'front', - target: ANY, - value: 1, - }, - { - type: 'track', - target: LIBERTY, - value: 1, - }, + create_effect('front', ANY, 1), + create_effect('track', LIBERTY, 1), null, - { - type: 'medaillon', - target: ANY, - value: 1, - }, + create_effect('medaillon', ANY, 1), ], }, { @@ -748,114 +863,50 @@ const data: StaticData = { name: 'Government', triggers: [ null, - { - type: 'medaillon', - target: ANY, - value: 1, - }, + create_effect('medaillon', ANY, 1), null, null, - { - type: 'track', - target: SOVIET_SUPPORT, - value: 1, - }, + create_effect('track', SOVIET_SUPPORT, 1), null, null, - { - type: 'track', - target: FOREIGN_AID, - value: 1, - }, + create_effect('track', FOREIGN_AID, 1), null, null, - { - type: 'medaillon', - target: ANY, - value: 1, - }, + create_effect('medaillon', ANY, 1), ], }, { id: SOVIET_SUPPORT, name: 'Soviet Support', triggers: [ - { - type: 'bonus', - target: MORALE_BONUS, - value: OFF, - }, - { - type: 'attack', - target: SOUTHERN, - value: -1, - }, + create_effect('bonus', MORALE_BONUS, OFF), + create_effect('attack', SOUTHERN, -1), null, null, null, - { - type: 'track', - target: LIBERTY, - value: -1, - }, + create_effect('track', LIBERTY, -1), null, - { - type: 'front', - target: ANY, - value: 1, - }, - { - type: 'track', - target: GOVERNMENT, - value: -1, - }, + create_effect('front', ANY, 1), + create_effect('track', GOVERNMENT, -1), null, - { - type: 'medaillon', - target: ANY, - value: 1, - }, + create_effect('medaillon', ANY, 1), ], }, { id: FOREIGN_AID, name: 'Foreign Aid', triggers: [ - { - type: 'bonus', - target: MORALE_BONUS, - value: OFF, - }, - { - type: 'attack', - target: NORTHERN, - value: -1, - }, + create_effect('bonus', MORALE_BONUS, OFF), + create_effect('attack', NORTHERN, -1), null, null, null, - { - type: 'track', - target: LIBERTY, - value: -1, - }, + create_effect('track', LIBERTY, -1), null, - { - type: 'front', - target: ANY, - value: 1, - }, - { - type: 'track', - target: GOVERNMENT, - value: 1, - }, + create_effect('front', ANY, 1), + create_effect('track', GOVERNMENT, 1), null, - { - type: 'medaillon', - target: ANY, - value: 1, - }, + create_effect('medaillon', ANY, 1), ], }, ], @@ -1,10 +1,6 @@ 'use strict'; -import { - - StaticData, -} from './data'; -import { View } from './types'; +import { StaticData, View } from './types'; declare function action_button(action: string, text: string): void; // declare function register_action(element: HTMLElement, type: string, s: number): void; @@ -33,21 +33,7 @@ const front_names = { d: 'the Front closest to Defeat', v: 'the Front closest to Victory', }; -const tracks = [ - data_1.LIBERTY, - data_1.COLLECTIVIZATION, - data_1.GOVERNMENT, - data_1.SOVIET_SUPPORT, - data_1.FOREIGN_AID, -]; -const track_names = { - [data_1.LIBERTY]: 'Liberty', - [data_1.COLLECTIVIZATION]: 'Collectivization', - [data_1.GOVERNMENT]: 'Government', - [data_1.SOVIET_SUPPORT]: 'Soviet Support', - [data_1.FOREIGN_AID]: 'Foreign Aid', -}; -const { cards, } = data_1.default; +const { cards, tracks, } = data_1.default; const faction_cards = { [ANARCHISTS_ID]: make_list(37, 54), [COMMUNISTS_ID]: make_list(19, 36), @@ -311,6 +297,7 @@ function setup(seed, _scenario, _options) { [MODERATES_ID]: [], }, tracks: [5, 5, 6, 3, 3], + triggered_track_effects: [[], [], [], [], []], log: [], undo: [], turn: 1, @@ -341,12 +328,7 @@ function start_turn() { game.current_events.push(cardId); const card = cards[cardId]; log_h3('Fascist Event: ' + card.title); - game.engine = card.effects.map((_effect, index) => ({ - t: leaf_node, - s: 'resolve_event', - p: game.initiative, - a: index, - })); + game.engine = card.effects.map((effect) => resolve_effect(effect, game.initiative)); game.engine.push({ t: 'f', f: 'setup_choose_card', @@ -375,12 +357,34 @@ states.add_glory = { resolve_active_and_proceed(); }, }; +states.attack_front = { + inactive: 'attack a Front', + prompt() { + const node = get_active_node(); + const front = node.a.f; + view.prompt = 'Attack ' + front_names[front]; + if (front === 'd' || front === 'v') { + const fronts = get_fronts_closest_to(front); + fronts.forEach((id) => gen_action('front', id)); + } + else { + gen_action('front', front); + } + }, + front(f) { + const node = get_active_node(); + const value = node.a.v; + game.fronts[f] += value; + log_h3(`${Math.abs(value)} attacks added to ${front_names[f]}`); + resolve_active_and_proceed(); + }, +}; states.choose_area_ap = { inactive: 'choose area to use Action Points', prompt() { view.prompt = 'Choose area of the board to affect'; - for (let track_id of tracks) { - gen_action_standee(track_id); + for (let track of tracks) { + gen_action_standee(track.id); } }, standee(track_id) { @@ -414,7 +418,7 @@ states.move_track_up_or_down = { const node = get_active_node(); move_track(node.a.track_id, node.a.strength); resolve_active_and_proceed(); - } + }, }; states.choose_card = { inactive: 'choose a card', @@ -433,6 +437,28 @@ states.choose_card = { resolve_active_and_proceed(); }, }; +states.lose_hero_points = { + inactive: 'choose a Player', + prompt() { + view.prompt = 'Lose Hero Points'; + }, +}; +states.move_track = { + inactive: 'move a Track', + prompt() { + const node = get_active_node(); + const track = node.a.t; + const value = node.a.v; + view.prompt = `Move ${tracks[track].name} ${value > 0 ? 'up' : 'down'}`; + gen_action_standee(track); + }, + standee(s) { + const node = get_active_node(); + const value = node.a.v; + move_track(s, value); + resolve_active_and_proceed(); + }, +}; states.player_turn = { inactive: 'play their turn', prompt() { @@ -519,15 +545,7 @@ states.resolve_event = { const node = get_active_node(game.engine); const effect = card.effects[node.a]; view.prompt = get_event_prompt(effect); - if (effect.type === 'attack' && - (effect.target === 'd' || effect.target === 'v')) { - const fronts = get_fronts_closest_to(effect.target); - fronts.forEach((id) => gen_action('front', id)); - } - else if (effect.type === 'attack') { - gen_action('front', effect.target); - } - else if (effect.type === 'track') { + if (effect.type === 'track') { gen_action('standee', effect.target); } else if (effect.type === 'hero_points' && @@ -538,20 +556,6 @@ states.resolve_event = { } } }, - front(f) { - const card = get_current_event(); - const value = card.effects[get_active_node_args()].value; - game.fronts[f] -= value; - log_h3(`${value} attacks added to ${front_names[f]}`); - resolve_active_and_proceed(); - }, - standee(s) { - const effect = get_current_event().effects[get_active_node_args()]; - const value = effect.value; - game.tracks[s] += value; - log_h3(`${track_names[effect.target]} decreased by ${Math.abs(value)}`); - resolve_active_and_proceed(); - }, Anarchist() { lose_hero_point(ANARCHISTS_ID, 1); resolve_active_and_proceed(); @@ -607,7 +611,66 @@ function resolve_fascist_test() { log_h2('Fascist test is resolved'); next(); } -function move_track(track, change) { +function move_track(track_id, change) { + const current_value = game.tracks[track_id]; + let new_value = current_value + change; + new_value = Math.max(new_value, track_id === data_1.GOVERNMENT ? 1 : 0); + new_value = Math.min(new_value, 10); + game.tracks[track_id] = new_value; + log(`${game.active} moves ${get_track_name(track_id)} to ${new_value}`); + const triggered_spaces = change > 0 + ? make_list(current_value + 1, new_value).reverse() + : make_list(new_value, current_value - 1); + triggered_spaces.forEach((space_id) => { + const trigger = tracks[track_id].triggers[space_id]; + if (trigger !== null && + !game.triggered_track_effects[track_id].includes(space_id)) { + if (space_id !== 0) { + game.triggered_track_effects[track_id].push(space_id); + } + const node = resolve_effect(trigger); + if (node !== null) { + insert_after_active_node(node); + } + } + }); +} +function resolve_effect(effect, faction = get_active_faction()) { + if (effect.type === 'attack') { + return { + t: leaf_node, + p: faction, + s: 'attack_front', + a: { + f: effect.target, + v: effect.value, + }, + }; + } + if (effect.type === 'track') { + return { + t: leaf_node, + p: faction, + s: 'move_track', + a: { + t: effect.target, + v: effect.value, + }, + }; + } + if (effect.type === 'hero_points' && + effect.target === data_1.PLAYER_WITH_MOST_HERO_POINTS) { + return { + t: leaf_node, + p: faction, + s: 'lose_hero_points', + a: { + p: effect.target, + v: effect.value, + }, + }; + } + return null; } function draw_card(deck) { clear_undo(); @@ -646,7 +709,7 @@ function get_event_prompt(effect) { case 'hero_points': return 'Select player with most Hero points'; case 'track': - return 'Decrease ' + track_names[effect.target]; + return 'Decrease ' + tracks[effect.target].name; } return prompt; } @@ -730,7 +793,7 @@ function get_factions_with_most_hero_poins() { return faction_ids; } function get_track_name(track_id) { - return track_names[track_id]; + return tracks[track_id].name; } function make_list(first, last) { let list = []; @@ -2,12 +2,15 @@ import { CardId, + Effect, EngineNode, + EventCard, FactionId, FunctionNode, Game, LeafNode, Player, + PlayerCard, States, View, } from './types'; @@ -22,15 +25,12 @@ import data, { // TEAMWORK_BONUS, // OFF, ON, - EventCard, - CardEffect, LIBERTY, COLLECTIVIZATION, GOVERNMENT, SOVIET_SUPPORT, FOREIGN_AID, PLAYER_WITH_MOST_HERO_POINTS, - PlayerCard, // StaticData, // PLAYER_WITH_MOST_HERO_POINTS, } from './data'; @@ -75,25 +75,10 @@ const front_names: Record<string, string> = { v: 'the Front closest to Victory', }; -const tracks = [ - LIBERTY, - COLLECTIVIZATION, - GOVERNMENT, - SOVIET_SUPPORT, - FOREIGN_AID, -]; - -const track_names: Record<number, string> = { - [LIBERTY]: 'Liberty', - [COLLECTIVIZATION]: 'Collectivization', - [GOVERNMENT]: 'Government', - [SOVIET_SUPPORT]: 'Soviet Support', - [FOREIGN_AID]: 'Foreign Aid', -}; - const { cards, - // fronts + // fronts, + tracks, } = data; const faction_cards = { @@ -453,6 +438,7 @@ export function setup(seed: number, _scenario: string, _options: unknown) { [MODERATES_ID]: [], }, tracks: [5, 5, 6, 3, 3], + triggered_track_effects: [[], [], [], [], []], log: [], undo: [], turn: 1, @@ -492,12 +478,9 @@ function start_turn() { const card = cards[cardId] as EventCard; log_h3('Fascist Event: ' + card.title); - game.engine = card.effects.map((_effect, index) => ({ - t: leaf_node, - s: 'resolve_event', - p: game.initiative, - a: index, - })); + game.engine = card.effects.map((effect) => + resolve_effect(effect, game.initiative) + ); game.engine.push({ t: 'f', f: 'setup_choose_card', @@ -534,12 +517,34 @@ states.add_glory = { }, }; +states.attack_front = { + inactive: 'attack a Front', + prompt() { + const node = get_active_node(); + const front = node.a.f; + view.prompt = 'Attack ' + front_names[front]; + if (front === 'd' || front === 'v') { + const fronts = get_fronts_closest_to(front); + fronts.forEach((id) => gen_action('front', id)); + } else { + gen_action('front', front); + } + }, + front(f: string) { + const node = get_active_node(); + const value = node.a.v; + game.fronts[f] += value; + log_h3(`${Math.abs(value)} attacks added to ${front_names[f]}`); + resolve_active_and_proceed(); + }, +}; + states.choose_area_ap = { inactive: 'choose area to use Action Points', prompt() { view.prompt = 'Choose area of the board to affect'; - for (let track_id of tracks) { - gen_action_standee(track_id); + for (let track of tracks) { + gen_action_standee(track.id); } }, standee(track_id: number) { @@ -561,7 +566,7 @@ states.move_track_up_or_down = { inactive: 'move a track', prompt() { const node = get_active_node(); - view.prompt = `Move ${get_track_name(node.a.track_id)} up or down` + view.prompt = `Move ${get_track_name(node.a.track_id)} up or down`; gen_action('up'); gen_action('down'); }, @@ -574,8 +579,8 @@ states.move_track_up_or_down = { const node = get_active_node(); move_track(node.a.track_id, node.a.strength); resolve_active_and_proceed(); - } -} + }, +}; states.choose_card = { inactive: 'choose a card', @@ -594,6 +599,31 @@ states.choose_card = { }, }; +states.lose_hero_points = { + inactive: 'choose a Player', + prompt() { + view.prompt = 'Lose Hero Points'; + }, +}; + +states.move_track = { + inactive: 'move a Track', + prompt() { + const node = get_active_node(); + const track = node.a.t; + const value = node.a.v; + view.prompt = `Move ${tracks[track].name} ${value > 0 ? 'up' : 'down'}`; + // return 'Decrease ' + tracks[effect.target].name; + gen_action_standee(track) + }, + standee(s: number) { + const node = get_active_node(); + const value = node.a.v; + move_track(s, value) + resolve_active_and_proceed(); + }, +}; + states.player_turn = { inactive: 'play their turn', prompt() { @@ -682,18 +712,10 @@ states.resolve_event = { prompt() { const card = get_current_event(); const node = get_active_node(game.engine) as LeafNode; - const effect: CardEffect = card.effects[node.a]; + const effect: Effect = card.effects[node.a]; view.prompt = get_event_prompt(effect); - if ( - effect.type === 'attack' && - (effect.target === 'd' || effect.target === 'v') - ) { - const fronts = get_fronts_closest_to(effect.target); - fronts.forEach((id) => gen_action('front', id)); - } else if (effect.type === 'attack') { - gen_action('front', effect.target); - } else if (effect.type === 'track') { +if (effect.type === 'track') { gen_action('standee', effect.target); } else if ( effect.type === 'hero_points' && @@ -706,20 +728,7 @@ states.resolve_event = { } // for (let p = 0; p < 5; ++p) gen_action('standee', p); }, - front(f: string) { - const card = get_current_event(); - const value = card.effects[get_active_node_args()].value; - game.fronts[f] -= value; - log_h3(`${value} attacks added to ${front_names[f]}`); - resolve_active_and_proceed(); - }, - standee(s: string) { - const effect = get_current_event().effects[get_active_node_args()]; - const value = effect.value; - game.tracks[s] += value; - log_h3(`${track_names[effect.target]} decreased by ${Math.abs(value)}`); - resolve_active_and_proceed(); - }, + Anarchist() { lose_hero_point(ANARCHISTS_ID, 1); resolve_active_and_proceed(); @@ -803,8 +812,100 @@ function resolve_fascist_test() { next(); } -function move_track(track: number, change: number) { - +function move_track(track_id: number, change: number) { + // Check if track can be moved + // Updata values + // Check all triggers + // Add states for triggers + const current_value = game.tracks[track_id]; + let new_value = current_value + change; + new_value = Math.max(new_value, track_id === GOVERNMENT ? 1 : 0); + new_value = Math.min(new_value, 10); + game.tracks[track_id] = new_value; + log(`${game.active} moves ${get_track_name(track_id)} to ${new_value}`); + const triggered_spaces = + change > 0 + ? make_list(current_value + 1, new_value).reverse() + : make_list(new_value, current_value - 1); + + triggered_spaces.forEach((space_id) => { + const trigger = tracks[track_id].triggers[space_id]; + if ( + trigger !== null && + !game.triggered_track_effects[track_id].includes(space_id) + ) { + if (space_id !== 0) { + game.triggered_track_effects[track_id].push(space_id); + } + const node = resolve_effect(trigger); + if (node !== null) { + insert_after_active_node(node); + } + } + }); +} + +function resolve_effect( + effect: Effect, + faction: FactionId = get_active_faction() +): EngineNode | null { + if (effect.type === 'attack') { + return { + t: leaf_node, + p: faction, + s: 'attack_front', + a: { + f: effect.target, + v: effect.value, + }, + }; + } + if (effect.type === 'track') { + return { + t: leaf_node, + p: faction, + s: 'move_track', + a: { + t: effect.target, + v: effect.value, + }, + }; + } + if ( + effect.type === 'hero_points' && + effect.target === PLAYER_WITH_MOST_HERO_POINTS + ) { + return { + t: leaf_node, + p: faction, + s: 'lose_hero_points', + a: { + p: effect.target, + v: effect.value, + }, + }; + } + return null; + + // if ( + // effect.type === 'attack' && + // (effect.target === 'd' || effect.target === 'v') + // ) { + // const fronts = get_fronts_closest_to(effect.target); + // fronts.forEach((id) => gen_action('front', id)); + // } else if (effect.type === 'attack') { + // gen_action('front', effect.target); + // } else if (effect.type === 'track') { + // gen_action('standee', effect.target); + // } else if ( + // effect.type === 'hero_points' && + // effect.target === PLAYER_WITH_MOST_HERO_POINTS + // ) { + // const factions = get_factions_with_most_hero_poins(); + // for (let faction_id of factions) { + // gen_action(get_player(faction_id)); + // } + // } } // #endregion @@ -874,7 +975,7 @@ function get_current_event(): EventCard { // } // } -function get_event_prompt(effect: CardEffect) { +function get_event_prompt(effect: Effect) { let prompt = ''; switch (effect.type) { case 'attack': @@ -884,7 +985,7 @@ function get_event_prompt(effect: CardEffect) { case 'hero_points': return 'Select player with most Hero points'; case 'track': - return 'Decrease ' + track_names[effect.target]; + return 'Decrease ' + tracks[effect.target].name; } return prompt; } @@ -1067,10 +1168,10 @@ function get_factions_with_most_hero_poins() { } function get_track_name(track_id: number): string { - return track_names[track_id]; + return tracks[track_id].name; } -function make_list(first: number, last: number) { +function make_list(first: number, last: number): number[] { let list = []; for (let i = first; i <= last; i++) list.push(i); return list; @@ -37,7 +37,7 @@ export interface Game { medaillons: Array<number | null>; tableaus: Record<FactionId, CardId[]>; tracks: number[]; - + triggered_track_effects: number[][]; result?: string; victory?: string; @@ -93,4 +93,48 @@ export interface LeafNode { p: FactionId; // Player a?: any; // args r?: 0 | 1; // 1 if resolved +} + +export interface CardBase { + id: number; + title: string; +} + +export type Card = EventCard | PlayerCard; + +export interface EventCard extends CardBase { + type: 'ec'; + year: number; + effects: Effect[]; +} + +export interface PlayerCard extends CardBase { + type: 'pc'; + strength: number; + effects: Effect[]; +} + +export interface Effect { + type: 'attack' | 'track' | 'bonus' | 'hero_points' | 'front' | 'medaillon' | 'draw_card' | 'swap_card_tableau_hand' | 'add_to_tableau' | 'remove_blank_marker' | 'return_card'; + target: string | number; + value: number; +} + +export interface StaticData { + cards: Card[]; + fronts: Array<{ + id: string; + name: string; + left: number; + top: number; + }>; + medaillons: Array<{ + id: number; + name: string; + }>; + tracks: Array<{ + id: number; + name: string; + triggers: Array<null | Effect>; + }>; }
\ No newline at end of file |