summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2024-10-23 12:08:47 +0200
committerTor Andersson <tor@ccxvii.net>2024-10-23 12:13:09 +0200
commit456d08d10840405e34f20af321e1802bcf156c53 (patch)
treeefbd31c898626597b246f11c665a6b068a98a350
parent7dc86dde42c3bf9cd38bc40da477dbd03f5b5ba3 (diff)
downloadmaria-456d08d10840405e34f20af321e1802bcf156c53.tar.gz
25 optional political rule
-rw-r--r--play.js14
-rw-r--r--rules.js139
2 files changed, 97 insertions, 56 deletions
diff --git a/play.js b/play.js
index e58e027..beb62e1 100644
--- a/play.js
+++ b/play.js
@@ -1003,10 +1003,10 @@ const colorize_3 = '<span class="value deck_3">$1</span>'
const colorize_4 = '<span class="value deck_4">$1</span>'
function colorize(text) {
- text = text.replace(/1\^(\d+)/g, colorize_1)
- text = text.replace(/2\^(\d+)/g, colorize_2)
- text = text.replace(/3\^(\d+)/g, colorize_3)
- text = text.replace(/4\^(\d+)/g, colorize_4)
+ text = text.replace(/1\^(\d+[\u2660\u2663\u2665\u2666R])/g, colorize_1)
+ text = text.replace(/2\^(\d+[\u2660\u2663\u2665\u2666R])/g, colorize_2)
+ text = text.replace(/3\^(\d+[\u2660\u2663\u2665\u2666R])/g, colorize_3)
+ text = text.replace(/4\^(\d+[\u2660\u2663\u2665\u2666R])/g, colorize_4)
text = text.replace(/(\d+)R/g, colorize_R)
text = text.replaceAll("\u2660", colorize_S)
text = text.replaceAll("\u2663", colorize_C)
@@ -1099,10 +1099,10 @@ function on_update() {
for (let pow of all_major_powers) {
ui.pc_placed[pow].replaceChildren()
- for (let tc of view.saved[pow])
+ for (let tc of view.face_up[pow])
+ ui.pc_placed[pow].appendChild(show_tc(tc))
+ for (let tc of view.face_down[pow])
ui.pc_placed[pow].appendChild(show_tc(tc))
- if (view.placed && view.placed[pow] >= 0)
- ui.pc_placed[pow].appendChild(show_tc(view.placed[pow]))
}
ui.pc_show.replaceChildren()
diff --git a/rules.js b/rules.js
index 719a81c..01532bf 100644
--- a/rules.js
+++ b/rules.js
@@ -4,8 +4,6 @@
/* TODO
-TODO: face-up / face-down TCs in display - use "placed" and "saved" arrays or implicit with "game.trump"?
-
show who controls which power in player list
set-aside victory marker areas
@@ -301,6 +299,9 @@ const MUNCHEN = find_city("München")
const DRESDEN = find_city("Dresden")
const ENGLAND = find_city("England")
+const EAST_PRUSSIA = find_city("East Prussia")
+const AUSTRIAN_ITALY_BOX = data.sectors.ItalyA[0]
+const FRENCH_ITALY_BOX = data.sectors.ItalyF[0]
const all_pieces = [ ...all_power_generals.flat(), ...all_power_trains.flat() ]
const all_trains = [ ...all_power_trains.flat() ]
@@ -584,6 +585,10 @@ function format_card(c) {
return (to_deck(c)+1) + "^" + format_card_prompt(c)
}
+function format_card_list(list) {
+ return list.map(format_card).join(", ")
+}
+
function format_reserve(c, v) {
return (to_deck(c)+1) + "^" + v + "R"
}
@@ -875,6 +880,13 @@ function count_used_troops() {
return current
}
+function has_general_of_power(to, power) {
+ for (let p of all_power_generals[power])
+ if (game.pos[p] === to)
+ return true
+ return false
+}
+
function has_any_piece(to) {
for (let p = 0; p <= last_piece; ++p)
if (game.pos[p] === to)
@@ -1151,9 +1163,11 @@ function count_used_cards() {
held[to_deck(c)]++
}
- // count cards in saved political display
+ // count cards in political display
for (let pow of all_major_powers) {
- for (let c of game.saved[pow])
+ for (let c of game.face_up[pow])
+ held[to_deck(c)]++
+ for (let c of game.face_down[pow])
held[to_deck(c)]++
}
@@ -3337,20 +3351,19 @@ const INFLUENCE_ORDER = [
function goto_politics() {
game.political = []
- game.placed = [ 0, 0, 0, 0 ]
game.stage = 0
game.save_saxony = game.saxony
- // 25.1 Return face-down TCs to the players
+ // 25.1 Return face-down (previously placed) TCs to the players
for (let pow of all_major_powers) {
- for (let c of game.saved[pow])
+ for (let c of game.face_down[pow])
set_add(game.hand[pow], c)
- game.saved[pow] = []
+ game.face_down[pow] = []
}
// 25.2 Reveal 2 Political Cards
- log("Reveal")
+ log("Political Cards")
while (game.political.length < 2) {
let pc = game.pol_deck.pop()
log(">C" + pc)
@@ -3412,7 +3425,7 @@ states.place_tc_on_display = {
push_undo()
log(power_name[game.power] + " placed a TC.")
set_delete(game.hand[game.power], c)
- game.placed[game.power] = c
+ set_add(game.face_down[game.power], c)
game.state = "place_tc_on_display_done"
},
pass() {
@@ -3447,18 +3460,22 @@ function goto_determine_order_of_influence() {
log_br()
log("Influence")
- // Turn cards face-up and turn bluff cards face down again
+ // Turn cards face-up (and turn bluff cards face down again)
for (let pow of POWER_FROM_POLITICAL_STAGE) {
- let c = game.placed[pow]
- if (c > 0) {
- if (is_trump_card(c))
- log(">" + format_card(c) + " " + power_name[pow])
- else
- log(">" + format_card(c) + " " + power_name[pow] + " (bluff)")
- set_add(game.saved[pow], c)
+ for (let i = 0; i < game.face_down[pow].length;) {
+ let c = game.face_down[pow][i]
+ if (is_trump_card(c)) {
+ array_remove(game.face_down[pow], i)
+ set_add(game.face_up[pow], c)
+ } else {
+ ++i
+ }
}
+ if (game.face_down[pow].length > 0)
+ log(">" + power_name[pow] + " " + format_card_list(game.face_down[pow]) + " (bluff)")
+ if (game.face_up[pow].length > 0)
+ log(">" + power_name[pow] + " " + format_card_list(game.face_up[pow]))
}
- delete game.placed
log_br()
game.stage = 0
@@ -3467,10 +3484,10 @@ function goto_determine_order_of_influence() {
function count_influence(pow) {
let n = 0
- for (let c of game.saved[pow])
+ for (let c of game.face_up[pow])
if (is_reserve(c))
n += 16
- else if (to_suit(c) === game.trump)
+ else
n += to_value(c)
return n
}
@@ -3521,7 +3538,7 @@ states.select_political_card = {
log(power_name[game.power] + " chose C" + pc + ".")
// face-up TCs to discard
- game.saved[game.power] = game.saved[game.power].filter(c => !is_trump_card(c))
+ game.face_up[game.power] = []
game.pc = pc
game.pcx = -1
@@ -3555,9 +3572,17 @@ states.political_card_discard_or_execute = {
function end_politics() {
delete game.political
- // flip TCs on display face down
game.trump = -1
+ // did not take a political turn; flip all cards face-down
+ for (let pow of all_major_powers) {
+ if (!(game.stage & (1 << pow))) {
+ for (let c of game.face_up[pow])
+ set_add(game.face_down[pow], c)
+ game.face_up[pow] = []
+ }
+ }
+
goto_adjust_political_tracks()
}
@@ -3802,7 +3827,7 @@ function is_saxony_austrian_ally() {
states.saxony_shift = {
inactive: "shift Saxony marker",
prompt() {
- prompt("Shift Saxony marker ${game.count} to the right.")
+ prompt(`Shift Saxony marker ${game.count} to the right.`)
view.actions.shift = [ 1 ]
view.actions.pass = 1
},
@@ -3840,8 +3865,34 @@ function goto_adjust_political_tracks() {
if (game.italy >= 8) game.flags |= F_ITALY_AUSTRIA
// Expeditionary corps
- // TODO
+ goto_expeditionary_corps()
+}
+
+function check_expeditionary_corps(power, space, active) {
+ if (active && !has_general_of_power(space, power)) {
+ set_active_to_power(power)
+ game.state = "send_expeditionary_corps_off_map"
+ return 1
+ }
+ if (!active && has_general_of_power(space, power)) {
+ set_active_to_power(power)
+ game.state = "bring_expeditionary_corps_on_map"
+ return 1
+ }
+ return 0
+}
+function goto_expeditionary_corps() {
+ if (check_expeditionary_corps(P_PRUSSIA, EAST_PRUSSIA, game.russia >= 5))
+ return
+ if (check_expeditionary_corps(P_FRANCE, FRENCH_ITALY_BOX, game.italy <= 2))
+ return
+ if (check_expeditionary_corps(P_AUSTRIA, AUSTRIAN_ITALY_BOX, game.italy >= 8))
+ return
+ goto_saxony_defection()
+}
+
+function goto_saxony_defection() {
// Saxony defection
let save_saxony = game.save_saxony
delete game.save_saxony
@@ -3991,9 +4042,12 @@ function make_tactics_discard(n) {
for (let pow of all_powers)
if (set_has(game.hand[pow], c))
return false
- for (let pow of all_major_powers)
- if (set_has(game.saved[pow], c))
+ for (let pow of all_major_powers) {
+ if (set_has(game.face_up[pow], c))
+ return false
+ if (set_has(game.face_down[pow], c))
return false
+ }
return true
})
}
@@ -4025,7 +4079,11 @@ exports.setup = function (seed, _scenario, _options) {
pol_deck: null,
deck: null,
hand: [ [], [], [], [], [], [] ],
- saved: [ [], [], [], [] ],
+
+ // face-up (saved) TCs
+ face_up: [ [], [], [], [] ],
+ // face-down (placed) TCs
+ face_down: [ [], [], [], [] ],
pos: setup_piece_position.slice(),
oos: 0,
@@ -4203,30 +4261,14 @@ function mask_hand(player) {
return view_hand
}
-function mask_placed(player) {
- let view_placed = []
- for (let pow of all_major_powers) {
- if (game.placed[pow] === 0)
- view_placed[pow] = -1
- else if (player_from_power(pow) === player)
- view_placed[pow] = game.placed[pow]
- else
- view_placed[pow] = game.placed[pow] & ~127
- }
- return view_placed
+function mask_face_down() {
+ return game.face_down.map(list => list.map(c => c & ~127))
}
function is_trump_card(c) {
return (game.trump >= 0) && (is_reserve(c) || to_suit(c) === game.trump)
}
-function mask_saved(player) {
- let view_saved = []
- for (let pow of all_major_powers)
- view_saved[pow] = game.saved[pow].map(c => is_trump_card(c) ? c : c & ~127)
- return view_saved
-}
-
function total_troops_list() {
let list = []
for (let pow of all_powers) {
@@ -4263,7 +4305,8 @@ exports.view = function (state, player) {
discard: total_discard_list(),
pol_deck: mask_pol_deck(),
- saved: mask_saved(),
+ face_up: game.face_up,
+ face_down: mask_face_down(),
power: game.power,
retro: game.retro,
@@ -4276,8 +4319,6 @@ exports.view = function (state, player) {
if (game.political)
view.political = game.political
- if (game.placed)
- view.placed = mask_placed(player)
if (game.state === "game_over") {
view.prompt = game.victory