summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data.js2
-rw-r--r--play.js1
-rw-r--r--rules.js390
-rw-r--r--tools/gendata.js3
4 files changed, 131 insertions, 265 deletions
diff --git a/data.js b/data.js
index ffff2e5..f4766ba 100644
--- a/data.js
+++ b/data.js
@@ -1,6 +1,6 @@
const all_hexes = [7,8,9,10,30,31,32,33,34,35,36,37,38,39,40,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215]
const hex_exists = [0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0]
-const hex_road = [0,0,0,0,0,0,0,4,4,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,1,1,4,2,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,1,1,1,1,2,1,1,2,2,1,1,4,1,4,2,4,4,2,4,4,0,0,0,2,1,2,2,2,1,0,1,1,1,1,1,0,1,0,2,0,0,0,2,0,0,0,0,0,1,1,0,1,1,0,1,0,0,1,1,1,1,0,2,0,0,0,2,0,0,0,0,0,0,1,1,1,0,0,1,0,0,0,1,1,1,1,2,0,0,0,0,0,0,0,0,0,4,1,1,0,0,0,1,0,0,0,0,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0]
+const hex_road = [0,0,0,0,0,0,0,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,4,4,1,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,4,4,1,1,2,2,2,4,4,2,4,4,4,4,4,4,4,4,4,4,4,0,0,0,4,2,2,2,2,2,0,1,2,2,2,2,0,1,0,2,0,0,0,2,0,0,0,0,0,4,2,0,1,1,0,1,0,0,1,2,1,1,0,2,0,0,0,2,0,0,0,0,0,0,4,1,1,0,0,1,0,0,0,1,1,1,1,2,0,0,0,0,0,0,0,0,0,4,4,1,0,0,0,1,0,0,0,0,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,1,1,1,1,1,1,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0]
const side_road = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,4,4,0,0,4,0,4,0,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,4,4,0,4,4,0,0,0,0,0,0,0,1,4,1,2,4,4,0,4,2,0,4,0,4,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,4,1,0,1,1,0,0,1,0,0,2,1,2,2,0,2,2,1,0,4,2,1,2,2,0,2,0,0,4,2,1,4,0,1,4,0,0,4,0,1,4,0,0,4,0,2,4,0,0,4,0,0,4,2,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,0,2,0,0,2,0,2,2,0,0,0,0,0,0,0,1,0,0,0,1,0,1,2,0,0,2,1,0,2,1,0,0,1,2,0,0,0,0,0,1,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,0,0,1,2,0,0,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
const side_limit = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,1,0,1,1,0,0,0,0,0,0,0,1,2,2,2,1,1,0,1,2,2,2,2,2,2,2,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,1,0,2,1,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,1,2,0,0,2,0,2,2,0,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,0,0,0,0,0,0,0,0,0,1,2,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,2,0,1,0,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,2,2,2,2,2,0,0,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
const hex_name = {"7":"El Garib","8":"Cyrene","9":"El Gubba","10":"Derna","30":"Tocra","31":"Barce","32":"Marawa","33":"Wadi Cuff","34":"Wadi Cuff E","35":"Gazala","36":"Acroma","37":"Tobruk","38":"Belhamed","39":"Gambut","40":"Bardia","54":"Benghazi","55":"Er Regima","56":"Charruba","57":"Charruba E","58":"Mechili","59":"Rotonda Segnali","60":"Sidi Mufta","61":"Bir Harmat","62":"El Adem","63":"Sidi Rezegh","64":"Ft. Capuzzo","65":"Sollum","66":"Buq Buq","67":"Sidi Barrani","68":"Sidi Barrani E","69":"Mersa Matruh","70":"Fuka","71":"El Daba","72":"El Alamein","73":"El Hamam","74":"Alexandria","78":"Ghemines","79":"Skeleidima","80":"Msus","81":"Msus E","82":"Tengeder W","83":"Tengeder","84":"Tengeder E","85":"Bir Hacheim","86":"Retma","87":"Bir Gubi","88":"Gabr Saleh","89":"Sidi Omar","90":"Bir Habata","91":"Sofafi","92":"Sofafi E","93":"Bir el Kenayis","94":"Bir Khalda","95":"Bir Khalda E","96":"Alam Halfa W","97":"Alam Halfa","98":"Alam Halfa E","103":"Beda Fomm","104":"Antelat","105":"Antelat E","106":"Ben Gania","107":"Ben Gania E","108":"Tengeder SE","109":"Bir Hacheim SW","110":"Bir Hacheim SE","111":"Retma SE","112":"Ft. Maddalena W","113":"Ft. Maddalena","114":"Ft. Maddalena E","115":"Bir Khamsa","116":"Bir el Qatrani","117":"Bir el Qatrani E","118":"Bir el Kenayis SE","119":"Bir Khalda SE","120":"El Himeimat W","121":"El Himeimat","122":"El Himeimat E","128":"Agedabia","129":"Jebel el Matar","130":"Haraga","131":"Haraga E","137":"Ft. Maddalena SW","138":"Ft. Maddalena SE","139":"Bir Khamsa SW","140":"Bir Fuad W","141":"Bir Fuad","142":"Bir Fuad E","151":"El Agheila","152":"Mersa Brega","153":"El Haseiat","154":"El Haseiat E","155":"Haraga SE","162":"Jarabub Oasis NW","163":"Jarabub Oasis NE","165":"Bir Fuad SW","166":"Bir Fuad SE","176":"Maaten Giofer","177":"Maaten Giofer E","178":"Sahaba","179":"Sahaba E","180":"Jalo Oasis NE","186":"Jarabub Oasis W","187":"Jarabub Oasis","188":"Jarabub Oasis E","189":"Siwa Oasis NE","200":"Maaten Giofer SW","201":"Maaten Giofer SE","202":"Sahaba SW","203":"Jalo Oasis W","204":"Jalo Oasis","205":"Jalo Oasis E","211":"Jarabub Oasis SW","212":"Siwa Oasis W","213":"Siwa Oasis","214":"Siwa Oasis E"}
diff --git a/play.js b/play.js
index 09df861..d495750 100644
--- a/play.js
+++ b/play.js
@@ -599,7 +599,6 @@ function on_update() {
action_button("overrun", "Overrun")
action_button("rommel", "Rommel")
- action_button("stop", "Stop")
action_button("retreat", "Retreat")
action_button("partial_retreat", "Partial retreat")
diff --git a/rules.js b/rules.js
index 1da88b5..ad38289 100644
--- a/rules.js
+++ b/rules.js
@@ -957,52 +957,63 @@ function print_path(who, from, to, road) {
log(">" + p.join(" - ") + ".")
}
-function search_move(start, start_cost, start_road) {
- // recon=4, forced march=+1, rommel bonus=+1
- let limit = 6
-
+function search_init() {
path_enemy.fill(0)
- for (let u = 0; u < units.length; ++u) {
- if (is_enemy_unit(u)) {
- let x = unit_hex(u)
- if (x >= first_hex && x <= last_hex)
- path_enemy[x] = 1
- }
- }
-
- search_move_bfs(path_from[0], path_cost[0], start, start_cost, 0, limit)
- if (start_road >= 1)
- search_move_bfs(path_from[1], path_cost[1], start, start_cost, 1, limit + 1)
- if (start_road >= 2)
- search_move_bfs(path_from[2], path_cost[2], start, start_cost, 2, limit + 2)
- if (start_road >= 4)
- search_move_bfs(path_from[4], path_cost[4], start, start_cost, 4, limit + 4)
-
- let grid = new Array(hexcount).fill('-')
- for (let x = first_hex; x <= last_hex; ++x) {
- for (let speed = 4; speed >= 1; --speed) {
- if (path_cost[0][x] <= speed)
- grid[x] = speed
- if (path_cost[1][x] <= speed + 1)
- grid[x] = speed
- if (path_cost[2][x] <= speed + 2)
- grid[x] = speed
- if (path_cost[4][x] <= speed + 4)
- grid[x] = speed
- }
- }
- grid[start] = '@'
+ for_each_enemy_unit(u => {
+ let x = unit_hex(u)
+ if (x >= first_hex && x <= last_hex)
+ path_enemy[x] = 1
+ })
+}
- debug_hexes2("reach", path_cost[0])
+function search_move(start, limit) {
+ // Normal moves.
+ search_init()
+ search_move_bfs(path_from[0], path_cost[0], start, 0, limit)
+ if (hex_road[start] >= 1)
+ search_move_bfs(path_from[1], path_cost[1], start, 1, limit + 1)
+ if (hex_road[start] >= 2)
+ search_move_bfs(path_from[2], path_cost[2], start, 2, limit + 2)
+ if (hex_road[start] >= 4)
+ search_move_bfs(path_from[4], path_cost[4], start, 4, limit + 4)
+}
+
+function search_retreat(start, limit) {
+ // (Non-withdrawal) Retreat moves may not cross enemy hex-sides, and may not engage.
+ search_init()
+ search_retreat_bfs(path_from[0], path_cost[0], start, 0, limit)
+ if (hex_road[start] >= 1)
+ search_retreat_bfs(path_from[1], path_cost[1], start, 1, limit + 1)
+ if (hex_road[start] >= 2)
+ search_retreat_bfs(path_from[2], path_cost[2], start, 2, limit + 2)
+ if (hex_road[start] >= 4)
+ search_retreat_bfs(path_from[4], path_cost[4], start, 4, limit + 4)
+}
+
+function search_withdraw(start, limit) {
+ // Withdrawal moves may not cross enemy hex-sides,
+ // and must follow a supply line,
+ // and must move closer to the supply source,
+ // and may not engage.
+ let sline = game.active === AXIS ? game.axis_supply_line : game.allied_supply_line
+ let sdist = game.active === AXIS ? distance_to[EL_AGHEILA] : distance_to[ALEXANDRIA]
+ search_init()
+ search_withdraw_bfs(path_from[0], path_cost[0], start, 0, limit, sline, sdist)
+ if (hex_road[start] >= 1)
+ search_withdraw_bfs(path_from[1], path_cost[1], start, 1, limit + 1, sline, sdist)
+ if (hex_road[start] >= 2)
+ search_withdraw_bfs(path_from[2], path_cost[2], start, 2, limit + 2, sline, sdist)
+ if (hex_road[start] >= 4)
+ search_withdraw_bfs(path_from[4], path_cost[4], start, 4, limit + 4, sline, sdist)
}
// Breadth First Search
-function search_move_bfs(from, cost, start, start_cost, road, max_cost) {
- let queue = [ start << 4 | start_cost ]
+function search_move_bfs(from, cost, start, road, max_cost) {
+ let queue = [ start << 4 ]
from.fill(0)
cost.fill(15)
- cost[start] = start_cost
+ cost[start] = 0
while (queue.length > 0) {
let item = queue.shift()
@@ -1050,45 +1061,6 @@ function search_move_bfs(from, cost, start, start_cost, road, max_cost) {
}
}
-function search_withdraw(start, is_pass_move) {
- // recon=4, forced march=+1, rommel bonus=+1
- let limit = is_pass_move ? 6 : 4
-
- path_enemy.fill(0)
- for (let u = 0; u < units.length; ++u) {
- if (is_enemy_unit(u)) {
- let x = unit_hex(u)
- if (x >= first_hex && x <= last_hex)
- path_enemy[x] = 1
- }
- }
-
- let sline = game.active === AXIS ? game.axis_supply_line : game.allied_supply_line
- let sdist = game.active === AXIS ? distance_to[EL_AGHEILA] : distance_to[ALEXANDRIA]
-
- search_withdraw_bfs(path_from[0], path_cost[0], start, 0, limit, sline, sdist)
- search_withdraw_bfs(path_from[1], path_cost[1], start, 1, limit + 1, sline, sdist)
- search_withdraw_bfs(path_from[2], path_cost[2], start, 2, limit + 2, sline, sdist)
- search_withdraw_bfs(path_from[4], path_cost[4], start, 4, limit + 4, sline, sdist)
-
- let grid = new Array(hexcount).fill('-')
- for (let x = first_hex; x <= last_hex; ++x) {
- for (let speed = 4; speed >= 1; --speed) {
- if (path_cost[0][x] <= speed)
- grid[x] = speed
- if (path_cost[1][x] <= speed + 1)
- grid[x] = speed
- if (path_cost[2][x] <= speed + 2)
- grid[x] = speed
- if (path_cost[4][x] <= speed + 4)
- grid[x] = speed
- }
- }
- grid[start] = '@'
-
- debug_hexes2("reach", path_cost[0])
-}
-
// Breadth First Search
function search_withdraw_bfs(from, cost, start, road, max_cost, sline, sdist) {
let queue = [ start << 4 ]
@@ -1143,39 +1115,24 @@ function search_withdraw_bfs(from, cost, start, road, max_cost, sline, sdist) {
}
}
-// TODO: search_retreat where first hexside exit is restricted to friendly
-
-function can_move_to(to, road, speed) {
- // TODO: engagement & hexside limit
- if (road >= 4 && path_cost[4][to] <= speed + 4)
+function can_move_to(to, speed) {
+ if (path_cost[4][to] <= speed + 4)
return true
- if (road >= 2 && path_cost[2][to] <= speed + 2)
+ if (path_cost[2][to] <= speed + 2)
return true
- if (road >= 1 && path_cost[1][to] <= speed + 1)
+ if (path_cost[1][to] <= speed + 1)
return true
if (path_cost[0][to] <= speed)
return true
return false
}
-function can_move_from(from, road, speed) {
- // TODO: engagement & hexside limit
- return can_move_to(from, road, speed)
+function can_move_from(from, speed) {
+ return can_move_to(from, speed)
}
-function can_force_march_to(to, road, speed) {
- if (road >= 4 && path_cost[4][to] <= speed + 5)
- return true
- if (road >= 2 && path_cost[2][to] <= speed + 3)
- return true
- if (road >= 1 && path_cost[1][to] <= speed + 2)
- return true
- if (path_cost[0][to] <= speed + 1)
- return true
- return false
-}
-
-function pick_path(to, road, speed) {
+function pick_path(to, speed) {
+ let road = 4
let next_cost = 15, next_road = 0
if (path_cost[0][to] <= speed) {
next_cost = path_cost[0][to]
@@ -1223,12 +1180,13 @@ function max_speed_of_undisrupted_friendly_unit_in_hex(from) {
}
function find_valid_regroup_destinations(from, rommel) {
+ // TODO: forced march
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)
+ search_move(from, speed + rommel)
+ for (let x of all_hexes)
if (!path_valid[x])
- if (can_move_to(x, 4, speed + rommel))
+ if (can_move_to(x, speed + rommel))
path_valid[x] = 1
}
}
@@ -1302,7 +1260,7 @@ function goto_initial_supply_check() {
}
function clear_all_unit_moved() {
- game.moved.length = 0
+ set_clear(game.moved)
}
function goto_turn_option() {
@@ -1464,11 +1422,12 @@ states.regroup_move_destination = {
cp = game.from1, rommel = (game.rommel === 1 ? 1 : 0)
else
cp = game.from2, rommel = (game.rommel === 2 ? 1 : 0)
+
path_valid.fill(0)
for_each_hex_and_adjacent_hex(cp, x => {
find_valid_regroup_destinations(x, rommel)
})
- for (let x = first_hex; x <= last_hex; ++x)
+ for (let x of all_hexes)
if (path_valid[x])
gen_action_hex(x)
},
@@ -1492,6 +1451,47 @@ states.regroup_move_destination = {
},
}
+function end_move_phase() {
+ game.side_limit = {}
+ game.rommel = 0
+ game.from1 = game.from2 = game.to1 = game.to2 = 0
+ // TODO: forced marches
+ goto_refuse_battle()
+}
+
+// === GROUP AND REGROUP MOVEMENT ===
+
+function unit_speed_1(who) {
+ return unit_speed(who) + (game.rommel === 1 ? 1 : 0)
+}
+
+function unit_speed_2(who) {
+ return unit_speed(who) + (game.rommel === 2 ? 1 : 0)
+}
+
+function gen_group_move_who(may_retreat, from) {
+ if (may_retreat !== is_battle_hex(from))
+ return
+ for_each_undisrupted_friendly_unit_in_hex(from, u => {
+ if (!is_unit_moved(u))
+ gen_action_unit(u)
+ })
+}
+
+function gen_regroup_move_who(may_retreat, command_point, destination, rommel) {
+ search_move(destination, 4 + rommel)
+ for_each_hex_and_adjacent_hex(command_point, x => {
+ if (x !== destination) {
+ if (may_retreat !== is_battle_hex(x))
+ return
+ for_each_undisrupted_friendly_unit_in_hex(x, u => {
+ if (!is_unit_moved(u) && can_move_from(x, unit_speed(u) + rommel))
+ gen_action_unit(u)
+ })
+ }
+ })
+}
+
function goto_move_who() {
if (game.rommel === 1) {
if (game.from1 && game.to1)
@@ -1516,33 +1516,9 @@ function goto_move_who() {
log(`Group move from #${game.from2}.`)
}
log_br()
- log("Moved:")
game.state = 'move_who'
}
-function gen_group_move_who(may_retreat, from) {
- if (may_retreat !== is_battle_hex(from))
- return
- for_each_undisrupted_friendly_unit_in_hex(from, u => {
- if (!is_unit_moved(u))
- gen_action_unit(u)
- })
-}
-
-function gen_regroup_move_who(may_retreat, command_point, destination, rommel) {
- search_move(destination, 0, 4)
- for_each_hex_and_adjacent_hex(command_point, x => {
- if (x !== destination) {
- if (may_retreat !== is_battle_hex(x))
- return
- 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)
- })
- }
- })
-}
-
states.move_who = {
inactive: "move (who)",
prompt() {
@@ -1567,8 +1543,6 @@ states.move_who = {
push_undo()
game.selected = [ who ]
game.state = 'move_to'
- game.move_used = 0
- game.move_road = 4
},
retreat() {
push_undo()
@@ -1582,26 +1556,15 @@ states.move_who = {
}
}
-function end_move_phase() {
- game.side_limit = {}
- game.rommel = 0
- game.from1 = game.from2 = game.to1 = game.to2 = 0
- // TODO: forced marches
- goto_refuse_battle()
-}
-
function apply_move(move, who, from, to) {
- let speed = unit_speed(who) + (move === game.rommel ? 1 : 0)
- let road = pick_path(to, game.move_road, speed)
-
- print_path(who, unit_hex(who), to, road)
-
- game.move_road = road
- game.move_used = path_cost[road][to]
+ let rommel = (game.rommel === move ? 1 : 0)
+ let road = pick_path(to, unit_speed(who) + rommel)
set_unit_moved(who)
set_unit_hex(who, to)
+ log(`>from #${from} to #${to}`)
+
if (is_battle_hex(to)) {
let side = to_side_id(to, path_from[road][to])
@@ -1617,19 +1580,6 @@ function apply_move(move, who, from, to) {
}
return true
}
-
- if (game.move_used === speed + game.move_road)
- return true
-
- return false
-}
-
-function unit_speed_1(who) {
- return unit_speed(who) + (game.rommel === 1 ? 1 : 0)
-}
-
-function unit_speed_2(who) {
- return unit_speed(who) + (game.rommel === 2 ? 1 : 0)
}
function can_move_regroup_1(who, from, to) {
@@ -1648,14 +1598,14 @@ function can_move_regroup_2(who, from, to) {
function can_move_group_1(who, from, to) {
if (from === game.from1 && !game.to1)
- if (can_move_to(to, game.move_road, unit_speed_1(who)))
+ if (can_move_to(to, unit_speed_1(who)))
return true
return false
}
function can_move_group_2(who, from, to) {
if (from === game.from2 && !game.to2)
- if (can_move_to(to, game.move_road, unit_speed_2(who)))
+ if (can_move_to(to, unit_speed_2(who)))
return true
return false
}
@@ -1666,8 +1616,9 @@ states.move_to = {
view.prompt = `Move: Select where to move.`
let who = game.selected[0]
let from = unit_hex(who)
+ let maybe_rommel = 1
- search_move(from, 0, 4)
+ search_move(from, unit_speed(who) + maybe_rommel)
if (from === game.from1 && !game.to1)
for (let to of all_hexes)
@@ -1694,102 +1645,26 @@ states.move_to = {
push_undo()
let who = game.selected[0]
let from = unit_hex(who)
+ let maybe_rommel = 1
- search_move(from, 0, 4)
+ search_move(from, unit_speed(who) + maybe_rommel)
- if (can_move_group_1(who, from, to)) {
- game.move_from = from
- if (apply_move(1, who, from, to))
- stop_move(who)
- else
- game.state = 'group_move_to'
- return
- }
-
- if (can_move_group_2(who, from, to)) {
- game.move_from = from
- if (apply_move(2, who, from, to))
- stop_move(who)
- else
- game.state = 'group_move_to'
- return
+ if (has_enemy_unit(to)) {
+ log("TODO: pick hex-side")
}
- if (can_move_regroup_1(who, from, to)) {
+ if (can_move_group_1(who, from, to))
apply_move(1, who, from, to)
- stop_move(who)
- game.state = 'move_who'
- return
- }
-
- if (can_move_regroup_2(who, from, to)) {
+ if (can_move_group_2(who, from, to))
+ apply_move(2, who, from, to)
+ if (can_move_regroup_1(who, from, to))
+ apply_move(1, who, from, to)
+ if (can_move_regroup_2(who, from, to))
apply_move(2, who, from, to)
- stop_move(who)
- game.state = 'move_who'
- return
- }
- },
-}
-
-states.group_move_to = {
- inactive: "group move (to)",
- prompt() {
- view.prompt = `Group Move: Select where to move.`
- let who = game.selected[0]
- let from = unit_hex(who)
- if (game.move_used > 0)
- gen_action('stop')
-
- search_move(from, game.move_used, game.move_road)
-
- if (game.move_from === game.from1 && !game.to1)
- for (let to of all_hexes)
- if (to != from && can_move_group_1(who, game.move_from, to))
- gen_action_hex(to)
-
- if (game.move_from === game.from2 && !game.to2)
- for (let to of all_hexes)
- if (to != from && can_move_group_2(who, game.move_from, to))
- gen_action_hex(to)
-
- gen_action_unit(who)
- },
- unit(who) {
- this.stop()
- },
- hex(to) {
- let who = game.selected[0]
- let from = unit_hex(who)
-
- search_move(from, game.move_used, game.move_road)
-
- if (can_move_group_1(who, game.move_from, to)) {
- log(`group continued ${who} to ${to}`)
- if (apply_move(1, who, from, to))
- stop_move(who)
- return
- }
- if (can_move_group_2(who, game.move_from, to)) {
- log(`group continued ${who} to ${to}`)
- if (apply_move(2, who, from, to))
- stop_move(who)
- return
- }
+ game.state = 'move_who'
+ game.selected.length = 0
},
- stop() {
- let who = game.selected[0]
- stop_move(who)
- }
-}
-
-function stop_move(who) {
- set_unit_moved(who)
- game.move_from = 0
- game.move_road = 4
- game.move_used = 0
- game.selected = []
- game.state = 'move_who'
}
// === RETREAT ===
@@ -1948,13 +1823,14 @@ states.retreat_to = {
prompt() {
view.prompt = `Retreat: Select destination.`
let who = game.selected[0]
+ let from = game.retreat
gen_action_unit(who)
if (game.turn_option === 'pass') {
- search_withdraw(game.retreat, true)
+ search_withdraw(from, true)
} else {
- search_retreat(game.retreat)
+ search_retreat(from)
}
if (from === game.from1 && !game.to1)
@@ -2382,11 +2258,6 @@ function end_battle() {
end_combat_phase()
}
-function end_probe() {
- game.battle = 0
- resume_retreat()
-}
-
// === PURSUIT FIRE ===
// Refuse battle
@@ -3144,11 +3015,6 @@ exports.setup = function (seed, scenario, options) {
from2: 0,
to2: 0,
- // current group move state
- move_from: 0,
- move_used: 0,
- move_road: 4,
-
// retreat
partial_retreats: [], // remember partial retreats to forbid initiating combat
retreat: 0,
diff --git a/tools/gendata.js b/tools/gendata.js
index a963248..1af2356 100644
--- a/tools/gendata.js
+++ b/tools/gendata.js
@@ -56,7 +56,8 @@ function def_side(t,a,b) {
function def_road(t, list) {
for (let i = 0; i < list.length; ++i)
- hex_road[list[i]] = t;
+ if (t > hex_road[list[i]])
+ hex_road[list[i]] = t;
for (let i = 1; i < list.length; ++i) {
let s = to_side_id(list[i-1], list[i]);
side_road[s] = t;