/* Voting state. */
vote_pending: null,
/* Game state. */
+ started: false,
finished: false,
done_players: new Set()
};
* Join / Events / Game lifecycle *
*****************************************************/
- handle_join(request, response) {
+ handle_start(request, response) {
const session_id = request.session.id;
const player = this.players_by_session[session_id];
return;
}
- if (!this.state.player_words[session_id]) {
- this.state.player_words[session_id] = [];
+ this.state.started = true;
+
+ /* Add all active players to the game. */
+ for (const p of this.players) {
+ if (p.active && !this.state.player_words[p.session_id]) {
+ this.state.player_words[p.session_id] = [];
+ }
}
- response.json({
- center: this.state.center,
- player_words: this._all_player_words(),
- scores: this._compute_all_scores(),
- remaining: this.state.bag.length
- });
+ this.broadcast_event_object("game-started", {});
+ response.json({ ok: true });
}
handle_done(request, response) {
const session_id = request.session.id;
+ /* If the game has already started, auto-join this player. */
+ if (this.state.started) {
+ if (!this.state.player_words[session_id]) {
+ this.state.player_words[session_id] = [];
+ }
+ response.write(`event: game-started\ndata: {}\n\n`);
+ }
+
/* Send center state. */
response.write(`event: center\ndata: ${JSON.stringify(
this.state.center
Anagrams.router = express.Router();
const router = Anagrams.router;
-router.post('/join', (request, response) => {
- request.game.handle_join(request, response);
+router.post('/start', (request, response) => {
+ request.game.handle_start(request, response);
});
router.post('/claim', (request, response) => {
player_boards: {},
results: null,
stuck: new Set(),
+ started: false,
finished: false
};
}
return true;
}
- handle_join(request, response) {
+ /* Deal initial tiles to a single player. */
+ _deal_initial(session_id) {
+ if (this.state.player_tiles[session_id]) return;
+
+ const tiles = [];
+ for (let i = 0; i < INITIAL_TILES && this.state.bag.length > 0; i++) {
+ tiles.push(this.state.bag.pop());
+ }
+ this.state.player_tiles[session_id] = tiles;
+ }
+
+ handle_start(request, response) {
const session_id = request.session.id;
const player = this.players_by_session[session_id];
return;
}
- /* Don't re-deal if player already has tiles. */
- if (this.state.player_tiles[session_id]) {
- response.json({
- tiles: this.state.player_tiles[session_id],
- remaining: this.state.bag.length
- });
- return;
- }
+ this.state.started = true;
- /* Deal initial tiles. */
- const tiles = [];
- for (let i = 0; i < INITIAL_TILES && this.state.bag.length > 0; i++) {
- tiles.push(this.state.bag.pop());
+ /* Deal initial tiles to all active players. */
+ for (const p of this.players) {
+ if (p.active) {
+ this._deal_initial(p.session_id);
+ }
}
- this.state.player_tiles[session_id] = tiles;
- this.broadcast_event_object("player-joined-game", {
- name: player.name
- });
+ /* Send each player their tiles. */
+ for (const p of this.players) {
+ if (p.active && this.state.player_tiles[p.session_id]) {
+ const data = JSON.stringify({
+ tiles: this.state.player_tiles[p.session_id]
+ });
+ p.send(`event: tiles\ndata: ${data}\n\n`);
+ }
+ }
+ this.broadcast_event_object("game-started", {});
this.broadcast_event_object("dealt", {
remaining: this.state.bag.length
});
- response.json({ tiles: tiles, remaining: this.state.bag.length });
+ response.json({ ok: true });
}
handle_stuck(request, response) {
super.handle_events(request, response);
const session_id = request.session.id;
+
+ /* If the game has already started, auto-join this player. */
+ if (this.state.started) {
+ this._deal_initial(session_id);
+ response.write(`event: game-started\ndata: {}\n\n`);
+ }
+
const tiles = this.state.player_tiles[session_id];
/* Send this player's current tiles so reconnecting players
LetterRip.router = express.Router();
const router = LetterRip.router;
-router.post('/join', (request, response) => {
- request.game.handle_join(request, response);
+router.post('/start', (request, response) => {
+ request.game.handle_start(request, response);
});
router.post('/stuck', (request, response) => {