def test_requirement_list_constructor(echoes_resource_database):
    def item(name):
        return search.find_resource_info_with_long_name(
            echoes_resource_database.item, name)

    req_list = RequirementList([
        ResourceRequirement.simple(item("Dark Visor")),
        ResourceRequirement.create(item("Missile"), 5, False),
        ResourceRequirement.simple(item("Seeker Launcher")),
    ])
    extract = [(req.resource.long_name, req.amount)
               for req in req_list.values()]

    assert sorted(extract) == [
        ("Dark Visor", 1),
        ("Missile", 5),
        ("Seeker Launcher", 1),
    ]
Example #2
0
def _unsatisfied_item_requirements_in_list(
        alternative: RequirementList, state: State,
        uncollected_resources: set[ResourceInfo]):
    possible = True
    items = []
    damage = []

    for individual in alternative.values():
        if individual.negate:
            possible = False
            break

        if individual.resource.resource_type == ResourceType.DAMAGE:
            damage.append(individual)
            continue

        if individual.satisfied(state.resources, state.energy,
                                state.resource_database):
            continue

        if individual.resource.resource_type != ResourceType.ITEM:
            if individual.resource not in uncollected_resources:
                possible = False
                break

        items.append(individual)

    if not possible:
        return

    sum_damage = sum(
        req.damage(state.resources, state.resource_database) for req in damage)
    if state.energy < sum_damage:
        tank_count = (sum_damage -
                      state.energy) // state.game_data.energy_per_tank
        yield items + [
            ResourceRequirement.create(state.resource_database.energy_tank,
                                       tank_count + 1, False)
        ]
        # FIXME: get the required items for reductions (aka suits)
    else:
        yield items
Example #3
0
def pickups_to_solve_list(pickup_pool: list[PickupEntry],
                          requirement_list: RequirementList, state: State):
    pickups = []

    db = state.resource_database
    resources = state.resources.duplicate()
    pickups_for_this = list(pickup_pool)

    # Check pickups that give less items in total first
    # This means we test for expansions before the major items, in case both give the same resource
    # Useful to get Dark Beam Ammo Expansion instead of Dark Beam.
    pickups_for_this.sort(key=lambda p: sum(
        1 for _ in p.resource_gain(resources, force_lock=True)))

    for individual in sorted(requirement_list.values()):
        if individual.satisfied(resources, state.energy,
                                state.resource_database):
            continue

        # Create another copy of the list so we can remove elements while iterating
        for pickup in list(pickups_for_this):
            new_resources = ResourceCollection.from_resource_gain(
                db, pickup.resource_gain(resources, force_lock=True))
            pickup_progression = ResourceCollection.from_resource_gain(
                db, pickup.progression)
            if new_resources[individual.resource] + pickup_progression[
                    individual.resource] > 0:
                pickups.append(pickup)
                pickups_for_this.remove(pickup)
                resources.add_resource_gain(new_resources.as_resource_gain())

            if individual.satisfied(resources, state.energy,
                                    state.resource_database):
                break

        if not individual.satisfied(resources, state.energy,
                                    state.resource_database):
            return None

    return pickups