2009-12-14 4 views
12

Vorwort: Ich habe keine Erfahrung mit Regel-Engines, Bauregeln, Modellierungsregeln, Implementieren von Datenstrukturen für Regeln oder was auch immer. Daher weiß ich nicht, was ich mache oder ob das, was ich versucht habe, weit von der Basis entfernt ist.Was ist eine geeignete Datenstruktur und ein Datenbankschema zum Speichern von Logikregeln?

Ich versuche herauszufinden, wie das folgende hypothetische Szenario zu speichern und zu verarbeiten. Um mein Problem zu vereinfachen, sage ich, dass ich einen Spieltyp habe, bei dem ein Benutzer ein Objekt kauft, wo es 1000 mögliche Objekte geben kann und die Objekte in einer bestimmten Reihenfolge und nur in bestimmten Gruppen gekauft werden müssen. Angenommen, ich bin der Benutzer und möchte Objekt F erwerben. Bevor ich Objekt F kaufen kann, muss ich zuvor Objekt A ODER (B und C) gekauft haben. Ich kann weder F und A noch F und B, C kaufen. Sie müssen in der Reihenfolge sein, die die Regel angibt. Eine erste, dann F später. Oder, B, C zuerst, dann F später. Ich bin jetzt nicht besorgt über die Zeitspanne zwischen Käufen oder andere Eigenschaften des Benutzers, nur dass sie die richtige Reihenfolge für jetzt sind.

Was ist der beste Weg, um diese Informationen für potenziell Tausende von Objekten zu speichern, die es mir erlaubt, die Regeln für das gekaufte Objekt einzulesen, und dann gegen den vorherigen Kaufverlauf des Benutzers zu überprüfen?

Ich habe das versucht, aber ich bin stecken bei dem Versuch, die Gruppierungen wie A OR (B und C) zu implementieren. Ich möchte die Regeln in einer Datenbank speichern, wo ich diese Tabellen haben:

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

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

Aber natürlich, wie Sie durch die Ergebnisse verarbeiten, ohne die Gruppierung, erhalten Sie die falsche Antwort. Ich möchte, wenn möglich, übermäßiges String-Parsing vermeiden :). Ein Objekt könnte eine unbekannte Anzahl vorher erforderlicher Käufe haben. SQL- oder psuedocode-Snippets zur Verarbeitung der Regeln wären willkommen. :)

Antwort

5

Es scheint, als ob Ihr Problem darin besteht, zu testen, ob eine bestimmte Bedingung erfüllt wurde.

Sie werden zusammengesetzte Bedingungen haben. So gegeben eine Tabelle mit Elementen:

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

und eine Tabelle der möglichen Aktionen gegeben:

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

wir eine Tabelle von Bedingungen konstruieren:

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

So OWNS bedeutet die ID ist ein Schlüssel für die Items-Tabelle und MEETS_CONDITION bedeutet, dass die ID ein Schlüssel für die Tabelle Conditions ist.

Dies soll Sie nicht einschränken. Du kannst andere Tische mit Quests oder was auch immer hinzufügen und zusätzliche Verben hinzufügen, um dir zu sagen, wo du suchen musst. Oder leg einfach Quests in deine Items-Tabelle, wenn du sie abgeschlossen hast, und interpretiere dann eine abgeschlossene Quest als Besitzer eines bestimmten Badges. Dann kannst du sowohl Items als auch Quests mit demselben Code bearbeiten.

0

Dies ist ein sehr komplexes Problem, das ich nicht beantworten kann, aber ich habe viele Referenzen zu gesehen. Das grundlegende Problem ist, dass für Spiele, Quests und Items und "Stats" für verschiedene Objekte nicht-relationale Abhängigkeiten bestehen können. This thread may help you a lot.

Sie möchten vielleicht ein paar Bücher zu diesem Thema aufgreifen und LUA als Regelprozessor verwenden.

0

Persönlich würde ich dies in Code tun, nicht in SQL. Jeder Gegenstand sollte seine eigene Klasse sein, die eine Schnittstelle implementiert (d. H.IItem). IItem würde eine Methode namens OkToPurchase haben, die bestimmen würde, ob es in Ordnung ist, diesen Artikel zu kaufen. Um dies zu tun, würde es eine oder mehrere einer Sammlung von Regeln verwenden (d. H. HasPreviouslyPurchased (x), CurrentOwns (x) usw.), die Sie erstellen können.

Das Schöne ist, dass es einfach ist, diesen Ansatz mit neuen Regeln zu erweitern, ohne die gesamte vorhandene Logik zu durchbrechen.

Hier einige Pseudo-Code:

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