From cabc26701c17b3875ac9baea957e32252f445874 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Sat, 24 Jun 2023 00:57:14 +0200 Subject: Pack data. Support, mobs, and all province bits in "game.provinces". Rival emperors and barbarians in "game.barbarians". Castra in "game.legions". --- play.js | 62 ++++---- rules.js | 437 ++++++++++++++++------------------------------------- tools/genpieces.js | 33 ---- 3 files changed, 155 insertions(+), 377 deletions(-) delete mode 100644 tools/genpieces.js diff --git a/play.js b/play.js index 3fb1ee1..da79aa6 100644 --- a/play.js +++ b/play.js @@ -154,14 +154,31 @@ const REGION_NAME = [ "Unavailable", ] -function is_no_place_governor(province) { - return province >= view.support.length -} -function get_support(province) { - return view.support[province] +const BIT_AMPHITHEATER = 1 << 7 +const BIT_BASILICA = 1 << 8 +const BIT_LIMES = 1 << 9 +const BIT_QUAESTOR = 1 << 10 +const BIT_MILITIA = 1 << 11 +const BIT_BREAKAWAY = 1 << 12 +const BIT_SEAT_OF_POWER = 1 << 13 +const BIT_MILITIA_CASTRA = 1 << 14 + +function get_support(where) { return view.provinces[where] & 15 } +function get_mobs(where) { return (view.provinces[where] >> 4) & 7 } +function has_quaestor(where) { return view.provinces[where] & BIT_QUAESTOR } +function has_militia(where) { return view.provinces[where] & BIT_MILITIA } +function has_amphitheater(where) { return view.provinces[where] & BIT_AMPHITHEATER } +function has_basilica(where) { return view.provinces[where] & BIT_BASILICA } +function has_limes(where) { return view.provinces[where] & BIT_LIMES } +function is_breakaway(where) { return view.provinces[where] & BIT_BREAKAWAY } +function is_seat_of_power(where) { return view.provinces[where] & BIT_SEAT_OF_POWER } +function has_militia_castra(where) { return view.provinces[where] & BIT_MILITIA_CASTRA } + +function is_no_place_governor(where) { + return where >= view.provinces.length } function get_rival_emperor_location(id) { - return view.rival_emperors[id] + return view.barbarians[id] & 63 } function get_barbarian_location(id) { return view.barbarians[id] & 63 @@ -188,35 +205,10 @@ function is_general_inside_capital(id) { return view.generals[id] & 64 } function has_general_castra(id) { - return view.castra & (1 << id) -} -function has_militia_castra(province) { - return view.mcastra & (1 << province) -} -function has_quaestor(province) { - return view.quaestor & (1 << province) -} -function has_militia(province) { - return view.militia & (1 << province) -} -function get_mobs(province) { - return view.mobs[province] -} -function has_amphitheater(province) { - return view.amphitheater & (1 << province) -} -function has_basilica(province) { - return view.basilica & (1 << province) -} -function has_limes(province) { - return view.limes & (1 << province) -} -function is_breakaway(province) { - return view.breakaway & (1 << province) -} -function is_seat_of_power(province) { - return view.seat_of_power & (1 << province) + return view.generals[id] & 128 } + + function find_governor(f) { let n = view.legacy.length * 6 for (let id = 0; id < n; ++id) @@ -1144,7 +1136,7 @@ function on_update() { } } - let n = view.mobs[region] + let n = get_mobs(region) layout_mob(region, 0, ui.mobs[region * 3 + 0], n >= 1, n >= 2) layout_mob(region, 1, ui.mobs[region * 3 + 1], n >= 3, n >= 4) layout_mob(region, 2, ui.mobs[region * 3 + 2], n >= 5, n >= 6) diff --git a/rules.js b/rules.js index 08faab7..32def10 100644 --- a/rules.js +++ b/rules.js @@ -10,8 +10,6 @@ TODO [ ] emperor variant (and tokens) [ ] expansion cards (and images) -[ ] barbarian_count - */ var game @@ -50,7 +48,7 @@ const SENATE = 1 const POPULACE = 2 const LEGION_COUNT = 33 -const BARBARIAN_COUNT = [ 33, 43, 53 ] +const BARBARIAN_COUNT = [ 36, 46, 56 ] // REGIONS @@ -94,10 +92,10 @@ const REGION_NAME = [ "Africa", "Hispania", "Alamanni Homeland", - "Franks Homeland", - "Goths Homeland", - "Sassanids Homeland", - "Nomads Homeland", + "Frank Homeland", + "Goth Homeland", + "Sassanid Homeland", + "Nomad Homeland", "Mare Occidentale", "Mare Orientale", "Oceanus Atlanticus", @@ -162,21 +160,22 @@ const GOTHS = 2 const SASSANIDS = 3 const NOMADS = 4 -const first_barbarian = [ 0, 10, 20, 31, 43 ] -const last_barbarian = [ 9, 19, 30, 42, 52 ] - -const CNIVA = first_barbarian[GOTHS] + 0 -const ARDASHIR = first_barbarian[SASSANIDS] + 0 -const SHAPUR = first_barbarian[SASSANIDS] + 1 +const first_barbarian = [ 3, 13, 23, 34, 46 ] +const last_barbarian = [ 12, 22, 33, 45, 55 ] const POSTUMUS = 0 const PRIEST_KING = 1 const ZENOBIA = 2 +const CNIVA = first_barbarian[GOTHS] + 0 +const ARDASHIR = first_barbarian[SASSANIDS] + 0 +const SHAPUR = first_barbarian[SASSANIDS] + 1 const CNIVA_BONUS = 1 << 3 const ARDASHIR_BONUS = 1 << 4 const SHAPUR_BONUS = 1 << 5 +const RIVAL_EMPEROR_NAME = [ "Postumus", "Priest King", "Zenobia" ] + const GENERAL_NAME = [ "Red 0", "Red 1", "Red 2", "Red 3", "Red 4", "Red 5", "Blue 0", "Blue 1", "Blue 2", "Blue 3", "Blue 4", "Blue 5", @@ -452,12 +451,63 @@ function is_barbarian_leader(id) { // === BOARD STATE === +const BIT_AMPHITHEATER = 1 << 7 +const BIT_BASILICA = 1 << 8 +const BIT_LIMES = 1 << 9 +const BIT_QUAESTOR = 1 << 10 +const BIT_MILITIA = 1 << 11 +const BIT_BREAKAWAY = 1 << 12 +const BIT_SEAT_OF_POWER = 1 << 13 +const BIT_MILITIA_CASTRA = 1 << 14 + function is_no_place_governor(where) { - return where >= game.support.length + return where >= game.provinces.length } -function get_support(province) { return game.support[province] } -function set_support(province, level) { game.support[province] = level } +function get_support(where) { + return game.provinces[where] & 15 +} + +function set_support(where, level) { + game.provinces[where] &= ~15 + game.provinces[where] |= level +} + +function get_mobs(where) { + return (game.provinces[where] >> 4) & 7 +} + +function set_mobs(where, n) { + game.provinces[where] &= 7 << 4 + game.provinces[where] |= n << 4 +} + +function has_quaestor(where) { return game.provinces[where] & BIT_QUAESTOR } +function add_quaestor(where) { game.provinces[where] |= BIT_QUAESTOR } +function remove_quaestor(where) { game.provinces[where] &= ~BIT_QUAESTOR } + +function has_militia(where) { return game.provinces[where] & BIT_MILITIA } +function add_militia(where) { game.provinces[where] |= BIT_MILITIA } +function remove_militia(where) { game.provinces[where] &= ~BIT_MILITIA } + +function has_amphitheater(where) { return game.provinces[where] & BIT_AMPHITHEATER } +function has_basilica(where) { return game.provinces[where] & BIT_BASILICA } +function has_limes(where) { return game.provinces[where] & BIT_LIMES } +function add_amphitheater(where) { game.provinces[where] |= BIT_AMPHITHEATER } +function add_basilica(where) { game.provinces[where] |= BIT_BASILICA } +function add_limes(where) { game.provinces[where] |= BIT_LIMES } + +function is_breakaway(where) { return game.provinces[where] & BIT_BREAKAWAY } +function add_breakaway(where) { game.provinces[where] |= BIT_BREAKAWAY } +function remove_breakaway(where) { game.provinces[where] &= ~BIT_BREAKAWAY } + +function is_seat_of_power(where) { return game.provinces[where] & BIT_SEAT_OF_POWER } +function add_seat_of_power(where) { game.provinces[where] |= BIT_SEAT_OF_POWER } +function remove_seat_of_power(where) { game.provinces[where] &= ~BIT_SEAT_OF_POWER } + +function has_militia_castra(where) { return game.provinces[where] & BIT_MILITIA_CASTRA } +function add_militia_castra(where) { game.provinces[where] |= BIT_MILITIA_CASTRA } +function remove_militia_castra(where) { game.provinces[where] &= ~BIT_MILITIA_CASTRA } function get_barbarian_location(id) { return game.barbarians[id] & 63 } function set_barbarian_location(id, loc) { game.barbarians[id] = loc } @@ -466,8 +516,8 @@ function is_barbarian_active(id) { return !is_barbarian_inactive(id) } function set_barbarian_inactive(id) { game.barbarians[id] |= 64 } function set_barbarian_active(id) { game.barbarians[id] &= 63 } -function get_rival_emperor_location(id) { return game.rival_emperors[id] } -function set_rival_emperor_location(id, loc) { game.rival_emperors[id] = loc } +function get_rival_emperor_location(id) { return game.barbarians[id] } +function set_rival_emperor_location(id, loc) { game.barbarians[id] = loc } function get_legion_location(ix) { return game.legions[ix] & 63 } function set_legion_location(ix, loc) { game.legions[ix] = loc } @@ -475,55 +525,18 @@ function is_legion_reduced(ix) { return game.legions[ix] & 64 } function set_legion_reduced(ix) { game.legions[ix] |= 64 } function set_legion_full_strength(ix) { game.legions[ix] &= 63 } -function is_legion_unused(ix) { - return game.legions[ix] === AVAILABLE -} - -function get_governor_location(id, loc) { return game.governors[id] & 63 } +function get_governor_location(id) { return game.governors[id] & 63 } function set_governor_location(id, loc) { game.governors[id] = loc } function get_general_location(id) { return game.generals[id] & 63 } function set_general_location(id, loc) { game.generals[id] = loc } function is_general_inside_capital(id) { return game.generals[id] & 64 } function set_general_inside_capital(id) { game.generals[id] |= 64 } -function set_general_outside_capital(id) { game.generals[id] &= 63 } - -function has_general_castra(id) { return game.castra & (1 << id) } -function add_general_castra(id) { game.castra |= (1 << id) } -function remove_general_castra(id) { game.castra &= ~(1 << id) } - -function has_militia_castra(province) { return game.mcastra & (1 << province) } -function add_militia_castra(province) { game.mcastra |= (1 << province) } -function remove_militia_castra(province) { game.mcastra &= ~(1 << province) } - -function has_quaestor(province) { return game.quaestor & (1 << province) } -function add_quaestor(province) { game.quaestor |= (1 << province) } -function remove_quaestor(province) { game.quaestor &= ~(1 << province) } - -function has_militia(province) { return game.militia & (1 << province) } -function add_militia(province) { game.militia |= (1 << province) } -function remove_militia(province) { game.militia &= ~(1 << province) } - -function has_mob(province) { return game.mobs[province] > 0 } -function count_mobs(province) { return game.mobs[province] } -function add_mobs(province, n) { game.mobs[province] += n } -function remove_mobs(province, n) { game.mobs[province] -= n } -function remove_all_mobs(province) { game.mobs[province] = 0 } +function set_general_outside_capital(id) { game.generals[id] &= ~64 } -function has_amphitheater(province) { return game.amphitheater & (1 << province) } -function has_basilica(province) { return game.basilica & (1 << province) } -function has_limes(province) { return game.limes & (1 << province) } -function add_amphitheater(province) { game.amphitheater |= (1 << province) } -function add_basilica(province) { game.basilica |= (1 << province) } -function add_limes(province) { game.limes |= (1 << province) } - -function is_breakaway(province) { return game.breakaway & (1 << province) } -function add_breakaway(province) { game.breakaway |= (1 << province) } -function remove_breakaway(province) { game.breakaway &= ~(1 << province) } - -function is_seat_of_power(province) { return game.seat_of_power & (1 << province) } -function add_seat_of_power(province) { game.seat_of_power |= (1 << province) } -function remove_seat_of_power(province) { game.seat_of_power &= ~(1 << province) } +function has_general_castra(id) { return game.generals[id] & 128 } +function add_general_castra(id) { game.generals[id] |= 128 } +function remove_general_castra(id) { game.generals[id] &= ~128 } // === TRANSIENT STATE === @@ -548,32 +561,14 @@ function get_selected_region() { return UNAVAILABLE } -function for_each_current_general(f) { - let a = game.current * 6 - for (let id = a; id < a + 6; ++id) - f(id, get_general_location(id), is_general_inside_capital(id)) -} - -function for_each_current_governor(f) { - let a = game.current * 6 - for (let id = a; id < a + 6; ++id) - f(id, get_governor_location(id)) -} - function for_each_general(f) { - let n = game.legacy.length * 6 + let n = get_player_count() * 6 for (let id = 0; id < n; ++id) f(id, get_general_location(id), is_general_inside_capital(id)) } -function for_each_governor(f) { - let n = game.legacy.length * 6 - for (let id = 0; id < n; ++id) - f(id, get_governor_location(id)) -} - function find_general(f) { - let n = game.legacy.length * 6 + let n = get_player_count() * 6 for (let id = 0; id < n; ++id) if (f(id, get_general_location(id), is_general_inside_capital(id))) return id @@ -581,31 +576,20 @@ function find_general(f) { } function find_governor(f) { - let n = game.legacy.length * 6 + let n = get_player_count() * 6 for (let id = 0; id < n; ++id) if (f(id, get_governor_location(id))) return id return -1 } -function for_each_barbarian(f) { - let n = game.barbarians.length - for (let id = 0; id < n; ++id) - f(id, get_barbarian_location(id), is_barbarian_active(id)) -} - function find_barbarian(f) { - let n = game.barbarians.length - for (let id = 0; id < n; ++id) + for (let id = 3; id < game.barbarians.length; ++id) if (f(id, get_barbarian_location(id), is_barbarian_active(id))) return id return -1 } -function some_governor(f) { - return find_governor(f) >= 0 -} - function some_general(f) { return find_general(f) >= 0 } @@ -615,11 +599,11 @@ function some_barbarian(f) { } function next_player() { - return (game.current + 1) % game.legacy.length + return (game.current + 1) % get_player_count() } function prev_player() { - return (game.current + game.legacy.length - 1) % game.legacy.length + return (game.current + get_player_count() - 1) % get_player_count() } function find_unused_legion() { @@ -630,7 +614,7 @@ function find_unused_legion() { } function can_build_improvement(province) { - if (has_mob(province)) + if (get_mobs(province)) return false if (has_active_barbarians(province)) return false @@ -658,7 +642,7 @@ function get_player_count() { } function get_tribe_count() { - return game.legacy.length + 1 + return get_player_count() + 1 } function can_enter_capital(where) { @@ -791,16 +775,6 @@ function has_enemy_general_in_capital(where) { return is_enemy_general(get_capital_general(where)) } -function has_enemy_army_in_province(where) { - if (some_general((id, loc) => loc === where && is_enemy_general(id))) - return true - if (is_province(where) && some_barbarian((id, loc) => loc === where)) - return true - if (!is_province(where) && some_barbarian((id, loc, active) => loc === where && active)) - return true - return false -} - function has_available_governor() { for (let i = 0; i < 6; ++i) if (get_governor_location(game.current * 6 + i) === AVAILABLE) @@ -876,7 +850,7 @@ function count_own_legions() { function count_barbarians_in_army(army_id) { let n = 0 - for (let id = 0; id < game.barbarians.length; ++id) + for (let id = 3; id < game.barbarians.length; ++id) if (get_barbarian_location(id) === ARMY + army_id) ++n return n @@ -902,8 +876,8 @@ function count_units_in_army(id) { for (let i = 0; i < LEGION_COUNT; ++i) if (get_legion_location(i) === ARMY + id) ++n - for (let loc of game.barbarians) - if (loc === ARMY + id) + for (let i = 3; i < game.barbarians.length; ++i) + if (get_barbarian_location(i) === ARMY + id) ++n return n } @@ -1226,9 +1200,9 @@ function goto_crisis() { } let tribe = 0 - if (game.legacy.length === 2) + if (get_player_count() === 2) tribe = CRISIS_TABLE_2P[sum - 2] - else if (game.legacy.length === 3) + else if (get_player_count() === 3) tribe = CRISIS_TABLE_3P[sum - 2] else tribe = CRISIS_TABLE_4P[sum - 2] @@ -1346,12 +1320,12 @@ function roll_barbarian_crisis() { logi(`B${black} W${white}`) if (black <= count_active_barbarians_at_home(tribe)) - goto_barbarian_invasion() + goto_barbarian_invasion(tribe) else goto_take_actions() } -function goto_barbarian_invasion(tribe, black, white) { +function goto_barbarian_invasion(tribe) { logi("Invasion!") game.count = game.dice[2] @@ -1464,7 +1438,7 @@ states.crisis_barbarian_leader = { gen_action_region(game.where) }, region(where) { - set_barbarian_location(game.count, game.where) + set_barbarian_location(game.count, where) goto_take_actions() }, } @@ -1483,7 +1457,7 @@ states.crisis_rival_emperor = { gen_action_region(game.where) }, region(where) { - set_rival_emperor_location(game.count, game.where) + set_rival_emperor_location(game.count, where) goto_take_actions() }, } @@ -1716,7 +1690,7 @@ states.take_actions = { } // Hold Games - if (has_mob(where)) { + if (get_mobs(where)) { view.actions.disperse_mob = 0 view.actions.hold_games = 0 if (has_lone_militia(where) && mip >= 1) @@ -1751,7 +1725,7 @@ states.take_actions = { view.actions.add_legion_to_army = 0 // Disperse Mob - if (has_mob(where) && is_own_province(where)) { + if (get_mobs(where) && is_own_province(where)) { if (mip >= 1) view.actions.disperse_mob = 1 } @@ -1874,7 +1848,7 @@ states.take_actions = { let where = get_governor_location(game.selected_governor) log("Held Games in S" + where + ".") spend_ip(POPULACE, 2) - remove_mobs(where, 1) + set_mobs(where, get_mobs(where) - 1) }, amphitheater() { @@ -1934,9 +1908,9 @@ states.take_actions = { n += 1 if (game.selected_general >= 0) n += count_units_in_army(game.selected_general) - n = Math.min(count_mobs(where), n) + n = Math.min(get_mobs(where), n) log("Disperse " + n + " Mobs in S" + where) - remove_mobs(where, n) + set_mobs(where, get_mobs(where) - n) reduce_support(where) }, @@ -1973,7 +1947,7 @@ states.take_actions = { goto_battle_vs_rival_emperor(get_selected_region(), game.selected_general, id) }, - militia(where) { + militia(_) { push_undo() goto_battle_vs_militia(get_selected_region(), game.selected_general) }, @@ -2135,7 +2109,7 @@ function remove_governor(where) { log("Removed Governor from S" + where) eliminate_militia(where) - remove_all_mobs(where) + set_mobs(where, 0) remove_quaestor(where) // TODO: manual? @@ -2158,7 +2132,7 @@ function remove_governor(where) { function place_governor(where, new_governor) { eliminate_militia(where) - remove_all_mobs(where) + set_mobs(where, 0) remove_quaestor(where) let old_governor = get_province_governor(where) @@ -2203,7 +2177,7 @@ function calc_needed_votes(where, pg) { states.place_governor = { prompt() { - let [ mip, sip, pip ] = game.ip + let sip = game.ip[SENATE] let need = calc_needed_votes(game.where, false) let votes = game.count if (game.where === ITALIA) @@ -2229,7 +2203,7 @@ states.place_governor = { states.praetorian_guard = { prompt() { - let [ mip, sip, pip ] = game.ip + let mip = game.ip[MILITARY] let need = calc_needed_votes(game.where, true) let votes = game.count if (game.where === ITALIA) @@ -2334,13 +2308,13 @@ states.damnatio_memoriae_mobs = { prompt("Damnatio Memoriae: Place " + game.count + " mobs in provinces you govern.") view.color = SENATE for (let where = 0; where < 12; ++where) - if (is_own_province(where) && count_mobs(where) < 6) + if (is_own_province(where) && get_mobs(where) < 6) gen_action_region(where) }, region(where) { push_undo() log("Added Mob to S" + where) - add_mobs(where, 1) + set_mobs(where, get_mobs(where) + 1) if (--game.count === 0) game.state = "take_actions" }, @@ -2416,7 +2390,7 @@ function gen_move_army() { states.move_army_at_sea = { prompt() { - let [ mip, sip, pip ] = game.ip + let mip = game.ip[MILITARY] prompt("Move Army: " + mip + " Military.") view.color = MILITARY view.selected_general = game.selected_general @@ -2600,7 +2574,7 @@ states.foederati = { function can_play_mob() { for (let where = 0; where < 12; ++where) - if (!has_mob(where) && is_enemy_province(where)) + if (!get_mobs(where) && is_enemy_province(where)) return true return false } @@ -2614,12 +2588,12 @@ states.mob = { prompt("Mob: Place a mob in a province with no mobs.") view.color = POPULACE for (let where = 0; where < 12; ++where) - if (!has_mob(where) && is_enemy_province(where)) + if (!get_mobs(where) && is_enemy_province(where)) gen_action_region(where) }, region(where) { log("Mob in S" + where) - add_one_mob(where) + set_mobs(where, get_mobs(where) + 1) game.state = "take_actions" }, } @@ -2875,7 +2849,7 @@ function roll_general_dice(general) { } let barbarians = 0 - for (let id = 0; id < game.barbarians.length; ++id) + for (let id = 3; id < game.barbarians.length; ++id) if (get_barbarian_location(id) === army) barbarians += 1 if (barbarians > 0) { @@ -2891,7 +2865,7 @@ function roll_militia_dice() { return roll_dice(1, 5 + get_roman_drm()) } -function roll_rival_emperor_dice(rival_emperor) { +function roll_rival_emperor_dice() { log("Rival Emperor") return roll_dice(3, 4) } @@ -2942,7 +2916,7 @@ function roll_defender_dice() { n = roll_militia_dice() break case "rival_emperor": - n = roll_rival_emperor_dice(game.battle.target) + n = roll_rival_emperor_dice() break case "barbarians": n = roll_barbarian_dice(game.battle.target) @@ -2995,7 +2969,7 @@ function has_hits_general(general) { let army = ARMY + general if (is_general_inside_capital(general) && has_militia(game.where)) return true - for (let id = 0; id < game.barbarians.length; ++id) + for (let id = 3; id < game.barbarians.length; ++id) if (get_barbarian_location(id) === army) return true for (let id = 0; id < LEGION_COUNT; ++id) @@ -3015,7 +2989,7 @@ function gen_hits_general(general) { } if (!done) { - for (let id = 0; id < game.barbarians.length; ++id) { + for (let id = 3; id < game.barbarians.length; ++id) { if (get_barbarian_location(id) === army) { gen_action_barbarian(id) done = true @@ -3058,16 +3032,12 @@ function has_hits_on_defender() { switch (game.battle.type) { case "militia": return has_hits_militia() - break case "rival_emperor": return has_hits_rival_emperor(game.battle.target) - break case "barbarians": return has_hits_barbarians(game.battle.target) - break case "general": return has_hits_general(game.battle.target) - break } } return false @@ -3239,7 +3209,7 @@ states.advance_after_combat = { gen_action_capital(game.where) view.actions.pass = 1 }, - capital(where) { + capital(_) { push_undo() enter_capital() }, @@ -3274,7 +3244,7 @@ states.free_increase_support_level = { }, region(where) { push_undo() - increase_support(game.where) + increase_support(where) game.battle = null game.state = "take_actions" }, @@ -3360,7 +3330,7 @@ states.support_check_emperor = { function goto_support_check_mobs() { for (let where = 0; where < 12; ++where) { - if (is_own_province(where) && count_mobs(where) >= get_support(where)) { + if (is_own_province(where) && get_mobs(where) >= get_support(where)) { game.state = "support_check_mobs" return } @@ -3373,7 +3343,7 @@ states.support_check_mobs = { prompt("Support Check: Remove governors where number of mobs exceed support.") view.color = POPULACE for (let where = 0; where < 12; ++where) - if (is_own_province(where) && count_mobs(where) >= get_support(where)) + if (is_own_province(where) && get_mobs(where) >= get_support(where)) gen_action_region(where) }, region(where) { @@ -3475,7 +3445,7 @@ function count_political_points() { for (let where = 0; where < 12; ++where) { if (is_own_province(where)) { pp += get_support(where) - pp -= count_mobs(where) + pp -= get_mobs(where) } } return pp @@ -3633,7 +3603,7 @@ function goto_end_of_turn() { function goto_grow_mobs() { for (let where = 0; where < 12; ++where) { if ((game.count & (1 << where)) === 0) { - if (is_own_province(where) && has_mob(where) && !has_amphitheater(where)) { + if (is_own_province(where) && get_mobs(where) && !has_amphitheater(where)) { game.state = "grow_mobs" return } @@ -3648,13 +3618,13 @@ states.grow_mobs = { view.color = POPULACE for (let where = 0; where < 12; ++where) if ((game.count & (1 << where)) === 0) - if (is_own_province(where) && has_mob(where) && !has_amphitheater(where)) + if (is_own_province(where) && get_mobs(where) && !has_amphitheater(where)) gen_action_region(where) }, region(where) { push_undo() game.count |= (1 << where) - add_one_mob(where) + set_mobs(where, get_mobs(where) + 1) goto_grow_mobs() }, } @@ -3752,7 +3722,7 @@ function max_emperor_turns(cutoff) { function award_emperor_turns(amount, cutoff) { let x = max_emperor_turns(cutoff) if (x > 0) { - for (let p = 0; p < game.legacy.length; ++p) + for (let p = 0; p < get_player_count(); ++p) if (game.emperor_turns[p] === x) award_legacy(p, "Emperor Turns", amount) } @@ -3775,14 +3745,12 @@ function vp_tie(p) { } function goto_game_end() { - let cutoff = 1000 - log_h2("Game End") - cutoff = award_emperor_turns(10, cutoff) + let cutoff = award_emperor_turns(10, 1000) cutoff = award_emperor_turns(6, cutoff) cutoff = award_emperor_turns(3, cutoff) - cutoff = award_emperor_turns(0, cutoff) + award_emperor_turns(0, cutoff) let victor = game.legacy.map((legacy,p) => [vp_tie(p),p]).sort((a,b) => b[0] - a[0])[0][1] @@ -3878,23 +3846,11 @@ exports.setup = function (seed, scenario, options) { where: 0, battle: null, - support: new Array(player_count * 3).fill(1), - mobs: new Array(player_count * 3).fill(0), - militia: 0, - quaestor: 0, - castra: 0, - mcastra: 0, - amphitheater: 0, - basilica: 0, - limes: 0, - breakaway: 0, - seat_of_power: 0, - + provinces: new Array(3 * player_count).fill(1), governors: new Array(6 * player_count).fill(UNAVAILABLE), generals: new Array(6 * player_count).fill(UNAVAILABLE), legions: new Array(LEGION_COUNT).fill(AVAILABLE), barbarians: new Array(BARBARIAN_COUNT[player_count - 2]).fill(AVAILABLE), - rival_emperors: [ UNAVAILABLE, UNAVAILABLE, UNAVAILABLE ], crisis: 0, dice: [ 0, 0, 0, 0 ], // first two are crisis table dice, second two are barbarian homeland dice @@ -3974,24 +3930,19 @@ exports.action = function (state, player, action, arg) { return save_game() } -function is_current_player(player) { - if (player === 4) - return true - return game.current === player -} - exports.view = function (state, player_name) { load_game(state) let player = PLAYER_INDEX[player_name] - let player_count = game.legacy.length + let player_count = get_player_count() view = { log: game.log, current: game.current, prompt: null, - crisis: game.crisis, + provinces: game.provinces, + /* support: game.support, mobs: game.mobs, militia: game.militia, @@ -4003,13 +3954,14 @@ exports.view = function (state, player_name) { limes: game.limes, seat_of_power: game.seat_of_power, breakaway: game.breakaway, + */ governors: game.governors, generals: game.generals, legions: game.legions, barbarians: game.barbarians, - rival_emperors: game.rival_emperors, + crisis: game.crisis, dice: game.dice, event: game.active_event, played: game.played, @@ -4080,10 +4032,6 @@ function logi(msg) { game.log.push(">" + msg) } -function logii(msg) { - game.log.push(">>" + msg) -} - // === COMMON LIBRARY === function roll_die() { @@ -4176,14 +4124,6 @@ function random(range) { return (game.seed = game.seed * 200105 % 34359738337) % range } -function random_bigint(range) { - // Largest MLCG that will fit its state in a double. - // Uses BigInt for arithmetic, so is an order of magnitude slower. - // https://www.ams.org/journals/mcom/1999-68-225/S0025-5718-99-00996-5/S0025-5718-99-00996-5.pdf - // m = 2**53 - 111 - return (game.seed = Number(BigInt(game.seed) * 5667072534355537n % 9007199254740881n)) % range -} - function shuffle(list) { // Fisher-Yates shuffle for (let i = list.length - 1; i > 0; --i) { @@ -4194,16 +4134,6 @@ function shuffle(list) { } } -function shuffle_bigint(list) { - // Fisher-Yates shuffle - for (let i = list.length - 1; i > 0; --i) { - let j = random_bigint(i + 1) - let tmp = list[j] - list[j] = list[i] - list[i] = tmp - } -} - // Fast deep copy for objects without cycles function object_copy(original) { if (Array.isArray(original)) { @@ -4245,28 +4175,8 @@ function array_insert(array, index, item) { array[index] = item } -function array_remove_pair(array, index) { - let n = array.length - for (let i = index + 2; i < n; ++i) - array[i - 2] = array[i] - array.length = n - 2 -} - -function array_insert_pair(array, index, key, value) { - for (let i = array.length; i > index; i -= 2) { - array[i] = array[i-2] - array[i+1] = array[i-1] - } - array[index] = key - array[index+1] = value -} - // Set as plain sorted array -function set_clear(set) { - set.length = 0 -} - function set_has(set, item) { let a = 0 let b = set.length - 1 @@ -4315,94 +4225,3 @@ function set_delete(set, item) { } } } - -function set_toggle(set, item) { - let a = 0 - let b = set.length - 1 - while (a <= b) { - let m = (a + b) >> 1 - let x = set[m] - if (item < x) - b = m - 1 - else if (item > x) - a = m + 1 - else { - array_remove(set, m) - return - } - } - array_insert(set, a, item) -} - -// Map as plain sorted array of key/value pairs - -function map_clear(map) { - map.length = 0 -} - -function map_has(map, key) { - let a = 0 - let b = (map.length >> 1) - 1 - while (a <= b) { - let m = (a + b) >> 1 - let x = map[m<<1] - if (key < x) - b = m - 1 - else if (key > x) - a = m + 1 - else - return true - } - return false -} - -function map_get(map, key, missing) { - let a = 0 - let b = (map.length >> 1) - 1 - while (a <= b) { - let m = (a + b) >> 1 - let x = map[m<<1] - if (key < x) - b = m - 1 - else if (key > x) - a = m + 1 - else - return map[(m<<1)+1] - } - return missing -} - -function map_set(map, key, value) { - let a = 0 - let b = (map.length >> 1) - 1 - while (a <= b) { - let m = (a + b) >> 1 - let x = map[m<<1] - if (key < x) - b = m - 1 - else if (key > x) - a = m + 1 - else { - map[(m<<1)+1] = value - return - } - } - array_insert_pair(map, a<<1, key, value) -} - -function map_delete(map, item) { - let a = 0 - let b = (map.length >> 1) - 1 - while (a <= b) { - let m = (a + b) >> 1 - let x = map[m<<1] - if (item < x) - b = m - 1 - else if (item > x) - a = m + 1 - else { - array_remove_pair(map, m<<1) - return - } - } -} diff --git a/tools/genpieces.js b/tools/genpieces.js deleted file mode 100644 index 01d7edb..0000000 --- a/tools/genpieces.js +++ /dev/null @@ -1,33 +0,0 @@ -var ix = 0 - -function mk(name, n) { - var a = ix - var b = ix + n - 1 - console.log("const " + name + "_data = " + a) - ix = b + 1 -} - -function size(name) { - console.log("const " + name + "_size = " + (ix)) -} - -mk("province", 12) -mk("legion", 33) -mk("rival_emperor", 3) -mk("barbarian_leader", 3) -mk("alamanni", 10) -mk("franks", 10) -mk("goths", 10) -mk("red_governor", 6) -mk("red_general", 6) -mk("blue_governor", 6) -mk("blue_general", 6) -size("data_2p") -mk("nomads", 10) -mk("yellow_governor", 6) -mk("yellow_general", 6) -size("data_3p") -mk("sassanids", 10) -mk("green_governor", 6) -mk("green_general", 6) -size("data_4p") -- cgit v1.2.3