diff options
-rw-r--r-- | rules.js | 175 |
1 files changed, 88 insertions, 87 deletions
@@ -58,7 +58,8 @@ const DIE_MISS = [ 0, '\u2460', '\u2461', '\u2462', '\u2463', '\u2464', '\u2465' const ATTACK_MARK = "*" const RESERVE_MARK = "" -let game = null +var game = null +var view = null function random(n) { // Largest MLCG that will fit its state in a double. @@ -510,7 +511,7 @@ function count_vp() { /* Game ability queries */ -function can_amphibious_move_to(b, from, to) { +function can_amphibious_move_to(_who, from, to) { let e = edge_id(from, to) if (EDGES[e] === 'sea') { if (is_city(to)) { @@ -673,7 +674,7 @@ function can_block_continue(b, last_from) { return false } -function can_sea_retreat(who, from, to) { +function can_sea_retreat(who, _from, to) { if (game.sea_retreated) return false if (BLOCKS[who].type === 'navis') @@ -822,7 +823,7 @@ function format_deployment_error(view) { } states.free_deployment = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to redeploy blocks..." gen_action_undo(view) @@ -836,12 +837,12 @@ states.free_deployment = { if (block_owner(b) === game.active && is_map_space(game.location[b])) gen_action_block(view, b) }, - block: function (who) { + block(who) { push_undo() game.who = who game.state = 'free_deployment_to' }, - pass: function () { + pass() { if (game.active === CAESAR) { clear_undo() game.moved = [] @@ -857,7 +858,7 @@ states.free_deployment = { } states.free_deployment_to = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to redeploy blocks..." if (game.setup_error.length === 0) { @@ -880,7 +881,7 @@ states.free_deployment_to = { } } }, - space: function (where) { + space(where) { game.location[game.who] = where set_add(game.moved, game.who) validate_free_deployment() @@ -921,7 +922,7 @@ function resume_discard_and_play_card() { } states.discard_and_play_card = { - prompt: function (view, current) { + prompt(current) { if (current === "Observer") return view.prompt = "Waiting for players to discard one card and play one card." if (current === CAESAR) { @@ -955,7 +956,7 @@ states.discard_and_play_card = { } } }, - card: function (c, current) { + card(c, current) { if (current === CAESAR) { if (!game.c_discard) game.c_discard = c @@ -972,7 +973,7 @@ states.discard_and_play_card = { } resume_discard_and_play_card() }, - undo: function (_, current) { + undo(_, current) { if (current === CAESAR) { if (game.c_discard) { set_add(game.c_hand, game.c_discard) @@ -1040,7 +1041,7 @@ function resume_play_card() { } states.play_card = { - prompt: function (view, current) { + prompt(current) { if (current === "Observer") { view.prior_c_card = game.prior_c_card view.prior_p_card = game.prior_p_card @@ -1069,7 +1070,7 @@ states.play_card = { } } }, - card: function (card, current) { + card(card, current) { if (current === CAESAR) { set_delete(game.c_hand, card) game.c_card = card @@ -1080,7 +1081,7 @@ states.play_card = { } resume_play_card() }, - undo: function (_, current) { + undo(_, current) { if (current === CAESAR) { if (game.c_card) { set_add(game.c_hand, game.c_card) @@ -1228,7 +1229,7 @@ function jupiter_block(b) { } states.jupiter = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + "..." view.prompt = "Jupiter: Choose an enemy city adjacent to a friendly city." @@ -1241,7 +1242,7 @@ states.jupiter = { } gen_action_pass(view, "Pass") }, - space: function (where) { + space(where) { /* pick a random block */ let list = [] for (let b = 0; b < block_count; ++b) @@ -1250,13 +1251,13 @@ states.jupiter = { let i = random(list.length) jupiter_block(list[i]) }, - pass: function () { + pass() { end_player_turn() }, } states.jupiter_to = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + "..." view.prompt = "Jupiter: Move " + block_name(game.who) + " to your city." @@ -1265,7 +1266,7 @@ states.jupiter_to = { if (is_friendly_city(to)) gen_action_space(view, to) }, - space: function (to) { + space(to) { log(block_name(game.who) + " joined " + game.active + ":") logi("#"+game.location[game.who] + " \u2192 #" + to + ".") game.location[game.who] = to @@ -1275,7 +1276,7 @@ states.jupiter_to = { } states.vulcan = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + "..." view.prompt = "Vulcan: Choose an enemy city to suffer a volcanic eruption." @@ -1283,7 +1284,7 @@ states.vulcan = { if (is_enemy_city(s)) gen_action_space(view, s) }, - space: function (city) { + space(city) { log("Vulcan struck #" + city + "!") game.where = city game.vulcan = [] @@ -1301,14 +1302,14 @@ states.vulcan = { } states.apply_vulcan = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + "..." view.prompt = "Apply Vulcan hits in " + space_name(game.where) + "." for (let i = 0; i < game.vulcan.length; ++i) gen_action_block(view, game.vulcan[i]) }, - block: function (who) { + block(who) { reduce_block(who) // NOTE: Cleopatra cannot switch sides in 2nd edition remove_from_array(game.vulcan, who) @@ -1340,7 +1341,7 @@ function goto_mars_and_neptune() { } states.mars_and_neptune = { - prompt: function (view, current) { + prompt(current) { let god = game.mars === game.active ? "Mars: " : "Neptune: " if (is_inactive_player(current)) return view.prompt = god + ": Waiting for " + game.active + "." @@ -1348,7 +1349,7 @@ states.mars_and_neptune = { for (let space of game.surprise_list) gen_action_space(view, space) }, - space: function (where) { + space(where) { game.surprise = where log("Surprise attack in #" + game.surprise + ".") delete game.surprise_list @@ -1383,11 +1384,11 @@ function move_or_attack(to) { return ATTACK_MARK } } - return false; // not a combat move + return false // not a combat move } states.move_who = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to move..." if (game.pluto === game.active) @@ -1428,7 +1429,7 @@ states.move_who = { gen_action_pass(view, "End movement phase") gen_action_undo(view) }, - block: function (who) { + block(who) { push_undo() game.who = who if (game.mercury === game.active) @@ -1436,7 +1437,7 @@ states.move_who = { else game.state = 'move_where' }, - pass: function () { + pass() { push_undo() end_movement() }, @@ -1444,7 +1445,7 @@ states.move_who = { } states.move_where = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to move..." view.prompt = "Move " + block_name(game.who) + "." @@ -1458,10 +1459,10 @@ states.move_where = { if (can_move_to) gen_action_space(view, to) } - gen_action_block(view, game.who); // for canceling move + gen_action_block(view, game.who) // for canceling move gen_action_undo(view) }, - space: function (to) { + space(to) { let from = game.location[game.who] if (is_amphibious_move(game.who, from, to)) { game.moves -- @@ -1502,7 +1503,7 @@ states.move_where = { } states.move_where_2 = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to move..." view.prompt = "Move " + block_name(game.who) + "." @@ -1510,10 +1511,10 @@ states.move_where_2 = { for (let to of SPACES[from].exits) if (to !== game.last_from && can_block_continue_to(game.who, to)) gen_action_space(view, to) - gen_action_space(view, from); // For ending move early. + gen_action_space(view, from) // For ending move early. gen_action_undo(view) }, - space: function (to) { + space(to) { let from = game.location[game.who] if (to !== from) { log_move_continue(to) @@ -1528,7 +1529,7 @@ states.move_where_2 = { } states.amphibious_move_to = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to move..." view.prompt = "Move " + block_name(game.who) + " to a friendly sea or port." @@ -1538,7 +1539,7 @@ states.amphibious_move_to = { gen_action_space(view, to) gen_action_undo(view) }, - space: function (to) { + space(to) { let from = game.location[game.who] game.last_from = from game.location[game.who] = to @@ -1557,7 +1558,7 @@ states.amphibious_move_to = { } states.mercury_move_1 = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to move..." view.prompt = "Mercury: Move " + block_name(game.who) + "." @@ -1567,7 +1568,7 @@ states.mercury_move_1 = { gen_action_space(view, to) gen_action_undo(view) }, - space: function (to) { + space(to) { let from = game.location[game.who] if (!game.activated.includes(from)) { logp("activated #" + from + ".") @@ -1588,7 +1589,7 @@ states.mercury_move_1 = { } states.mercury_move_2 = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to move..." view.prompt = "Mercury: Move " + block_name(game.who) + "." @@ -1596,10 +1597,10 @@ states.mercury_move_2 = { for (let to of SPACES[from].exits) if (to !== game.last_from && can_block_move_to(game.who, to)) gen_action_space(view, to) - gen_action_space(view, from); // For ending move early. + gen_action_space(view, from) // For ending move early. gen_action_undo(view) }, - space: function (to) { + space(to) { let from = game.location[game.who] if (to !== from) { let mark = move_or_attack(to) @@ -1623,7 +1624,7 @@ states.mercury_move_2 = { } states.mercury_move_3 = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to move..." view.prompt = "Mercury: Move " + block_name(game.who) + "." @@ -1631,10 +1632,10 @@ states.mercury_move_3 = { for (let to of SPACES[from].exits) if (to !== game.last_from && can_block_continue_to(game.who, to)) gen_action_space(view, to) - gen_action_space(view, from); // For ending move early. + gen_action_space(view, from) // For ending move early. gen_action_undo(view) }, - space: function (to) { + space(to) { let from = game.location[game.who] if (to !== from) { log_move_continue(to) @@ -1664,7 +1665,7 @@ function end_movement() { } states.levy = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to levy..." view.prompt = "Choose an army to levy. "+game.levies+"LP left." @@ -1681,7 +1682,7 @@ states.levy = { gen_action_pass(view, "End levy phase") gen_action_undo(view) }, - block: function (who) { + block(who) { push_undo() if (game.location[who] === LEVY) { if (BLOCKS[who].levy) { @@ -1701,24 +1702,24 @@ states.levy = { game.state = 'levy' } }, - pass: function () { + pass() { end_player_turn() }, undo: pop_undo, } states.levy_where = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to levy..." view.prompt = "Choose a friendly city to levy " + block_name(game.who) + " in." for (let s = first_map_space; s < space_count; ++s) if (can_levy_to(game.who, s)) gen_action_space(view, s) - gen_action_block(view, game.who); // for canceling levy + gen_action_block(view, game.who) // for canceling levy gen_action_undo(view) }, - space: function (to) { + space(to) { log_levy(to) game.levies -- game.steps[game.who] = 1 @@ -1754,7 +1755,7 @@ function goto_pick_battle() { } states.pick_battle = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to pick a battle..." view.prompt = "Choose the next battle to fight!" @@ -1762,7 +1763,7 @@ states.pick_battle = { if (is_contested_city(s) || is_contested_sea(s)) gen_action_space(view, s) }, - space: function (where) { + space(where) { game.where = where start_battle() }, @@ -1854,7 +1855,7 @@ function end_disrupt_reserves() { states.disrupt_reserves = { show_battle: true, - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to apply disruption hits..." view.prompt = "Apply disruption hits to reserves." @@ -2088,7 +2089,7 @@ function pass_with_block(who) { states.battle_round = { show_battle: true, - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to choose a combat action..." let can_fire = false @@ -2121,7 +2122,7 @@ states.battle_round = { if (game.hits > 0) gen_action(view, 'assign') }, - assign: function () { + assign() { game.active = enemy(game.active) if (game.hits === 1) game.flash = `Inflicted 1 hit.` @@ -2129,7 +2130,7 @@ states.battle_round = { game.flash = `Inflicted ${game.hits} hits.` goto_battle_hits() }, - block: function (who) { + block(who) { if (can_fire_with_block(who)) fire_with_block(who) else if (can_retreat_with_block(who)) @@ -2139,13 +2140,13 @@ states.battle_round = { else pass_with_block(who) }, - battle_fire: function (who) { + battle_fire(who) { fire_with_block(who) }, - battle_retreat: function (who) { + battle_retreat(who) { retreat_with_block(who) }, - battle_pass: function (who) { + battle_pass(who) { pass_with_block(who) }, } @@ -2211,7 +2212,7 @@ function apply_hit(who) { states.battle_hits = { show_battle: true, - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to apply hits..." view.prompt = "Assign " + game.hits + (game.hits !== 1 ? " hits" : " hit") + " to your armies." @@ -2220,17 +2221,17 @@ states.battle_hits = { gen_action_block(view, b) } }, - block: function (who) { + block(who) { apply_hit(who) }, - battle_hit: function (who) { + battle_hit(who) { apply_hit(who) }, } states.retreat = { show_battle: false, - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to retreat..." view.prompt = "Retreat " + block_name(game.who) + "." @@ -2247,7 +2248,7 @@ states.retreat = { gen_action(view, 'undo') gen_action_block(view, game.who) }, - space: function (to) { + space(to) { let from = game.location[game.who] if (is_sea(to) && !is_navis(game.who)) { push_undo() @@ -2263,17 +2264,17 @@ states.retreat = { resume_battle() } }, - block: function () { + block() { resume_battle() }, - undo: function () { + undo() { resume_battle() }, } states.sea_retreat = { show_battle: false, - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to retreat..." view.prompt = "Retreat " + block_name(game.who) + " to a friendly port." @@ -2284,7 +2285,7 @@ states.sea_retreat = { } gen_action(view, 'undo') }, - space: function (to) { + space(to) { clear_undo() let from = game.location[game.who] game.flash = block_name(game.who) + " retreated." @@ -2308,7 +2309,7 @@ function goto_regroup() { } states.regroup = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to regroup..." view.prompt = "Regroup: Choose an army to move." @@ -2321,12 +2322,12 @@ states.regroup = { gen_action_pass(view, "End regroup") gen_action_undo(view) }, - block: function (who) { + block(who) { push_undo() game.who = who game.state = 'regroup_to' }, - pass: function () { + pass() { print_turn_log("regrouped") clear_undo() game.where = -1 @@ -2336,7 +2337,7 @@ states.regroup = { } states.regroup_to = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to regroup..." view.prompt = "Regroup: Move " + block_name(game.who) + " to a friendly or vacant location." @@ -2345,10 +2346,10 @@ states.regroup_to = { if (can_regroup_to(game.who, from, to)) gen_action_space(view, to) } - gen_action_block(view, game.who); // for canceling move + gen_action_block(view, game.who) // for canceling move gen_action_undo(view) }, - space: function (to) { + space(to) { let from = game.location[game.who] game.turn_log.push([from, to]) move_to(game.who, from, to) @@ -2448,7 +2449,7 @@ function next_navis_to_port() { } states.navis_to_port = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to move navis to port..." view.prompt = "Move all Navis to a friendly port." @@ -2469,12 +2470,12 @@ states.navis_to_port = { gen_action_pass(view, "End navis to port") gen_action_undo(view) }, - block: function (who) { + block(who) { push_undo() game.who = who game.state = 'navis_to_port_where' }, - pass: function () { + pass() { print_turn_log("moved to port") next_navis_to_port() }, @@ -2482,7 +2483,7 @@ states.navis_to_port = { } states.navis_to_port_where = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to move navis to port..." view.prompt = "Move " + block_name(game.who) + " to a friendly port." @@ -2491,10 +2492,10 @@ states.navis_to_port_where = { if (is_friendly_city(to)) gen_action_space(view, to) } - gen_action_block(view, game.who); // for canceling move + gen_action_block(view, game.who) // for canceling move gen_action_undo(view) }, - space: function (to) { + space(to) { let from = game.location[game.who] game.turn_log.push([from, to]) game.location[game.who] = to @@ -2513,7 +2514,7 @@ function winter_supply() { } states.disband = { - prompt: function (view, current) { + prompt(current) { if (is_inactive_player(current)) return view.prompt = "Waiting for " + game.active + " to disband..." let okay_to_end = true @@ -2540,12 +2541,12 @@ states.disband = { } gen_action_undo(view) }, - block: function (who) { + block(who) { push_undo() game.turn_log.push([game.location[who]]) disband_block(who) }, - pass: function () { + pass() { print_turn_log("disbanded") if (game.active === CAESAR) { game.turn_log = [] @@ -2597,7 +2598,7 @@ function end_game() { } states.game_over = { - prompt: function (view) { + prompt() { return view.prompt = game.victory }, } @@ -2815,7 +2816,7 @@ exports.view = function(state, current) { count_vp() - let view = { + view = { log: game.log, year: game.year, turn: game.turn, @@ -2840,7 +2841,7 @@ exports.view = function(state, current) { if (game.main_road && game.main_road.length > 0) view.main_road = game.main_road - states[game.state].prompt(view, current) + states[game.state].prompt(current) if (states[game.state].show_battle) view.battle = make_battle_view() |