示例#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
文件: logic.py 项目: Alkalit/the-tale
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
示例#3
0
            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)
            ]

    selector = Selector(kb, qb)
    kb += Quest.construct_from_place(nesting=0, selector=selector, start_place=selector.new_place(candidates=('place_1',)))

    try:
        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()])
        pass
    except Exception:
        print 'quesr %s is invalid' % Quest.TYPE
        raise

    drawer = Drawer(knowledge_base=kb)
    drawer.draw('./svgs/%s.svg' % Quest.TYPE)
示例#4
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]))
示例#5
0
文件: example.py 项目: mm3/questgen
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
示例#6
0
        facts.UpgradeEquipmentCost(money=777)
    ]

    selector = Selector(kb, qb)
    kb += Quest.construct_from_place(
        nesting=0,
        selector=selector,
        start_place=selector.new_place(candidates=('place_1', )))

    try:
        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()
        ])
        pass
    except Exception:
        print('quesr %s is invalid' % Quest.TYPE)
        raise

    drawer = Drawer(knowledge_base=kb)
    drawer.draw('./svgs/%s.svg' % Quest.TYPE)
示例#7
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))
示例#8
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]))
示例#9
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))
示例#10
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))
示例#11
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))
示例#12
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