From 96e41fa9fa0e6cf564e85d93f768de26e9c32a17 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Sat, 27 Jul 2024 19:10:14 +0200 Subject: fix capture washington (at end of strategy card / activation) --- rules.js | 133 ++++++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 85 insertions(+), 48 deletions(-) diff --git a/rules.js b/rules.js index ea0992d..96763e2 100644 --- a/rules.js +++ b/rules.js @@ -123,6 +123,10 @@ function card_name(c) { return "\u201c" + CARDS[c].title + "\u201d" } +function colony_name(x) { + return data.colony_name[x] +} + function space_name(s) { return SPACES[s].name } @@ -442,6 +446,13 @@ function has_enemy_pc(space) { return has_british_pc(space) } +function has_friendly_pc(space) { + if (game.active !== P_BRITAIN) + return has_american_pc(space) + else + return has_british_pc(space) +} + function is_adjacent_to_british_pc(a) { for (let b of SPACES[a].adjacent) if (has_british_pc(b)) @@ -570,6 +581,13 @@ function has_enemy_cu(where) { return has_british_cu(where) } +function has_friendly_cu(where) { + if (game.active !== P_BRITAIN) + return has_american_or_french_cu(where) + else + return has_british_cu(where) +} + function count_unmoved_british_cu(where) { return count_british_cu(where) - map_get(game.mvcu, where * 3 + 0, 0) } @@ -710,6 +728,13 @@ function has_enemy_general(where) { return has_british_general(where) } +function has_friendly_general(where) { + if (game.active !== P_BRITAIN) + return has_american_or_french_general(where) + else + return has_british_general(where) +} + function count_friendly_generals(where) { let list if (game.active === P_BRITAIN) @@ -780,18 +805,19 @@ function capture_washington() { game.french_alliance = 0 } +console.log("CAPTURE WASHINGTON!!!") game.captured_washington = 1 } function capture_british_general(where) { let g = find_british_general(where) - log(g + " was captured!") + log(general_name(g) + " was captured!") move_general(g, CAPTURED_GENERALS) } function capture_american_or_french_general(where) { let g = find_american_or_french_general(where) - log(g + " was captured!") + log(general_name(g) + " was captured!") if (g === WASHINGTON) capture_washington() else @@ -993,7 +1019,7 @@ states.committees_of_correspondence = { if (game.colonies.length > 0) { view.prompt = "Committees of Correspondence: Place a PC marker in " if (game.colonies.length <= 3) - view.prompt += game.colonies.map(x=>data.colony_name[x]).join(" and ") + "." + view.prompt += game.colonies.map(colony_name).join(" and ") + "." else view.prompt += "each of the 13 colonies." gen_place_american_pc_in_colony(game.colonies) @@ -1449,20 +1475,20 @@ states.strategy_phase_event = { function end_strategy_card() { if (automatic_victory()) { clear_undo() - return + return false } if (game.captured_washington) { delete game.captured_washington goto_george_washington_captured() - return + return false } if (game.campaign) { if (--game.campaign > 0) { game.count = 3 // can activate any general! game.state = "ops_general_who" - return + return false } else { clear_flag(F_LANDING_PARTY) delete game.campaign @@ -1470,11 +1496,12 @@ function end_strategy_card() { } game.state = "end_strategy_card" + return true } function end_strategy_card_after_move() { - end_strategy_card() - next_strategy_card() + if (!end_strategy_card()) + next_strategy_card() } states.end_strategy_card = { @@ -2216,8 +2243,7 @@ function end_move(stop) { if (count_friendly_generals(where) > 1) goto_remove_general(where) else { - end_strategy_card() - if (stop) + if (end_strategy_card() && stop) next_strategy_card() } } @@ -2417,16 +2443,6 @@ function end_intercept() { /* RETREAT BEFORE BATTLE */ -function can_retreat_before_battle() { - if (game.move.did_intercept) - return false - // can't retreat if attempted (successful or not) interception! - let g = find_american_or_french_general(game.move.to) - if (g !== NOBODY && !has_general_moved(g)) - return true - return false -} - function goto_start_battle() { game.combat = { attacker: game.active, @@ -2443,6 +2459,36 @@ function goto_start_battle() { goto_play_attacker_battle_card() } +function can_retreat_before_battle() { + if (game.move.did_intercept) + return false + + let here = game.move.to + + // can't retreat if attempted (successful or not) interception! + let g = find_american_or_french_general(here) + if (g === NOBODY || has_general_moved(g)) + return false + + for (let to of SPACES[here].adjacent) + if (can_retreat_before_battle_to(to)) + return true + + return false +} + +function can_retreat_before_battle_to(to) { + if (to === game.move.from) + return false + if (has_friendly_pc(to)) + return false + if (has_friendly_cu(to)) + return false + if (is_lone && has_friendly_general(to)) + return false + return true +} + function goto_retreat_before_battle() { game.active = P_AMERICA game.state = "retreat_before_battle" @@ -3016,27 +3062,26 @@ function is_general_without_cu(s) { return has_british_general(s) && !has_british_cu(s) } +function is_not_fortified_port_without_british_cu(s) { + if (is_fortified_port(s)) + return has_british_cu(s) + return true +} + function gen_defender_retreat() { let here = game.move.to let is_lone = is_general_without_cu(here) let can_retreat = false + for (let to of SPACES[here].adjacent) { if (can_defender_retreat(to, is_lone)) { gen_action_space(to) can_retreat = true } } + if (game.active === P_BRITAIN) { - let can_sea_retreat = false - if (is_non_blockaded_port(here)) { - if (is_fortified_port(here)) { - if (has_british_pc(here) && is_non_blockaded_port(here)) - can_sea_retreat = true - } else { - can_sea_retreat = true - } - } - if (can_sea_retreat) { + if (is_non_blockaded_port(here) && is_not_fortified_port_without_british_cu(here)) { for (let to of all_spaces) { if (to !== game.move.from && is_non_blockaded_port(to)) { if (!has_american_pc(to) && !has_american_or_french_cu(to)) { @@ -3047,6 +3092,7 @@ function gen_defender_retreat() { } } } + if (!can_retreat) view.actions.surrender = 1 } @@ -3256,7 +3302,7 @@ events.remove_british_pc_from = function (c, card) { states.remove_british_pc_from = { prompt() { - view.prompt = "Remove British PC markers from " + game.where.map(x=>data.colony_name[x]).join(", ") + ". " + game.count + " left." + view.prompt = "Remove British PC markers from " + game.where.map(colony_name).join(", ") + ". " + game.count + " left." view.actions.pass = 1 for (let colony of game.where) for (let space of COLONIES[colony]) @@ -3314,7 +3360,7 @@ events.remove_american_pc_from = function (c, card) { states.remove_american_pc_from = { prompt() { - view.prompt = "Remove American PC markers from " + game.where.join(", ") + ". " + game.count + " left." + view.prompt = "Remove American PC markers from " + game.where.map(colony_name).join(", ") + ". " + game.count + " left." for (let colony of game.where) for (let space of COLONIES[colony]) if (has_american_pc(space) && has_no_american_unit(space)) @@ -3345,7 +3391,7 @@ events.remove_american_pc_from_non_port = function (c, card) { states.remove_american_pc_from_non_port = { prompt() { - view.prompt = "Remove American PC markers from non-Port space in " + game.where.join(", ") + ". " + game.count + " left." + view.prompt = "Remove American PC markers from non-Port space in " + game.where.map(colony_name).join(", ") + ". " + game.count + " left." for (let colony of game.where) { for (let space of COLONIES[colony]) { if (!is_port(space)) { @@ -3647,16 +3693,8 @@ function end_declaration_of_independence() { } function goto_george_washington_captured() { - // TODO: this is not robust enough! figure out exactly where we are called. - - /* Save all the state we clobber during the interrupt. */ - game.save = { - state: game.state, - active: game.active, - count: game.count - } - game.state = "george_washington_captured" + game.save = game.active game.active = P_BRITAIN game.count = 5 } @@ -3670,22 +3708,21 @@ states.george_washington_captured = { view.actions.pass = 1 }, space(where) { + push_undo() remove_pc(where) - if (--game.count === 0) { + if (--game.count === 0) end_george_washington_captured() - } }, pass() { + push_undo() end_george_washington_captured() }, } function end_george_washington_captured() { - /* Restore previous state. */ - game.state = game.save.state - game.count = game.save.count - game.active = game.save.active + game.active = game.save delete game.save + end_strategy_card() } function do_event(c) { -- cgit v1.2.3