summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2023-03-06 13:52:13 +0100
committerTor Andersson <tor@ccxvii.net>2023-05-03 18:48:15 +0200
commit14891230a45429c396c0731cd7737e4b8b9b4e88 (patch)
treebf62f4644657a5695e9455bc06f2f9f0c2ecbbad
parent2d66908b20d43a39974f99a0ec74212eaa5031ed (diff)
downloadandean-abyss-14891230a45429c396c0731cd7737e4b8b9b4e88.tar.gz
LimOp Patrol.
-rw-r--r--play.css5
-rw-r--r--rules.js97
2 files changed, 87 insertions, 15 deletions
diff --git a/play.css b/play.css
index f0c5d60..e284d0b 100644
--- a/play.css
+++ b/play.css
@@ -10,7 +10,6 @@ main { background-color: #777; }
#role_AUC_\+_Cartels { background-image: linear-gradient(135deg, khaki 30%, darkseagreen 70%) }
#log { background-color: whitesmoke; }
-#log > div { padding-left: 20px; text-indent: -12px; }
#log .h1 { background-color: silver; font-weight: bold; padding-top:4px; padding-bottom:4px; }
#log .h2 { background-color: gainsboro; padding-top:2px; padding-bottom:2px; }
#log .h2.govt { background-color: #c6d1eb }
@@ -21,6 +20,10 @@ main { background-color: #777; }
#log .tip { cursor: pointer; }
#log .tip:hover { text-decoration: underline; }
+#log div { padding-left: 20px; text-indent: -12px; }
+#log div.i { padding-left: 32px; text-indent: -12px; }
+#log div.ii { padding-left: 44px; text-indent: -12px; }
+
.action { cursor: pointer }
.role.active span { text-decoration: underline; }
diff --git a/rules.js b/rules.js
index 8dd00a4..c78342b 100644
--- a/rules.js
+++ b/rules.js
@@ -50,6 +50,8 @@ const last_loc = data.last_loc
const first_foreign = data.first_foreign
const last_foreign = data.last_foreign
+const path_seen = new Array(last_space+1).fill(0)
+
// Sequence of Play options
const ELIGIBLE = 0
const SOP_1ST_OP_ONLY = 1
@@ -949,10 +951,7 @@ states.op = {
view.prompt = "Choose an Operation."
if (game.current === GOVT) {
view.actions.train = 1
- if (game.op.free || game.resources[game.current] >= 3)
- view.actions.patrol = 1
- else
- view.actions.patrol = 0
+ view.actions.patrol = 1
if (is_final_card())
view.actions.sweep = 0
else
@@ -978,6 +977,10 @@ states.op = {
push_undo()
log_h3("Patrol")
goto_patrol()
+ if (game.op.free)
+ goto_patrol()
+ else
+ game.state = "patrol_pay"
},
sweep() {
push_undo()
@@ -1021,7 +1024,7 @@ function gen_operation_common() {
}
function can_select_op_space(cost) {
- if (!game.free && game.resources[game.current] < cost)
+ if (!game.op.free && game.resources[game.current] < cost)
return false
if (game.op.limited)
return game.op.spaces.length === 0
@@ -1034,7 +1037,7 @@ function is_selected_op_space(s) {
function select_op_space(s, cost) {
set_add(game.op.spaces, s)
- if (!game.free)
+ if (!game.op.free)
game.resources[game.current] -= cost
}
@@ -1210,36 +1213,102 @@ states.train_civic = operation({
// OPERATION: PATROL
+states.patrol_pay = operation({
+ prompt() {
+ view.prompt = "Patrol: Pay 3 resources."
+ gen_action("resources", GOVT)
+ },
+ resources(_) {
+ game.resources[GOVT] -= 3
+ goto_patrol()
+ }
+})
+
function goto_patrol() {
- if (!game.op.free)
- game.resources[game.current] -= 3
if (game.op.limited)
- game.state = "limited_patrol"
+ game.state = "patrol_limop"
else
game.state = "patrol"
game.op.who = -1
game.op.pieces = []
}
-states.limited_patrol = operation({
+states.patrol_limop = operation({
+ prompt() {
+ view.prompt = "Patrol: Select destination City or LoC."
+
+ // TODO: check that destination can be reached by any cubes
+ for (let s = first_city; s <= last_city; ++s)
+ gen_action_space(s)
+ for (let s = first_loc; s <= last_loc; ++s)
+ gen_action_space(s)
+ },
+ space(s) {
+ push_undo()
+
+ logi(`S${s}.`)
+
+ select_op_space(s, 0)
+
+ game.op.where = s
+ game.state = "patrol_limop_move"
+ },
+})
+
+function gen_patrol_move_limop(start) {
+ let queue = [ start ]
+ path_seen.fill(0)
+ while (queue.length > 0) {
+ let here = queue.shift()
+ for (let next of data.spaces[here].adjacent) {
+ // already seen
+ if (path_seen[next])
+ continue
+
+ path_seen[next] = 1
+ gen_piece_in_space(next, GOVT, TROOPS)
+ gen_piece_in_space(next, GOVT, POLICE)
+
+ // must stop if guerrilla
+ if (has_any_guerrilla(next))
+ continue
+
+ // continue along locs and cities
+ if (is_loc(next) || is_city(next))
+ queue.push(next)
+ }
+ }
+}
+
+states.patrol_limop_move = operation({
prompt() {
- view.prompt = "Patrol: ... TODO LimOp Patrol ..."
+ view.prompt = `Patrol: Move cubes to ${space_name[game.op.where]}.`
+ view.where = game.op.where
+
+ gen_patrol_move_limop(game.op.where)
+
view.actions.next = 1
},
+ piece(p) {
+ push_undo()
+ move_piece(p, game.op.where)
+ update_control()
+ },
next: goto_patrol_activate,
})
function gen_patrol_move(start) {
let queue = [ start ]
- view.actions.space = []
+ path_seen.fill(0)
while (queue.length > 0) {
let here = queue.shift()
for (let next of data.adjacent_patrol[here]) {
// already seen
- if (set_has(view.actions.space, next))
+ if (path_seen[next])
continue
- set_add(view.actions.space, next)
+ path_seen[next] = 1
+ gen_action_space(next)
// must stop if guerrilla
if (has_any_guerrilla(next))