Пример #1
0
def get_knowledge_base(hero_info, without_restrictions=False):  # pylint: disable=R0912

    kb = KnowledgeBase()

    hero_uid = uids.hero(hero_info.id)

    kb += facts.Hero(uid=hero_uid, externals={'id': hero_info.id})

    setup_places(kb, hero_info)
    setup_persons(kb, hero_info)
    setup_preferences(kb, hero_info)
    setup_social_connections(kb)

    if not without_restrictions:

        for person in persons_storage.persons.all():
            if person.place.id == hero_info.position_place_id and person.id in hero_info.interfered_persons:
                kb += facts.NotFirstInitiator(person=uids.person(person.id))

    kb.validate_consistency(WORLD_RESTRICTIONS)

    kb += [
        facts.UpgradeEquipmentCost(
            money=QuestPrototype.upgrade_equipment_cost(hero_info))
    ]

    return kb
Пример #2
0
    def setUp(self):
        self.kb = KnowledgeBase()

        self.fact = Fact(uid='fact')
        self.fact_2 = Fact(uid='fact_2', description='cba')

        self.kb += [self.fact, self.fact_2]
Пример #3
0
    def test_linked_choices__linked_option_with_processed_choice(self):
        is_raised = False

        for i in xrange(100):
            kb = KnowledgeBase()
            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,
                facts.Jump(state_from=start.uid,
                           state_to=choice_1.uid), choice_1, choice_2,
                finish_1, finish_2, option_1, option_2, option_2_1, option_2_2,
                facts.OptionsLink(options=(option_2.uid, option_2_2.uid))
            ]

            kb += facts_list

            try:
                transformators.determine_default_choices(kb)
            except exceptions.LinkedOptionWithProcessedChoiceError:
                is_raised = True
                self.assertEqual(len(list(kb.filter(facts.ChoicePath))), 1)
                self.assertEqual(
                    [path.choice for path in kb.filter(facts.ChoicePath)],
                    [choice_2.uid])
                self.assertEqual(
                    [path.option for path in kb.filter(facts.ChoicePath)],
                    [option_2_1.uid])
                break

        self.assertFalse(is_raised)
Пример #4
0
 def test_serialize(self):
     self.assertEqual(self.kb.serialize(), KnowledgeBase.deserialize(self.kb.serialize(), FACTS).serialize())
     self.assertEqual(
         self.kb.serialize(short=True), KnowledgeBase.deserialize(self.kb.serialize(short=True), FACTS).serialize()
     )
     self.assertNotEqual(
         self.kb.serialize(), KnowledgeBase.deserialize(self.kb.serialize(short=True), FACTS).serialize()
     )
Пример #5
0
    def setUp(self):
        self.kb = KnowledgeBase()

        # world
        self.kb += [
            Place(uid='place_from'),
            Person(uid='person_from'),
            Place(uid='place_thought'),
            Place(uid='place_to'),
            Person(uid='person_to'),
            LocatedIn(object='person_from', place='place_from'),
            LocatedIn(object='person_to', place='place_to')
        ]

        # quest
        self.kb += [
            Start(uid='start',
                  nesting=0,
                  type='simple_test',
                  require=(requirements.LocatedIn(object='person_from',
                                                  place='place_from'),
                           requirements.LocatedIn(object='person_to',
                                                  place='place_to'),
                           requirements.LocatedIn(object='hero',
                                                  place='place_from'))),
            State(uid='st_throught_place',
                  require=(requirements.LocatedIn(object='hero',
                                                  place='place_thought'), )),
            Finish(uid='st_finish',
                   start='start',
                   results={},
                   nesting=0,
                   require=(requirements.LocatedIn(object='hero',
                                                   place='place_to'), )),
            Jump(state_from='start', state_to='st_throught_place'),
            Jump(state_from='st_throught_place', state_to='st_finish')
        ]

        self.kb += [Hero(uid='hero')]

        self.kb.validate_consistency([
            restrictions.SingleStartStateWithNoEnters(),
            restrictions.FinishStateExists(),
            restrictions.AllStatesHasJumps(),
            restrictions.SingleLocationForObject(),
            restrictions.ReferencesIntegrity(),
            restrictions.ConnectedStateJumpGraph(),
            restrictions.NoCirclesInStateJumpGraph(),
            restrictions.MultipleJumpsFromNormalState(),
            restrictions.ChoicesConsistency()
        ])

        self.machine = machine.Machine(knowledge_base=self.kb,
                                       interpreter=FakeInterpreter())
Пример #6
0
 def test_serialize(self):
     self.assertEqual(
         self.kb.serialize(),
         KnowledgeBase.deserialize(self.kb.serialize(), FACTS).serialize())
     self.assertEqual(
         self.kb.serialize(short=True),
         KnowledgeBase.deserialize(self.kb.serialize(short=True),
                                   FACTS).serialize())
     self.assertNotEqual(
         self.kb.serialize(),
         KnowledgeBase.deserialize(self.kb.serialize(short=True),
                                   FACTS).serialize())
Пример #7
0
    def setUp(self):
        self.kb = KnowledgeBase()

        self.hero = facts.Hero(uid='hero')

        self.start = facts.Start(uid='start', type='test', nesting=0)
        self.state_1 = facts.State(uid='state_1')
        self.state_2 = facts.State(uid='state_2')
        self.finish_1 = facts.Finish(start='start', uid='finish_1', results={}, nesting=0)

        self.kb += [ self.start, self.state_1, self.state_2, self.finish_1, self.hero]

        self.machine = Machine(knowledge_base=self.kb, interpreter=FakeInterpreter())
Пример #8
0
    def setUp(self):
        super(LogicTestsBase, self).setUp()

        self.place_1, self.place_2, self.place_3 = create_test_map()

        result, account_id, bundle_id = register_user('test_user')

        self.storage = LogicStorage()
        self.storage.load_account_data(AccountPrototype.get_by_id(account_id))
        self.hero = self.storage.accounts_to_heroes[account_id]

        self.hero_uid = uids.hero(self.hero.id)

        self.knowledge_base = KnowledgeBase()
Пример #9
0
    def setUp(self):
        super(LogicTestsBase, self).setUp()

        self.place_1, self.place_2, self.place_3 = create_test_map()

        account = self.accounts_factory.create_account(is_fast=True)

        self.storage = LogicStorage()
        self.storage.load_account_data(account)
        self.hero = self.storage.accounts_to_heroes[account.id]

        self.hero_uid = uids.hero(self.hero.id)

        self.knowledge_base = KnowledgeBase()
Пример #10
0
    def setUp(self):
        self.qb = QuestsBase()
        self.qb += [Simple]

        self.kb = KnowledgeBase()

        self.kb += [
            facts.Hero(uid='hero'),
            facts.Place(uid='place_1', terrains=(1, )),
            facts.Place(uid='place_2', terrains=(0, )),
            facts.Place(uid='place_3', terrains=(0, )),
            facts.Place(uid='place_4', terrains=(1, )),
            facts.Place(uid='place_5', terrains=(2, )),
            facts.Place(uid='place_6', terrains=(1, )),
            facts.Place(uid='place_7', terrains=(2, )),
            facts.Place(uid='place_8', terrains=(2, )),
            facts.Place(uid='place_9', terrains=(1, )),
            facts.Place(uid='place_10', terrains=(2, )),
            facts.Person(uid='person_1', profession=PROFESSION.NONE),
            facts.Person(uid='person_2', profession=PROFESSION.BLACKSMITH),
            facts.Person(uid='person_3', profession=PROFESSION.NONE),
            facts.Person(uid='person_4', profession=PROFESSION.NONE),
            facts.Person(uid='person_5', profession=PROFESSION.NONE),
            facts.Person(uid='person_6', profession=PROFESSION.NONE),
            facts.Person(uid='person_7', profession=PROFESSION.NONE),
            facts.Person(uid='person_8', profession=PROFESSION.NONE),
            facts.Person(uid='person_9', profession=PROFESSION.NONE),
            facts.Person(uid='person_10', profession=PROFESSION.NONE),
            facts.LocatedIn(object='person_1', place='place_1'),
            facts.LocatedIn(object='person_2', place='place_2'),
            facts.LocatedIn(object='person_3', place='place_3'),
            facts.LocatedIn(object='person_4', place='place_4'),
            facts.LocatedIn(object='person_5', place='place_5'),
            facts.LocatedIn(object='person_6', place='place_6'),
            facts.LocatedIn(object='person_7', place='place_7'),
            facts.LocatedIn(object='person_8', place='place_8'),
            facts.LocatedIn(object='person_9', place='place_9'),
            facts.LocatedIn(object='person_10', place='place_10'),
            facts.LocatedIn(object='hero', place='place_1'),
            facts.Mob(uid='mob_1', terrains=(0, )),
            facts.PreferenceMob(object='hero', mob='mob_1'),
            facts.PreferenceHometown(object='hero', place='place_2'),
            facts.PreferenceFriend(object='hero', person='person_4'),
            facts.PreferenceEnemy(object='hero', person='person_5'),
            facts.UpgradeEquipmentCost(money=777)
        ]

        self.selector = Selector(self.kb, self.qb)
Пример #11
0
    def setUp(self):
        self.kb = KnowledgeBase()

        self.fact = Fact(uid="fact")
        self.fact_2 = Fact(uid="fact_2", description=u"cba")

        self.kb += [self.fact, self.fact_2]
Пример #12
0
 def deserialize(cls, data):
     return cls(
         knowledge_base=KnowledgeBase.deserialize(data["knowledge_base"], fact_classes=facts.FACTS),
         quests_stack=[QuestInfo.deserialize(info_data) for info_data in data["quests_stack"]],
         created_at=datetime.datetime.fromtimestamp(data["created_at"]),
         states_to_percents=data["states_to_percents"],
     )
Пример #13
0
    def setUp(self):
        self.kb = KnowledgeBase()

        self.fact = Fact(uid='fact')
        self.fact_2 = Fact(uid='fact_2', description='cba')

        self.kb += [ self.fact,
                     self.fact_2 ]
Пример #14
0
    def test_linked_choices__linked_option_with_processed_choice(self):
        is_raised = False

        for i in xrange(100):
            kb = KnowledgeBase()
            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,
                facts.Jump(state_from=start.uid, state_to=choice_1.uid),
                choice_1,
                choice_2,
                finish_1,
                finish_2,
                option_1,
                option_2,
                option_2_1,
                option_2_2,
                facts.OptionsLink(options=(option_2.uid, option_2_2.uid)),
            ]

            kb += facts_list

            try:
                transformators.determine_default_choices(kb)
            except exceptions.LinkedOptionWithProcessedChoiceError:
                is_raised = True
                self.assertEqual(len(list(kb.filter(facts.ChoicePath))), 1)
                self.assertEqual([path.choice for path in kb.filter(facts.ChoicePath)], [choice_2.uid])
                self.assertEqual([path.option for path in kb.filter(facts.ChoicePath)], [option_2_1.uid])
                break

        self.assertFalse(is_raised)
