summaryrefslogtreecommitdiff
path: root/rules.js
blob: 52bdd63d80e23dfa35be538d90348599613acd9e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
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() {}
}