summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js104
1 files changed, 104 insertions, 0 deletions
diff --git a/rules.js b/rules.js
index f0449c4..f91e303 100644
--- a/rules.js
+++ b/rules.js
@@ -43,6 +43,7 @@ const first_piece = data.first_piece
const last_piece = data.last_piece
const first_space = S_ANDHRA
const last_space = S_PUNJAB
+const last_province = S_TAMILAKAM
const faction_name = [ "Delhi Sultanate", "Bahmani Kingdom", "Vijayanagara Empire", "Mongol Invaders" ]
@@ -99,6 +100,7 @@ exports.view = function (state, role) {
cylinder: game.cylinder,
pieces: game.pieces,
tributary: game.tributary,
+ control: game.control,
}
if (game.result) {
@@ -186,6 +188,7 @@ exports.setup = function (seed, scenario, _options) {
bk_inf: 0,
ve_inf: 0,
tributary: 8191, // all 13 provinces
+ control: [0, 0, 0],
rebel: 0, // amir/raja rebel status
pieces: Array(104).fill(AVAILABLE), // piece locations
cavalry: [0, 0, 0],
@@ -415,6 +418,11 @@ function goto_conscript() {
game.state = "rally"
}
+function goto_rebel() {
+ init_command("Rebel")
+ game.state = "rebel"
+}
+
/* STATES */
states.eligible = {
@@ -467,6 +475,7 @@ states.command_decree = {
build: goto_build,
conscript: goto_conscript,
rally: goto_rally,
+ rebel: goto_rebel,
}
states.event_command = {
@@ -477,6 +486,7 @@ states.event_command = {
},
conscript: goto_conscript,
rally: goto_rally,
+ rebel: goto_rebel,
}
states.lim_command = {
@@ -487,6 +497,7 @@ states.lim_command = {
},
conscript: goto_conscript,
rally: goto_rally,
+ rebel: goto_rebel,
}
states.build = {
@@ -600,6 +611,29 @@ states.rally_space = {
}
}
+states.rebel = {
+ prompt() {
+ view.prompt = "Rebel: Select a Province where you are in majority."
+
+ if (can_select_cmd_space(1)) {
+ for (let s = first_space; s <= last_space; ++s) {
+ if (!is_selected_cmd_space(s) && can_rebel_in_space(s))
+ gen_action_space(s)
+ }
+ }
+
+ view.actions.end_rebel = prompt_end_cmd(1)
+ },
+ space(s) {
+ push_undo()
+ select_cmd_space(s, 1)
+ remove_tributary(s)
+ log_space(s, "Rebel")
+ },
+ end_rebel: end_command,
+
+}
+
/* COMMANDS */
function init_command(type) {
@@ -616,6 +650,7 @@ function gen_any_command() {
view.actions.conscript = can_conscript() ? 1 : 0
} else if (game.current === BK || game.current === VE) {
view.actions.rally = can_rally() ? 1 : 0
+ view.actions.rebel = can_rebel() ? 1 : 0
}
}
@@ -676,6 +711,21 @@ function rally_count() {
return count
}
+function can_rebel() {
+ // todo: implement dynasty logic
+ for (let s = first_space; s <= last_space; ++s) {
+ if (can_rebel_in_space(s))
+ return true
+ }
+ return false
+}
+
+function can_rebel_in_space(s) {
+ if (is_tributary(s) && has_majority(s) === game.current)
+ return true
+ return false
+}
+
function prompt_end_cmd(cost) {
if (!view.actions.space) {
if (game.op.limited && game.op.spaces && game.op.spaces.length > 0)
@@ -716,6 +766,7 @@ function can_build_in_space(s) {
function add_tributary(s) {
game.tributary |= (1 << s)
+ update_control()
}
function is_tributary(s) {
@@ -724,10 +775,52 @@ function is_tributary(s) {
function remove_tributary(s) {
game.tributary &= ~(1 << s)
+ update_control()
}
/* MISC SPACE + PIECE QUERIES */
+function count_pieces(s, faction, type) {
+ let first = first_piece[faction][type]
+ let last = last_piece[faction][type]
+ let n = 0
+ for (let p = first; p <= last; ++p)
+ if (piece_space(p) === s)
+ ++n
+ return n
+}
+
+function count_faction_pieces(s, faction) {
+ switch (faction) {
+ case DS:
+ return count_pieces(s, DS, TROOPS) + count_pieces(s, DS, ELITE) + count_pieces(s, DS, DISC)
+ case BK:
+ return count_pieces(s, BK, ELITE) + count_pieces(s, BK, DISC)
+ case VE:
+ return count_pieces(s, VE, ELITE) + count_pieces(s, VE, DISC)
+ case MI:
+ return count_pieces(s, MI, TROOPS)
+ }
+}
+
+function has_majority(s) {
+ let d = count_faction_pieces(s, DS)
+ let b = count_faction_pieces(s, BK)
+ let v = count_faction_pieces(s, VE)
+ let m = count_faction_pieces(s, MI)
+
+ if (d > b + v + m)
+ return DS
+ else if (b > d + v + m)
+ return BK
+ else if (v > b + d + m)
+ return VE
+ else if (m > b + d+ v)
+ return MI
+ else
+ return -1
+}
+
function has_piece(s, faction, type) {
let first = first_piece[faction][type]
let last = last_piece[faction][type]
@@ -770,6 +863,7 @@ function place_piece(p, s) {
p = find_piece(AVAILABLE, piece_faction(p), piece_type(p))
set_piece_space(p, s)
+ update_control()
}
function piece_faction(p) {
@@ -822,6 +916,16 @@ function add_resources(faction, n) {
game.resources[faction] = Math.max(0, Math.min(24, game.resources[faction] + n))
}
+function update_control() {
+ game.control = [0, 0, 0]
+ for (let s = first_space; s <= last_province; ++s) {
+ if (is_tributary(s)) continue
+
+ let c = has_majority(s)
+ if (c <= VE)
+ game.control[c] |= (1 << s)
+ }
+}
/* ACTIONS */