Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 81ca8bb

Browse files
tic-tac-toe game
Building the tic-tac-toe game using PySimpleGUI. Status - InProgress
1 parent 30fcead commit 81ca8bb

File tree

6 files changed

+255
-0
lines changed

6 files changed

+255
-0
lines changed
4.8 KB
Loading[フレーム]
5.2 KB
Loading[フレーム]
4.14 KB
Loading[フレーム]
4.1 KB
Loading[フレーム]
Lines changed: 255 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,255 @@
1+
'''tic-tac-toe Game using PySimpleGUI'''
2+
3+
import os
4+
import numpy as np
5+
import PySimpleGUI as sg
6+
7+
CURRENT_WORKING_DIRECTORY = os.path.dirname(os.path.realpath(__file__))
8+
X_IMAGE = CURRENT_WORKING_DIRECTORY + '\\X.png'
9+
X_RED = CURRENT_WORKING_DIRECTORY + '\\X_Red.png'
10+
O_IMAGE = CURRENT_WORKING_DIRECTORY + '\\O.png'
11+
O_RED = CURRENT_WORKING_DIRECTORY + '\\O_Red.png'
12+
GAME_ICON = CURRENT_WORKING_DIRECTORY + '\\tictactoe.ico'
13+
14+
START_GAME: bool = False
15+
CHECK_FOR_WINNER: bool = False
16+
17+
ROWS, COLS = (3, 3)
18+
GAME_PROGRESS_ARRAY = [['' for i in range(COLS)] for j in range(ROWS)]
19+
GAME_PROGRESS_ARRAY = np.array(GAME_PROGRESS_ARRAY, dtype=str)
20+
WINNING_PATTERNS: list = [['00', '10', '20'], ['01', '11', '21'], ['02', '12', '22'], # rows
21+
['00', '01', '02'], ['10', '11', '12'], ['20', '21', '22'], # columns
22+
['00', '11', '22'], ['00', '11', '02']] # diagonals
23+
24+
def split(word):
25+
'''splits a string to constituents chars.'''
26+
return [int(char) for char in word]
27+
28+
def progress_game(key: str, player_marker: str):
29+
'''populated the 'GAME_PROGRESS_ARRAY' and
30+
checks for is winning condition.'''
31+
32+
global GAME_PROGRESS_ARRAY
33+
34+
row, column = split(key)
35+
GAME_PROGRESS_ARRAY[row][column] = player_marker
36+
37+
if CHECK_FOR_WINNER:
38+
is_winning()
39+
40+
def is_row_column_diagonal_complete(row_col_num: int = -1, is_row: bool = True, is_diagonal: bool = False):
41+
'''checks if the given row or column is complete
42+
to proceed with a winner.'''
43+
44+
if is_diagonal == False and row_col_num != -1:
45+
if is_row:
46+
row = row_col_num
47+
if GAME_PROGRESS_ARRAY[row][0] != '' and \
48+
GAME_PROGRESS_ARRAY[row][1] != '' and \
49+
GAME_PROGRESS_ARRAY[row][2] != '':
50+
return True
51+
else:
52+
return False
53+
else:
54+
col = row_col_num
55+
if GAME_PROGRESS_ARRAY[0][col] != '' and \
56+
GAME_PROGRESS_ARRAY[1][col] != '' and \
57+
GAME_PROGRESS_ARRAY[2][col] != '':
58+
return True
59+
else:
60+
return False
61+
else:
62+
if GAME_PROGRESS_ARRAY[0][0] != '' and \
63+
GAME_PROGRESS_ARRAY[1][1] != '' and \
64+
GAME_PROGRESS_ARRAY[2][2] != '':
65+
return True
66+
elif GAME_PROGRESS_ARRAY[2][0] != '' and \
67+
GAME_PROGRESS_ARRAY[1][1] != '' and \
68+
GAME_PROGRESS_ARRAY[0][2] != '':
69+
return True
70+
71+
72+
def mark_the_winner(row_column_index: int, row_as_winner: bool):
73+
'''marks the winner row/column by updating
74+
the button row/column.'''
75+
76+
if row_as_winner:
77+
row = row_column_index
78+
if GAME_PROGRESS_ARRAY[row][0] == 'X':
79+
GAME_BOARD[str(row)+str(0)].update(image_filename=X_RED)
80+
GAME_BOARD[str(row)+str(1)].update(image_filename=X_RED)
81+
GAME_BOARD[str(row)+str(2)].update(image_filename=X_RED)
82+
else:
83+
GAME_BOARD[str(row)+str(0)].update(image_filename=O_RED)
84+
GAME_BOARD[str(row)+str(1)].update(image_filename=O_RED)
85+
GAME_BOARD[str(row)+str(2)].update(image_filename=O_RED)
86+
else:
87+
col = row_column_index
88+
if GAME_PROGRESS_ARRAY[0][col] == 'X':
89+
GAME_BOARD[str(0)+str(col)].update(image_filename=X_RED)
90+
GAME_BOARD[str(1)+str(col)].update(image_filename=X_RED)
91+
GAME_BOARD[str(2)+str(col)].update(image_filename=X_RED)
92+
else:
93+
GAME_BOARD[str(0)+str(col)].update(image_filename=O_RED)
94+
GAME_BOARD[str(1)+str(col)].update(image_filename=O_RED)
95+
GAME_BOARD[str(2)+str(col)].update(image_filename=O_RED)
96+
97+
def is_winning():
98+
'''evaluated the current state of the gameboard
99+
and checks if there is a winner currently.'''
100+
101+
global GAME_PROGRESS_ARRAY
102+
global CHECK_FOR_WINNER
103+
104+
# check for the row wise sequence.
105+
for row in range(ROWS):
106+
if is_row_column_diagonal_complete(row_col_num=row, is_row=True):
107+
if GAME_PROGRESS_ARRAY[row][0] == GAME_PROGRESS_ARRAY[row][1] == GAME_PROGRESS_ARRAY[row][2]:
108+
mark_the_winner(row_column_index=row, row_as_winner=True)
109+
sg.popup('winnner', grab_anywhere=True)
110+
CHECK_FOR_WINNER = False
111+
return True
112+
113+
# check for the column wise sequence.
114+
for col in range(COLS):
115+
if is_row_column_diagonal_complete(row_col_num=col, is_row=False):
116+
if GAME_PROGRESS_ARRAY[0][col] == GAME_PROGRESS_ARRAY[1][col] == GAME_PROGRESS_ARRAY[2][col]:
117+
mark_the_winner(row_column_index=col, row_as_winner=False)
118+
sg.popup('winnner')
119+
CHECK_FOR_WINNER = False
120+
return True
121+
122+
# check for the 2 diagonals for a winning sequence.
123+
if is_row_column_diagonal_complete(is_diagonal=True):
124+
if GAME_PROGRESS_ARRAY[0][0] == GAME_PROGRESS_ARRAY[1][1] == GAME_PROGRESS_ARRAY[2][2]:
125+
# mark_the_winner(row_column_index=col, row_as_winner=False)
126+
sg.popup('winnner')
127+
CHECK_FOR_WINNER = False
128+
return True
129+
elif GAME_PROGRESS_ARRAY[2][0] == GAME_PROGRESS_ARRAY[1][1] == GAME_PROGRESS_ARRAY[0][2]:
130+
# mark_the_winner(row_column_index=col, row_as_winner=False)
131+
sg.popup('winnner')
132+
CHECK_FOR_WINNER = False
133+
return True
134+
135+
136+
137+
138+
def init_game_window():
139+
'''Initializes and creates the game options window.'''
140+
init_game_layout = [[sg.Text('Player 1 Name: ', size=(12, 1)),
141+
sg.InputText('', key='-P1_NAME-')],
142+
[sg.Text('Player 2 Name: ', size=(12, 1)),
143+
sg.InputText('', key='-P2_NAME-')],
144+
[sg.Frame(layout=[[sg.Radio('X', group_id="P1_PREF", key='-P1_MARK-',
145+
default=True, size=(10, 1)),
146+
sg.Radio('O', group_id="P1_PREF", key='-P2_MARK-')]],
147+
title='Player 1 Preference', relief=sg.RELIEF_GROOVE,
148+
tooltip='Set Player 1 Preference')],
149+
[sg.Button("Start Game", key='-START-'), sg.Button('Exit', key='-EXIT-')]]
150+
151+
return sg.Window('Tic Tac Toe Options', icon=GAME_ICON, finalize=True).Layout(init_game_layout)
152+
153+
INIT_WINDOW = init_game_window()
154+
155+
while True:
156+
EVENT, VALUES = INIT_WINDOW.Read()
157+
158+
if EVENT in (sg.WINDOW_CLOSED, '-EXIT-'):
159+
break
160+
161+
if EVENT not in (None, '-EXIT-'):
162+
if EVENT == '-START-':
163+
if VALUES['-P1_NAME-'] == '' and VALUES['-P2_NAME-'] == '':
164+
sg.popup_ok("Error initializing players name. Enter both the players name before proceeding.",
165+
title='Tic Tac Toe', icon=GAME_ICON)
166+
167+
else:
168+
PLAYER1_NAME, PLAYER2_NAME, PLAYER1_X, PLAYER2_X = VALUES['-P1_NAME-'], VALUES['-P2_NAME-'], VALUES['-P1_MARK-'], VALUES['-P2_MARK-']
169+
170+
# Get the PLayer Markers to start with.
171+
if PLAYER1_X:
172+
PLAYER1_MARKER, PLAYER2_MARKER = ("X", "O")
173+
else:
174+
PLAYER1_MARKER, PLAYER2_MARKER = ("O", "X")
175+
176+
# set the flag to start the game as once the
177+
# window is closed the event loop will be destroyed.
178+
if EVENT == '-START-':
179+
if VALUES['-P1_NAME-'] is not None and VALUES['-P2_NAME-'] is not None:
180+
START_GAME = True
181+
# Close the options window and start the game.
182+
INIT_WINDOW.close()
183+
184+
INIT_WINDOW.close()
185+
186+
STEP_COUNTER: int = 0
187+
PLAYER_SWITCH = True
188+
PLAYER1_MARKED_CELLS: list = []
189+
PLAYER2_MARKED_CELLS: list = []
190+
if START_GAME:
191+
192+
GAME_BOARD_LAYOUT = [[sg.Text('Player 1: ' + PLAYER1_NAME, key='-P1-', text_color='darkblue')],
193+
[sg.Text('Player 2: ' + PLAYER2_NAME, key='-P2-', text_color='white')],
194+
[sg.Text(PLAYER1_NAME + "'s Marker: " + PLAYER1_MARKER)],
195+
[sg.Text(PLAYER2_NAME + "'s Marker: " + PLAYER2_MARKER)],
196+
[sg.Text('')]]
197+
198+
GAME_BOARD_LAYOUT += [[sg.Button(' ', size=(8, 4), key=str(j)+str(i))
199+
for i in range(3)] for j in range(3)]
200+
201+
GAME_BOARD = sg.Window('Tic Tac Toe', icon=GAME_ICON).Layout(GAME_BOARD_LAYOUT)
202+
203+
while True:
204+
205+
GAME_EVENT, GAME_VALUES = GAME_BOARD.Read()
206+
207+
if GAME_EVENT in (sg.WINDOW_CLOSED, 'Exit'):
208+
break
209+
210+
CURRENT_MARKER = GAME_BOARD[GAME_EVENT].get_text()
211+
GAME_BOARD[GAME_EVENT].update(PLAYER1_MARKER if CURRENT_MARKER == ' ' and\
212+
PLAYER_SWITCH is True else PLAYER2_MARKER if CURRENT_MARKER == ' ' and\
213+
PLAYER_SWITCH is False else PLAYER1_MARKER if CURRENT_MARKER == PLAYER1_MARKER
214+
else PLAYER2_MARKER if CURRENT_MARKER == PLAYER2_MARKER else ' ')
215+
216+
# Change the color of the player text to mark
217+
# the next player's turn. 'DarkBlue indicates
218+
# the player who should make the next move.'
219+
# Additionally, Once the player has made a move,
220+
# disable the button.
221+
if GAME_BOARD[GAME_EVENT].get_text() == PLAYER1_MARKER:
222+
# increase the step counter.
223+
# The minimum number of steps required to win the game is 5
224+
STEP_COUNTER += 1
225+
PLAYER_SWITCH = False
226+
PLAYER1_MARKED_CELLS.append(GAME_EVENT)
227+
228+
GAME_BOARD['-P1-'].update(text_color='white')
229+
GAME_BOARD['-P2-'].update(text_color='darkblue')
230+
231+
GAME_BOARD[GAME_EVENT].update(image_filename=X_IMAGE)
232+
GAME_BOARD[GAME_EVENT].update(disabled=True)
233+
234+
progress_game(GAME_EVENT, PLAYER1_MARKER)
235+
elif GAME_BOARD[GAME_EVENT].get_text() == PLAYER2_MARKER:
236+
# increase the step counter.
237+
# The minimum number of steps required to win the game is 5
238+
STEP_COUNTER += 1
239+
PLAYER_SWITCH = True
240+
PLAYER2_MARKED_CELLS.append(GAME_EVENT)
241+
242+
GAME_BOARD['-P1-'].update(text_color='darkblue')
243+
GAME_BOARD['-P2-'].update(text_color='white')
244+
245+
GAME_BOARD[GAME_EVENT].update(image_filename=O_IMAGE)
246+
GAME_BOARD[GAME_EVENT].update(disabled=True)
247+
248+
progress_game(GAME_EVENT, PLAYER2_MARKER)
249+
250+
# The minimum number of steps required
251+
# to win the game board is 5.
252+
if STEP_COUNTER == 4:
253+
CHECK_FOR_WINNER = True
254+
255+
# GAME_BOARD.close()
66.1 KB
Binary file not shown.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /