Example #1
0
def test_add_pickup_to_state(state_game_data, empty_patches,
                             generic_item_category):
    # Starting State
    s = state.State({}, (), 99, None, empty_patches, None, state_game_data)

    resource_a = ItemResourceInfo("A", "A", 10)
    resource_b = ItemResourceInfo("B", "B", 10)
    p = PickupEntry("B",
                    2,
                    generic_item_category,
                    generic_item_category,
                    progression=(
                        (resource_a, 1),
                        (resource_b, 1),
                    ))

    # Run
    state.add_pickup_to_state(s, p)
    state.add_pickup_to_state(s, p)

    # Assert
    assert s.resources == {
        resource_a: 1,
        resource_b: 1,
    }
Example #2
0
def test_add_pickup_to_state(state_game_data, empty_patches,
                             generic_item_category):
    # Starting State
    db = state_game_data.resource_database
    starting_node = state_game_data.world_list.resolve_teleporter_connection(
        empty_patches.game.starting_location)
    s = state.State(ResourceCollection(), (), 99, starting_node, empty_patches,
                    None, state_game_data)

    resource_a = db.item[0]
    resource_b = db.item[1]
    p = PickupEntry("B",
                    2,
                    generic_item_category,
                    generic_item_category,
                    progression=(
                        (resource_a, 1),
                        (resource_b, 1),
                    ))

    # Run
    state.add_pickup_to_state(s, p)
    state.add_pickup_to_state(s, p)

    # Assert
    assert s.resources == ResourceCollection.from_dict(db, {
        resource_a: 1,
        resource_b: 1,
    })
def test_database_collectable(preset_manager, game_enum: RandovaniaGame,
                              ignore_events: set[str],
                              ignore_pickups: set[int]):
    game, initial_state, permalink = run_bootstrap(
        preset_manager.default_preset_for_game(game_enum).get_preset())
    all_pickups = set(
        reach_lib.filter_pickup_nodes(game.world_list.iterate_nodes()))
    pool_results = pool_creator.calculate_pool_results(
        permalink.get_preset(0).configuration, game.resource_database)

    initial_state.resources.add_resource_gain(
        pool_results.initial_resources.as_resource_gain())
    for pickup in pool_results.pickups:
        add_pickup_to_state(initial_state, pickup)
    for pickup in pool_results.assignment.values():
        add_pickup_to_state(initial_state, pickup)
    for trick in game.resource_database.trick:
        initial_state.resources.set_resource(
            trick,
            LayoutTrickLevel.maximum().as_number)

    expected_events = sorted([
        event for event in game.resource_database.event
        if event.short_name not in ignore_events
    ],
                             key=lambda it: it.short_name)
    expected_pickups = sorted(it.pickup_index for it in all_pickups
                              if it.pickup_index.index not in ignore_pickups)

    reach = _create_reach_with_unsafe(game, initial_state.heal())
    while list(reach_lib.collectable_resource_nodes(reach.nodes, reach)):
        reach.act_on(
            next(iter(reach_lib.collectable_resource_nodes(reach.nodes,
                                                           reach))))
        reach = advance_reach_with_possible_unsafe_resources(reach)

    # print("\nCurrent reach:")
    # print(game.world_list.node_name(reach.state.node, with_world=True))
    # for world in game.world_list.worlds:
    #     print(f"\n>> {world.name}")
    #     for node in world.all_nodes:
    #         print("[{!s:>5}, {!s:>5}, {!s:>5}] {}".format(
    #             reach.is_reachable_node(node), reach.is_safe_node(node),
    #             reach.state.resources.get(node.resource(), 0) > 0
    #             if isinstance(node, ResourceNode) else "",
    #             game.world_list.node_name(node, with_world=True)))

    collected_indices = set(reach.state.collected_pickup_indices)
    collected_events = {
        resource
        for resource, quantity in reach.state.resources.as_resource_gain()
        if quantity > 0 and resource.resource_type == ResourceType.EVENT
    }
    assert list(reach_lib.collectable_resource_nodes(reach.nodes, reach)) == []
    assert sorted(collected_indices) == expected_pickups
    assert sorted(collected_events,
                  key=lambda it: it.short_name) == expected_events
