-
Notifications
You must be signed in to change notification settings - Fork 39
/
Copy pathkata.ts
115 lines (92 loc) · 2.92 KB
/
kata.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
/* eslint-disable */
export class Game {
private _lastSymbol = ' ';
private _board: Board = new Board();
private readonly emptyPlay = ' ';
private readonly firstRow = 0;
private readonly secondRow = 1;
private readonly thirdRow = 2;
private readonly firstColumn = 0;
private readonly secondColumn = 1;
private readonly thirdColumn = 2;
public Play(symbol: string, x: number, y: number): void {
this.validateFirstMove(symbol);
this.validatePlayer(symbol);
this.validatePositionIsEmpty(x, y);
this.updateLastPlayer(symbol);
this.updateBoard(symbol, x, y);
}
private validateFirstMove(player: string) {
const playerO = 'O';
if (this._lastSymbol == this.emptyPlay) {
if (player == playerO) {
throw new Error('Invalid first player');
}
}
}
private validatePlayer(player: string) {
if (player == this._lastSymbol) {
throw new Error('Invalid next player');
}
}
private validatePositionIsEmpty(x: number, y: number) {
if (this._board.TileAt(x, y).Symbol != this.emptyPlay) {
throw new Error('Invalid position');
}
}
private updateLastPlayer(player: string) {
this._lastSymbol = player;
}
private updateBoard(player: string, x: number, y: number) {
this._board.AddTileAt(player, x, y);
}
public Winner(): string {
if (this.isRowFull(0) && this.isRowFullWithSameSymbol(0)) {
return this._board.TileAt(this.firstRow, this.firstColumn)!.Symbol;
}
if (this.isRowFull(1) && this.isRowFullWithSameSymbol(1)) {
return this._board.TileAt(this.secondRow, this.firstColumn)!.Symbol;
}
if (this.isRowFull(2) && this.isRowFullWithSameSymbol(2)) {
return this._board.TileAt(this.thirdRow, this.firstColumn)!.Symbol;
}
return this.emptyPlay;
}
private isRowFull(row: number) {
return (
this._board.TileAt(row, this.firstColumn)!.Symbol != this.emptyPlay &&
this._board.TileAt(row, this.secondColumn)!.Symbol != this.emptyPlay &&
this._board.TileAt(row, this.thirdColumn)!.Symbol != this.emptyPlay
);
}
private isRowFullWithSameSymbol(row: number) {
return (
this._board.TileAt(row, this.firstColumn)!.Symbol ==
this._board.TileAt(row, this.secondColumn)!.Symbol &&
this._board.TileAt(row, this.thirdColumn)!.Symbol ==
this._board.TileAt(row, this.secondColumn)!.Symbol
);
}
}
interface Tile {
X: number;
Y: number;
Symbol: string;
}
class Board {
private _plays: Tile[] = [];
constructor() {
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
const tile: Tile = { X: i, Y: j, Symbol: ' ' };
this._plays.push(tile);
}
}
}
public TileAt(x: number, y: number): Tile {
return this._plays.find((t: Tile) => t.X == x && t.Y == y)!;
}
public AddTileAt(symbol: string, x: number, y: number): void {
this._plays.find((t: Tile) => t.X == x && t.Y == y)!.Symbol = symbol;
}
}