|
4 | 4 | import numpy as np
|
5 | 5 | import PySimpleGUI as sg
|
6 | 6 |
|
| 7 | +INIT_WINDOW = None |
| 8 | + |
7 | 9 | CURRENT_WORKING_DIRECTORY = os.path.dirname(os.path.realpath(__file__))
|
8 | 10 | X_IMAGE = CURRENT_WORKING_DIRECTORY + '\\X.png'
|
9 | 11 | X_RED = CURRENT_WORKING_DIRECTORY + '\\X_Red.png'
|
|
13 | 15 |
|
14 | 16 | START_GAME: bool = False
|
15 | 17 | CHECK_FOR_WINNER: bool = False
|
| 18 | +MAIN_DIAGONAL_IS_WINNER: bool = False |
| 19 | +CURENT_BOARD_WON: bool = False |
16 | 20 |
|
17 | 21 | ROWS, COLS = (3, 3)
|
18 | 22 | GAME_PROGRESS_ARRAY = [['' for i in range(COLS)] for j in range(ROWS)]
|
@@ -30,18 +34,20 @@ def progress_game(key: str, player_marker: str):
|
30 | 34 | checks for is winning condition.'''
|
31 | 35 |
|
32 | 36 | global GAME_PROGRESS_ARRAY
|
| 37 | +global CURENT_BOARD_WON |
33 | 38 |
|
34 | 39 | row, column = split(key)
|
35 | 40 | GAME_PROGRESS_ARRAY[row][column] = player_marker
|
36 | 41 |
|
37 | 42 | if CHECK_FOR_WINNER:
|
38 |
| -is_winning() |
| 43 | +if is_winning(): |
| 44 | +CURENT_BOARD_WON = True |
39 | 45 |
|
40 | 46 | def is_row_column_diagonal_complete(row_col_num: int = -1, is_row: bool = True, is_diagonal: bool = False):
|
41 | 47 | '''checks if the given row or column is complete
|
42 | 48 | to proceed with a winner.'''
|
43 | 49 |
|
44 |
| -if is_diagonal == False and row_col_num != -1: |
| 50 | +if is_diagonal is False and row_col_num != -1: |
45 | 51 | if is_row:
|
46 | 52 | row = row_col_num
|
47 | 53 | if GAME_PROGRESS_ARRAY[row][0] != '' and \
|
@@ -69,70 +75,111 @@ def is_row_column_diagonal_complete(row_col_num: int = -1, is_row: bool = True,
|
69 | 75 | return True
|
70 | 76 |
|
71 | 77 |
|
72 |
| -def mark_the_winner(row_column_index: int, row_as_winner: bool): |
73 |
| -'''marks the winner row/column by updating |
| 78 | +def mark_the_winner(row_is_winner: bool, row_column_index: int = -1, diagonal_is_winner: bool = False): |
| 79 | +'''marks the winner row/column by updating |
74 | 80 | the button row/column.'''
|
75 | 81 |
|
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 | +if not diagonal_is_winner and row_column_index != -1: |
| 83 | +if row_is_winner: |
| 84 | +row = row_column_index |
| 85 | +if GAME_PROGRESS_ARRAY[row][0] == 'X': |
| 86 | +GAME_BOARD[str(row)+str(0)].update(image_filename=X_RED) |
| 87 | +GAME_BOARD[str(row)+str(1)].update(image_filename=X_RED) |
| 88 | +GAME_BOARD[str(row)+str(2)].update(image_filename=X_RED) |
| 89 | +else: |
| 90 | +GAME_BOARD[str(row)+str(0)].update(image_filename=O_RED) |
| 91 | +GAME_BOARD[str(row)+str(1)].update(image_filename=O_RED) |
| 92 | +GAME_BOARD[str(row)+str(2)].update(image_filename=O_RED) |
82 | 93 | 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) |
| 94 | +col = row_column_index |
| 95 | +if GAME_PROGRESS_ARRAY[0][col] == 'X': |
| 96 | +GAME_BOARD[str(0)+str(col)].update(image_filename=X_RED) |
| 97 | +GAME_BOARD[str(1)+str(col)].update(image_filename=X_RED) |
| 98 | +GAME_BOARD[str(2)+str(col)].update(image_filename=X_RED) |
| 99 | +else: |
| 100 | +GAME_BOARD[str(0)+str(col)].update(image_filename=O_RED) |
| 101 | +GAME_BOARD[str(1)+str(col)].update(image_filename=O_RED) |
| 102 | +GAME_BOARD[str(2)+str(col)].update(image_filename=O_RED) |
86 | 103 | 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) |
| 104 | +if MAIN_DIAGONAL_IS_WINNER: |
| 105 | +if GAME_PROGRESS_ARRAY[1][1] == 'X': |
| 106 | +GAME_BOARD[str(0)+str(0)].update(image_filename=X_RED) |
| 107 | +GAME_BOARD[str(1)+str(1)].update(image_filename=X_RED) |
| 108 | +GAME_BOARD[str(2)+str(2)].update(image_filename=X_RED) |
| 109 | +else: |
| 110 | +GAME_BOARD[str(0)+str(0)].update(image_filename=O_RED) |
| 111 | +GAME_BOARD[str(1)+str(1)].update(image_filename=O_RED) |
| 112 | +GAME_BOARD[str(2)+str(2)].update(image_filename=O_RED) |
92 | 113 | 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) |
| 114 | +if GAME_PROGRESS_ARRAY[1][1] == 'X': |
| 115 | +GAME_BOARD[str(0)+str(2)].update(image_filename=X_RED) |
| 116 | +GAME_BOARD[str(1)+str(1)].update(image_filename=X_RED) |
| 117 | +GAME_BOARD[str(2)+str(0)].update(image_filename=X_RED) |
| 118 | +else: |
| 119 | +GAME_BOARD[str(0)+str(2)].update(image_filename=O_RED) |
| 120 | +GAME_BOARD[str(1)+str(1)].update(image_filename=O_RED) |
| 121 | +GAME_BOARD[str(2)+str(0)].update(image_filename=O_RED) |
96 | 122 |
|
97 | 123 | def is_winning():
|
98 | 124 | '''evaluated the current state of the gameboard
|
99 | 125 | and checks if there is a winner currently.'''
|
100 | 126 |
|
101 | 127 | global GAME_PROGRESS_ARRAY
|
102 | 128 | global CHECK_FOR_WINNER
|
| 129 | +global MAIN_DIAGONAL_IS_WINNER |
103 | 130 |
|
104 | 131 | # check for the row wise sequence.
|
105 | 132 | for row in range(ROWS):
|
106 | 133 | if is_row_column_diagonal_complete(row_col_num=row, is_row=True):
|
107 | 134 | 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) |
| 135 | +mark_the_winner(row_is_winner=True, row_column_index=row) |
| 136 | +display_winner_and_continue(winning_marker=GAME_PROGRESS_ARRAY[row][0]) |
110 | 137 | CHECK_FOR_WINNER = False
|
111 | 138 | return True
|
112 | 139 |
|
113 | 140 | # check for the column wise sequence.
|
114 | 141 | for col in range(COLS):
|
115 | 142 | if is_row_column_diagonal_complete(row_col_num=col, is_row=False):
|
116 | 143 | 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') |
| 144 | +mark_the_winner(row_is_winner=False, row_column_index=col) |
| 145 | +display_winner_and_continue(winning_marker=GAME_PROGRESS_ARRAY[0][col]) |
119 | 146 | CHECK_FOR_WINNER = False
|
120 | 147 | return True
|
121 | 148 |
|
122 | 149 | # check for the 2 diagonals for a winning sequence.
|
123 | 150 | if is_row_column_diagonal_complete(is_diagonal=True):
|
124 | 151 | 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 |
| 152 | +MAIN_DIAGONAL_IS_WINNER = True |
| 153 | +mark_the_winner(row_column_index=-1, row_is_winner=False, diagonal_is_winner=True) |
| 154 | +display_winner_and_continue(winning_marker=GAME_PROGRESS_ARRAY[1][1]) |
| 155 | +CHECK_FOR_WINNER = False |
| 156 | +return True |
129 | 157 | 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 |
| 158 | +mark_the_winner(row_column_index=-1, row_is_winner=False, diagonal_is_winner=True) |
| 159 | +display_winner_and_continue(winning_marker=GAME_PROGRESS_ARRAY[1][1]) |
| 160 | +CHECK_FOR_WINNER = False |
| 161 | +return True |
134 | 162 |
|
| 163 | +def display_winner_and_continue(winning_marker: str): |
| 164 | +'''display the winner of the current board.''' |
135 | 165 |
|
| 166 | +global INIT_WINDOW |
| 167 | + |
| 168 | +if winning_marker == PLAYER1_MARKER: |
| 169 | +continue_with_same_player = sg.PopupYesNo('The Winner is ' + PLAYER1_NAME + '.\nDo you want to play another game with the current players?', |
| 170 | +title='Board Winner!', text_color='darkblue', icon=GAME_ICON, |
| 171 | +grab_anywhere=True, font=('Blackadder ITC', 20)) |
| 172 | +elif winning_marker == PLAYER2_MARKER: |
| 173 | +continue_with_same_player = sg.PopupYesNo('The Winner is ' + PLAYER2_NAME + '.\nDo you want to play another game with the current players?', |
| 174 | +title='Board Winner!', text_color='darkblue', icon=GAME_ICON, |
| 175 | +grab_anywhere=True, font=('Blackadder ITC', 20)) |
| 176 | + |
| 177 | +if continue_with_same_player == 'Yes': |
| 178 | +GAME_BOARD.close() |
| 179 | +initialize_game_board() |
| 180 | +elif continue_with_same_player == 'No' and not INIT_WINDOW: |
| 181 | +GAME_BOARD.hide() |
| 182 | +INIT_WINDOW = init_game_window() |
136 | 183 |
|
137 | 184 |
|
138 | 185 | def init_game_window():
|
@@ -182,23 +229,31 @@ def init_game_window():
|
182 | 229 | INIT_WINDOW.close()
|
183 | 230 |
|
184 | 231 | INIT_WINDOW.close()
|
| 232 | +INIT_WINDOW = None |
185 | 233 |
|
186 | 234 | STEP_COUNTER: int = 0
|
187 | 235 | PLAYER_SWITCH = True
|
188 | 236 | PLAYER1_MARKED_CELLS: list = []
|
189 | 237 | PLAYER2_MARKED_CELLS: list = []
|
190 | 238 | if START_GAME:
|
191 | 239 |
|
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('')]] |
| 240 | +def initialize_game_board(): |
| 241 | +'''initialize the game board.''' |
| 242 | + |
| 243 | +GAME_BOARD_LAYOUT = [[sg.Text('Player 1: ' + PLAYER1_NAME, key='-P1-', text_color='darkblue')], |
| 244 | +[sg.Text('Player 2: ' + PLAYER2_NAME, key='-P2-', text_color='white')], |
| 245 | +[sg.Text(PLAYER1_NAME + "'s Marker: " + PLAYER1_MARKER)], |
| 246 | +[sg.Text(PLAYER2_NAME + "'s Marker: " + PLAYER2_MARKER)], |
| 247 | +[sg.Text('')]] |
197 | 248 |
|
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)] |
| 249 | +GAME_BOARD_LAYOUT += [[sg.Button(' ', size=(8, 4), key=str(j)+str(i)) |
| 250 | +for i in range(3)] for j in range(3)] |
200 | 251 |
|
201 |
| -GAME_BOARD = sg.Window('Tic Tac Toe', icon=GAME_ICON).Layout(GAME_BOARD_LAYOUT) |
| 252 | +BOARD = sg.Window('Tic Tac Toe', icon=GAME_ICON).Layout(GAME_BOARD_LAYOUT) |
| 253 | + |
| 254 | +return BOARD |
| 255 | + |
| 256 | +GAME_BOARD = initialize_game_board() |
202 | 257 |
|
203 | 258 | while True:
|
204 | 259 |
|
@@ -228,10 +283,17 @@ def init_game_window():
|
228 | 283 | GAME_BOARD['-P1-'].update(text_color='white')
|
229 | 284 | GAME_BOARD['-P2-'].update(text_color='darkblue')
|
230 | 285 |
|
231 |
| -GAME_BOARD[GAME_EVENT].update(image_filename=X_IMAGE) |
| 286 | +if PLAYER1_MARKER == 'X': |
| 287 | +GAME_BOARD[GAME_EVENT].update(image_filename=X_IMAGE) |
| 288 | +else: |
| 289 | +GAME_BOARD[GAME_EVENT].update(image_filename=O_IMAGE) |
| 290 | + |
232 | 291 | GAME_BOARD[GAME_EVENT].update(disabled=True)
|
233 | 292 |
|
234 | 293 | progress_game(GAME_EVENT, PLAYER1_MARKER)
|
| 294 | + |
| 295 | +if CURENT_BOARD_WON: |
| 296 | +break |
235 | 297 | elif GAME_BOARD[GAME_EVENT].get_text() == PLAYER2_MARKER:
|
236 | 298 | # increase the step counter.
|
237 | 299 | # The minimum number of steps required to win the game is 5
|
@@ -242,11 +304,17 @@ def init_game_window():
|
242 | 304 | GAME_BOARD['-P1-'].update(text_color='darkblue')
|
243 | 305 | GAME_BOARD['-P2-'].update(text_color='white')
|
244 | 306 |
|
245 |
| -GAME_BOARD[GAME_EVENT].update(image_filename=O_IMAGE) |
| 307 | +if PLAYER2_MARKER == 'X': |
| 308 | +GAME_BOARD[GAME_EVENT].update(image_filename=X_IMAGE) |
| 309 | +else: |
| 310 | +GAME_BOARD[GAME_EVENT].update(image_filename=O_IMAGE) |
| 311 | + |
246 | 312 | GAME_BOARD[GAME_EVENT].update(disabled=True)
|
247 | 313 |
|
248 | 314 | progress_game(GAME_EVENT, PLAYER2_MARKER)
|
249 | 315 |
|
| 316 | +if CURENT_BOARD_WON: |
| 317 | +break |
250 | 318 | # The minimum number of steps required
|
251 | 319 | # to win the game board is 5.
|
252 | 320 | if STEP_COUNTER == 4:
|
|
0 commit comments