def test_adding_extra_report_format_multiple(self): with self.assert_output("Message: [<(Hello)>], extra: extra\n"): debugger = Debugger() with debugger.adding_extra_report_format( self.wrapping_debugger_format): with debugger.adding_extra_report_format( self.wrapping_debugger_format_2): with debugger.adding_extra_report_format( self.wrapping_debugger_format_3): debugger.default_report("Hello")
def get_min_step_count_to_target( self, start: str, target: str, debugger: Debugger = Debugger(enabled=False)) -> int: """ >>> MachineExtended.from_substitutions_text( ... "e => H\\n" ... "e => O\\n" ... "H => HO\\n" ... "H => OH\\n" ... "O => HH\\n" ... ).get_min_step_count_to_target("e", "HOH") 3 >>> MachineExtended.from_substitutions_text( ... "e => H\\n" ... "e => O\\n" ... "H => HO\\n" ... "H => OH\\n" ... "O => HH\\n" ... ).get_min_step_count_to_target("e", "HOHOHO") 6 """ def min_length_report_format(_debugger, message): return f"min length: {min_length}, {message}" min_length = None with debugger.adding_extra_report_format(min_length_report_format): for chain in self.get_all_possible_chains_to_target( start, target, debugger=debugger): chain_length = len(chain) - 1 if min_length is None or chain_length < min_length: min_length = chain_length return min_length
def find(self, debugger: Debugger = Debugger(enabled=False)) -> Paths: def reporting_format(_: Debugger, message: str) -> str: return ( f"{message} ({len(paths)} found, {len(seen)} seen, " f"{len(stack)} in stack)" ) paths = [] stack: List[CaveFinderStateT] = [self.get_state_class().make_initial()] seen = {stack[0]} with debugger.adding_extra_report_format(reporting_format): debugger.default_report("Looking...") while debugger.step_if(stack): debugger.default_report_if("Looking...") state = stack.pop(0) for next_state in state.get_next_states(self.system.graph): if next_state in seen: continue seen.add(next_state) if next_state.is_terminal: paths.append(next_state.path) continue stack.append(next_state) debugger.default_report("Finished looking") return paths
def find_min_mana_necessary( self, debugger: Debugger = Debugger(enabled=False), ) -> int: def reporting_format(_: Debugger, message: str) -> str: if min_mana_spent is None: min_mana_spent_str = "no winner yet" else: min_mana_spent_str = f"best is {min_mana_spent}" return f"{message} ({min_mana_spent_str}, {len(stack)} in stack)" with debugger.adding_extra_report_format(reporting_format): stack = [deepcopy(self)] min_mana_spent = None min_mana_game = None debugger.default_report_if("Searching for a winning game...") while debugger.step_if(stack): debugger.default_report_if("Searching for a winning game...") game = stack.pop(0) if min_mana_spent is not None \ and game.player.mana_spent >= min_mana_spent: continue next_games = game.get_next_games(debugger) for next_game in next_games: if (min_mana_spent is not None and next_game.player.mana_spent >= min_mana_spent): continue if next_game.winner == CharacterEnum.Player: min_mana_spent = next_game.player.mana_spent min_mana_game = next_game debugger.report(f"Better game found: {min_mana_spent}") stack.append(next_game) debugger.default_report(f"Finished searching") if min_mana_spent is None: raise Exception(f"Could not find a winning game") options_played_str = ', '.join( option.name for option in min_mana_game.options_played if isinstance(option, SpellEnum)) debugger.report(f"Min mana game moves: {options_played_str}") return min_mana_spent