-
Notifications
You must be signed in to change notification settings - Fork 2
/
board.go
143 lines (128 loc) · 2.31 KB
/
board.go
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
package main
import "fmt"
// ---
// BOARDCASE DEFINITION
// ---
type boardCase int
const (
e boardCase = iota
x
o
)
func (c boardCase) String() string {
switch c {
case e:
return "_"
case x:
return "x"
case o:
return "o"
}
return ""
}
// ---
// BOARDLINE DEFINITION
// ---
type boardLine []boardCase
// ---
// BOARD DEFINITION
// ---
type board []boardLine
// Create a new empty board
func newBoard() board {
return board{
boardLine{e, e, e},
boardLine{e, e, e},
boardLine{e, e, e},
}
}
// Count the number of diff between two boards
func (b board) diff(b2 board) int {
diff := 0
for i, l := range b {
for j := range l {
if b[i][j] != b2[i][j] {
diff++
}
}
}
return diff
}
// Return a copy of the board rotated by 90°
func (b board) rotate() board {
bRot := newBoard()
// Transpose the board
for i, row := range b {
for j := range row {
bRot[i][j] = b[j][i]
}
}
// Reverse each rows
for _, row := range bRot {
tmp := row[0]
row[0] = row[2]
row[2] = tmp
}
return bRot
}
// Return the number of occurence a sign in the board
func (b board) countSign(s boardCase) int {
count := 0
for _, l := range b {
for _, c := range l {
if c == s {
count++
}
}
}
return count
}
// Return true if the board is full
func (b board) isFull() bool {
return b.countSign(e) == 0
}
// Return the winner
// Need three signs aligned
// If no winner, return e
func (b board) getWinnerSign() boardCase {
// Check all lines and columns
for i, l := range b {
// Lines
if l[0] == l[1] && l[1] == l[2] {
return l[0]
}
// Columns
if b[0][i] == b[1][i] && b[1][i] == b[2][i] {
return b[0][i]
}
}
// Check diagonals
if b[0][0] == b[1][1] && b[1][1] == b[2][2] {
return b[0][0]
}
if b[2][0] == b[1][1] && b[1][1] == b[0][2] {
return b[2][0]
}
return e
}
// Copy a board to a new board
func (b board) copy() board {
newB := newBoard()
copy(newB[0], b[0])
copy(newB[1], b[1])
copy(newB[2], b[2])
return newB
}
// Overide default String method
func (b board) String() string {
return fmt.Sprintf("%v\n%v\n%v", b[0], b[1], b[2])
}
// Stringify a board
// Example:
// X - X
// - O -
// - - -
// ==> "X-X--O---"
func (b board) serialize() string {
return fmt.Sprintf("%v%v%v%v%v%v%v%v%v", b[0][0], b[0][1], b[0][2], b[1][0], b[1][1], b[1][2], b[2][0], b[2][1], b[2][2])
}