-
Notifications
You must be signed in to change notification settings - Fork 34
/
GameBoardBuilder.ts
153 lines (143 loc) · 4.15 KB
/
GameBoardBuilder.ts
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import localize from '@i18n/localize';
import AI from '@tictactoe/AI';
import Entity from '@tictactoe/Entity';
import { Player } from '@tictactoe/Player';
import { MessageOptions } from 'discord.js';
/**
* Builds representation of a game board using text emojis
* whiches will be displayed in a Discord message.
*
* @author Utarwyn
* @since 2.1.0
*/
export default class GameBoardBuilder {
/**
* Unicode reactions available for moves.
*/
public static readonly MOVE_REACTIONS = ['↖️', '⬆️', '↗️', '⬅️', '⏺️', '➡️', '↙️', '⬇️', '↘️'];
/**
* Unicode emojis used for representing the two players.
* @protected
*/
protected emojies = ['⬜', '🇽', '🅾️'];
/**
* Stores game board title message.
* @protected
*/
protected title: string;
/**
* Stores game current state.
* @protected
*/
protected state: string;
/**
* Stores game board size.
* @protected
*/
protected boardSize: number;
/**
* Stores game board data.
* @protected
*/
protected boardData: Player[];
/**
* Constructs a new game board builder.
*/
constructor() {
this.title = '';
this.state = '';
this.boardSize = 0;
this.boardData = [];
}
/**
* Writes a title to the game board message.
*
* @param player1 first entity to play
* @param player2 second entity to play
* @returns same instance
*/
withTitle(player1: Entity, player2: Entity): GameBoardBuilder {
this.title =
localize.__('game.title', {
player1: player1.displayName,
player2: player2.displayName
}) + '\n\n';
return this;
}
/**
* Configures emojies used for representing both entities.
*
* @param first emoji of the first entity
* @param second emoji of the second entity
* @returns same instance
*/
withEmojies(first: string, second: string): GameBoardBuilder {
this.emojies[1] = first;
this.emojies[2] = second;
return this;
}
/**
* Writes representation of a game board.
*
* @param boardSize size of the board
* @param board game board data
* @returns same instance
*/
withBoard(boardSize: number, board: Player[]): GameBoardBuilder {
this.boardSize = boardSize;
this.boardData = board;
return this;
}
/**
* Writes that an entity is playing.
*
* @param entity entity whiches is playing. If undefined: display loading message
* @returns same instance
*/
withEntityPlaying(entity?: Entity): GameBoardBuilder {
if (entity instanceof AI) {
this.state = localize.__('game.waiting-ai');
} else if (!entity) {
this.state = localize.__('game.load');
} else {
this.state = localize.__('game.action', { player: entity.toString() });
}
return this;
}
/**
* Writes ending state of a game.
*
* @param winner winning entity. If undefined: display tie message
* @returns same instance
*/
withEndingMessage(winner?: Entity): GameBoardBuilder {
if (winner) {
this.state = localize.__('game.win', { player: winner.toString() });
} else {
this.state = localize.__('game.end');
}
return this;
}
/**
* Constructs final representation of the game board.
*
* @returns message options of the gameboard
*/
toMessageOptions(): MessageOptions {
// Generate string representation of the board
let board = '';
for (let i = 0; i < this.boardSize * this.boardSize; i++) {
board += this.emojies[this.boardData[i]] + ' ';
if ((i + 1) % this.boardSize === 0) {
board += '\n';
}
}
// Generate final string
const state = this.state && board ? '\n' + this.state : this.state;
return {
allowedMentions: { parse: ['users'] },
content: this.title + board + state,
components: []
};
}
}