15 def valid_board(board
):
16 xs
, os
= xo_count(board
)
17 return (xs
- os
) == 0 or (xs
- os
) == 1
25 return [b
for b
in itertools
.product('.xo', repeat
=9)
31 if board
[0] == board
[1] == board
[2] and board
[0] != '.':
32 winning_player
= board
[0]
33 if board
[3] == board
[4] == board
[5] and board
[3] != '.':
34 winning_player
= board
[3]
35 if board
[6] == board
[7] == board
[8] and board
[6] != '.':
36 winning_player
= board
[6]
37 if board
[0] == board
[3] == board
[6] and board
[0] != '.':
38 winning_player
= board
[0]
39 if board
[1] == board
[4] == board
[7] and board
[1] != '.':
40 winning_player
= board
[1]
41 if board
[2] == board
[5] == board
[8] and board
[2] != '.':
42 winning_player
= board
[2]
43 if board
[0] == board
[4] == board
[8] and board
[0] != '.':
44 winning_player
= board
[0]
45 if board
[2] == board
[4] == board
[6] and board
[2] != '.':
46 winning_player
= board
[2]
52 return s
[0:3] + '\n' + s
[3:6] + '\n' + s
[6:9]
60 rows
[i
] += [s
[i
*3:i
*3+3]]
61 return '\n'.join(' '.join(r
) for r
in rows
)
67 rotation
= {0: 6, 1: 3, 2: 0, 3: 7, 4: 4, 5: 1, 6: 8, 7: 5, 8: 2}
68 inverse_rotation
= {t
: f
for f
, t
in rotation
.items()}
73 reflection
= {0: 2, 1: 1, 2: 0, 3: 5, 4: 4, 5: 3, 6: 8, 7: 7, 8: 6}
76 def rotate(board
, n
=1):
79 b
= tuple(b
[rotation
[i
]] for i
in range(len(board
)))
83 def reflect(board
, r
=True):
85 return tuple(board
[reflection
[i
]] for i
in range(len(board
)))
90 def transform(board
, n
, r
):
95 def untransform(board
, n
, r
):
97 return rotate(b
, abs(4-n
))
100 def all_transforms(board
):
101 return [(transform(board
, rot
, ref
), rot
, ref
)
103 for ref
in [False, True]]
107 return ''.join(board
)
110 def canonical(board
):
111 return max(all_transforms(board
), key
=lambda brf
: score(brf
[0]))
114 def non_winning_boards():
115 return set([canonical(b
)[0] for b
in all_boards()
119 def successors(board
):
120 xs
, os
= xo_count(board
)
124 for i
in range(len(board
)):
126 succs
+= [tuple(board
[:i
] + ('x',) + board
[i
+1:])]
130 for i
in range(len(board
)):
132 succs
+= [tuple(board
[:i
] + ('o',) + board
[i
+1:])]
137 return [i
for i
, c
in enumerate(board
) if c
== '.']
140 def apply_move(board
, position
, piece
):
141 return tuple(board
[:position
] + (piece
,) + board
[position
+1:])
144 def token_for_player(is_player_1
):