Example #4
0
    def state_for_current_configuration(self) -> Optional[State]:
        state = self._initial_state.copy()
        state.node = self._actions[-1]

        for pickup, quantity in self._collected_pickups.items():
            for _ in range(quantity):
                add_pickup_to_state(state, pickup)

        for node in self._collected_nodes:
            add_resource_gain_to_current_resources(node.resource_gain_on_collect(state.patches, state.resources),
                                                   state.resources)

        return state
Example #5
0
def test_database_collectable(preset_manager, preset_name, ignore_events,
                              ignore_pickups):
    game, initial_state, permalink = run_bootstrap(
        preset_manager.preset_for_name(preset_name).get_preset())
    all_pickups = set(filter_pickup_nodes(game.world_list.all_nodes))
    pool_results = pool_creator.calculate_pool_results(
        permalink.get_preset(0).configuration, game.resource_database)
    add_resources_into_another(initial_state.resources,
                               pool_results.initial_resources)
    for pickup in pool_results.pickups:
        add_pickup_to_state(initial_state, pickup)
    for pickup in pool_results.assignment.values():
        add_pickup_to_state(initial_state, pickup)
    for trick in game.resource_database.trick:
        initial_state.resources[trick] = LayoutTrickLevel.HYPERMODE.as_number

    expected_events = [
        event for event in game.resource_database.event
        if event.index not in ignore_events
    ]
    expected_pickups = sorted(it.pickup_index for it in all_pickups
                              if it.pickup_index.index not in ignore_pickups)

    reach = _create_reach_with_unsafe(game, initial_state.heal())
    while list(collectable_resource_nodes(reach.nodes, reach)):
        reach.act_on(next(iter(collectable_resource_nodes(reach.nodes,
                                                          reach))))
        reach = advance_reach_with_possible_unsafe_resources(reach)

    # print("\nCurrent reach:")
    # for world in game.world_list.worlds:
    #     print(f"\n>> {world.name}")
    #     for node in world.all_nodes:
    #         print("[{!s:>5}, {!s:>5}, {!s:>5}] {}".format(
    #             reach.is_reachable_node(node), reach.is_safe_node(node),
    #             reach.state.resources.get(node.resource(), 0) > 0 if isinstance(node, ResourceNode) else "",
    #             game.world_list.node_name(node)))

    collected_indices = {
        resource
        for resource, quantity in reach.state.resources.items()
        if quantity > 0 and isinstance(resource, PickupIndex)
    }
    collected_events = {
        resource
        for resource, quantity in reach.state.resources.items()
        if quantity > 0 and resource.resource_type == ResourceType.EVENT
    }
    assert list(collectable_resource_nodes(reach.nodes, reach)) == []
    assert sorted(collected_indices) == expected_pickups
    assert sorted(collected_events, key=lambda it: it.index) == expected_events
def test_calculate_reach_with_all_pickups(test_data):
    game, state, _ = test_data

    item_pool = calculate_item_pool(LayoutConfiguration.from_params(),
                                    game.resource_database, state.patches)
    add_resources_into_another(state.resources, item_pool[0].starting_items)
    for pickup in item_pool[1]:
        add_pickup_to_state(state, pickup)

    first_reach, second_reach = _create_reaches_and_compare(game, state)
    first_actions, second_actions = _compare_actions(first_reach, second_reach)

    found_pickups = set(
        filter_pickup_nodes(filter_reachable(second_reach.nodes, first_reach)))
    all_pickups = set(filter_pickup_nodes(game.world_list.all_nodes))

    # assert (len(list(first_reach.nodes)), len(first_actions)) == (898, 9)
    # assert (len(list(second_reach.nodes)), len(second_actions)) == (898, 9)
    pprint.pprint(first_actions)
    assert all_pickups == found_pickups
