summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rules.js209
1 files changed, 110 insertions, 99 deletions
diff --git a/rules.js b/rules.js
index bf8832c..7519ebd 100644
--- a/rules.js
+++ b/rules.js
@@ -1,6 +1,7 @@
"use strict"
// TODO: partial moves during regroup (to allow deciding entry hex-side)
+// TODO: first_friendly_unit / for_each_friendly_unit
// unit state: location (8 bits), supply source (3 bits), steps (2 bits), disrupted (1 bit)
@@ -14,6 +15,13 @@ var view = null
let { all_hexes, hex_exists, hex_road, side_road, side_limit, hex_name, units, regions } = require("./data")
+const first_axis_unit = 0
+const first_allied_unit = units.findIndex(item => item.nationality === 'allied')
+const last_axis_unit = first_allied_unit - 1
+const last_allied_unit = units.length - 1
+
+console.log("FOO", first_axis_unit, last_axis_unit, first_allied_unit, last_allied_unit)
+
function debug_hexes3(n, list) {
console.log("--", n, "--")
list = list.map((x,i) => hex_exists[i] ? x : "")
@@ -75,7 +83,6 @@ const FIREPOWER_MATRIX = [
[ SF, DF, DF, SF ],
]
-
const CLEAR = 2
const PASS = 1
const ROUGH = 0
@@ -357,98 +364,82 @@ function is_axis_unit(u) {
// === MAP STATE ===
+function has_axis_unit(x) {
+ for (let u = first_axis_unit; u <= last_axis_unit; ++u)
+ if (unit_hex(u) === x)
+ return true
+ return false
+}
+
+function has_allied_unit(x) {
+ for (let u = first_allied_unit; u <= last_allied_unit; ++u)
+ if (unit_hex(u) === x)
+ return true
+ return false
+}
+
+function has_undisrupted_axis_unit(x) {
+ for (let u = first_axis_unit; u <= last_axis_unit; ++u)
+ if (!is_unit_disrupted(u) && unit_hex(u) === x)
+ return true
+ return false
+}
+
+function has_undisrupted_allied_unit(x) {
+ for (let u = first_allied_unit; u <= last_allied_unit; ++u)
+ if (!is_unit_disrupted(u) && unit_hex(u) === x)
+ return true
+ return false
+}
+
function is_axis_hex(x) {
- if (!hex_exists[x])
- return false
- let has_axis = false, has_allied = false
- for (let u = 0; u < units.length; ++u) {
- if (unit_hex(u) === x) {
- if (is_axis_unit(u))
- has_axis = true
- else
- has_allied = true
- }
- }
+ let has_axis = has_axis_unit(x)
+ let has_allied = has_allied_unit(x)
return has_axis && !has_allied
}
function is_allied_hex(x) {
- if (!hex_exists[x])
- return false
- let has_axis = false, has_allied = false
- for (let u = 0; u < units.length; ++u) {
- if (unit_hex(u) === x) {
- if (is_axis_unit(u))
- has_axis = true
- else
- has_allied = true
- }
- }
+ let has_axis = has_axis_unit(x)
+ let has_allied = has_allied_unit(x)
return !has_axis && has_allied
}
function is_battle_hex(x) {
- if (!hex_exists[x])
- return false
- let has_axis = false, has_allied = false
- for (let u = 0; u < units.length; ++u) {
- if (unit_hex(u) === x) {
- if (is_axis_unit(u))
- has_axis = true
- else
- has_allied = true
- }
- }
+ let has_axis = has_axis_unit(x)
+ let has_allied = has_allied_unit(x)
return has_axis && has_allied
}
function is_empty_hex(x) {
- if (!hex_exists[x])
- return false
- let has_axis = false, has_allied = false
- for (let u = 0; u < units.length; ++u) {
- if (unit_hex(u) === x) {
- if (is_axis_unit(u))
- has_axis = true
- else
- has_allied = true
- }
- }
+ let has_axis = has_axis_unit(x)
+ let has_allied = has_allied_unit(x)
return !has_axis && !has_allied
}
-function has_axis_unit(x) {
- if (!hex_exists[x])
- return false
- for (let u = 0; u < units.length; ++u)
- if (unit_hex(u) === x)
- if (is_axis_unit(u))
- return true
- return false
-}
-
-function has_allied_unit(x) {
- if (!hex_exists[x])
- return false
- for (let u = 0; u < units.length; ++u)
- if (unit_hex(u) === x)
- if (is_allied_unit(u))
- return true
- return false
-}
-
function has_friendly_unit(x) {
if (game.active === AXIS)
return has_axis_unit(x)
return has_allied_unit(x)
}
+function has_undisrupted_friendly_unit(x) {
+ if (game.active === AXIS)
+ return has_undisrupted_axis_unit(x)
+ return has_undisrupted_allied_unit(x)
+}
+
function has_enemy_unit(x) {
if (game.active === ALLIED)
return has_axis_unit(x)
return has_allied_unit(x)
}
+function has_undisrupted_enemy_unit(x) {
+ if (game.active === ALLIED)
+ return has_undisrupted_axis_unit(x)
+ return has_undisrupted_allied_unit(x)
+}
+
function claim_hexside_control(side) {
if (game.active === AXIS) {
set_add(game.axis_sides, side)
@@ -994,11 +985,11 @@ function pick_path(to, road, speed) {
return next_road
}
-function adjacent_hex_has_friendly_unit(here) {
+function adjacent_hex_has_undisrupted_friendly_unit(here) {
for (let s = 0; s < 6; ++s) {
let next = here + hexnext[s]
if (is_map_hex(next))
- if (has_friendly_unit(next))
+ if (has_undisrupted_friendly_unit(next))
return true
}
return false
@@ -1022,14 +1013,36 @@ function for_each_hex_and_adjacent_hex(here, fn) {
}
function for_each_friendly_unit_in_hex(x, fn) {
+ // TODO: first/last_enemy_unit
for (let u = 0; u < units.length; ++u)
if (is_friendly_unit(u) && unit_hex(u) === x)
fn(u)
}
-function max_speed_of_friendly_unit_in_hex(from) {
+function for_each_undisrupted_friendly_unit_in_hex(x, fn) {
+ // TODO: first/last_enemy_unit
+ for (let u = 0; u < units.length; ++u)
+ if (is_friendly_unit(u) && !is_unit_disrupted(u) && unit_hex(u) === x)
+ fn(u)
+}
+
+function for_each_enemy_unit_in_hex(x, fn) {
+ // TODO: first/last_enemy_unit
+ for (let u = 0; u < units.length; ++u)
+ if (is_enemy_unit(u) && unit_hex(u) === x)
+ fn(u)
+}
+
+function for_each_undisrupted_enemy_unit_in_hex(x, fn) {
+ // TODO: first/last_enemy_unit
+ for (let u = 0; u < units.length; ++u)
+ if (is_enemy_unit(u) && !is_unit_disrupted(u) && unit_hex(u) === x)
+ fn(u)
+}
+
+function max_speed_of_undisrupted_friendly_unit_in_hex(from) {
let max = 0
- for_each_friendly_unit_in_hex(from, u => {
+ for_each_undisrupted_friendly_unit_in_hex(from, u => {
let s = unit_speed(u)
if (s > max)
max = s
@@ -1038,7 +1051,7 @@ function max_speed_of_friendly_unit_in_hex(from) {
}
function find_valid_regroup_destinations(from, rommel) {
- let speed = max_speed_of_friendly_unit_in_hex(from)
+ let speed = max_speed_of_undisrupted_friendly_unit_in_hex(from)
if (speed > 0) {
search_move(from, 0, 4)
for (let x = first_hex; x <= last_hex; ++x)
@@ -1188,7 +1201,7 @@ states.group_move_from = {
for (let x = first_hex; x <= last_hex; ++x) {
if (x === game.from1 && !game.to1)
continue
- if (has_friendly_unit(x))
+ if (has_undisrupted_friendly_unit(x))
gen_action_hex(x)
}
},
@@ -1219,7 +1232,7 @@ states.regroup_move_command_point = {
gen_rommel_move()
for (let x = first_hex; x <= last_hex; ++x) {
if (!is_enemy_hex(x)) {
- if (has_friendly_unit(x) || adjacent_hex_has_friendly_unit(x))
+ if (has_undisrupted_friendly_unit(x) || adjacent_hex_has_undisrupted_friendly_unit(x))
gen_action_hex(x)
}
}
@@ -1306,7 +1319,7 @@ function goto_move_who() {
}
function gen_group_move_who(from) {
- for_each_friendly_unit_in_hex(from, u => {
+ for_each_undisrupted_friendly_unit_in_hex(from, u => {
if (!is_unit_moved(u))
gen_action_unit(u)
})
@@ -1316,7 +1329,7 @@ function gen_regroup_move_who(command_point, destination, rommel) {
search_move(destination, 0, 4)
for_each_hex_and_adjacent_hex(command_point, x => {
if (x !== destination) {
- for_each_friendly_unit_in_hex(x, u => {
+ for_each_undisrupted_friendly_unit_in_hex(x, u => {
if (!is_unit_moved(u) && can_move_from(x, 4, unit_speed(u) + rommel))
gen_action_unit(u)
})
@@ -1630,7 +1643,7 @@ states.refuse_battle_who = {
prompt() {
view.prompt = `Withdraw: Select unit to move.`
let done = true
- for_each_friendly_unit_in_hex(game.from1, u => {
+ for_each_undisrupted_friendly_unit_in_hex(game.from1, u => {
gen_action_unit(u)
done = false
})
@@ -1761,21 +1774,20 @@ const xxx_fire = {
view.prompt = `Fire!`
let arty = false
- for (let u = 0; u < units.length; ++u) {
- if (is_friendly_unit(u) && !is_unit_fired(u) && unit_hex(u) === game.battle) {
- if (is_artillery_unit(u)) {
+ for_each_undisrupted_friendly_unit_in_hex(game.battle, u => {
+ if (is_artillery_unit(u)) {
+ if (!is_unit_fired(u)) {
gen_action_unit(u)
arty = true
}
}
- }
+ })
if (!arty) {
- for (let u = 0; u < units.length; ++u) {
- if (is_friendly_unit(u) && !is_unit_fired(u) && unit_hex(u) === game.battle) {
+ for_each_undisrupted_friendly_unit_in_hex(game.battle, u => {
+ if (!is_unit_fired(u))
gen_action_unit(u)
- }
- }
+ })
}
},
unit(who) {
@@ -1802,9 +1814,9 @@ function count_elite_steps_in_battle() {
function count_hp_in_battle() {
let hp = [ 0, 0, 0, 0 ]
- for (let u = 0; u < units.length; ++u)
- if (is_enemy_unit(u) && unit_hex(u) === game.battle)
- hp[unit_class(u)] += unit_hp(u)
+ for_each_undisrupted_enemy_unit_in_hex(game.battle, u => {
+ hp[unit_class(u)] += unit_hp(u)
+ })
return hp
}
@@ -1905,7 +1917,7 @@ const xxx_fire_hits = {
let elite_steps = count_elite_steps_in_battle()
let done = true
- for_each_friendly_unit_in_hex(game.battle, u => {
+ for_each_undisrupted_friendly_unit_in_hex(game.battle, u => {
let c = unit_class(u)
if (is_unit_elite(u)) {
if (game.hits[c] >= 2) {
@@ -1966,9 +1978,10 @@ function fire_at(firing, tc) {
function resume_fire() {
game.state = game.state.replace("_target", "")
let done = true
- for (let u = 0; u < units.length; ++u)
- if (is_friendly_unit(u) && !is_unit_fired(u) && unit_hex(u) === game.battle)
+ for_each_undisrupted_friendly_unit_in_hex(game.battle, u => {
+ if (!is_unit_fired(u))
done = false
+ })
if (done)
goto_fire_hits()
}
@@ -2023,15 +2036,13 @@ function goto_pursuit_fire() {
game.hits = 0
}
-function slowest_enemy_unit_speed(where) {
+function slowest_undisrupted_enemy_unit_speed(where) {
let r = 4
- for (let u = 0; u < units.length; ++u) {
- if (is_enemy_unit(u) && unit_hex(u) === where) {
- let s = unit_speed(u)
- if (s < r)
- r = s
- }
- }
+ for_each_undisrupted_enemy_unit_in_hex(where, u => {
+ let s = unit_speed(u)
+ if (s < r)
+ r = s
+ })
return r
}
@@ -2048,8 +2059,8 @@ states.pursuit_fire = {
inactive: "pursuit fire (fire)",
prompt() {
view.prompt = `Pursuit Fire.`
- let slowest = slowest_enemy_unit_speed(game.pursuit)
- for_each_friendly_unit_in_hex(game.pursuit, u => {
+ let slowest = slowest_undisrupted_enemy_unit_speed(game.pursuit)
+ for_each_undisrupted_friendly_unit_in_hex(game.pursuit, u => {
if (unit_speed(u) >= slowest && !is_unit_fired(u))
gen_action_unit(u)
})