This repository has been archived by the owner on Nov 9, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
ia_test.go
106 lines (82 loc) · 1.93 KB
/
ia_test.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
package TicTacToe
import (
"testing"
"fmt"
"github.com/stretchr/testify/assert"
)
// TestPlay_NeverLose checks that the "IA" never loses
func TestPlay_NeverLose(t *testing.T) {
// Opponent first
grid := NewGrid()
playAllPossibilitiesForTest(t, grid)
// IA first
grid = NewGrid()
playIA(t, grid)
playAllPossibilitiesForTest(t, grid)
}
func playAllPossibilitiesForTest(t *testing.T, originalGrid Grid) {
for _, coordinates := range NewAllCellsIterator() {
if originalGrid.OccupiedBy(coordinates).Valid {
continue
}
grid := originalGrid.Copy()
if playOpponent(t, grid, coordinates) {
continue
}
if playIA(t, grid) {
continue
}
// Next turn
playAllPossibilitiesForTest(t, grid)
}
}
func BenchmarkPlayAllPossibilities(b *testing.B) {
for i := 0; i < b.N; i++ {
grid := NewGrid()
playAllPossibilities(grid)
}
}
func playOpponent(t *testing.T, grid Grid, coordinates Coordinates) bool {
isOver, _ := grid.IsGameOver()
if isOver {
panic("Game already over")
}
grid.Play(coordinates)
isOver, winner := grid.IsGameOver()
if isOver {
// Must be a draw
assert.False(t, winner.Valid, "IA lost")
}
return isOver
}
func playIA(t *testing.T, grid Grid) bool {
grid.Play(BestNextMove(grid))
isOver, _ := grid.IsGameOver()
return isOver
}
func TestIA_TakeTheWin(t *testing.T) {
// Regression test for a situation where the IA can win immediately but doesn't
g := GridFromID(393466) // 0b1100000000011111010
result := BestNextMove(g)
assert.Equal(t, Coordinates{2, 0}, result)
}
func ExampleBestNextMove() {
grid := NewGrid()
// Let's have a game just between IA
var (
isOver bool
winner NullPlayer
)
for !isOver {
coordinatesToPlay := BestNextMove(grid)
grid.Play(coordinatesToPlay)
isOver, winner = grid.IsGameOver()
}
if !winner.Valid {
// Spoilers: it's always a draw game
fmt.Println("Draw game!")
} else {
fmt.Println(winner.String() + " wins!")
}
// Output: Draw game!
}