def _is_path_clear(self, tile_model: TileModel, dirn: str) -> bool:
        """
        Determines if there is an obstacle blocking the
        way from the tile in the direction 'dirn'.

        :param tile_model: tile the player is moving from
        :param dirn: direction from tile in which moving
        :return: True if the path from the first tile to
                the second is clear, False otherwise.
        """
        has_obstacle = tile_model.has_obstacle_in_direction(dirn)
        obstacle = tile_model.get_obstacle_in_direction(dirn)
        is_open_door = isinstance(obstacle, DoorModel) and obstacle.door_status == DoorStatusEnum.OPEN
        is_damaged_wall = isinstance(obstacle, WallModel) and obstacle.wall_status == WallStatusEnum.DAMAGED
        is_carrying_victim = isinstance(self.target.carrying_victim, VictimModel)
        # there is a destroyed door or a destroyed wall or no obstacle or an open door or a damaged wall
        if self.current_player.role == PlayerRoleEnum.DOGE:
            if not has_obstacle or is_open_door or is_damaged_wall:
                # The Doge is not allowed to carry a
                # victim through a damaged wall.
                if is_carrying_victim and is_damaged_wall:
                    return False
                else:
                    return True

        # there is a destroyed door or a destroyed wall or no obstacle or an open door
        else:
            if not has_obstacle or is_open_door:
                return True

        return False
Exemple #2
0
    def advance_on_tile(self, target_tile: TileModel) -> bool:
        """
        Advances the fire on the target tile.
        Determines whether a flare up should
        occur or not after this instance of
        Advance Fire is done.

        :param target_tile:
        :return: boolean which tells us if a flare up will occur
        """
        flare_up_will_occur = False
        if target_tile.is_hotspot:
            flare_up_will_occur = True

        tile_status = target_tile.space_status

        # Safe -> Smoke
        if tile_status == SpaceStatusEnum.SAFE:
            target_tile.space_status = SpaceStatusEnum.SMOKE

        # Smoke -> Fire
        elif tile_status == SpaceStatusEnum.SMOKE:
            target_tile.space_status = SpaceStatusEnum.FIRE

        # Fire -> Explosion
        else:
            self.explosion(target_tile)

        return flare_up_will_occur
    def _perform_fire_hotspot_explosion(
            self, tile: TileModel, advance_event: EndTurnAdvanceFireEvent):
        """
        Set the tile on fire, turn hotspot to true and
        cause an explosion on that tile.

        :param tile: Target tile
        :param advance_event: Advance event to access explosion
        :return:
        """
        tile.space_status = SpaceStatusEnum.FIRE
        tile.is_hotspot = True
        advance_event.explosion(tile)
Exemple #4
0
    def explosion(self, origin_tile: TileModel):
        FileImporter.play_music(EXPLOSION_SOUND, 1)
        logger.info(f"Explosion occurred on {origin_tile}")
        game_state = GameStateModel.instance()
        tile_sprite = GameBoard.instance().grid.grid[origin_tile.column][
            origin_tile.row]
        tile_sprite.explosion = True

        for direction, obstacle in origin_tile.adjacent_edge_objects.items():
            # fire does not move to the neighbouring tile
            # damaging wall present along the tile
            if isinstance(
                    obstacle, WallModel
            ) and obstacle.wall_status != WallStatusEnum.DESTROYED:
                obstacle.inflict_damage()
                game_state.damage = game_state.damage + 1

            # fire does not move to the neighbouring tile
            # removing door that borders the tile
            elif isinstance(obstacle, DoorModel):
                obstacle.destroy_door()

            # fire can move to the neighbouring tile
            # if the neighbouring tile is on fire, a shockwave is created
            # else it is just set on fire.
            else:
                nb_tile = origin_tile.get_tile_in_direction(direction)
                if not isinstance(nb_tile, NullModel):
                    if nb_tile.space_status == SpaceStatusEnum.FIRE:
                        self.shockwave(nb_tile, direction)
                    else:
                        nb_tile.space_status = SpaceStatusEnum.FIRE
Exemple #5
0
    def shockwave(self, tile: TileModel, direction: str):
        """
        Send shockwave along a direction.

        :param tile: the tile where the shockwave starts
        :param direction: direction in which shockwave continues
        :return:
        """
        game_state = GameStateModel.instance()
        should_stop = False
        while not should_stop:
            # if there is no obstacle in the given direction -
            #   1. if neighbouring tile is not on fire, set it to fire
            #       and stop the shockwave.
            #   2. else set the current tile to the neighbouring tile
            #       and continue the shockwave.
            if not tile.has_obstacle_in_direction(direction):
                nb_tile: TileModel = tile.get_tile_in_direction(direction)
                if nb_tile.space_status != SpaceStatusEnum.FIRE:
                    nb_tile.space_status = SpaceStatusEnum.FIRE
                    should_stop = True

                else:
                    tile = nb_tile

            # if there is an obstacle in the given direction
            else:
                # 1. if obstacle is a wall, inflict damage on it, increment
                #   game state damage and stop the shockwave.
                # 2. if obstacle is an open door, continue the shockwave
                #   and destroy the door.
                # 3. if obstacle is a closed door, stop the shockwave
                #   and destroy the door.
                obstacle = tile.get_obstacle_in_direction(direction)
                if isinstance(obstacle, WallModel):
                    obstacle.inflict_damage()
                    game_state.damage = game_state.damage + 1
                    should_stop = True

                elif isinstance(obstacle, DoorModel):
                    if obstacle.door_status == DoorStatusEnum.CLOSED:
                        should_stop = True
                    obstacle.destroy_door()

                else:
                    pass
