Skip to content

Instantly share code, notes, and snippets.

@raheelrjunaid
Last active July 5, 2021 02:49
Show Gist options
  • Save raheelrjunaid/925f61a541c872184c7c0497c300031a to your computer and use it in GitHub Desktop.
Save raheelrjunaid/925f61a541c872184c7c0497c300031a to your computer and use it in GitHub Desktop.
# Tic Tac Toe by Raheel Junaid
# Date Finished: July 4th
# Full YouTube Series: https://youtube.com/playlist?list=PL3ZaFz0_yUh4KSXM8qXyPjxr_j5uxcG4E
# This Version is commented
from random import randint
class Game:
def __init__(self) -> None:
self.board = [[None for i in range(3)] for i in range(3)] # Generate empty board
def display_board(self, numbers=None):
# Determine which (if any) numbers to show
# Compact two conditionals in one (pep8 column restriction)
show_numbers_x = True if numbers == 'x' or numbers == 'both' else False
show_numbers_y = True if numbers == 'y' or numbers == 'both' else False
for row_count, row in enumerate(self.board):
# Print line seperator for every row
if row_count != 0:
print(f'\n {"-" * 10}')
for col_count, col in enumerate(row):
# Show the numbers on the left if requested
if col_count == 0 and show_numbers_x:
print(str(row_count + 1), ' ', end="")
elif col_count == 0:
print(' ', end="")
# None values are symbolic, reassign to empty space
col = ' ' if col is None else col
print(col, end="")
# Add a divider between the first two columns
if col_count != 2:
print(" | ", end="")
# The last row should show a new line
if row_count == 2:
if show_numbers_y: # Show properly spaced numbers if requested
print("\n\n 1 2 3", end="")
print('\n')
def place_piece(self, piece, x_pos, y_pos):
self.board[x_pos][y_pos] = piece
# Determine if all elements in a given list are equal
all_equal = lambda iterable: iterable.count(iterable[0]) == len(iterable)
# Return a list of all pieces on the board
def all_pieces(board):
all_pieces = list()
for row in range(3):
for column in range(3):
all_pieces.append(board[row][column])
return all_pieces
# Check whether a certain axis (or diagonal) has the same pieces)
def check_win(board):
# Check for a tie
if all(all_pieces(game.board)):
return 'tie'
# Check all rows
for row in board:
if all_equal(row) and all(row):
return 'win'
# Check all columns
for i in range(3):
column = [board[0][i], board[1][i], board[2][i]]
if all_equal(column) and all(column):
return 'win'
# Check both diagonals
tl_br = [board[0][0], board[1][1], board[2][2]]
tr_bl = [board[0][2], board[1][1], board[2][0]]
for cross in [tl_br, tr_bl]:
if all_equal(cross) and all(cross):
return 'win'
# Return if the game is still playable
return False
def play(piece):
print(f"{piece.upper()}'s turn.")
# O is always computers move
if piece == 'o':
move = computerMove(game.board)
game.place_piece('o', move[0], move[1])
else:
# Accept coordinates for piece placement
game.display_board(numbers='y')
y_pos = int(input("Choose Y Position: ")) - 1
game.display_board(numbers='x')
x_pos = int(input("Choose X Position: ")) - 1
# Ensure the location isn't already occupied
if game.board[x_pos][y_pos] == None:
game.place_piece(piece, x_pos, y_pos)
else:
print("A piece is already there, please try again.")
play(piece)
def computerMove(board):
# Test whether there could be a winner
# Check every unoccupied column
for row_count, row in enumerate(board):
for col_count, column in enumerate(row):
if column == None:
# Toggle between both players to see if someone is going to win
for piece in ['x', 'o']:
board[row_count][col_count] = piece
if check_win(board) == 'win':
# Place a piece in that position if a winner is possible
return row_count, col_count
board[row_count][col_count] = None
# Random Move
random_move = [randint(0, 2), randint(0, 2)]
# Check if the random location is occupied
while board[random_move[0]][random_move[1]] != None:
random_move = [randint(0,2), randint(0, 2)]
return random_move
# Main program (very little error-handling)
game = Game()
while True:
for piece in ['x', 'o']: # Take turns playing the game
play(piece)
result = check_win(game.board)
if result == 'win' or result == 'tie':
game.display_board()
# Print line seperator
print('-' * 20)
if result == 'win':
print(piece.upper(), 'WINS!')
else:
print('Tie')
print('-' * 20)
restart = input('Play again [y/n]? ')
if restart.lower() == 'n':
break
game = Game() # Empty the board
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment