I programmed the tic-tac-toe game in Python using object oriented programming and I wanted to share it here to get some feedback
class TicTacToe:
def __init__(self):
self.board = [" "] * 9
self.spacer = "-" * 50
@property
def _select_letter(self):
computer_side = None
player_side = None
while True:
player_side = input("Choose your side: ").upper()
if player_side not in ("X", "O"):
print("You can only choose X or O.")
else:
break
computer_side = "O" if player_side == "X" else "X"
print(f"The computer has chosen to be {computer_side}.")
print(f"You will be {player_side}.")
return player_side, computer_side
@property
def _human_goes_first(self):
go_first = None
while go_first not in ("y", "n"):
go_first = input(("Do you require the first move? (y/n): ")).lower()
return go_first == "y"
@property
def _print_board(self):
return f"{self.board[0]}|{self.board[1]}|{self.board[2]}\n-+-+-\n{self.board[3]}|{self.board[4]}|{self.board[5]}\n-+-+-\n{self.board[6]}|{self.board[7]}|{self.board[8]}"
@property
def _board_full(self):
return not " " in self.board
def _check_win(self, letter):
win_combs = [letter, letter, letter]
return self.board[:3] == win_combs or self.board[3:6] == win_combs or self.board[6:] == win_combs or \
self.board[:7:3] == win_combs or self.board[1:8:3] == win_combs or self.board[2::3] == win_combs or \
self.board[::4] == win_combs or self.board[2:7:2] == win_combs
def _computer_move(self, player_letter, computer_letter):
corners = (2, 4, 6, 8)
# First, check if we can win in the next move.
for i in range(8):
if self.board[i] == " ":
if self._check_win(computer_letter):
self.board[i] = computer_letter
return
# Check if the player could win on their next move, and block them.
for i in range(8):
if self.board[i] == " ":
if self._check_win(player_letter):
self.board[i] = computer_letter
return
# Try to take one of the corners, if they are free.
for i in corners:
if self.board[i] == " ":
self.board[i] = computer_letter
return
# Try to take the center, if it is free.
if self.board[4] == " ":
self.board[4] = computer_letter
return
def _player_move(self, letter):
while True:
try:
move = int(input(f"It's your turn {letter}. Enter a number between 1-9: ")) - 1
if not 0 <= move <= 8:
print("The number entered is invalid. Enter a number between 1 and 9.")
elif self.board[move] != " ":
print("This place is already occupied.")
print(f"\n{self.spacer}\n")
else:
self.board[move] = letter
break
except ValueError:
print(f"Enter a number!\n\n{self.spacer}\n")
def play(self):
print("Welcome to Tic Tac Toe!")
human, computer = self._select_letter
first_player = self._human_goes_first
print(f"\n{self.spacer}")
while not self._board_full:
if first_player:
print(f"\nNow playing: Human ({human})")
self._player_move(human)
else:
print(f"\nNow playing: Computer ({computer})")
self._computer_move(human, computer)
first_player = False if first_player else True
print(f"\n{self._print_board}")
print(f"\n{self.spacer}")
if self._check_win(human):
print("\nYou won!")
print("Thanks for playing!")
break
elif self._check_win(computer):
print("\nComputer won!")
print("Thanks for playing!")
break
else:
print("\nNobody won, it's a tie.")
if __name__ == '__main__':
game = TicTacToe()
game.play()