Exemple #6
0
    def _init_all_tiles_board(self, amb_engine_parking_fname: str, outside_doors_fname: str, inside_walls_doors_fname: str) -> List[List[TileModel]]:
        """
        Create all tiles for the board and set their adjacencies.

        :param amb_engine_parking_fname: Name of file that contains details about the ambulance
                                        and engine parking spaces
        :param outside_doors_fname: Name of file that contains details about the outside doors
        :param inside_walls_doors_fname: Name of file that contains details about the inside walls/doors
        :return: A list of list of tile models that will act as the board
        """
        tiles = []

        for i in range(self._dimensions[0]):
            tiles.append([])
            for j in range(self._dimensions[1]):
                tile_kind = self._determine_tile_kind(i, j)
                tile = TileModel(i, j, tile_kind)
                tiles[i].append(tile)

        # setting tile adjacencies
        self.set_adjacencies(tiles)

        # setting the top and bottom walls on the outside of the house
        for top, bottom in [(0, 1), (6, 7)]:
            for i in range(1, 9):
                wall = WallModel(top, i, "South")
                tiles[top][i].set_adjacent_edge_obstacle("South", wall)
                tiles[bottom][i].set_adjacent_edge_obstacle("North", wall)

        # setting the left and right walls on the outside of the house
        for left, right in [(0, 1), (8, 9)]:
            for i in range(1, 7):
                wall = WallModel(i, left, "East")
                tiles[i][left].set_adjacent_edge_obstacle("East", wall)
                tiles[i][right].set_adjacent_edge_obstacle("West", wall)

        # setting the ambulance and engine parking spaces
        self.set_parking_spaces(amb_engine_parking_fname, tiles)

        # setting the doors present on the outside of the house EXPLICITLY
        self.set_outside_doors(outside_doors_fname, tiles)

        # setting the walls and doors present inside the house
        self.set_inside_walls_doors(inside_walls_doors_fname, tiles)

        # setting the arrow directions given for the inside tiles
        self.set_all_tiles_arrows(MEDIA_CONSTS.TILE_ARROW_DIRECTIONS, tiles)

        return tiles
Exemple #7
0
    def run_checks_pickup(self, tile_model: TileModel):
        # Doge cannot pick up a hazmat
        if not self._current_player == GameStateModel.instance().players_turn:
            return False
        if self._current_player.role == PlayerRoleEnum.DOGE:
            return False

        if isinstance(self._current_player.carrying_victim,
                      VictimModel) or isinstance(
                          self._current_player.carrying_hazmat, HazmatModel):
            return False

        if self._current_player.column == tile_model.column and self._current_player.row == tile_model.row:
            if tile_model.has_hazmat():
                return True
        return False
    def _determine_movement_direction(self, src_tile: TileModel, dest_tile: TileModel) -> str:
        """
        Determine the direction from the
        source tile to the destination tile

        :param src_tile:
        :param dest_tile:
        :return: string representation of movement direction
        """
        directions = ["North", "East", "West", "South"]
        for dirn in directions:
            nb_src_tile: TileModel = src_tile.get_tile_in_direction(dirn)
            if isinstance(nb_src_tile, NullModel):
                continue

            if nb_src_tile.row == dest_tile.row and nb_src_tile.column == dest_tile.column:
                return dirn
Exemple #9
0
    def set_single_tile_adjacencies(self, tile: TileModel):
        # set north tile
        if tile.row == 0:
            tile.set_adjacent_tile("North", NullModel())
        else:
            tile.set_adjacent_tile("North", self.get_tile_at(tile.row - 1, tile.column))

        # set east tile
        if tile.column == BOARD_DIMENSIONS[1] - 1:
            tile.set_adjacent_tile("East", NullModel())
        else:
            tile.set_adjacent_tile("East", self.get_tile_at(tile.row, tile.column + 1))

        # set west tile
        if tile.column == 0:
            tile.set_adjacent_tile("West", NullModel())
        else:
            tile.set_adjacent_tile("West", self.get_tile_at(tile.row, tile.column - 1))

        # set south tile
        if tile.row == BOARD_DIMENSIONS[0] - 1:
            tile.set_adjacent_tile("South", NullModel())
        else:
            tile.set_adjacent_tile("South", self.get_tile_at(tile.row + 1, tile.column))
Exemple #10
0
 def _deserialize_tile(payload: Dict) -> TileModel:
     tile: TileModel = TileModel(payload['_row'], payload['_column'],
                                 payload['_space_kind'])
     return tile