diff options
-rw-r--r-- | play.js | 41 | ||||
-rw-r--r-- | rules.js | 91 |
2 files changed, 88 insertions, 44 deletions
@@ -677,27 +677,20 @@ function on_blur_piece() { /* UPDATE UI */ -function layout_general_offset(g, s) { - // if not selected: number of unselected generals below us - // if not selected: (number of unselected generals + 1) + number of selected generals below us - if (!set_has(view.selected, g)) { - let n = 0 - for (let i = g+1; i < 20; ++i) - if (view.pos[i] === s && !set_has(view.selected, i)) - ++n - return n - } else { - let n = 0 - for (let i = 0; i < 20; ++i) - if (view.pos[i] === s && !set_has(view.selected, i)) - ++n - if (n > 0) - ++n - for (let i = g+1; i < 20; ++i) - if (view.pos[i] === s && set_has(view.selected, i)) - ++n - return n - } +function layout_general_offset(who, here) { + let other = -1 + for (let p = 0; p < 20; ++p) + if (view.pos[p] === here && who !== p) + other = p + if (other < 0) + return 0 + if ((view.supreme & (1 << who)) || view.selected === who) + return 1 + if ((view.supreme & (1 << other)) || view.selected === other) + return 0 + if (who < other) + return 1 + return 0 } function layout_general_offset_elim(g) { @@ -1026,10 +1019,8 @@ function on_update() { for (let v = 16; v >= 0; --v) action_button_with_argument("value", v, v) - for (let p = 0; p < 20; ++p) { - action_button_with_argument("promote", p, "Promote " + piece_abbr[p]) - action_button_with_argument("demote", p, "Demote " + piece_abbr[p]) - } + for (let p = 0; p < 20; ++p) + action_button_with_argument("supreme", p, power_name[piece_power[p]]) action_button("force_march", "Force march") @@ -5,7 +5,6 @@ /* TODO victory check -supreme commander in mixed stacks supply phase hussar payment re-entering supply trains during movement (10.2) @@ -188,6 +187,15 @@ const piece_power = [ P_AUSTRIA, P_AUSTRIA ] +const piece_rank = [ + 1, 2, 3, 4, 5, + 1, + 1, 2, 3, 4, + 1, + 1, 2, 3, + 1, 2, 3, 4, 5, 6, +] + const piece_name = [ "Moritz", "Belle-Isle", @@ -219,6 +227,7 @@ const piece_name = [ ] const all_pieces = [ ...all_power_generals.flat(), ...all_power_trains.flat() ] +const all_trains = [ ...all_power_trains.flat() ] const all_generals = [ ...all_power_generals.flat() ] const all_france_bavaria_generals = [ @@ -634,16 +643,18 @@ function current_player() { } function get_top_piece(s) { - for (let p of all_pieces) + for (let p of all_trains) if (game.pos[p] === s) return p - return -1 + return get_supreme_commander(s) } function get_supreme_commander(s) { - // TODO: promoted minor power (check who is actually on top!) for (let p of all_generals) - if (game.pos[p] === s) + if ((game.supreme & (1<<p)) && game.pos[p] === s) + return p + for (let p of all_generals) + if (!(game.supreme & (1<<p)) && game.pos[p] === s) return p return -1 } @@ -768,7 +779,10 @@ function count_generals(to) { function select_stack(s) { let list = [] for (let p of all_generals) - if (game.pos[p] === s) + if ((game.supreme & (1<<p)) && game.pos[p] === s) + list.push(p) + for (let p of all_generals) + if (!(game.supreme & (1<<p)) && game.pos[p] === s) list.push(p) return list } @@ -787,6 +801,7 @@ function eliminate_general(p, indent) { log(">P" + p + " eliminated") else log("P" + p + " eliminated.") + game.supreme &= ~(1 << p) game.pos[p] = ELIMINATED game.troops[p] = 0 set_in_supply(p) @@ -1207,8 +1222,10 @@ states.movement = { game.move_path = [ here ] if (is_supply_train(p)) game.state = "move_supply_train" - else + else { + game.supreme &= ~(1 << p) game.state = "move_general" + } }, confirm_end_movement() { this.end_movement() @@ -1224,7 +1241,6 @@ states.movement = { log_conquest(game.move_conq) delete game.move_conq - // MARIA: recruit during winter goto_recruit() goto_combat() }, } @@ -1545,14 +1561,7 @@ states.move_give = { function end_move_piece() { let here = game.pos[game.selected] - // uniting stacks: flag all as moved - if (is_general(game.selected)) { - for (let p of all_coop_generals(game.power)) - if (game.pos[p] === here) - set_add(game.moved, p) - } else { - set_add(game.moved, game.selected) - } + set_add(game.moved, game.selected) log_move_path() @@ -1563,10 +1572,52 @@ function end_move_piece() { } delete game.move_path - game.selected = -1 - game.state = "movement" - set_active_to_current_action_step() + // uniting stacks: flag all as moved + let supreme = false + if (is_general(game.selected)) { + for (let p of all_coop_generals(game.power)) { + if (game.pos[p] === here && p !== game.selected) { + if (piece_rank[p] === piece_rank[game.selected]) + supreme = true + set_add(game.moved, p) + } + } + } + + if (supreme) { + game.state = "move_supreme" + } else { + game.selected = -1 + game.state = "movement" + set_active_to_current_action_step() + } +} + +states.move_supreme = { + inactive: "move", + prompt() { + prompt("Choose supreme commander for mixed stack.") + let here = game.pos[game.selected] + for (let p of all_coop_generals(game.power)) { + if (game.pos[p] === here) { + gen_action("supreme", p) + gen_action_piece(p) + } + } + }, + supreme(p) { + let here = game.pos[game.selected] + for (let p of all_coop_generals(game.power)) + if (game.pos[p] === here) + game.supreme &= ~(1<<p) + game.supreme |= (1<<p) + game.selected = -1 + game.state = "movement" + }, + piece(p) { + this.supreme(p) + }, } /* RECRUITMENT */ @@ -2830,6 +2881,7 @@ exports.setup = function (seed, _scenario, _options) { pos: setup_piece_position.slice(), oos: 0, + supreme: 0, troops: new Array(20).fill(0), victory: [], elector: [], @@ -3015,6 +3067,7 @@ exports.view = function (state, player) { turn: game.turn, pos: game.pos, oos: game.oos, + supreme: game.supreme, victory: game.victory, elector: game.elector, troops: mask_troops(player), |