Пример #15
0
 def deserialize(cls, data):
     return cls(
         knowledge_base=KnowledgeBase.deserialize(data['knowledge_base'],
                                                  fact_classes=facts.FACTS),
         quests_stack=[
             QuestInfo.deserialize(info_data)
             for info_data in data['quests_stack']
         ],
         created_at=datetime.datetime.fromtimestamp(data['created_at']),
         states_to_percents=data['states_to_percents'])
Пример #16
0
    def setUp(self):
        self.qb = QuestsBase()
        self.qb += [Simple]

        self.kb = KnowledgeBase()

        self.kb += [ facts.Hero(uid='hero'),

            facts.Place(uid='place_1', terrains=(1,)),
            facts.Place(uid='place_2', terrains=(0,)),
            facts.Place(uid='place_3', terrains=(0,)),
            facts.Place(uid='place_4', terrains=(1,)),
            facts.Place(uid='place_5', terrains=(2,)),
            facts.Place(uid='place_6', terrains=(1,)),
            facts.Place(uid='place_7', terrains=(2,)),
            facts.Place(uid='place_8', terrains=(2,)),
            facts.Place(uid='place_9', terrains=(1,)),
            facts.Place(uid='place_10', terrains=(2,)),

            facts.Person(uid='person_1', profession=PROFESSION.NONE),
            facts.Person(uid='person_2', profession=PROFESSION.BLACKSMITH),
            facts.Person(uid='person_3', profession=PROFESSION.NONE),
            facts.Person(uid='person_4', profession=PROFESSION.NONE),
            facts.Person(uid='person_5', profession=PROFESSION.NONE),
            facts.Person(uid='person_6', profession=PROFESSION.NONE),
            facts.Person(uid='person_7', profession=PROFESSION.NONE),
            facts.Person(uid='person_8', profession=PROFESSION.NONE),
            facts.Person(uid='person_9', profession=PROFESSION.NONE),
            facts.Person(uid='person_10', profession=PROFESSION.NONE),

            facts.LocatedIn(object='person_1', place='place_1'),
            facts.LocatedIn(object='person_2', place='place_2'),
            facts.LocatedIn(object='person_3', place='place_3'),
            facts.LocatedIn(object='person_4', place='place_4'),
            facts.LocatedIn(object='person_5', place='place_5'),
            facts.LocatedIn(object='person_6', place='place_6'),
            facts.LocatedIn(object='person_7', place='place_7'),
            facts.LocatedIn(object='person_8', place='place_8'),
            facts.LocatedIn(object='person_9', place='place_9'),
            facts.LocatedIn(object='person_10', place='place_10'),

            facts.LocatedIn(object='hero', place='place_1'),

            facts.Mob(uid='mob_1', terrains=(0,)),
            facts.PreferenceMob(object='hero', mob='mob_1'),
            facts.PreferenceHometown(object='hero', place='place_2'),
            facts.PreferenceFriend(object='hero', person='person_4'),
            facts.PreferenceEnemy(object='hero', person='person_5'),
            facts.UpgradeEquipmentCost(money=777)
            ]

        self.selector = Selector(self.kb, self.qb)
Пример #17
0
    def setUp(self):
        self.kb = KnowledgeBase()

        self.hero = facts.Hero(uid='hero')

        self.start = facts.Start(uid='start', type='test', nesting=0)
        self.state_1 = facts.State(uid='state_1')
        self.state_2 = facts.State(uid='state_2')
        self.finish_1 = facts.Finish(start='start', uid='finish_1', results={}, nesting=0)

        self.kb += [ self.start, self.state_1, self.state_2, self.finish_1, self.hero]

        self.machine = Machine(knowledge_base=self.kb, interpreter=FakeInterpreter())
Пример #18
0
    def setUp(self):
        super(LogicTestsBase, self).setUp()

        self.place_1, self.place_2, self.place_3 = create_test_map()

        result, account_id, bundle_id = register_user('test_user')

        self.storage = LogicStorage()
        self.storage.load_account_data(AccountPrototype.get_by_id(account_id))
        self.hero = self.storage.accounts_to_heroes[account_id]

        self.hero_uid = uids.hero(self.hero.id)

        self.knowledge_base = KnowledgeBase()
Пример #19
0
    def setUp(self):
        super(LogicTestsBase, self).setUp()

        self.place_1, self.place_2, self.place_3 = create_test_map()

        account = self.accounts_factory.create_account(is_fast=True)

        self.storage = LogicStorage()
        self.storage.load_account_data(account)
        self.hero = self.storage.accounts_to_heroes[account.id]

        self.hero_uid = uids.hero(self.hero.id)

        self.knowledge_base = KnowledgeBase()
Пример #20
0
def get_knowledge_base(hero_info, without_restrictions=False): # pylint: disable=R0912

    kb = KnowledgeBase()

    hero_uid = uids.hero(hero_info.id)

    kb += facts.Hero(uid=hero_uid, externals={'id': hero_info.id})

    setup_places(kb, hero_info)
    setup_persons(kb, hero_info)
    setup_preferences(kb, hero_info)
    setup_social_connections(kb)

    if not without_restrictions:

        for person in persons_storage.persons_storage.filter(state=PERSON_STATE.IN_GAME):
            if person.place.id == hero_info.position_place_id and person.id in hero_info.interfered_persons:
                kb += facts.NotFirstInitiator(person=uids.person(person.id))

    kb.validate_consistency(WORLD_RESTRICTIONS)

    kb += [facts.UpgradeEquipmentCost(money=QuestPrototype.upgrade_equipment_cost(hero_info))]

    return kb
Пример #21
0
def setup_quest_for_hero(hero, knowledge_base_data):

    # do nothing if hero has already had quest
    if not hero.actions.current_action.searching_quest:
        return

    knowledge_base = KnowledgeBase.deserialize(knowledge_base_data, fact_classes=facts.FACTS)

    states_to_percents = analysers.percents_collector(knowledge_base)

    quest = QuestPrototype(hero=hero, knowledge_base=knowledge_base, states_to_percents=states_to_percents)

    if quest.machine.can_do_step():
        quest.machine.step() # do first step to setup pointer

    hero.actions.current_action.setup_quest(quest)
Пример #22
0
    def setUp(self):
        self.kb = KnowledgeBase()

        # world
        self.kb += [ Place(uid='place_from'),
                     Person(uid='person_from'),
                     Place(uid='place_thought'),
                     Place(uid='place_to'),
                     Person(uid='person_to'),
                     LocatedIn(object='person_from', place='place_from'),
                     LocatedIn(object='person_to', place='place_to')]

        # quest
        self.kb += [ Start(uid='start',
                           nesting=0,
                           type='simple_test',
                           require=(requirements.LocatedIn(object='person_from', place='place_from'),
                                    requirements.LocatedIn(object='person_to', place='place_to'),
                                    requirements.LocatedIn(object='hero', place='place_from'))),

                     State(uid='st_throught_place',
                           require=(requirements.LocatedIn(object='hero', place='place_thought'),)),

                     Finish(uid='st_finish',
                            start='start',
                            results={},
                            nesting=0,
                            require=(requirements.LocatedIn(object='hero', place='place_to'),)),

                     Jump(state_from='start', state_to='st_throught_place'),
                     Jump(state_from='st_throught_place', state_to='st_finish') ]

        self.kb += [ Hero(uid='hero') ]

        self.kb.validate_consistency([restrictions.SingleStartStateWithNoEnters(),
                                      restrictions.FinishStateExists(),
                                      restrictions.AllStatesHasJumps(),
                                      restrictions.SingleLocationForObject(),
                                      restrictions.ReferencesIntegrity(),
                                      restrictions.ConnectedStateJumpGraph(),
                                      restrictions.NoCirclesInStateJumpGraph(),
                                      restrictions.MultipleJumpsFromNormalState(),
                                      restrictions.ChoicesConsistency()])

        self.machine = machine.Machine(knowledge_base=self.kb, interpreter=FakeInterpreter())
Пример #23
0
    def setUp(self):
        self.kb = KnowledgeBase()

        self.kb += [
            facts.Hero(uid='hero'),
            facts.Hero(uid='hero_2'),
            facts.Place(uid='place_1', terrains=(1, ), type=11),
            facts.Place(uid='place_2', terrains=(0, ), type=22),
            facts.Place(uid='place_3', terrains=(0, ), type=33),
            facts.Person(uid='person_1', profession=0),
            facts.Person(uid='person_2', profession=1),
            facts.Person(uid='person_3', profession=2),
            facts.LocatedIn(object='person_1', place='place_1'),
            facts.LocatedIn(object='person_2', place='place_2'),
            facts.LocatedIn(object='person_3', place='place_3'),
            facts.Mob(uid='mob_1', terrains=(0, ))
        ]

        self.selector = selectors.Selector(self.kb, None)
Пример #24
0
def setup_quest_for_hero(hero, knowledge_base_data):

    # do nothing if hero has already had quest
    if not hero.actions.current_action.searching_quest:
        return

    knowledge_base = KnowledgeBase.deserialize(knowledge_base_data,
                                               fact_classes=facts.FACTS)

    states_to_percents = analysers.percents_collector(knowledge_base)

    quest = QuestPrototype(hero=hero,
                           knowledge_base=knowledge_base,
                           states_to_percents=states_to_percents)

    if quest.machine.can_do_step():
        quest.machine.step()  # do first step to setup pointer

    hero.actions.current_action.setup_quest(quest)
