summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js207
1 files changed, 167 insertions, 40 deletions
diff --git a/rules.js b/rules.js
index 3b085a9..f68af28 100644
--- a/rules.js
+++ b/rules.js
@@ -71,7 +71,10 @@ function gen_action_standee(track_id) {
gen_action('standee', track_id);
}
function action(state, player, action, arg) {
- console.log('action', state, player, action, arg);
+ console.log('action', player, action, arg);
+ if (action !== 'undo') {
+ state.undo = push_undo();
+ }
game = state;
let S = states[game.state];
if (action in S)
@@ -212,17 +215,27 @@ function next() {
}
else if (node.t === 'l') {
game.state = node.s;
- game.active = faction_player_map[node.p];
+ const current_active = game.active;
+ const next_active = faction_player_map[node.p];
+ if (next_active !== current_active && game.undo.length > 0) {
+ insert_before_active_node(create_leaf_node('confirm_turn', get_active_faction()));
+ game.state = 'confirm_turn';
+ return;
+ }
+ game.active = next_active;
}
}
-function resolve_active_node() {
+function resolve_active_node(checkpoint = false) {
const next_node = get_active_node(game.engine);
if (next_node !== null) {
next_node.r = resolved;
}
+ if (checkpoint) {
+ clear_undo();
+ }
}
-function resolve_active_and_proceed() {
- resolve_active_node();
+function resolve_active_and_proceed(checkpoint = false) {
+ resolve_active_node(checkpoint);
next();
}
function game_view(state, player) {
@@ -248,6 +261,7 @@ function game_view(state, player) {
tableaus: game.tableaus,
tracks: game.tracks,
triggered_track_effects: game.triggered_track_effects,
+ undo: game.undo,
used_medallions: game.used_medallions,
year: game.year,
};
@@ -791,6 +805,34 @@ states.choose_medallion = {
resolve_active_and_proceed();
},
};
+states.confirm_turn = {
+ inactive: 'confirm their turn',
+ prompt() {
+ view.prompt = 'Confirm your actions or undo';
+ gen_action('confirm');
+ },
+ confirm() {
+ resolve_active_and_proceed(true);
+ },
+};
+states.draw_card = {
+ inactive: 'draw a card',
+ prompt() {
+ const { v } = get_active_node_args();
+ view.prompt = v === 1 ? 'Draw a card' : `Draw ${v} cards`;
+ gen_action(v === 1 ? 'draw_card' : 'draw_cards');
+ },
+ draw_card() {
+ const { v } = get_active_node_args();
+ draw_hand_cards(get_active_faction(), v);
+ resolve_active_and_proceed();
+ },
+ draw_cards() {
+ const { v } = get_active_node_args();
+ draw_hand_cards(get_active_faction(), v);
+ resolve_active_and_proceed();
+ },
+};
states.end_of_year_discard = {
inactive: 'discard cards from hand and tableau',
prompt() {
@@ -947,7 +989,7 @@ states.player_turn = {
}
},
done() {
- resolve_active_and_proceed();
+ resolve_active_and_proceed(true);
},
play_for_ap() {
const faction_id = get_faction_id(game.active);
@@ -1137,14 +1179,6 @@ states.use_strategy_medallion = {
resolve_active_and_proceed();
},
};
-function pop_undo() {
- const save_log = game.log;
- const save_undo = game.undo;
- game = save_undo.pop();
- save_log.length = game.log;
- game.log = save_log;
- game.undo = save_undo;
-}
function add_glory(faction, amount, indent = false) {
for (let i = 0; i < amount; ++i) {
game.bag_of_glory.push(get_active_faction());
@@ -1560,7 +1594,14 @@ function resolve_effect(effect) {
if (effect.type === 'hero_points' && effect.target === data_1.SELF) {
state = 'gain_hero_points';
}
- return state === undefined ? null : create_leaf_node(state, faction, args);
+ if (effect.type === 'draw_card' && effect.target === data_1.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) {
log_br();
@@ -1625,11 +1666,6 @@ function log_h3(msg) {
log_br();
log('.h3 ' + msg);
}
-function clear_undo() {
- console.log('game clear undo', game?.undo);
- if (game?.undo && game.undo.length > 0)
- game.undo = [];
-}
function get_active_faction() {
return player_faction_map[game.active];
}
@@ -1724,25 +1760,6 @@ function make_list(first, last) {
list.push(i);
return list;
}
-function random(range) {
- return (game.seed = (game.seed * 200105) % 34359738337) % range;
-}
-function set_delete(set, item) {
- let a = 0;
- let b = set.length - 1;
- while (a <= b) {
- let m = (a + b) >> 1;
- let x = set[m];
- if (item < x)
- b = m - 1;
- else if (item > x)
- a = m + 1;
- else {
- array_remove(set, m);
- return;
- }
- }
-}
function list_deck(id) {
const deck = [];
const card_list = id === 'fascist' ? fascist_decks[game.year] : faction_cards[id];
@@ -1754,7 +1771,8 @@ function list_deck(id) {
else if (id !== 'fascist' &&
(game.hands[id].includes(card) ||
game.discard[id].includes(card) ||
- game.tableaus[id].includes(card))) {
+ game.tableaus[id].includes(card) ||
+ game.trash[id].includes(card))) {
return;
}
deck.push(card);
@@ -1770,6 +1788,67 @@ function draw_medallions() {
game.medallions.pool.push(r);
}
}
+function clear_undo() {
+ if (game.undo) {
+ game.undo.length = 0;
+ }
+}
+function push_undo() {
+ if (game.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);
+ }
+ return game.undo;
+}
+function pop_undo() {
+ if (game.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;
+ }
+ next();
+}
+function random(range) {
+ return (game.seed = (game.seed * 200105) % 34359738337) % range;
+}
+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;
+ }
+}
function array_remove(array, index) {
let n = array.length;
for (let i = index + 1; i < n; ++i)
@@ -1781,3 +1860,51 @@ function array_insert(array, index, item) {
array[i] = array[i - 1];
array[index] = item;
}
+function set_clear(set) {
+ set.length = 0;
+}
+function set_has(set, item) {
+ let a = 0;
+ let b = set.length - 1;
+ while (a <= b) {
+ const m = (a + b) >> 1;
+ const x = set[m];
+ if (item < x)
+ b = m - 1;
+ else if (item > x)
+ a = m + 1;
+ else
+ return true;
+ }
+ return false;
+}
+function set_add(set, item) {
+ let a = 0;
+ let b = set.length - 1;
+ while (a <= b) {
+ const m = (a + b) >> 1;
+ const x = set[m];
+ if (item < x)
+ b = m - 1;
+ else if (item > x)
+ a = m + 1;
+ else
+ return set;
+ }
+ return array_insert(set, a, item);
+}
+function set_delete(set, item) {
+ let a = 0;
+ let b = set.length - 1;
+ while (a <= b) {
+ const m = (a + b) >> 1;
+ const x = set[m];
+ if (item < x)
+ b = m - 1;
+ else if (item > x)
+ a = m + 1;
+ else
+ return array_remove(set, m);
+ }
+ return set;
+}