-
Notifications
You must be signed in to change notification settings - Fork 0
/
23.ts
130 lines (112 loc) Β· 4.51 KB
/
23.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
type Connect4Chips = 'π΄' | 'π‘';
type Connect4Cell = Connect4Chips | ' ';
type Connect4CellEmpty = ' ';
type Connect4State = 'π΄' | 'π‘' | 'π΄ Won' | 'π‘ Won' | 'Draw';
type EmptyBoard = [
[" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "],
[" ", " ", " ", " ", " ", " ", " "],
];
type NewGame = {
board: EmptyBoard;
state: "π‘";
};
type Board = Connect4Cell[][];
type GameState = {
board: Board;
state: Connect4State;
};
type Columns = 0 | 1 | 2 | 3 | 4 | 5 | 6;
type ColumnsTuple = [0, 1, 2, 3, 4, 5, 6];
type Rows = 0 | 1 | 2 | 3 | 4 | 5;
type RowsTuple = [0, 1, 2, 3, 4, 5];
type RowsP1Tuple = [1, 2, 3, 4, 5];
type NextBoard<B extends GameState, N extends Columns> =
[
[NSC<B, N, 0, 0>, NSC<B, N, 0, 1>, NSC<B, N, 0, 2>, NSC<B, N, 0, 3>, NSC<B, N, 0, 4>, NSC<B, N, 0, 5>, NSC<B, N, 0, 6>],
[NSC<B, N, 1, 0>, NSC<B, N, 1, 1>, NSC<B, N, 1, 2>, NSC<B, N, 1, 3>, NSC<B, N, 1, 4>, NSC<B, N, 1, 5>, NSC<B, N, 1, 6>],
[NSC<B, N, 2, 0>, NSC<B, N, 2, 1>, NSC<B, N, 2, 2>, NSC<B, N, 2, 3>, NSC<B, N, 2, 4>, NSC<B, N, 2, 5>, NSC<B, N, 2, 6>],
[NSC<B, N, 3, 0>, NSC<B, N, 3, 1>, NSC<B, N, 3, 2>, NSC<B, N, 3, 3>, NSC<B, N, 3, 4>, NSC<B, N, 3, 5>, NSC<B, N, 3, 6>],
[NSC<B, N, 4, 0>, NSC<B, N, 4, 1>, NSC<B, N, 4, 2>, NSC<B, N, 4, 3>, NSC<B, N, 4, 4>, NSC<B, N, 4, 5>, NSC<B, N, 4, 6>],
[NSC<B, N, 5, 0>, NSC<B, N, 5, 1>, NSC<B, N, 5, 2>, NSC<B, N, 5, 3>, NSC<B, N, 5, 4>, NSC<B, N, 5, 5>, NSC<B, N, 5, 6>]
];
// NextStateCell
type NSC<B extends GameState, N extends Columns, R extends Rows, C extends Columns> =
N extends C
? B['state'] extends Connect4Chips
? B['board'][R][C] extends Connect4CellEmpty
? RowsP1Tuple[R] extends Rows
? B['board'][RowsP1Tuple[R]][C] extends Connect4Chips
? B['state']
: B['board'][RowsP1Tuple[R]][C]
: B['state']
: B['board'][R][C]
: B['board'][R][C]
: B['board'][R][C];
type NextStateN<NB extends Board, C extends Connect4Chips> =
HasWon<NB, C> extends false
? NB[number][number] extends Connect4Chips
? 'Draw'
: C extends 'π΄'
? 'π‘'
: 'π΄'
: `${C} Won`
type Connect4<B extends GameState, N extends Columns> =
NextBoard<B, N> extends infer NB extends Board
? B['state'] extends Connect4Chips
? {
board: NB,
state: NextStateN<NB, B['state']>,
}
: never
: never;
// Longest line including diagonals is 7.
type Connected4Sets<T extends Connect4Chips> =
| [T, T, T, T]
| [T, T, T, T, any]
| [T, T, T, T, any, any]
| [T, T, T, T, any, any, any]
| [T, T, T, T, any, any, any, any]
| [any, T, T, T, T]
| [any, T, T, T, T, any]
| [any, T, T, T, T, any, any]
| [any, T, T, T, T, any, any, any]
| [any, any, T, T, T, T]
| [any, any, T, T, T, T, any]
| [any, any, T, T, T, T, any, any]
| [any, any, any, T, T, T, T]
| [any, any, any, T, T, T, T, any]
| [any, any, any, any, T, T, T, T]
// From type-testing
type IsNever<T> = [T] extends [never] ? true : false;
type IsTuple<T> = IsNever<T> extends true ? false : T extends readonly unknown[] ? number extends T["length"] ? false : true : false;
type HasWon<B extends Board, C extends Connect4Chips> = IsTuple<(
(
// Rows
| B[number]
// Columns
| [B[0][0], B[1][0], B[2][0], B[3][0], B[4][0], B[5][0]]
| [B[0][1], B[1][1], B[2][1], B[3][1], B[4][1], B[5][1]]
| [B[0][2], B[1][2], B[2][2], B[3][2], B[4][2], B[5][2]]
| [B[0][3], B[1][3], B[2][3], B[3][3], B[4][3], B[5][3]]
| [B[0][4], B[1][4], B[2][4], B[3][4], B[4][4], B[5][4]]
| [B[0][5], B[1][5], B[2][5], B[3][5], B[4][5], B[5][5]]
| [B[0][6], B[1][6], B[2][6], B[3][6], B[4][6], B[5][6]]
// Diagonals
| [B[0][0], B[1][1], B[2][2], B[3][3], B[4][4], B[5][5]]
| [B[1][0], B[2][1], B[3][2], B[4][3], B[5][4]]
| [B[2][0], B[3][1], B[4][2], B[5][3]]
| [B[3][0], B[4][1], B[5][2], B[6][3]]
| [B[0][1], B[1][2], B[2][3], B[3][4], B[4][5], B[5][6]]
| [B[0][2], B[1][3], B[2][4], B[3][5], B[4][6]]
| [B[0][3], B[1][4], B[2][5], B[3][6]]
| [B[0][6], B[1][5], B[2][4], B[3][3], B[4][2], B[5][1]]
| [B[1][6], B[2][5], B[3][4], B[4][3], B[5][2]]
| [B[2][6], B[3][5], B[4][4], B[5][3]]
| [B[0][5], B[1][4], B[2][3], B[3][2], B[4][1], B[5][0]]
| [B[0][4], B[1][3], B[2][2], B[3][1], B[4][0]]
| [B[0][3], B[1][2], B[2][1], B[3][0]]
) & Connected4Sets<C>)>;