summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data.js4
-rw-r--r--data.ts4
-rw-r--r--play.js5
-rw-r--r--play.ts6
-rw-r--r--rules.js110
-rw-r--r--rules.ts152
6 files changed, 170 insertions, 111 deletions
diff --git a/data.js b/data.js
index 7b86c73..dde7a1e 100644
--- a/data.js
+++ b/data.js
@@ -1144,7 +1144,7 @@ const data = {
pass: create_effect('hero_points', PLAYER_WITH_MOST_HERO_POINTS, 1),
fail: create_effect('track', FOREIGN_AID, -2),
},
- title: 'NAZI MINING',
+ title: 'NAZI MINING CONTRACT',
type: 'ec',
year: 2,
},
@@ -1627,7 +1627,7 @@ const data = {
test: {
front: MADRID,
value: 0,
- pass: create_effect('play_card', INITIATIVE_PLAYER, 1),
+ pass: create_effect('play_card', INITIATIVE_PLAYER, 1, INITIATIVE_PLAYER),
fail: create_effect('track', FOREIGN_AID, -3),
},
title: 'NATIONAL DEFENCE COUNCIL',
diff --git a/data.ts b/data.ts
index 8121115..d5992a5 100644
--- a/data.ts
+++ b/data.ts
@@ -1181,7 +1181,7 @@ const data: StaticData = {
pass: create_effect('hero_points', PLAYER_WITH_MOST_HERO_POINTS, 1),
fail: create_effect('track', FOREIGN_AID, -2),
},
- title: 'NAZI MINING',
+ title: 'NAZI MINING CONTRACT',
type: 'ec',
year: 2,
},
@@ -1689,7 +1689,7 @@ const data: StaticData = {
test: {
front: MADRID,
value: 0,
- pass: create_effect('play_card', INITIATIVE_PLAYER, 1),
+ pass: create_effect('play_card', INITIATIVE_PLAYER, 1, INITIATIVE_PLAYER),
fail: create_effect('track', FOREIGN_AID, -3),
},
title: 'NATIONAL DEFENCE COUNCIL',
diff --git a/play.js b/play.js
index ffef09f..00a436a 100644
--- a/play.js
+++ b/play.js
@@ -330,6 +330,7 @@ function on_update() {
ui.turn_info.style.display = 'none';
}
else {
+ ui.turn_info.style.display = '';
ui.turn_info_card.setAttribute('data-card-id', view.played_card + '');
}
for (let g = 0; g < view.glory.length; ++g) {
@@ -346,8 +347,6 @@ function on_update() {
action_button('d_foreign_aid', 'Decrease Foreign Aid');
action_button('d_government', 'Decrease Government');
action_button('d_soviet_support', 'Decrease Soviet Support');
- action_button('draw_card', 'Draw a card');
- action_button('draw_cards', 'Draw cards');
action_button('foreign_aid', 'Foreign Aid');
action_button('government', 'Government');
action_button('liberty', 'Liberty');
@@ -357,6 +356,8 @@ function on_update() {
action_button('Communist', 'Communist');
action_button('Moderate', 'Moderate');
action_button('gain_hp', 'Gain Hero Points');
+ action_button('draw_card', 'Draw a card');
+ action_button('draw_cards', 'Draw cards');
action_button('play_for_ap', 'Play card for Action Points');
action_button('play_for_event', 'Play card for Event');
action_button('spend_hp', 'Spend Hero Points');
diff --git a/play.ts b/play.ts
index 898982e..61e6206 100644
--- a/play.ts
+++ b/play.ts
@@ -432,6 +432,7 @@ function on_update() {
if (view.played_card === null) {
ui.turn_info.style.display = 'none';
} else {
+ ui.turn_info.style.display = '';
ui.turn_info_card.setAttribute('data-card-id', view.played_card + '');
}
@@ -454,8 +455,7 @@ function on_update() {
action_button('d_government', 'Decrease Government');
action_button('d_soviet_support', 'Decrease Soviet Support');
- action_button('draw_card', 'Draw a card');
- action_button('draw_cards', 'Draw cards');
+
action_button('foreign_aid', 'Foreign Aid');
action_button('government', 'Government');
action_button('liberty', 'Liberty');
@@ -466,6 +466,8 @@ function on_update() {
action_button('Communist', 'Communist');
action_button('Moderate', 'Moderate');
action_button('gain_hp', 'Gain Hero Points');
+ action_button('draw_card', 'Draw a card');
+ action_button('draw_cards', 'Draw cards');
// action_button('draw_card', 'Draw card');
action_button('play_for_ap', 'Play card for Action Points');
action_button('play_for_event', 'Play card for Event');
diff --git a/rules.js b/rules.js
index 1573b05..5fbc167 100644
--- a/rules.js
+++ b/rules.js
@@ -433,7 +433,7 @@ states.activate_icon = {
inactive: 'activate an icon',
prompt() {
view.prompt = 'Choose an icon to activate';
- const c = cards[game.selected_cards[get_active_faction_id()][0]];
+ const c = cards[game.played_card];
for (const i of c.icons) {
gen_action(i);
}
@@ -764,12 +764,17 @@ states.choose_card = {
inactive: 'choose a card',
prompt() {
view.prompt = 'Choose a card to play this turn';
- const hand = game.hands[player_faction_map[game.active]];
- for (let c of hand)
- gen_action_card(c);
+ const faction = get_active_faction();
+ const hand = game.hands[faction];
+ for (let c of hand) {
+ if (!game.selected_cards[faction].includes(c)) {
+ gen_action_card(c);
+ }
+ }
},
card(c) {
- game.selected_cards[player_faction_map[game.active]].push(c);
+ const faction = get_active_faction();
+ game.selected_cards[faction].push(c);
resolve_active_and_proceed();
},
};
@@ -824,6 +829,7 @@ states.choose_medallion = {
gain_hero_points(faction, 7);
break;
case 2:
+ insert_after_active_node(create_leaf_node('choose_card', faction));
break;
default:
game.medallions[faction].push(m);
@@ -928,32 +934,34 @@ states.game_over = {
view.prompt = game.victory;
},
};
-states.lose_hero_points = {
+function resolve_player_with_most_hero_points(faction) {
+ const value = get_active_node_args().v;
+ if (value < 0) {
+ lose_hero_point(faction, value);
+ }
+ else {
+ gain_hero_points(faction, value);
+ }
+ resolve_active_and_proceed();
+}
+states.select_player_with_most_hero_points = {
inactive: 'choose a Player',
prompt() {
- const args = get_active_node_args();
- view.prompt = 'Choose player to lose Hero Points';
- if (args.t === data_1.PLAYER_WITH_MOST_HERO_POINTS) {
- const factions = get_factions_with_most_hero_poins();
- for (let faction_id of factions) {
- gen_action(faction_player_map[faction_id]);
- }
+ const { v } = get_active_node_args();
+ view.prompt = v < 0 ? 'Choose player to lose Hero Points' : 'Choose player to gain Hero Points';
+ const factions = get_factions_with_most_hero_poins();
+ for (let faction_id of factions) {
+ gen_action(faction_player_map[faction_id]);
}
},
Anarchist() {
- const value = get_active_node_args().v;
- lose_hero_point(data_1.ANARCHISTS_ID, value);
- resolve_active_and_proceed();
+ resolve_player_with_most_hero_points(data_1.ANARCHISTS_ID);
},
Communist() {
- const value = get_active_node_args().v;
- lose_hero_point(data_1.COMMUNISTS_ID, value);
- resolve_active_and_proceed();
+ resolve_player_with_most_hero_points(data_1.COMMUNISTS_ID);
},
Moderate() {
- const value = get_active_node_args().v;
- lose_hero_point(data_1.MODERATES_ID, value);
- resolve_active_and_proceed();
+ resolve_player_with_most_hero_points(data_1.MODERATES_ID);
},
};
states.move_attacks = {
@@ -1027,8 +1035,8 @@ states.player_turn = {
inactive: 'play their turn',
prompt() {
const faction_id = get_faction_id(game.active);
- const can_spend_hp = game.hero_points[faction_id] > 0;
- const can_play_card = game.hands[faction_id].includes(game.selected_cards[faction_id][0]);
+ const can_spend_hp = game.faction_turn === faction_id && game.hero_points[faction_id] > 0;
+ const can_play_card = game.selected_cards[faction_id].length > 0;
view.prompt = 'Play a card or spend Hero points';
if (!(can_play_card || can_spend_hp)) {
view.prompt = 'End turn';
@@ -1036,6 +1044,9 @@ states.player_turn = {
else if (!can_play_card && can_spend_hp) {
view.prompt = 'Spend Hero Points or end turn';
}
+ else if (can_play_card && !can_spend_hp) {
+ view.prompt = 'Play a card';
+ }
if (can_play_card) {
gen_action('play_for_ap');
gen_action('play_for_event');
@@ -1053,28 +1064,20 @@ states.player_turn = {
resolve_active_and_proceed(true);
},
play_for_ap() {
- const faction_id = get_faction_id(game.active);
- const card = game.selected_cards[faction_id][0];
- game.played_card = card;
- log_h3(`${game.active} plays ${cards[card].title} for the Action Points`);
- array_remove(game.hands[faction_id], game.hands[faction_id].indexOf(card));
- game.tableaus[faction_id].push(card);
+ const faction = get_active_faction();
+ const { strength } = play_card(faction, 'play_for_ap');
insert_before_active_node(create_seq_node([
- create_leaf_node('choose_area_ap', faction_id, {
- strength: cards[card].strength,
+ create_leaf_node('choose_area_ap', faction, {
+ strength,
}),
create_function_node('check_activate_icon'),
]));
next();
},
play_for_event() {
- const faction_id = get_faction_id(game.active);
- const card = game.selected_cards[faction_id][0];
- game.played_card = card;
- array_remove(game.hands[faction_id], game.hands[faction_id].indexOf(card));
- game.trash[faction_id].push(card);
- log_h3(`${game.active} plays ${cards[card].title} for the Event`);
- insert_before_active_node(create_effects_node(cards[card].effects));
+ const faction = get_active_faction();
+ const { effects } = play_card(faction, 'play_for_ap');
+ insert_before_active_node(create_effects_node(effects));
next();
},
spend_hp() {
@@ -1513,6 +1516,22 @@ function get_hand_limit(faction) {
}
return hand_limit;
}
+function play_card(faction, type) {
+ const index = game.selected_cards[faction].length - 1;
+ const card_id = game.selected_cards[faction][index];
+ const card = cards[card_id];
+ game.played_card = card_id;
+ log_h3(`${game.active} plays ${card.title} for the ${type === 'play_for_event' ? 'Event' : 'Action Points'}`);
+ array_remove(game.hands[faction], game.hands[faction].indexOf(card_id));
+ array_remove(game.selected_cards[faction], index);
+ if (type === 'play_for_event') {
+ game.trash[faction].push(card_id);
+ }
+ else {
+ game.tableaus[faction].push(card_id);
+ }
+ return card;
+}
function resolve_fascist_test() {
log_h2('Fascist Test', 'fascist');
const test = get_current_event().test;
@@ -1784,7 +1803,7 @@ function resolve_effect(effect) {
condition: effect.type === 'hero_points' &&
effect.target === data_1.PLAYER_WITH_MOST_HERO_POINTS,
resolve: () => {
- return create_leaf_node('lose_hero_points', faction, args);
+ return create_leaf_node('select_player_with_most_hero_points', faction, args);
},
},
{
@@ -1811,7 +1830,7 @@ function resolve_effect(effect) {
{
condition: effect.type === 'hero_points' && effect.target === data_1.INITIATIVE_PLAYER,
resolve: () => {
- return create_leaf_node('gain_hero_points', game.initiative);
+ return create_leaf_node('gain_hero_points', game.initiative, args);
},
},
{
@@ -1851,6 +1870,15 @@ function resolve_effect(effect) {
return create_seq_node(leaf_nodes);
},
},
+ {
+ condition: effect.type === 'play_card',
+ resolve: () => {
+ return create_seq_node([
+ create_leaf_node('choose_card', faction),
+ create_leaf_node('player_turn', faction),
+ ]);
+ },
+ },
];
const strategy = strategies.find((strategy) => strategy.condition);
if (strategy) {
diff --git a/rules.ts b/rules.ts
index 7b49f1b..dfa17f3 100644
--- a/rules.ts
+++ b/rules.ts
@@ -634,7 +634,7 @@ states.activate_icon = {
inactive: 'activate an icon',
prompt() {
view.prompt = 'Choose an icon to activate';
- const c = cards[game.selected_cards[get_active_faction_id()][0]] as PlayerCard;
+ const c = cards[game.played_card] as PlayerCard;
for (const i of c.icons) {
gen_action(i);
}
@@ -978,11 +978,17 @@ states.choose_card = {
inactive: 'choose a card',
prompt() {
view.prompt = 'Choose a card to play this turn';
- const hand = game.hands[player_faction_map[game.active]];
- for (let c of hand) gen_action_card(c);
+ const faction = get_active_faction();
+ const hand = game.hands[faction];
+ for (let c of hand) {
+ if (!game.selected_cards[faction].includes(c)) {
+ gen_action_card(c);
+ }
+ }
},
card(c: CardId) {
- game.selected_cards[player_faction_map[game.active]].push(c);
+ const faction = get_active_faction();
+ game.selected_cards[faction].push(c);
resolve_active_and_proceed();
},
};
@@ -1042,7 +1048,7 @@ states.choose_medallion = {
gain_hero_points(faction, 7);
break;
case 2:
- // insert play another card action
+ insert_after_active_node(create_leaf_node('choose_card', faction));
break;
default:
game.medallions[faction].push(m);
@@ -1153,32 +1159,36 @@ states.game_over = {
},
};
-states.lose_hero_points = {
+function resolve_player_with_most_hero_points(faction: FactionId) {
+ const value = get_active_node_args().v;
+ if (value < 0) {
+ lose_hero_point(faction, value);
+ } else {
+ gain_hero_points(faction, value)
+ }
+ resolve_active_and_proceed();
+}
+
+
+states.select_player_with_most_hero_points = {
inactive: 'choose a Player',
prompt() {
- const args = get_active_node_args();
- view.prompt = 'Choose player to lose Hero Points';
- if (args.t === PLAYER_WITH_MOST_HERO_POINTS) {
- const factions = get_factions_with_most_hero_poins();
- for (let faction_id of factions) {
- gen_action(faction_player_map[faction_id]);
- }
+ const { v } = get_active_node_args();
+ view.prompt = v < 0 ? 'Choose player to lose Hero Points' : 'Choose player to gain Hero Points';
+
+ const factions = get_factions_with_most_hero_poins();
+ for (let faction_id of factions) {
+ gen_action(faction_player_map[faction_id]);
}
},
Anarchist() {
- const value = get_active_node_args().v;
- lose_hero_point(ANARCHISTS_ID, value);
- resolve_active_and_proceed();
+ resolve_player_with_most_hero_points(ANARCHISTS_ID);
},
Communist() {
- const value = get_active_node_args().v;
- lose_hero_point(COMMUNISTS_ID, value);
- resolve_active_and_proceed();
+ resolve_player_with_most_hero_points(COMMUNISTS_ID);
},
Moderate() {
- const value = get_active_node_args().v;
- lose_hero_point(MODERATES_ID, value);
- resolve_active_and_proceed();
+ resolve_player_with_most_hero_points(MODERATES_ID);
},
};
@@ -1266,16 +1276,19 @@ states.player_turn = {
inactive: 'play their turn',
prompt() {
const faction_id = get_faction_id(game.active as Player);
- const can_spend_hp = game.hero_points[faction_id] > 0;
- // TODO: refactor to check selected_cards.length
- const can_play_card = game.hands[faction_id].includes(
- game.selected_cards[faction_id][0]
- );
+
+ const can_spend_hp =
+ game.faction_turn === faction_id && game.hero_points[faction_id] > 0;
+
+ const can_play_card = game.selected_cards[faction_id].length > 0;
+
view.prompt = 'Play a card or spend Hero points';
if (!(can_play_card || can_spend_hp)) {
view.prompt = 'End turn';
} else if (!can_play_card && can_spend_hp) {
view.prompt = 'Spend Hero Points or end turn';
+ } else if (can_play_card && !can_spend_hp) {
+ view.prompt = 'Play a card';
}
// const card = game.cards_in_play[faction_id];
@@ -1296,16 +1309,13 @@ states.player_turn = {
resolve_active_and_proceed(true);
},
play_for_ap() {
- const faction_id = get_faction_id(game.active as Player);
- const card = game.selected_cards[faction_id][0];
- game.played_card = card;
- log_h3(`${game.active} plays ${cards[card].title} for the Action Points`);
- array_remove(game.hands[faction_id], game.hands[faction_id].indexOf(card));
- game.tableaus[faction_id].push(card);
+ const faction = get_active_faction();
+ const { strength } = play_card(faction, 'play_for_ap');
+
insert_before_active_node(
create_seq_node([
- create_leaf_node('choose_area_ap', faction_id, {
- strength: (cards[card] as PlayerCard).strength,
+ create_leaf_node('choose_area_ap', faction, {
+ strength,
}),
create_function_node('check_activate_icon'),
])
@@ -1313,14 +1323,10 @@ states.player_turn = {
next();
},
play_for_event() {
- const faction_id = get_faction_id(game.active as Player);
- const card = game.selected_cards[faction_id][0];
- game.played_card = card;
- array_remove(game.hands[faction_id], game.hands[faction_id].indexOf(card));
- game.trash[faction_id].push(card);
- log_h3(`${game.active} plays ${cards[card].title} for the Event`);
+ const faction = get_active_faction();
+ const { effects } = play_card(faction, 'play_for_ap');
- insert_before_active_node(create_effects_node(cards[card].effects));
+ insert_before_active_node(create_effects_node(effects));
next();
},
@@ -1497,7 +1503,7 @@ states.swap_card_tableau_hand = {
gen_action_card(c);
}
},
- // card(c: CardId) {},
+ // card(c: CardId) {},
};
// TODO: implement, card 12 + card 32 + card 44
@@ -1887,6 +1893,29 @@ function get_hand_limit(faction: FactionId) {
return hand_limit;
}
+function play_card(
+ faction: FactionId,
+ type: 'play_for_event' | 'play_for_ap'
+): PlayerCard {
+ const index = game.selected_cards[faction].length - 1;
+ const card_id = game.selected_cards[faction][index];
+ const card = cards[card_id];
+ game.played_card = card_id;
+ log_h3(
+ `${game.active} plays ${card.title} for the ${
+ type === 'play_for_event' ? 'Event' : 'Action Points'
+ }`
+ );
+ array_remove(game.hands[faction], game.hands[faction].indexOf(card_id));
+ array_remove(game.selected_cards[faction], index);
+ if (type === 'play_for_event') {
+ game.trash[faction].push(card_id);
+ } else {
+ game.tableaus[faction].push(card_id);
+ }
+ return card as PlayerCard;
+}
+
function resolve_fascist_test() {
log_h2('Fascist Test', 'fascist');
@@ -1939,7 +1968,9 @@ function resolve_final_bid() {
highest_bid = player_bid;
winners = [f];
}
- game.hands[f] = game.hands[f].filter((c) => !game.selected_cards[f].includes(c));
+ game.hands[f] = game.hands[f].filter(
+ (c) => !game.selected_cards[f].includes(c)
+ );
game.discard[f].concat(game.selected_cards[f]);
game.selected_cards[f] = [];
}
@@ -2237,7 +2268,11 @@ function resolve_effect(
effect.type === 'hero_points' &&
effect.target === PLAYER_WITH_MOST_HERO_POINTS,
resolve: () => {
- return create_leaf_node('lose_hero_points', faction, args);
+ return create_leaf_node(
+ 'select_player_with_most_hero_points',
+ faction,
+ args
+ );
},
},
{
@@ -2274,7 +2309,7 @@ function resolve_effect(
condition:
effect.type === 'hero_points' && effect.target === INITIATIVE_PLAYER,
resolve: () => {
- return create_leaf_node('gain_hero_points', game.initiative);
+ return create_leaf_node('gain_hero_points', game.initiative, args);
},
},
{
@@ -2323,6 +2358,15 @@ function resolve_effect(
return create_seq_node(leaf_nodes);
},
},
+ {
+ condition: effect.type === 'play_card',
+ resolve: () => {
+ return create_seq_node([
+ create_leaf_node('choose_card', faction),
+ create_leaf_node('player_turn', faction),
+ ]);
+ },
+ },
];
const strategy = strategies.find((strategy) => strategy.condition);
@@ -2333,22 +2377,6 @@ function resolve_effect(
console.log('----UNRESOLVED EFFECT----', effect);
throw new Error('Unresolved effect');
}
- // if (
- // // TODO: determine state based on value?
- // effect.type === 'hero_points' &&
- // effect.target === PLAYER_WITH_MOST_HERO_POINTS
- // ) {
- // state = 'lose_hero_points';
- // } else if (effect.type === 'hero_points' && effect.target === SELF) {
- // state = 'gain_hero_points';
- // } else if (effect.type === 'draw_card' && effect.target === SELF) {
- // state = 'draw_card';
- // }
- // if (state === undefined) {
- // console.log('----UNRESOLVED EFFECT----', effect);
- // return null;
- // }
- // return create_leaf_node(state, faction, args);
}
function win_final_bid(faction_id: FactionId) {