summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--rules.js241
1 files changed, 4 insertions, 237 deletions
diff --git a/rules.js b/rules.js
index 297ae2b..5c3f646 100644
--- a/rules.js
+++ b/rules.js
@@ -16,6 +16,8 @@
// TODO: for_each_exit -> flat list of all exits
// TODO: retreats with no survivors
+// TODO: johnson and mohawks if subcommander!
+// TODO: select leader for defense instead of automatically picking
// TODO: flat force definition - use sum of leader command rating
// (only allow dropping subordinate if stacking limit allows)
@@ -1883,7 +1885,7 @@ function update_vp(name, s) {
game[name] = v;
}
-// PATH FINDING
+// SUPPLY LINES
function search_supply_spaces_imp(queue) {
console.log("======");
@@ -1964,242 +1966,7 @@ function is_in_supply(space) {
return x;
}
-function list_intercept_spaces(is_lone_ld, is_lone_ax) {
- let intercept = {};
-
- // 6.723 Leaders moving alone can NOT be intercepted
- if (is_lone_ld)
- return intercept;
-
- console.log("INTERCEPT SEARCH is_lone_ax", is_lone_ax, "is_lone_ld", is_lone_ld);
-
- for (let from = first_space; from <= last_space; ++from) {
- if (has_unbesieged_enemy_units(from)) {
- console.log("INTERCEPT FROM", space_name(from));
-
- // 6.721 exception -- can always intercept units infiltrating same space
- // TODO: infiltration
- // intercept[from] = 3;
-
- for_each_exit(from, to => {
- // 6.722
- if (has_unbesieged_friendly_units(to))
- return;
- if (has_unbesieged_friendly_fortifications(to))
- return;
-
- // 6.721
- if (is_lone_ax && is_wilderness_or_mountain(to)) {
- if (has_unbesieged_enemy_auxiliary(from)) {
- console.log("INTERCEPT TO", space_name(to), "(lone ax)");
- intercept[to] = 2;
- }
- } else {
- console.log("INTERCEPT TO", space_name(to));
- intercept[to] = 1;
- }
- });
- }
- }
-
- return intercept;
-}
-
-// Use Breadth First Search to find all paths.
-
-function pq_push(queue, item, prio) {
- // TODO: reprioritize if item is already in the queue
- for (let i = 0, n = queue.length; i < n; ++i)
- if (queue[i].prio > prio)
- return queue.splice(i, 0, [prio, item]);
- queue.push([prio, item])
-}
-
-function pq_pop(queue) {
- return queue.shift()[1];
-}
-
-function search_boat_move(who, start_space, start_cost, max_cost) {
- let move_cost = game.move.cost = {};
- let move_path = game.move.path = {};
-
- if (start_cost >= max_cost)
- return;
-
- let queue = [];
- pq_push(queue, start_space, 0);
- move_cost[start_space] = start_cost;
- move_path[start_space] = null;
-
- const is_lone_ld = is_lone_leader(who);
- const is_lone_ax = is_lone_auxiliary(who);
- const has_dt = force_has_drilled_troops(who);
-
- while (queue.length > 0) {
- let current = pq_pop(queue);
- let c_cost = move_cost[current];
- let c_ff = has_friendly_fortifications(current) || is_originally_friendly(current);
- for_each_exit(current, (next, connection) => {
- let n_ff = has_friendly_fortifications(next) || is_originally_friendly(next);
- let n_cost = c_cost + 2;
- let must_stop = false;
-
- // TODO: check actual MP required to reach safe space
- let may_infiltrate = is_lone_ax && n_cost < max_cost;
-
- if (connection === 'land') {
- if (c_ff && n_ff && (c_cost & 1) === 0) {
- n_cost += 1;
- } else {
- return; // Not a usable land connection
- }
- }
-
- // Must stop on entering interception space
- if (next in game.move.intercept)
- must_stop = true;
-
- // Must stop on entering enemy occupied spaces
- if (has_unbesieged_enemy_units(next)) {
- if (is_lone_ld)
- return; // Lone leaders can never enter an enemy occupied space
- if (may_infiltrate)
- game.move.infiltrate[next] = 1;
- must_stop = true; // May continue if over-run
- }
-
- if (has_enemy_stockade(next)) {
- if (may_infiltrate)
- game.move.infiltrate[next] = 1;
- else
- n_cost = 18; // may not continue
- }
-
- if (has_unbesieged_enemy_fort_or_fortress(next)) {
- if (may_infiltrate) {
- game.move.infiltrate[next] = 1;
- } else {
- if (!has_dt)
- return; // Must have Drilled Troops to enter an enemy fort or fortress space.
- n_cost = 18; // may not continue
- }
- }
-
- // Stop when entering a space with a lone enemy leader(s) to force a retreat
- if (!is_lone_ld && has_unbesieged_enemy_leader(next))
- must_stop = true; // May continue after retreat
-
- // No movement points left.
- if (n_cost >= max_cost)
- must_stop = true;
-
- console.log("SEARCH BOAT MOVE", space_name(current), ">", space_name(next), c_cost, n_cost, c_ff, n_ff);
-
- if (!(next in move_cost) || (n_cost < move_cost[next])) {
- move_cost[next] = n_cost;
- move_path[next] = current;
- if (!must_stop)
- pq_push(queue, next, n_cost);
- }
-
- });
- }
-}
-
-function search_land_move(who, start_space, start_cost, max_cost) {
- let move_cost = game.move.cost = {};
- let move_path = game.move.path = {};
-
- if (start_cost >= max_cost)
- return;
-
- let queue = [];
- pq_push(queue, start_space, 0);
- move_cost[start_space] = start_cost;
- move_path[start_space] = null;
-
- const is_lone_ld = is_lone_leader(who);
- const is_lone_ax = is_lone_auxiliary(who);
- const has_dt = force_has_drilled_troops(who);
- const has_ax = force_has_auxiliary_unit(who);
-
- while (queue.length > 0) {
- let current = pq_pop(queue);
- let c_cost = move_cost[current];
- let c_ff = has_friendly_fortifications(current);
- for_each_exit(current, (next, connection) => {
- let n_ff = has_friendly_fortifications(next);
- let n_cost = c_cost + 1;
- let must_stop = false;
-
- // TODO: check actual MP required to reach safe space
- let may_infiltrate = is_lone_ax && n_cost < max_cost;
-
- // Must stop on mountains.
- if (is_mountain(next) && !n_ff)
- n_cost = 9; // may not continue
-
- // Must stop in the next space after passing through...
- if (current !== game.move.start_space && !c_ff) {
- // Drilled Troops that pass through wilderness must stop in the next space.
- if (has_dt && !has_ax && is_wilderness(current))
- if (!game.events.george_croghan)
- n_cost = 9; // may not continue
-
- // Auxiliaries that pass through enemy cultivated must stop in the next space.
- if (has_ax && !has_dt && is_originally_enemy(current))
- n_cost = 9; // may not continue
- }
-
- // Must stop on entering interception space
- if (next in game.move.intercept)
- must_stop = true;
-
- // Must stop on entering enemy occupied spaces
- if (has_unbesieged_enemy_units(next)) {
- if (is_lone_ld)
- return; // Lone leaders can never enter an enemy occupied space
- if (may_infiltrate)
- game.move.infiltrate[next] = 1;
- must_stop = true; // May continue if over-run
- }
-
- if (has_enemy_stockade(next)) {
- if (may_infiltrate)
- game.move.infiltrate[next] = 1;
- else
- n_cost = 9; // may not continue
- }
-
- if (has_unbesieged_enemy_fort_or_fortress(next)) {
- if (may_infiltrate) {
- game.move.infiltrate[next] = 1;
- } else {
- if (!has_dt)
- return; // Must have Drilled Troops to enter an enemy fort or fortress space.
- n_cost = 9; // may not continue
- }
- }
-
- // Stop when entering a space with a lone enemy leader(s) to force a retreat
- if (!is_lone_ld && has_unbesieged_enemy_leader(next))
- must_stop = true; // May continue after retreat
-
- // No movement points left.
- if (n_cost >= max_cost)
- must_stop = true;
-
- console.log("SEARCH LAND MOVE", space_name(current), ">", space_name(next), c_cost, n_cost, must_stop, game.move.infiltrate[next]);
-
- if (!(next in move_cost) || (n_cost < move_cost[next])) {
- move_cost[next] = n_cost;
- move_path[next] = current;
- if (!must_stop)
- pq_push(queue, next, n_cost);
- }
- });
- }
-}
+// CLOSEST PATH SEARCH
function find_closest_friendly_unbesieged_fortification(start) {
let queue = [];