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()
def __init__(self, board_id): super(BoardGameMaster, self).__init__() self.board_id = board_id self.players = [] self.status = ReversiStatus() self.board = ReversiBoard()
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')
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, ])
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, ])
def test_able_to_put(self): board = ReversiBoard() board.put_piece(26, 2) result = board.able_to_put(1) assert len(result) == 3