def endgame(self): if self._state == GameStateEnum.LOST: for player in self.players: with open(PROFILES, mode='r+', encoding='utf-8') as file: temp = json.load(file) file.seek(0) file.truncate() for user in temp: if user['_nickname'] == player.nickname: losses = user['_losses'] user['_losses'] = losses + 1 json.dump(temp, file) player.status = PlayerStatusEnum.NOT_READY EventQueue.block() EventQueue.post(CustomEvent(ChangeSceneEnum.LOSESCENE)) else: for player in self.players: with open(PROFILES, mode='r+', encoding='utf-8') as file: temp = json.load(file) file.seek(0) file.truncate() for user in temp: if user['_nickname'] == player.nickname: wins = user['_wins'] user['_wins'] = wins + 1 json.dump(temp, file) player.status = PlayerStatusEnum.NOT_READY EventQueue.block() EventQueue.post(CustomEvent(ChangeSceneEnum.WINSCENE))
def go_back(): if Networking.get_instance().is_host: next_scene = ChangeSceneEnum.SETMAXPLAYERSCENE else: next_scene = ChangeSceneEnum.JOINSCENE Networking.get_instance().disconnect() EventQueue.post(CustomEvent(next_scene))
def execute(self): logger.info( f"Player {self._source.nickname} is asking you for command permission" ) EventQueue.post( CustomEvent(CustomEventEnum.PERMISSION_PROMPT, source=self._source, target=self._target))
def callback_disconnect(): """ Define callback here when client's connection to host is interrupted. :return: """ # if Networking.get_instance().is_host: logger.warning("It seems that client is not connected...") Networking.get_instance().disconnect() EventQueue.post(CustomEvent(ChangeSceneEnum.DISCONNECT))
def load_game(self, save): """Instantiate a new family game and move to the lobby scene.""" data = save # Restore game metadata game: GameStateModel = JSONSerializer.deserialize(data) game.host = self._current_player game.players = [self._current_player] game._players_turn_index = 0 # Restore GameBoard GameStateModel.set_game(game) game.game_board.is_loaded = True Networking.get_instance().create_host() EventQueue.post(CustomEvent(ChangeSceneEnum.LOBBYSCENE))
def confirm(self): if self.character_enum: accept = True # This is a boolean flag if any([player.role == self.character_enum for player in self._game.players]): accept = False if accept: # means no one took this character EventQueue.post(CustomEvent(ChangeSceneEnum.LOBBYSCENE)) event = ChooseCharacterEvent(self.character_enum, self._game.players.index(self._current_player)) if Networking.get_instance().is_host: Networking.get_instance().send_to_all_client(event) else: Networking.get_instance().send_to_server(event)
def join(self): """ Start the join host process in Networking :param ip_addr: ip address to connect :param next_scene: next scene to be called after the process completes :param args: extra arguments for the next scene :return: """ ip_addr = self.text_bar_msg try: self._current_player.status = PlayerStatusEnum.NOT_READY Networking.get_instance().join_host(ip_addr, player=self._current_player) reply = Networking.wait_for_reply() # Connection error will be raised if no reply if reply: reply = JSONSerializer.deserialize(reply) if isinstance(reply, TooManyPlayersEvent): raise TooManyPlayersException(self._current_player) # GameStateModel.set_game(JSONSerializer.deserialize(reply)) EventQueue.post(CustomEvent(ChangeSceneEnum.LOBBYSCENE)) except TimeoutError: msg = "Host not found." print(msg) self.init_error_message(msg) except TooManyPlayersException: msg = "Lobby is full. Cannot join the game." print(msg) self.init_error_message(msg) # Disconnect client that's trying to connect if not Networking.get_instance().is_host: Networking.get_instance().client.disconnect() except Networking.Client.SocketError: msg = "Failed to establish connection." print(msg) self.init_error_message(msg) except OSError: msg = "Invalid IP address" print(msg) self.init_error_message(msg)
def dodge(self, player: PlayerModel) -> bool: """ Determines whether the player can dodge (out of turn) to avoid being knocked down and performs dodge. Returns False otherwise. :param player: player that is attempting to dodge :return: True if the player is able to dodge, False otherwise """ logger.info("Attempting to dodge...") # Doge cannot dodge if player.role == PlayerRoleEnum.DOGE: self._log_player_dodge(1, player) return False if not self._valid_to_dodge(player): self._log_player_dodge(1, player) return False player_tile = self.game_state.game_board.get_tile_at( player.row, player.column) possible_dodge_target = NullModel() for dirn, nb_tile in player_tile.adjacent_tiles.items(): if isinstance(nb_tile, TileModel): has_obstacle = player_tile.has_obstacle_in_direction(dirn) obstacle = player_tile.get_obstacle_in_direction(dirn) is_open_door = isinstance( obstacle, DoorModel) and obstacle.door_status == DoorStatusEnum.OPEN if not has_obstacle or is_open_door: if nb_tile.space_status != SpaceStatusEnum.FIRE: possible_dodge_target = nb_tile break # If we couldn't find a potential space # to dodge, the player cannot avoid being # knocked down. if isinstance(possible_dodge_target, NullModel): self._log_player_dodge(1, player) return False # Pause the current event and ask player to dodge: EventQueue.post(CustomEvent(CustomEventEnum.DODGE_PROMPT, player)) logger.info( f"Thread {threading.current_thread().getName()} going to sleep") # Go to sleep switch.pause_event.clear() switch.pause_event.wait() logger.info(f"Thread {threading.current_thread().getName()} woke up") if not GameStateModel.instance().dodge_reply: logger.info("Reply was no, knocking player down") return False logger.info("Reply was yes, attempting to dodge...") GameStateModel.instance().dodge_reply = False # Disassociate the victim/hazmat that the player # may be carrying since they cannot dodge with them player_victim = player.carrying_victim player_hazmat = player.carrying_hazmat is_carrying_victim = isinstance(player_victim, VictimModel) is_carrying_hazmat = isinstance(player_hazmat, HazmatModel) if is_carrying_victim: self._log_player_dodge(2, player, player_victim, player_tile) player_tile.add_associated_model(player_victim) player.carrying_victim = NullModel() if is_carrying_hazmat: self._log_player_dodge(2, player, player_hazmat, player_tile) player_tile.add_associated_model(player_hazmat) player.carrying_hazmat = NullModel() self._log_player_dodge(3, player) player.set_pos(possible_dodge_target.row, possible_dodge_target.column) # Costs 1 AP for Veteran to dodge # and 2 AP for the rest of the roles if player.role == PlayerRoleEnum.VETERAN: player.ap = player.ap - 1 else: player.ap = player.ap - 2 return True
def _continue(self): Networking.get_instance().disconnect() EventQueue.post(CustomEvent(ChangeSceneEnum.STARTSCENE))
def create_new_game(self, game_kind: GameKindEnum, difficulty_level: DifficultyLevelEnum = None): """Instantiate a new family game and move to the lobby scene.""" GameStateModel(self._current_player, 6, game_kind, GameBoardTypeEnum.ORIGINAL, difficulty_level) EventQueue.post(CustomEvent(ChangeSceneEnum.CHOOSEBOARDSCENE))
def _disconnect_and_back(): Networking.get_instance().disconnect() EventQueue.post(CustomEvent(ChangeSceneEnum.HOSTMENUSCENE))
def set_and_continue(desired_players: int): GameStateModel.instance().max_players = desired_players Networking.get_instance().create_host() EventQueue.post(CustomEvent(ChangeSceneEnum.LOBBYSCENE))
def countdown(self): EventQueue.post(CustomEvent(CustomEventEnum.ENABLE_KNOCKDOWN_PROMPT, self.player.nickname)) time.sleep(5) EventQueue.post(CustomEvent(CustomEventEnum.DISABLE_KNOCKDOWN_PROMPT))
def set_and_continue(board_type: GameBoardTypeEnum): GameStateModel.instance().board_type = board_type EventQueue.post(CustomEvent(ChangeSceneEnum.SETMAXPLAYERSCENE))
def execute(self): logging.info("Executing StartGameEvent.") GameStateModel.instance().state = GameStateEnum.PLACING_PLAYERS EventQueue.block() EventQueue.post(CustomEvent(ChangeSceneEnum.GAMEBOARDSCENE))
def countdown(self): EventQueue.post(CustomEvent( CustomEventEnum.ENABLE_VICTIM_SAVED_PROMPT)) time.sleep(5) EventQueue.post( CustomEvent(CustomEventEnum.DISABLE_VICTIM_SAVED_PROMPT))
def execute(self, *args, **kwargs): logger.info(f"Host has disconnected") EventQueue.post(CustomEvent(ChangeSceneEnum.DISCONNECT))