Exemplo n.º 1
0
    def __init__(self, layout_configuration: LayoutConfiguration):
        super().__init__()
        self.setupUi(self)
        set_default_window_icon(self)

        self.layout_configuration = layout_configuration
        self.game_description = data_reader.decode_data(
            layout_configuration.game_data, True)

        self.logic, self._initial_state = logic_bootstrap(
            layout_configuration, self.game_description,
            GamePatches.with_game(self.game_description))
        self.resource_filter_check.stateChanged.connect(
            self.update_locations_tree_for_reachable_nodes)
        self.hide_collected_resources_check.stateChanged.connect(
            self.update_locations_tree_for_reachable_nodes)
        self.undo_last_action_button.clicked.connect(self._undo_last_action)

        self.configuration_label.setText(
            "Trick Level: {}; Elevators: Vanilla; Item Loss: {}".format(
                layout_configuration.trick_level.value,
                layout_configuration.starting_resources.configuration.value,
            ))

        self.setup_pickups_box()
        self.setup_possible_locations_tree()

        self._starting_nodes = {
            node
            for node in self.game_description.world_list.all_nodes
            if node.is_resource_node
            and node.resource() in self._initial_state.resources
        }
        self._add_new_action(self._initial_state.node)
Exemplo n.º 2
0
def test_reach_size_from_start(echoes_game_description,
                               default_layout_configuration, minimal_logic,
                               nodes, safe_nodes):
    # Setup
    specific_levels = {
        trick.short_name: LayoutTrickLevel.HYPERMODE
        for trick in echoes_game_description.resource_database.trick
    }

    layout_configuration = dataclasses.replace(
        default_layout_configuration,
        trick_level_configuration=TrickLevelConfiguration(
            minimal_logic=minimal_logic,
            specific_levels=specific_levels if not minimal_logic else {}),
    )
    player_pool = generator.create_player_pool(Random(15000),
                                               layout_configuration, 0)

    game, state = logic_bootstrap(layout_configuration, player_pool.game,
                                  player_pool.patches)

    # Run
    reach = GeneratorReach.reach_from_state(game, state)

    # Assert
    assert len(list(reach.nodes)) >= nodes
    assert len(list(reach.safe_nodes)) >= safe_nodes
Exemplo n.º 3
0
def run_filler(
    configuration: LayoutConfiguration,
    game: GameDescription,
    item_pool: List[PickupEntry],
    patches: GamePatches,
    rng: Random,
    status_update: Callable[[str], None],
) -> Tuple[GamePatches, List[PickupEntry]]:
    """
    Runs the filler logic for the given configuration and item pool.
    Returns a GamePatches with progression items and hints assigned, along with all items in the pool
    that weren't assigned.

    :param configuration:
    :param game:
    :param item_pool:
    :param patches:
    :param rng:
    :param status_update:
    :return:
    """
    major_items, expansions = _split_expansions(item_pool)
    rng.shuffle(major_items)
    rng.shuffle(expansions)

    major_configuration = configuration.major_items_configuration

    new_game, state = bootstrap.logic_bootstrap(configuration, game, patches)
    new_game.patch_requirements(state.resources,
                                configuration.damage_strictness.value)

    filler_patches = retcon_playthrough_filler(
        new_game,
        state,
        major_items,
        rng,
        configuration=FillerConfiguration(
            randomization_mode=configuration.available_locations.
            randomization_mode,
            minimum_random_starting_items=major_configuration.
            minimum_random_starting_items,
            maximum_random_starting_items=major_configuration.
            maximum_random_starting_items,
            indices_to_exclude=configuration.available_locations.
            excluded_indices,
        ),
        status_update=status_update)

    # Since we haven't added expansions yet, these hints will always be for items added by the filler.
    full_hints_patches = fill_unassigned_hints(filler_patches, game.world_list,
                                               rng)

    if configuration.hints.item_hints:
        result = add_hints_precision(full_hints_patches, rng)
    else:
        result = replace_hints_without_precision_with_jokes(full_hints_patches)

    return result, major_items + expansions