Example #7
0
def test_add_pickup_to_state(database, patches):
    # Starting State
    s = state.State({}, (), 99, None, patches, None, database, None)

    resource_a = ItemResourceInfo(1, "A", "A", 10, None)
    resource_b = ItemResourceInfo(2, "B", "B", 10, None)
    p = PickupEntry("B", 2, ItemCategory.SUIT, ItemCategory.LIFE_SUPPORT, (
        ConditionalResources(None, None, ((resource_a, 1), )),
        ConditionalResources(None, resource_a, ((resource_b, 1), )),
    ))

    # Run
    state.add_pickup_to_state(s, p)
    state.add_pickup_to_state(s, p)

    # Assert
    assert s.resources == {
        resource_a: 1,
        resource_b: 1,
    }
Example #8
0
def test_add_pickup_to_state(database):
    # Starting State
    s = state.State({}, (), 99, None, None, None, database)

    resource_a = SimpleResourceInfo(1, "A", "A", ResourceType.ITEM)
    resource_b = SimpleResourceInfo(2, "B", "B", ResourceType.ITEM)
    p = PickupEntry("B", 2, ItemCategory.SUIT, (
        ConditionalResources(None, None, ((resource_a, 1), )),
        ConditionalResources(None, resource_a, ((resource_b, 1), )),
    ))

    # Run
    state.add_pickup_to_state(s, p)
    state.add_pickup_to_state(s, p)

    # Assert
    assert s.resources == {
        resource_a: 1,
        resource_b: 1,
    }
def test_calculate_reach_with_all_pickups(test_data):
    game, state, permalink = test_data

    pool_results = pool_creator.calculate_pool_results(
        permalink.get_preset(0).layout_configuration, game.resource_database)
    add_resources_into_another(state.resources, pool_results.initial_resources)
    for pickup in pool_results.pickups:
        add_pickup_to_state(state, pickup)
    for pickup in pool_results.assignment.values():
        add_pickup_to_state(state, pickup)

    first_reach, second_reach = _create_reaches_and_compare(game, state)
    first_actions, second_actions = _compare_actions(first_reach, second_reach)

    found_pickups = set(
        filter_pickup_nodes(filter_reachable(second_reach.nodes, first_reach)))
    all_pickups = set(filter_pickup_nodes(game.world_list.all_nodes))

    # assert (len(list(first_reach.nodes)), len(first_actions)) == (898, 9)
    # assert (len(list(second_reach.nodes)), len(second_actions)) == (898, 9)
    pprint.pprint(first_actions)
    assert all_pickups == found_pickups
Example #10
0
    def state_for_current_configuration(self) -> Optional[State]:
        state = self._initial_state.copy()
        if self._actions:
            state.node = self._actions[-1]

        for teleporter, combo in self._elevator_id_to_combo.items():
            assert combo.currentData() is not None
            state.patches.elevator_connection[teleporter] = combo.currentData()

        for gate, item in self._translator_gate_to_combo.items():
            state.patches.translator_gates[gate] = item.currentData()

        for pickup, quantity in self._collected_pickups.items():
            for _ in range(quantity):
                add_pickup_to_state(state, pickup)

        for node in self._collected_nodes:
            add_resource_gain_to_current_resources(
                node.resource_gain_on_collect(state.patches, state.resources),
                state.resources)

        return state
Example #11
0
    def state_for_current_configuration(self) -> Optional[State]:
        state = self._initial_state.copy()
        if self._actions:
            state.node = self._actions[-1]

        state.patches = state.patches.assign_elevators(
            (state.world_list.get_teleporter_node(teleporter),
             combo.currentData())
            for teleporter, combo in self._elevator_id_to_combo.items())

        for gate, item in self._translator_gate_to_combo.items():
            scan_visor = self.game_description.resource_database.get_item(
                "Scan")

            requirement: Optional[
                LayoutTranslatorRequirement] = item.currentData()
            if requirement is None:
                translator_req = Requirement.impossible()
            else:
                translator = self.game_description.resource_database.get_item(
                    requirement.item_name)
                translator_req = ResourceRequirement.simple(translator)

            state.patches.configurable_nodes[gate] = RequirementAnd([
                ResourceRequirement.simple(scan_visor),
                translator_req,
            ])

        for pickup, quantity in self._collected_pickups.items():
            for _ in range(quantity):
                add_pickup_to_state(state, pickup)

        for node in self._collected_nodes:
            state.resources.add_resource_gain(
                node.resource_gain_on_collect(state.node_context()))

        return state
