-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtictactoe.py
131 lines (112 loc) · 3.61 KB
/
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#!/usr/bin/env python3
"""
Basic functions in order to start a game of tic tac toe
"""
from random import choice
ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
SIZE = 3 #Will determine the size of the grid. Normally, you play on a 3x3 grid.
PLAYER = {True: 'O', False: 'X', None: ' '}
def empty():
"""
Creates an empty grid
"""
return [[None for j in range(SIZE)] for i in range(SIZE)]
def is_playable(grid):
"""
Tells if it is possible to continue playing on <grid>
ie: is there an empty case in <grid>?
"""
return any(None in row for row in grid)
def is_won(grid):
"""
Tells if the player who just finished is turn won the game
"""
for row in grid: #First, we check if one of the rows is full of the same symbol
if all_same(row):
return True
for column in columns(grid): #Then, we work on the columns
if all_same(column):
return True
for diag in diagonals(grid): #Finally, we do the same thing on diagonals
if all_same(diag):
return True
return False #If nothing worked before, then it means it's not won
def columns(grid):
"""
Returns all the columns of the grid (basically the transpose)
"""
return zip(*grid)
def diagonals(grid):
"""
Returns both diagonals of the grid
"""
return [(grid[i][i] for i in range(SIZE)), (grid[i][SIZE - 1 - i] for i in range(SIZE))]
def all_same(iterable):
"""
Tells if all the elements in an iterable are the same
"""
shrink = set(iterable)
return len(shrink) == 1 and not None in shrink
def separation():
"""
Visual separation between two lines
"""
print("\n +" + (4 * SIZE - 1) * "-" + "+")
def show(grid):
"""
Visual function in order to make the game look nicer
"""
print(" ", end="")
for number in range(SIZE):
print(number, end=" ")
separation()
for i, row in enumerate(grid):
print('{} |'.format(ALPHABET[i]), end='')
for elt in row:
print(' {} '.format(PLAYER[elt]), end='|')
separation()
def game(first_player):
"""
A game of tic tac toe
"""
grid = empty()
player = first_player
list_turns_played = {lettre:[range(SIZE, 27)] for lettre in ALPHABET if ALPHABET.index(lettre) < SIZE}
win = False
while is_playable(grid):
show(grid)
current_turn = ""
while len(current_turn) != 2 or current_turn[0] not in list_turns_played \
or int(current_turn[1]) in list_turns_played[current_turn[0]]:
current_turn = input("It's {} turn. Please enter a valid combination to play.\n"
.format(PLAYER[player])).upper()
list_turns_played[current_turn[0]].append(int(current_turn[1]))
grid[ALPHABET.index(current_turn[0])][int(current_turn[1])] = player
if is_won(grid):
print("Well played ! {} wins ;-)".format(PLAYER[player]))
win = True
break
player = not player
if not win:
print("Oh... That's a draw!")
show(grid)
def tictactoe():
"""
Play several games
"""
wants_to_play = True
random_player = True
first_game = True
player = True
while wants_to_play:
print("Time to play!")
if not first_game:
random_player = "y" == input("Do you want a random player to start ? Y/N\n").lower()
if random_player:
player = choice((True, False))
game(player)
player = not player
wants_to_play = "y" == input("Play again? Y/N\n").lower()
print("Bye!")
if __name__ == "__main__":
tictactoe()