Пример #25
0
class MachineTests(unittest.TestCase):

    def setUp(self):
        self.kb = KnowledgeBase()

        self.hero = facts.Hero(uid='hero')

        self.start = facts.Start(uid='start', type='test', nesting=0)
        self.state_1 = facts.State(uid='state_1')
        self.state_2 = facts.State(uid='state_2')
        self.finish_1 = facts.Finish(start='start', uid='finish_1', results={}, nesting=0)

        self.kb += [ self.start, self.state_1, self.state_2, self.finish_1, self.hero]

        self.machine = Machine(knowledge_base=self.kb, interpreter=FakeInterpreter())

    def test_get_pointer(self):
        self.assertEqual(list(self.kb.filter(facts.Pointer)), [])
        pointer = self.machine.pointer
        self.assertEqual(list(self.kb.filter(facts.Pointer)), [pointer])

    def test_get_available_jumps__no_jumps(self):
        self.assertEqual(self.machine.get_available_jumps(self.start), [])

    def test_get_available_jumps__all_jumps(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        jump_2 = facts.Jump(state_from=self.start.uid, state_to=self.state_2.uid)
        self.kb += [jump_1, jump_2]

        self.assertEqual(set(jump.uid for jump in self.machine.get_available_jumps(self.start)),
                         set([jump_1.uid, jump_2.uid]))

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

    def test_get_available_jumps__for_question_state(self):
        condition = requirements.LocatedIn(object='object', place='place')

        question = facts.Question(uid='choice', condition=[condition])
        answer_1 = facts.Answer(state_from=question.uid, state_to=self.state_1.uid, condition=True)
        answer_2 = facts.Answer(state_from=question.uid, state_to=self.state_2.uid, condition=False)
        self.kb += (question, answer_1, answer_2)

        with mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_located_in=False)):
            for i in xrange(100):
                self.assertEqual(self.machine.get_available_jumps(question), [answer_2])

        with mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_located_in=True)):
            for i in xrange(100):
                self.assertEqual(self.machine.get_available_jumps(question), [answer_1])

    def test_get_next_jump__no_jumps(self):
        self.assertRaises(exceptions.NoJumpsAvailableError,
                          self.machine.get_next_jump, self.start)

    def test_get_next_jump__all_jumps(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        jump_2 = facts.Jump(state_from=self.start.uid, state_to=self.state_2.uid)
        self.kb += [jump_1, jump_2]

        jumps = set()

        for i in xrange(100):
            jumps.add(self.machine.get_next_jump(self.start, single=False).uid)

        self.assertEqual(jumps, set([jump_1.uid, jump_2.uid]))

    def test_get_next_jump__require_one_jump__exception(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        jump_2 = facts.Jump(state_from=self.start.uid, state_to=self.state_2.uid)
        self.kb += [jump_1, jump_2]

        self.assertRaises(exceptions.MoreThenOneJumpsAvailableError, self.machine.get_next_jump, self.start, single=True)

    def test_get_next_jump__require_one_jump(self):
        jump = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        self.kb += jump
        self.assertEqual(self.machine.get_next_jump(self.start, single=True).uid, jump.uid)

    def test_can_do_step__no_pointer(self):
        self.assertEqual(list(self.kb.filter(facts.Pointer)), [])
        self.assertTrue(self.machine.can_do_step())

    @mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_is_alive=False))
    def test_can_do_step__requirement_failed(self):
        state_3 = facts.State(uid='state_3', require=[requirements.IsAlive(object='hero')])
        jump_3 = facts.Jump(state_from=self.start.uid, state_to=state_3.uid)
        self.kb += [ state_3, jump_3]

        pointer = self.machine.pointer
        self.kb -= pointer
        self.kb += pointer.change(state=self.start.uid, jump=jump_3.uid)

        self.assertFalse(self.machine.can_do_step())

    def test_can_do_step__success(self):
        state_3 = facts.State(uid='state_3', require=[requirements.IsAlive(object='hero')])
        jump_3 = facts.Jump(state_from=self.start.uid, state_to=state_3.uid)
        self.kb += [ state_3, jump_3]

        pointer = self.machine.pointer
        self.kb -= pointer
        self.kb += pointer.change(state=self.start.uid, jump=jump_3.uid)

        with mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_is_alive=True)):
            self.assertTrue(self.machine.can_do_step())


    def test_do_step__no_pointer(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        jump_2 = facts.Jump(state_from=self.state_1.uid, state_to=self.state_2.uid)
        self.kb += [jump_1, jump_2]

        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.assertEqual(list(self.kb.filter(facts.Pointer)), [])
                                self.machine.step()
                                self.assertEqual(len(list(self.kb.filter(facts.Pointer))), 1)

                                self.assertEqual(calls_manager.mock_calls, [mock.call.on_state__before_actions(state=self.start),
                                                                            mock.call.on_state__after_actions(state=self.start)])

        pointer = self.machine.pointer
        self.assertEqual(pointer.state, self.start.uid)
        self.assertEqual(pointer.jump, None)


    def test_do_step__finish(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.finish_1.uid)
        self.kb += jump_1

        self.machine.step()
        self.machine.step()

        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.step()

                                self.assertEqual(calls_manager.mock_calls, [mock.call.on_jump_end__before_actions(jump=jump_1),
                                                                            mock.call.on_jump_end__after_actions(jump=jump_1),
                                                                            mock.call.on_state__before_actions(state=self.finish_1),
                                                                            mock.call.on_state__after_actions(state=self.finish_1)])

        pointer = self.machine.pointer
        self.assertEqual(pointer.state, self.finish_1.uid)
        self.assertEqual(pointer.jump, None)

    def test_do_step__step_after_finish(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.finish_1.uid)
        self.kb += jump_1

        self.machine.step()
        self.machine.step()
        self.machine.step()

        self.assertRaises(exceptions.NoJumpsFromLastStateError, self.machine.step)

    def test_do_step__next_jump(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        jump_2 = facts.Jump(state_from=self.state_1.uid, state_to=self.state_2.uid)
        self.kb += [jump_1, jump_2]

        self.machine.step()

        calls_manager = mock.MagicMock()

        pointer = self.machine.pointer
        self.assertEqual(pointer.state, self.start.uid)
        self.assertEqual(pointer.jump, None)

        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.step()

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

        pointer = self.machine.pointer
        self.assertEqual(pointer.state, self.start.uid)
        self.assertEqual(pointer.jump, jump_1.uid)

    def test_do_step__next_state(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        jump_2 = facts.Jump(state_from=self.state_1.uid, state_to=self.state_2.uid)
        self.kb += [jump_1, jump_2]

        self.machine.step()
        self.machine.step()
        self.machine.step()

        pointer = self.machine.pointer
        self.assertEqual(pointer.state, self.state_1.uid)
        self.assertEqual(pointer.jump, None)

        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.step()

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

        pointer = self.machine.pointer
        self.assertEqual(pointer.state, self.state_1.uid)
        self.assertEqual(pointer.jump, jump_2.uid)

    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)

    def test_get_start_state(self):
        start_2 = facts.Start(uid='s2', type='test', nesting=0)
        start_3 = facts.Start(uid='start_3', type='test', nesting=0)


        self.kb += [ start_2,
                     start_3,
                     facts.Jump(state_from=self.start.uid, state_to=start_2.uid),
                     facts.Jump(state_from=start_3.uid, state_to=self.start.uid) ]

        self.assertEqual(self.machine.get_start_state().uid, start_3.uid)

    def test_get_nearest_choice__no_choice(self):
        self.kb += facts.Jump(state_from=self.start.uid, state_to=self.finish_1.uid)
        self.assertEqual(self.machine.get_nearest_choice(), (None, None, None))

    def test_get_nearest_choice__choice(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=choice.uid)    )

        choice_, options_, path_ = self.machine.get_nearest_choice()
        self.assertEqual(choice_.uid, choice.uid)
        self.assertEqual(set(o.uid for o in options_), set([option_1.uid, option_2.uid]))
        self.assertEqual([p.uid for p in path_], [path.uid])

    def test_get_nearest_choice__2_choices(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),
            )

        choice_, options_, path_ = self.machine.get_nearest_choice()
        self.assertEqual(choice_.uid, choice_1.uid)
        self.assertEqual(set(o.uid for o in options_), set([option_1_1.uid, option_1_2.uid]))
        self.assertEqual([p.uid for p in path_], [path_1.uid])

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

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

    def test_get_nearest_choice__choice_after_question(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)

        question = facts.Question(uid='question', condition=())

        self.kb += (choice,
                    option_1,
                    option_2,
                    path,
                    question,
                    facts.Jump(state_from=self.start.uid, state_to=question.uid),
                    facts.Jump(state_from=question.uid, state_to=choice.uid))

        self.assertEqual(self.machine.get_nearest_choice(), (None, None, None))

    def test_get_nearest_choice__choice_after_start(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)
        start_2 = facts.Start(uid='start_2', type='test', nesting=0)
        self.kb += (choice,
                    option_1,
                    option_2,
                    path,
                    start_2,
                    facts.Jump(state_from=self.start.uid, state_to=start_2.uid),
                    facts.Jump(state_from=start_2.uid, state_to=choice.uid))

        self.assertEqual(self.machine.get_nearest_choice(), (None, None, None))


    @mock.patch('questgen.machine.Machine.can_do_step', lambda self: True)
    def test_do_step__step_done(self):
        with mock.patch('questgen.machine.Machine.step') as step:
            self.assertTrue(self.machine.do_step())

        self.assertEqual(step.call_args_list, [mock.call()])

    @mock.patch('questgen.machine.Machine.can_do_step', lambda self: False)
    @mock.patch('questgen.machine.Machine.is_processed', True)
    def test_do_step__quest_processed(self):
        with mock.patch('questgen.machine.Machine.step') as step:
            self.assertFalse(self.machine.do_step())

        self.assertEqual(step.call_args_list, [])

    @mock.patch('questgen.machine.Machine.can_do_step', lambda self: False)
    @mock.patch('questgen.machine.Machine.is_processed', False)
    @mock.patch('questgen.machine.Machine.next_state', 'next-state')
    def test_do_step__satisfy_requirements(self):
        with mock.patch('questgen.machine.Machine.step') as step:
            with mock.patch('questgen.machine.Machine.satisfy_requirements') as satisfy_requirements:
                self.assertTrue(self.machine.do_step())

        self.assertEqual(step.call_args_list, [])
        self.assertEqual(satisfy_requirements.call_args_list, [mock.call('next-state')])
