Skip to content

Instantly share code, notes, and snippets.

@sequentialchaos
Created April 19, 2019 15:41
Show Gist options
  • Save sequentialchaos/fac7cb3c3720c15672355bc3226659a1 to your computer and use it in GitHub Desktop.
Save sequentialchaos/fac7cb3c3720c15672355bc3226659a1 to your computer and use it in GitHub Desktop.
Tic Tac Toe game in Python
import re
class TicTacToe:
def __init__(self, n=3):
self.n = n
self.board = [
['_' for col in range(n)]
for row in range(n)
]
self.teams = ['X', 'O']
self.winner = ' '
def __str__(self):
return '\n'.join([
' ' + '|'.join(row) for row in self.board
])
def play(self):
"""Begins the game."""
i = 0
print('Tic Tac Toe!')
while (not self.has_winner()) and (not self.is_filled()):
print('-------------')
print(self)
team = self.teams[i % 2]
row, col = self.get_move(team)
self.make_move(team, row, col)
i += 1
print('-------------')
print(self)
if self.has_winner():
print('Team {0} has won!'.format(self.winner))
else:
print('It is a draw!')
def get_move(self, team):
"""Retrieves move from user."""
move = ''
while not self.is_valid(move):
move = raw_input("{0}'s turn: ".format(team))
return self.parse_move(move)
def is_valid(self, move):
"""Returns True if move is valid, False otherwise."""
pattern = re.compile('^\d+,\d+$')
if pattern.match(str(move)):
row, col = self.parse_move(move)
if (0 <= row < self.n) and (0 <= col < self.n):
# move is valid if its spot on the board is blank
return self.board[row][col] == '_'
else:
return False
def parse_move(self, move):
"""Parses move into a (row, col) after it has been validated"""
coordinates = [int(n) for n in move.split(',')]
return coordinates[0], coordinates[1]
def make_move(self, team, row, col):
"""Places the given team's symbol at (row, col)"""
self.board[row][col] = team
self.check(team, row, col)
def check(self, team, row, col):
"""Checks the row, column, and diagonals of the cell at (row, col)
to see if their cells are each the same as the given team."""
# row
if all([cell == team for cell in self.board[row]]):
self.winner = team
# column
if all([self.board[i][col] == team for i in range(self.n)]):
self.winner = team
# diagonal A: top-left to bottom-right
if row == col:
if all([self.board[i][j] == team for i, j in enumerate(range(self.n))]):
self.winner = team
# diagonal B: top-right to bottom-left
if row == self.n - col - 1:
if all([self.board[i][self.n - j - 1] == team for i, j in enumerate(range(self.n))]):
self.winner = team
def is_filled(self):
"""Returns True if no cell on the board is blank, False otherwise."""
for row in self.board:
for cell in row:
if cell == '_':
return False
return True
def has_winner(self):
"""Returns True if a winner has been determined, False otherwise"""
return self.winner in self.teams
tictactoe = TicTacToe()
tictactoe.play()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment