From c75f43589d83938727603be46a971c049a6946de Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Tue, 26 Jul 2022 20:28:38 +0200 Subject: retreat rework --- rules.js | 71 +++++++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/rules.js b/rules.js index 3f4afab..c3e7fb5 100644 --- a/rules.js +++ b/rules.js @@ -1129,6 +1129,7 @@ function search_move_retreat(start, speed) { } function search_withdraw(start, speed) { + // TODO: who+bonus instead of start+speed update_supply_networks() let sline = is_axis_player() ? game.axis_supply_line : game.allied_supply_line let sdist = is_axis_player() ? distance_to[EL_AGHEILA] : distance_to[ALEXANDRIA] @@ -1141,6 +1142,7 @@ function search_withdraw(start, speed) { } function search_withdraw_retreat(start, speed) { + // TODO: who+bonus instead of start+speed update_supply_networks() let sline = is_axis_player() ? game.axis_supply_line : game.allied_supply_line let sdist = is_axis_player() ? distance_to[EL_AGHEILA] : distance_to[ALEXANDRIA] @@ -1983,9 +1985,19 @@ function move_unit(who, to, speed) { // === RETREAT === -// TODO: check each unit separately to deal with fortress supply +function friendly_unit_supply_line(who) { + update_supply_networks() + return is_axis_player() ? game.axis_supply_line : game.allied_supply_line +} + +function friendly_unit_supply_distance(who) { + return is_axis_player() ? distance_to[EL_AGHEILA] : distance_to[ALEXANDRIA] +} -function can_disengage_and_withdraw(from, sline, sdist) { +function can_unit_disengage_and_withdraw(who) { + let sline = friendly_unit_supply_line(who) + let sdist = friendly_unit_supply_distance(who) + let from = unit_hex(who) let result = false for_each_adjacent_hex(from, to => { let side = to_side_id(from, to) @@ -1996,6 +2008,15 @@ function can_disengage_and_withdraw(from, sline, sdist) { return result } +function can_all_disengage_and_withdraw(from) { + let result = true + for_each_undisrupted_friendly_unit_in_hex(from, u => { + if (result && !can_unit_disengage_and_withdraw(u)) + result = false + }) + return result +} + function can_disengage_and_move(from) { let result = false for_each_adjacent_hex(from, to => { @@ -2006,40 +2027,39 @@ function can_disengage_and_move(from) { return result } -function can_retreat_with_group_move(from, sline, sdist) { +function can_retreat_with_group_move(from) { if (!is_battle_hex(from) || set_has(game.partial_retreats, from)) return false - if (game.turn_option === 'pass') { - // no partial retreats! - if (has_undisrupted_and_moved_friendly_unit_in_hex(from)) - return false - return can_disengage_and_withdraw(from, sline, sdist) - } else { + + if (game.turn_option === 'pass') + return can_all_disengage_and_withdraw(from) + else return can_disengage_and_move(from) - } +} + +function can_all_disengage_and_move_to(from) { + let result = true + for_each_undisrupted_friendly_unit_in_hex(from, u => { + if (result && !can_unit_disengage_and_withdraw(u)) + result = false + }) + return result } function can_retreat_with_regroup_move(from, to, rommel) { if (!is_battle_hex(from) || set_has(game.partial_retreats, from)) return false + let speed = max_speed_of_undisrupted_and_unmoved_friendly_unit_in_hex(from) if (game.turn_option === 'pass') search_withdraw_retreat(from, speed + rommel) else search_move_retreat(from, speed + rommel) - let result = 0 - for_each_undisrupted_friendly_unit_in_hex(from, u => { - if (can_move_to(to, unit_speed(u) + rommel) && !is_unit_moved(u)) - result |= 1 - else - result |= 2 - }) - if (game.turn_option === 'pass') - return result === 1 + return can_all_disengage_and_move_to(from, to, rommel) else - return result === 1 || result === 3 + return can_any_disengage_and_move_to(from, to, rommel) } function can_select_retreat_hex() { @@ -2050,11 +2070,11 @@ function can_select_retreat_hex() { let rommel2 = (game.rommel === 2) ? 1 : 0 if (!game.to1 && game.from1) - if (can_retreat_with_group_move(game.from1, sline, sdist)) + if (can_retreat_with_group_move(game.from1) return true if (!game.to2 && game.from2) - if (can_retreat_with_group_move(game.from2, sline, sdist)) + if (can_retreat_with_group_move(game.from2) return true if (game.to1) { @@ -2307,13 +2327,8 @@ states.refuse_battle = { inactive: "refuse battle", prompt() { view.prompt = `You may Refuse Battle.` - - update_supply_networks() - let sline = is_axis_player() ? game.axis_supply_line : game.allied_supply_line - let sdist = is_axis_player() ? distance_to[EL_AGHEILA] : distance_to[ALEXANDRIA] - for (let x of game.active_battles) - if (can_disengage_and_withdraw(x, sline, sdist)) + if (can_all_disengage_and_withdraw(x)) gen_action_hex(x) gen_action('next') }, -- cgit v1.2.3