Exemplo n.º 1
0
    def test_get_nearest_choice__2_choices__second_choice(self):
        choice_1 = facts.Choice(uid='choice_1')

        choice_2 = facts.Choice(uid='choice_2')
        option_2_1 = facts.Option(state_from=choice_2.uid, state_to=self.state_1.uid, type='opt_2_1', markers=())
        option_2_2 = facts.Option(state_from=choice_2.uid, state_to=self.state_2.uid, type='opt_2_2', markers=())
        path_2 = facts.ChoicePath(choice=choice_2.uid, option=option_2_2.uid, default=True)

        option_1_1 = facts.Option(state_from=choice_1.uid, state_to=self.state_1.uid, type='opt_1_1', markers=())
        option_1_2 = facts.Option(state_from=choice_1.uid, state_to=choice_2.uid, type='opt_1_2', markers=())
        path_1 = facts.ChoicePath(choice=choice_1.uid, option=option_1_2.uid, default=True)

        self.kb += (choice_1,
                    option_1_1,
                    option_1_2,
                    path_1,

                    choice_2,
                    option_2_1,
                    option_2_2,
                    path_2,
                    facts.Jump(state_from=self.start.uid, state_to=choice_1.uid),

                    facts.Pointer(state=choice_2.uid)
            )

        choice_, options_, path_ = self.machine.get_nearest_choice()
        self.assertEqual(choice_.uid, choice_2.uid)
        self.assertEqual(set(o.uid for o in options_), set([option_2_1.uid, option_2_2.uid]))
        self.assertEqual([p.uid for p in path_], [path_2.uid])
Exemplo n.º 2
0
def change_choice(knowledge_base, new_option_uid, default):

    choice_uid = knowledge_base[new_option_uid].state_from

    knowledge_base -= [
        path for path in knowledge_base.filter(facts.ChoicePath)
        if path.choice == choice_uid
    ]
    knowledge_base += facts.ChoicePath(choice=choice_uid,
                                       option=new_option_uid,
                                       default=default)

    links = [
        link for link in knowledge_base.filter(facts.OptionsLink)
        if new_option_uid in link.options
    ]
    if links:
        link = links[0]
        for linked_option_uid in link.options:
            if new_option_uid == linked_option_uid:
                continue
            linked_choice_uid = knowledge_base[linked_option_uid].state_from

            knowledge_base -= [
                path for path in knowledge_base.filter(facts.ChoicePath)
                if path.choice == linked_choice_uid
            ]
            knowledge_base += facts.ChoicePath(choice=linked_choice_uid,
                                               option=linked_option_uid,
                                               default=default)

    return True
Exemplo n.º 3
0
    def get_choices(self, default=True):
        choice = self.quest.knowledge_base['[ns-0]choice_1']
        options = sorted((o for o in self.quest.knowledge_base.filter(facts.Option) if o.state_from == choice.uid),
                         key=lambda o: o.uid)
        defaults = [facts.ChoicePath(choice=choice.uid, option=options[-1].uid, default=default)]

        return choice, options, defaults
Exemplo n.º 4
0
    def test_sync_pointer(self):
        choice = facts.Choice(uid='choice')
        option_1 = facts.Option(state_from=choice.uid, state_to=self.state_1.uid, type='opt_1', markers=())
        option_2 = facts.Option(state_from=choice.uid, state_to=self.state_2.uid, type='opt_2', markers=())
        path = facts.ChoicePath(choice=choice.uid, option=option_2.uid, default=True)
        pointer = facts.Pointer(state=choice.uid, jump=option_1.uid)

        self.kb += (choice, option_1, option_2, path, pointer)

        calls_manager = mock.MagicMock()

        with mock.patch.object(self.machine.interpreter, 'on_state__before_actions') as on_state__before_actions:
            with mock.patch.object(self.machine.interpreter, 'on_state__after_actions') as on_state__after_actions:
                with mock.patch.object(self.machine.interpreter, 'on_jump_start__before_actions') as on_jump_start__before_actions:
                    with mock.patch.object(self.machine.interpreter, 'on_jump_start__after_actions') as on_jump_start__after_actions:
                        with mock.patch.object(self.machine.interpreter, 'on_jump_end__before_actions') as on_jump_end__before_actions:
                            with mock.patch.object(self.machine.interpreter, 'on_jump_end__after_actions') as on_jump_end__after_actions:

                                calls_manager.attach_mock(on_state__before_actions, 'on_state__before_actions')
                                calls_manager.attach_mock(on_state__after_actions, 'on_state__after_actions')
                                calls_manager.attach_mock(on_jump_start__before_actions, 'on_jump_start__before_actions')
                                calls_manager.attach_mock(on_jump_start__after_actions, 'on_jump_start__after_actions')
                                calls_manager.attach_mock(on_jump_end__before_actions, 'on_jump_end__before_actions')
                                calls_manager.attach_mock(on_jump_end__after_actions, 'on_jump_end__after_actions')

                                self.machine.sync_pointer()

                                self.assertEqual(calls_manager.mock_calls, [mock.call.on_jump_start__before_actions(jump=option_2),
                                                                            mock.call.on_jump_start__after_actions(jump=option_2)])

        self.assertEqual(self.machine.pointer.jump, option_2.uid)
        self.assertEqual(self.machine.pointer.state, choice.uid)
Exemplo n.º 5
0
    def test_get_available_jumps__for_choice_state(self):
        choice = facts.Choice(uid='choice')
        option_1 = facts.Option(state_from=choice.uid, state_to=self.state_1.uid, type='opt_1', markers=())
        option_2 = facts.Option(state_from=choice.uid, state_to=self.state_2.uid, type='opt_2', markers=())
        path = facts.ChoicePath(choice=choice.uid, option=option_2.uid, default=True)
        self.kb += (choice, option_1, option_2, path)

        for i in xrange(100):
            self.assertEqual(self.machine.get_available_jumps(choice), [option_2])
