-
Notifications
You must be signed in to change notification settings - Fork 0
/
naughts.py
133 lines (108 loc) · 3.65 KB
/
naughts.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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import signal
import sys
from bot import Bot
def coordinate_to_board_position(coordinate):
x_plane = {'A': 0, 'B': 1, 'C': 2}
y_plane = {'1': 0, '2': 1, '3': 2}
return [y_plane[coordinate[1]], x_plane[coordinate[0]]]
def game_over(moves):
if moves[0][0] != ' ' and moves[0][0] == moves[0][1] == moves[0][2]:
return moves[0][0]
if moves[0][0] != ' ' and moves[0][0] == moves[1][0] == moves[2][0]:
return moves[0][0]
if moves[0][0] != ' ' and moves[0][0] == moves[1][1] == moves[2][2]:
return moves[0][0]
if moves[0][2] != ' ' and moves[0][2] == moves[1][2] == moves[2][2]:
return moves[0][2]
if moves[0][2] != ' ' and moves[0][2] == moves[1][1] == moves[2][0]:
return moves[0][2]
if moves[2][0] != ' ' and moves[2][0] == moves[2][1] == moves[2][2]:
return moves[2][0]
if moves[1][0] != ' ' and moves[1][0] == moves[1][1] == moves[1][2]:
return moves[1][0]
def print_board(moves):
y_coords_to_line = {1: 0, 4: 1, 7: 2}
line_to_x_coords = {0: 3, 1: 8, 2: 13}
board = [
' | | ',
'1 | | ',
' _____|___|_____',
' | | ',
'2 | | ',
' _____|___|_____',
' | | ',
'3 | | ',
' | | ',
' A B C ',
]
for idx, line in enumerate(board):
line_as_list = list(line)
if idx in [1, 4, 7]:
for idx_moves, move in enumerate(moves[y_coords_to_line[idx]]):
line_as_list[line_to_x_coords[idx_moves]] = move
print(''.join(line_as_list))
def get_valid_move(player, moves):
while True:
try:
response = input('Player {0}\'s turn: '.format(player)).upper()
if response == 'Q':
sys.exit(0)
print(response)
if len(response) == 2 and 'A' <= response[0] <= 'C' and 0 < int(response[1]) < 4:
move = coordinate_to_board_position(response)
if moves[move[0]][move[1]] != ' ':
raise ValueError('That move is already taken!')
else:
return move
raise ValueError('Please enter a valid move, i.e., "A1"\n')
except ValueError as error:
print(error)
continue
def get_input(message, options=['y', 'n']):
while True:
response = input(message).lower()
if len(options) > 0:
if response in options:
return response
else:
return response
def play_game(players, starting):
moves_taken = 0
moves = [
[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' '],
]
b = Bot('X')
winner = None
player = starting and 'O' or 'X'
while moves_taken < 9:
player = players[moves_taken % 2]
print_board(moves)
print('Moves:', moves_taken)
if player == 'X':
move = b.move(moves)
else:
move = get_valid_move(player, moves)
moves[int(move[0])][int(move[1])] = player
moves_taken += 1
winner = game_over(moves)
if winner:
break
print_board(moves)
if winner:
print('\n{0} wins the game!\n'.format(player))
else:
print('\nDraw!\n')
def signal_handler(signal, frame):
print('\n')
sys.exit(0)
def main():
starting = get_input('Do you want to start? (y/n) ') == 'y'
players = starting and ['O', 'X'] or ['X', 'O']
while True:
play_game(players, starting)
if get_input('Play again? (y/n) ') == 'n':
break
signal.signal(signal.SIGINT, signal_handler)
main()