class TicTacToeUserHandler(UserHandler): def __init__(self, send_message: Callable[[str], None]) -> None: super(TicTacToeUserHandler, self).__init__(send_message) self.game: Optional[TicTacToe] = None def handle_message(self, message: str) -> None: command = message.rstrip('\n') if command == 'start': self.start_game() return if not self.game: self.send_message('Game is not started') return name, col, row = command.rstrip('\n').split(maxsplit=2) if name == 'O': self.make_turn(player=Player.O, row=int(row), col=int(col)) elif name == 'X': self.make_turn(player=Player.X, row=int(row), col=int(col)) def start_game(self) -> None: self.game = None self.game = TicTacToe() self.send_field() def make_turn(self, player: Player, *, row: int, col: int) -> None: assert self.game if not self.game.can_make_turn(player, row=row, col=col): self.send_message('Invalid turn') return else: self.game.make_turn(player, row=row, col=col) self.send_field() if self.game.is_finished(): if self.game.current_player() == Player.X: self.send_message('Game is finished, O wins') elif self.game.current_player() == Player.O: self.send_message('Game is finished, X wins') else: self.send_message('Game is finished, draw') self.game = None def send_field(self) -> None: assert self.game field_print = '' for column in self.game.field: for row in column: if row: field_print += row.name else: field_print += '.' field_print += '\n' self.send_message(field_print.rstrip('\n'))
class TicTacToeUserHandler(UserHandler): def __init__(self, send_message: Callable[[str], None]) -> None: super(TicTacToeUserHandler, self).__init__(send_message) self.game: Optional[TicTacToe] = None def handle_message(self, message: str) -> None: if message == 'start': self.start_game() elif not self.game: self.send_message('Game is not started') else: mark, col, row = message.split() player = {'X': Player.X, 'O': Player.O}.get(mark) if mark != 'X' and mark != 'O': self.send_message('Invalid turn') else: assert player self.make_turn(player, row=int(row), col=int(col)) def start_game(self) -> None: self.game = TicTacToe() self.send_field() def make_turn(self, player: Player, *, row: int, col: int) -> None: assert self.game if not self.game.can_make_turn(player, row=row, col=col): self.send_message('Invalid turn') else: self.game.make_turn(player, row=row, col=col) self.send_field() if self.game.is_finished(): self.send_message( 'Game is finished, {}'.format({None: 'draw', Player.X: 'X wins', Player.O: 'O wins'}.get(self.game.winner()))) self.game = None def send_field(self) -> None: assert self.game field = [] for row in self.game.field: field.append(''.join([col.name if col else '.' for col in row])) self.send_message('\n'.join(field))
def test_game_draw() -> None: game = TicTacToe() assert not game.is_finished() assert game.winner() is None assert game.current_player() == Player.X assert game.can_make_turn(Player.X, col=0, row=0) assert not game.can_make_turn(Player.O, col=0, row=0) game.make_turn(Player.X, col=0, row=0) assert not game.is_finished() assert game.winner() is None assert not game.can_make_turn(Player.X, col=0, row=0) assert not game.can_make_turn(Player.O, col=0, row=0) assert game.current_player() == Player.O assert not game.can_make_turn(Player.X, col=1, row=0) assert game.can_make_turn(Player.O, col=1, row=0) game.make_turn(Player.O, col=1, row=0) assert not game.is_finished() assert game.winner() is None assert not game.can_make_turn(Player.X, col=0, row=0) assert not game.can_make_turn(Player.O, col=0, row=0) assert not game.can_make_turn(Player.X, col=1, row=0) assert not game.can_make_turn(Player.O, col=1, row=0) assert game.current_player() == Player.X assert game.can_make_turn(Player.X, col=2, row=0) assert not game.can_make_turn(Player.O, col=2, row=0) game.make_turn(Player.X, col=2, row=0) assert not game.is_finished() assert game.winner() is None # XOX # ... # ... assert game.current_player() == Player.O assert game.can_make_turn(Player.O, col=0, row=1) game.make_turn(Player.O, col=0, row=1) assert not game.is_finished() assert game.winner() is None # XOX # O.. # ... assert game.current_player() == Player.X assert game.can_make_turn(Player.X, col=2, row=1) game.make_turn(Player.X, col=2, row=1) assert not game.is_finished() assert game.winner() is None # XOX # O.X # ... assert game.current_player() == Player.O assert game.can_make_turn(Player.O, col=1, row=1) game.make_turn(Player.O, col=1, row=1) assert not game.is_finished() assert game.winner() is None # XOX # OOX # ... assert game.current_player() == Player.X assert game.can_make_turn(Player.X, col=1, row=2) game.make_turn(Player.X, col=1, row=2) assert not game.is_finished() assert game.winner() is None # XOX # OOX # .X. assert game.current_player() == Player.O assert game.can_make_turn(Player.O, col=2, row=2) game.make_turn(Player.O, col=2, row=2) assert not game.is_finished() assert game.winner() is None # XOX # OOX # .XO assert game.current_player() == Player.X assert game.can_make_turn(Player.X, col=0, row=2) game.make_turn(Player.X, col=0, row=2) # XOX # OOX # XXO assert game.is_finished() assert game.winner() is None assert game.current_player() is None