Exemplo n.º 6
0
    def test_get_nearest_choice__choice_after_finish(self):
        choice = facts.Choice(uid='choice')
        option_1 = facts.Option(state_from=choice.uid, state_to=self.state_1.uid, type='opt_1', markers=())
        option_2 = facts.Option(state_from=choice.uid, state_to=self.state_2.uid, type='opt_2', markers=())
        path = facts.ChoicePath(choice=choice.uid, option=option_2.uid, default=True)
        self.kb += (choice,
                    option_1,
                    option_2,
                    path,
                    facts.Jump(state_from=self.start.uid, state_to=self.finish_1.uid),
                    facts.Jump(state_from=self.finish_1.uid, state_to=choice.uid))

        self.assertEqual(self.machine.get_nearest_choice(), (None, None, None))
Exemplo n.º 7
0
def determine_default_choices(knowledge_base, preferred_markers=()):
    '''
    '''
    processed_choices = set()
    linked_options = {}
    restricted_options = set()  # options, that can not be used as default
    preferred_markers = set(preferred_markers)

    for link in knowledge_base.filter(facts.OptionsLink):
        for option_uid in link.options:
            if option_uid in linked_options:
                raise exceptions.OptionWithTwoLinksError(
                    option=knowledge_base[option_uid])
            linked_options[option_uid] = link

    for choice in knowledge_base.filter(facts.Choice):
        if choice.uid in processed_choices:
            continue

        processed_choices.add(choice.uid)

        options_choices = [
            option for option in knowledge_base.filter(facts.Option)
            if option.state_from == choice.uid
            and option.uid not in restricted_options
        ]

        if not options_choices:
            # if there no valid options (in valuid graph), then all options where cancels by other chocices
            # and we will no go to that state by defaul states (quest author responded for this)
            # TODO: make restriction, that check if we have full default path
            continue

        filtered_options_choices = []

        if preferred_markers:
            filtered_options_choices = [
                candidate for candidate in options_choices
                if set(candidate.markers) & preferred_markers
            ]

        if not filtered_options_choices:
            filtered_options_choices = options_choices

        default_option = random.choice(filtered_options_choices)

        if default_option.uid in linked_options:
            for linked_option_uid in linked_options[
                    default_option.uid].options:
                if linked_option_uid == default_option.uid:
                    continue

                # option can be removed by other transformations
                if linked_option_uid not in knowledge_base:
                    continue

                linked_choice_uid = knowledge_base[
                    linked_option_uid].state_from

                if linked_choice_uid in processed_choices:
                    raise exceptions.LinkedOptionWithProcessedChoiceError(
                        option=knowledge_base[linked_option_uid])

                processed_choices.add(linked_choice_uid)

                knowledge_base += facts.ChoicePath(choice=linked_choice_uid,
                                                   option=linked_option_uid,
                                                   default=True)

        # if add all options linked to unused to restricted_options
        for unused_option in options_choices:
            if unused_option.uid == default_option.uid:
                continue
            if unused_option.uid not in linked_options:
                continue
            for linked_option_uid in linked_options[unused_option.uid].options:
                restricted_options.add(linked_option_uid)

        knowledge_base += facts.ChoicePath(choice=choice.uid,
                                           option=default_option.uid,
                                           default=True)
Exemplo n.º 8
0
    def test_linked_choices(self):
        start = facts.Start(uid='start', type='test', nesting=0)
        choice_1 = facts.Choice(uid='choice_1')
        choice_2 = facts.Choice(uid='choice_2')
        finish_1 = facts.Finish(uid='finish_1',
                                results={},
                                nesting=0,
                                start='start')
        finish_2 = facts.Finish(uid='finish_2',
                                results={},
                                nesting=0,
                                start='start')

        option_1 = facts.Option(state_from=choice_1.uid,
                                state_to=finish_1.uid,
                                type='opt_1',
                                markers=())
        option_2 = facts.Option(state_from=choice_1.uid,
                                state_to=choice_2.uid,
                                type='opt_2',
                                markers=())

        option_2_1 = facts.Option(state_from=choice_2.uid,
                                  state_to=finish_1.uid,
                                  type='opt_2_1',
                                  markers=())
        option_2_2 = facts.Option(state_from=choice_2.uid,
                                  state_to=finish_2.uid,
                                  type='opt_2_2',
                                  markers=())

        facts_list = [
            start, choice_1, choice_2, finish_1, finish_2, option_1, option_2,
            option_2_1, option_2_2,
            facts.OptionsLink(options=(option_1.uid, option_2_1.uid)),
            facts.OptionsLink(options=(option_2.uid, option_2_2.uid))
        ]

        self.kb += facts_list

        choices = [
            facts.ChoicePath(choice=choice_1.uid,
                             option=option_2.uid,
                             default=True),
            facts.ChoicePath(choice=choice_2.uid,
                             option=option_2_2.uid,
                             default=True)
        ]

        self.kb += choices

        transformators.change_choice(self.kb, option_1.uid, default=False)

        self.check_in_knowledge_base(self.kb, facts_list)
        self.check_not_in_knowledge_base(self.kb, choices)

        self.assertEqual(len(list(self.kb.filter(facts.ChoicePath))), 2)
        self.assertEqual(
            len(set([path.choice
                     for path in self.kb.filter(facts.ChoicePath)])), 2)

        self.assertEqual(
            set([path.option for path in self.kb.filter(facts.ChoicePath)]),
            set([option_1.uid, option_2_1.uid]))