'''An object-oriented game of Tic Tac Toe.''' EMPTY = " " # marker for an empty square SIZE = 3 # size of the game board DASHES = 7 * '-' # used in printing class TicTacToe: '''A text-based game of Tic-Tac-Toe''' def __init__(self): '''Initialize the game board.''' self.board = [] for row_num in range(SIZE): board_row = [] for col_num in range(SIZE): board_row.append(EMPTY) self.board.append(board_row) self.winner = None # who has won the game self.empty_squares = SIZE * SIZE # number of empty squares left def __str__(self): '''Draw the game board.''' board_str = DASHES + "\n" for row in self.board: board_str += "|" for marker in row: board_str += marker + "|" board_str += "\n" + DASHES + "\n" return board_str def read_move(self): '''Read in a move as x,y''' valid_move = False while not valid_move: input_str = input('Enter a move r, c: ') try: (play_x, play_y) = input_str.split(',') play_x = int(play_x) - 1 play_y = int(play_y) - 1 if play_x >= 0 and play_y >= 0 and self.board[play_x][play_y] == EMPTY: valid_move = True else: print("Invalid move, try again") except: print("Invalid move, try again") return (play_x, play_y) def make_play(self, player, row_num, col_num): '''Set the given square at (row, col) to the given player's marker.''' if self.board[row_num][col_num] != EMPTY: self.empty_squares -= 1 self.board[row_num][col_num] = player.marker def game_over(self, last_player, row_played, col_played): '''Given the last player to play and where they played, returns whether the game is over and sets self.winner if the player has won.''' if last_player == None: # ignore on the first check return False if self.empty_squares == 0: # all squares played return True marker = last_player.marker # check the row through row_played win = True for col in range(SIZE): if self.board[row_played][col] != marker: win = False break if win: self.winner = last_player return True # check the col through col_played win = True for row in range(SIZE): if self.board[row][col_played] != marker: win = False break if win: self.winner = last_player return True # right diag win = True for i in range(SIZE): if self.board[i][i] != marker: win = False break if win: self.winner = last_player return True # left diag win = True for i in range(SIZE): if self.board[i][SIZE - 1 - i] != marker: win = False break if win: self.winner = last_player return True # otherwise, not a win return False class Player: '''A player of the game represented as a name and a marker.''' def __init__(self, name, marker): self.name = name self.marker = marker def __str__(self): return self.name + " (" + self.marker + ")" def main(): '''Run a game of tic tac toe.''' ttt = TicTacToe() player1 = Player('Alice', 'A') player2 = Player('Bob', 'B') cur_player = None play_x = None play_y = None while not ttt.game_over(cur_player, play_x, play_y): print(ttt) if cur_player == player1: cur_player = player2 else: cur_player = player1 print(str(cur_player) + "'s move") (play_x, play_y) = ttt.read_move() ttt.make_play(cur_player, play_x, play_y) print(ttt) if ttt.winner == None: print("No winner!") else: print(ttt.winner, "wins!") main()