diff options
-rw-r--r-- | play.js | 14 | ||||
-rw-r--r-- | rules.js | 139 |
2 files changed, 97 insertions, 56 deletions
@@ -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() @@ -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 |