示例#1
0
 def test_export(self):
     board = ReversiBoard()
     data = board.export_board()
     init_data = [
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 1, 2, 0, 0, 0],
         [0, 0, 0, 2, 1, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
         [0, 0, 0, 0, 0, 0, 0, 0],
     ]
     assert data == init_data
 def __init__(self, board_id, access_token, user_id):
     self.board_id = board_id
     self.access_token = access_token
     self.user_id = user_id
     self.turn = None
     self.v_board = ReversiBoard()
     ws = websocket.WebSocketApp(
         f"ws://localhost:8000/v1/board/{self.board_id}/ws",
         header=[f"Authorization: Bearer {self.access_token}"],
         on_open=self.on_open,
         on_message=self.on_message,
         on_error=self.on_error,
         on_close=self.on_close,
     )
     try:
         ws.run_forever()
     except KeyboardInterrupt:
         ws.close()
示例#3
0
 def __init__(self, board_id):
     super(BoardGameMaster, self).__init__()
     self.board_id = board_id
     self.players = []
     self.status = ReversiStatus()
     self.board = ReversiBoard()
示例#4
0
class BoardGameMaster(object):
    """docstring for BoardGameMaster"""

    def __init__(self, board_id):
        super(BoardGameMaster, self).__init__()
        self.board_id = board_id
        self.players = []
        self.status = ReversiStatus()
        self.board = ReversiBoard()

    def add_player(self, player):
        if len(self.players) < 2:
            duplicated = False

            for p in self.players:
                if not duplicated:
                    duplicated = player['user'] == p['user']

            if not duplicated:
                self.players.append(player)
                if len(self.players) == 2:
                    self.game_start()
                data_message = json.dumps(
                    self.extract_data(), sort_keys=True, ensure_ascii=False)
                self.send_all(data_message)
                return True
            else:
                print('this user is already entered this board')
        else:
            print(f'{self.board_id} is already full')
        return False

    def remove_player(self, player_ws):
        _p = None
        for p in self.players:
            if player_ws == p['ws']:
                _p = p
        if _p in self.players:
            self.players.remove(_p)

    def send_all(self, message):
        for p in self.players:
            p['ws'].write_message(message)

    def extract_data(self, status=True):
        user_data = {
            'first': {
                'id': self.players[0]['user'].id,
            } if len(self.players) >= 1 else None,
            'second': {
                'id': self.players[1]['user'].id,
            } if len(self.players) >= 2 else None,
        }

        meta_data = {
            'status': 200 if status else 400
        }
        game_data = {
            'users': user_data,
            'board': self.board.export_board(),
            **self.status.export_status(),
        }

        if self.status.finished:
            score1 = (self.board.board == 1).sum()
            score2 = (self.board.board == 2).sum()
            game_data['result'] = {
                'win': 'player1' if score1 > score2 else 'player2',
                'lose': 'player1' if score1 < score2 else 'player2',
                'draw': True if score1 == score2 else False,
            }

        data = {
            "meta": meta_data,
            "data": game_data,
        }

        return data

    def game_start(self):
        self.status.start()

    def pass_check(self, count=0):
        print("passing", count)
        if count == 2:
            self.finish()
        else:
            putable = self.board.able_to_put(self.status.turn)
            print(self.status.turn, "putable", putable)
            if len(putable) == 0:  # どこにも置けなかったら
                print(self.status.turn, "has passed!")
                self.status.progress_turn()
                self.pass_check(count + 1)
        print()

    def finish(self):
        self.status.finish()
        print("finished")

    def receive_move(self, user, x, y):
        ind = None
        for i, p in enumerate(self.players):
            if p['user'] == user:
                ind = i + 1
        place = x + y * 8
        reverse_num = 0

        try:
            reverse_num = self.board.put_piece(place, ind)
            self.status.progress_turn()
            if self.pass_check():
                pass
        except Exception as e:
            if isinstance(e, AssertionError):
                print("invalid move")
            else:
                raise e

        send_data = self.extract_data(bool(reverse_num))
        send_data['data']['move'] = {
            'x': x,
            'y': y,
            'correct': bool(reverse_num),
        }

        data_message = json.dumps(
            send_data, sort_keys=True, ensure_ascii=False)
        self.send_all(data_message)
        if self.status.finished:
            self.close_board()
        return bool(reverse_num)

    def close_board(self):
        for p in self.players:
            p['ws'].close(code=1000, reason="board no.[{board_id}] is closed")
