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))
Beispiel #3
0
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