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), ]
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
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