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. --- data.js | 12 ++------ rules.js | 91 +++++++++++++++++++++++++++++++++++++++---------------- tools/layout.json | 9 ------ tools/layout.svg | 46 ++++++++++++---------------- 4 files changed, 88 insertions(+), 70 deletions(-) diff --git a/data.js b/data.js index ec8ea3f..dcfe949 100644 --- a/data.js +++ b/data.js @@ -297,15 +297,12 @@ const data = { "name": "Quebec", "type": "fortified_port", "adjacent": [ - 1, - 31 + 1 ], "path": [ 1 ], - "wilderness": [ - 31 - ], + "wilderness": [], "port": 0, "colony": 0, "x": 1163, @@ -845,7 +842,6 @@ const data = { "name": "Falmouth", "type": "regular", "adjacent": [ - 3, 7, 29 ], @@ -853,9 +849,7 @@ const data = { 7, 29 ], - "wilderness": [ - 3 - ], + "wilderness": [], "port": 1, "colony": 3, "x": 1374, 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) diff --git a/tools/layout.json b/tools/layout.json index e2c4c2d..22c7cdb 100644 --- a/tools/layout.json +++ b/tools/layout.json @@ -2358,15 +2358,6 @@ "name": null, "name1": "Bassett Town", "name2": "Point Pleasant" - }, - { - "x1": 1196, - "y1": 127, - "x2": 1346.2935, - "y2": 418.71331, - "name": "Quebec-Falmouth", - "name1": "Quebec", - "name2": "Falmouth" } ], "sea": [ diff --git a/tools/layout.svg b/tools/layout.svg index 629e3c4..bb910e7 100644 --- a/tools/layout.svg +++ b/tools/layout.svg @@ -40,10 +40,10 @@ inkscape:window-height="480" id="namedview8" showgrid="false" - inkscape:zoom="1.9957644" - inkscape:cx="1218.7481" - inkscape:cy="710.99692" - inkscape:current-layer="g2117" + inkscape:zoom="1.2135381" + inkscape:cx="1256.2877" + inkscape:cy="352.6483" + inkscape:current-layer="g2128" inkscape:snap-center="false" inkscape:snap-others="true" inkscape:snap-object-midpoints="true" @@ -55,27 +55,27 @@ + sodipodi:insensitive="true" + image-rendering="pixelated" + height="2550" + width="1650" + y="0" + x="0" /> + style="display:inline" + id="image4" + opacity="0.535871" + image-rendering="pixelated" + height="2550" + width="1650" + y="0" + x="0" /> -