Example #12
0
def test_add_pickup_to_state(state_game_data, empty_patches):
    # Starting State
    s = state.State({}, (), 99, None, empty_patches, None, state_game_data)

    resource_a = ItemResourceInfo(1, "A", "A", 10, None)
    resource_b = ItemResourceInfo(2, "B", "B", 10, None)
    p = PickupEntry("B",
                    2,
                    ItemCategory.SUIT,
                    ItemCategory.LIFE_SUPPORT,
                    progression=(
                        (resource_a, 1),
                        (resource_b, 1),
                    ))

    # Run
    state.add_pickup_to_state(s, p)
    state.add_pickup_to_state(s, p)

    # Assert
    assert s.resources == {
        resource_a: 1,
        resource_b: 1,
    }
Example #13
0
def random_assumed_filler(
    logic: Logic,
    initial_state: State,
    patches: GamePatches,
    available_pickups: Tuple[PickupEntry],
    rng: Random,
    status_update: Callable[[str], None],
) -> PickupAssignment:
    pickup_assignment = copy.copy(patches.pickup_assignment)
    print("Major items: {}".format([item.name for item in available_pickups]))
    game = logic.game

    base_reach = advance_reach_with_possible_unsafe_resources(
        reach_with_all_safe_resources(game, initial_state))

    reaches_for_pickup = {}

    previous_reach = base_reach
    for pickup in reversed(available_pickups):
        print("** Preparing reach for {}".format(pickup.name))
        new_reach = copy.deepcopy(previous_reach)
        add_pickup_to_state(new_reach.state, pickup)
        new_reach.state.previous_state = new_reach.state
        new_reach.advance_to(new_reach.state)
        collect_all_safe_resources_in_reach(new_reach)
        previous_reach = advance_reach_with_possible_unsafe_resources(
            new_reach)
        reaches_for_pickup[pickup] = previous_reach

    for i, pickup in enumerate(available_pickups):
        print("\n\n\nWill place {}, have {} pickups left".format(
            pickup,
            len(available_pickups) - i - 1))
        reach = reaches_for_pickup[pickup]
        debug.print_actions_of_reach(reach)
        escape_state = state_with_pickup(reach.state, pickup)

        total_pickup_nodes = list(
            _filter_pickups(filter_reachable(reach.nodes, reach)))
        pickup_nodes = list(
            filter_unassigned_pickup_nodes(total_pickup_nodes,
                                           pickup_assignment))
        num_nodes = len(pickup_nodes)
        actions_weights = {
            node: len(path)
            for node, path in reach.shortest_path_from(
                initial_state.node).items()
        }

        try:
            pickup_node = next(
                pickup_nodes_that_can_reach(
                    iterate_with_weights(pickup_nodes, actions_weights, rng),
                    reach_with_all_safe_resources(game, escape_state),
                    set(reach.safe_nodes)))
            print("Placed {} at {}. Had {} available of {} nodes.".format(
                pickup.name, game.world_list.node_name(pickup_node, True),
                num_nodes, len(total_pickup_nodes)))

        except StopIteration:
            print("\n".join(
                game.world_list.node_name(node, True)
                for node in reach.safe_nodes))
            raise Exception(
                "Couldn't place {}. Had {} available of {} nodes.".format(
                    pickup.name, num_nodes, len(total_pickup_nodes)))

        pickup_assignment[pickup_node.pickup_index] = pickup

    return pickup_assignment