Exemplo n.º 4
0
    def __init__(self, persistence_path: Path, layout_configuration: LayoutConfiguration):
        super().__init__()
        self.setupUi(self)
        set_default_window_icon(self)

        self._collected_pickups = {}
        self._widget_for_pickup = {}
        self._actions = []
        self._asset_id_to_item = {}
        self._node_to_item = {}
        self.layout_configuration = layout_configuration
        self.persistence_path = persistence_path

        player_index = 0  # FIXME
        try:
            player_pool = generator.create_player_pool(None, self.layout_configuration, player_index)
        except base_patches_factory.MissingRng as e:
            raise InvalidLayoutForTracker("Layout is configured to have random {}, "
                                          "but that isn't supported by the tracker.".format(e))

        pool_patches = player_pool.patches
        self.game_description, self._initial_state = logic_bootstrap(layout_configuration,
                                                                     player_pool.game,
                                                                     pool_patches)
        self.logic = Logic(self.game_description, layout_configuration)

        self._initial_state.resources["add_self_as_requirement_to_resources"] = 1

        self.menu_reset_action.triggered.connect(self._confirm_reset)
        self.resource_filter_check.stateChanged.connect(self.update_locations_tree_for_reachable_nodes)
        self.hide_collected_resources_check.stateChanged.connect(self.update_locations_tree_for_reachable_nodes)
        self.undo_last_action_button.clicked.connect(self._undo_last_action)

        self.configuration_label.setText("Trick Level: {}; Elevators: Vanilla; Starts with:\n{}".format(
            layout_configuration.trick_level_configuration.global_level.value,
            ", ".join(
                resource.short_name
                for resource in pool_patches.starting_items.keys()
            )
        ))

        self.setup_pickups_box(player_pool.pickups)
        self.setup_possible_locations_tree()

        self._starting_nodes = {
            node
            for node in self.game_description.world_list.all_nodes
            if node.is_resource_node and node.resource() in self._initial_state.resources
        }

        persistence_path.mkdir(parents=True, exist_ok=True)
        previous_state = _load_previous_state(persistence_path, layout_configuration)

        if not self.apply_previous_state(previous_state):
            with persistence_path.joinpath("layout_configuration.json").open("w") as layout_file:
                json.dump(layout_configuration.as_json, layout_file)
            self._add_new_action(self._initial_state.node)
Exemplo n.º 5
0
    def __init__(self, persistence_path: Path,
                 layout_configuration: LayoutConfiguration):
        super().__init__()
        self.setupUi(self)
        set_default_window_icon(self)

        self._collected_pickups = {}
        self._widget_for_pickup = {}
        self._actions = []
        self._asset_id_to_item = {}
        self._node_to_item = {}
        self.layout_configuration = layout_configuration
        self.persistence_path = persistence_path

        player_pool = generator.create_player_pool(Random(0),
                                                   self.layout_configuration,
                                                   0)
        pool_patches = player_pool.patches
        self.game_description, self._initial_state = logic_bootstrap(
            layout_configuration, player_pool.game, pool_patches)
        self.logic = Logic(self.game_description, layout_configuration)

        self._initial_state.resources[
            "add_self_as_requirement_to_resources"] = 1

        self.menu_reset_action.triggered.connect(self._confirm_reset)
        self.resource_filter_check.stateChanged.connect(
            self.update_locations_tree_for_reachable_nodes)
        self.hide_collected_resources_check.stateChanged.connect(
            self.update_locations_tree_for_reachable_nodes)
        self.undo_last_action_button.clicked.connect(self._undo_last_action)

        self.configuration_label.setText(
            "Trick Level: {}; Starts with:\n{}".format(
                layout_configuration.trick_level_configuration.
                pretty_description,
                ", ".join(resource.short_name
                          for resource in pool_patches.starting_items.keys())))

        self.setup_pickups_box(player_pool.pickups)
        self.setup_possible_locations_tree()
        self.setup_elevators()
        self.setup_translator_gates()

        persistence_path.mkdir(parents=True, exist_ok=True)
        previous_state = _load_previous_state(persistence_path,
                                              layout_configuration)

        if not self.apply_previous_state(previous_state):
            self.setup_starting_location(None)

            with persistence_path.joinpath("layout_configuration.json").open(
                    "w") as layout_file:
                json.dump(layout_configuration.as_json, layout_file)
            self._add_new_action(self._initial_state.node)
Exemplo n.º 6
0
def resolve(
        configuration: LayoutConfiguration,
        game: GameDescription,
        patches: GamePatches,
        status_update: Optional[Callable[[str],
                                         None]] = None) -> Optional[State]:
    if status_update is None:
        status_update = lambda s: None

    logic, starting_state = logic_bootstrap(configuration, game, patches)
    debug.log_resolve_start()
    return advance_depth(starting_state, logic, status_update)
