Skip to content

Instantly share code, notes, and snippets.

@mvlsqz
Last active January 19, 2023 21:50
Show Gist options
  • Save mvlsqz/264d25ccc3883bc9b78b226a8b50102f to your computer and use it in GitHub Desktop.
Save mvlsqz/264d25ccc3883bc9b78b226a8b50102f to your computer and use it in GitHub Desktop.

Tic Tac Toe Game

This is my own version of the game Tic Tac Toe Game, it is part of my Python's learning process

Although the original Tic Tac Toe game has to be play on a 3x3 board by default, this python code can handle any board size, no real use case was in my mind for this just did it for learning and fun purposes.

TODO

  • Make board spots start counting from 1 instead of 0.
  • Better formatting
from IPython.display import clear_output
def make_board(size: int) -> list:
'''
Function generates a board of size * size (kind of a 2D matrix)
'''
return list(range(size * size))
def make_rows(game_board: list, size: int) -> list:
'''
Create a matrix from the flat game_board list
'''
return [game_board[i:i + size] for i in range(0, size * size, size)]
def is_valid_symbol(player_symbol: str) -> tuple[bool, str]:
'''
Check for the symbol to be on the valid options X or O
'''
symbol = str(player_symbol)
is_valid = True if symbol.upper() == 'O' or \
symbol.upper() == 'X' else False
return is_valid, symbol.upper()
def spot_taken(game_board: list, position: int) -> bool:
'''
Check if spot was already take
'''
return game_board[position] == 'X' or game_board[position] == 'O'
def place_symbol_in_to_position(
game_board: list,
user_symbol: str,
position: int) -> list:
'''
Stores the player_symbol in a position of the game_board
'''
game_board[position] = user_symbol
return game_board
def full_board(game_board: list):
'''
Check if all spots on the board are taken
'''
full_board = len(game_board)
taken_spots = 0
for spot in game_board:
if spot == 'O' or spot == 'X':
taken_spots += 1
return full_board == taken_spots
def make_win_combiantions(game_board: list, size: int) -> list:
'''
Iterate over the board looking for every possible winner combination.
To calculate the rows list the function uses the size as length of each
To calculate the columns the zip function merge the elements of the rows
The diagonals are generated using list comprehensions
'''
rows = make_rows(game_board, size)
columns = list(zip(*rows))
left_to_right = [item[idx] for idx, item in enumerate(rows)]
right_to_left = [item[(size - 1) - idx] for idx, item in enumerate(rows)]
return rows + columns + [left_to_right] + [right_to_left]
def three_in_a_row(
win_combinations_matrix: list,
player_symbol: str, size: int) -> bool:
'''
Check for every row in the win_combinations_matrix
has the size number of the player_symbol
'''
for row in win_combinations_matrix:
player_set = [str(char) for char in row]
if ''.join(player_set) == player_symbol.upper() * size:
return True
return False
def draw_board(game_board: list, size: int) -> str:
'''
generates a visual representation of the game_board
to print it out to the console
'''
clear_output()
board_matrix = make_rows(game_board, size)
line_separator = '---+' * (size - 1)
line_separator += '---\n'
board_draw = ''
for line_index, line in enumerate(board_matrix):
for index, spot in enumerate(line):
this_spot = f' {spot} |'\
if not index == (size - 1)\
else f' {spot} \n'
board_draw += this_spot
board_draw += line_separator if not line_index == (size - 1) else '\n'
return board_draw
if __name__ == "__main__":
print('Welcome to Tic-Tac-Toe Game', end='\n')
# setup players
is_player_ready = False
player1 = ''
while not is_player_ready:
print('Player 1: Please chose a symbol to use in the game X or O')
is_player_ready, player1 = is_valid_symbol(
input('> '))
player2 = 'X' if player1.upper() == 'O' else 'O'
print(f'Player 1 will use {player1}')
print(f'Player 2 will use {player2}')
# setup the game board
size = 3
board = make_board(3)
winner = False
# start the game
print(draw_board(board, size))
while not winner:
print(
'Player 1 turn: ',
'Please mark a spot in the board: '
)
player1_move = int(input('> '))
while spot_taken(board, player1_move):
print(
'Player 1:',
'Spot taken already, please chose a different one'
)
player1_move = int(input('> '))
else:
board = place_symbol_in_to_position(
board,
player1,
player1_move
)
if not three_in_a_row(
make_win_combiantions(board, size),
player1,
size
):
if not full_board(board):
print(draw_board(board, size))
else:
print(
'Board full, No winner\n',
draw_board(board, size),
sep='\n'
)
break
else:
print('Player 1 won the game')
winner = True
print(draw_board(board, size))
break
print(
'Player 2 turn: ',
'Please mark a spot in the board: '
)
player2_move = int(input('> '))
while spot_taken(board, player2_move):
print(
'Player 2:',
'Spot taken already, please chose a different one'
)
player2_move = int(input('> '))
else:
board = place_symbol_in_to_position(
board,
player2,
player2_move
)
if not three_in_a_row(
make_win_combiantions(board, size),
player2,
size
):
if not full_board(board):
print(draw_board(board, size))
else:
print(
'Board full, No winner',
draw_board(board, size),
sep='\n'
)
break
else:
print('Player 2 won the game')
winner = True
print(draw_board(board, size))
break
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment