Подтвердить что ты не робот

Какова подходящая структура данных и схема базы данных для хранения логических правил?

Предисловие: у меня нет опыта работы с механизмами правил, правилами построения, правилами моделирования, реализацией структур данных для правил или еще чего-то. Поэтому я не знаю, что делаю, или что то, что я пытаюсь сделать ниже, находится вне базы.

Я пытаюсь понять, как хранить и обрабатывать следующий гипотетический сценарий. Чтобы упростить мою проблему, скажите, что у меня есть тип игры, где пользователь покупает объект, где может быть 1000 возможных объектов, и объекты должны быть приобретены в указанной последовательности и только в определенных группах. Например, скажите, что я пользователь, и я хочу приобрести объект F. Прежде чем я могу купить объект F, я должен предварительно приобрести объект A OR (B AND C). Я не могу покупать F и A одновременно, а не F и B, C. Они должны быть в последовательности, указанной в правиле. Сначала, затем F позже. Или, B, C сначала, затем F позже. Меня сейчас не интересует с промежутком времени между покупками или любыми другими характеристиками пользователя, только что они являются правильной последовательностью на данный момент.

Каков наилучший способ хранения этой информации для потенциально тысяч объектов, которые позволяют мне читать правила для приобретаемого объекта, а затем проверять его против предыдущей истории покупок пользователя?

Я попытался это сделать, но я застрял в попытке реализовать группы, такие как A OR (B AND C). Я хотел бы сохранить правила в базе данных, где у меня есть эти таблицы:

 Objects
    (ID(int),Description(char)) 

ObjectPurchRules
    (ObjectID(int),ReqirementObjectID(int),OperatorRule(char),Sequence(int)) 

Но, очевидно, по мере того, как вы обрабатываете результаты, без группировки, вы получаете неправильный ответ. Я хотел бы избежать чрезмерного синтаксического анализа строк, если это возможно:). Один объект может иметь неизвестное количество предыдущих требуемых покупок. Фрагменты SQL или psuedocode для обработки правил будут оценены.:)

4b9b3361

Ответ 1

Кажется, что ваша проблема ломается, проверяя, выполнено ли какое-либо конкретное условие.

У вас будут сложные условия. Поэтому дается таблица элементов:

ID_Item    Description
----------------------
1          A         
2          B         
3          C         
4          F         

и приведена таблица возможных действий:

ID_Action  VerbID  ItemID    ConditionID
----------------------------------------
1          BUY     4         1

Построим таблицу условий:

ID_Condition  VerbA  ObjectA_ID  Boolean  VerbB            ObjectB_ID
---------------------------------------------------------------------
1             OWNS   1           OR       MEETS_CONDITION  2
2             OWNS   2           AND      OWNS             3

Таким образом, OWNS означает, что идентификатор является ключом к таблице Items, а MEETS_CONDITION означает, что идентификатор является ключом к таблице условий.

Это не должно ограничивать вас. Вы можете добавить другие таблицы с квестами или что-то еще, и добавить дополнительные глаголы, чтобы рассказать вам, где искать. Или просто поместите квесты в таблицу Items, когда вы их завершите, а затем интерпретируете завершенный квест как владеющий определенным значком. Затем вы можете обрабатывать оба элемента и квесты с тем же кодом.

Ответ 2

Это очень сложная проблема, на которую я не способен ответить, но я видел много ссылок. Основная проблема заключается в том, что для игр, квесты и элементы и "статистика" для разных объектов могут иметь нереляционные зависимости. Этот поток может вам очень помочь.

Возможно, вам захочется собрать пару книг по этой теме и изучить использование LUA в качестве процессора правил.

Ответ 3

Лично я бы сделал это в коде, а не в SQL. Каждый элемент должен быть собственным классом, реализующим интерфейс (т.е. IItem). У IItem был бы метод под названием OkToPurchase, который определит, нормально ли покупать этот элемент. Для этого он будет использовать один или несколько наборов правил (т.е. HasPreviouslyPurchased (x), CurrentOwns (x) и т.д.), Которые вы можете создать.

Приятно, что этот подход можно легко расширить с помощью новых правил, не нарушая при этом всю существующую логику.

Здесь некоторый псевдокод:

bool OkToPurchase()
{
   if( HasPreviouslyPurchased('x') && !CurrentlyOwns('y') )
       return true;
   else
       return false;
}

bool HasPreviouslyPurchased( item )
{
    return purchases.contains( item )
}

bool CurrentlyOwns( item )
{
    return user.Items.contains( item )
}