def run_bootstrap(preset: Preset):
    game = data_reader.decode_data(preset.configuration.game_data)
    permalink = Permalink(
        seed_number=15000,
        spoiler=True,
        presets={0: preset},
    )
    patches = base_patches_factory.create_base_patches(preset.configuration,
                                                       Random(15000), game,
                                                       False)
    _, state = logic_bootstrap(preset.configuration, game, patches)

    return game, state, permalink
Exemplo n.º 8
0
def run_bootstrap(preset: Preset):
    game = default_database.game_description_for(preset.game)
    permalink = Permalink(
        seed_number=15000,
        spoiler=True,
        presets={0: preset},
    )
    patches = base_patches_factory.create_base_patches(preset.configuration,
                                                       Random(15000),
                                                       game,
                                                       False,
                                                       player_index=0)
    _, state = logic_bootstrap(preset.configuration, game, patches)

    return game, state, permalink
Exemplo n.º 9
0
def _test_data(default_preset):
    data = default_data.decode_default_prime2()
    game = data_reader.decode_data(data)
    permalink = Permalink(
        seed_number=15000,
        spoiler=True,
        presets={0: default_preset},
    )
    configuration = permalink.get_preset(0).layout_configuration
    patches = game.create_game_patches()
    patches = patches.assign_gate_assignment(
        base_patches_factory.gate_assignment_for_configuration(
            configuration, game.resource_database, Random(15000)))
    game, state = logic_bootstrap(configuration, game, patches)

    return game, state, permalink
Exemplo n.º 10
0
def resolve(configuration: LayoutConfiguration,
            patches: GamePatches,
            status_update: Optional[Callable[[str], None]] = None
            ) -> Optional[State]:
    if status_update is None:
        status_update = _quiet_print

    game = data_reader.decode_data(configuration.game_data)
    event_pickup.replace_with_event_pickups(game)

    new_game, starting_state = logic_bootstrap(configuration, game, patches)
    logic = Logic(new_game, configuration)
    starting_state.resources["add_self_as_requirement_to_resources"] = 1
    debug.log_resolve_start()

    return advance_depth(starting_state, logic, status_update)
Exemplo n.º 11
0
def test_retcon_filler_integration():
    layout_configuration = LayoutConfiguration.default()

    rng = Random("fixed-seed!")
    status_update = MagicMock()

    game = data_reader.decode_data(layout_configuration.game_data)
    patches = GamePatches.with_game(game)
    available_pickups = game.pickup_database.all_useful_pickups

    logic, state = logic_bootstrap(layout_configuration, game, patches)
    logic.game.simplify_connections(state.resources)

    filler_patches = retcon.retcon_playthrough_filler(logic, state,
                                                      tuple(available_pickups),
                                                      rng, status_update)
    assert filler_patches == patches
Exemplo n.º 12
0
def _test_data():
    data = default_data.decode_default_prime2()
    game = data_reader.decode_data(data)
    configuration = LayoutConfiguration.from_params()
    permalink = Permalink(
        seed_number=15000,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )
    patches = GamePatches.with_game(game)
    patches = patches.assign_gate_assignment(
        base_patches_factory.gate_assignment_for_configuration(
            configuration, game.resource_database, Random(15000)))
    game, state = logic_bootstrap(configuration, game, patches)

    return game, state, permalink
Exemplo n.º 13
0
async def resolve(
        configuration: EchoesConfiguration,
        patches: GamePatches,
        status_update: Optional[Callable[[str],
                                         None]] = None) -> Optional[State]:
    if status_update is None:
        status_update = _quiet_print

    game = copy.deepcopy(
        default_database.game_description_for(configuration.game))
    event_pickup.replace_with_event_pickups(game)

    new_game, starting_state = logic_bootstrap(configuration, game, patches)
    logic = Logic(new_game, configuration)
    starting_state.resources["add_self_as_requirement_to_resources"] = 1
    debug.log_resolve_start()

    return await advance_depth(starting_state, logic, status_update)
