From f21b40df81c695a0adf05e1d8107956d8fd918ab Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Mon, 18 Jul 2022 17:00:11 +0200 Subject: iterators and undisrupted --- rules.js | 209 +++++++++++++++++++++++++++++++++------------------------------ 1 file 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) }) -- cgit v1.2.3