Пример #26
0
class MachineTests(unittest.TestCase):

    def setUp(self):
        self.kb = KnowledgeBase()

        self.hero = facts.Hero(uid='hero')

        self.start = facts.Start(uid='start', type='test', nesting=0)
        self.state_1 = facts.State(uid='state_1')
        self.state_2 = facts.State(uid='state_2')
        self.finish_1 = facts.Finish(start='start', uid='finish_1', results={}, nesting=0)

        self.kb += [ self.start, self.state_1, self.state_2, self.finish_1, self.hero]

        self.machine = Machine(knowledge_base=self.kb, interpreter=FakeInterpreter())

    def test_get_pointer(self):
        self.assertEqual(list(self.kb.filter(facts.Pointer)), [])
        pointer = self.machine.pointer
        self.assertEqual(list(self.kb.filter(facts.Pointer)), [pointer])

    def test_get_available_jumps__no_jumps(self):
        self.assertEqual(self.machine.get_available_jumps(self.start), [])

    def test_get_available_jumps__all_jumps(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        jump_2 = facts.Jump(state_from=self.start.uid, state_to=self.state_2.uid)
        self.kb += [jump_1, jump_2]

        self.assertEqual(set(jump.uid for jump in self.machine.get_available_jumps(self.start)),
                         set([jump_1.uid, jump_2.uid]))

    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 range(100):
            self.assertEqual(self.machine.get_available_jumps(choice), [option_2])

    def test_get_available_jumps__for_question_state(self):
        condition = requirements.LocatedIn(object='object', place='place')

        question = facts.Question(uid='choice', condition=[condition])
        answer_1 = facts.Answer(state_from=question.uid, state_to=self.state_1.uid, condition=True)
        answer_2 = facts.Answer(state_from=question.uid, state_to=self.state_2.uid, condition=False)
        self.kb += (question, answer_1, answer_2)

        with mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_located_in=False)):
            for i in range(100):
                self.assertEqual(self.machine.get_available_jumps(question), [answer_2])

        with mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_located_in=True)):
            for i in range(100):
                self.assertEqual(self.machine.get_available_jumps(question), [answer_1])

    def test_get_next_jump__no_jumps(self):
        self.assertRaises(exceptions.NoJumpsAvailableError,
                          self.machine.get_next_jump, self.start)

    def test_get_next_jump__all_jumps(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        jump_2 = facts.Jump(state_from=self.start.uid, state_to=self.state_2.uid)
        self.kb += [jump_1, jump_2]

        jumps = set()

        for i in range(100):
            jumps.add(self.machine.get_next_jump(self.start, single=False).uid)

        self.assertEqual(jumps, set([jump_1.uid, jump_2.uid]))

    def test_get_next_jump__require_one_jump__exception(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        jump_2 = facts.Jump(state_from=self.start.uid, state_to=self.state_2.uid)
        self.kb += [jump_1, jump_2]

        self.assertRaises(exceptions.MoreThenOneJumpsAvailableError, self.machine.get_next_jump, self.start, single=True)

    def test_get_next_jump__require_one_jump(self):
        jump = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        self.kb += jump
        self.assertEqual(self.machine.get_next_jump(self.start, single=True).uid, jump.uid)

    def test_can_do_step__no_pointer(self):
        self.assertEqual(list(self.kb.filter(facts.Pointer)), [])
        self.assertTrue(self.machine.can_do_step())

    @mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_is_alive=False))
    def test_can_do_step__requirement_failed(self):
        state_3 = facts.State(uid='state_3', require=[requirements.IsAlive(object='hero')])
        jump_3 = facts.Jump(state_from=self.start.uid, state_to=state_3.uid)
        self.kb += [ state_3, jump_3]

        pointer = self.machine.pointer
        self.kb -= pointer
        self.kb += pointer.change(state=self.start.uid, jump=jump_3.uid)

        self.assertFalse(self.machine.can_do_step())

    def test_can_do_step__success(self):
        state_3 = facts.State(uid='state_3', require=[requirements.IsAlive(object='hero')])
        jump_3 = facts.Jump(state_from=self.start.uid, state_to=state_3.uid)
        self.kb += [ state_3, jump_3]

        pointer = self.machine.pointer
        self.kb -= pointer
        self.kb += pointer.change(state=self.start.uid, jump=jump_3.uid)

        with mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_is_alive=True)):
            self.assertTrue(self.machine.can_do_step())


    def test_do_step__no_pointer(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        jump_2 = facts.Jump(state_from=self.state_1.uid, state_to=self.state_2.uid)
        self.kb += [jump_1, jump_2]

        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.assertEqual(list(self.kb.filter(facts.Pointer)), [])
                                self.machine.step()
                                self.assertEqual(len(list(self.kb.filter(facts.Pointer))), 1)

                                self.assertEqual(calls_manager.mock_calls, [mock.call.on_state__before_actions(state=self.start),
                                                                            mock.call.on_state__after_actions(state=self.start)])

        pointer = self.machine.pointer
        self.assertEqual(pointer.state, self.start.uid)
        self.assertEqual(pointer.jump, None)


    def test_do_step__finish(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.finish_1.uid)
        self.kb += jump_1

        self.machine.step()
        self.machine.step()

        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.step()

                                self.assertEqual(calls_manager.mock_calls, [mock.call.on_jump_end__before_actions(jump=jump_1),
                                                                            mock.call.on_jump_end__after_actions(jump=jump_1),
                                                                            mock.call.on_state__before_actions(state=self.finish_1),
                                                                            mock.call.on_state__after_actions(state=self.finish_1)])

        pointer = self.machine.pointer
        self.assertEqual(pointer.state, self.finish_1.uid)
        self.assertEqual(pointer.jump, None)

    def test_do_step__step_after_finish(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.finish_1.uid)
        self.kb += jump_1

        self.machine.step()
        self.machine.step()
        self.machine.step()

        self.assertRaises(exceptions.NoJumpsFromLastStateError, self.machine.step)

    def test_do_step__next_jump(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        jump_2 = facts.Jump(state_from=self.state_1.uid, state_to=self.state_2.uid)
        self.kb += [jump_1, jump_2]

        self.machine.step()

        calls_manager = mock.MagicMock()

        pointer = self.machine.pointer
        self.assertEqual(pointer.state, self.start.uid)
        self.assertEqual(pointer.jump, None)

        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.step()

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

        pointer = self.machine.pointer
        self.assertEqual(pointer.state, self.start.uid)
        self.assertEqual(pointer.jump, jump_1.uid)

    def test_do_step__next_state(self):
        jump_1 = facts.Jump(state_from=self.start.uid, state_to=self.state_1.uid)
        jump_2 = facts.Jump(state_from=self.state_1.uid, state_to=self.state_2.uid)
        self.kb += [jump_1, jump_2]

        self.machine.step()
        self.machine.step()
        self.machine.step()

        pointer = self.machine.pointer
        self.assertEqual(pointer.state, self.state_1.uid)
        self.assertEqual(pointer.jump, None)

        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.step()

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

        pointer = self.machine.pointer
        self.assertEqual(pointer.state, self.state_1.uid)
        self.assertEqual(pointer.jump, jump_2.uid)

    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)

    def test_get_start_state(self):
        start_2 = facts.Start(uid='s2', type='test', nesting=0)
        start_3 = facts.Start(uid='start_3', type='test', nesting=0)


        self.kb += [ start_2,
                     start_3,
                     facts.Jump(state_from=self.start.uid, state_to=start_2.uid),
                     facts.Jump(state_from=start_3.uid, state_to=self.start.uid) ]

        self.assertEqual(self.machine.get_start_state().uid, start_3.uid)

    def test_get_nearest_choice__no_choice(self):
        self.kb += facts.Jump(state_from=self.start.uid, state_to=self.finish_1.uid)
        self.assertEqual(self.machine.get_nearest_choice(), (None, None, None))

    def test_get_nearest_choice__choice(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=choice.uid)    )

        choice_, options_, path_ = self.machine.get_nearest_choice()
        self.assertEqual(choice_.uid, choice.uid)
        self.assertEqual(set(o.uid for o in options_), set([option_1.uid, option_2.uid]))
        self.assertEqual([p.uid for p in path_], [path.uid])

    def test_get_nearest_choice__2_choices(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),
            )

        choice_, options_, path_ = self.machine.get_nearest_choice()
        self.assertEqual(choice_.uid, choice_1.uid)
        self.assertEqual(set(o.uid for o in options_), set([option_1_1.uid, option_1_2.uid]))
        self.assertEqual([p.uid for p in path_], [path_1.uid])

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

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

    def test_get_nearest_choice__choice_after_question(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)

        question = facts.Question(uid='question', condition=())

        self.kb += (choice,
                    option_1,
                    option_2,
                    path,
                    question,
                    facts.Jump(state_from=self.start.uid, state_to=question.uid),
                    facts.Jump(state_from=question.uid, state_to=choice.uid))

        self.assertEqual(self.machine.get_nearest_choice(), (None, None, None))

    def test_get_nearest_choice__choice_after_start(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)
        start_2 = facts.Start(uid='start_2', type='test', nesting=0)
        self.kb += (choice,
                    option_1,
                    option_2,
                    path,
                    start_2,
                    facts.Jump(state_from=self.start.uid, state_to=start_2.uid),
                    facts.Jump(state_from=start_2.uid, state_to=choice.uid))

        self.assertEqual(self.machine.get_nearest_choice(), (None, None, None))


    @mock.patch('questgen.machine.Machine.can_do_step', lambda self: True)
    def test_do_step__step_done(self):
        with mock.patch('questgen.machine.Machine.step') as step:
            self.assertTrue(self.machine.do_step())

        self.assertEqual(step.call_args_list, [mock.call()])

    @mock.patch('questgen.machine.Machine.can_do_step', lambda self: False)
    @mock.patch('questgen.machine.Machine.is_processed', True)
    def test_do_step__quest_processed(self):
        with mock.patch('questgen.machine.Machine.step') as step:
            self.assertFalse(self.machine.do_step())

        self.assertEqual(step.call_args_list, [])

    @mock.patch('questgen.machine.Machine.can_do_step', lambda self: False)
    @mock.patch('questgen.machine.Machine.is_processed', False)
    @mock.patch('questgen.machine.Machine.next_state', 'next-state')
    def test_do_step__satisfy_requirements(self):
        with mock.patch('questgen.machine.Machine.step') as step:
            with mock.patch('questgen.machine.Machine.satisfy_requirements') as satisfy_requirements:
                self.assertTrue(self.machine.do_step())

        self.assertEqual(step.call_args_list, [])
        self.assertEqual(satisfy_requirements.call_args_list, [mock.call('next-state')])
