summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
authorTor Andersson <tor@ccxvii.net>2022-10-02 17:34:09 +0200
committerTor Andersson <tor@ccxvii.net>2022-11-16 19:19:39 +0100
commitc26bd4c55134db4a776ffd1f9f33f8789445aa97 (patch)
tree0fb53d60da140174b4dd4ed758c2c8d025ce0774 /rules.js
parenta0ee653860e471bba2fb1cd8d7611fd633af9878 (diff)
downloadcrusader-rex-c26bd4c55134db4a776ffd1f9f33f8789445aa97.tar.gz
No semicolons.
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js3068
1 files changed, 1533 insertions, 1535 deletions
diff --git a/rules.js b/rules.js
index 533881d..49b2799 100644
--- a/rules.js
+++ b/rules.js
@@ -1,4 +1,4 @@
-"use strict";
+"use strict"
// TODO: optional rule - force marches
@@ -9,45 +9,46 @@
exports.scenarios = [
"Standard"
-];
+]
exports.roles = [
"Franks",
"Saracens",
-];
-
-const { CARDS, BLOCKS, TOWNS, PORTS, ROADS, SHIELDS } = require('./data');
-
-const FRANKS = "Franks";
-const SARACENS = "Saracens";
-const ASSASSINS = "Assassins";
-const OBSERVER = "Observer";
-const BOTH = "Both";
-const DEAD = "Dead";
-const F_POOL = "FP";
-const S_POOL = "SP";
-const SEA = "Sea";
-const ENGLAND = "England";
-const FRANCE = "France";
-const GERMANIA = "Germania";
-const TYRE = "Tyre";
-const TRIPOLI = "Tripoli";
-const ALEPPO = "Aleppo";
-const ANTIOCH = "Antioch";
-const ST_SIMEON = "St. Simeon";
-const DAMASCUS = "Damascus";
-const MASYAF = "Masyaf";
-const SALADIN = "Saladin";
-
-const INTRIGUE = 3;
-const WINTER_CAMPAIGN = 6;
-
-const ENGLISH_CRUSADERS = [ "Richard", "Robert", "Crossbows" ];
-const GERMAN_CRUSADERS = [ "Barbarossa", "Frederik", "Leopold" ];
-const FRENCH_CRUSADERS = [ "Philippe", "Hugues", "Fileps" ];
-const SALADIN_FAMILY = [ "Saladin", "Al Adil", "Al Aziz", "Al Afdal", "Al Zahir" ];
-
-const GERMAN_ROADS = [ ST_SIMEON, ANTIOCH, ALEPPO ];
+]
+
+const { CARDS, BLOCKS, TOWNS, PORTS, ROADS, SHIELDS } = require('./data')
+
+const FRANKS = "Franks"
+const SARACENS = "Saracens"
+const ASSASSINS = "Assassins"
+const OBSERVER = "Observer"
+const BOTH = "Both"
+const ELIMINATED = null
+const DEAD = "Dead"
+const F_POOL = "FP"
+const S_POOL = "SP"
+const SEA = "Sea"
+const ENGLAND = "England"
+const FRANCE = "France"
+const GERMANIA = "Germania"
+const TYRE = "Tyre"
+const TRIPOLI = "Tripoli"
+const ALEPPO = "Aleppo"
+const ANTIOCH = "Antioch"
+const ST_SIMEON = "St. Simeon"
+const DAMASCUS = "Damascus"
+const MASYAF = "Masyaf"
+const SALADIN = "Saladin"
+
+const INTRIGUE = 3
+const WINTER_CAMPAIGN = 6
+
+const ENGLISH_CRUSADERS = [ "Richard", "Robert", "Crossbows" ]
+const GERMAN_CRUSADERS = [ "Barbarossa", "Frederik", "Leopold" ]
+const FRENCH_CRUSADERS = [ "Philippe", "Hugues", "Fileps" ]
+const SALADIN_FAMILY = [ "Saladin", "Al Adil", "Al Aziz", "Al Afdal", "Al Zahir" ]
+
+const GERMAN_ROADS = [ ST_SIMEON, ANTIOCH, ALEPPO ]
const KINGDOMS = {
Syria: SARACENS,
@@ -55,35 +56,35 @@ const KINGDOMS = {
Tripoli: FRANKS,
Jerusalem: FRANKS,
Egypt: SARACENS,
-};
+}
const VICTORY_TOWNS = [
"Aleppo", "Damascus", "Egypt",
"Antioch", "Tripoli", "Acre", "Jerusalem"
-];
+]
// serif cirled numbers
-const DIE_HIT = [ 0, '\u2776', '\u2777', '\u2778', '\u2779', '\u277A', '\u277B' ];
-const DIE_MISS = [ 0, '\u2460', '\u2461', '\u2462', '\u2463', '\u2464', '\u2465' ];
-const DIE_SELF = '\u2716';
+const DIE_HIT = [ 0, '\u2776', '\u2777', '\u2778', '\u2779', '\u277A', '\u277B' ]
+const DIE_MISS = [ 0, '\u2460', '\u2461', '\u2462', '\u2463', '\u2464', '\u2465' ]
+const DIE_SELF = '\u2716'
-const ATTACK_MARK = "*";
-const RESERVE_MARK_1 = "\u2020";
-const RESERVE_MARK_2 = "\u2021";
+const ATTACK_MARK = "*"
+const RESERVE_MARK_1 = "\u2020"
+const RESERVE_MARK_2 = "\u2021"
// Only used by UI layer for layout. remove from game logic.
-delete TOWNS[DEAD];
-delete TOWNS[F_POOL];
-delete TOWNS[S_POOL];
-delete TOWNS[SEA];
+delete TOWNS[DEAD]
+delete TOWNS[F_POOL]
+delete TOWNS[S_POOL]
+delete TOWNS[SEA]
// Quick lists for fast iteration
const BLOCKLIST = Object.keys(BLOCKS)
const TOWNLIST = Object.keys(TOWNS)
-let states = {};
+let states = {}
-let game = null;
+let game = null
function random(n) {
if (game.rng === 1)
@@ -92,80 +93,80 @@ function random(n) {
}
function log(s) {
- game.log.push(s);
+ game.log.push(s)
}
function active_adjective() {
- return (game.active === FRANKS ? "Frank" : "Saracen");
+ return (game.active === FRANKS ? "Frank" : "Saracen")
}
function join(list, conj = "or") {
- if (list.length === 0) return "";
- if (list.length === 1) return list[0];
- if (list.length === 2) return `${list[0]} ${conj} ${list[1]}`;
- return `${list.slice(0,-1).join(", ")}, ${conj} ${list[list.length-1]}`;
+ if (list.length === 0) return ""
+ if (list.length === 1) return list[0]
+ if (list.length === 2) return `${list[0]} ${conj} ${list[1]}`
+ return `${list.slice(0,-1).join(", ")}, ${conj} ${list[list.length-1]}`
}
function log_move_start(from) {
- game.move_buf = [ from ];
+ game.move_buf = [ from ]
}
function log_move_continue(to, mark) {
if (mark)
- game.move_buf.push(to + mark);
+ game.move_buf.push(to + mark)
else
- game.move_buf.push(to);
+ game.move_buf.push(to)
}
function log_move_end() {
if (game.move_buf && game.move_buf.length > 1)
- game.summary.push(game.move_buf);
- delete game.move_buf;
+ game.summary.push(game.move_buf)
+ delete game.move_buf
}
function print_summary(text, skip_if_empty = false) {
- let n = 0;
+ let n = 0
function print_move(last) {
- return "\n" + n + " " + last.join(" \u2192 ");
+ return "\n" + n + " " + last.join(" \u2192 ")
}
if (!skip_if_empty || game.summary.length > 0) {
- game.summary.sort();
- let last = game.summary[0];
+ game.summary.sort()
+ let last = game.summary[0]
for (let entry of game.summary) {
if (entry.toString() !== last.toString()) {
- text += print_move(last);
- n = 0;
+ text += print_move(last)
+ n = 0
}
- ++n;
- last = entry;
+ ++n
+ last = entry
}
if (n > 0)
- text += print_move(last);
+ text += print_move(last)
else
- text += "\nnothing.";
- log(text);
+ text += "\nnothing."
+ log(text)
}
- delete game.summary;
+ delete game.summary
}
function enemy(p) {
- if (p === FRANKS) return SARACENS;
- if (p === SARACENS) return FRANKS;
- return null;
+ if (p === FRANKS) return SARACENS
+ if (p === SARACENS) return FRANKS
+ return null
}
function is_inactive_player(current) {
- return current === OBSERVER || (game.active !== current && game.active !== BOTH);
+ return current === OBSERVER || (game.active !== current && game.active !== BOTH)
}
function is_winter() {
- return game.turn === 6;
+ return game.turn === 6
}
function remove_from_array(array, item) {
- let i = array.indexOf(item);
+ let i = array.indexOf(item)
if (i >= 0)
- array.splice(i, 1);
+ array.splice(i, 1)
}
function deep_copy(original) {
@@ -222,9 +223,9 @@ function gen_action_undo(view) {
if (!view.actions)
view.actions = {}
if (game.undo && game.undo.length > 0)
- view.actions.undo = 1;
+ view.actions.undo = 1
else
- view.actions.undo = 0;
+ view.actions.undo = 0
}
function gen_action(view, action, argument) {
@@ -232,462 +233,462 @@ function gen_action(view, action, argument) {
view.actions = {}
if (argument !== undefined) {
if (!(action in view.actions)) {
- view.actions[action] = [ argument ];
+ view.actions[action] = [ argument ]
} else {
if (!view.actions[action].includes(argument))
- view.actions[action].push(argument);
+ view.actions[action].push(argument)
}
} else {
- view.actions[action] = true;
+ view.actions[action] = true
}
}
function roll_d6() {
- return random(6) + 1;
+ return random(6) + 1
}
function shuffle_deck() {
- let deck = [];
+ let deck = []
for (let c = 1; c <= 27; ++c)
- deck.push(c);
- return deck;
+ deck.push(c)
+ return deck
}
function deal_cards(deck, n) {
- let hand = [];
+ let hand = []
for (let i = 0; i < n; ++i) {
- let k = random(deck.length);
- hand.push(deck[k]);
- deck.splice(k, 1);
+ let k = random(deck.length)
+ hand.push(deck[k])
+ deck.splice(k, 1)
}
- return hand;
+ return hand
}
function select_random_block(where) {
- let list = [];
+ let list = []
for (let b of BLOCKLIST)
if (game.location[b] === where)
- list.push(b);
+ list.push(b)
if (list.length === 0)
- return null;
- return list[random(list.length)];
+ return null
+ return list[random(list.length)]
}
function select_random_enemy_block(where) {
- let list = [];
+ let list = []
for (let b of BLOCKLIST)
if (game.location[b] === where && block_owner(b) === enemy(game.active))
- list.push(b);
+ list.push(b)
if (list.length === 0)
- return null;
- return list[random(list.length)];
+ return null
+ return list[random(list.length)]
}
function block_name(who) {
if (BLOCKS[who].type === 'nomads')
- return BLOCKS[who].name;
- return who;
+ return BLOCKS[who].name
+ return who
}
function block_type(who) {
- return BLOCKS[who].type;
+ return BLOCKS[who].type
}
function block_home(who) {
- let home = BLOCKS[who].home;
- if (home === "Normandy") return "England";
- if (home === "Aquitaine") return "England";
- if (home === "Bourgogne") return "France";
- if (home === "Flanders") return "France";
- return home;
+ let home = BLOCKS[who].home
+ if (home === "Normandy") return "England"
+ if (home === "Aquitaine") return "England"
+ if (home === "Bourgogne") return "France"
+ if (home === "Flanders") return "France"
+ return home
}
function list_seats(who) {
switch (block_type(who)) {
case 'nomads':
- return [ block_home(who) ];
+ return [ block_home(who) ]
case 'turcopoles':
- who = "Turcopoles";
- break;
+ who = "Turcopoles"
+ break
case 'military_orders':
- who = BLOCKS[who].name;
- break;
+ who = BLOCKS[who].name
+ break
}
if (is_saladin_family(who))
- who = SALADIN;
+ who = SALADIN
if (who === "Raymond (Tiberias)" || who === "Raymond (Tripoli)")
- who = "Raymond";
- let list = [];
+ who = "Raymond"
+ let list = []
for (let town in SHIELDS)
if (SHIELDS[town].includes(who))
- list.push(town);
- return list;
+ list.push(town)
+ return list
}
function is_home_seat(where, who) {
if (is_saladin_family(who))
- who = SALADIN;
+ who = SALADIN
switch (block_type(who)) {
case 'nomads':
- return where === block_home(who);
+ return where === block_home(who)
case 'turcopoles':
- who = "Turcopoles";
- break;
+ who = "Turcopoles"
+ break
case 'military_orders':
- who = BLOCKS[who].name;
- break;
+ who = BLOCKS[who].name
+ break
}
if (who === "Raymond (Tiberias)" || who === "Raymond (Tripoli)")
- who = "Raymond";
+ who = "Raymond"
if (SHIELDS[where] && SHIELDS[where].includes(who))
- return true;
- return false;
+ return true
+ return false
}
function block_pool(who) {
if (BLOCKS[who].owner === FRANKS)
- return F_POOL;
- return S_POOL;
+ return F_POOL
+ return S_POOL
}
function block_owner(who) {
- return BLOCKS[who].owner;
+ return BLOCKS[who].owner
}
function block_initiative(who) {
- return BLOCKS[who].combat[0];
+ return BLOCKS[who].combat[0]
}
function block_fire_power(who) {
- return BLOCKS[who].combat[1] | 0;
+ return BLOCKS[who].combat[1] | 0
}
function block_move(who) {
- return BLOCKS[who].move;
+ return BLOCKS[who].move
}
function block_max_steps(who) {
- return BLOCKS[who].steps;
+ return BLOCKS[who].steps
}
function is_saladin_family(who) {
- return who === "Saladin" || who === "Al Adil" || who === "Al Aziz" || who === "Al Afdal" || who === "Al Zahir";
+ return who === "Saladin" || who === "Al Adil" || who === "Al Aziz" || who === "Al Afdal" || who === "Al Zahir"
}
function is_english_crusader(who) {
- return (who === "Richard" || who === "Robert" || who === "Crossbows");
+ return (who === "Richard" || who === "Robert" || who === "Crossbows")
}
function are_crusaders_not_in_pool(crusaders) {
for (let b of crusaders)
if (game.location[b] === F_POOL)
- return false;
- return true;
+ return false
+ return true
}
function is_block_on_map(who) {
- let location = game.location[who];
- return location && location !== DEAD && location !== F_POOL && location !== S_POOL;
+ let location = game.location[who]
+ return location && location !== DEAD && location !== F_POOL && location !== S_POOL
}
function is_block_on_land(who) {
- let location = game.location[who];
+ let location = game.location[who]
return location && location !== DEAD && location !== F_POOL && location !== S_POOL &&
- location !== ENGLAND && location !== FRANCE && location !== GERMANIA;
+ location !== ENGLAND && location !== FRANCE && location !== GERMANIA
}
function road_id(a, b) {
- return (a < b) ? a + "/" + b : b + "/" + a;
+ return (a < b) ? a + "/" + b : b + "/" + a
}
function road_was_last_used_by_enemy(from, to) {
- return game.last_used[road_id(from, to)] === enemy(game.active);
+ return game.last_used[road_id(from, to)] === enemy(game.active)
}
function road_was_last_used_by_friendly(from, to) {
- return game.last_used[road_id(from, to)] === game.active;
+ return game.last_used[road_id(from, to)] === game.active
}
function road_type(a, b) {
- return ROADS[road_id(a,b)];
+ return ROADS[road_id(a,b)]
}
function road_limit(a, b) {
- return game.road_limit[road_id(a,b)] || 0;
+ return game.road_limit[road_id(a,b)] || 0
}
function reset_road_limits() {
- game.road_limit = {};
+ game.road_limit = {}
}
function count_player(p, where) {
- let count = 0;
+ let count = 0
for (let b of BLOCKLIST)
if (game.location[b] === where && block_owner(b) === p)
- ++count;
- return count;
+ ++count
+ return count
}
function count_friendly(where) {
- let p = game.active;
- let count = 0;
+ let p = game.active
+ let count = 0
for (let b of BLOCKLIST)
if (game.location[b] === where && block_owner(b) === p)
- ++count;
- return count;
+ ++count
+ return count
}
function count_enemy(where) {
- let p = enemy(game.active);
- let count = 0;
+ let p = enemy(game.active)
+ let count = 0
for (let b of BLOCKLIST)
if (game.location[b] === where && block_owner(b) === p)
- ++count;
- return count;
+ ++count
+ return count
}
function count_friendly_in_field(where) {
- let p = game.active;
- let count = 0;
+ let p = game.active
+ let count = 0
for (let b of BLOCKLIST)
if (game.location[b] === where && block_owner(b) === p)
if (!is_block_in_castle(b))
- ++count;
- return count;
+ ++count
+ return count
}
function count_enemy_in_field(where) {
- let p = enemy(game.active);
- let count = 0;
+ let p = enemy(game.active)
+ let count = 0
for (let b of BLOCKLIST)
if (game.location[b] === where && block_owner(b) === p)
if (!is_block_in_castle(b))
- ++count;
- return count;
+ ++count
+ return count
}
function count_friendly_in_field_excluding_reserves(where) {
- let p = game.active;
- let count = 0;
+ let p = game.active
+ let count = 0
for (let b of BLOCKLIST)
if (game.location[b] === where && block_owner(b) === p)
if (!is_block_in_castle(b) && !is_reserve(b))
- ++count;
- return count;
+ ++count
+ return count
}
function count_enemy_in_field_excluding_reserves(where) {
- let p = enemy(game.active);
- let count = 0;
+ let p = enemy(game.active)
+ let count = 0
for (let b of BLOCKLIST)
if (game.location[b] === where && block_owner(b) === p)
if (!is_block_in_castle(b) && !is_reserve(b))
- ++count;
- return count;
+ ++count
+ return count
}
function count_blocks_in_castle(where) {
- let n = 0;
+ let n = 0
for (let b of BLOCKLIST)
if (game.location[b] === where && game.castle.includes(b))
- ++n;
- return n;
+ ++n
+ return n
}
function count_enemy_in_field_and_reserve(where) {
- let n = 0;
+ let n = 0
for (let b of BLOCKLIST)
if (block_owner(b) !== game.active)
if (game.location[b] === where && !game.castle.includes(b))
- ++n;
- return n;
+ ++n
+ return n
}
function count_reserves(where) {
- let n = 0;
+ let n = 0
for (let b of BLOCKLIST)
if (block_owner(b) === game.active)
if (game.location[b] === where && is_reserve(b))
- ++n;
- return n;
+ ++n
+ return n
}
function is_player_kingdom(p, where) {
- return KINGDOMS[TOWNS[where].region] === p;
+ return KINGDOMS[TOWNS[where].region] === p
}
function is_friendly_kingdom(where) {
- return KINGDOMS[TOWNS[where].region] === game.active;
+ return KINGDOMS[TOWNS[where].region] === game.active
}
function is_enemy_kingdom(where) {
- return KINGDOMS[TOWNS[where].region] !== game.active;
+ return KINGDOMS[TOWNS[where].region] !== game.active
}
/* Town queries include castle and field. */
function is_friendly_town(where) {
- return (count_enemy(where) === 0) && (count_friendly(where) > 0 || is_friendly_kingdom(where));
+ return (count_enemy(where) === 0) && (count_friendly(where) > 0 || is_friendly_kingdom(where))
}
function is_enemy_town(where) {
- return (count_friendly(where) === 0) && (count_enemy(where) > 0 || is_enemy_kingdom(where));
+ return (count_friendly(where) === 0) && (count_enemy(where) > 0 || is_enemy_kingdom(where))
}
function is_vacant_town(where) {
- return count_friendly(where) === 0 && count_enemy(where) === 0;
+ return count_friendly(where) === 0 && count_enemy(where) === 0
}
function is_contested_town(where) {
- return count_friendly(where) > 0 && count_enemy(where) > 0;
+ return count_friendly(where) > 0 && count_enemy(where) > 0
}
function is_enemy_occupied_town(where) {
- return count_enemy(where) > 0;
+ return count_enemy(where) > 0
}
/* Field queries exclude castles. */
function is_friendly_field(where) {
- return (count_enemy_in_field(where) === 0) && (count_friendly_in_field(where) > 0 || is_friendly_kingdom(where));
+ return (count_enemy_in_field(where) === 0) && (count_friendly_in_field(where) > 0 || is_friendly_kingdom(where))
}
function is_enemy_field(where) {
- return (count_friendly_in_field(where) === 0) && (count_enemy_in_field(where) > 0 || is_enemy_kingdom(where));
+ return (count_friendly_in_field(where) === 0) && (count_enemy_in_field(where) > 0 || is_enemy_kingdom(where))
}
function is_contested_field(where) {
- return count_friendly_in_field(where) > 0 && count_enemy_in_field(where) > 0;
+ return count_friendly_in_field(where) > 0 && count_enemy_in_field(where) > 0
}
function is_friendly_or_vacant_field(where) {
- return is_friendly_field(where) || is_vacant_town(where);
+ return is_friendly_field(where) || is_vacant_town(where)
}
function is_enemy_or_contested_field(where) {
- return (count_enemy_in_field(where) > 0 || is_enemy_kingdom(where));
+ return (count_enemy_in_field(where) > 0 || is_enemy_kingdom(where))
}
/* Battle field queries exclude castles and reserves. */
function is_contested_battle_field() {
- let f = count_friendly_in_field_excluding_reserves(game.where);
- let e = count_enemy_in_field_excluding_reserves(game.where);
- return f > 0 && e > 0;
+ let f = count_friendly_in_field_excluding_reserves(game.where)
+ let e = count_enemy_in_field_excluding_reserves(game.where)
+ return f > 0 && e > 0
}
function is_friendly_battle_field() {
- return count_enemy_in_field_excluding_reserves(game.where) === 0;
+ return count_enemy_in_field_excluding_reserves(game.where) === 0
}
function is_enemy_battle_field() {
- return count_friendly_in_field_excluding_reserves(game.where) === 0;
+ return count_friendly_in_field_excluding_reserves(game.where) === 0
}
function is_reserve(who) {
- return game.reserves1.includes(who) || game.reserves2.includes(who);
+ return game.reserves1.includes(who) || game.reserves2.includes(who)
}
function is_field_attacker(who) {
if (game.location[who] === game.where && block_owner(who) === game.attacker[game.where])
- return !is_reserve(who) && !is_block_in_castle(who);
- return false;
+ return !is_reserve(who) && !is_block_in_castle(who)
+ return false
}
function is_field_defender(who) {
if (game.location[who] === game.where && block_owner(who) !== game.attacker[game.where])
- return !is_reserve(who) && !is_block_in_castle(who);
- return false;
+ return !is_reserve(who) && !is_block_in_castle(who)
+ return false
}
function is_field_combatant(who) {
if (game.location[who] === game.where)
- return !is_reserve(who) && !is_block_in_castle(who);
- return false;
+ return !is_reserve(who) && !is_block_in_castle(who)
+ return false
}
function is_block_in_field(who) {
- return !is_reserve(who) && !is_block_in_castle(who);
+ return !is_reserve(who) && !is_block_in_castle(who)
}
function is_siege_attacker(who) {
- return game.storming.includes(who);
+ return game.storming.includes(who)
}
function is_siege_defender(who) {
- return is_block_in_castle_in(who, game.where);
+ return is_block_in_castle_in(who, game.where)
}
function is_siege_combatant(who) {
- return game.storming.includes(who) || is_block_in_castle_in(who, game.where);
+ return game.storming.includes(who) || is_block_in_castle_in(who, game.where)
}
function castle_limit(where) {
- return TOWNS[where].rating;
+ return TOWNS[where].rating
}
function is_more_room_in_castle(where) {
- return count_blocks_in_castle(where) < castle_limit(where);
+ return count_blocks_in_castle(where) < castle_limit(where)
}
function is_within_castle_limit(where) {
- return count_friendly(where) <= Math.max(1, castle_limit(where));
+ return count_friendly(where) <= Math.max(1, castle_limit(where))
}
function is_castle_town(where) {
- return castle_limit(where) > 0;
+ return castle_limit(where) > 0
}
function is_under_siege(where) {
- return count_blocks_in_castle(where) > 0;
+ return count_blocks_in_castle(where) > 0
}
function is_block_in_castle(b) {
- return game.castle.includes(b);
+ return game.castle.includes(b)
}
function is_block_in_castle_in(b, town) {
- return game.location[b] === town && game.castle.includes(b);
+ return game.location[b] === town && game.castle.includes(b)
}
function besieged_player(where) {
for (let b of BLOCKLIST)
if (is_block_in_castle_in(b, where))
- return block_owner(b);
- return null;
+ return block_owner(b)
+ return null
}
function besieging_player(where) {
- return enemy(besieged_player(where));
+ return enemy(besieged_player(where))
}
function is_port(where) {
- return TOWNS[where].port;
+ return TOWNS[where].port
}
function is_friendly_port(where) {
- return TOWNS[where].port && is_friendly_field(where);
+ return TOWNS[where].port && is_friendly_field(where)
}
function can_activate(who) {
return block_owner(who) === game.active &&
is_block_on_map(who) &&
!is_block_in_castle(who) &&
- !game.moved[who];
+ !game.moved[who]
}
function can_activate_for_sea_move(who) {
return block_owner(who) === game.active &&
is_block_on_map(who) &&
- !game.moved[who];
+ !game.moved[who]
}
function count_pinning(where) {
- return count_enemy_in_field_excluding_reserves(where);
+ return count_enemy_in_field_excluding_reserves(where)
}
function count_pinned(where) {
- let count = 0;
+ let count = 0
for (let b of BLOCKLIST)
if (game.location[b] === where && block_owner(b) === game.active)
if (!is_reserve(b))
- ++count;
- return count;
+ ++count
+ return count
}
function is_pinned(who, from) {
if (game.active === game.p2) {
if (count_pinned(from) <= count_pinning(from))
- return true;
+ return true
}
- return false;
+ return false
}
function can_block_use_road(from, to) {
@@ -695,85 +696,86 @@ function can_block_use_road(from, to) {
switch (road_type(from, to)) {
case 'iron-bridge':
// https://boardgamegeek.com/thread/744750/20-rules-iron-bridge-question
+ // fallthrough
case 'major':
- return road_limit(from, to) < 8;
+ return road_limit(from, to) < 8
case 'minor':
- return road_limit(from, to) < 4;
+ return road_limit(from, to) < 4
}
} else {
switch (road_type(from, to)) {
case 'iron-bridge':
if (game.iron_bridge)
- return road_limit(from, to) < 3;
+ return road_limit(from, to) < 3
else
- return road_limit(from, to) < 4;
+ return road_limit(from, to) < 4
case 'major':
- return road_limit(from, to) < 4;
+ return road_limit(from, to) < 4
case 'minor':
- return road_limit(from, to) < 2;
+ return road_limit(from, to) < 2
}
}
- return false;
+ return false
}
function can_block_land_move_to(who, from, to) {
if (can_block_use_road(from, to)) {
if (count_pinning(from) > 0)
if (road_was_last_used_by_enemy(from, to))
- return false;
+ return false
// cannot start or reinforce battles in winter
if (is_winter() && is_enemy_occupied_town(to)) {
// but can move through friendly sieges
if (!is_friendly_field(to))
- return false;
+ return false
if (game.distance + 1 >= block_move(who))
- return false;
+ return false
}
- return true;
+ return true
}
- return false;
+ return false
}
function can_germans_move(who) {
- let from = game.location[who];
+ let from = game.location[who]
if (from === GERMANIA) {
if (can_activate(who)) {
for (let to of GERMAN_ROADS)
if (can_germans_move_to(who, to))
- return true;
+ return true
}
}
- return false;
+ return false
}
function can_germans_move_to(who, to) {
if (are_crusaders_not_in_pool(GERMAN_CRUSADERS)) {
if (is_winter() && is_enemy_occupied_town(to))
- return false;
+ return false
if (to === ALEPPO)
- return true;
+ return true
if (to === ANTIOCH)
- return true;
+ return true
if (to === ST_SIMEON)
- return road_limit(GERMANIA, ST_SIMEON) < 2;
+ return road_limit(GERMANIA, ST_SIMEON) < 2
}
- return false;
+ return false
}
function can_block_land_move(who) {
if (can_activate(who)) {
- let from = game.location[who];
+ let from = game.location[who]
if (from) {
if (is_pinned(who, from))
- return false;
+ return false
for (let to of TOWNS[from].exits)
if (can_block_land_move_to(who, from, to))
- return true;
+ return true
}
}
- return false;
+ return false
}
function can_use_richards_sea_legs(who, to) {
@@ -782,28 +784,28 @@ function can_use_richards_sea_legs(who, to) {
if (is_english_crusader(who)) {
if (is_enemy_or_contested_field(to)) {
if (!game.attacker[to])
- return true;
+ return true
if (game.attacker[to] === FRANKS)
- return (game.main_road[to] === "England");
+ return (game.main_road[to] === "England")
}
}
- return false;
+ return false
}
function can_enter_besieged_port(where) {
// Tripoli and Tyre are friendly to besieged defender!
if (where === TRIPOLI || where === TYRE)
if (besieged_player(where) === game.active)
- return count_blocks_in_castle(where) < castle_limit(where);
- return false;
+ return count_blocks_in_castle(where) < castle_limit(where)
+ return false
}
function can_leave_besieged_port(where) {
// Tripoli and Tyre are friendly to besieged defender!
if (where === TRIPOLI || where === TYRE)
if (besieged_player(where) === game.active)
- return true;
- return false;
+ return true
+ return false
}
function can_block_sea_move_to(who, to) {
@@ -811,266 +813,266 @@ function can_block_sea_move_to(who, to) {
// cannot start or reinforce battles in winter
if (!is_winter()) {
if (can_use_richards_sea_legs(who, to))
- return true;
+ return true
if (can_enter_besieged_port(to))
- return true;
+ return true
}
- return is_friendly_port(to);
+ return is_friendly_port(to)
}
- return false;
+ return false
}
function can_block_sea_move_from(who, from) {
if (is_friendly_port(from))
- return true;
+ return true
if (can_leave_besieged_port(from))
- return true;
+ return true
if (from === ENGLAND)
- return are_crusaders_not_in_pool(ENGLISH_CRUSADERS);
+ return are_crusaders_not_in_pool(ENGLISH_CRUSADERS)
if (from === FRANCE)
- return are_crusaders_not_in_pool(FRENCH_CRUSADERS);
- return false;
+ return are_crusaders_not_in_pool(FRENCH_CRUSADERS)
+ return false
}
function can_block_sea_move(who) {
if (can_activate_for_sea_move(who)) {
- let from = game.location[who];
+ let from = game.location[who]
if (can_block_sea_move_from(who, from)) {
for (let to of PORTS)
if (to !== from && can_block_sea_move_to(who, to))
- return true;
+ return true
}
}
- return false;
+ return false
}
function can_block_continue(who, from, to) {
if (is_contested_field(to))
- return false;
+ return false
if (game.distance >= block_move(who))
- return false;
- return true;
+ return false
+ return true
}
function can_block_retreat_to(who, to) {
- let from = game.location[who];
+ let from = game.location[who]
if (block_owner(who) === game.attacker[from]) {
if (!road_was_last_used_by_friendly(from, to))
- return false;
+ return false
}
if (is_friendly_field(to) || is_vacant_town(to)) {
if (can_block_use_road(from, to)) {
if (road_was_last_used_by_enemy(from, to))
- return false;
- return true;
+ return false
+ return true
}
}
- return false;
+ return false
}
function can_block_retreat(who) {
if (block_owner(who) === game.active) {
- let from = game.location[who];
+ let from = game.location[who]
for (let to of TOWNS[from].exits)
if (can_block_retreat_to(who, to))
- return true;
+ return true
}
- return false;
+ return false
}
function can_block_regroup_to(who, to) {
// regroup during winter campaign
if (is_winter() && is_enemy_occupied_town(to))
- return false;
+ return false
if (is_friendly_field(to) || is_vacant_town(to)) {
- let from = game.location[who];
+ let from = game.location[who]
if (can_block_use_road(from, to))
- return true;
+ return true
}
- return false;
+ return false
}
function can_block_regroup(who) {
if (block_owner(who) === game.active) {
- let from = game.location[who];
+ let from = game.location[who]
for (let to of TOWNS[from].exits)
if (can_block_regroup_to(who, to))
- return true;
+ return true
}
- return false;
+ return false
}
function can_block_use_road_to_muster(from, to) {
- return can_block_use_road(from, to) && is_friendly_or_vacant_field(to);
+ return can_block_use_road(from, to) && is_friendly_or_vacant_field(to)
}
function can_block_muster_with_3_moves(n0, muster) {
for (let n1 of TOWNS[n0].exits) {
if (can_block_use_road_to_muster(n0, n1)) {
if (n1 === muster)
- return true;
+ return true
for (let n2 of TOWNS[n1].exits) {
- if (n2 === n0) continue; // don't backtrack!
+ if (n2 === n0) continue // don't backtrack!
if (can_block_use_road_to_muster(n1, n2)) {
if (n2 === muster)
- return true;
+ return true
if (TOWNS[n2].exits.includes(muster))
if (can_block_use_road_to_muster(n2, muster))
- return true;
+ return true
}
}
}
}
- return false;
+ return false
}
function can_block_muster_with_2_moves(n0, muster, avoid) {
for (let n1 of TOWNS[n0].exits) {
if (n1 === avoid)
- continue;
+ continue
if (can_block_use_road_to_muster(n0, n1)) {
if (n1 === muster)
- return true;
+ return true
if (TOWNS[n1].exits.includes(muster))
if (can_block_use_road_to_muster(n1, muster))
- return true;
+ return true
}
}
- return false;
+ return false
}
function can_block_muster_with_1_move(n0, muster) {
if (TOWNS[n0].exits.includes(muster))
- return can_block_use_road_to_muster(n0, muster);
- return false;
+ return can_block_use_road_to_muster(n0, muster)
+ return false
}
function can_block_muster(who, muster) {
- let from = game.location[who];
+ let from = game.location[who]
if (from === muster)
- return false;
+ return false
if (can_activate(who)) {
if (is_pinned(who, from))
- return false;
+ return false
if (block_move(who) === 3)
- return can_block_muster_with_3_moves(from, muster);
+ return can_block_muster_with_3_moves(from, muster)
else
- return can_block_muster_with_2_moves(from, muster, null);
+ return can_block_muster_with_2_moves(from, muster, null)
}
- return false;
+ return false
}
function can_muster_to(muster) {
for (let b of BLOCKLIST)
if (can_block_muster(b, muster))
- return true;
- return false;
+ return true
+ return false
}
function can_muster_anywhere() {
for (let where of TOWNLIST)
if (is_friendly_field(where))
if (can_muster_to(where))
- return true;
- return false;
+ return true
+ return false
}
function lift_siege(where) {
if (is_under_siege(where) && !is_contested_town(where)) {
- log("Siege lifted in " + where + ".");
+ log("Siege lifted in " + where + ".")
for (let b of BLOCKLIST)
if (is_block_in_castle_in(b, where))
- remove_from_array(game.castle, b);
+ remove_from_array(game.castle, b)
}
}
function lift_all_sieges() {
for (let t of TOWNLIST)
- lift_siege(t);
+ lift_siege(t)
}
function reset_blocks() {
for (let b of BLOCKLIST) {
- game.location[b] = null;
- game.steps[b] = block_max_steps(b);
+ game.location[b] = ELIMINATED
+ game.steps[b] = block_max_steps(b)
}
}
function deploy(who, where) {
- game.location[who] = where;
- game.steps[who] = block_max_steps(who);
+ game.location[who] = where
+ game.steps[who] = block_max_steps(who)
}
function disband(who) {
- game.summary.push([game.location[who]]);
+ game.summary.push([game.location[who]])
if (is_saladin_family(who) || block_type(who) === 'crusaders' || block_type(who) === 'military_orders')
- game.location[who] = null; // permanently eliminated
+ game.location[who] = ELIMINATED // permanently eliminated
else
- game.location[who] = DEAD; // into to the pool next year
- game.steps[who] = block_max_steps(who);
+ game.location[who] = DEAD // into to the pool next year
+ game.steps[who] = block_max_steps(who)
}
function eliminate_block(who) {
- remove_from_array(game.castle, who);
- if (game.sallying) remove_from_array(game.sallying, who);
- if (game.storming) remove_from_array(game.storming, who);
- log(block_name(who) + " was eliminated.");
+ remove_from_array(game.castle, who)
+ if (game.sallying) remove_from_array(game.sallying, who)
+ if (game.storming) remove_from_array(game.storming, who)
+ log(block_name(who) + " was eliminated.")
if (is_saladin_family(who) || block_type(who) === 'crusaders' || block_type(who) === 'military_orders')
- game.location[who] = null; // permanently eliminated
+ game.location[who] = ELIMINATED // permanently eliminated
else
- game.location[who] = DEAD; // into to the pool next year
- game.steps[who] = block_max_steps(who);
+ game.location[who] = DEAD // into to the pool next year
+ game.steps[who] = block_max_steps(who)
}
function reduce_block(who) {
if (game.steps[who] === 1) {
- eliminate_block(who);
+ eliminate_block(who)
} else {
- --game.steps[who];
+ --game.steps[who]
}
}
// DEPLOYMENT
function is_valid_frank_deployment() {
- let errors = [];
+ let errors = []
for (let town of TOWNLIST)
if (!is_within_castle_limit(town))
- errors.push(town);
- return errors;
+ errors.push(town)
+ return errors
}
function goto_frank_deployment() {
- game.active = FRANKS;
- game.state = 'frank_deployment';
+ game.active = FRANKS
+ game.state = 'frank_deployment'
}
states.frank_deployment = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Deployment: Waiting for " + game.active + ".";
- gen_action_undo(view);
- let errors = is_valid_frank_deployment();
+ return view.prompt = "Deployment: Waiting for " + game.active + "."
+ gen_action_undo(view)
+ let errors = is_valid_frank_deployment()
if (errors.length === 0)
- gen_action(view, 'next');
+ gen_action(view, 'next')
for (let b of BLOCKLIST) {
if (block_owner(b) === game.active && is_block_on_land(b))
if (list_seats(b).length > 1)
- gen_action(view, 'block', b);
+ gen_action(view, 'block', b)
}
if (errors.length > 0)
- view.prompt = "Deployment: Too many blocks in " + join(errors, "and") + ".";
+ view.prompt = "Deployment: Too many blocks in " + join(errors, "and") + "."
else
- view.prompt = "Deployment: You may make seat adjustments.";
+ view.prompt = "Deployment: You may make seat adjustments."
},
block: function (who) {
- push_undo();
- game.who = who;
- game.state = 'frank_deployment_to';
+ push_undo()
+ game.who = who
+ game.state = 'frank_deployment_to'
},
next: function () {
- clear_undo();
- goto_saracen_deployment();
+ clear_undo()
+ goto_saracen_deployment()
},
undo: pop_undo
}
@@ -1078,19 +1080,19 @@ states.frank_deployment = {
states.frank_deployment_to = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Deployment: Waiting for " + game.active + ".";
- view.prompt = "Deployment: Move " + game.who + " to " + join(list_seats(game.who), "or") + ".";
- gen_action_undo(view);
- gen_action(view, 'block', game.who);
- let from = game.location[game.who];
+ return view.prompt = "Deployment: Waiting for " + game.active + "."
+ view.prompt = "Deployment: Move " + game.who + " to " + join(list_seats(game.who), "or") + "."
+ gen_action_undo(view)
+ gen_action(view, 'block', game.who)
+ let from = game.location[game.who]
for (let town of list_seats(game.who))
if (town !== from)
- gen_action(view, 'town', town);
+ gen_action(view, 'town', town)
},
town: function (where) {
- game.location[game.who] = where;
- game.who = null;
- game.state = 'frank_deployment';
+ game.location[game.who] = where
+ game.who = null
+ game.state = 'frank_deployment'
},
block: pop_undo,
undo: pop_undo
@@ -1098,39 +1100,39 @@ states.frank_deployment_to = {
function goto_saracen_deployment() {
for (let i = 0; i < 4; ++i) {
- let nomad = select_random_block(S_POOL);
- log(BLOCKS[nomad].name + " arrived in " + block_home(nomad) + ".");
- deploy(nomad, block_home(nomad));
+ let nomad = select_random_block(S_POOL)
+ log(BLOCKS[nomad].name + " arrived in " + block_home(nomad) + ".")
+ deploy(nomad, block_home(nomad))
}
- game.active = SARACENS;
- game.state = 'saracen_deployment';
- game.who = SALADIN;
+ game.active = SARACENS
+ game.state = 'saracen_deployment'
+ game.who = SALADIN
}
states.saracen_deployment = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Deployment: Waiting for " + game.active + ".";
- view.prompt = "Deployment: You may swap places with Saladin and any other block of his family.";
- gen_action(view, 'next');
- gen_action_undo(view);
+ return view.prompt = "Deployment: Waiting for " + game.active + "."
+ view.prompt = "Deployment: You may swap places with Saladin and any other block of his family."
+ gen_action(view, 'next')
+ gen_action_undo(view)
if (game.location[SALADIN] === DAMASCUS) {
for (let b of SALADIN_FAMILY)
if (b !== SALADIN && game.location[b] !== game.location[SALADIN])
- gen_action(view, 'block', b);
+ gen_action(view, 'block', b)
}
},
block: function (who) {
- push_undo();
- let saladin = game.location[SALADIN];
- game.location[SALADIN] = game.location[who];
- game.location[who] = saladin;
- game.who = null;
+ push_undo()
+ let saladin = game.location[SALADIN]
+ game.location[SALADIN] = game.location[who]
+ game.location[who] = saladin
+ game.who = null
},
next: function () {
- clear_undo();
- game.who = null;
- start_year();
+ clear_undo()
+ game.who = null
+ start_year()
},
undo: pop_undo
}
@@ -1138,235 +1140,235 @@ states.saracen_deployment = {
// GAME TURN
function is_friendly_town_for_player(p, where) {
- return (count_player(enemy(p), where) === 0) && (count_player(p, where) > 0 || is_player_kingdom(p, where));
+ return (count_player(enemy(p), where) === 0) && (count_player(p, where) > 0 || is_player_kingdom(p, where))
}
function is_friendly_town_for_vp(p, town) {
if (is_friendly_town_for_player(p, town))
- return true;
+ return true
if (is_under_siege(town))
- return besieged_player(town) === p;
- return false;
+ return besieged_player(town) === p
+ return false
}
function count_victory_points(p) {
- let vp = 0;
+ let vp = 0
for (let town of VICTORY_TOWNS)
if (is_friendly_town_for_vp(p, town))
- ++ vp;
- return vp;
+ ++ vp
+ return vp
}
function check_sudden_death() {
if (count_victory_points(FRANKS) === 7) {
- game.state = 'game_over';
- game.result = FRANKS;
+ game.state = 'game_over'
+ game.result = FRANKS
game.victory = "Franks controlled all seven victory cities."
- log("");
- log(game.victory);
- return true;
+ log("")
+ log(game.victory)
+ return true
}
if (count_victory_points(SARACENS) === 7) {
- game.state = 'game_over';
- game.result = SARACENS;
+ game.state = 'game_over'
+ game.result = SARACENS
game.victory = "Saracens controlled all seven victory cities."
- log("");
- log(game.victory);
- return true;
+ log("")
+ log(game.victory)
+ return true
}
}
function start_year() {
- log("");
- log("Start Year " + game.year);
+ log("")
+ log("Start Year " + game.year)
- game.turn = 1;
+ game.turn = 1
- let deck = shuffle_deck();
- game.f_hand = deal_cards(deck, 6);
- game.s_hand = deal_cards(deck, 6);
- game.prior_f_card = 0;
- game.prior_s_card = 0;
+ let deck = shuffle_deck()
+ game.f_hand = deal_cards(deck, 6)
+ game.s_hand = deal_cards(deck, 6)
+ game.prior_f_card = 0
+ game.prior_s_card = 0
- start_game_turn();
+ start_game_turn()
}
function start_game_turn() {
- log("");
- log("Start Turn " + game.turn + " of Year " + game.year);
+ log("")
+ log("Start Turn " + game.turn + " of Year " + game.year)
- game.guide = null;
- game.jihad = null;
+ game.guide = null
+ game.jihad = null
// Reset movement and attack tracking state
- reset_road_limits();
- game.last_used = {};
- game.attacker = {};
- game.reserves1 = [];
- game.reserves2 = [];
- game.moved = {};
+ reset_road_limits()
+ game.last_used = {}
+ game.attacker = {}
+ game.reserves1 = []
+ game.reserves2 = []
+ game.moved = {}
- goto_card_phase();
+ goto_card_phase()
}
// CARD PHASE
function goto_card_phase() {
- game.f_card = 0;
- game.s_card = 0;
- game.show_cards = false;
- game.state = 'play_card';
- game.active = BOTH;
+ game.f_card = 0
+ game.s_card = 0
+ game.show_cards = false
+ game.state = 'play_card'
+ game.active = BOTH
}
function resume_play_card() {
if (game.s_card && game.f_card)
- reveal_cards();
+ reveal_cards()
else if (game.f_card)
- game.active = SARACENS;
+ game.active = SARACENS
else if (game.s_card)
- game.active = FRANKS;
+ game.active = FRANKS
else
- game.active = BOTH;
+ game.active = BOTH
}
states.play_card = {
prompt: function (view, current) {
if (current === OBSERVER) {
- view.prior_s_card = game.prior_s_card;
- view.prior_f_card = game.prior_f_card;
- return view.prompt = "Card Phase: Waiting for players to play a card.";
+ view.prior_s_card = game.prior_s_card
+ view.prior_f_card = game.prior_f_card
+ return view.prompt = "Card Phase: Waiting for players to play a card."
}
if (current === FRANKS) {
- view.prior_s_card = game.prior_s_card;
+ view.prior_s_card = game.prior_s_card
if (game.f_card) {
- view.prompt = "Card Phase: Waiting for Saracens to play a card.";
- gen_action(view, 'undo');
+ view.prompt = "Card Phase: Waiting for Saracens to play a card."
+ gen_action(view, 'undo')
} else {
- view.prior_f_card = game.prior_f_card;
- view.prompt = "Card Phase: Play a card.";
+ view.prior_f_card = game.prior_f_card
+ view.prompt = "Card Phase: Play a card."
for (let c of game.f_hand)
if (game.turn > 1 || c !== INTRIGUE)
- gen_action(view, 'play', c);
+ gen_action(view, 'play', c)
}
}
if (current === SARACENS) {
- view.prior_f_card = game.prior_f_card;
+ view.prior_f_card = game.prior_f_card
if (game.s_card) {
- view.prompt = "Card Phase: Waiting for Franks to play a card.";
- gen_action(view, 'undo');
+ view.prompt = "Card Phase: Waiting for Franks to play a card."
+ gen_action(view, 'undo')
} else {
- view.prior_s_card = game.prior_s_card;
- view.prompt = "Card Phase: Play a card.";
+ view.prior_s_card = game.prior_s_card
+ view.prompt = "Card Phase: Play a card."
for (let c of game.s_hand)
if (game.turn > 1 || c !== INTRIGUE)
- gen_action(view, 'play', c);
+ gen_action(view, 'play', c)
}
}
},
play: function (card, current) {
if (current === FRANKS) {
- remove_from_array(game.f_hand, card);
- game.f_card = card;
+ remove_from_array(game.f_hand, card)
+ game.f_card = card
}
if (current === SARACENS) {
- remove_from_array(game.s_hand, card);
- game.s_card = card;
+ remove_from_array(game.s_hand, card)
+ game.s_card = card
}
- resume_play_card();
+ resume_play_card()
},
undo: function (_, current) {
if (current === FRANKS) {
- game.f_hand.push(game.f_card);
- game.f_card = 0;
+ game.f_hand.push(game.f_card)
+ game.f_card = 0
}
if (current === SARACENS) {
- game.s_hand.push(game.s_card);
- game.s_card = 0;
+ game.s_hand.push(game.s_card)
+ game.s_card = 0
}
- resume_play_card();
+ resume_play_card()
}
}
function reveal_cards() {
- log("");
- log("Franks played " + CARDS[game.f_card].name + ".");
- log("Saracens played " + CARDS[game.s_card].name + ".");
- game.show_cards = true;
+ log("")
+ log("Franks played " + CARDS[game.f_card].name + ".")
+ log("Saracens played " + CARDS[game.s_card].name + ".")
+ game.show_cards = true
if (CARDS[game.f_card].event && CARDS[game.s_card].event) {
- log("Game Turn cancelled.");
- game.prior_f_card = game.f_card;
- game.prior_s_card = game.s_card;
- end_game_turn();
- return;
+ log("Game Turn cancelled.")
+ game.prior_f_card = game.f_card
+ game.prior_s_card = game.s_card
+ end_game_turn()
+ return
}
if (game.f_card === INTRIGUE) {
- game.f_card = game.prior_s_card;
- log("Intrigue copied " + CARDS[game.f_card].name + ".");
+ game.f_card = game.prior_s_card
+ log("Intrigue copied " + CARDS[game.f_card].name + ".")
}
if (game.s_card === INTRIGUE) {
- game.s_card = game.prior_f_card;
- log("Intrigue copied " + CARDS[game.s_card].name + ".");
+ game.s_card = game.prior_f_card
+ log("Intrigue copied " + CARDS[game.s_card].name + ".")
}
- delete game.winter_campaign;
+ delete game.winter_campaign
if (is_winter()) {
if (game.f_card === WINTER_CAMPAIGN)
- game.winter_campaign = FRANKS;
+ game.winter_campaign = FRANKS
if (game.s_card === WINTER_CAMPAIGN)
- game.winter_campaign = SARACENS;
+ game.winter_campaign = SARACENS
}
- game.prior_f_card = game.f_card;
- game.prior_s_card = game.s_card;
+ game.prior_f_card = game.f_card
+ game.prior_s_card = game.s_card
- let fp = CARDS[game.f_card].event ? 10 : CARDS[game.f_card].moves;
- let sp = CARDS[game.s_card].event ? 10 : CARDS[game.s_card].moves;
+ let fp = CARDS[game.f_card].event ? 10 : CARDS[game.f_card].moves
+ let sp = CARDS[game.s_card].event ? 10 : CARDS[game.s_card].moves
if (fp === sp) {
- let die = roll_d6();
- log("Random first player.");
+ let die = roll_d6()
+ log("Random first player.")
if (die > 3)
- ++fp;
+ ++fp
else
- ++sp;
+ ++sp
}
if (fp > sp) {
- game.p1 = FRANKS;
- game.p2 = SARACENS;
+ game.p1 = FRANKS
+ game.p2 = SARACENS
} else {
- game.p1 = SARACENS;
- game.p2 = FRANKS;
+ game.p1 = SARACENS
+ game.p2 = FRANKS
}
- game.active = game.p1;
- start_player_turn();
+ game.active = game.p1
+ start_player_turn()
}
function start_player_turn() {
- log("");
- log("Start " + game.active);
- reset_road_limits();
- game.main_road = {};
- let card = CARDS[game.active === FRANKS ? game.f_card : game.s_card];
+ log("")
+ log("Start " + game.active)
+ reset_road_limits()
+ game.main_road = {}
+ let card = CARDS[game.active === FRANKS ? game.f_card : game.s_card]
if (card.event)
- goto_event_card(card.event);
+ goto_event_card(card.event)
else
- goto_move_phase(card.moves);
+ goto_move_phase(card.moves)
}
function end_player_turn() {
- game.moves = 0;
- game.main_road = null;
+ game.moves = 0
+ game.main_road = null
if (game.active === game.p2) {
- goto_combat_phase();
+ goto_combat_phase()
} else {
- game.active = game.p2;
- start_player_turn();
+ game.active = game.p2
+ start_player_turn()
}
}
@@ -1374,66 +1376,66 @@ function end_player_turn() {
function goto_event_card(event) {
switch (event) {
- case 'assassins': goto_assassins(); break;
- case 'guide': goto_guide(); break;
- case 'jihad': goto_jihad(); break;
- case 'manna': goto_manna(); break;
+ case 'assassins': goto_assassins(); break
+ case 'guide': goto_guide(); break
+ case 'jihad': goto_jihad(); break
+ case 'manna': goto_manna(); break
}
}
function goto_assassins() {
- game.state = 'assassins';
- game.who = ASSASSINS;
+ game.state = 'assassins'
+ game.who = ASSASSINS
}
states.assassins = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Assassins: Waiting for " + game.active + ".";
- view.prompt = "Assassins: Choose one enemy block.";
+ return view.prompt = "Assassins: Waiting for " + game.active + "."
+ view.prompt = "Assassins: Choose one enemy block."
for (let b of BLOCKLIST) {
if (is_block_on_land(b) && block_owner(b) === enemy(game.active))
- gen_action(view, 'block', b);
+ gen_action(view, 'block', b)
}
},
block: function (who) {
- game.where = game.location[who];
- game.who = select_random_enemy_block(game.where);
- game.location[ASSASSINS] = game.where;
- game.state = 'assassins_show_1';
+ game.where = game.location[who]
+ game.who = select_random_enemy_block(game.where)
+ game.location[ASSASSINS] = game.where
+ game.state = 'assassins_show_1'
},
}
states.assassins_show_1 = {
prompt: function (view, current) {
- view.assassinate = game.who;
- view.who = ASSASSINS;
+ view.assassinate = game.who
+ view.who = ASSASSINS
if (is_inactive_player(current))
- return view.prompt = "Assassins: Waiting for " + game.active + ".";
- view.prompt = "Assassins: The assassins target " + block_name(game.who) + " in " + game.where + ".";
- gen_action(view, 'next');
- gen_action(view, 'block', game.who);
- gen_action(view, 'block', ASSASSINS);
+ return view.prompt = "Assassins: Waiting for " + game.active + "."
+ view.prompt = "Assassins: The assassins target " + block_name(game.who) + " in " + game.where + "."
+ gen_action(view, 'next')
+ gen_action(view, 'block', game.who)
+ gen_action(view, 'block', ASSASSINS)
},
next: assassins_next_1,
block: assassins_next_1,
}
function assassins_next_1() {
- assassinate(game.who, game.where);
- game.state = 'assassins_show_2';
+ assassinate(game.who, game.where)
+ game.state = 'assassins_show_2'
}
states.assassins_show_2 = {
prompt: function (view, current) {
- view.assassinate = game.who;
- view.who = ASSASSINS;
+ view.assassinate = game.who
+ view.who = ASSASSINS
if (is_inactive_player(current))
- return view.prompt = "Assassins: Waiting for " + game.active + ".";
- view.prompt = "Assassins: The assassins hit " + block_name(game.who) + " in " + game.where + ".";
- gen_action(view, 'next');
- gen_action(view, 'block', ASSASSINS);
- gen_action(view, 'town', MASYAF);
+ return view.prompt = "Assassins: Waiting for " + game.active + "."
+ view.prompt = "Assassins: The assassins hit " + block_name(game.who) + " in " + game.where + "."
+ gen_action(view, 'next')
+ gen_action(view, 'block', ASSASSINS)
+ gen_action(view, 'town', MASYAF)
},
next: assassins_next_2,
block: assassins_next_2,
@@ -1441,111 +1443,111 @@ states.assassins_show_2 = {
}
function assassins_next_2() {
- lift_siege(game.where);
- game.location[ASSASSINS] = MASYAF;
- game.who = null;
- game.where = null;
- end_player_turn();
+ lift_siege(game.where)
+ game.location[ASSASSINS] = MASYAF
+ game.who = null
+ game.where = null
+ end_player_turn()
}
function assassinate(who, where) {
- let hits = 0;
- let rolls = [];
+ let hits = 0
+ let rolls = []
for (let i = 0; i < 3; ++i) {
- let die = roll_d6();
+ let die = roll_d6()
if (die <= 3) {
- rolls.push(DIE_HIT[die]);
- ++hits;
+ rolls.push(DIE_HIT[die])
+ ++hits
} else {
- rolls.push(DIE_MISS[die]);
+ rolls.push(DIE_MISS[die])
}
}
- hits = Math.min(hits, game.steps[who]);
- log("Assassins hit " + block_name(who) + " in " + where + ": " + rolls.join("") + ".");
+ hits = Math.min(hits, game.steps[who])
+ log("Assassins hit " + block_name(who) + " in " + where + ": " + rolls.join("") + ".")
for (let i = 0; i < hits; ++i)
- reduce_block(who);
+ reduce_block(who)
}
function goto_guide() {
- game.guide = game.active;
- game.state = 'move_phase_event';
- game.summary = [];
+ game.guide = game.active
+ game.state = 'move_phase_event'
+ game.summary = []
}
function goto_jihad() {
- game.jihad = game.active;
- game.state = 'move_phase_event';
- game.summary = [];
+ game.jihad = game.active
+ game.state = 'move_phase_event'
+ game.summary = []
}
function goto_select_jihad() {
- game.jihad_list = [];
+ game.jihad_list = []
for (let where of TOWNLIST)
if (is_contested_field(where) || besieging_player(where) === game.active)
- game.jihad_list.push(where);
+ game.jihad_list.push(where)
if (game.jihad_list.length === 0) {
- delete game.jihad_list;
- return end_player_turn();
+ delete game.jihad_list
+ return end_player_turn()
}
if (game.jihad_list.length === 1) {
- game.jihad = game.jihad_list[0];
- log("Jihad in " + game.jihad + ".");
- delete game.jihad_list;
- return end_player_turn();
+ game.jihad = game.jihad_list[0]
+ log("Jihad in " + game.jihad + ".")
+ delete game.jihad_list
+ return end_player_turn()
}
- game.state = 'select_jihad';
+ game.state = 'select_jihad'
}
states.select_jihad = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Jihad: Waiting for " + game.active + ".";
- view.prompt = "Jihad: Select battle for Jihad.";
+ return view.prompt = "Jihad: Waiting for " + game.active + "."
+ view.prompt = "Jihad: Select battle for Jihad."
for (let town of game.jihad_list)
- gen_action(view, 'town', town);
+ gen_action(view, 'town', town)
},
town: function (where) {
- game.jihad = where;
- log("Jihad in " + game.jihad + ".");
- delete game.jihad_list;
- end_player_turn();
+ game.jihad = where
+ log("Jihad in " + game.jihad + ".")
+ delete game.jihad_list
+ end_player_turn()
},
}
function goto_manna() {
- game.state = 'manna';
- game.moves = 3;
- game.moved = {};
- game.summary = [];
+ game.state = 'manna'
+ game.moves = 3
+ game.moved = {}
+ game.summary = []
}
states.manna = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Manna: Waiting for " + game.active + ".";
- view.prompt = "Manna: Add one step to three different friendly blocks \u2014 " + game.moves + " left.";
- gen_action_undo(view);
- gen_action(view, 'next');
+ return view.prompt = "Manna: Waiting for " + game.active + "."
+ view.prompt = "Manna: Add one step to three different friendly blocks \u2014 " + game.moves + " left."
+ gen_action_undo(view)
+ gen_action(view, 'next')
if (game.moves > 0) {
for (let b of BLOCKLIST) {
if (is_block_on_land(b) && block_owner(b) === game.active && !game.moved[b])
if (game.steps[b] < block_max_steps(b))
- gen_action(view, 'block', b);
+ gen_action(view, 'block', b)
}
}
},
block: function (who) {
- push_undo();
- game.summary.push([game.location[who]]);
- ++game.steps[who];
- --game.moves;
- game.moved[who] = 1;
+ push_undo()
+ game.summary.push([game.location[who]])
+ ++game.steps[who]
+ --game.moves
+ game.moved[who] = 1
},
next: function () {
- clear_undo();
- print_summary(game.active + " used Manna:");
- game.moved = {};
- end_player_turn();
+ clear_undo()
+ print_summary(game.active + " used Manna:")
+ game.moved = {}
+ end_player_turn()
},
undo: pop_undo
}
@@ -1554,102 +1556,102 @@ states.manna = {
function queue_attack(who, round) {
if (round === 1)
- return ATTACK_MARK;
+ return ATTACK_MARK
if (round === 2) {
- game.reserves1.push(who);
- return RESERVE_MARK_1;
+ game.reserves1.push(who)
+ return RESERVE_MARK_1
}
if (round === 3) {
- game.reserves2.push(who);
- return RESERVE_MARK_2;
+ game.reserves2.push(who)
+ return RESERVE_MARK_2
}
}
function move_block(who, from, to) {
- game.location[who] = to;
- game.road_limit[road_id(from, to)] = road_limit(from, to) + 1;
- game.distance ++;
+ game.location[who] = to
+ game.road_limit[road_id(from, to)] = road_limit(from, to) + 1
+ game.distance ++
if (is_contested_field(to)) {
- game.last_used[road_id(from, to)] = game.active;
+ game.last_used[road_id(from, to)] = game.active
// 6.56 Main Attack relief force by Player 2 arrives one round later than normal
- let relief_delay = 0;
+ let relief_delay = 0
if (game.active === game.p2 && besieged_player(to) === game.p2) {
- relief_delay = 1;
+ relief_delay = 1
}
if (!game.attacker[to]) {
- game.attacker[to] = game.active;
- game.main_road[to] = from;
- return queue_attack(who, 1 + relief_delay);
+ game.attacker[to] = game.active
+ game.main_road[to] = from
+ return queue_attack(who, 1 + relief_delay)
} else {
// Attacker main attack or reinforcements
if (game.attacker[to] === game.active) {
if (game.main_road[to] !== from)
- return queue_attack(who, 2 + relief_delay);
- return queue_attack(who, 1 + relief_delay);
+ return queue_attack(who, 2 + relief_delay)
+ return queue_attack(who, 1 + relief_delay)
}
// Defender reinforcements
if (!game.main_road[to])
- game.main_road[to] = from;
+ game.main_road[to] = from
if (game.main_road[to] === from) {
- return queue_attack(who, 2);
+ return queue_attack(who, 2)
} else {
- return queue_attack(who, 3);
+ return queue_attack(who, 3)
}
}
}
- return false;
+ return false
}
function goto_move_phase(moves) {
- game.state = 'move_phase';
- game.moves = moves;
+ game.state = 'move_phase'
+ game.moves = moves
}
function end_move_phase() {
if (game.moves > 0) {
- push_undo();
- game.state = 'confirm_end_move_phase';
- return;
+ push_undo()
+ game.state = 'confirm_end_move_phase'
+ return
}
- clear_undo();
- game.who = null;
- game.where = null;
- game.moves = 0;
+ clear_undo()
+ game.who = null
+ game.where = null
+ game.moves = 0
// declined to use winter campaign
if (game.winter_campaign === game.active)
- delete game.winter_campaign;
+ delete game.winter_campaign
if (game.active === game.jihad)
- goto_select_jihad();
+ goto_select_jihad()
else
- end_player_turn();
+ end_player_turn()
}
states.confirm_end_move_phase = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Move Phase: Waiting for " + game.active + ".";
+ return view.prompt = "Move Phase: Waiting for " + game.active + "."
if (game.moves > 1)
- view.prompt = "Move Phase: You have " + game.moves + " moves left";
+ view.prompt = "Move Phase: You have " + game.moves + " moves left"
else
- view.prompt = "Move Phase: You have 1 move left";
- view.prompt += " \u2014 are you sure you want to end the move phase?";
- gen_action_undo(view);
- gen_action(view, 'end_move_phase');
+ view.prompt = "Move Phase: You have 1 move left"
+ view.prompt += " \u2014 are you sure you want to end the move phase?"
+ gen_action_undo(view)
+ gen_action(view, 'end_move_phase')
},
end_move_phase: function () {
if (game.moves === 1)
- log(game.active + " did nothing with " + game.moves + " move.");
+ log(game.active + " did nothing with " + game.moves + " move.")
else
- log(game.active + " did nothing with " + game.moves + " moves.");
- game.moves = 0;
- end_move_phase();
+ log(game.active + " did nothing with " + game.moves + " moves.")
+ game.moves = 0
+ end_move_phase()
},
undo: pop_undo
}
@@ -1657,51 +1659,51 @@ states.confirm_end_move_phase = {
states.move_phase = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Move Phase: Waiting for " + game.active + ".";
+ return view.prompt = "Move Phase: Waiting for " + game.active + "."
if (game.moves === 0)
- view.prompt = "Move Phase: No moves left.";
+ view.prompt = "Move Phase: No moves left."
else if (game.moves === 1)
- view.prompt = "Move Phase: 1 move left.";
+ view.prompt = "Move Phase: 1 move left."
else
- view.prompt = "Move Phase: " + game.moves + " moves left.";
- gen_action_undo(view);
- gen_action(view, 'end_move_phase');
+ view.prompt = "Move Phase: " + game.moves + " moves left."
+ gen_action_undo(view)
+ gen_action(view, 'end_move_phase')
if (game.moves > 0) {
for (let b of BLOCKLIST) {
if (can_block_land_move(b))
- gen_action(view, 'block', b);
+ gen_action(view, 'block', b)
if (can_block_sea_move(b))
- gen_action(view, 'block', b);
+ gen_action(view, 'block', b)
if (can_germans_move(b))
- gen_action(view, 'block', b);
+ gen_action(view, 'block', b)
}
if (can_muster_anywhere())
- gen_action(view, 'muster');
+ gen_action(view, 'muster')
if (game.winter_campaign === game.active)
- gen_action(view, 'winter_campaign');
+ gen_action(view, 'winter_campaign')
}
},
winter_campaign: function () {
- push_undo();
- --game.moves;
- game.state = 'winter_campaign';
+ push_undo()
+ --game.moves
+ game.state = 'winter_campaign'
},
muster: function () {
- push_undo();
- --game.moves;
- game.state = 'muster';
+ push_undo()
+ --game.moves
+ game.state = 'muster'
},
block: function (who) {
- push_undo();
- game.summary = [];
- game.who = who;
- game.where = game.location[who];
+ push_undo()
+ game.summary = []
+ game.who = who
+ game.where = game.location[who]
if (game.where === GERMANIA) {
- game.state = 'german_move_to';
+ game.state = 'german_move_to'
} else if (game.where === FRANCE || game.where === ENGLAND) {
- game.state = 'sea_move_to';
+ game.state = 'sea_move_to'
} else {
- game.state = 'move_phase_to';
+ game.state = 'move_phase_to'
}
},
end_move_phase: end_move_phase,
@@ -1711,21 +1713,21 @@ states.move_phase = {
states.move_phase_event = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = group_move_name(1) + "Waiting for " + game.active + ".";
- view.prompt = group_move_name(0) + "Choose a block to group move.";
- gen_action_undo(view);
- gen_action(view, 'end_move_phase');
+ return view.prompt = group_move_name(1) + "Waiting for " + game.active + "."
+ view.prompt = group_move_name(0) + "Choose a block to group move."
+ gen_action_undo(view)
+ gen_action(view, 'end_move_phase')
for (let b of BLOCKLIST)
if (can_block_land_move(b))
- gen_action(view, 'block', b);
+ gen_action(view, 'block', b)
},
block: function (who) {
- push_undo();
- game.where = game.location[who];
- game.who = who;
- game.distance = 0;
- game.last_from = null;
- game.state = 'group_move_to';
+ push_undo()
+ game.where = game.location[who]
+ game.who = who
+ game.distance = 0
+ game.last_from = null
+ game.state = 'group_move_to'
},
end_move_phase: end_move_phase,
undo: pop_undo
@@ -1735,55 +1737,55 @@ states.move_phase_event = {
states.move_phase_to = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Move Phase: Waiting for " + game.active + ".";
- view.prompt = "Move Phase: Move " + block_name(game.who);
- gen_action_undo(view);
- gen_action(view, 'block', game.who);
- let from = game.location[game.who];
- let can_group_move = false;
- let can_sea_move = false;
+ return view.prompt = "Move Phase: Waiting for " + game.active + "."
+ view.prompt = "Move Phase: Move " + block_name(game.who)
+ gen_action_undo(view)
+ gen_action(view, 'block', game.who)
+ let from = game.location[game.who]
+ let can_group_move = false
+ let can_sea_move = false
if (can_block_land_move(game.who)) {
for (let to of TOWNS[from].exits) {
if (can_block_land_move_to(game.who, from, to)) {
- gen_action(view, 'town', to);
- can_group_move = true;
+ gen_action(view, 'town', to)
+ can_group_move = true
}
}
}
if (can_block_sea_move(game.who)) {
- gen_action(view, 'town', SEA);
- can_sea_move = true;
+ gen_action(view, 'town', SEA)
+ can_sea_move = true
}
if (can_group_move && can_sea_move)
- view.prompt += " by road or by sea.";
+ view.prompt += " by road or by sea."
else if (can_sea_move)
- view.prompt += " by sea.";
+ view.prompt += " by sea."
else
- view.prompt += " by road.";
+ view.prompt += " by road."
},
town: function (to) {
- let from = game.location[game.who];
+ let from = game.location[game.who]
if (to === SEA) {
- log_move_start(from);
- log_move_continue(to);
- game.location[game.who] = SEA;
- game.state = 'sea_move_to';
- return;
- }
- -- game.moves;
- game.distance = 0;
- log_move_start(from);
- let mark = move_block(game.who, from, to);
+ log_move_start(from)
+ log_move_continue(to)
+ game.location[game.who] = SEA
+ game.state = 'sea_move_to'
+ return
+ }
+ -- game.moves
+ game.distance = 0
+ log_move_start(from)
+ let mark = move_block(game.who, from, to)
if (mark)
- log_move_continue(to + mark);
+ log_move_continue(to + mark)
else
- log_move_continue(to);
- lift_siege(from);
- game.last_from = from;
+ log_move_continue(to)
+ lift_siege(from)
+ game.last_from = from
if (!can_block_continue(game.who, from, to))
- end_move();
+ end_move()
else {
- game.state = 'group_move_to';
+ game.state = 'group_move_to'
}
},
block: pop_undo,
@@ -1793,44 +1795,44 @@ states.move_phase_to = {
// GROUP MOVE
function group_move_name() {
- if (game.active === game.jihad) return "Jihad: ";
- if (game.active === game.guide) return "Guide: ";
- return "Group Move: ";
+ if (game.active === game.jihad) return "Jihad: "
+ if (game.active === game.guide) return "Guide: "
+ return "Group Move: "
}
function can_group_move_more() {
for (let b of BLOCKLIST)
if (game.location[b] === game.where)
if (can_block_land_move(b))
- return true;
- return false;
+ return true
+ return false
}
states.group_move_who = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = group_move_name(1) + "Waiting for " + game.active + ".";
- view.prompt = group_move_name(0) + "Move blocks from " + game.where + ".";
- gen_action_undo(view);
+ return view.prompt = group_move_name(1) + "Waiting for " + game.active + "."
+ view.prompt = group_move_name(0) + "Move blocks from " + game.where + "."
+ gen_action_undo(view)
if (game.active === game.guide || game.active === game.jihad)
- gen_action(view, 'end_move_phase');
+ gen_action(view, 'end_move_phase')
else
- gen_action(view, 'end_group_move');
+ gen_action(view, 'end_group_move')
for (let b of BLOCKLIST)
if (game.location[b] === game.where)
if (can_block_land_move(b))
- gen_action(view, 'block', b);
+ gen_action(view, 'block', b)
},
block: function (who) {
- push_undo();
- game.who = who;
- game.distance = 0;
- game.last_from = null;
- game.state = 'group_move_to';
+ push_undo()
+ game.who = who
+ game.distance = 0
+ game.last_from = null
+ game.state = 'group_move_to'
},
end_move_phase: function () {
- end_group_move();
- end_move_phase();
+ end_group_move()
+ end_move_phase()
},
end_group_move: end_group_move,
undo: pop_undo
@@ -1839,40 +1841,40 @@ states.group_move_who = {
states.group_move_to = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = group_move_name(1) + "Waiting for " + game.active + ".";
- view.prompt = group_move_name(0) + "Move " + block_name(game.who) + ".";
- gen_action_undo(view);
+ return view.prompt = group_move_name(1) + "Waiting for " + game.active + "."
+ view.prompt = group_move_name(0) + "Move " + block_name(game.who) + "."
+ gen_action_undo(view)
if (game.distance === 0)
- gen_action(view, 'block', game.who);
- let from = game.location[game.who];
+ gen_action(view, 'block', game.who)
+ let from = game.location[game.who]
if (game.distance > 0) {
// cannot start or reinforce battles in winter
if (!(is_winter() && is_enemy_occupied_town(from)))
- gen_action(view, 'town', from);
+ gen_action(view, 'town', from)
}
for (let to of TOWNS[from].exits) {
if (to !== game.last_from && can_block_land_move_to(game.who, from, to)) {
- gen_action(view, 'town', to);
+ gen_action(view, 'town', to)
}
}
},
town: function (to) {
- let from = game.location[game.who];
+ let from = game.location[game.who]
if (to === from) {
- end_move();
- return;
+ end_move()
+ return
}
if (game.distance === 0)
- log_move_start(from);
- let mark = move_block(game.who, from, to);
+ log_move_start(from)
+ let mark = move_block(game.who, from, to)
if (mark)
- log_move_continue(to + mark);
+ log_move_continue(to + mark)
else
- log_move_continue(to);
- lift_siege(from);
- game.last_from = from;
+ log_move_continue(to)
+ lift_siege(from)
+ game.last_from = from
if (!can_block_continue(game.who, from, to))
- end_move();
+ end_move()
},
block: pop_undo,
undo: pop_undo
@@ -1880,19 +1882,19 @@ states.group_move_to = {
function end_move() {
if (game.distance > 0)
- game.moved[game.who] = 1;
- log_move_end();
- game.who = null;
- game.distance = 0;
+ game.moved[game.who] = 1
+ log_move_end()
+ game.who = null
+ game.distance = 0
if (can_group_move_more())
- game.state = 'group_move_who';
+ game.state = 'group_move_who'
else
- end_group_move();
+ end_group_move()
}
function end_group_move() {
- print_summary(game.active + " activated " + game.where + ":");
- game.state = 'move_phase';
+ print_summary(game.active + " activated " + game.where + ":")
+ game.state = 'move_phase'
}
// SEA MOVE
@@ -1900,27 +1902,27 @@ function end_group_move() {
states.german_move_to = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Move Phase: Waiting for " + game.active + ".";
- view.prompt = "Move Phase: Move " + block_name(game.who) + " to Aleppo, Antioch, or St. Simeon.";
- gen_action_undo(view);
- gen_action(view, 'block', game.who);
+ return view.prompt = "Move Phase: Waiting for " + game.active + "."
+ view.prompt = "Move Phase: Move " + block_name(game.who) + " to Aleppo, Antioch, or St. Simeon."
+ gen_action_undo(view)
+ gen_action(view, 'block', game.who)
for (let to of GERMAN_ROADS)
if (can_germans_move_to(game.who, to))
- gen_action(view, 'town', to);
+ gen_action(view, 'town', to)
},
town: function (to) {
- --game.moves;
- let from = GERMANIA;
- game.location[game.who] = to;
- game.moved[game.who] = 1;
- game.distance = 0;
- let mark = move_block(game.who, from, to);
+ --game.moves
+ let from = GERMANIA
+ game.location[game.who] = to
+ game.moved[game.who] = 1
+ game.distance = 0
+ let mark = move_block(game.who, from, to)
if (mark)
- log(game.active + " moved:\n Germania \u2192 " + to + mark + ".");
+ log(game.active + " moved:\n Germania \u2192 " + to + mark + ".")
else
- log(game.active + " moved:\n Germania \u2192 " + to + ".");
- game.who = null;
- game.state = 'move_phase';
+ log(game.active + " moved:\n Germania \u2192 " + to + ".")
+ game.who = null
+ game.state = 'move_phase'
},
block: pop_undo,
undo: pop_undo,
@@ -1929,53 +1931,53 @@ states.german_move_to = {
states.sea_move_to = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Move Phase: Waiting for " + game.active + ".";
+ return view.prompt = "Move Phase: Waiting for " + game.active + "."
if (is_english_crusader(game.who))
- view.prompt = "Sea Move: Move " + block_name(game.who) + " to a port.";
+ view.prompt = "Sea Move: Move " + block_name(game.who) + " to a port."
else
- view.prompt = "Sea Move: Move " + block_name(game.who) + " to a friendly port.";
- gen_action_undo(view);
- gen_action(view, 'block', game.who);
- let from = game.location[game.who];
+ view.prompt = "Sea Move: Move " + block_name(game.who) + " to a friendly port."
+ gen_action_undo(view)
+ gen_action(view, 'block', game.who)
+ let from = game.location[game.who]
if (from === GERMANIA) {
for (let to of GERMAN_ROADS)
if (can_germans_move_to(game.who, to))
- gen_action(view, 'town', to);
+ gen_action(view, 'town', to)
} else {
for (let to of PORTS)
if (to !== game.where && can_block_sea_move_to(game.who, to))
- gen_action(view, 'town', to);
+ gen_action(view, 'town', to)
}
},
town: function (to) {
- --game.moves;
+ --game.moves
- let from = game.where;
- game.location[game.who] = to;
- game.moved[game.who] = 1;
+ let from = game.where
+ game.location[game.who] = to
+ game.moved[game.who] = 1
- lift_siege(from);
+ lift_siege(from)
- remove_from_array(game.castle, game.who);
+ remove_from_array(game.castle, game.who)
if (besieged_player(to) === game.active && is_more_room_in_castle(to)) {
// Move into besieged fortified port
- game.castle.push(game.who);
- log(game.active + " sea moved:\n" + from + " \u2192 " + to + " castle.");
+ game.castle.push(game.who)
+ log(game.active + " sea moved:\n" + from + " \u2192 " + to + " castle.")
} else if (!is_friendly_port(to)) {
// English Crusaders attack!
- game.attacker[to] = FRANKS;
- game.main_road[to] = "England";
- log(game.active + " sea moved:\n" + from + " \u2192 " + to + ATTACK_MARK + ".");
+ game.attacker[to] = FRANKS
+ game.main_road[to] = "England"
+ log(game.active + " sea moved:\n" + from + " \u2192 " + to + ATTACK_MARK + ".")
} else {
// Normal move.
- log(game.active + " sea moved:\n" + from + " \u2192 " + to + ".");
+ log(game.active + " sea moved:\n" + from + " \u2192 " + to + ".")
}
- game.who = null;
- game.state = 'move_phase';
+ game.who = null
+ game.state = 'move_phase'
},
block: pop_undo,
undo: pop_undo,
@@ -1986,27 +1988,27 @@ states.sea_move_to = {
states.muster = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Move Phase: Waiting for " + game.active + ".";
- view.prompt = "Muster: Choose a friendly muster town.";
- gen_action_undo(view);
+ return view.prompt = "Move Phase: Waiting for " + game.active + "."
+ view.prompt = "Muster: Choose a friendly muster town."
+ gen_action_undo(view)
for (let where of TOWNLIST) {
// cannot start or reinforce battles in winter
if (is_winter()) {
if (is_friendly_town(where))
if (can_muster_to(where))
- gen_action(view, 'town', where);
+ gen_action(view, 'town', where)
} else {
if (is_friendly_field(where))
if (can_muster_to(where))
- gen_action(view, 'town', where);
+ gen_action(view, 'town', where)
}
}
},
town: function (where) {
- push_undo();
- game.where = where;
- game.state = 'muster_who';
- game.summary = [];
+ push_undo()
+ game.where = where
+ game.state = 'muster_who'
+ game.summary = []
},
undo: pop_undo,
}
@@ -2014,24 +2016,24 @@ states.muster = {
states.muster_who = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Move Phase: Waiting for " + game.active + ".";
- view.prompt = "Muster: Move blocks to " + game.where + ".";
- view.muster = game.where;
- gen_action_undo(view);
- gen_action(view, 'end_muster');
+ return view.prompt = "Move Phase: Waiting for " + game.active + "."
+ view.prompt = "Muster: Move blocks to " + game.where + "."
+ view.muster = game.where
+ gen_action_undo(view)
+ gen_action(view, 'end_muster')
for (let b of BLOCKLIST)
if (can_block_muster(b, game.where))
- gen_action(view, 'block', b);
+ gen_action(view, 'block', b)
},
block: function (who) {
- push_undo();
- game.who = who;
- game.state = 'muster_move_1';
+ push_undo()
+ game.who = who
+ game.state = 'muster_move_1'
},
end_muster: function () {
- print_summary(game.active + " mustered to " + game.where + ":");
- game.where = null;
- game.state = 'move_phase';
+ print_summary(game.active + " mustered to " + game.where + ":")
+ game.where = null
+ game.state = 'move_phase'
},
undo: pop_undo,
}
@@ -2039,39 +2041,39 @@ states.muster_who = {
states.muster_move_1 = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Move Phase: Waiting for " + game.active + ".";
- view.prompt = "Muster: Move " + block_name(game.who) + " to " + game.where + ".";
- view.muster = game.where;
- gen_action_undo(view);
- gen_action(view, 'block', game.who);
- let from = game.location[game.who];
- let muster = game.where;
+ return view.prompt = "Move Phase: Waiting for " + game.active + "."
+ view.prompt = "Muster: Move " + block_name(game.who) + " to " + game.where + "."
+ view.muster = game.where
+ gen_action_undo(view)
+ gen_action(view, 'block', game.who)
+ let from = game.location[game.who]
+ let muster = game.where
if (block_move(game.who) === 3) {
for (let to of TOWNS[from].exits) {
if (can_block_use_road_to_muster(from, to)) {
if (to === muster || can_block_muster_with_2_moves(to, muster, from))
- gen_action(view, 'town', to);
+ gen_action(view, 'town', to)
}
}
} else {
for (let to of TOWNS[from].exits) {
if (can_block_use_road_to_muster(from, to)) {
if (to === muster || can_block_muster_with_1_move(to, muster))
- gen_action(view, 'town', to);
+ gen_action(view, 'town', to)
}
}
}
},
town: function (to) {
- let from = game.location[game.who];
- log_move_start(from);
- log_move_continue(to);
- move_block(game.who, from, to);
- lift_siege(from);
+ let from = game.location[game.who]
+ log_move_start(from)
+ log_move_continue(to)
+ move_block(game.who, from, to)
+ lift_siege(from)
if (to === game.where) {
- end_muster_move();
+ end_muster_move()
} else {
- game.state = 'muster_move_2';
+ game.state = 'muster_move_2'
}
},
block: pop_undo,
@@ -2081,36 +2083,36 @@ states.muster_move_1 = {
states.muster_move_2 = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Move Phase: Waiting for " + game.active + ".";
- view.prompt = "Muster: Move " + block_name(game.who) + " to " + game.where + ".";
- view.muster = game.where;
- gen_action_undo(view);
- let from = game.location[game.who];
- let muster = game.where;
+ return view.prompt = "Move Phase: Waiting for " + game.active + "."
+ view.prompt = "Muster: Move " + block_name(game.who) + " to " + game.where + "."
+ view.muster = game.where
+ gen_action_undo(view)
+ let from = game.location[game.who]
+ let muster = game.where
if (block_move(game.who) === 3) {
for (let to of TOWNS[from].exits) {
if (can_block_use_road_to_muster(from, to)) {
if (to === muster || can_block_muster_with_1_move(to, muster))
- gen_action(view, 'town', to);
+ gen_action(view, 'town', to)
}
}
} else {
for (let to of TOWNS[from].exits) {
if (can_block_use_road_to_muster(from, to)) {
if (to === muster)
- gen_action(view, 'town', to);
+ gen_action(view, 'town', to)
}
}
}
},
town: function (to) {
- let from = game.location[game.who];
- log_move_continue(to);
- move_block(game.who, from, to);
+ let from = game.location[game.who]
+ log_move_continue(to)
+ move_block(game.who, from, to)
if (to === game.where) {
- end_muster_move();
+ end_muster_move()
} else {
- game.state = 'muster_move_3';
+ game.state = 'muster_move_3'
}
},
undo: pop_undo,
@@ -2119,33 +2121,33 @@ states.muster_move_2 = {
states.muster_move_3 = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Move Phase: Waiting for " + game.active + ".";
- view.prompt = "Muster: Move " + block_name(game.who) + " to " + game.where + ".";
- view.muster = game.where;
- gen_action_undo(view);
- let from = game.location[game.who];
- let muster = game.where;
+ return view.prompt = "Move Phase: Waiting for " + game.active + "."
+ view.prompt = "Muster: Move " + block_name(game.who) + " to " + game.where + "."
+ view.muster = game.where
+ gen_action_undo(view)
+ let from = game.location[game.who]
+ let muster = game.where
for (let to of TOWNS[from].exits) {
if (can_block_use_road_to_muster(from, to)) {
if (to === muster)
- gen_action(view, 'town', to);
+ gen_action(view, 'town', to)
}
}
},
town: function (to) {
- let from = game.location[game.who];
- log_move_continue(to);
- move_block(game.who, from, to);
- end_muster_move();
+ let from = game.location[game.who]
+ log_move_continue(to)
+ move_block(game.who, from, to)
+ end_muster_move()
},
undo: pop_undo,
}
function end_muster_move() {
- log_move_end();
- game.moved[game.who] = 1;
- game.who = null;
- game.state = 'muster_who';
+ log_move_end()
+ game.moved[game.who] = 1
+ game.who = null
+ game.state = 'muster_who'
}
// WINTER CAMPAIGN
@@ -2153,17 +2155,17 @@ function end_muster_move() {
states.winter_campaign = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Move Phase: Waiting for " + game.active + ".";
- view.prompt = "Winter Campaign: Select a siege to maintain over the winter.";
- gen_action_undo(view);
+ return view.prompt = "Move Phase: Waiting for " + game.active + "."
+ view.prompt = "Winter Campaign: Select a siege to maintain over the winter."
+ gen_action_undo(view)
for (let town of TOWNLIST)
if (is_friendly_field(town) && is_under_siege(town))
- gen_action(view, 'town', town);
+ gen_action(view, 'town', town)
},
town: function (where) {
- log(game.active + " winter campaigned in " + where + ".");
- game.winter_campaign = where;
- game.state = 'move_phase';
+ log(game.active + " winter campaigned in " + where + ".")
+ game.winter_campaign = where
+ game.state = 'move_phase'
},
undo: pop_undo
}
@@ -2172,94 +2174,94 @@ states.winter_campaign = {
function goto_combat_phase() {
if (is_winter()) {
- game.moved = {};
- return end_game_turn();
+ game.moved = {}
+ return end_game_turn()
}
- game.combat_list = [];
+ game.combat_list = []
for (let where of TOWNLIST)
if (is_contested_town(where))
- game.combat_list.push(where);
- resume_combat_phase();
+ game.combat_list.push(where)
+ resume_combat_phase()
}
function resume_combat_phase() {
- reset_road_limits();
- reset_moved_for_combat();
+ reset_road_limits()
+ reset_moved_for_combat()
if (game.combat_list.length > 0) {
- game.active = game.p1;
- game.state = 'combat_phase';
+ game.active = game.p1
+ game.state = 'combat_phase'
} else {
- goto_draw_phase();
+ goto_draw_phase()
}
}
states.combat_phase = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Battle Phase: Waiting for " + game.active + ".";
- view.prompt = "Battle Phase: Choose the next battle or siege!";
+ return view.prompt = "Battle Phase: Waiting for " + game.active + "."
+ view.prompt = "Battle Phase: Choose the next battle or siege!"
for (let where of game.combat_list)
- gen_action(view, 'town', where);
+ gen_action(view, 'town', where)
},
town: function (where) {
- remove_from_array(game.combat_list, where);
- game.where = where;
- start_combat();
+ remove_from_array(game.combat_list, where)
+ game.where = where
+ start_combat()
},
}
function start_combat() {
- game.flash = "";
- log("");
- log("Battle in " + game.where);
- game.combat_round = 0;
- game.halfhit = null;
- game.storming = [];
- game.sallying = [];
+ game.flash = ""
+ log("")
+ log("Battle in " + game.where)
+ game.combat_round = 0
+ game.halfhit = null
+ game.storming = []
+ game.sallying = []
- game.show_castle = 0;
- game.show_field = 0;
+ game.show_castle = 0
+ game.show_field = 0
if (is_castle_town(game.where)) {
if (!is_under_siege(game.where)) {
- log("~ Combat Deployment ~");
- game.castle_owner = enemy(game.attacker[game.where]);
- game.active = game.castle_owner;
- game.state = 'combat_deployment';
- game.is_existing_siege = 0;
+ log("~ Combat Deployment ~")
+ game.castle_owner = enemy(game.attacker[game.where])
+ game.active = game.castle_owner
+ game.state = 'combat_deployment'
+ game.is_existing_siege = 0
} else {
- game.castle_owner = besieged_player(game.where);
+ game.castle_owner = besieged_player(game.where)
if (!game.attacker[game.where])
- game.attacker[game.where] = enemy(game.castle_owner);
- log("Existing siege continued.");
- game.is_existing_siege = 1;
- next_combat_round();
+ game.attacker[game.where] = enemy(game.castle_owner)
+ log("Existing siege continued.")
+ game.is_existing_siege = 1
+ next_combat_round()
}
} else {
- game.castle_owner = null;
- next_combat_round();
+ game.castle_owner = null
+ next_combat_round()
}
}
function end_combat() {
- lift_siege(game.where);
+ lift_siege(game.where)
if (game.jihad === game.where)
- game.jihad = null;
+ game.jihad = null
- delete game.is_existing_siege;
- delete game.castle_owner;
- delete game.storming;
- delete game.sallying;
- delete game.show_castle;
- delete game.show_field;
- game.where = null;
- game.flash = "";
- game.combat_round = 0;
+ delete game.is_existing_siege
+ delete game.castle_owner
+ delete game.storming
+ delete game.sallying
+ delete game.show_castle
+ delete game.show_field
+ game.where = null
+ game.flash = ""
+ game.combat_round = 0
- resume_combat_phase();
+ resume_combat_phase()
}
// COMBAT DEPLOYMENT
@@ -2268,47 +2270,47 @@ states.combat_deployment = {
show_battle: true,
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Battle: Waiting for " + game.active + ".";
- view.prompt = "Battle: Deploy blocks on the field and in the castle.";
- let max = castle_limit(game.where);
- let n = count_blocks_in_castle(game.where);
- let have_options = false;
+ return view.prompt = "Battle: Waiting for " + game.active + "."
+ view.prompt = "Battle: Deploy blocks on the field and in the castle."
+ let max = castle_limit(game.where)
+ let n = count_blocks_in_castle(game.where)
+ let have_options = false
if (n < max) {
for (let b of BLOCKLIST) {
if (block_owner(b) === game.active && !is_reserve(b)) {
if (game.location[b] === game.where && !game.castle.includes(b)) {
- gen_action(view, 'withdraw', b);
- gen_action(view, 'block', b);
- have_options = true;
+ gen_action(view, 'withdraw', b)
+ gen_action(view, 'block', b)
+ have_options = true
}
}
}
}
if (!have_options)
- view.flash_next = "Click Next when you're done.";
- gen_action_undo(view);
- gen_action(view, 'next');
+ view.flash_next = "Click Next when you're done."
+ gen_action_undo(view)
+ gen_action(view, 'next')
},
withdraw: function (who) {
- push_undo();
- game.castle.push(who);
+ push_undo()
+ game.castle.push(who)
},
block: function (who) {
- push_undo();
- game.castle.push(who);
+ push_undo()
+ game.castle.push(who)
},
next: function () {
- clear_undo();
- let n = count_blocks_in_castle(game.where);
+ clear_undo()
+ let n = count_blocks_in_castle(game.where)
if (n === 1)
- log(game.active + " withdrew 1 block.");
+ log(game.active + " withdrew 1 block.")
else
- log(game.active + " withdrew " + n + " blocks.");
- game.active = game.attacker[game.where];
+ log(game.active + " withdrew " + n + " blocks.")
+ game.active = game.attacker[game.where]
if (count_enemy_in_field_and_reserve(game.where) === 0) {
- return goto_regroup();
+ return goto_regroup()
}
- next_combat_round();
+ next_combat_round()
},
undo: pop_undo
}
@@ -2317,47 +2319,47 @@ states.combat_deployment = {
function print_retreat_summary() {
if (game.summary && game.summary.length > 0)
- print_summary("Retreated from " + game.where + ":");
+ print_summary("Retreated from " + game.where + ":")
}
function goto_regroup() {
- lift_siege(game.where);
+ lift_siege(game.where)
if (!is_under_siege(game.where))
- clear_reserves(); // no siege battle, reserves arrive before regroup
- reset_road_limits();
- reset_moved_for_combat();
- game.state = 'regroup';
- game.summary = [];
+ clear_reserves() // no siege battle, reserves arrive before regroup
+ reset_road_limits()
+ reset_moved_for_combat()
+ game.state = 'regroup'
+ game.summary = []
}
states.regroup = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Regroup: Waiting for " + game.active + ".";
- view.prompt = "Regroup: Choose a block to move.";
- gen_action_undo(view);
- gen_action(view, 'end_regroup');
+ return view.prompt = "Regroup: Waiting for " + game.active + "."
+ view.prompt = "Regroup: Choose a block to move."
+ gen_action_undo(view)
+ gen_action(view, 'end_regroup')
for (let b of BLOCKLIST) {
if (game.location[b] === game.where) {
if (can_block_regroup(b))
- gen_action(view, 'block', b);
+ gen_action(view, 'block', b)
}
}
},
block: function (who) {
- push_undo();
- game.who = who;
- game.state = 'regroup_to';
+ push_undo()
+ game.who = who
+ game.state = 'regroup_to'
},
end_regroup: function () {
- clear_undo();
- print_summary(game.active + " regrouped:", true);
+ clear_undo()
+ print_summary(game.active + " regrouped:", true)
if (is_winter())
- goto_winter_2();
+ goto_winter_2()
else if (is_contested_town(game.where))
- next_combat_round();
+ next_combat_round()
else
- end_combat();
+ end_combat()
},
undo: pop_undo
}
@@ -2365,24 +2367,24 @@ states.regroup = {
states.regroup_to = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Regroup: Waiting for " + game.active + ".";
- view.prompt = "Regroup: Move the block to a friendly or vacant town.";
- gen_action_undo(view);
- gen_action(view, 'block', game.who);
+ return view.prompt = "Regroup: Waiting for " + game.active + "."
+ view.prompt = "Regroup: Move the block to a friendly or vacant town."
+ gen_action_undo(view)
+ gen_action(view, 'block', game.who)
for (let to of TOWNS[game.where].exits)
if (can_block_regroup_to(game.who, to))
- gen_action(view, 'town', to);
+ gen_action(view, 'town', to)
},
town: function (to) {
// We can regroup while reserves are still on the way...
- remove_from_array(game.reserves1, game.who);
- remove_from_array(game.reserves2, game.who);
+ remove_from_array(game.reserves1, game.who)
+ remove_from_array(game.reserves2, game.who)
- let from = game.where;
- game.summary.push([from, to]);
- move_block(game.who, game.where, to);
- game.who = null;
- game.state = 'regroup';
+ let from = game.where
+ game.summary.push([from, to])
+ move_block(game.who, game.where, to)
+ game.who = null
+ game.state = 'regroup'
},
block: pop_undo,
undo: pop_undo
@@ -2391,287 +2393,287 @@ states.regroup_to = {
// COMBAT ROUND
function next_combat_round() {
- print_retreat_summary();
+ print_retreat_summary()
if (game.jihad === game.where && game.combat_round === 1)
- game.jihad = null;
+ game.jihad = null
switch (game.combat_round) {
- case 0: return goto_combat_round(1);
- case 1: return goto_combat_round(2);
- case 2: return goto_combat_round(3);
- case 3: return goto_retreat_after_combat();
+ case 0: return goto_combat_round(1)
+ case 1: return goto_combat_round(2)
+ case 2: return goto_combat_round(3)
+ case 3: return goto_retreat_after_combat()
}
}
function bring_on_reserves(reserves) {
- let f = 0;
- let s = 0;
+ let f = 0
+ let s = 0
for (let b of BLOCKLIST) {
if (game.location[b] === game.where) {
if (reserves.includes(b)) {
if (block_owner(b) === FRANKS)
- ++f;
+ ++f
else
- ++s;
- remove_from_array(reserves, b);
+ ++s
+ remove_from_array(reserves, b)
}
}
}
if (f > 0)
- log(f + " Frank " + (f === 1 ? "reserve arrived." : "reserves arrived."));
+ log(f + " Frank " + (f === 1 ? "reserve arrived." : "reserves arrived."))
if (s > 0)
- log(s + " Saracen " + (s === 1 ? "reserve arrived." : "reserves arrived."));
+ log(s + " Saracen " + (s === 1 ? "reserve arrived." : "reserves arrived."))
}
function clear_reserves(where) {
for (let b of BLOCKLIST) {
if (game.location[b] === where) {
- remove_from_array(game.reserves1, b);
- remove_from_array(game.reserves2, b);
+ remove_from_array(game.reserves1, b)
+ remove_from_array(game.reserves2, b)
}
}
}
function reset_moved_for_combat() {
- for (let b in game.moved) game.moved[b] = 0;
- for (let b of game.reserves1) game.moved[b] = 1;
- for (let b of game.reserves2) game.moved[b] = 1;
+ for (let b in game.moved) game.moved[b] = 0
+ for (let b of game.reserves1) game.moved[b] = 1
+ for (let b of game.reserves2) game.moved[b] = 1
}
function goto_combat_round(new_combat_round) {
- game.combat_round = new_combat_round;
- game.summary = [];
+ game.combat_round = new_combat_round
+ game.summary = []
- let was_contested = is_contested_battle_field();
+ let was_contested = is_contested_battle_field()
// If the main attack regroups away from a new siege while reinforcements
// are on the way, we need to skip the first combat round.
if (game.combat_round === 1 && is_under_siege(game.where)) {
- game.active = besieging_player(game.where);
+ game.active = besieging_player(game.where)
if (count_friendly_in_field_excluding_reserves(game.where) === 0) {
- log("Combat round skipped because main attack regrouped away.");
- game.combat_round = 2;
+ log("Combat round skipped because main attack regrouped away.")
+ game.combat_round = 2
}
}
- log("~ Combat Round " + game.combat_round + " ~");
+ log("~ Combat Round " + game.combat_round + " ~")
if (game.combat_round === 2)
- bring_on_reserves(game.reserves1);
+ bring_on_reserves(game.reserves1)
if (game.combat_round === 3)
- bring_on_reserves(game.reserves2);
+ bring_on_reserves(game.reserves2)
- reset_moved_for_combat();
+ reset_moved_for_combat()
if (is_contested_battle_field()) {
if (is_under_siege(game.where)) {
if (!was_contested) {
- log("Relief forces arrived!");
+ log("Relief forces arrived!")
if (game.storming.length > 0) {
- log("Storming canceled by arriving relief force.");
- game.halfhit = null;
- game.storming.length = 0;
+ log("Storming canceled by arriving relief force.")
+ game.halfhit = null
+ game.storming.length = 0
}
- let old_attacker = game.attacker[game.where];
- game.attacker[game.where] = besieged_player(game.where);
+ let old_attacker = game.attacker[game.where]
+ game.attacker[game.where] = besieged_player(game.where)
if (old_attacker !== game.attacker[game.where]) {
- log(game.attacker[game.where] + " are now the attacker.");
+ log(game.attacker[game.where] + " are now the attacker.")
}
}
// No sally first round after combat deployment.
if (game.combat_round > 1 || game.is_existing_siege)
- return goto_declare_sally();
+ return goto_declare_sally()
}
- return goto_field_battle();
+ return goto_field_battle()
}
- goto_declare_storm();
+ goto_declare_storm()
}
// DECLARE STORM
function goto_declare_storm() {
- game.active = besieging_player(game.where);
+ game.active = besieging_player(game.where)
// Castle is full.
if (game.storming.length === castle_limit(game.where))
- return goto_siege_battle();
+ return goto_siege_battle()
// Field is empty.
if (count_friendly(game.where) - game.storming.length === 0)
- return goto_siege_battle();
- game.state = 'declare_storm';
+ return goto_siege_battle()
+ game.state = 'declare_storm'
}
states.declare_storm = {
show_battle: true,
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Siege Declaration: Waiting for " + game.active + " to declare storm.";
- view.prompt = "Siege Declaration: Declare which blocks should storm the castle.";
- let have_options = false;
+ return view.prompt = "Siege Declaration: Waiting for " + game.active + " to declare storm."
+ view.prompt = "Siege Declaration: Declare which blocks should storm the castle."
+ let have_options = false
if (game.storming.length < castle_limit(game.where)) {
for (let b of BLOCKLIST) {
if (block_owner(b) === game.active && !is_reserve(b)) {
if (game.location[b] === game.where && !game.storming.includes(b)) {
- gen_action(view, 'storm', b);
- gen_action(view, 'block', b);
- have_options = true;
+ gen_action(view, 'storm', b)
+ gen_action(view, 'block', b)
+ have_options = true
}
}
}
}
if (!have_options)
- view.flash_next = "Click Next when you're done.";
- gen_action_undo(view);
- gen_action(view, 'next');
+ view.flash_next = "Click Next when you're done."
+ gen_action_undo(view)
+ gen_action(view, 'next')
},
storm: storm_with_block,
block: storm_with_block,
next: function () {
- clear_undo();
- let n = game.storming.length;
+ clear_undo()
+ let n = game.storming.length
if (n === 0) {
- game.flash = game.active + " declined to storm.";
+ game.flash = game.active + " declined to storm."
if (game.jihad === game.where)
- game.jihad = null;
- log(game.active + " declined to storm.");
- goto_declare_sally();
+ game.jihad = null
+ log(game.active + " declined to storm.")
+ goto_declare_sally()
} else {
- goto_siege_battle();
+ goto_siege_battle()
}
},
undo: pop_undo
}
function storm_with_block(who) {
- push_undo();
- game.storming.push(who);
+ push_undo()
+ game.storming.push(who)
if (game.storming.length > 1)
- game.flash = game.active + " stormed with " + game.storming.length + " blocks.";
+ game.flash = game.active + " stormed with " + game.storming.length + " blocks."
else
- game.flash = game.active + " stormed with 1 block.";
- log(game.active[0] + ": " + block_name(who) + " stormed.");
+ game.flash = game.active + " stormed with 1 block."
+ log(game.active[0] + ": " + block_name(who) + " stormed.")
}
// DECLARE SALLY
function goto_declare_sally() {
- game.active = besieged_player(game.where);
- game.state = 'declare_sally';
- game.was_contested = is_contested_battle_field();
+ game.active = besieged_player(game.where)
+ game.state = 'declare_sally'
+ game.was_contested = is_contested_battle_field()
}
states.declare_sally = {
show_battle: true,
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Siege Declaration: Waiting for " + game.active + " to declare sally.";
- view.prompt = "Siege Declaration: Declare which blocks should sally onto the field.";
- let have_options = false;
+ return view.prompt = "Siege Declaration: Waiting for " + game.active + " to declare sally."
+ view.prompt = "Siege Declaration: Declare which blocks should sally onto the field."
+ let have_options = false
for (let b of BLOCKLIST) {
if (block_owner(b) === game.active && !is_reserve(b) && is_block_in_castle(b)) {
if (game.location[b] === game.where && !game.sallying.includes(b)) {
- gen_action(view, 'sally', b);
- gen_action(view, 'block', b);
- have_options = true;
+ gen_action(view, 'sally', b)
+ gen_action(view, 'block', b)
+ have_options = true
}
}
}
if (!have_options)
- view.flash_next = "Click Next when you're done.";
- gen_action_undo(view);
- gen_action(view, 'next');
+ view.flash_next = "Click Next when you're done."
+ gen_action_undo(view)
+ gen_action(view, 'next')
},
sally: sally_with_block,
block: sally_with_block,
next: function () {
- clear_undo();
- let n = game.sallying.length;
+ clear_undo()
+ let n = game.sallying.length
if (n === 0) {
- game.flash = game.active + " declined to sally.";
- log(game.active + " declined to sally.");
+ game.flash = game.active + " declined to sally."
+ log(game.active + " declined to sally.")
}
if (is_contested_battle_field()) {
if (!game.was_contested) {
- log(game.active + " are now the attacker.");
- game.attacker[game.where] = game.active;
+ log(game.active + " are now the attacker.")
+ game.attacker[game.where] = game.active
}
- goto_field_battle();
+ goto_field_battle()
} else if (count_reserves(game.where) > 0) {
- next_combat_round();
+ next_combat_round()
} else {
- goto_siege_attrition();
+ goto_siege_attrition()
}
},
undo: pop_undo
}
function sally_with_block(who) {
- push_undo();
- remove_from_array(game.castle, who);
- game.sallying.push(who);
+ push_undo()
+ remove_from_array(game.castle, who)
+ game.sallying.push(who)
if (game.sallying.length > 1)
- game.flash = game.active + " sallied with " + game.sallying.length + " blocks.";
+ game.flash = game.active + " sallied with " + game.sallying.length + " blocks."
else
- game.flash = game.active + " sallied with 1 block.";
- log(game.active[0] + ": " + block_name(who) + " sallied.");
+ game.flash = game.active + " sallied with 1 block."
+ log(game.active[0] + ": " + block_name(who) + " sallied.")
}
// RETREAT AFTER COMBAT
function goto_retreat_after_combat() {
- reset_moved_for_combat();
+ reset_moved_for_combat()
// withdraw all sallying blocks to castle.
for (let b of game.sallying)
- game.castle.push(b);
- game.sallying.length = 0;
+ game.castle.push(b)
+ game.sallying.length = 0
// TODO: 6.2 - In Sieges, the attacker /may/ retreat or stay on siege.
// withdraw all storming blocks to the field.
- game.halfhit = null;
- game.storming.length = 0;
+ game.halfhit = null
+ game.storming.length = 0
if (is_contested_field(game.where)) {
- log("~ Retreat ~");
- game.active = game.attacker[game.where];
- game.state = 'retreat';
- game.summary = [];
+ log("~ Retreat ~")
+ game.active = game.attacker[game.where]
+ game.state = 'retreat'
+ game.summary = []
} else if (is_under_siege(game.where)) {
- goto_siege_attrition();
+ goto_siege_attrition()
} else {
- end_combat();
+ end_combat()
}
}
states.retreat = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Retreat: Waiting for " + game.active + ".";
- view.prompt = "Retreat: Choose a block to move.";
- gen_action_undo(view);
- let can_retreat = false;
+ return view.prompt = "Retreat: Waiting for " + game.active + "."
+ view.prompt = "Retreat: Choose a block to move."
+ gen_action_undo(view)
+ let can_retreat = false
for (let b of BLOCKLIST) {
if (game.location[b] === game.where && !is_block_in_castle(b) && can_block_retreat(b)) {
- gen_action(view, 'block', b);
- can_retreat = true;
+ gen_action(view, 'block', b)
+ can_retreat = true
}
}
if (!is_contested_field(game.where) || !can_retreat)
- gen_action(view, 'end_retreat');
+ gen_action(view, 'end_retreat')
},
end_retreat: function () {
- clear_undo();
+ clear_undo()
for (let b of BLOCKLIST)
if (game.location[b] === game.where && !is_block_in_castle(b) && block_owner(b) === game.active)
- eliminate_block(b);
- print_summary(game.active + " retreated:");
- game.active = enemy(game.active);
- goto_regroup();
+ eliminate_block(b)
+ print_summary(game.active + " retreated:")
+ game.active = enemy(game.active)
+ goto_regroup()
},
block: function (who) {
- push_undo();
- game.who = who;
- game.state = 'retreat_to';
+ push_undo()
+ game.who = who
+ game.state = 'retreat_to'
},
undo: pop_undo
}
@@ -2679,31 +2681,31 @@ states.retreat = {
states.retreat_to = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Retreat: Waiting for " + game.active + ".";
- view.prompt = "Retreat: Move the block to a friendly or neutral town.";
- gen_action_undo(view);
- gen_action(view, 'block', game.who);
- let can_retreat = false;
+ return view.prompt = "Retreat: Waiting for " + game.active + "."
+ view.prompt = "Retreat: Move the block to a friendly or neutral town."
+ gen_action_undo(view)
+ gen_action(view, 'block', game.who)
+ let can_retreat = false
for (let to of TOWNS[game.where].exits) {
if (can_block_retreat_to(game.who, to)) {
- gen_action(view, 'town', to);
- can_retreat = true;
+ gen_action(view, 'town', to)
+ can_retreat = true
}
}
if (!can_retreat)
- gen_action(view, 'eliminate');
+ gen_action(view, 'eliminate')
},
town: function (to) {
- let from = game.where;
- game.summary.push([from, to]);
- move_block(game.who, game.where, to);
- game.who = null;
- game.state = 'retreat';
+ let from = game.where
+ game.summary.push([from, to])
+ move_block(game.who, game.where, to)
+ game.who = null
+ game.state = 'retreat'
},
eliminate: function () {
- eliminate_block(game.who);
- game.who = null;
- game.state = 'retreat';
+ eliminate_block(game.who)
+ game.who = null
+ game.state = 'retreat'
},
block: pop_undo,
undo: pop_undo
@@ -2712,25 +2714,25 @@ states.retreat_to = {
// SIEGE ATTRITION
function goto_siege_attrition() {
- log("~ Siege Attrition ~");
- game.active = besieged_player(game.where);
- game.state = 'siege_attrition';
- game.attrition_list = [];
+ log("~ Siege Attrition ~")
+ game.active = besieged_player(game.where)
+ game.state = 'siege_attrition'
+ game.attrition_list = []
for (let b of BLOCKLIST)
if (is_block_in_castle_in(b, game.where))
- game.attrition_list.push(b);
+ game.attrition_list.push(b)
}
function resume_siege_attrition() {
if (game.attrition_list.length === 0) {
- delete game.attrition_list;
+ delete game.attrition_list
if (!is_under_siege(game.where)) {
- game.active = enemy(game.active);
- log(game.where + " fell to siege attrition.");
- goto_regroup();
+ game.active = enemy(game.active)
+ log(game.where + " fell to siege attrition.")
+ goto_regroup()
} else {
- log("Siege continued.");
- end_combat();
+ log("Siege continued.")
+ end_combat()
}
}
}
@@ -2738,157 +2740,157 @@ function resume_siege_attrition() {
states.siege_attrition = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Siege Attrition: Waiting for " + game.active + ".";
- view.prompt = "Siege Attrition: Roll for siege attrition in " + game.where + ".";
+ return view.prompt = "Siege Attrition: Waiting for " + game.active + "."
+ view.prompt = "Siege Attrition: Roll for siege attrition in " + game.where + "."
for (let b of game.attrition_list)
gen_action(view, 'block', b)
},
block: function (who) {
- let target = (game.where === TYRE || game.where === TRIPOLI) ? 1 : 3;
- let die = roll_d6();
+ let target = (game.where === TYRE || game.where === TRIPOLI) ? 1 : 3
+ let die = roll_d6()
if (die <= target) {
- log("Attrition roll " + DIE_HIT[die] + ".");
- reduce_block(who);
+ log("Attrition roll " + DIE_HIT[die] + ".")
+ reduce_block(who)
} else {
- log("Attrition roll " + DIE_MISS[die] + ".");
+ log("Attrition roll " + DIE_MISS[die] + ".")
}
- remove_from_array(game.attrition_list, who);
- resume_siege_attrition();
+ remove_from_array(game.attrition_list, who)
+ resume_siege_attrition()
}
}
// FIELD AND SIEGE BATTLE HELPERS
function filter_battle_blocks(ci, is_candidate) {
- let output = null;
+ let output = null
for (let b of BLOCKLIST) {
if (is_candidate(b) && !game.moved[b]) {
if (block_initiative(b) === ci) {
if (!output)
- output = [];
- output.push(b);
+ output = []
+ output.push(b)
}
}
}
- return output;
+ return output
}
function battle_step(active, initiative, candidate) {
- game.battle_list = filter_battle_blocks(initiative, candidate);
+ game.battle_list = filter_battle_blocks(initiative, candidate)
if (game.battle_list) {
- game.active = active;
- return true;
+ game.active = active
+ return true
}
- return false;
+ return false
}
function pump_battle_step(is_candidate_attacker, is_candidate_defender) {
- let attacker = game.attacker[game.where];
- let defender = enemy(attacker);
+ let attacker = game.attacker[game.where]
+ let defender = enemy(attacker)
if (game.jihad === game.where && game.combat_round === 1) {
- if (battle_step(attacker, 'A', is_candidate_attacker)) return;
- if (battle_step(attacker, 'B', is_candidate_attacker)) return;
- if (battle_step(attacker, 'C', is_candidate_attacker)) return;
- if (battle_step(defender, 'A', is_candidate_defender)) return;
- if (battle_step(defender, 'B', is_candidate_defender)) return;
- if (battle_step(defender, 'C', is_candidate_defender)) return;
+ if (battle_step(attacker, 'A', is_candidate_attacker)) return
+ if (battle_step(attacker, 'B', is_candidate_attacker)) return
+ if (battle_step(attacker, 'C', is_candidate_attacker)) return
+ if (battle_step(defender, 'A', is_candidate_defender)) return
+ if (battle_step(defender, 'B', is_candidate_defender)) return
+ if (battle_step(defender, 'C', is_candidate_defender)) return
} else {
- if (battle_step(defender, 'A', is_candidate_defender)) return;
- if (battle_step(attacker, 'A', is_candidate_attacker)) return;
- if (battle_step(defender, 'B', is_candidate_defender)) return;
- if (battle_step(attacker, 'B', is_candidate_attacker)) return;
- if (battle_step(defender, 'C', is_candidate_defender)) return;
- if (battle_step(attacker, 'C', is_candidate_attacker)) return;
+ if (battle_step(defender, 'A', is_candidate_defender)) return
+ if (battle_step(attacker, 'A', is_candidate_attacker)) return
+ if (battle_step(defender, 'B', is_candidate_defender)) return
+ if (battle_step(attacker, 'B', is_candidate_attacker)) return
+ if (battle_step(defender, 'C', is_candidate_defender)) return
+ if (battle_step(attacker, 'C', is_candidate_attacker)) return
}
- next_combat_round();
+ next_combat_round()
}
// FIELD BATTLE
function goto_field_battle() {
- resume_field_battle();
+ resume_field_battle()
}
function resume_field_battle() {
// we have a queued up harry action
if (game.harry) {
- game.active = game.harry;
- game.state = 'harry';
- delete game.harry;
- return;
+ game.active = game.harry
+ game.state = 'harry'
+ delete game.harry
+ return
}
- game.active = game.attacker[game.where];
+ game.active = game.attacker[game.where]
if (is_friendly_field(game.where)) {
- print_retreat_summary();
- log("Field battle won by " + game.active + ".");
- game.show_field = 0;
- return goto_regroup();
+ print_retreat_summary()
+ log("Field battle won by " + game.active + ".")
+ game.show_field = 0
+ return goto_regroup()
}
if (is_enemy_field(game.where)) {
- game.active = enemy(game.active);
- print_retreat_summary();
- log("Field battle won by " + game.active + ".");
- game.show_field = 0;
- return goto_regroup();
+ game.active = enemy(game.active)
+ print_retreat_summary()
+ log("Field battle won by " + game.active + ".")
+ game.show_field = 0
+ return goto_regroup()
}
if (is_enemy_battle_field()) {
- print_retreat_summary();
- log("Attacking main force was eliminated.");
- return next_combat_round();
+ print_retreat_summary()
+ log("Attacking main force was eliminated.")
+ return next_combat_round()
}
if (is_friendly_battle_field()) {
- print_retreat_summary();
- log("Defending main force was eliminated.");
- log("Battlefield control changed.");
- game.attacker[game.where] = enemy(game.active);
+ print_retreat_summary()
+ log("Defending main force was eliminated.")
+ log("Battlefield control changed.")
+ game.attacker[game.where] = enemy(game.active)
// The new defender takes control of the empty castle
if (!is_under_siege(game.where))
- game.castle_owner = game.active;
- return next_combat_round();
+ game.castle_owner = game.active
+ return next_combat_round()
}
- game.state = 'field_battle';
- game.show_field = 1;
- pump_battle_step(is_field_attacker, is_field_defender);
+ game.state = 'field_battle'
+ game.show_field = 1
+ pump_battle_step(is_field_attacker, is_field_defender)
}
states.field_battle = {
show_battle: true,
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Field Battle: Waiting for " + game.active + ".";
- view.prompt = "Field Battle: Choose a combat action.";
+ return view.prompt = "Field Battle: Waiting for " + game.active + "."
+ view.prompt = "Field Battle: Choose a combat action."
for (let b of game.battle_list) {
- gen_action(view, 'block', b); // take default action
- gen_action(view, 'fire', b);
+ gen_action(view, 'block', b) // take default action
+ gen_action(view, 'fire', b)
if (game.sallying.includes(b)) {
// Only sallying forces may withdraw into the castle
- gen_action(view, 'withdraw', b);
+ gen_action(view, 'withdraw', b)
} else {
if (can_block_retreat(b)) {
- gen_action(view, 'retreat', b);
+ gen_action(view, 'retreat', b)
// Turcopoles and Nomads can Harry (fire and retreat)
if (block_type(b) === 'turcopoles' || block_type(b) === 'nomads')
- gen_action(view, 'harry', b);
+ gen_action(view, 'harry', b)
}
// Defender can withdraw into castle if friendly and there is room.
if (game.active !== game.attacker[game.where] && game.active === game.castle_owner) {
// TODO: allow swapping place of sallying block, leaving it to die if it cannot withdraw?
if (game.sallying.length + count_blocks_in_castle(game.where) < castle_limit(game.where))
- gen_action(view, 'withdraw', b);
+ gen_action(view, 'withdraw', b)
}
}
// All Frank B blocks are knights who can Charge
if (block_owner(b) === FRANKS && block_initiative(b) === 'B')
- gen_action(view, 'charge', b);
+ gen_action(view, 'charge', b)
}
},
block: field_fire_with_block,
@@ -2902,57 +2904,57 @@ states.field_battle = {
// SIEGE BATTLE
function goto_siege_battle() {
- game.attacker[game.where] = besieging_player(game.where);
- game.show_castle = 1;
- resume_siege_battle();
+ game.attacker[game.where] = besieging_player(game.where)
+ game.show_castle = 1
+ resume_siege_battle()
}
function resume_siege_battle() {
- game.active = game.attacker[game.where];
+ game.active = game.attacker[game.where]
if (is_friendly_town(game.where)) {
- log("Siege battle won by " + game.active + ".");
- return goto_regroup();
+ log("Siege battle won by " + game.active + ".")
+ return goto_regroup()
}
if (is_enemy_town(game.where)) {
- game.active = enemy(game.active);
- game.halfhit = null;
- log("Siege battle won by " + game.active + ".");
- return goto_regroup();
+ game.active = enemy(game.active)
+ game.halfhit = null
+ log("Siege battle won by " + game.active + ".")
+ return goto_regroup()
}
if (count_blocks_in_castle(game.where) === 0) {
- log("Defending main force was eliminated.");
- log(game.active + " are now the defender.");
- game.attacker[game.where] = enemy(game.active);
+ log("Defending main force was eliminated.")
+ log(game.active + " are now the defender.")
+ game.attacker[game.where] = enemy(game.active)
// The new defender takes control of the empty castle
- game.castle_owner = game.active;
- game.storming.length = 0;
- return next_combat_round();
+ game.castle_owner = game.active
+ game.storming.length = 0
+ return next_combat_round()
}
if (game.storming.length === 0) {
- game.halfhit = null;
- log("Storming repulsed.");
- return next_combat_round();
+ game.halfhit = null
+ log("Storming repulsed.")
+ return next_combat_round()
}
- game.state = 'siege_battle';
- pump_battle_step(is_siege_attacker, is_siege_defender);
+ game.state = 'siege_battle'
+ pump_battle_step(is_siege_attacker, is_siege_defender)
}
states.siege_battle = {
show_battle: true,
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Siege Battle: Waiting for " + game.active + ".";
- view.prompt = "Siege Battle: Choose a combat action.";
+ return view.prompt = "Siege Battle: Waiting for " + game.active + "."
+ view.prompt = "Siege Battle: Choose a combat action."
for (let b of game.battle_list) {
- gen_action(view, 'block', b); // take default action
- gen_action(view, 'fire', b);
+ gen_action(view, 'block', b) // take default action
+ gen_action(view, 'fire', b)
if (game.storming.includes(b))
- gen_action(view, 'retreat', b);
+ gen_action(view, 'retreat', b)
}
},
block: siege_fire_with_block,
@@ -2963,35 +2965,35 @@ states.siege_battle = {
// FIELD BATTLE HITS
function goto_field_battle_hits() {
- game.active = enemy(game.active);
- game.battle_list = list_field_victims();
+ game.active = enemy(game.active)
+ game.battle_list = list_field_victims()
if (game.battle_list.length === 0)
- resume_field_battle();
+ resume_field_battle()
else
- game.state = 'field_battle_hits';
+ game.state = 'field_battle_hits'
}
function list_field_victims() {
- let max = 0;
+ let max = 0
for (let b of BLOCKLIST)
if (block_owner(b) === game.active && is_field_combatant(b) && game.steps[b] > max)
- max = game.steps[b];
- let list = [];
+ max = game.steps[b]
+ let list = []
for (let b of BLOCKLIST)
if (block_owner(b) === game.active && is_field_combatant(b) && game.steps[b] === max)
- list.push(b);
- return list;
+ list.push(b)
+ return list
}
states.field_battle_hits = {
show_battle: true,
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Field Battle: Waiting for " + game.active + " to assign hits.";
- view.prompt = "Field Battle: Assign " + game.hits + (game.hits !== 1 ? " hits" : " hit") + " to your armies.";
+ return view.prompt = "Field Battle: Waiting for " + game.active + " to assign hits."
+ view.prompt = "Field Battle: Assign " + game.hits + (game.hits !== 1 ? " hits" : " hit") + " to your armies."
for (let b of game.battle_list) {
- gen_action(view, 'hit', b);
- gen_action(view, 'block', b);
+ gen_action(view, 'hit', b)
+ gen_action(view, 'block', b)
}
},
hit: apply_field_battle_hit,
@@ -2999,62 +3001,62 @@ states.field_battle_hits = {
}
function apply_field_battle_hit_to(who, flash) {
- let msg;
- msg = block_name(who) + " took a hit.";
- log(game.active[0] + ": " + msg);
+ let msg
+ msg = block_name(who) + " took a hit."
+ log(game.active[0] + ": " + msg)
if (flash)
- game.flash = msg;
- reduce_block(who);
- game.hits--;
+ game.flash = msg
+ reduce_block(who)
+ game.hits--
}
function apply_field_battle_hit(who) {
- apply_field_battle_hit_to(who, true);
+ apply_field_battle_hit_to(who, true)
if (game.hits === 0)
- resume_field_battle();
+ resume_field_battle()
else {
- game.battle_list = list_field_victims();
+ game.battle_list = list_field_victims()
if (game.battle_list.length === 0)
- resume_field_battle();
+ resume_field_battle()
else
- game.flash += " " + game.hits + (game.hits === 1 ? " hit left." : " hits left.");
+ game.flash += " " + game.hits + (game.hits === 1 ? " hit left." : " hits left.")
}
}
// SIEGE BATTLE HITS
function goto_siege_battle_hits() {
- game.active = enemy(game.active);
- game.battle_list = list_siege_victims();
+ game.active = enemy(game.active)
+ game.battle_list = list_siege_victims()
if (game.battle_list.length === 0)
- resume_siege_battle();
+ resume_siege_battle()
else
- game.state = 'siege_battle_hits';
+ game.state = 'siege_battle_hits'
}
function list_siege_victims() {
if (game.halfhit && block_owner(game.halfhit) === game.active)
- return [ game.halfhit ];
- let max = 0;
+ return [ game.halfhit ]
+ let max = 0
for (let b of BLOCKLIST)
if (block_owner(b) === game.active && is_siege_combatant(b) && game.steps[b] > max)
- max = game.steps[b];
- let list = [];
+ max = game.steps[b]
+ let list = []
for (let b of BLOCKLIST)
if (block_owner(b) === game.active && is_siege_combatant(b) && game.steps[b] === max)
- list.push(b);
- return list;
+ list.push(b)
+ return list
}
states.siege_battle_hits = {
show_battle: true,
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Siege Battle: Waiting for " + game.active + " to assign hits.";
- view.prompt = "Siege Battle: Assign " + game.hits + (game.hits !== 1 ? " hits" : " hit") + " to your armies.";
+ return view.prompt = "Siege Battle: Waiting for " + game.active + " to assign hits."
+ view.prompt = "Siege Battle: Assign " + game.hits + (game.hits !== 1 ? " hits" : " hit") + " to your armies."
for (let b of game.battle_list) {
- gen_action(view, 'hit', b);
- gen_action(view, 'block', b);
+ gen_action(view, 'hit', b)
+ gen_action(view, 'block', b)
}
},
hit: apply_siege_battle_hit,
@@ -3062,38 +3064,38 @@ states.siege_battle_hits = {
}
function apply_siege_battle_hit_to(who, flash) {
- let msg = block_name(who) + " took a ";
+ let msg = block_name(who) + " took a "
if (game.halfhit === who) {
- msg += "hit.";
- log(game.active[0] + ": " + msg);
- reduce_block(who);
- game.halfhit = null;
+ msg += "hit."
+ log(game.active[0] + ": " + msg)
+ reduce_block(who)
+ game.halfhit = null
} else {
if (is_block_in_castle(who)) {
- msg += "half-hit.";
- log(game.active[0] + ": " + msg);
- game.halfhit = who;
+ msg += "half-hit."
+ log(game.active[0] + ": " + msg)
+ game.halfhit = who
} else {
- msg += "hit.";
- log(game.active[0] + ": " + msg);
- reduce_block(who);
+ msg += "hit."
+ log(game.active[0] + ": " + msg)
+ reduce_block(who)
}
}
if (flash)
- game.flash = msg;
- game.hits--;
+ game.flash = msg
+ game.hits--
}
function apply_siege_battle_hit(who) {
- apply_siege_battle_hit_to(who, true);
+ apply_siege_battle_hit_to(who, true)
if (game.hits === 0) {
- resume_siege_battle();
+ resume_siege_battle()
} else {
- game.battle_list = list_siege_victims();
+ game.battle_list = list_siege_victims()
if (game.battle_list.length === 0) {
- resume_siege_battle();
+ resume_siege_battle()
} else {
- game.flash += " " + game.hits + (game.hits === 1 ? " hit left." : " hits left.");
+ game.flash += " " + game.hits + (game.hits === 1 ? " hit left." : " hits left.")
}
}
}
@@ -3101,305 +3103,305 @@ function apply_siege_battle_hit(who) {
// BATTLE ACTIONS
function roll_attack(active, b, verb, is_charge) {
- game.hits = 0;
- let fire = block_fire_power(b, game.where) + is_charge;
- let rolls = [];
- let steps = game.steps[b];
- let name = block_name(b) + " " + BLOCKS[b].combat;
- let self = 0;
+ game.hits = 0
+ let fire = block_fire_power(b, game.where) + is_charge
+ let rolls = []
+ let steps = game.steps[b]
+ let name = block_name(b) + " " + BLOCKS[b].combat
+ let self = 0
for (let i = 0; i < steps; ++i) {
- let die = roll_d6();
+ let die = roll_d6()
if (die <= fire) {
- rolls.push(DIE_HIT[die]);
- ++game.hits;
+ rolls.push(DIE_HIT[die])
+ ++game.hits
} else {
if (is_charge && die === 6) {
- rolls.push(DIE_SELF);
- ++self;
+ rolls.push(DIE_SELF)
+ ++self
} else {
- rolls.push(DIE_MISS[die]);
+ rolls.push(DIE_MISS[die])
}
}
}
- game.flash = name + " " + verb + " " + rolls.join(" ") + " ";
+ game.flash = name + " " + verb + " " + rolls.join(" ") + " "
if (game.hits === 0)
- game.flash += "and missed.";
+ game.flash += "and missed."
else if (game.hits === 1)
- game.flash += "and scored 1 hit.";
+ game.flash += "and scored 1 hit."
else
- game.flash += "and scored " + game.hits + " hits.";
+ game.flash += "and scored " + game.hits + " hits."
if (self > 0) {
if (self === 1)
- game.flash += " " + self + " self hit.";
+ game.flash += " " + self + " self hit."
else
- game.flash += " " + self + " self hits.";
- self = Math.min(self, game.steps[b]);
+ game.flash += " " + self + " self hits."
+ self = Math.min(self, game.steps[b])
while (self-- > 0)
- reduce_block(b);
+ reduce_block(b)
}
- log(active[0] + ": " + name + " " + verb + " " + rolls.join("") + ".");
+ log(active[0] + ": " + name + " " + verb + " " + rolls.join("") + ".")
}
function field_fire_with_block(b) {
- game.moved[b] = 1;
- roll_attack(game.active, b, "fired", 0);
+ game.moved[b] = 1
+ roll_attack(game.active, b, "fired", 0)
if (game.hits > 0) {
- goto_field_battle_hits();
+ goto_field_battle_hits()
} else {
- resume_field_battle();
+ resume_field_battle()
}
}
function siege_fire_with_block(b) {
- game.moved[b] = 1;
- roll_attack(game.active, b, "fired", 0);
+ game.moved[b] = 1
+ roll_attack(game.active, b, "fired", 0)
if (game.hits > 0) {
- goto_siege_battle_hits();
+ goto_siege_battle_hits()
} else {
- resume_siege_battle();
+ resume_siege_battle()
}
}
function charge_with_block(b) {
- game.moved[b] = 1;
- roll_attack(game.active, b, "charged", 1);
+ game.moved[b] = 1
+ roll_attack(game.active, b, "charged", 1)
if (game.hits > 0) {
- goto_field_battle_hits();
+ goto_field_battle_hits()
} else {
- resume_field_battle();
+ resume_field_battle()
}
}
function field_withdraw_with_block(b) {
- game.flash = b + " withdrew.";
- log(game.active[0] + ": " + game.flash);
- game.moved[b] = 1;
- remove_from_array(game.sallying, b);
- game.castle.push(b);
- resume_field_battle();
+ game.flash = b + " withdrew."
+ log(game.active[0] + ": " + game.flash)
+ game.moved[b] = 1
+ remove_from_array(game.sallying, b)
+ game.castle.push(b)
+ resume_field_battle()
}
function siege_withdraw_with_block(b) {
- game.flash = b + " withdrew.";
- log(game.active[0] + ": " + game.flash);
- game.moved[b] = 1;
- remove_from_array(game.storming, b);
- resume_siege_battle();
+ game.flash = b + " withdrew."
+ log(game.active[0] + ": " + game.flash)
+ game.moved[b] = 1
+ remove_from_array(game.storming, b)
+ resume_siege_battle()
}
function harry_with_block(b) {
- game.harry = game.active; // remember to retreat after hits have been applied
- game.who = b;
- roll_attack(game.active, b, "harried", 0);
+ game.harry = game.active // remember to retreat after hits have been applied
+ game.who = b
+ roll_attack(game.active, b, "harried", 0)
if (game.hits > 0) {
- goto_field_battle_hits();
+ goto_field_battle_hits()
} else {
- resume_field_battle();
+ resume_field_battle()
}
}
states.harry = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Field Battle: Waiting for " + game.active + " to retreat the harrying block.";
- view.prompt = "Field Battle: Retreat the harrying block to a friendly or vacant town.";
+ return view.prompt = "Field Battle: Waiting for " + game.active + " to retreat the harrying block."
+ view.prompt = "Field Battle: Retreat the harrying block to a friendly or vacant town."
for (let to of TOWNS[game.where].exits)
if (can_block_retreat_to(game.who, to))
- gen_action(view, 'town', to);
+ gen_action(view, 'town', to)
},
town: function (to) {
- game.flash += " " + block_name(game.who) + " retreated.";
- game.summary.push([game.active, to]);
- game.location[game.who] = to;
- move_block(game.who, game.where, to);
- game.who = null;
- resume_field_battle();
+ game.flash += " " + block_name(game.who) + " retreated."
+ game.summary.push([game.active, to])
+ game.location[game.who] = to
+ move_block(game.who, game.where, to)
+ game.who = null
+ resume_field_battle()
},
}
function retreat_with_block(b) {
- game.who = b;
- game.state = 'retreat_in_battle';
+ game.who = b
+ game.state = 'retreat_in_battle'
}
states.retreat_in_battle = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Field Battle: Waiting for " + game.active + " to retreat.";
- gen_action(view, 'undo');
- gen_action(view, 'block', game.who);
- view.prompt = "Field Battle: Retreat the block to a friendly or vacant town.";
+ return view.prompt = "Field Battle: Waiting for " + game.active + " to retreat."
+ gen_action(view, 'undo')
+ gen_action(view, 'block', game.who)
+ view.prompt = "Field Battle: Retreat the block to a friendly or vacant town."
for (let to of TOWNS[game.where].exits)
if (can_block_retreat_to(game.who, to))
- gen_action(view, 'town', to);
+ gen_action(view, 'town', to)
},
town: function (to) {
- game.flash = block_name(game.who) + " retreated.";
- log(game.active[0] + ": " + game.flash);
- game.summary.push([game.active, to]);
- game.location[game.who] = to;
- move_block(game.who, game.where, to);
- game.who = null;
- resume_field_battle();
+ game.flash = block_name(game.who) + " retreated."
+ log(game.active[0] + ": " + game.flash)
+ game.summary.push([game.active, to])
+ game.location[game.who] = to
+ move_block(game.who, game.where, to)
+ game.who = null
+ resume_field_battle()
},
block: function () {
- game.who = null;
- resume_field_battle();
+ game.who = null
+ resume_field_battle()
},
undo: function () {
- game.who = null;
- resume_field_battle();
+ game.who = null
+ resume_field_battle()
}
}
// DRAW PHASE
function goto_draw_phase() {
- delete game.combat_list;
+ delete game.combat_list
if (game.year > 1187 && !is_winter()) {
- game.active = game.p1;
- log("");
- start_draw_phase();
+ game.active = game.p1
+ log("")
+ start_draw_phase()
} else {
- end_game_turn();
+ end_game_turn()
}
}
function start_draw_phase() {
- game.state = 'draw_phase';
+ game.state = 'draw_phase'
if (game.active === FRANKS) {
- game.who = select_random_block(F_POOL);
+ game.who = select_random_block(F_POOL)
if (!game.who)
- end_draw_phase();
+ end_draw_phase()
} else {
- game.who = select_random_block(S_POOL);
+ game.who = select_random_block(S_POOL)
if (!game.who)
- end_draw_phase();
+ end_draw_phase()
}
}
states.draw_phase = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Draw Phase: Waiting for " + game.active + ".";
- let can_place = false;
+ return view.prompt = "Draw Phase: Waiting for " + game.active + "."
+ let can_place = false
switch (block_type(game.who)) {
case 'crusaders':
- view.prompt = "Draw Phase: Place " + block_name(game.who) + " in the staging area.";
- gen_action(view, 'town', block_home(game.who));
- can_place = true;
- break;
+ view.prompt = "Draw Phase: Place " + block_name(game.who) + " in the staging area."
+ gen_action(view, 'town', block_home(game.who))
+ can_place = true
+ break
case 'pilgrims':
- view.prompt = "Draw Phase: Place " + block_name(game.who) + " in a friendly port.";
+ view.prompt = "Draw Phase: Place " + block_name(game.who) + " in a friendly port."
for (let town of TOWNLIST) {
if (is_friendly_port(town) || can_enter_besieged_port(town)) {
- gen_action(view, 'town', town);
- can_place = true;
+ gen_action(view, 'town', town)
+ can_place = true
}
}
- break;
+ break
case 'turcopoles':
case 'outremers':
case 'emirs':
case 'nomads':
view.prompt = "Draw Phase: Place " + BLOCKS[game.who].name + " at full strength in "
- + list_seats(game.who).join(", ") + " or at strength 1 in any friendly town.";
+ + list_seats(game.who).join(", ") + " or at strength 1 in any friendly town."
for (let town of TOWNLIST) {
if (town === ENGLAND || town === FRANCE || town === GERMANIA)
- continue;
+ continue
// FAQ claims besieger controls town for draw purposes
if (is_friendly_field(town)) {
- gen_action(view, 'town', town);
- can_place = true;
+ gen_action(view, 'town', town)
+ can_place = true
}
}
- break;
+ break
}
if (!can_place)
- gen_action(view, 'next');
+ gen_action(view, 'next')
},
town: function (where) {
- let type = block_type(game.who);
+ let type = block_type(game.who)
- log(game.active + " placed drawn block in " + where + ".");
+ log(game.active + " placed drawn block in " + where + ".")
- game.location[game.who] = where;
+ game.location[game.who] = where
if (type === 'turcopoles' || type === 'outremers' || type === 'emirs' || type === 'nomads') {
if (is_home_seat(where, game.who))
- game.steps[game.who] = block_max_steps(game.who);
+ game.steps[game.who] = block_max_steps(game.who)
else
- game.steps[game.who] = 1;
+ game.steps[game.who] = 1
} else {
- game.steps[game.who] = block_max_steps(game.who);
+ game.steps[game.who] = block_max_steps(game.who)
if (can_enter_besieged_port(where))
- game.castle.push(game.who);
+ game.castle.push(game.who)
}
- game.who = null;
- end_draw_phase();
+ game.who = null
+ end_draw_phase()
},
next: function () {
- end_draw_phase();
+ end_draw_phase()
},
}
function end_draw_phase() {
if (game.active === game.p1) {
- game.active = game.p2;
- start_draw_phase();
+ game.active = game.p2
+ start_draw_phase()
} else {
- end_game_turn();
+ end_game_turn()
}
}
function end_game_turn() {
if (is_winter()) {
- goto_winter_1();
+ goto_winter_1()
} else {
if (check_sudden_death())
- return;
- game.turn ++;
- start_game_turn();
+ return
+ game.turn ++
+ start_game_turn()
}
}
// WINTER CAMPAIGN & SUPPLY
function goto_winter_1() {
- log("");
- log("Start Winter of " + game.year);
- log("");
+ log("")
+ log("Start Winter of " + game.year)
+ log("")
if (game.winter_campaign)
- goto_winter_siege_attrition();
+ goto_winter_siege_attrition()
else
- goto_winter_2();
+ goto_winter_2()
}
function goto_winter_siege_attrition() {
- log(game.active + " winter campaigned in " + game.winter_campaign + ".");
- game.where = game.winter_campaign;
+ log(game.active + " winter campaigned in " + game.winter_campaign + ".")
+ game.where = game.winter_campaign
- game.active = besieged_player(game.where);
- game.state = 'winter_siege_attrition';
- game.attrition_list = [];
+ game.active = besieged_player(game.where)
+ game.state = 'winter_siege_attrition'
+ game.attrition_list = []
for (let b of BLOCKLIST)
if (is_block_in_castle_in(b, game.where))
- game.attrition_list.push(b);
+ game.attrition_list.push(b)
}
function resume_winter_siege_attrition() {
if (game.attrition_list.length === 0) {
- delete game.attrition_list;
+ delete game.attrition_list
if (!is_under_siege(game.where)) {
- game.active = enemy(game.active);
- log(game.where + " fell to siege attrition.");
- goto_regroup();
+ game.active = enemy(game.active)
+ log(game.where + " fell to siege attrition.")
+ goto_regroup()
} else {
- log("Siege continued.");
- goto_winter_2();
+ log("Siege continued.")
+ goto_winter_2()
}
}
}
@@ -3407,78 +3409,78 @@ function resume_winter_siege_attrition() {
states.winter_siege_attrition = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Winter Siege Attrition: Waiting for " + game.active + ".";
- view.prompt = "Winter Siege Attrition: Roll for siege attrition in " + game.where + ".";
+ return view.prompt = "Winter Siege Attrition: Waiting for " + game.active + "."
+ view.prompt = "Winter Siege Attrition: Roll for siege attrition in " + game.where + "."
for (let b of game.attrition_list)
gen_action(view, 'block', b)
},
block: function (who) {
- let target = (game.where === TYRE || game.where === TRIPOLI) ? 2 : 4;
- let die = roll_d6();
+ let target = (game.where === TYRE || game.where === TRIPOLI) ? 2 : 4
+ let die = roll_d6()
if (die <= target) {
- log("Attrition roll " + DIE_HIT[die] + ".");
- reduce_block(who);
+ log("Attrition roll " + DIE_HIT[die] + ".")
+ reduce_block(who)
} else {
- log("Attrition roll " + DIE_MISS[die] + ".");
+ log("Attrition roll " + DIE_MISS[die] + ".")
}
- remove_from_array(game.attrition_list, who);
- resume_winter_siege_attrition();
+ remove_from_array(game.attrition_list, who)
+ resume_winter_siege_attrition()
}
}
function goto_winter_2() {
- game.where = null;
- eliminate_besieging_blocks(FRANKS);
- eliminate_besieging_blocks(SARACENS);
- lift_all_sieges();
+ game.where = null
+ eliminate_besieging_blocks(FRANKS)
+ eliminate_besieging_blocks(SARACENS)
+ lift_all_sieges()
if (check_sudden_death())
- return;
+ return
if (game.year === 1192)
- return goto_year_end();
- goto_winter_supply();
+ return goto_year_end()
+ goto_winter_supply()
}
function eliminate_besieging_blocks(owner) {
- game.summary = [];
+ game.summary = []
for (let b of BLOCKLIST) {
if (block_owner(b) === owner) {
- let where = game.location[b];
+ let where = game.location[b]
if (where === game.winter_campaign)
- continue;
+ continue
if (is_block_on_land(b) && is_under_siege(where))
if (block_owner(b) === besieging_player(where))
- disband(b);
+ disband(b)
}
}
if (game.summary.length > 0)
- print_summary(owner + " disbanded sieges:");
+ print_summary(owner + " disbanded sieges:")
else
- game.summary = null;
+ game.summary = null
}
function need_winter_supply_check() {
for (let town of TOWNLIST) {
if (town === game.winter_campaign)
- continue;
+ continue
if (is_friendly_town(town) && !is_within_castle_limit(town))
- return true;
+ return true
}
- return false;
+ return false
}
function goto_winter_supply() {
- game.active = FRANKS;
+ game.active = FRANKS
if (need_winter_supply_check()) {
- game.state = 'winter_supply';
- game.summary = [];
+ game.state = 'winter_supply'
+ game.summary = []
} else {
- game.active = SARACENS;
+ game.active = SARACENS
if (need_winter_supply_check()) {
- game.state = 'winter_supply';
- game.summary = [];
+ game.state = 'winter_supply'
+ game.summary = []
} else {
- game.active = FRANKS;
- goto_winter_replacements();
+ game.active = FRANKS
+ goto_winter_replacements()
}
}
}
@@ -3486,43 +3488,43 @@ function goto_winter_supply() {
states.winter_supply = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Winter Supply: Waiting for " + game.active + ".";
- gen_action_undo(view);
- let okay_to_end = true;
+ return view.prompt = "Winter Supply: Waiting for " + game.active + "."
+ gen_action_undo(view)
+ let okay_to_end = true
for (let b of BLOCKLIST) {
if (block_owner(b) === game.active) {
if (is_block_on_land(b)) {
- let where = game.location[b];
+ let where = game.location[b]
if (where === game.winter_campaign)
- continue;
+ continue
if (!is_within_castle_limit(where)) {
- gen_action(view, 'block', b);
- okay_to_end = false;
+ gen_action(view, 'block', b)
+ okay_to_end = false
}
}
}
}
if (okay_to_end) {
- view.prompt = "Winter Supply: Disband excess blocks \u2014 done.";
- gen_action(view, 'next');
+ view.prompt = "Winter Supply: Disband excess blocks \u2014 done."
+ gen_action(view, 'next')
} else {
- view.prompt = "Winter Supply: Disband excess blocks.";
+ view.prompt = "Winter Supply: Disband excess blocks."
}
},
block: function (who) {
- push_undo();
- disband(who);
+ push_undo()
+ disband(who)
},
next: function () {
- clear_undo();
+ clear_undo()
if (game.summary.length > 0)
- print_summary(game.active + " disbanded:");
+ print_summary(game.active + " disbanded:")
if (game.active === FRANKS) {
- game.active = SARACENS;
- game.summary = [];
+ game.active = SARACENS
+ game.summary = []
} else {
- game.active = FRANKS;
- goto_winter_replacements();
+ game.active = FRANKS
+ goto_winter_replacements()
}
},
undo: pop_undo
@@ -3531,153 +3533,149 @@ states.winter_supply = {
// WINTER REPLACEMENTS
function goto_winter_replacements() {
- game.rp = {};
+ game.rp = {}
for (let town of TOWNLIST)
if (is_under_siege(town))
- game.rp[town] = 0;
+ game.rp[town] = 0
else
- game.rp[town] = castle_limit(town);
+ game.rp[town] = castle_limit(town)
- game.summary = [];
- game.state = 'winter_replacements';
+ game.summary = []
+ game.state = 'winter_replacements'
}
function replacement_cost(where) {
- let region = TOWNS[where].region;
+ let region = TOWNS[where].region
if (KINGDOMS[region] === game.active)
- return 1;
- return 2;
+ return 1
+ return 2
}
states.winter_replacements = {
prompt: function (view, current) {
if (is_inactive_player(current))
- return view.prompt = "Winter Replacements: Waiting for " + game.active + ".";
- view.prompt = "Winter Replacements: Distribute replacement points.";
- gen_action_undo(view);
- let okay_to_end = true;
+ return view.prompt = "Winter Replacements: Waiting for " + game.active + "."
+ view.prompt = "Winter Replacements: Distribute replacement points."
+ gen_action_undo(view)
+ let okay_to_end = true
for (let b of BLOCKLIST) {
if (block_owner(b) === game.active && is_block_on_land(b)) {
- let where = game.location[b];
- let cost = replacement_cost(where);
+ let where = game.location[b]
+ let cost = replacement_cost(where)
if (is_friendly_town(where) && game.rp[where] >= cost) {
if (game.steps[b] < block_max_steps(b)) {
- gen_action(view, 'block', b);
- okay_to_end = false;
+ gen_action(view, 'block', b)
+ okay_to_end = false
}
}
}
}
if (okay_to_end) {
- view.prompt = "Winter Replacements: Distribute replacement points \u2014 done.";
- gen_action(view, 'next');
+ view.prompt = "Winter Replacements: Distribute replacement points \u2014 done."
+ gen_action(view, 'next')
} else {
- view.prompt = "Winter Replacements: Distribute replacement points.";
+ view.prompt = "Winter Replacements: Distribute replacement points."
}
},
block: function (who) {
- push_undo();
- let where = game.location[who];
- let cost = replacement_cost(where);
- game.summary.push([where]);
- game.steps[who] ++;
- game.rp[where] -= cost;
+ push_undo()
+ let where = game.location[who]
+ let cost = replacement_cost(where)
+ game.summary.push([where])
+ game.steps[who] ++
+ game.rp[where] -= cost
},
next: function () {
- clear_undo();
- end_winter_replacements();
+ clear_undo()
+ end_winter_replacements()
},
undo: pop_undo
}
function end_winter_replacements() {
- print_summary(active_adjective() + " replacements:");
+ print_summary(active_adjective() + " replacements:")
if (game.active === FRANKS) {
- game.active = SARACENS;
- game.summary = [];
+ game.active = SARACENS
+ game.summary = []
} else {
- goto_year_end();
+ goto_year_end()
}
}
function goto_year_end() {
if (game.year === 1192) {
- game.state = 'game_over';
- let f_vp = count_victory_points(FRANKS);
- let s_vp = count_victory_points(SARACENS);
+ game.state = 'game_over'
+ let f_vp = count_victory_points(FRANKS)
+ let s_vp = count_victory_points(SARACENS)
if (f_vp > s_vp) {
- game.result = FRANKS;
- game.victory = "Franks won!";
+ game.result = FRANKS
+ game.victory = "Franks won!"
} else if (f_vp < s_vp) {
- game.victory = "Saracens won!";
- game.result = SARACENS;
+ game.victory = "Saracens won!"
+ game.result = SARACENS
} else {
- game.victory = "The game ended in a draw.";
- game.result = null;
+ game.victory = "The game ended in a draw."
+ game.result = null
}
- log("");
- log(game.victory);
- return;
+ log("")
+ log(game.victory)
+ return
}
// Return eliminated blocks to pool.
for (let b of BLOCKLIST)
if (game.location[b] === DEAD)
- game.location[b] = block_pool(b);
+ game.location[b] = block_pool(b)
- game.year ++;
- start_year();
+ game.year ++
+ start_year()
}
// GAME OVER
states.game_over = {
prompt: function (view) {
- view.prompt = game.victory;
+ view.prompt = game.victory
}
}
// SETUP
function setup_game() {
- reset_blocks();
- game.year = 1187;
- game.turn = 0;
+ reset_blocks()
+ game.year = 1187
+ game.turn = 0
for (let b of BLOCKLIST) {
if (block_owner(b) === FRANKS) {
switch (block_type(b)) {
case 'pilgrims':
- deploy(b, block_pool(b));
- break;
+ deploy(b, block_pool(b))
+ break
case 'crusaders':
- deploy(b, block_pool(b));
- break;
+ deploy(b, block_pool(b))
+ break
default:
- deploy(b, block_home(b));
- break;
+ deploy(b, block_home(b))
+ break
}
}
if (block_owner(b) === SARACENS) {
if (block_type(b) === 'emirs')
- deploy(b, block_home(b));
+ deploy(b, block_home(b))
if (block_type(b) === 'nomads')
- deploy(b, block_pool(b));
+ deploy(b, block_pool(b))
}
if (block_owner(b) === ASSASSINS) {
- deploy(b, block_home(b));
+ deploy(b, block_home(b))
}
}
- goto_frank_deployment();
+ goto_frank_deployment()
}
// VIEW
function make_battle_view() {
- let is_storming = game.storming.length > 0 && game.state !== 'declare_storm';
- let is_sallying = game.sallying.length > 0 && game.state !== 'declare_sally';
- let is_field_battle = game.is_field_battle;
-
let battle = {
FR: [], FC: [], FF: [],
SR: [], SC: [], SF: [],
@@ -3691,18 +3689,18 @@ function make_battle_view() {
show_castle: game.show_castle,
show_field: game.show_field,
town: game.where,
- };
+ }
if (is_under_siege(game.where) && !is_contested_battle_field(game.where))
- battle.title = enemy(game.castle_owner) + " besiege " + game.where;
+ battle.title = enemy(game.castle_owner) + " besiege " + game.where
else
- battle.title = game.attacker[game.where] + " attack " + game.where;
+ battle.title = game.attacker[game.where] + " attack " + game.where
if (game.combat_round === 0)
- battle.title += " \u2014 Combat Deployment";
+ battle.title += " \u2014 Combat Deployment"
else
- battle.title += " \u2014 Round " + game.combat_round + " of 3";
+ battle.title += " \u2014 Round " + game.combat_round + " of 3"
if (game.where === game.jihad)
- battle.title += " \u2014 Jihad!";
+ battle.title += " \u2014 Jihad!"
function fill_cell(cell, owner, fn) {
for (let b of BLOCKLIST)
@@ -3710,16 +3708,16 @@ function make_battle_view() {
cell.push(b)
}
- fill_cell(battle.FR, FRANKS, b => is_reserve(b));
- fill_cell(battle.FC, FRANKS, b => is_block_in_castle(b));
- fill_cell(battle.FF, FRANKS, b => is_block_in_field(b) && !game.storming.includes(b));
- fill_cell(battle.FF, SARACENS, b => is_block_in_field(b) && game.storming.includes(b));
- fill_cell(battle.SF, FRANKS, b => is_block_in_field(b) && game.storming.includes(b));
- fill_cell(battle.SF, SARACENS, b => is_block_in_field(b) && !game.storming.includes(b));
- fill_cell(battle.SC, SARACENS, b => is_block_in_castle(b));
- fill_cell(battle.SR, SARACENS, b => is_reserve(b));
+ fill_cell(battle.FR, FRANKS, b => is_reserve(b))
+ fill_cell(battle.FC, FRANKS, b => is_block_in_castle(b))
+ fill_cell(battle.FF, FRANKS, b => is_block_in_field(b) && !game.storming.includes(b))
+ fill_cell(battle.FF, SARACENS, b => is_block_in_field(b) && game.storming.includes(b))
+ fill_cell(battle.SF, FRANKS, b => is_block_in_field(b) && game.storming.includes(b))
+ fill_cell(battle.SF, SARACENS, b => is_block_in_field(b) && !game.storming.includes(b))
+ fill_cell(battle.SC, SARACENS, b => is_block_in_castle(b))
+ fill_cell(battle.SR, SARACENS, b => is_reserve(b))
- return battle;
+ return battle
}
exports.setup = function (seed, scenario, options) {
@@ -3754,57 +3752,57 @@ exports.setup = function (seed, scenario, options) {
game.rng = options.rng
if (options && options.iron_bridge) {
- game.iron_bridge = 1;
- log("Iron Bridge:\nThe road between Antioch and Harim has a move limit of 3.");
- log("");
+ game.iron_bridge = 1
+ log("Iron Bridge:\nThe road between Antioch and Harim has a move limit of 3.")
+ log("")
}
- setup_game();
- return game;
+ setup_game()
+ return game
}
exports.action = function (state, current, action, arg) {
- game = state;
- let S = states[game.state];
+ game = state
+ let S = states[game.state]
if (action in S)
- S[action](arg, current);
+ S[action](arg, current)
else
- throw new Error("Invalid action: " + action);
- return game;
+ throw new Error("Invalid action: " + action)
+ return game
}
exports.resign = function (state, current) {
- game = state;
+ game = state
if (game.state !== 'game_over') {
- log("");
- log(current + " resigned.");
- game.active = "None";
- game.state = 'game_over';
- game.victory = current + " resigned.";
- game.result = enemy(current);
+ log("")
+ log(current + " resigned.")
+ game.active = "None"
+ game.state = 'game_over'
+ game.victory = current + " resigned."
+ game.result = enemy(current)
}
- return game;
+ return game
}
function make_siege_view() {
- let list = {};
+ let list = {}
for (let t of TOWNLIST)
if (is_under_siege(t))
- list[t] = besieging_player(t);
- return list;
+ list[t] = besieging_player(t)
+ return list
}
function observer_hand() {
- let hand = [];
- hand.length = Math.max(game.s_hand.length, game.f_hand.length);
- hand.fill(0);
- return hand;
+ let hand = []
+ hand.length = Math.max(game.s_hand.length, game.f_hand.length)
+ hand.fill(0)
+ return hand
}
-exports.is_checkpoint = (a, b) => a.turn !== b.turn;
+exports.is_checkpoint = (a, b) => a.turn !== b.turn
exports.view = function(state, current) {
- game = state;
+ game = state
let view = {
log: game.log,
@@ -3826,17 +3824,17 @@ exports.view = function(state, current) {
battle: null,
prompt: null,
actions: null,
- };
+ }
if (game.jihad && game.jihad !== game.p1)
- view.jihad = game.jihad;
+ view.jihad = game.jihad
if (game.winter_campaign && game.winter_campaign !== game.p1 && game.winter_campaign !== game.p2)
- view.winter_campaign = game.winter_campaign;
+ view.winter_campaign = game.winter_campaign
- states[game.state].prompt(view, current);
+ states[game.state].prompt(view, current)
if (states[game.state].show_battle)
- view.battle = make_battle_view();
+ view.battle = make_battle_view()
- return view;
+ return view
}