]> git.cworth.org Git - empires-server/blob - empathy.js
empathy: Tell clients how many players have responded
[empires-server] / empathy.js
1 const express = require("express");
2 const Game = require("./game.js");
3
4 class Empathy extends Game {
5   constructor(id) {
6     super(id);
7     this.state = {
8       prompts: [],
9       active_prompt: null,
10       players_answered: 0
11     };
12     this.answers = [];
13     this.next_prompt_id = 1;
14   }
15
16   add_prompt(items, prompt_string) {
17     const prompt = new Prompt(this.next_prompt_id, items, prompt_string);
18     this.next_prompt_id++;
19
20     this.state.prompts.push(prompt);
21
22     this.broadcast_event_object('prompt', prompt);
23
24     return prompt;
25   }
26
27   /* Returns true if vote toggled, false for player or prompt not found */
28   toggle_vote(prompt_id, session_id) {
29     const player = this.players_by_session[session_id];
30
31     const prompt = this.state.prompts.find(p => p.id === prompt_id);
32     if (! prompt || ! player)
33       return false;
34
35     prompt.toggle_vote(player.name);
36
37     this.broadcast_event_object('prompt', prompt);
38
39     return true;
40   }
41
42   /* Returns true on success, false for prompt not found. */
43   start(prompt_id) {
44     const prompt = this.state.prompts.find(p => p.id === prompt_id);
45     if (! prompt)
46       return false;
47
48     /* Ignore any start request that comes in while a prompt is
49      * already being played. */
50     if (this.state.active_prompt)
51       return false;
52
53     this.state.active_prompt = prompt;
54
55     this.broadcast_event_object('start', prompt);
56
57     return true;
58   }
59
60   receive_answer(prompt_id, session_id, answers) {
61     const player = this.players_by_session[session_id];
62     if (! player)
63       return { valid: false, message: "Player not found" };
64
65     const prompt = this.state.prompts.find(p => p.id === prompt_id);
66     if (! prompt)
67       return { valid: false, message: "Prompt not found" };
68
69     if (prompt !== this.state.active_prompt)
70       return { valid: false, message: "Prompt no longer active" };
71
72     /* Save the complete answers for our own use later. */
73     this.answers.push({
74       player: player,
75       answers: answers
76     });
77
78     /* And notify players how many players have answered. */
79     this.state.players_answered++;
80
81     this.broadcast_event_object('answered', this.state.players_answered);
82
83     return { valid: true };
84   }
85 }
86
87 Empathy.router = express.Router();
88 const router = Empathy.router;
89
90 class Prompt {
91   constructor(id, items, prompt) {
92     this.id = id;
93     this.items = items;
94     this.prompt = prompt;
95     this.votes = [];
96   }
97
98   toggle_vote(player_name) {
99     if (this.votes.find(v => v === player_name))
100       this.votes = this.votes.filter(v => v !== player_name);
101     else
102       this.votes.push(player_name);
103   }
104 }
105
106 router.post('/prompts', (request, response) => {
107   const game = request.game;
108
109   game.add_prompt(request.body.items, request.body.prompt);
110 });
111
112 router.post('/vote/:prompt_id([0-9]+)', (request, response) => {
113   const game = request.game;
114   const prompt_id = parseInt(request.params.prompt_id, 10);
115
116   if (game.toggle_vote(prompt_id, request.session.id))
117     response.sendStatus(200);
118   else
119     response.sendStatus(404);
120 });
121
122 router.post('/start/:prompt_id([0-9]+)', (request, response) => {
123   const game = request.game;
124   const prompt_id = parseInt(request.params.prompt_id, 10);
125
126   if (game.start(prompt_id))
127     response.sendStatus(200);
128   else
129     response.sendStatus(404);
130 });
131
132 router.post('/answer/:prompt_id([0-9]+)', (request, response) => {
133   const game = request.game;
134   const prompt_id = parseInt(request.params.prompt_id, 10);
135
136   const result = game.receive_answer(prompt_id,
137                                      request.session.id,
138                                      request.body.answers);
139   response.json(result);
140 });
141
142 Empathy.meta = {
143   name: "Empathy",
144   identifier: "empathy",
145 };
146
147 exports.Game = Empathy;