Skip to content

Commit 1c5be29

Browse files
authored
Create Exercise-29-Tic-Tac-Toe-Game.py
1 parent e36fe04 commit 1c5be29

File tree

1 file changed

+339
-0
lines changed

1 file changed

+339
-0
lines changed

Exercise-29-Tic-Tac-Toe-Game.py

Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
'''
2+
Exercise 29: Tic Tac Toe Game
3+
4+
This exercise is Part 4 of 4 of the Tic Tac Toe exercise series.
5+
The other exercises are: Part 1, Part 2, and Part 3.
6+
7+
In 3 previous exercises, we built up a few components needed to
8+
build a Tic Tac Toe game in Python:
9+
10+
Draw the Tic Tac Toe game board
11+
Checking whether a game board has a winner
12+
Handle a player move from user input
13+
The next step is to put all these three components together to
14+
make a two-player Tic Tac Toe game! Your challenge in this
15+
exercise is to use the functions from those previous exercises
16+
all together in the same program to make a two-player game that
17+
you can play with a friend. There are a lot of choices you will
18+
have to make when completing this exercise, so you can go as
19+
far or as little as you want with it.
20+
21+
Here are a few things to keep in mind:
22+
23+
You should keep track of who won - if there is a winner, show a
24+
congratulatory message on the screen.
25+
If there are no more moves left, don’t ask for the next player’s
26+
move!
27+
As a bonus, you can ask the players if they want to play again
28+
and keep a running tally of who won more - Player 1 or Player 2.
29+
30+
'''
31+
32+
# Solution
33+
def check_winner(input_list, size):
34+
"""
35+
Check the winner number in row, column, or diagonal direction.
36+
37+
Arguments:
38+
input_list -- a two dimensional list for checking.
39+
size -- the length for winning.
40+
41+
Returns:
42+
winner -- the winner player number, if no winner return None.
43+
44+
"""
45+
# Check row
46+
winner = check_row_winner(input_list, size)
47+
if winner == None:
48+
# Transpose matrix
49+
input_list = transpose(input_list)
50+
# Check column
51+
winner = check_row_winner(input_list, size)
52+
if winner == None:
53+
# Check diagnal
54+
winner = check_diagonal_winner(input_list, size)
55+
if winner == None:
56+
winner = check_diagonal_winner(list(zip(*reversed(input_list))), size)
57+
return winner
58+
59+
def transpose(input_list):
60+
"""
61+
Transpose a two dimensinal list.
62+
63+
Arguments:
64+
input_list -- a two dimensional list for transposing.
65+
66+
Returns:
67+
result -- transposed two dimensinal list.
68+
69+
"""
70+
result = []
71+
for i in range(len(input_list[0])):
72+
new_line = [new_list[i] for new_list in input_list]
73+
result.append(new_line)
74+
return result
75+
76+
def check_row_winner(input_list, size):
77+
"""
78+
Check the winner number in row direction.
79+
80+
Arguments:
81+
input_list -- a two dimensional list for checking.
82+
size -- the length for winning.
83+
84+
Returns:
85+
winner -- the winner player number, if no winner return None.
86+
87+
"""
88+
for line in input_list:
89+
count = 1
90+
for idx, value in enumerate(line):
91+
if line[idx] == line[idx+1]:
92+
count += 1
93+
else:
94+
count = 1
95+
if count == size and value != ' ':
96+
return value
97+
if idx == len(line)-size+1:
98+
break
99+
100+
def check_diagonal_winner(input_list, size):
101+
"""
102+
Check the winner number in diagonal direction.
103+
104+
Arguments:
105+
input_list -- a two dimensional list for checking.
106+
size -- the length for winning.
107+
108+
Returns:
109+
winner -- the winner player number, if no winner return None.
110+
111+
"""
112+
for row_idx, line in enumerate(input_list):
113+
winner = ' '
114+
try:
115+
list_for_check = []
116+
for i in range(size):
117+
list_for_check.append(input_list[row_idx+i][i])
118+
if list_for_check.count(list_for_check[0]) == size:
119+
if list_for_check[0] != ' ':
120+
return list_for_check[0]
121+
except IndexError:
122+
winner = ' '
123+
124+
def draw_board_v2(input_list):
125+
"""
126+
Draw game boards.
127+
128+
Arguments:
129+
input_list -- a two dimensional list for game board.
130+
131+
"""
132+
h_element = ' ---'
133+
for v_element in input_list:
134+
print(h_element * len(input_list))
135+
row = [('| ' + j + ' ') for j in v_element]
136+
row = ''.join(map(str,row))
137+
print(row + '|')
138+
print(h_element * len(input_list))
139+
140+
def draw_turn(row, column, input_list, user):
141+
"""
142+
Draw the game board after user typing a choice.
143+
144+
Arguments:
145+
row -- the row index.
146+
column -- the column index.
147+
input_list -- a two dimensional list for game board.
148+
user -- the user who type the choice
149+
150+
Returns:
151+
input_list -- a two dimensional list for game board after changed. If the position has been change perviously, return False.
152+
153+
"""
154+
mark_dict = {'player1':'X', 'player2':'O'}
155+
if input_list[row-1][column-1] == ' ':
156+
input_list[row-1][column-1] = mark_dict[user]
157+
else:
158+
print('That position has been taken, please input a new place:')
159+
return input_list
160+
return input_list
161+
162+
def require_input(user, input_list, info_dict):
163+
"""
164+
Get the user's input position.
165+
166+
Arguments:
167+
input_list -- a two dimensional list for game board.
168+
user -- the user who type the choice
169+
info_dict -- the information database.
170+
171+
Returns:
172+
input_list -- a two dimensional list for game board after changed.
173+
174+
"""
175+
import copy
176+
input_list_before = copy.deepcopy(input_list)
177+
while True:
178+
row, column = input("Round {}, {}'s turn:".format(info_dict['round'], user)).split()
179+
input_list = draw_turn(int(row), int(column), input_list, info_dict[user])
180+
if input_list != input_list_before:
181+
break
182+
draw_board_v2(input_list)
183+
return input_list
184+
185+
def initiation():
186+
'''
187+
Ask user how large the game board you want
188+
'''
189+
pass
190+
191+
def to_the_end():
192+
'''
193+
Check is there position available.
194+
'''
195+
pass
196+
197+
def main():
198+
print('Welcome to the game!')
199+
user1 = input("Player 1's name:")
200+
user2 = input("Player 2's name:")
201+
info_dict = {user1:'player1', user2:'player2', 'round':1}
202+
input_list = [[' ',' ',' ',' ',' ',' '],
203+
[' ',' ',' ',' ',' ',' '],
204+
[' ',' ',' ',' ',' ',' '],
205+
[' ',' ',' ',' ',' ',' '],
206+
[' ',' ',' ',' ',' ',' '],
207+
[' ',' ',' ',' ',' ',' ']]
208+
draw_board_v2(input_list)
209+
while True:
210+
# The code is redundant, improvement needed.
211+
input_list = require_input(user1, input_list, info_dict)
212+
if check_winner(input_list, 4) not in [None, ' ']:
213+
print('{} win!'.format(winner))
214+
break
215+
input_list = require_input(user2, input_list, info_dict)
216+
if check_winner(input_list, 4) not in [None, ' ']:
217+
print('{} win!'.format(winner))
218+
break
219+
info_dict['round'] += 1
220+
221+
if __name__ == "__main__":
222+
main()
223+
224+
# >>> %Run test.py
225+
# Welcome to the game!
226+
# Player 1's name:Soi
227+
# Player 2's name:Peruru
228+
# --- --- --- --- --- ---
229+
# | | | | | | |
230+
# --- --- --- --- --- ---
231+
# | | | | | | |
232+
# --- --- --- --- --- ---
233+
# | | | | | | |
234+
# --- --- --- --- --- ---
235+
# | | | | | | |
236+
# --- --- --- --- --- ---
237+
# | | | | | | |
238+
# --- --- --- --- --- ---
239+
# | | | | | | |
240+
# --- --- --- --- --- ---
241+
# Round 1, Soi's turn:2 2
242+
# --- --- --- --- --- ---
243+
# | | | | | | |
244+
# --- --- --- --- --- ---
245+
# | | X | | | | |
246+
# --- --- --- --- --- ---
247+
# | | | | | | |
248+
# --- --- --- --- --- ---
249+
# | | | | | | |
250+
# --- --- --- --- --- ---
251+
# | | | | | | |
252+
# --- --- --- --- --- ---
253+
# | | | | | | |
254+
# --- --- --- --- --- ---
255+
# Round 1, Peruru's turn:3 3
256+
# --- --- --- --- --- ---
257+
# | | | | | | |
258+
# --- --- --- --- --- ---
259+
# | | X | | | | |
260+
# --- --- --- --- --- ---
261+
# | | | O | | | |
262+
# --- --- --- --- --- ---
263+
# | | | | | | |
264+
# --- --- --- --- --- ---
265+
# | | | | | | |
266+
# --- --- --- --- --- ---
267+
# | | | | | | |
268+
# --- --- --- --- --- ---
269+
# Round 2, Soi's turn:3 2
270+
# --- --- --- --- --- ---
271+
# | | | | | | |
272+
# --- --- --- --- --- ---
273+
# | | X | | | | |
274+
# --- --- --- --- --- ---
275+
# | | X | O | | | |
276+
# --- --- --- --- --- ---
277+
# | | | | | | |
278+
# --- --- --- --- --- ---
279+
# | | | | | | |
280+
# --- --- --- --- --- ---
281+
# | | | | | | |
282+
# --- --- --- --- --- ---
283+
# Round 2, Peruru's turn:3 4
284+
# --- --- --- --- --- ---
285+
# | | | | | | |
286+
# --- --- --- --- --- ---
287+
# | | X | | | | |
288+
# --- --- --- --- --- ---
289+
# | | X | O | O | | |
290+
# --- --- --- --- --- ---
291+
# | | | | | | |
292+
# --- --- --- --- --- ---
293+
# | | | | | | |
294+
# --- --- --- --- --- ---
295+
# | | | | | | |
296+
# --- --- --- --- --- ---
297+
# Round 3, Soi's turn:4 2
298+
# --- --- --- --- --- ---
299+
# | | | | | | |
300+
# --- --- --- --- --- ---
301+
# | | X | | | | |
302+
# --- --- --- --- --- ---
303+
# | | X | O | O | | |
304+
# --- --- --- --- --- ---
305+
# | | X | | | | |
306+
# --- --- --- --- --- ---
307+
# | | | | | | |
308+
# --- --- --- --- --- ---
309+
# | | | | | | |
310+
# --- --- --- --- --- ---
311+
# Round 3, Peruru's turn:6 6
312+
# --- --- --- --- --- ---
313+
# | | | | | | |
314+
# --- --- --- --- --- ---
315+
# | | X | | | | |
316+
# --- --- --- --- --- ---
317+
# | | X | O | O | | |
318+
# --- --- --- --- --- ---
319+
# | | X | | | | |
320+
# --- --- --- --- --- ---
321+
# | | | | | | |
322+
# --- --- --- --- --- ---
323+
# | | | | | | O |
324+
# --- --- --- --- --- ---
325+
# Round 4, Soi's turn:5 2
326+
# --- --- --- --- --- ---
327+
# | | | | | | |
328+
# --- --- --- --- --- ---
329+
# | | X | | | | |
330+
# --- --- --- --- --- ---
331+
# | | X | O | O | | |
332+
# --- --- --- --- --- ---
333+
# | | X | | | | |
334+
# --- --- --- --- --- ---
335+
# | | X | | | | |
336+
# --- --- --- --- --- ---
337+
# | | | | | | O |
338+
# --- --- --- --- --- ---
339+
# X win!

0 commit comments

Comments
 (0)