From 24611a0d96685296c0704c54e1abfccd608ff739 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Sat, 28 Sep 2024 21:34:34 +0200 Subject: Special case Quebec-Falmouth for Arnold move/intercept/retreat only. --- rules.js | 91 +++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 26 deletions(-) (limited to 'rules.js') diff --git a/rules.js b/rules.js index d393351..261d41d 100644 --- a/rules.js +++ b/rules.js @@ -56,6 +56,7 @@ const NORFOLK = data.space_index["Norfolk"] const PHILADELPHIA = data.space_index["Philadelphia"] const QUEBEC = data.space_index["Quebec"] const WILMINGTON_NC = data.space_index["Wilmington"] +const CONCORD = data.space_index["Concord"] const CAPTURED_GENERALS = data.space_index["Captured Generals"] const CONTINENTAL_CONGRESS_DISPERSED = data.space_index["Continental Congress Dispersed"] @@ -109,6 +110,19 @@ function general_name(s) { return GENERALS[s].name } +const arnold_quebec_adjacent = [ MONTREAL, FALMOUTH ] +const arnold_falmouth_adjacent = [ QUEBEC, CONCORD, BOSTON ] + +function get_adjacent_for_move(s, who) { + if (who === ARNOLD) { + if (s === QUEBEC) + return arnold_quebec_adjacent + if (s === FALMOUTH) + return arnold_falmouth_adjacent + } + return SPACES[s].adjacent +} + /* SETUP */ function setup_game(seed) { @@ -2357,6 +2371,8 @@ function end_move(stop) { } function path_type(from, to) { + if ((from === QUEBEC && to === FALMOUTH) || (to === QUEBEC && from === FALMOUTH)) + return "wilderness" if (set_has(SPACES[from].path, to)) return "path" if (set_has(SPACES[from].wilderness, to)) @@ -2397,20 +2413,13 @@ function movement_cost(from, to) { } } -function is_quebec_falmouth_path(from, to) { - return (from === QUEBEC && to === FALMOUTH) || (to === QUEBEC && from === FALMOUTH) -} - function gen_move_general() { let from = location_of_general(game.move.who) let alone = game.move.carry_british + game.move.carry_american + game.move.carry_french === 0 - for (let to of SPACES[from].adjacent) { + for (let to of get_adjacent_for_move(from, game.move.who)) { let mp = 1 - if (path_type(from, to) === "wilderness") { - if (is_quebec_falmouth_path(from, to) && game.move.who !== ARNOLD) - continue + if (path_type(from, to) === "wilderness") mp = 3 - } if (alone) { if (has_enemy_cu(to)) @@ -2451,11 +2460,13 @@ function gen_move_general() { /* INTERCEPT */ function can_intercept_to(to) { - for (let space of SPACES[to].adjacent) { - if (has_american_army(space)) { - let g = find_american_or_french_general(space) - if (is_quebec_falmouth_path(to, space) && g !== ARNOLD) - continue + if (to === QUEBEC && find_american_or_french_general(FALMOUTH) === ARNOLD && has_american_or_french_cu(FALMOUTH)) + return true + if (to === FALMOUTH && find_american_or_french_general(QUEBEC) === ARNOLD && has_american_or_french_cu(QUEBEC)) + return true + for (let from of SPACES[to].adjacent) { + if (has_american_army(from)) { + let g = find_american_or_french_general(from) if (g !== NOBODY && !has_general_moved(g)) return true } @@ -2463,12 +2474,16 @@ function can_intercept_to(to) { return false } -function gen_intercept() { - for (let space of SPACES[game.move.to].adjacent) { - if (has_american_army(space)) { - let g = find_american_or_french_general(space) - if (is_quebec_falmouth_path(game.move.to, space) && g !== ARNOLD) - continue +function gen_intercept(to) { + if (!has_general_moved(ARNOLD)) { + if (to === QUEBEC && find_american_or_french_general(FALMOUTH) === ARNOLD && has_american_or_french_cu(FALMOUTH)) + gen_action_general(ARNOLD) + if (to === FALMOUTH && find_american_or_french_general(QUEBEC) === ARNOLD && has_american_or_french_cu(QUEBEC)) + gen_action_general(ARNOLD) + } + for (let from of SPACES[game.move.to].adjacent) { + if (has_american_army(from)) { + let g = find_american_or_french_general(from) if (g !== NOBODY && !has_general_moved(g)) gen_action_general(g) } @@ -2486,7 +2501,7 @@ states.intercept_who = { prompt() { view.prompt = "Intercept " + general_name(game.move.who) + " at " + space_name(game.move.to) + "?" view.actions.pass = 1 - gen_intercept() + gen_intercept(game.move.to) }, general(g) { push_undo() @@ -2583,6 +2598,15 @@ function can_retreat_before_battle() { if (g === NOBODY || has_general_moved(g)) return false + if (g === ARNOLD) { + if (here === FALMOUTH) + if (can_retreat_before_battle_to(g, here, QUEBEC)) + return true + if (here === QUEBEC) + if (can_retreat_before_battle_to(g, here, FALMOUTH)) + return true + } + for (let to of SPACES[here].adjacent) if (can_retreat_before_battle_to(g, here, to)) return true @@ -2591,8 +2615,6 @@ function can_retreat_before_battle() { } function can_retreat_before_battle_to(g, from, to) { - if (is_quebec_falmouth_path(from, to) && g !== ARNOLD) - return false if (to === game.move.from) return false if (has_friendly_pc(to)) @@ -3127,8 +3149,6 @@ function resolve_battle() { /* RETREAT AFTER BATTLE */ function can_defender_retreat(g, from, to, is_lone) { - if (is_quebec_falmouth_path(from, to) && g !== ARNOLD) - return false if (to === game.move.from) return false if (has_enemy_pc(to)) @@ -3144,8 +3164,12 @@ function can_attacker_retreat() { let g = game.move.who let from = game.move.to let to = game.move.from - if (is_quebec_falmouth_path(from, to) && g !== ARNOLD) + + if (from === FALMOUTH && to == QUEBEC && g !== ARNOLD) + return false + if (from === QUEBEC && to == FALMOUTH && g !== ARNOLD) return false + if (has_enemy_pc(to)) return false if (has_enemy_cu(to)) @@ -3179,6 +3203,21 @@ function gen_defender_retreat() { view.selected_general = g + if (g === ARNOLD) { + if (here === FALMOUTH) { + if (can_defender_retreat(g, here, QUEBEC, is_lone)) { + gen_action_space(QUEBEC) + can_retreat = true + } + } + if (here === QUEBEC) { + if (can_defender_retreat(g, here, FALMOUTH, is_lone)) { + gen_action_space(FALMOUTH) + can_retreat = true + } + } + } + for (let to of SPACES[here].adjacent) { if (can_defender_retreat(g, here, to, is_lone)) { gen_action_space(to) -- cgit v1.2.3