summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--play.html6
-rw-r--r--play.js35
-rw-r--r--rules.js115
3 files changed, 136 insertions, 20 deletions
diff --git a/play.html b/play.html
index f5ce9a7..538c1a7 100644
--- a/play.html
+++ b/play.html
@@ -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>
diff --git a/play.js b/play.js
index 40c7920..72d34b3 100644
--- a/play.js
+++ b/play.js
@@ -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")
diff --git a/rules.js b/rules.js
index b14549b..aed4003 100644
--- a/rules.js
+++ b/rules.js
@@ -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) {