46
46
START_GAME : bool = False
47
47
CHECK_FOR_WINNER : bool = False
48
48
MAIN_DIAGONAL_IS_WINNER : bool = False
49
- CURENT_BOARD_WON : bool = False
50
49
CONTINUE_WITH_NEXT_GAME : str = ''
51
50
STEP_COUNTER : int = 0
52
51
PLAYER_SWITCH = True
56
55
PLAYER2_NAME : str = ''
57
56
PLAYER2_MARKER : str = ''
58
57
59
- ROWS , COLS = (3 , 3 )
58
+ ROWS , COLS = (3 , 3 )
60
59
GAME_PROGRESS_ARRAY = [['' for i in range (COLS )] for j in range (ROWS )]
61
60
GAME_PROGRESS_ARRAY = np .array (GAME_PROGRESS_ARRAY , dtype = str )
62
61
# WINNING_PATTERNS: list = [['00', '10', '20'], ['01', '11', '21'], ['02', '12', '22'], # rows
@@ -69,28 +68,46 @@ def split(word):
69
68
70
69
def progress_game (key : str , player_marker : str ):
71
70
'''populated the 'GAME_PROGRESS_ARRAY' and
72
- checks for is winning condition.'''
71
+ checks for is winning condition.
72
+
73
+ PARAMS:
74
+ 1. key - the button element in the grid that was clicked.
75
+
76
+ 2. player_marker - the marker of the current player.
77
+
78
+ RETURNS:
79
+ continue_with_next_game - 'Yes' / 'No' indicator from the user action
80
+ whether to continue with the same players.
81
+ '''
73
82
74
83
global GAME_PROGRESS_ARRAY
75
- global CURENT_BOARD_WON
76
84
77
85
continue_with_next_game : str = ''
78
86
79
87
row , column = split (key )
80
88
GAME_PROGRESS_ARRAY [row ][column ] = player_marker
81
89
90
+ # check if we have a winner in the current state of the board.
82
91
if CHECK_FOR_WINNER :
83
92
game_won , winning_marker = is_winning ()
84
93
if game_won :
85
- CURENT_BOARD_WON = True
86
94
continue_with_next_game = display_winner_and_continue (winning_marker = winning_marker )
87
95
88
96
return continue_with_next_game
89
97
90
98
def is_row_column_diagonal_complete (row_col_num : int = - 1 , is_row : bool = True ,
91
99
is_diagonal : bool = False ):
92
100
'''checks if the given row or column is complete
93
- to proceed with a winner.'''
101
+ to proceed with a winner.
102
+
103
+ PARAMS:
104
+ 1. row_col_num - the row/column index to check if the row/columns is complete.
105
+ 2. is_row: True if a ROW needs to be checked for completion else FALSE for a column.
106
+ 3. is_diagonal: True is any of the diagonal needs to be checked for completion.
107
+
108
+ RETURNS:
109
+ is_complete: BOOLEAN FLAG to indicate of the row/column/diagonal is complete.
110
+ '''
94
111
is_complete : bool = False
95
112
96
113
if is_diagonal is False and row_col_num != - 1 :
@@ -117,10 +134,22 @@ def is_row_column_diagonal_complete(row_col_num: int = -1, is_row: bool = True,
117
134
118
135
return is_complete
119
136
120
-
121
- def mark_the_winner ( row_is_winner : bool , row_column_index : int = - 1 , diagonal_is_winner : bool = False ):
137
+ def mark_the_winner ( row_is_winner : bool , row_column_index : int = - 1 ,
138
+ diagonal_is_winner : bool = False ):
122
139
'''marks the winner row/column by updating
123
- the button row/column.'''
140
+ the button row/column. The button image background
141
+ changes to red to mark the winning sequence.
142
+
143
+ PARAMS:
144
+ 1. row_is_winner - Is the winner found in a ROW wise sequence.
145
+ TRUE for a row & FALSE incase the winner is a column.
146
+
147
+ 2. row_column_index - The winning row/column index.
148
+ This default value is -1 to indicate the winner being found
149
+ in one of the diagonals.
150
+
151
+ 3. diagonal_is_winner - Is the winner found in one of the diagonals.
152
+ '''
124
153
125
154
if not diagonal_is_winner and row_column_index != - 1 :
126
155
if row_is_winner :
@@ -203,7 +232,11 @@ def is_winning():
203
232
return False , ''
204
233
205
234
def display_winner_and_continue (winning_marker : str ):
206
- '''display the winner of the current board.'''
235
+ '''display the winner of the current board.
236
+
237
+ PARAMS:
238
+ 1. winning_marker - the marker that won the current board.
239
+ '''
207
240
208
241
if winning_marker == PLAYER1_MARKER :
209
242
popup_result = sg .PopupYesNo ('The Winner is ' + PLAYER1_NAME + '.\n Do you want to play another game with the current players?' ,
@@ -218,6 +251,7 @@ def display_winner_and_continue(winning_marker: str):
218
251
219
252
def init_game_window ():
220
253
'''Initializes and creates the game options window.'''
254
+
221
255
init_game_layout = [[sg .Text ('Player 1 Name: ' , size = (12 , 1 )),
222
256
sg .InputText ('' , key = '-P1_NAME-' )],
223
257
[sg .Text ('Player 2 Name: ' , size = (12 , 1 )),
@@ -239,18 +273,36 @@ def reset_game_board():
239
273
global STEP_COUNTER
240
274
global CONTINUE_WITH_NEXT_GAME
241
275
global CHECK_FOR_WINNER
242
- global CURENT_BOARD_WON
243
276
global GAME_BOARD
244
277
global PLAYER_SWITCH
278
+ global MAIN_DIAGONAL_IS_WINNER
245
279
246
280
GAME_BOARD = initialize_game_board ()
247
281
GAME_PROGRESS_ARRAY = [['' for i in range (COLS )] for j in range (ROWS )]
248
282
GAME_PROGRESS_ARRAY = np .array (GAME_PROGRESS_ARRAY , dtype = str )
249
283
STEP_COUNTER = 0
250
284
CHECK_FOR_WINNER = False
251
285
CONTINUE_WITH_NEXT_GAME = ''
252
- CURENT_BOARD_WON = False
253
286
PLAYER_SWITCH = True
287
+ MAIN_DIAGONAL_IS_WINNER = False
288
+
289
+ def start_next_session (user_choice : str ):
290
+
291
+ '''starts the next session as per the user choice.
292
+ YES - retain the players and reset the board state.
293
+ NO - return to the game init dialog to start over with new set of players.'''
294
+
295
+ global INIT_WINDOW
296
+ global GAME_BOARD
297
+
298
+ if user_choice == 'Yes' :
299
+ # retain the players and reset the board state.
300
+ GAME_BOARD .Close ()
301
+ reset_game_board ()
302
+ elif user_choice == 'No' :
303
+ # return to the game init dialog to start over with new set of players.
304
+ GAME_BOARD .Close ()
305
+ INIT_WINDOW = init_game_window ()
254
306
255
307
def initialize_game_board ():
256
308
'''initialize the game board.'''
@@ -291,6 +343,7 @@ def initialize_game_board():
291
343
292
344
if EVENT == '-START-' and not GAME_BOARD :
293
345
346
+ # player name validation. Valid names required.
294
347
if VALUES ['-P1_NAME-' ] == '' and VALUES ['-P2_NAME-' ] == '' :
295
348
sg .popup_ok ("Error initializing players name. Enter both the players name before proceeding." ,
296
349
title = 'Tic Tac Toe' , icon = GAME_ICON )
@@ -313,14 +366,16 @@ def initialize_game_board():
313
366
INIT_WINDOW .close ()
314
367
GAME_BOARD = initialize_game_board ()
315
368
316
- if WINDOW == GAME_BOARD and (EVENT in ('WIN_CLOSE' , 'Exit ' )):
369
+ if WINDOW == GAME_BOARD and (EVENT in ('WIN_CLOSE' , '-EXIT- ' )):
317
370
GAME_BOARD .close ()
318
371
GAME_BOARD = None
319
372
INIT_WINDOW = init_game_window ()
320
373
321
- if START_GAME :
374
+ # We do not want to execute the progress logic in case
375
+ # of the reset event.
376
+ if START_GAME and EVENT != '-RESET-' :
322
377
323
- if EVENT not in ('-START-' , 'WIN_CLOSE' ):
378
+ if EVENT not in ('-START-' , 'WIN_CLOSE' , '-EXIT-' ):
324
379
CURRENT_MARKER = GAME_BOARD .Element (EVENT ).get_text ()
325
380
GAME_BOARD .Element (EVENT ).update (PLAYER1_MARKER if CURRENT_MARKER == ' ' and \
326
381
PLAYER_SWITCH is True else PLAYER2_MARKER if CURRENT_MARKER == ' ' and \
@@ -341,6 +396,7 @@ def initialize_game_board():
341
396
GAME_BOARD .Element ('-P1-' ).update (text_color = 'white' )
342
397
GAME_BOARD .Element ('-P2-' ).update (text_color = 'darkblue' )
343
398
399
+ # update the button images as per the current players marker.
344
400
if PLAYER1_MARKER == 'X' :
345
401
GAME_BOARD .Element (EVENT ).update (image_filename = X_IMAGE )
346
402
else :
@@ -349,12 +405,10 @@ def initialize_game_board():
349
405
GAME_BOARD .Element (EVENT ).update (disabled = True )
350
406
351
407
CONTINUE_WITH_NEXT_GAME = progress_game (EVENT , PLAYER1_MARKER )
352
- if CONTINUE_WITH_NEXT_GAME == 'Yes' :
353
- GAME_BOARD .Close ()
354
- reset_game_board ()
355
- elif CONTINUE_WITH_NEXT_GAME == 'No' :
356
- GAME_BOARD .Close ()
357
- INIT_WINDOW = init_game_window ()
408
+
409
+ # start with the same players or new game
410
+ # session with different players
411
+ start_next_session (CONTINUE_WITH_NEXT_GAME )
358
412
359
413
elif GAME_BOARD .Element (EVENT ).get_text () == PLAYER2_MARKER :
360
414
# increase the step counter.
@@ -365,6 +419,7 @@ def initialize_game_board():
365
419
GAME_BOARD .Element ('-P1-' ).update (text_color = 'darkblue' )
366
420
GAME_BOARD .Element ('-P2-' ).update (text_color = 'white' )
367
421
422
+ # update the button images as per the current players marker.
368
423
if PLAYER2_MARKER == 'X' :
369
424
GAME_BOARD .Element (EVENT ).update (image_filename = X_IMAGE )
370
425
else :
@@ -373,18 +428,20 @@ def initialize_game_board():
373
428
GAME_BOARD .Element (EVENT ).update (disabled = True )
374
429
375
430
CONTINUE_WITH_NEXT_GAME = progress_game (EVENT , PLAYER2_MARKER )
376
- if CONTINUE_WITH_NEXT_GAME == 'Yes' :
377
- GAME_BOARD .Close ()
378
- reset_game_board ()
379
- elif CONTINUE_WITH_NEXT_GAME == 'No' :
380
- GAME_BOARD .Close ()
381
- INIT_WINDOW = init_game_window ()
431
+
432
+ # start with the same players or new game
433
+ # session with different players
434
+ start_next_session (CONTINUE_WITH_NEXT_GAME )
382
435
383
436
# The minimum number of steps required
384
437
# to win the game board is 5.
385
438
if STEP_COUNTER == 4 :
386
439
CHECK_FOR_WINNER = True
387
440
388
- if EVENT == '-RESET-' :
389
- GAME_BOARD .Close ()
390
- reset_game_board ()
441
+ if EVENT == '-RESET-' and WINDOW == GAME_BOARD :
442
+ # reset the current board state.
443
+ RESET_GAME = sg .popup_yes_no ('Are you sure you want to reset the current board?' ,
444
+ title = 'Game Reset' , icon = GAME_ICON , grab_anywhere = True )
445
+ if RESET_GAME == 'Yes' :
446
+ GAME_BOARD .Close ()
447
+ reset_game_board ()
0 commit comments