summaryrefslogtreecommitdiff
path: root/rules.js
diff options
context:
space:
mode:
Diffstat (limited to 'rules.js')
-rw-r--r--rules.js116
1 files changed, 116 insertions, 0 deletions
diff --git a/rules.js b/rules.js
new file mode 100644
index 0000000..52bdd63
--- /dev/null
+++ b/rules.js
@@ -0,0 +1,116 @@
+"use strict"
+
+const P1 = "Red"
+const P2 = "Blue"
+const P3 = "Yellow"
+const P4 = "Green"
+
+const player_names = [ P1, P2, P3, P4 ]
+
+const player_names_by_scenario = {
+ "4P": [ P1, P2, P3, P4 ],
+ "3P": [ P1, P2, P3 ],
+ "2P": [ P1, P2 ],
+}
+
+const scenario_player_count = {
+ "4P": 4,
+ "3P": 3,
+ "2P": 2,
+}
+
+const player_index = {
+ [P1]: 0,
+ [P2]: 1,
+ [P3]: 2,
+ [P4]: 3,
+ "Observer": -1,
+}
+
+var game
+var view
+
+const states = {}
+
+exports.scenarios = [ "Standard" ]
+
+exports.roles = function (scenario, options) {
+ if (options.players == 2)
+ return [ P1, P2 ]
+ if (options.players == 3)
+ return [ P1, P2, P3 ]
+ return [ P1, P2, P3, P4 ]
+}
+
+exports.setup = function (seed, scenario, options) {
+ let players = options.players || 4
+ game = {
+ seed: seed,
+ log: [],
+ undo: [],
+ players: players,
+ active: 0,
+ state: "none",
+ }
+ return save_game()
+}
+
+function load_game(state) {
+ game = state
+ game.active = player_index[game.active]
+}
+
+function save_game() {
+ game.active = player_names[game.active]
+ return game
+}
+
+exports.action = function (state, player, action, arg) {
+ load_game(state)
+ let S = states[game.state]
+ if (action in S) {
+ S[action](arg)
+ } else {
+ if (action === "undo" && game.undo && game.undo.length > 0)
+ pop_undo()
+ else
+ throw new Error("Invalid action: " + action)
+ }
+ return save_game()
+}
+
+exports.view = function (state, player_name) {
+ let player = player_index[player_name]
+
+ load_game(state)
+
+ view = {
+ log: game.log,
+ active: player_names[game.active],
+ prompt: null,
+ }
+
+ if (game.state === "game_over") {
+ view.prompt = game.victory
+ } else if (game.active !== player) {
+ let inactive = states[game.state].inactive || game.state
+ view.prompt = `Waiting for ${player_names[game.active]} \u2014 ${inactive}...`
+ } else {
+ view.actions = {}
+ states[game.state].prompt()
+ view.prompt = player_names[game.active] + ": " + view.prompt
+ if (game.undo && game.undo.length > 0)
+ view.actions.undo = 1
+ else
+ view.actions.undo = 0
+ }
+
+ save_game()
+ return view
+}
+
+// STATES
+
+states.none = {
+ prompt() {}
+}