예제 #1
0
 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
예제 #4
0
    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