Пример #27
0
class KnowledgeBaseTests(unittest.TestCase):
    def setUp(self):
        self.kb = KnowledgeBase()

        self.fact = Fact(uid='fact')
        self.fact_2 = Fact(uid='fact_2', description='cba')

        self.kb += [self.fact, self.fact_2]

    def test_serialize(self):
        self.assertEqual(
            self.kb.serialize(),
            KnowledgeBase.deserialize(self.kb.serialize(), FACTS).serialize())
        self.assertEqual(
            self.kb.serialize(short=True),
            KnowledgeBase.deserialize(self.kb.serialize(short=True),
                                      FACTS).serialize())
        self.assertNotEqual(
            self.kb.serialize(),
            KnowledgeBase.deserialize(self.kb.serialize(short=True),
                                      FACTS).serialize())

    def test_contains__for_child(self):
        self.assertTrue('fact' in self.kb)
        self.assertFalse('wrong uid' in self.kb)

    def test_getitem__for_child(self):
        self.assertEqual(self.kb['fact'].uid, 'fact')
        self.assertRaises(exceptions.NoFactError, self.kb.__getitem__,
                          'wrong uid')

    def test_get__for_child(self):
        self.assertEqual(self.kb.get('fact').uid, 'fact')
        self.assertEqual(self.kb.get('wrong uid'), None)

    def test_delitem__no_item(self):
        self.assertRaises(exceptions.NoFactError, self.kb.__delitem__,
                          'wrong_fact')

    def test_delitem(self):
        del self.kb['fact']
        self.assertFalse('fact' in self.kb)

    def test_add_fact__list(self):
        self.kb += [Fact(uid='fact 1'), Fact(uid='fact 2')]
        self.assertTrue('fact 1' in self.kb)
        self.assertTrue('fact 2' in self.kb)

    def test_add_fact__duplicate_fact(self):
        self.assertRaises(exceptions.DuplicatedFactError, self.kb.__iadd__,
                          self.fact)

    def test_add_fact__wrong_type(self):
        self.assertRaises(exceptions.WrongFactTypeError, self.kb.__iadd__,
                          'some string')

    def test_add_fact__wrong_type_for_nested_lists(self):
        self.assertRaises(exceptions.WrongFactTypeError, self.kb.__iadd__,
                          [[Fact(uid='some fact')]])

    def test_remove_fact__no_fact(self):
        self.assertRaises(exceptions.NoFactError, self.kb.__isub__,
                          Fact(uid='some fact'))

    def test_remove_fact__wrong_type(self):
        self.assertRaises(exceptions.WrongFactTypeError, self.kb.__isub__,
                          'some string')

    def test_remove_fact__wrong_type_for_nested_lists(self):
        self.assertRaises(exceptions.WrongFactTypeError, self.kb.__isub__,
                          [[self.fact]])

    def test_validate_consistency__success(self):
        self.kb.validate_consistency([])
        self.kb.validate_consistency([restrictions.AlwaysSuccess()])

    def test_validate_consistency__error(self):
        self.assertRaises(restrictions.AlwaysError.Error,
                          self.kb.validate_consistency,
                          [restrictions.AlwaysError()])

    def test_uids(self):
        self.assertEqual(self.kb.uids(), set(self.kb._facts.keys()))

    def test_facts(self):
        self.assertEqual(set(fact.uid for fact in self.kb.facts()),
                         set(self.kb._facts.keys()))

    def test_filter__no_facts(self):
        self.assertEqual(list(self.kb.filter(Person)), [])

    def test_filter(self):
        self.assertEqual(len(list(self.kb.filter(Fact))), 2)

        person_1 = Person(uid='person_1')
        person_2 = Person(uid='person_2')
        place_1 = Place(uid='place_1')

        self.kb += [person_1, person_2, place_1]

        self.assertEqual(len(list(self.kb.filter(Fact))), 5)
        self.assertEqual(set(fact.uid for fact in self.kb.filter(Person)),
                         set([person_1.uid, person_2.uid]))
        self.assertEqual(set(fact.uid for fact in self.kb.filter(Place)),
                         set([place_1.uid]))
Пример #28
0
class LogicTestsBase(testcase.TestCase):

    def setUp(self):
        super(LogicTestsBase, self).setUp()

        self.place_1, self.place_2, self.place_3 = create_test_map()

        result, account_id, bundle_id = register_user('test_user')

        self.storage = LogicStorage()
        self.storage.load_account_data(AccountPrototype.get_by_id(account_id))
        self.hero = self.storage.accounts_to_heroes[account_id]

        self.hero_uid = uids.hero(self.hero.id)

        self.knowledge_base = KnowledgeBase()


    def get_hero_info(self):
        return logic.create_hero_info(self.hero)


    def check_uids(self, left, right):
        self.assertEqual(set(f.uid for f in left), set(f.uid for f in right))

    def check_facts(self,
                    places=[],
                    persons=[],
                    locations=[],
                    mobs=[],
                    prefered_mobs=[],
                    hometowns=[],
                    friends=[],
                    bad_branches=[],
                    enemies=[],
                    good_branches=[],
                    equipment_slots=[],
                    social_connections=[]):
        self.check_uids(self.knowledge_base.filter(facts.Place), places)
        self.check_uids(self.knowledge_base.filter(facts.Person), persons)
        self.check_uids(self.knowledge_base.filter(facts.LocatedIn), locations)
        self.check_uids(self.knowledge_base.filter(facts.Mob), mobs)
        self.check_uids(self.knowledge_base.filter(facts.PreferenceMob), prefered_mobs)
        self.check_uids(self.knowledge_base.filter(facts.PreferenceHometown), hometowns)
        self.check_uids(self.knowledge_base.filter(facts.PreferenceFriend), friends)
        self.check_uids(self.knowledge_base.filter(facts.ExceptBadBranches), bad_branches)
        self.check_uids(self.knowledge_base.filter(facts.PreferenceEnemy), enemies)
        self.check_uids(self.knowledge_base.filter(facts.ExceptGoodBranches), good_branches)
        self.check_uids(self.knowledge_base.filter(facts.PreferenceEquipmentSlot), equipment_slots)
        self.check_uids(self.knowledge_base.filter(facts.SocialConnection), social_connections)
Пример #29
0
 def deserialize(cls, hero, data):
     return cls(knowledge_base=KnowledgeBase.deserialize(data['knowledge_base'], fact_classes=facts.FACTS),
                quests_stack=[QuestInfo.deserialize(info_data) for info_data in data['quests_stack']],
                created_at=datetime.datetime.fromtimestamp(data['created_at']),
                states_to_percents=data['states_to_percents'],
                hero=hero)
Пример #30
0
class QuestsTests(unittest.TestCase):
    def setUp(self):
        self.qb = QuestsBase()
        self.qb += [Simple]

        self.kb = KnowledgeBase()

        self.kb += [
            facts.Hero(uid='hero'),
            facts.Place(uid='place_1', terrains=(1, )),
            facts.Place(uid='place_2', terrains=(0, )),
            facts.Place(uid='place_3', terrains=(0, )),
            facts.Place(uid='place_4', terrains=(1, )),
            facts.Place(uid='place_5', terrains=(2, )),
            facts.Place(uid='place_6', terrains=(1, )),
            facts.Place(uid='place_7', terrains=(2, )),
            facts.Place(uid='place_8', terrains=(2, )),
            facts.Place(uid='place_9', terrains=(1, )),
            facts.Place(uid='place_10', terrains=(2, )),
            facts.Person(uid='person_1', profession=PROFESSION.NONE),
            facts.Person(uid='person_2', profession=PROFESSION.BLACKSMITH),
            facts.Person(uid='person_3', profession=PROFESSION.NONE),
            facts.Person(uid='person_4', profession=PROFESSION.NONE),
            facts.Person(uid='person_5', profession=PROFESSION.NONE),
            facts.Person(uid='person_6', profession=PROFESSION.NONE),
            facts.Person(uid='person_7', profession=PROFESSION.NONE),
            facts.Person(uid='person_8', profession=PROFESSION.NONE),
            facts.Person(uid='person_9', profession=PROFESSION.NONE),
            facts.Person(uid='person_10', profession=PROFESSION.NONE),
            facts.LocatedIn(object='person_1', place='place_1'),
            facts.LocatedIn(object='person_2', place='place_2'),
            facts.LocatedIn(object='person_3', place='place_3'),
            facts.LocatedIn(object='person_4', place='place_4'),
            facts.LocatedIn(object='person_5', place='place_5'),
            facts.LocatedIn(object='person_6', place='place_6'),
            facts.LocatedIn(object='person_7', place='place_7'),
            facts.LocatedIn(object='person_8', place='place_8'),
            facts.LocatedIn(object='person_9', place='place_9'),
            facts.LocatedIn(object='person_10', place='place_10'),
            facts.LocatedIn(object='hero', place='place_1'),
            facts.Mob(uid='mob_1', terrains=(0, )),
            facts.PreferenceMob(object='hero', mob='mob_1'),
            facts.PreferenceHometown(object='hero', place='place_2'),
            facts.PreferenceFriend(object='hero', person='person_4'),
            facts.PreferenceEnemy(object='hero', person='person_5'),
            facts.UpgradeEquipmentCost(money=777)
        ]

        self.selector = Selector(self.kb, self.qb)

    def check_quest(self, quest_class):
        self.kb += quest_class.construct_from_place(
            nesting=0,
            selector=self.selector,
            start_place=self.selector.new_place(candidates=('place_1', )))

        self.kb.validate_consistency([
            restrictions.SingleStartStateWithNoEnters(),
            restrictions.FinishStateExists(),
            restrictions.AllStatesHasJumps(),
            restrictions.SingleLocationForObject(),
            restrictions.ReferencesIntegrity(),
            restrictions.ConnectedStateJumpGraph(),
            restrictions.NoCirclesInStateJumpGraph(),
            # restrictions.MultipleJumpsFromNormalState(),
            restrictions.ChoicesConsistency(),
            restrictions.QuestionsConsistency(),
            restrictions.FinishResultsConsistency(),
            restrictions.RequirementsConsistency(),
            restrictions.ActionsConsistency()
        ])

    def check_linked_options_has_similar_markers(self, quest_class):
        self.kb += quest_class.construct_from_place(
            nesting=0,
            selector=self.selector,
            start_place=self.selector.new_place(candidates=('place_1', )))

        for options_link in self.kb.filter(facts.OptionsLink):

            makrers = None

            for option_uid in options_link.options:
                option = self.kb[option_uid]

                if makrers is None:
                    makrers = set(option.markers)

                self.assertEqual(makrers, set(option.markers))
