def get_pickups_that_solves_unreachable( pickups_left: List[PickupEntry], reach: GeneratorReach, uncollected_resource_nodes: List[ResourceNode], ) -> PickupCombinations: """New logic. Given pickup list and a reach, checks the combination of pickups that satisfies on unreachable nodes""" state = reach.state possible_sets = list(reach.unreachable_nodes_with_requirements().values()) context = reach.node_context() uncollected_resources = [ node.resource(context) for node in uncollected_resource_nodes ] all_lists = _requirement_lists_without_satisfied_resources( state, possible_sets, uncollected_resources) result = [] for requirement_list in sorted(all_lists, key=lambda it: it.as_stable_sort_tuple): pickups = pickups_to_solve_list(pickups_left, requirement_list, state) if pickups is not None and pickups: # FIXME: avoid duplicates in result result.append(tuple(pickups)) if debug.debug_level() > 2: print(">> All pickup combinations alternatives:") for items in sorted(result): print("* {}".format(", ".join(p.name for p in items))) return tuple(result)
def print_new_resources( game: GameDescription, reach: GeneratorReach, seen_count: dict[ResourceInfo, int], label: str, ): if debug.debug_level() > 1: world_list = game.world_list for index, count in seen_count.items(): if count == 1: node = find_node_with_resource(index, reach.node_context(), world_list.iterate_nodes()) print("-> New {}: {}".format( label, world_list.node_name(node, with_world=True)))
def collect_all_safe_resources_in_reach(reach: GeneratorReach) -> None: """ :param reach: :return: """ while True: actions = list(_get_safe_resources(reach)) if not actions: break for action in actions: if action.can_collect(reach.node_context()): # assert reach.is_safe_node(action) reach.advance_to(reach.state.act_on_node(action), is_safe=True)
def _get_safe_resources(reach: GeneratorReach) -> Iterator[ResourceNode]: yield from _filter_reachable( _filter_out_dangerous_actions( collectable_resource_nodes(reach.safe_nodes, reach), reach.game, reach.node_context()), reach)
def _filter_collectable(resource_nodes: Iterator[ResourceNode], reach: GeneratorReach) -> Iterator[ResourceNode]: for resource_node in resource_nodes: if resource_node.can_collect(reach.node_context()): yield resource_node