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