Exemplo n.º 14
0
def test_reach_size_from_start(echoes_game_description,
                               default_layout_configuration):
    # Setup
    layout_configuration = dataclasses.replace(
        default_layout_configuration,
        trick_level_configuration=TrickLevelConfiguration(
            LayoutTrickLevel.HYPERMODE),
    )
    player_pool = generator.create_player_pool(Random(15000),
                                               layout_configuration, 0)

    game, state = logic_bootstrap(layout_configuration, player_pool.game,
                                  player_pool.patches)

    # Run
    reach = GeneratorReach.reach_from_state(game, state)

    # Assert
    assert len(list(reach.nodes)) == 44
    assert len(list(reach.safe_nodes)) == 5
Exemplo n.º 15
0
def test_reach_size_from_start(echoes_game_description):
    # Setup
    configuration = LayoutConfiguration.from_params(
        trick_level_configuration=TrickLevelConfiguration(
            LayoutTrickLevel.HYPERMODE), )
    patches = GamePatches.with_game(echoes_game_description)
    patches = patches.assign_gate_assignment(
        base_patches_factory.gate_assignment_for_configuration(
            configuration, echoes_game_description.resource_database,
            Random(15000)))

    game, state = logic_bootstrap(configuration, echoes_game_description,
                                  patches)

    # Run
    reach = GeneratorReach.reach_from_state(game, state)

    # Assert
    assert len(list(reach.nodes)) == 26
    assert len(list(reach.safe_nodes)) == 4
Exemplo n.º 16
0
def _test_data():
    data = default_data.decode_default_prime2()
    game = data_reader.decode_data(data, False)
    configuration = LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.NO_TRICKS,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.default(),
    )
    permalink = Permalink(
        seed_number=15000,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )
    logic, state = logic_bootstrap(configuration, game,
                                   GamePatches.with_game(game))

    return logic, state, permalink
Exemplo n.º 17
0
def _create_patches(
    permalink: Permalink,
    game: GameDescription,
    status_update: Callable[[str], None],
) -> GamePatches:
    rng = Random(permalink.as_str)
    configuration = permalink.layout_configuration

    categories = {
        "translator", "major", "energy_tank", "sky_temple_key", "temple_key"
    }
    item_pool = tuple(sorted(calculate_item_pool(permalink, game)))
    available_pickups = list(
        shuffle(rng, calculate_available_pickups(item_pool, categories, None)))

    if configuration.starting_location.configuration != StartingLocationConfiguration.SHIP:
        raise GenerationFailure("The only supported StartingLocation is SHIP",
                                permalink)

    if configuration.starting_resources.configuration == StartingResourcesConfiguration.CUSTOM:
        raise GenerationFailure("Custom StartingResources is unsupported",
                                permalink)

    patches = GamePatches.with_game(game)
    patches = _add_elevator_connections_to_patches(permalink, patches)
    patches = _sky_temple_key_distribution_logic(permalink, patches,
                                                 available_pickups)

    logic, state = logic_bootstrap(configuration, game, patches)
    logic.game.simplify_connections(state.resources)

    filler_patches = retcon_playthrough_filler(logic, state,
                                               tuple(available_pickups), rng,
                                               status_update)

    return filler_patches.assign_new_pickups(
        _indices_for_unassigned_pickups(rng, game,
                                        filler_patches.pickup_assignment,
                                        item_pool))
Exemplo n.º 18
0
def test_reach_size_from_start(echoes_game_description,
                               default_layout_configuration):
    # Setup
    configuration = dataclasses.replace(
        default_layout_configuration,
        trick_level_configuration=TrickLevelConfiguration(
            LayoutTrickLevel.HYPERMODE),
    )
    patches = echoes_game_description.create_game_patches()
    patches = patches.assign_gate_assignment(
        base_patches_factory.gate_assignment_for_configuration(
            configuration, echoes_game_description.resource_database,
            Random(15000)))

    game, state = logic_bootstrap(configuration, echoes_game_description,
                                  patches)

    # Run
    reach = GeneratorReach.reach_from_state(game, state)

    # Assert
    assert len(list(reach.nodes)) == 25
    assert len(list(reach.safe_nodes)) == 4
