¿Cuál es una estructura de datos y un esquema de base de datos apropiados para almacenar reglas lógicas?

StackOverflow https://stackoverflow.com/questions/1902951

Pregunta

Prefacio:No tengo experiencia con motores de reglas, construcción de reglas, modelado de reglas, implementación de estructuras de datos para reglas o todo eso.Por lo tanto, no sé qué estoy haciendo o si lo que intenté a continuación está fuera de lugar.

Estoy intentando descubrir cómo almacenar y procesar el siguiente escenario hipotético.Para simplificar mi problema, digamos que tengo un tipo de juego en el que un usuario compra un objeto, donde podría haber miles de objetos posibles, y los objetos deben comprarse en una secuencia específica y solo en ciertos grupos.Por ejemplo, digamos que soy el usuario y quiero comprar el objeto F.Antes de poder comprar el objeto F, debo haber comprado previamente el objeto A O (B Y C).No puedo comprar F y A al mismo tiempo, ni F y B,C.Deben estar en la secuencia que especifica la regla.A primero, luego F después.O B, C primero y luego F después.No me preocupa en este momento el lapso de tiempo entre compras, ni ninguna otra característica del usuario, solo que sean la secuencia correcta por ahora.

¿Cuál es la mejor manera de almacenar esta información para potencialmente miles de objetos que me permita leer las reglas del objeto que se está comprando y luego compararla con el historial de compras anterior del usuario?

Intenté esto, pero no puedo intentar implementar agrupaciones como A O (B Y C).Me gustaría almacenar las reglas en una base de datos donde tenga estas tablas:

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

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

Pero, obviamente, a medida que procesa los resultados, sin la agrupación, obtiene la respuesta incorrecta.Si es posible, me gustaría evitar el análisis excesivo de cadenas :).Un objeto podría tener un número desconocido de compras previas requeridas.Se agradecerían fragmentos de SQL o psuedocódigo para procesar las reglas.:)

¿Fue útil?

Solución

Parece que su problema se descompone para probar si una condición particular, ha sido satisfecho.

Usted tendrá condiciones compuestas. Así que dada una tabla de elementos:

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

y que recibe un cuadro de posibles acciones:

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

Construimos una tabla de condiciones:

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

Así OWNS significa que el ID es una clave para la tabla de artículos, y MEETS_CONDITION significa que el ID es una clave para la tabla Condiciones.

Esto no pretende restringir usted. Se pueden añadir otras tablas con misiones o lo que sea, y añadir los verbos adicionales para decirle dónde buscar. O bien, sólo hay que poner misiones en su tabla de artículos cuando se complete, y luego interpretar una búsqueda completa como ser dueño de una tarjeta de identificación particular. A continuación, puede manejar ambos objetos y misiones con el mismo código.

Otros consejos

Este es un problema muy complejo que no estoy calificado para responder, pero he visto muchas referencias al mismo.El problema fundamental es que en los juegos, las misiones, los elementos y las "estadísticas" de varios objetos pueden tener dependencias no relacionales. Este hilo puede ayudarte mucho..

Quizás quieras leer un par de libros sobre el tema y considerar el uso de LUA como procesador de reglas.

En lo personal me gustaría hacer esto en el código, no en SQL. Cada elemento debe ser su propia clase que implementa una interfaz (es decir iItem). IItem tendría un método llamado OkToPurchase que determinar si está bien para comprar ese artículo. Para hacer eso, sería utilizar uno o más de un conjunto de reglas (es decir HasPreviouslyPurchased (x), CurrentlyOwns (x), etc.) que se puede construir.

Lo bueno es que es fácil de extender este enfoque con nuevas reglas sin romper toda la lógica existente.

Aquí hay algo pseudocódigo:

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 )
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top