summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rules.js71
1 files 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')
},