forked from PatrickJS/angular-webpack-starter
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGameService.ts
More file actions
85 lines (67 loc) · 1.83 KB
/
GameService.ts
File metadata and controls
85 lines (67 loc) · 1.83 KB
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
/// <reference path="../../typings/_custom.d.ts" />
import {provide, Injectable} from 'angular2/angular2';
type Triple = [ string, string, string ]; // tuple type
type Rows = [ Triple, Triple, Triple ];
type Point = { x: number; y: number };
@Injectable()
export class GameService {
board: Rows = [
['', '', ''],
['', '', ''],
['', '', '']
];
plays: Point[] = [];
static create() {
return new GameService();
}
dispose() {
this.board = null
this.plays = null;
}
play(coord: Point) {
const { x, y } = coord;
if (!this.gameover && this.board[x][y] === '') {
this.board[x][y] = this.player;
}
this.plays.push(coord); //TODO: create Rx Observable
}
get player() {
return ['x', 'o'][this.plays.length % 2];
}
get gameover() {
return this.draw || this.winner !== '';
}
get winner(): string {
return getWinnerFromBoard(this.board);
}
get draw() {
return this.plays.length === 9;
}
}
export var GAMESERVICE_BINDINGS = [
provide(GameService, {useClass: GameService})
];
// Pure functions
export function getWinnerFromBoard(board: Rows): string {
const allWinningLists = [].concat(
board, // rows
zip(board), // columns
diagonals(board) // diagonals
);
return allWinningLists.reduce(getWinnerFromList, '');
}
export function getWinnerFromList(winner: string, list: Triple) {
if (winner) return winner;
if (list.every(s => s == 'o')) return 'o';
if (list.every(s => s == 'x')) return 'x';
return '';
}
export function zip(arrays: Rows) {
return arrays[0].map((_, i) => arrays.map(array => array[i]));
}
export function diagonals(rows: Rows) {
return [
rows.map((row, index) => row[index]), // left to right diagonal
rows.map((row, index) => row[row.length - 1 - index]) // right to left diagonal
];
}