class SampleReversiBot(object):
    def __init__(self, board_id, access_token, user_id):
        self.board_id = board_id
        self.access_token = access_token
        self.user_id = user_id
        self.turn = None
        self.v_board = ReversiBoard()
        ws = websocket.WebSocketApp(
            f"ws://localhost:8000/v1/board/{self.board_id}/ws",
            header=[f"Authorization: Bearer {self.access_token}"],
            on_open=self.on_open,
            on_message=self.on_message,
            on_error=self.on_error,
            on_close=self.on_close,
        )
        try:
            ws.run_forever()
        except KeyboardInterrupt:
            ws.close()

    def print_board(self, board):
        print("  0 1 2 3 4 5 6 7")
        for i, bo in enumerate(board):
            print(str(i) + " " + " ".join([".*o"[b] for b in bo]))

    def get_board(self, board):
        for i, bo in enumerate(board):
            self.v_board.board[i * 8:(i + 1) * 8] = bo

    def move(self, ws, board):
        print(".*o"[self.turn])

        places = self.v_board.able_to_put(self.turn)

        place = random.choice(places)

        y, x = divmod(place, 8)

        message = json.dumps({'x': x, 'y': y})
        ws.send(message)

    def handler(self, ws, data):
        print(data)
        self.print_board(data['data']['board'])
        self.get_board(data['data']['board'])
        if data.get('data'):
            if data['data']['users']['first']['id'] == self.user_id:
                self.turn = 1
            elif data['data']['users']['second']['id'] == self.user_id:
                self.turn = 2
            if data['data']['started'] and not data['data']['finished']:
                print("my turn", self.turn, ": now turn", data['data']['turn'])
                if self.turn == data['data']['turn']:
                    self.move(ws, data['data']['board'])

    def on_message(self, ws, message):
        data = json.loads(message)
        self.handler(ws, data)

    def on_error(self, ws, error):
        print(error)

    def on_close(self, ws):
        if self.v_board:
            score1 = (self.v_board.board == 1).sum()
            score2 = (self.v_board.board == 2).sum()
            print(f"{score1} - {score2}")
            if score1 > score2:
                print(f'You {"win" if self.turn == 1 else "lose"}')
            elif score1 < score2:
                print(f'You {"lose" if self.turn == 1 else "win"}')
            elif score1 == score2:
                print("draw")

        print('disconnected streaming server')

    def on_open(self, ws):
        print('connected streaming server')
示例#6
0
    def test_invalid_moves(self):
        board = ReversiBoard()
        with pytest.raises(Exception):
            board.put_piece(1, 1)

        with pytest.raises(Exception):
            board.put_piece(1, 2)

        assert all(board.board == [
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            1,
            2,
            0,
            0,
            0,
            0,
            0,
            0,
            2,
            1,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
            0,
        ])
示例#7
0
 def test_valid_moves(self):
     board = ReversiBoard()
     result = board.put_piece(26, 2)
     assert result == 1
     result = board.put_piece(18, 1)
     assert result == 1
     assert all(board.board == [
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         2,
         1,
         2,
         0,
         0,
         0,
         0,
         0,
         0,
         2,
         1,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
         0,
     ])
示例#8
0
 def test_able_to_put(self):
     board = ReversiBoard()
     board.put_piece(26, 2)
     result = board.able_to_put(1)
     assert len(result) == 3