2009-12-14 11 views
12

Wstęp: Nie mam doświadczenia z silnikami reguł, regułami budowania, regułami modelowania, implementowaniem struktur danych dla reguł ani nic. Dlatego nie wiem, co robię lub jeśli to, co próbowałem poniżej, jest daleko poza bazą.Jaka jest odpowiednia struktura danych i schemat bazy danych do przechowywania reguł logicznych?

Próbuję dowiedzieć się, jak przechowywać i przetwarzać poniższy hipotetyczny scenariusz. Aby uprościć mój problem, powiedz, że mam typ gry, w której użytkownik kupuje obiekt, w którym może znajdować się 1000 możliwych obiektów, a przedmioty muszą zostać zakupione w określonej kolejności i tylko w określonych grupach. Na przykład powiedz, że jestem użytkownikiem i chcę kupić obiekt F. Zanim będę mógł kupić obiekt F, muszę wcześniej zakupić obiekt A OR (B i C). Nie mogę kupić F i A w tym samym czasie, ani F i B, C. Muszą być w kolejności określonej przez regułę. Pierwsza, potem F później. Albo najpierw B, C, potem F później. Nie interesuje mnie teraz czas między zakupami ani żadna inna cecha użytkownika, tylko że są one na razie właściwą sekwencją.

Jaki jest najlepszy sposób przechowywania tych informacji dla potencjalnie tysięcy obiektów, które pozwalają mi odczytać reguły dotyczące kupowanego obiektu, a następnie sprawdzić je w porównaniu z poprzednią historią zakupów użytkownika?

Próbowałem tego, ale utknąłem przy próbach implementacji grupowań, takich jak A OR (B i C). Chciałbym zapisać reguły w bazie danych, gdzie mam te tabele:

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

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

ale oczywiście, jak przetwarzać poprzez wynikach, bez grupowania, masz złą odpowiedź. Chciałbym, jeśli to możliwe, unikać nadmiernego parsowania napisów :). Jeden obiekt może mieć nieznaną liczbę wcześniejszych wymaganych zakupów. Zwracamy uwagę na fragmenty kodu SQL lub psuedocode do przetwarzania reguł. :)

Odpowiedz

5

Wygląda na to, że problem ustąpił przy testowaniu, czy określony warunek został spełniony.

Będziesz miał warunki złożone. Więc biorąc pod uwagę tabelę elementów:

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

i biorąc pod uwagę tabelę możliwych działań:

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

Budujemy tabelę warunków:

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

Więc WŁAŚCICIELEM oznacza id klucz do tabeli Items, a MEETS_CONDITION oznacza, że ​​id jest kluczem do tabeli Conditions.

Nie ma to na celu ograniczenia użytkownika. Możesz dodawać inne tabele z zadaniami lub cokolwiek innego i dodawać dodatkowe czasowniki, aby powiedzieć, gdzie szukać. Lub po prostu umieść questy w swoim stole przedmiotów, gdy je ukończysz, a następnie zinterpretuj ukończoną misję jako posiadanie określonej odznaki. Następnie możesz obsłużyć zarówno przedmioty, jak i misje z tym samym kodem.

0

Jest to bardzo złożony problem, którego nie jestem w stanie odpowiedzieć, ale widziałem wiele odniesień do. Podstawowym problemem jest to, że gry, questy i przedmioty oraz "statystyki" dla różnych obiektów mogą mieć zależności nierelacyjne. This thread may help you a lot.

Być może zechcesz pobrać kilka książek na ten temat i przyjrzeć się użyciu LUA jako procesora reguł.

0

Osobiście zrobiłbym to w kodzie, a nie w SQL. Każdy element powinien być własną klasą implementującą interfejs (tj.IItem). IItem miałby metodę zwaną OkToPurchase, która określałaby, czy można ją kupić. Aby to zrobić, użyje co najmniej jednego zestawu reguł (np. HasPreviouslyPurchased (x), CurrentOwns (x) itd.), Które możesz zbudować.

Przyjemne jest to, że łatwo jest rozszerzyć to podejście o nowe zasady bez łamania całej istniejącej logiki.

Oto niektóre Pseudokod:

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) 
} 
Powiązane problemy