Пример #31
0
class SimpleQuestTests(unittest.TestCase):
    def setUp(self):
        self.kb = KnowledgeBase()

        # world
        self.kb += [
            Place(uid='place_from'),
            Person(uid='person_from'),
            Place(uid='place_thought'),
            Place(uid='place_to'),
            Person(uid='person_to'),
            LocatedIn(object='person_from', place='place_from'),
            LocatedIn(object='person_to', place='place_to')
        ]

        # quest
        self.kb += [
            Start(uid='start',
                  nesting=0,
                  type='simple_test',
                  require=(requirements.LocatedIn(object='person_from',
                                                  place='place_from'),
                           requirements.LocatedIn(object='person_to',
                                                  place='place_to'),
                           requirements.LocatedIn(object='hero',
                                                  place='place_from'))),
            State(uid='st_throught_place',
                  require=(requirements.LocatedIn(object='hero',
                                                  place='place_thought'), )),
            Finish(uid='st_finish',
                   start='start',
                   results={},
                   nesting=0,
                   require=(requirements.LocatedIn(object='hero',
                                                   place='place_to'), )),
            Jump(state_from='start', state_to='st_throught_place'),
            Jump(state_from='st_throught_place', state_to='st_finish')
        ]

        self.kb += [Hero(uid='hero')]

        self.kb.validate_consistency([
            restrictions.SingleStartStateWithNoEnters(),
            restrictions.FinishStateExists(),
            restrictions.AllStatesHasJumps(),
            restrictions.SingleLocationForObject(),
            restrictions.ReferencesIntegrity(),
            restrictions.ConnectedStateJumpGraph(),
            restrictions.NoCirclesInStateJumpGraph(),
            restrictions.MultipleJumpsFromNormalState(),
            restrictions.ChoicesConsistency()
        ])

        self.machine = machine.Machine(knowledge_base=self.kb,
                                       interpreter=FakeInterpreter())

    def test_initialized(self):
        pass

    def test_full_story_forced(self):
        self.machine.step()
        self.assertEqual(self.machine.pointer, Pointer(state='start'))

        self.machine.step()
        self.assertEqual(
            self.machine.pointer,
            Pointer(state='start',
                    jump=Jump(state_from='start',
                              state_to='st_throught_place').uid))

        self.machine.step()
        self.assertEqual(self.machine.pointer,
                         Pointer(state='st_throught_place'))

        self.machine.step()
        self.assertEqual(
            self.machine.pointer,
            Pointer(state='st_throught_place',
                    jump=Jump(state_from='st_throught_place',
                              state_to='st_finish').uid))

        self.machine.step()
        self.assertEqual(self.machine.pointer,
                         Pointer(state='st_finish', jump=None))

    def test_full_story_real(self):
        # no move, since hero not in right place
        self.assertEqual(self.machine.pointer, Pointer(state=None, jump=None))

        def check_located_in_place_from(requirement):
            return requirement.place == 'place_from'

        def check_located_in_place_to(requirement):
            return requirement.place == 'place_to'

        def check_located_in_place_thought(requirement):
            return requirement.place == 'place_thought'

        with mock.patch(
                'questgen.machine.Machine.interpreter',
                FakeInterpreter(check_located_in=check_located_in_place_from)):
            self.machine.step_until_can()

        self.assertEqual(
            self.machine.pointer,
            Pointer(state='start',
                    jump=Jump(state_from='start',
                              state_to='st_throught_place').uid))

        with mock.patch(
                'questgen.machine.Machine.interpreter',
                FakeInterpreter(check_located_in=check_located_in_place_from)):
            self.machine.step_until_can()
        self.assertEqual(
            self.machine.pointer,
            Pointer(state='start',
                    jump=Jump(state_from='start',
                              state_to='st_throught_place').uid))

        # no move, since hero not in right place
        with mock.patch(
                'questgen.machine.Machine.interpreter',
                FakeInterpreter(check_located_in=check_located_in_place_from)):
            self.machine.step_until_can()
        self.assertEqual(
            self.machine.pointer,
            Pointer(state='start',
                    jump=Jump(state_from='start',
                              state_to='st_throught_place').uid))

        with mock.patch(
                'questgen.machine.Machine.interpreter',
                FakeInterpreter(
                    check_located_in=check_located_in_place_thought)):
            self.machine.step_until_can()

        self.assertEqual(
            self.machine.pointer,
            Pointer(state='st_throught_place',
                    jump=Jump(state_from='st_throught_place',
                              state_to='st_finish').uid))

        # no move, since hero not in right place
        with mock.patch(
                'questgen.machine.Machine.interpreter',
                FakeInterpreter(
                    check_located_in=check_located_in_place_thought)):
            self.machine.step_until_can()
        self.assertEqual(
            self.machine.pointer,
            Pointer(state='st_throught_place',
                    jump=Jump(state_from='st_throught_place',
                              state_to='st_finish').uid))

        with mock.patch(
                'questgen.machine.Machine.interpreter',
                FakeInterpreter(check_located_in=check_located_in_place_to)):
            self.machine.step_until_can()
        self.assertEqual(self.machine.pointer,
                         Pointer(state='st_finish', jump=None))
Пример #32
0
def create_quest():

    # формируем список заданий для генерации
    qb = QuestsBase()
    qb += [
        Spying, Hunt, Hometown, SearchSmith, Delivery, Caravan, CollectDebt,
        HelpFriend, InterfereEnemy, Help
    ]

    kb = KnowledgeBase()

    # описываем мир
    kb += [
        facts.Hero(uid='hero'),  # наш герой
        facts.Place(uid='place_1', terrains=(
            1,
        )),  # есть место с идентификатором place_1 и типами ландшафта 1,
        facts.Place(uid='place_2', terrains=(0, )),
        facts.Place(uid='place_3', terrains=(0, )),
        facts.Place(uid='place_4', terrains=(1, )),
        facts.Place(uid='place_5', terrains=(2, )),
        facts.Place(uid='place_6', terrains=(1, )),
        facts.Place(uid='place_7', terrains=(2, )),
        facts.Place(uid='place_8', terrains=(2, )),
        facts.Place(uid='place_9', terrains=(1, )),
        facts.Place(uid='place_10', terrains=(2, )),
        facts.Person(
            uid='person_1', profession=PROFESSION.NONE
        ),  # есть персонаж с идентификатором perons_1 и без профессии
        facts.Person(uid='person_2', profession=PROFESSION.BLACKSMITH),
        facts.Person(uid='person_3', profession=PROFESSION.ROGUE),
        facts.Person(uid='person_4', profession=PROFESSION.NONE),
        facts.Person(uid='person_5', profession=PROFESSION.NONE),
        facts.Person(uid='person_6', profession=PROFESSION.NONE),
        facts.Person(uid='person_7', profession=PROFESSION.NONE),
        facts.Person(uid='person_8', profession=PROFESSION.NONE),
        facts.Person(uid='person_9', profession=PROFESSION.NONE),
        facts.Person(uid='person_10', profession=PROFESSION.NONE),
        facts.LocatedIn(
            object='person_1',
            place='place_1'),  # персонаж person_1 находится в place_1
        facts.LocatedIn(object='person_2', place='place_2'),
        facts.LocatedIn(object='person_3', place='place_3'),
        facts.LocatedIn(object='person_4', place='place_4'),
        facts.LocatedIn(object='person_5', place='place_5'),
        facts.LocatedIn(object='person_6', place='place_6'),
        facts.LocatedIn(object='person_7', place='place_7'),
        facts.LocatedIn(object='person_8', place='place_8'),
        facts.LocatedIn(object='person_9', place='place_9'),
        facts.LocatedIn(object='person_10', place='place_10'),
        facts.LocatedIn(object='hero',
                        place='place_1'),  # герой находится в place_1
        facts.Mob(
            uid='mob_1', terrains=(0, )
        ),  # есть монстр, обитающий на территориях с идентификатором 0 (для задания на охоту)
        facts.PreferenceMob(
            object='hero',
            mob='mob_1'),  # герой любит охотиться на монстра mob_1
        facts.PreferenceHometown(
            object='hero',
            place='place_2'),  # герой считате родным место place_2
        facts.PreferenceFriend(object='hero',
                               person='person_4'),  # герой дружит с person_4
        facts.PreferenceEnemy(object='hero',
                              person='person_5'),  # герой враждует с person_5

        # указываем, что обновление экипировки стоит 777 монет (для задания SearchSmith)
        # facts.HasMoney(object='hero', money=888), # если этот факт раскоментировать то в этом задании герой купит экипировку, а не пойдёт делать задание кузнеца
        facts.UpgradeEquipmentCost(money=777),
        facts.OnlyGoodBranches(object='place_2'),  # не вредить месту place_2
        facts.OnlyGoodBranches(
            object='person_4'),  # не вредить персонажу person_4
        facts.OnlyBadBranches(object='person_5')
    ]  # не помогать персонажу person_5

    kb.validate_consistency(
        WORLD_RESTRICTIONS)  # проверяем ограничения на мир,

    selector = Selector(kb, qb)

    # создаём квест (получаем список фактов)
    quests_facts = selector.create_quest_from_place(
        nesting=0, initiator_position=kb['place_1'], tags=('can_start', ))

    kb += quests_facts

    transformators.activate_events(
        kb
    )  # активируем события (из нескольких вершин графа оставляем одну, остальные удаляем)
    transformators.remove_restricted_states(
        kb
    )  # удаляем состояния, в которые нельзя переходить (например, которые вредят тому, кому вредить нельщя)
    transformators.remove_broken_states(
        kb
    )  # чистим граф задания от разрушений, вызванных предыдущими действиями
    transformators.determine_default_choices(
        kb)  # определяем выборы по умолчанию на развилках

    kb.validate_consistency(WORLD_RESTRICTIONS)  # ещё раз проверяем мир
    kb.validate_consistency(
        QUEST_RESTRICTIONS
    )  # проверяем граф задания (вдруг полностью разрушен)

    return kb