def test_retcon_filler_integration(default_layout_configuration):
    layout_configuration = default_layout_configuration

    rng = Random("fixed-seed!")
    status_update = MagicMock()

    game = default_database.game_description_for(layout_configuration.game)
    patches = game.create_game_patches()
    available_pickups = game.pickup_database.all_useful_pickups

    new_game, state = logic_bootstrap(layout_configuration, game, patches)
    new_game.patch_requirements(state.resources,
                                layout_configuration.damage_strictness.value)

    filler_patches = retcon.retcon_playthrough_filler(
        new_game, state, tuple(available_pickups), rng,
        FillerConfiguration(
            randomization_mode=RandomizationMode.FULL,
            minimum_random_starting_items=0,
            maximum_random_starting_items=0,
            indices_to_exclude=frozenset(),
        ), status_update)
    assert filler_patches == patches
Exemplo n.º 20
0
def run_filler(rng: Random,
               player_pools: Dict[int, PlayerPool],
               status_update: Callable[[str], None],
               ) -> FillerResults:
    """
    Runs the filler logic for the given configuration and item pool.
    Returns a GamePatches with progression items and hints assigned, along with all items in the pool
    that weren't assigned.

    :param player_pools:
    :param rng:
    :param status_update:
    :return:
    """

    player_states = []
    player_expansions: Dict[int, List[PickupEntry]] = {}

    for index, pool in player_pools.items():
        status_update(f"Creating state for player {index + 1}")
        major_items, player_expansions[index] = _split_expansions(pool.pickups)
        rng.shuffle(major_items)
        rng.shuffle(player_expansions[index])

        new_game, state = bootstrap.logic_bootstrap(pool.configuration, pool.game, pool.patches)
        new_game.patch_requirements(state.resources, pool.configuration.damage_strictness.value)

        major_configuration = pool.configuration.major_items_configuration
        player_states.append(PlayerState(
            index=index,
            game=new_game,
            initial_state=state,
            pickups_left=major_items,
            configuration=FillerConfiguration(
                randomization_mode=pool.configuration.available_locations.randomization_mode,
                minimum_random_starting_items=major_configuration.minimum_random_starting_items,
                maximum_random_starting_items=major_configuration.maximum_random_starting_items,
                indices_to_exclude=pool.configuration.available_locations.excluded_indices,
            ),
        ))

    try:
        filler_result, actions_log = retcon_playthrough_filler(rng, player_states, status_update=status_update)
    except UnableToGenerate as e:
        message = "{}\n\n{}".format(
            str(e),
            "\n\n".join(
                "#### Player {}\n{}".format(player.index + 1, player.current_state_report())
                for player in player_states
            ),
        )
        debug.debug_print(message)
        raise UnableToGenerate(message) from e

    results = {}

    for player_state, patches in filler_result.items():
        game = player_state.game

        if game.game == RandovaniaGame.PRIME2:
            # Since we haven't added expansions yet, these hints will always be for items added by the filler.
            full_hints_patches = fill_unassigned_hints(patches, game.world_list, rng,
                                                       player_state.scan_asset_initial_pickups)

            if player_pools[player_state.index].configuration.hints.item_hints:
                result = add_hints_precision(player_state, full_hints_patches, rng)
            else:
                result = replace_hints_without_precision_with_jokes(full_hints_patches)
        else:
            result = patches

        results[player_state.index] = FillerPlayerResult(
            game=game,
            patches=result,
            unassigned_pickups=player_state.pickups_left + player_expansions[player_state.index],
        )

    return FillerResults(results, actions_log)
