Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MR414N-ID
GitHub Repository: MR414N-ID/botku2
Path: blob/master/lib/tictactoe.js
1126 views
1
class TicTacToe {
2
constructor(playerX = 'x', playerO = 'o') {
3
this.playerX = playerX
4
this.playerO = playerO
5
this._currentTurn = false
6
this._x = 0
7
this._o = 0
8
this.turns = 0
9
}
10
11
get board() {
12
return this._x | this._o
13
}
14
15
get currentTurn() {
16
return this._currentTurn ? this.playerO : this.playerX
17
}
18
19
get enemyTurn() {
20
return this._currentTurn ? this.playerX : this.playerO
21
}
22
23
static check(state) {
24
for (let combo of [7, 56, 73, 84, 146, 273, 292, 448])
25
if ((state & combo) === combo)
26
return !0
27
return !1
28
}
29
30
/**
31
* ```js
32
* TicTacToe.toBinary(1, 2) // 0b010000000
33
* ```
34
*/
35
static toBinary(x = 0, y = 0) {
36
if (x < 0 || x > 2 || y < 0 || y > 2) throw new Error('invalid position')
37
return 1 << x + (3 * y)
38
}
39
40
/**
41
* @param player `0` is `X`, `1` is `O`
42
*
43
* - `-3` `Game Ended`
44
* - `-2` `Invalid`
45
* - `-1` `Invalid Position`
46
* - ` 0` `Position Occupied`
47
* - ` 1` `Sucess`
48
* @returns {-3|-2|-1|0|1}
49
*/
50
turn(player = 0, x = 0, y) {
51
if (this.board === 511) return -3
52
let pos = 0
53
if (y == null) {
54
if (x < 0 || x > 8) return -1
55
pos = 1 << x
56
} else {
57
if (x < 0 || x > 2 || y < 0 || y > 2) return -1
58
pos = TicTacToe.toBinary(x, y)
59
}
60
if (this._currentTurn ^ player) return -2
61
if (this.board & pos) return 0
62
this[this._currentTurn ? '_o' : '_x'] |= pos
63
this._currentTurn = !this._currentTurn
64
this.turns++
65
return 1
66
}
67
68
/**
69
* @returns {('X'|'O'|1|2|3|4|5|6|7|8|9)[]}
70
*/
71
static render(boardX = 0, boardO = 0) {
72
let x = parseInt(boardX.toString(2), 4)
73
let y = parseInt(boardO.toString(2), 4) * 2
74
return [...(x + y).toString(4).padStart(9, '0')].reverse().map((value, index) => value == 1 ? 'X' : value == 2 ? 'O' : ++index)
75
}
76
77
/**
78
* @returns {('X'|'O'|1|2|3|4|5|6|7|8|9)[]}
79
*/
80
render() {
81
return TicTacToe.render(this._x, this._o)
82
}
83
84
get winner() {
85
let x = TicTacToe.check(this._x)
86
let o = TicTacToe.check(this._o)
87
return x ? this.playerX : o ? this.playerO : false
88
}
89
}
90
91
new TicTacToe().turn
92
93
module.exports = TicTacToe
94