diff options
-rw-r--r-- | play.html | 6 | ||||
-rw-r--r-- | play.js | 35 | ||||
-rw-r--r-- | rules.js | 115 |
3 files changed, 136 insertions, 20 deletions
@@ -63,8 +63,10 @@ <div id="hexes"></div> <div id="pieces"> -<div id="marker_turn" class="marker large y1" style="top:1665px;left:45px"></div> -<div id="marker_remain" class="marker large y3" style="top:1857px;left:129px"></div> +<div id="marker_turn" class="marker large y1" style="top:1665px;left:53px"></div> +<div id="marker_remain" class="marker large y3 hide" style="top:1857px;left:129px"></div> +<div id="marker_french_moves" class="marker large y2 hide" style="top:1857px;left:129px"></div> +<div id="marker_prussian_moves" class="marker large y4 hide" style="top:1857px;left:129px"></div> <div id="french_hq_1" class="french large y1"></div> <div id="french_hq_2" class="french large y2"></div> @@ -128,6 +128,8 @@ let ui = { stack: new Array(last_hex+1).fill(0), turn: document.getElementById("marker_turn"), remain: document.getElementById("marker_remain"), + french_moves: document.getElementById("marker_french_moves"), + prussian_moves: document.getElementById("marker_prussian_moves"), } function toggle_pieces() { @@ -406,8 +408,37 @@ function on_update() { ui.turn.style.left = (40 + TURN_X + (view.turn-1) * TURN_DX) + "px" ui.turn.classList.toggle("flip", view.rain === 2) - ui.remain.style.left = (20 + 109 + (view.remain % 10) * 47.5 | 0) + "px" - ui.remain.classList.toggle("flip", view.remain > 9) + if (view.remain > 0) { + ui.remain.style.left = (20 + 109 + (view.remain % 10) * 47.5 | 0) + "px" + ui.remain.classList.toggle("flip", view.remain > 9) + ui.remain.classList.remove("hide") + } else { + ui.remain.classList.add("hide") + } + + if (view.french_moves !== undefined) { + let x = (20 + 109 + (view.french_moves % 10) * 47.5 | 0) + ui.french_moves.style.left = x + "px" + ui.french_moves.classList.toggle("flip", view.french_moves > 9) + ui.french_moves.classList.remove("hide") + } else { + ui.french_moves.classList.add("hide") + } + + if (view.prussian_moves !== undefined) { + let x = (20 + 109 + (view.prussian_moves % 10) * 47.5 | 0) + let y = 1857 + if (view.prussian_moves === view.french_moves) { + x += 12 + y -= 12 + } + ui.prussian_moves.style.left = x + "px" + ui.prussian_moves.style.top = y + "px" + ui.prussian_moves.classList.toggle("flip", view.prussian_moves > 9) + ui.prussian_moves.classList.remove("hide") + } else { + ui.prussian_moves.classList.add("hide") + } action_button("blow", "Blow") action_button("roll", "Roll") @@ -7,8 +7,6 @@ // TODO: forbidden - enemy or enemy zoc on entry or adjacent hex special case retreat/recall -// TODO: june 15 special rules - // TODO: pause after last battle before next turn (do not auto-pass move and attack?) // TODO: confirm attack step? // TODO: roll attack step? @@ -60,6 +58,7 @@ const HILL_1 = find_piece("II Corps (Hill*)") const HILL_2 = find_piece("II Corps (Hill**)") const IMPERIAL_GUARD = find_piece("Guard Corps (Drouot)") const IMPERIAL_GUARD_CAV = find_piece("Guard Cav Corps (Guyot)") +const ZIETHEN = find_piece("I Corps (Ziethen)") function is_map_hex(x) { if (x >= 1000 && x <= 4041) @@ -178,13 +177,16 @@ const p1_inf = make_piece_list(p => p.side === P1 && p.type === "inf") const p2_inf = make_piece_list(p => p.side !== P1 && p.type === "inf") const p1_det = make_piece_list(p => p.side === P1 && p.type === "det") const p2_det = make_piece_list(p => p.side !== P1 && p.type === "det") -const aa_det = make_piece_list(p => p.side === "Anglo" && p.type === "det") const p1_corps = make_piece_list(p => p.side === P1 && (p.type === "inf" || p.type === "cav")) const p2_corps = make_piece_list(p => p.side !== P1 && (p.type === "inf" || p.type === "cav")) const p1_units = make_piece_list(p => p.side === P1 && (p.type === "inf" || p.type === "cav" || p.type === "det")) const p2_units = make_piece_list(p => p.side !== P1 && (p.type === "inf" || p.type === "cav" || p.type === "det")) const all_units = make_piece_list(p => (p.type === "inf" || p.type === "cav" || p.type === "det")) +const anglo_det = make_piece_list(p => p.side === "Anglo" && p.type === "det") +const prussian_cav = make_piece_list(p => p.side === "Prussian" && p.type === "cav") +const prussian_inf = make_piece_list(p => p.side === "Prussian" && p.type === "inf") + function friendly_hqs() { return (game.active === P1) ? p1_hqs : p2_hqs } function enemy_hqs() { return (game.active !== P1) ? p1_hqs : p2_hqs } function friendly_cavalry_corps() { return (game.active === P1) ? p1_cav : p2_cav } @@ -433,25 +435,46 @@ function update_zoc() { // === COMMAND PHASE === -function goto_command_phase() { +function count_french_reinforcements() { + let n = 0 + for (let p of p1_corps) + if (piece_hex(p) === REINFORCEMENTS) + ++n + return n +} + +function init_turn() { + let die + log(".h1 Turn " + game.turn) + bring_on_reinforcements() + if (game.rain > 0) game.rain-- if (game.turn === 1) { - log("Surprise!") - log("Road Congestion.") + log("Surprise:\nOnly P" + ZIETHEN + " can move.") } if (game.turn === 2) { - log("Delayed Reaction.") - log("Concentrating the Army.") - log("Road Congestion.") + log("Delayed Reaction:\nAnglo-Allied units cannot move.") + die = roll_die() + log("Concentrating the Army:\nD" + die + " Prussian moves.") + game.prussian_moves = die + } + + if (game.turn <= 2) { + let n = 3 + if (game.turn === 2) + n = count_french_reinforcements() + die = roll_die() + log("Road Congestion:\nD" + die + " + " + n + " French moves.") + game.french_moves = die + n } if (game.turn === 5 || game.turn === 6) { - let die = roll_die() + die = roll_die() if (die <= 4) { log("The Deluge:\nD" + die + " \u2013 Rain.") game.rain = 2 @@ -463,8 +486,10 @@ function goto_command_phase() { if (game.rain > 0) log("Artillery Ricochet Ineffective.") +} + +function goto_command_phase() { log(".h2 Command") - bring_on_reinforcements() goto_hq_placement_step() } @@ -892,7 +917,7 @@ function goto_organization_phase() { // British Line of Communication Angst let n = 0 - for (let p of aa_det) + for (let p of anglo_det) if (piece_is_on_map(p) || piece_hex(p) === ELIMINATED) ++n @@ -1111,6 +1136,12 @@ function next_movement() { function pass_movement() { log(game.active + " passed.") + + if (game.turn <= 2 && game.active === P1) + game.french_moves = 0 + if (game.turn === 2 && game.active === P2) + game.prussian_moves = 0 + if (game.remain > 0) { end_movement() } else { @@ -1140,6 +1171,10 @@ function pass_movement() { } function end_movement() { + if (game.turn <= 2) + delete game.french_moves + if (game.turn === 2) + delete game.prussian_moves goto_attack_phase() } @@ -1149,6 +1184,44 @@ states.movement = { update_zoc() + // June 15: Surprise + if (game.turn === 1 && game.active === P2) { + if (piece_is_not_in_enemy_zoc(ZIETHEN)) + gen_action_piece(ZIETHEN) + view.actions.pass = 1 + return + } + + // June 15: Congestion + if (game.turn <= 2 && game.active === P1) { + if (game.french_moves === 0) { + view.prompt += " Congestion." + view.actions.pass = 1 + return + } + } + + // June 15: Concentrating the Army + if (game.turn === 2 && game.active === P2) { + if (game.prussian_moves === 0) { + view.prompt += " Concentrating the Army." + view.actions.pass = 1 + return + } + } + + // June 15: Delayed Reaction + if (game.turn === 2 && game.active === P2) { + for (let p of prussian_cav) + if (piece_is_not_in_enemy_cav_zoc(p)) + gen_action_piece(p) + for (let p of prussian_inf) + if (piece_is_not_in_enemy_zoc(p)) + gen_action_piece(p) + view.actions.pass = 1 + return + } + let has_reinf = false for (let info of data.reinforcements) { if (info.turn <= game.turn && info.side === game.active) { @@ -1237,6 +1310,11 @@ states.movement_to = { // TODO: forbidden (retreat then next_movement) + if (game.turn <= 2 && game.active === P1) + --game.french_moves + if (game.turn === 2 && game.active === P2) + --game.prussian_moves + log("") next_movement() }, @@ -2119,6 +2197,7 @@ function goto_end_phase() { recall_detachment(GRAND_BATTERY) game.turn += 1 + init_turn() goto_command_phase() } @@ -2245,9 +2324,8 @@ function setup_june_15() { setup_piece("Prussian", "I Detachment (Pirch)", 1217) setup_piece("Prussian", "I Detachment (Lutzow)", 1221) - log(".h1 Turn " + game.turn) + init_turn() - bring_on_reinforcements() goto_movement_phase() } @@ -2284,10 +2362,10 @@ function setup_june_16() { setup_piece("Prussian", "IV Corps (Bulow)", 3) setup_piece("Prussian", "I Detachment (Lutzow)", 1623) - log(".h1 Turn " + game.turn) + init_turn() + log(".h2 Command") - bring_on_reinforcements() goto_detachment_placement_step() } @@ -2356,6 +2434,11 @@ exports.view = function (state, player) { target: game.target, } + if (game.turn <= 2) + view.french_moves = game.french_moves + if (game.turn === 2) + view.prussian_moves = game.prussian_moves + if (game.state === "game_over") { view.prompt = game.victory } else if (game.active !== player) { |