def reset_game(self): """ Resets the game to initial state. """ self.game = Game(self.game_name, observed=True, num_players=self.num_players, num_turns=self.num_turns, map_name=self.map_name) self.players = {} self.current_turn = 0 self.current_action = 0
def reset_game(self): """ Resets the game to initial state. """ self._game = Game(self._game_name, self._map_name, num_players=self.num_players, observed=True) for action in self._actions: if action['code'] == Action.LOGIN: data = json.loads(action['message']) self._game.add_player(Player.create(data['name'])) self._current_turn = 0 self._current_action = 0
def on_login(self, data: dict): if self.game is not None or self.player is not None: raise errors.BadCommand('You are already logged in') self.check_keys(data, ['name']) player_name = data['name'] password = data.get('password', None) player = Player.get(player_name, password=password) if not player.check_password(password): raise errors.AccessDenied('Password mismatch') game_name = data.get('game', 'Game of {}'.format(player_name)) num_players = data.get('num_players', CONFIG.DEFAULT_NUM_PLAYERS) num_turns = data.get('num_turns', CONFIG.DEFAULT_NUM_TURNS) game = Game.get(game_name, num_players=num_players, num_turns=num_turns) game.check_state(GameState.INIT, GameState.RUN) player = game.add_player(player) self.game = game self.game_idx = game.game_idx self.player = player log.info('Player successfully logged in: {}'.format(player), game=self.game) message = self.player.to_json_str() return Result.OKEY, message
def run_server(_, address=CONFIG.SERVER_ADDR, port=CONFIG.SERVER_PORT, log_level='INFO'): """ Launches 'WG Forge' TCP server. """ log.setLevel(log_level) ThreadingTCPServer.allow_reuse_address = True server = ThreadingTCPServer((address, port), GameServerRequestHandler) log.info('Serving on {}'.format(server.socket.getsockname())) try: server.serve_forever() except KeyboardInterrupt: log.warn('Server stopped by keyboard interrupt, shutting down...') finally: try: GameServerRequestHandler.shutdown_all_sockets() Game.stop_all_games() if log.is_queued: log.stop() finally: server.shutdown() server.server_close()
class Observer(object): """ Observer entity. """ PLAYER_NAME = '-=Observer=-' def __init__(self): self._db = DbReplay() self._game = None self._actions = [] self._map_name = None self._game_name = None self._current_turn = 0 self._current_action = 0 self._max_turn = 0 self.num_players = 0 def games(self): """ Retrieves list of games. """ return self._db.get_all_games() def reset_game(self): """ Resets the game to initial state. """ self._game = Game(self._game_name, self._map_name, num_players=self.num_players, observed=True) for action in self._actions: if action['code'] == Action.LOGIN: data = json.loads(action['message']) self._game.add_player(Player.create(data['name'])) self._current_turn = 0 self._current_action = 0 def action(self, action, data): """ Interprets observer's actions. """ if action in self.COMMAND_MAP: method = self.COMMAND_MAP[action] return method(self, data) return Result.BAD_COMMAND, None def _on_get_map(self, data): if self._game is None: return Result.RESOURCE_NOT_FOUND, None if 'layer' in data: player = None layer = data['layer'] return Result.OKEY, self._game.get_map_layer(player, layer) return Result.BAD_COMMAND, None def game_turn(self, turns): """ Plays game turns. """ assert turns > 0 sub_turn = 0 for action in self._actions[self._current_action:]: self._current_action += 1 if action['code'] == Action.MOVE: player = None data = json.loads(action['message']) self._game.move_train(player, data['train_idx'], data['speed'], data['line_idx']) elif action['code'] == Action.TURN: self._game.tick() sub_turn += 1 self._current_turn += 1 if sub_turn >= turns: break def _on_turn(self, data): if self._game is None: return Result.BAD_COMMAND, None if not self._actions: return Result.RESOURCE_NOT_FOUND, None if 'idx' not in data: return Result.BAD_COMMAND, None turn = data['idx'] if turn < 0: turn = 0 elif turn > self._max_turn: turn = self._max_turn if turn == self._current_turn: return Result.OKEY, None delta_turn = turn - self._current_turn if delta_turn > 0: self.game_turn(delta_turn) elif delta_turn < 0: self.reset_game() if turn > 0: self.game_turn(turn) self._current_turn = turn return Result.OKEY, None def _on_game(self, data): if 'idx' not in data: return Result.BAD_COMMAND, None self._game = None game_id = data['idx'] for game in self._db.get_all_games(): if game['idx'] == game_id: game_name = game['name'] self._game_name = game_name self.num_players = game['num_players'] self._map_name = game['map'] log(log.INFO, "Observer selected game: {}".format(game_name)) self._actions = self._db.get_all_actions(game_id) self.reset_game() self._max_turn = game['length'] break if self._game is None: return Result.RESOURCE_NOT_FOUND, None return Result.OKEY, None def _on_observer(self, _): return Result.OKEY, json.dumps(self.games()) COMMAND_MAP = { Action.MAP: _on_get_map, Action.TURN: _on_turn, Action.GAME: _on_game, Action.OBSERVER: _on_observer, }
def __init__(self, argv): self.db = None self.game = Game(argv[1])
def on_list_games(self, _): games = Serializable() games.set_attributes(games=Game.get_all_active_games()) return Result.OKEY, games.to_json_str()
class Observer(object): def __init__(self): self.game = None self.actions = [] self.players = {} self.map_name = None self.game_name = None self.current_turn = 0 self.current_action = 0 self.max_turn = 0 self.num_players = 0 self.num_turns = 0 @staticmethod def check_keys(data: dict, keys, agg_func=all): if not agg_func([k in data for k in keys]): raise errors.BadCommand( 'The command\'s payload does not contain all needed keys, ' 'following keys are expected: {}'.format(keys)) else: return True def games_to_json_str(self): """ Retrieves list of games. """ games_list = [] for game_data, game_length in game_db.get_all_games(): game = { 'idx': game_data.id, 'name': game_data.name, 'created_at': game_data.created_at.strftime(CONFIG.TIME_FORMAT), 'map_idx': game_data.map_id, 'length': game_length, 'num_players': game_data.num_players, 'data': game_data.data, } games_list.append(game) games = Serializable() games.set_attributes(games=games_list) return games.to_json_str() def reset_game(self): """ Resets the game to initial state. """ self.game = Game(self.game_name, observed=True, num_players=self.num_players, num_turns=self.num_turns, map_name=self.map_name) self.players = {} self.current_turn = 0 self.current_action = 0 def action(self, action, data): """ Interprets observer's actions. """ if action not in self.ACTION_MAP: raise errors.BadCommand('No such action: {}'.format(action)) method = self.ACTION_MAP[action] return method(self, data) @game_required def on_get_map(self, data): """ Returns specified game map layer. """ self.check_keys(data, ['layer']) message = self.game.get_map_layer(None, data['layer']) return Result.OKEY, message def game_turn(self, turns): """ Plays game turns. """ sub_turn = 0 events_map = { EventType.HIJACKERS_ASSAULT: (self.game.make_hijackers_assault, 'hijackers_power'), EventType.PARASITES_ASSAULT: (self.game.make_parasites_assault, 'parasites_power'), EventType.REFUGEES_ARRIVAL: (self.game.make_refugees_arrival, 'refugees_number'), } for action in self.actions[self.current_action:]: self.current_action += 1 code = action.code message = action.message player_idx = action.player_id player = self.players.get(player_idx, None) if code == Action.LOGIN: player = Player(message['name'], password=message.get('password', None)) player.idx = player_idx self.players[player_idx] = player self.game.add_player(player) elif code == Action.MOVE: self.game.move_train(player, message['train_idx'], message['speed'], message['line_idx']) elif code == Action.UPGRADE: self.game.make_upgrade(player, posts_idx=message.get('posts', []), trains_idx=message.get('trains', [])) elif code == Action.TURN: self.game.tick() sub_turn += 1 self.current_turn += 1 elif code == Action.EVENT: event, power_attr = events_map[message['type']] event(message[power_attr]) elif code == Action.LOGOUT: self.game.remove_player(player) else: log.error('Unknown action code: {}'.format(code)) if sub_turn >= turns: break @game_required def on_turn(self, data): """ Sets specified game turn. """ self.check_keys(data, ['idx']) turn = data['idx'] turn = min(max(turn, 0), self.max_turn) if turn == self.current_turn: return Result.OKEY, None delta_turn = turn - self.current_turn if delta_turn > 0: self.game_turn(delta_turn) elif delta_turn < 0: self.reset_game() if turn > 0: self.game_turn(turn) self.current_turn = turn return Result.OKEY, None def on_game(self, data): """ Chooses a game. """ self.check_keys(data, ['idx']) game_idx = data['idx'] game = game_db.get_game(game_idx) if game is None: raise errors.ResourceNotFound( 'Game index not found, index: {}'.format(game_idx)) game, game_length = game game_map = map_db.get_map_by_id(game.map_id) self.game = None self.game_name = game.name self.num_players = game.num_players self.num_turns = game.num_turns self.map_name = game_map.name self.actions = game_db.get_all_actions(game_idx) self.max_turn = game_length self.reset_game() log.info('Observer selected game: {}'.format(self.game_name)) return Result.OKEY, None def on_observer(self, _): """ Returns list of games. """ message = self.games_to_json_str() return Result.OKEY, message ACTION_MAP = { Action.MAP: on_get_map, Action.TURN: on_turn, Action.GAME: on_game, Action.OBSERVER: on_observer, }