-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest_tictactoe.py
executable file
·110 lines (89 loc) · 3.51 KB
/
test_tictactoe.py
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
#!/usr/bin/env python3
import numpy as np
import copy
from tictactoe import TicTacToeBoard, eval_tictactoe, WIN_SCORE, play_game
from search import minmax
def test_display():
b = TicTacToeBoard()
b.board[0, 0] = "x"
b.board[0, 2] = "x"
b.board[1, 1] = "o"
b.board[2, 1] = "o"
print(b)
assert b.__str__() == "\x1b[4mx| |x\x1b[0m\n\x1b[4m |o| \x1b[0m\n |o| \n"
def test_moves():
b = TicTacToeBoard()
b.board[0, 0] = "x"
b.board[0, 2] = "x"
b.board[1, 1] = "o"
b.board[2, 1] = "o"
moves = b.moves()
print(moves)
expected = [(0, 1), (1, 0), (1, 2), (2, 0), (2, 2)]
assert set(moves) == set(expected)
def test_do_move():
b = TicTacToeBoard(turn="x")
b.board[0, 0] = "x"
b.board[0, 2] = "x"
b.board[1, 1] = "o"
b.board[2, 1] = "o"
b.do_move((2, 2))
assert b.board[2, 2] == "x"
assert b.turn == "o"
def test_eval_tictactoe():
b = TicTacToeBoard()
# [(score, done, board), ...]
tests = [
(0, False, np.array(((" ", " ", " "), (" ", " ", " "), (" ", " ", " ")))),
(WIN_SCORE, True, np.array((("x", "x", "x"), (" ", " ", " "), (" ", " ", " ")))),
(-WIN_SCORE, True, np.array(((" ", " ", " "), ("o", "o", "o"), (" ", " ", " ")))),
(WIN_SCORE, True, np.array((("o", "x", " "), (" ", "x", "o"), (" ", "x", "o")))),
(-WIN_SCORE, True, np.array((("o", " ", " "), (" ", "o", " "), (" ", " ", "o")))),
(-WIN_SCORE, True, np.array(((" ", " ", "o"), (" ", "o", "x"), ("o", " ", " ")))),
(0, True, np.array((("o", "x", "x"), ("x", "o", "o"), ("x", "o", "x")))),
]
for e_score, e_done, board in tests:
b.board = board
score, done = eval_tictactoe(b)
assert score == e_score, "board: \n{}".format(b)
assert done == e_done, "board: \n{}".format(b)
def test_minmax():
# depth = 0
b = TicTacToeBoard(turn="x")
b.board = np.array((("x", "x", "x"), (" ", " ", " "), (" ", " ", " ")))
score, _ = minmax(b, eval_tictactoe, 0)
assert score == WIN_SCORE
b = TicTacToeBoard(turn="o")
b.board = np.array((("o", " ", " "), (" ", "o", " "), (" ", " ", " ")))
score, move = minmax(b, eval_tictactoe, 1)
assert score <= .75 * -WIN_SCORE # some latitude for time discounting
assert move == (2,2)
# depth = 1, offense
b = TicTacToeBoard(turn="x")
b.board = np.array((("x", " ", " "), (" ", "x", " "), (" ", " ", " ")))
score, move = minmax(b, eval_tictactoe, 1)
assert move == (2, 2)
assert score >= .75 * WIN_SCORE
# depth = 2, defense
b = TicTacToeBoard(turn="x")
b.board = np.array((("o", " ", " "), (" ", "o", " "), (" ", " ", " ")))
score, move = minmax(b, eval_tictactoe, 2)
assert score == 0
assert move == (2, 2)
def test_minmax_deep():
b = TicTacToeBoard(turn="x")
# can stop a force win
b.board = np.array((("o", " ", " "), (" ", " ", " "), (" ", " ", " ")))
score, move = minmax(b, eval_tictactoe, 6)
assert score == 0
assert move == (1, 1)
# can do a force win
b = TicTacToeBoard(turn="o")
start = np.array((("o", " ", " "), ("x", " ", " "), (" ", " ", " ")))
b.board = copy.deepcopy(start)
score, move = minmax(b, eval_tictactoe, 6)
assert score <= .75 * -WIN_SCORE # some latitude for time discounting
assert move == (0, 2) or move == (0, 1) # there are many other force victories
# check board is unchanged after call to eval
assert np.all(b.board == start)
assert b.past_moves == []