summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2024-10-16 21:30:07 +0200
committerTor Andersson <tor@ccxvii.net>2024-10-16 22:38:19 +0200
commita64246a8df40773167afd6820a3c7ae54acf1a68 (patch)
treec5207058c38be9eecb1c10d9bf87bcfb95f80b5f
parent4beb78140f7d71ca546c30bada088390b1cecb26 (diff)
downloadmaria-a64246a8df40773167afd6820a3c7ae54acf1a68.tar.gz
place hussars
-rw-r--r--play.js13
-rw-r--r--rules.js133
2 files changed, 128 insertions, 18 deletions
diff --git a/play.js b/play.js
index 60b1690..1c08fbd 100644
--- a/play.js
+++ b/play.js
@@ -41,8 +41,9 @@ const ELIMINATED_TRAIN_DX = 33
const ELIMINATED_GENERAL_X = 340
const ELIMINATED_GENERAL_Y = 110
const ELIMINATED_GENERAL_DX = 50
-const ELIMINATED_DISC_X = 340 + 75
-const ELIMINATED_DISC_Y = 240
+
+const HUSSAR_X = 2190
+const HUSSAR_Y = 1630
const power_class = [ "france", "bavaria", "prussia", "saxony", "pragmatic", "austria" ]
const power_name = [ "France", "Bavaria", "Prussia", "Saxony", "Pragmatic", "Austria" ]
@@ -726,16 +727,16 @@ function layout_hussar(id, s) {
ui.pieces_element.appendChild(e)
if (s === ELIMINATED) {
- x = ELIMINATED_DISC_X
- y = ELIMINATED_DISC_Y
+ x = HUSSAR_X
+ y = HUSSAR_Y
n = id - 30
} else {
x = data.cities.x[s]
y = data.cities.y[s]
}
- e.style.left = (x - 21) + "px"
- e.style.top = (y - 29 + 7 - n * 8) + "px"
+ e.style.left = (x - 21 + n * ELIMINATED_GENERAL_DX) + "px"
+ e.style.top = (y - 29 + 7) + "px"
e.classList.toggle("selected", set_has(view.selected, id))
}
diff --git a/rules.js b/rules.js
index 0c602ad..28415a6 100644
--- a/rules.js
+++ b/rules.js
@@ -1,5 +1,11 @@
"use strict"
+// TODO: game.selected - singleton instead of array
+
+// TODO: austria/pragmatic action step - show both sides cards and interleave movement on flanders map
+// PLAN: move all austria on bohemia first, then alternate pragmatic and austria activations on flanders map
+// TODO: confirm mixed stack creation on flanders map (force "undo" to previous location if denied?)
+
const R_LOUIS_XV = "Louis XV"
const R_FREDERICK = "Frederick"
const R_MARIA_THERESA = "Maria Theresa"
@@ -16,6 +22,18 @@ var states = {}
const data = require("./data")
+function is_bohemia_space(s) {
+ return s >= 0 && s <= 401
+}
+
+function is_flanders_space(s) {
+ return s >= 402 && s <= 618
+}
+
+function is_map_space(s) {
+ return s >= 0 && s <= 618
+}
+
function find_city(city) {
let n = data.cities.name.length
let x = -1
@@ -218,6 +236,20 @@ function all_non_coop_powers(pow) {
}
}
+function all_coop_generals(pow) {
+ switch (pow) {
+ case P_FRANCE:
+ case P_BAVARIA:
+ return all_france_bavaria_generals
+ case P_PRUSSIA:
+ case P_SAXONY:
+ return all_prussia_saxony_generals
+ case P_PRAGMATIC:
+ case P_AUSTRIA:
+ return all_austria_pragmatic_generals
+ }
+}
+
function all_controlled_generals(pow) {
switch (pow) {
case P_FRANCE:
@@ -662,7 +694,7 @@ function goto_start_turn() {
// MARIA: politics
// MARIA: hussars
- goto_action_stage()
+ goto_place_hussars()
}
function goto_action_stage() {
@@ -693,6 +725,83 @@ function check_victory() {
return false
}
+/* HUSSARS */
+
+function goto_place_hussars() {
+ set_active_to_power(P_AUSTRIA)
+ game.state = "place_hussars"
+}
+
+function end_place_hussars() {
+ set_clear(game.moved)
+ goto_action_stage()
+}
+
+states.place_hussars = {
+ inactive: "place Hussars",
+ prompt() {
+ prompt("Place the Hussars.")
+ for (let p of all_hussars)
+ if (!set_has(game.moved, p))
+ gen_action_piece(p)
+ view.actions.next = 1
+ },
+ piece(p) {
+ push_undo()
+ set_add(game.moved, p)
+ game.selected = p
+ game.state = "place_hussars_where"
+ },
+ next() {
+ end_place_hussars()
+ },
+}
+
+states.place_hussars_where = {
+ inactive: "place Hussars",
+ prompt() {
+ prompt("Place the Hussar in a city.")
+ view.selected = game.selected
+
+ // bohemia
+ // within 4 of an austrian general
+ // not occupied by any piece
+ for (let p of all_power_generals[P_AUSTRIA]) {
+ let s = game.pos[p]
+ if (is_bohemia_space(s))
+ for (let x of search_hussar_bfs(s))
+ gen_action_space(x)
+ }
+ },
+ space(to) {
+ game.state = "place_hussars"
+ game.pos[game.selected] = to
+ game.selected = -1
+ },
+}
+
+function search_hussar_bfs(from) {
+ let seen = [ from ]
+ let queue = [ from << 4 ]
+ while (queue.length > 0) {
+ let item = queue.shift()
+ let here = item >> 4
+ let dist = (item & 15) + 1
+ for (let next of data.cities.adjacent[here]) {
+ if (set_has(seen, next))
+ continue
+ if (!is_bohemia_space(next))
+ continue
+ if (!has_any_piece(next))
+ set_add(seen, next)
+ if (dist < 4)
+ queue.push((next << 4) | dist)
+ }
+ }
+ set_delete(seen, from)
+ return seen
+}
+
/* TACTICAL CARDS */
function find_largest_discard(u) {
@@ -1071,16 +1180,6 @@ function move_general_to(to) {
game.pos[p] = to
}
- // uniting stacks (turn all oos if one is oos)
- let oos = false
- for (let p of all_controlled_generals(game.power))
- if (game.pos[p] === to && is_out_of_supply(p))
- oos = true
- if (oos)
- for (let p of all_controlled_generals(game.power))
- if (game.pos[p] === to)
- set_out_of_supply(p)
-
// conquer space
if (is_conquest_space(pow, from) && !set_has(game.conquest, from)) {
if (is_protected_from_conquest(from)) {
@@ -1113,13 +1212,23 @@ function move_general_to(to) {
}
// uniting stacks: flag all as moved and stop moving
- for (let p of all_controlled_generals(pow)) {
+ for (let p of all_coop_generals(pow)) {
if (game.pos[p] === to && !set_has(game.selected, p)) {
set_add(game.moved, p)
stop = true
}
}
+ // remove hussars
+ for (let p of all_hussars) {
+ if (game.pos[p] === to) {
+ if (!game.move_elim)
+ game.move_elim = []
+ set_add(game.move_elim, p)
+ game.pos[p] = ELIMINATED
+ }
+ }
+
return stop
}