Пример #33
0
class KnowledgeBaseTests(unittest.TestCase):

    def setUp(self):
        self.kb = KnowledgeBase()

        self.fact = Fact(uid='fact')
        self.fact_2 = Fact(uid='fact_2', description='cba')

        self.kb += [ self.fact,
                     self.fact_2 ]

    def test_serialize(self):
        self.assertEqual(self.kb.serialize(), KnowledgeBase.deserialize(self.kb.serialize(), FACTS).serialize())
        self.assertEqual(self.kb.serialize(short=True), KnowledgeBase.deserialize(self.kb.serialize(short=True), FACTS).serialize())
        self.assertNotEqual(self.kb.serialize(), KnowledgeBase.deserialize(self.kb.serialize(short=True), FACTS).serialize())

    def test_contains__for_child(self):
        self.assertTrue('fact' in self.kb)
        self.assertFalse('wrong uid' in self.kb)

    def test_getitem__for_child(self):
        self.assertEqual(self.kb['fact'].uid, 'fact')
        self.assertRaises(exceptions.NoFactError, self.kb.__getitem__, 'wrong uid')

    def test_get__for_child(self):
        self.assertEqual(self.kb.get('fact').uid, 'fact')
        self.assertEqual(self.kb.get('wrong uid'), None)

    def test_delitem__no_item(self):
        self.assertRaises(exceptions.NoFactError, self.kb.__delitem__, 'wrong_fact')

    def test_delitem(self):
        del self.kb['fact']
        self.assertFalse('fact' in self.kb)

    def test_add_fact__list(self):
        self.kb += [Fact(uid='fact 1'), Fact(uid='fact 2')]
        self.assertTrue('fact 1' in self.kb)
        self.assertTrue('fact 2' in self.kb)

    def test_add_fact__duplicate_fact(self):
        self.assertRaises(exceptions.DuplicatedFactError,
                          self.kb.__iadd__, self.fact)

    def test_add_fact__wrong_type(self):
        self.assertRaises(exceptions.WrongFactTypeError,
                          self.kb.__iadd__, 'some string')

    def test_add_fact__wrong_type_for_nested_lists(self):
        self.assertRaises(exceptions.WrongFactTypeError,
                          self.kb.__iadd__, [[Fact(uid='some fact')]])

    def test_remove_fact__no_fact(self):
        self.assertRaises(exceptions.NoFactError,
                          self.kb.__isub__, Fact(uid='some fact'))

    def test_remove_fact__wrong_type(self):
        self.assertRaises(exceptions.WrongFactTypeError,
                          self.kb.__isub__, 'some string')

    def test_remove_fact__wrong_type_for_nested_lists(self):
        self.assertRaises(exceptions.WrongFactTypeError,
                          self.kb.__isub__, [[self.fact]])

    def test_validate_consistency__success(self):
        self.kb.validate_consistency([])
        self.kb.validate_consistency([restrictions.AlwaysSuccess()])

    def test_validate_consistency__error(self):
        self.assertRaises(restrictions.AlwaysError.Error, self.kb.validate_consistency, [restrictions.AlwaysError()])

    def test_uids(self):
        self.assertEqual(self.kb.uids(),
                         set(self.kb._facts.keys()))

    def test_facts(self):
        self.assertEqual(set(fact.uid for fact in self.kb.facts()),
                         set(self.kb._facts.keys()))

    def test_filter__no_facts(self):
        self.assertEqual(list(self.kb.filter(Person)), [])

    def test_filter(self):
        self.assertEqual(len(list(self.kb.filter(Fact))), 2)

        person_1 = Person(uid='person_1')
        person_2 = Person(uid='person_2')
        place_1 = Place(uid='place_1')

        self.kb += [ person_1, person_2, place_1]

        self.assertEqual(len(list(self.kb.filter(Fact))), 5)
        self.assertEqual(set(fact.uid for fact in self.kb.filter(Person)),
                         set([person_1.uid, person_2.uid]))
        self.assertEqual(set(fact.uid for fact in self.kb.filter(Place)),
                         set([place_1.uid]))
Пример #34
0
from questgen.quests.help import Help
from questgen.quests.pilgrimage import Pilgrimage

QUESTS = [
    Spying, Hunt, Hometown, SearchSmith, Delivery, Caravan, CollectDebt,
    HelpFriend, InterfereEnemy, Help, Simple, Simplest, Complex, Pilgrimage
]

qb = QuestsBase()
qb += [Simple]