Exemplo n.º 21
0
    def __init__(self, persistence_path: Path,
                 layout_configuration: LayoutConfiguration):
        super().__init__()
        self.setupUi(self)
        set_default_window_icon(self)

        self.menu_reset_action = QAction("Reset", self)
        self.menu_reset_action.triggered.connect(self._confirm_reset)
        self.menu_bar.addAction(self.menu_reset_action)

        self._collected_pickups = {}
        self._widget_for_pickup = {}
        self._actions = []
        self._asset_id_to_item = {}
        self._node_to_item = {}
        self.layout_configuration = layout_configuration
        self.persistence_path = persistence_path
        self.game_description = data_reader.decode_data(
            layout_configuration.game_data)

        try:
            base_patches = base_patches_factory.create_base_patches(
                self.layout_configuration, None, self.game_description)
        except base_patches_factory.MissingRng as e:
            raise InvalidLayoutForTracker(
                "Layout is configured to have random {}, "
                "but that isn't supported by the tracker.".format(e))

        pool_patches, item_pool = pool_creator.calculate_item_pool(
            self.layout_configuration, self.game_description.resource_database,
            base_patches)

        self.game_description, self._initial_state = logic_bootstrap(
            layout_configuration, self.game_description, pool_patches)
        self.logic = Logic(self.game_description, layout_configuration)

        self._initial_state.resources[
            "add_self_as_requirement_to_resources"] = 1

        self.resource_filter_check.stateChanged.connect(
            self.update_locations_tree_for_reachable_nodes)
        self.hide_collected_resources_check.stateChanged.connect(
            self.update_locations_tree_for_reachable_nodes)
        self.undo_last_action_button.clicked.connect(self._undo_last_action)

        self.configuration_label.setText(
            "Trick Level: {}; Elevators: Vanilla; Starts with:\n{}".format(
                layout_configuration.trick_level_configuration.global_level.
                value,
                ", ".join(resource.short_name
                          for resource in pool_patches.starting_items.keys())))

        self.setup_pickups_box(item_pool)
        self.setup_possible_locations_tree()

        self._starting_nodes = {
            node
            for node in self.game_description.world_list.all_nodes
            if node.is_resource_node
            and node.resource() in self._initial_state.resources
        }

        persistence_path.mkdir(parents=True, exist_ok=True)

        previous_state = _load_previous_state(persistence_path,
                                              layout_configuration)
        if previous_state is not None:
            pickup_name_to_pickup = {
                pickup.name: pickup
                for pickup in self._collected_pickups.keys()
            }
            self.bulk_change_quantity({
                pickup_name_to_pickup[pickup_name]: quantity
                for pickup_name, quantity in
                previous_state["collected_pickups"].items()
            })
            self._add_new_actions([
                self.game_description.world_list.all_nodes[index]
                for index in previous_state["actions"]
            ])
        else:
            with persistence_path.joinpath("layout_configuration.json").open(
                    "w") as layout_file:
                json.dump(layout_configuration.as_json, layout_file)
            self._add_new_action(self._initial_state.node)
Exemplo n.º 22
0
def run_filler(
    rng: Random,
    player_pools: Dict[int, PlayerPool],
    status_update: Callable[[str], None],
) -> FillerResults:
    """
    Runs the filler logic for the given configuration and item pool.
    Returns a GamePatches with progression items and hints assigned, along with all items in the pool
    that weren't assigned.

    :param player_pools:
    :param rng:
    :param status_update:
    :return:
    """

    player_states = {}
    player_expansions = {}

    for index, pool in player_pools.items():
        major_items, player_expansions[index] = _split_expansions(pool.pickups)
        rng.shuffle(major_items)
        rng.shuffle(player_expansions[index])

        new_game, state = bootstrap.logic_bootstrap(pool.configuration,
                                                    pool.game, pool.patches)
        new_game.patch_requirements(state.resources,
                                    pool.configuration.damage_strictness.value)

        major_configuration = pool.configuration.major_items_configuration
        player_states[index] = PlayerState(
            game=new_game,
            initial_state=state,
            pickups_left=major_items,
            configuration=FillerConfiguration(
                randomization_mode=pool.configuration.available_locations.
                randomization_mode,
                minimum_random_starting_items=major_configuration.
                minimum_random_starting_items,
                maximum_random_starting_items=major_configuration.
                maximum_random_starting_items,
                indices_to_exclude=pool.configuration.available_locations.
                excluded_indices,
            ),
        )

    filler_result, actions_log = retcon_playthrough_filler(
        rng, player_states, status_update=status_update)

    results = {}

    for index, patches in filler_result.items():
        game = player_pools[index].game

        # Since we haven't added expansions yet, these hints will always be for items added by the filler.
        full_hints_patches = fill_unassigned_hints(patches, game.world_list,
                                                   rng)

        if player_pools[index].configuration.hints.item_hints:
            result = add_hints_precision(full_hints_patches, rng)
        else:
            result = replace_hints_without_precision_with_jokes(
                full_hints_patches)

        results[index] = FillerPlayerResult(
            game=game,
            patches=result,
            unassigned_pickups=player_states[index].pickups_left +
            player_expansions[index],
        )

    return FillerResults(results, actions_log)
Exemplo n.º 23
0
def test_logic_bootstrap(default_preset, echoes_game_description):
    new_game, state = bootstrap.logic_bootstrap(default_preset.configuration, echoes_game_description,
                                                echoes_game_description.create_game_patches())