for Quest in QUESTS:

    print('process quest: %s' % Quest.TYPE)

    kb = KnowledgeBase()

    kb += [
        facts.Hero(uid='hero'),
        facts.Place(uid='place_1', terrains=(1, )),
        facts.Place(uid='place_2', terrains=(0, )),
        facts.Place(uid='place_3', terrains=(0, )),
        facts.Place(uid='place_4', terrains=(1, )),
        facts.Place(uid='place_5', terrains=(2, )),
        facts.Place(uid='place_6', terrains=(1, )),
        facts.Place(uid='place_7', terrains=(2, )),
        facts.Place(uid='place_8', terrains=(2, )),
        facts.Place(uid='place_9', terrains=(1, )),
        facts.Place(uid='place_10',
                    terrains=(2, ),
                    type=relations.PLACE_TYPE.HOLY_CITY),
Пример #35
0
# coding: utf-8

from questgen.knowledge_base import KnowledgeBase
from questgen.facts import Hero, Place, Person, Start, Finish, Choice, Jump, LocatedIn
from questgen.states import Option

kb = KnowledgeBase()

kb += [
    Hero(uid='hero'),
    Place(uid='place_from', label='место отправления'),
    Person(uid='person_from', label='отправитель'),
    Place(uid='place_to', label='место назначения'),
    Place(uid='place_steal', label='место схрона'),
    Person(uid='person_to', label='получатель'),

    Start(uid='st_start', require=(LocatedIn('person_from', 'place_from'),
                                   LocatedIn('person_to', 'place_to'),
                                   LocatedIn('hero', 'place_from'))),

    Choice(uid='st_steal'),
    Option(uid='st_steal.steal', choice='st_steal', label='украсть'),
    Option(uid='st_steal.deliver', choice='st_steal', label='доставить'),

    Finish(uid='st_finish_delivered', require=(LocatedIn('hero', 'place_to'),)),
    Finish(uid='st_finish_stealed', require=(LocatedIn('hero', 'place_steal'),)),

    Jump('st_start', 'st_steal'),
    Jump('st_steal.deliver', 'st_finish_delivered'),
    Jump('st_steal.steal', 'st_finish_stealed'),
    ]
Пример #36
0
class QuestsTests(unittest.TestCase):

    def setUp(self):
        self.qb = QuestsBase()
        self.qb += [Simple]

        self.kb = KnowledgeBase()

        self.kb += [ facts.Hero(uid='hero'),

            facts.Place(uid='place_1', terrains=(1,)),
            facts.Place(uid='place_2', terrains=(0,)),
            facts.Place(uid='place_3', terrains=(0,)),
            facts.Place(uid='place_4', terrains=(1,)),
            facts.Place(uid='place_5', terrains=(2,)),
            facts.Place(uid='place_6', terrains=(1,)),
            facts.Place(uid='place_7', terrains=(2,)),
            facts.Place(uid='place_8', terrains=(2,)),
            facts.Place(uid='place_9', terrains=(1,)),
            facts.Place(uid='place_10', terrains=(2,)),

            facts.Person(uid='person_1', profession=PROFESSION.NONE),
            facts.Person(uid='person_2', profession=PROFESSION.BLACKSMITH),
            facts.Person(uid='person_3', profession=PROFESSION.NONE),
            facts.Person(uid='person_4', profession=PROFESSION.NONE),
            facts.Person(uid='person_5', profession=PROFESSION.NONE),
            facts.Person(uid='person_6', profession=PROFESSION.NONE),
            facts.Person(uid='person_7', profession=PROFESSION.NONE),
            facts.Person(uid='person_8', profession=PROFESSION.NONE),
            facts.Person(uid='person_9', profession=PROFESSION.NONE),
            facts.Person(uid='person_10', profession=PROFESSION.NONE),

            facts.LocatedIn(object='person_1', place='place_1'),
            facts.LocatedIn(object='person_2', place='place_2'),
            facts.LocatedIn(object='person_3', place='place_3'),
            facts.LocatedIn(object='person_4', place='place_4'),
            facts.LocatedIn(object='person_5', place='place_5'),
            facts.LocatedIn(object='person_6', place='place_6'),
            facts.LocatedIn(object='person_7', place='place_7'),
            facts.LocatedIn(object='person_8', place='place_8'),
            facts.LocatedIn(object='person_9', place='place_9'),
            facts.LocatedIn(object='person_10', place='place_10'),

            facts.LocatedIn(object='hero', place='place_1'),

            facts.Mob(uid='mob_1', terrains=(0,)),
            facts.PreferenceMob(object='hero', mob='mob_1'),
            facts.PreferenceHometown(object='hero', place='place_2'),
            facts.PreferenceFriend(object='hero', person='person_4'),
            facts.PreferenceEnemy(object='hero', person='person_5'),
            facts.UpgradeEquipmentCost(money=777)
            ]

        self.selector = Selector(self.kb, self.qb)


    def check_quest(self, quest_class):
        self.kb += quest_class.construct_from_place(nesting=0, selector=self.selector, start_place=self.selector.new_place(candidates=('place_1',)))

        self.kb.validate_consistency([restrictions.SingleStartStateWithNoEnters(),
                                      restrictions.FinishStateExists(),
                                      restrictions.AllStatesHasJumps(),
                                      restrictions.SingleLocationForObject(),
                                      restrictions.ReferencesIntegrity(),
                                      restrictions.ConnectedStateJumpGraph(),
                                      restrictions.NoCirclesInStateJumpGraph(),
                                      # restrictions.MultipleJumpsFromNormalState(),
                                      restrictions.ChoicesConsistency(),
                                      restrictions.QuestionsConsistency(),
                                      restrictions.FinishResultsConsistency(),
                                      restrictions.RequirementsConsistency(),
                                      restrictions.ActionsConsistency()])

    def check_linked_options_has_similar_markers(self, quest_class):
        self.kb += quest_class.construct_from_place(nesting=0, selector=self.selector, start_place=self.selector.new_place(candidates=('place_1',)))

        for options_link in self.kb.filter(facts.OptionsLink):

            makrers = None

            for option_uid in options_link.options:
                option = self.kb[option_uid]

                if makrers is None:
                    makrers = set(option.markers)

                self.assertEqual(makrers, set(option.markers))
Пример #37
0
from questgen.quests.help_friend import HelpFriend
from questgen.quests.interfere_enemy import InterfereEnemy
from questgen.quests.help import Help
from questgen.quests.pilgrimage import Pilgrimage


QUESTS = [Spying, Hunt, Hometown, SearchSmith, Delivery, Caravan, CollectDebt, HelpFriend, InterfereEnemy, Help, Simple, Simplest, Complex, Pilgrimage]

qb = QuestsBase()
qb += [Simple]

for Quest in QUESTS:

    print 'process quest: %s' % Quest.TYPE

    kb = KnowledgeBase()

    kb += [ facts.Hero(uid='hero'),

            facts.Place(uid='place_1', terrains=(1,)),
            facts.Place(uid='place_2', terrains=(0,)),
            facts.Place(uid='place_3', terrains=(0,)),
            facts.Place(uid='place_4', terrains=(1,)),
            facts.Place(uid='place_5', terrains=(2,)),
            facts.Place(uid='place_6', terrains=(1,)),
            facts.Place(uid='place_7', terrains=(2,)),
            facts.Place(uid='place_8', terrains=(2,)),
            facts.Place(uid='place_9', terrains=(1,)),
            facts.Place(uid='place_10', terrains=(2,), type=relations.PLACE_TYPE.HOLY_CITY),

            facts.Person(uid='person_1', profession=relations.PROFESSION.NONE),
Пример #38
0
class LogicTestsBase(testcase.TestCase):
    def setUp(self):
        super(LogicTestsBase, self).setUp()

        self.place_1, self.place_2, self.place_3 = create_test_map()

        account = self.accounts_factory.create_account(is_fast=True)

        self.storage = LogicStorage()
        self.storage.load_account_data(account)
        self.hero = self.storage.accounts_to_heroes[account.id]

        self.hero_uid = uids.hero(self.hero.id)

        self.knowledge_base = KnowledgeBase()

    def get_hero_info(self):
        return logic.create_hero_info(self.hero)

    def check_uids(self, left, right):
        self.assertEqual(set(f.uid for f in left), set(f.uid for f in right))

    def check_facts(self,
                    places=[],
                    persons=[],
                    locations=[],
                    mobs=[],
                    prefered_mobs=[],
                    hometowns=[],
                    friends=[],
                    bad_branches=[],
                    enemies=[],
                    good_branches=[],
                    equipment_slots=[],
                    social_connections=[]):
        self.check_uids(self.knowledge_base.filter(facts.Place), places)
        self.check_uids(self.knowledge_base.filter(facts.Person), persons)
        self.check_uids(self.knowledge_base.filter(facts.LocatedIn), locations)
        self.check_uids(self.knowledge_base.filter(facts.Mob), mobs)
        self.check_uids(self.knowledge_base.filter(facts.PreferenceMob),
                        prefered_mobs)
        self.check_uids(self.knowledge_base.filter(facts.PreferenceHometown),
                        hometowns)
        self.check_uids(self.knowledge_base.filter(facts.PreferenceFriend),
                        friends)
        self.check_uids(self.knowledge_base.filter(facts.ExceptBadBranches),
                        bad_branches)
        self.check_uids(self.knowledge_base.filter(facts.PreferenceEnemy),
                        enemies)
        self.check_uids(self.knowledge_base.filter(facts.ExceptGoodBranches),
                        good_branches)
        self.check_uids(
            self.knowledge_base.filter(facts.PreferenceEquipmentSlot),
            equipment_slots)
        self.check_uids(self.knowledge_base.filter(facts.SocialConnection),
                        social_connections)
Пример #39
0
def create_quest():

    # формируем список заданий для генерации
    qb = QuestsBase()
    qb += [Spying, Hunt, Hometown, SearchSmith, Delivery, Caravan, CollectDebt, HelpFriend, InterfereEnemy, Help]

    kb = KnowledgeBase()

    # описываем мир
    kb += [ facts.Hero(uid='hero'), # наш герой

            facts.Place(uid='place_1', terrains=(1,)), # есть место с идентификатором place_1 и типами ландшафта 1,
            facts.Place(uid='place_2', terrains=(0,)),
            facts.Place(uid='place_3', terrains=(0,)),
            facts.Place(uid='place_4', terrains=(1,)),
            facts.Place(uid='place_5', terrains=(2,)),
            facts.Place(uid='place_6', terrains=(1,)),
            facts.Place(uid='place_7', terrains=(2,)),
            facts.Place(uid='place_8', terrains=(2,)),
            facts.Place(uid='place_9', terrains=(1,)),
            facts.Place(uid='place_10', terrains=(2,)),

            facts.Person(uid='person_1', profession=PROFESSION.NONE), # есть персонаж с идентификатором perons_1 и без профессии
            facts.Person(uid='person_2', profession=PROFESSION.BLACKSMITH),
            facts.Person(uid='person_3', profession=PROFESSION.ROGUE),
            facts.Person(uid='person_4', profession=PROFESSION.NONE),
            facts.Person(uid='person_5', profession=PROFESSION.NONE),
            facts.Person(uid='person_6', profession=PROFESSION.NONE),
            facts.Person(uid='person_7', profession=PROFESSION.NONE),
            facts.Person(uid='person_8', profession=PROFESSION.NONE),
            facts.Person(uid='person_9', profession=PROFESSION.NONE),
            facts.Person(uid='person_10', profession=PROFESSION.NONE),

            facts.LocatedIn(object='person_1', place='place_1'), # персонаж person_1 находится в place_1
            facts.LocatedIn(object='person_2', place='place_2'),
            facts.LocatedIn(object='person_3', place='place_3'),
            facts.LocatedIn(object='person_4', place='place_4'),
            facts.LocatedIn(object='person_5', place='place_5'),
            facts.LocatedIn(object='person_6', place='place_6'),
            facts.LocatedIn(object='person_7', place='place_7'),
            facts.LocatedIn(object='person_8', place='place_8'),
            facts.LocatedIn(object='person_9', place='place_9'),
            facts.LocatedIn(object='person_10', place='place_10'),

            facts.LocatedIn(object='hero', place='place_1'), # герой находится в place_1

            facts.Mob(uid='mob_1', terrains=(0,)), # есть монстр, обитающий на территориях с идентификатором 0 (для задания на охоту)
            facts.PreferenceMob(object='hero', mob='mob_1'), # герой любит охотиться на монстра mob_1
            facts.PreferenceHometown(object='hero', place='place_2'), # герой считате родным место place_2
            facts.PreferenceFriend(object='hero', person='person_4'), # герой дружит с person_4
            facts.PreferenceEnemy(object='hero', person='person_5'), # герой враждует с person_5

            # указываем, что обновление экипировки стоит 777 монет (для задания SearchSmith)
            # facts.HasMoney(object='hero', money=888), # если этот факт раскоментировать то в этом задании герой купит экипировку, а не пойдёт делать задание кузнеца
            facts.UpgradeEquipmentCost(money=777),

            facts.OnlyGoodBranches(object='place_2'), # не вредить месту place_2
            facts.OnlyGoodBranches(object='person_4'), # не вредить персонажу person_4
            facts.OnlyBadBranches(object='person_5') ] # не помогать персонажу person_5


    kb.validate_consistency(WORLD_RESTRICTIONS) # проверяем ограничения на мир,

    selector = Selector(kb, qb)

    # создаём квест (получаем список фактов)
    quests_facts = selector.create_quest_from_place(nesting=0,
                                                    initiator_position=kb['place_1'],
                                                    tags=('can_start', ))

    kb += quests_facts

    transformators.activate_events(kb) # активируем события (из нескольких вершин графа оставляем одну, остальные удаляем)
    transformators.remove_restricted_states(kb) # удаляем состояния, в которые нельзя переходить (например, которые вредят тому, кому вредить нельщя)
    transformators.remove_broken_states(kb) # чистим граф задания от разрушений, вызванных предыдущими действиями
    transformators.determine_default_choices(kb) # определяем выборы по умолчанию на развилках

    kb.validate_consistency(WORLD_RESTRICTIONS) # ещё раз проверяем мир
    kb.validate_consistency(QUEST_RESTRICTIONS) # проверяем граф задания (вдруг полностью разрушен)

    return kb
Пример #40
0
class SimpleQuestTests(unittest.TestCase):

    def setUp(self):
        self.kb = KnowledgeBase()

        # world
        self.kb += [ Place(uid='place_from'),
                     Person(uid='person_from'),
                     Place(uid='place_thought'),
                     Place(uid='place_to'),
                     Person(uid='person_to'),
                     LocatedIn(object='person_from', place='place_from'),
                     LocatedIn(object='person_to', place='place_to')]

        # quest
        self.kb += [ Start(uid='start',
                           nesting=0,
                           type='simple_test',
                           require=(requirements.LocatedIn(object='person_from', place='place_from'),
                                    requirements.LocatedIn(object='person_to', place='place_to'),
                                    requirements.LocatedIn(object='hero', place='place_from'))),

                     State(uid='st_throught_place',
                           require=(requirements.LocatedIn(object='hero', place='place_thought'),)),

                     Finish(uid='st_finish',
                            start='start',
                            results={},
                            nesting=0,
                            require=(requirements.LocatedIn(object='hero', place='place_to'),)),

                     Jump(state_from='start', state_to='st_throught_place'),
                     Jump(state_from='st_throught_place', state_to='st_finish') ]

        self.kb += [ Hero(uid='hero') ]

        self.kb.validate_consistency([restrictions.SingleStartStateWithNoEnters(),
                                      restrictions.FinishStateExists(),
                                      restrictions.AllStatesHasJumps(),
                                      restrictions.SingleLocationForObject(),
                                      restrictions.ReferencesIntegrity(),
                                      restrictions.ConnectedStateJumpGraph(),
                                      restrictions.NoCirclesInStateJumpGraph(),
                                      restrictions.MultipleJumpsFromNormalState(),
                                      restrictions.ChoicesConsistency()])

        self.machine = machine.Machine(knowledge_base=self.kb, interpreter=FakeInterpreter())

    def test_initialized(self):
        pass

    def test_full_story_forced(self):
        self.machine.step()
        self.assertEqual(self.machine.pointer, Pointer(state='start'))

        self.machine.step()
        self.assertEqual(self.machine.pointer,
                         Pointer(state='start', jump=Jump(state_from='start', state_to='st_throught_place').uid))

        self.machine.step()
        self.assertEqual(self.machine.pointer, Pointer(state='st_throught_place'))

        self.machine.step()
        self.assertEqual(self.machine.pointer,
                         Pointer(state='st_throught_place',
                                 jump=Jump(state_from='st_throught_place', state_to='st_finish').uid))

        self.machine.step()
        self.assertEqual(self.machine.pointer,
                         Pointer(state='st_finish', jump=None))


    def test_full_story_real(self):
        # no move, since hero not in right place
        self.assertEqual(self.machine.pointer, Pointer(state=None, jump=None) )

        def check_located_in_place_from(requirement):
            return requirement.place == 'place_from'

        def check_located_in_place_to(requirement):
            return requirement.place == 'place_to'

        def check_located_in_place_thought(requirement):
            return requirement.place == 'place_thought'

        with mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_located_in=check_located_in_place_from)):
            self.machine.step_until_can()

        self.assertEqual(self.machine.pointer, Pointer(state='start', jump=Jump(state_from='start', state_to='st_throught_place').uid) )

        with mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_located_in=check_located_in_place_from)):
            self.machine.step_until_can()
        self.assertEqual(self.machine.pointer,
                         Pointer(state='start', jump=Jump(state_from='start', state_to='st_throught_place').uid))

        # no move, since hero not in right place
        with mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_located_in=check_located_in_place_from)):
            self.machine.step_until_can()
        self.assertEqual(self.machine.pointer,
                         Pointer(state='start', jump=Jump(state_from='start', state_to='st_throught_place').uid))

        with mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_located_in=check_located_in_place_thought)):
            self.machine.step_until_can()

        self.assertEqual(self.machine.pointer,
                         Pointer(state='st_throught_place',
                                 jump=Jump(state_from='st_throught_place', state_to='st_finish').uid))

        # no move, since hero not in right place
        with mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_located_in=check_located_in_place_thought)):
            self.machine.step_until_can()
        self.assertEqual(self.machine.pointer,
                         Pointer(state='st_throught_place',
                                 jump=Jump(state_from='st_throught_place', state_to='st_finish').uid))

        with mock.patch('questgen.machine.Machine.interpreter', FakeInterpreter(check_located_in=check_located_in_place_to)):
            self.machine.step_until_can()
        self.assertEqual(self.machine.pointer,
                         Pointer(state='st_finish', jump=None))
Пример #41
0
 def setUp(self):
     self.kb = KnowledgeBase()