Regelwerek für Wettkampf



  • Hi!

    Ich hab ein Programm geschrieben, um die Auswertung für einen Wettkampf zu machen.
    Ich habe die Regeln für den Wettkampf im Code hart codiert, allerdings möchte ich das ändern, da sich diese Regeln von Jahr zu Jahr ändern können.
    Evtl. mit Config-Files oder mit Scripten.
    Allerdings fehlt mir da irgendwie die zündende Idee, wie ich so etwas machen kann.

    Hat von euch jemand schon mal so etwas gemacht?

    Das Programm ist in C# geschrieben und im Hintergrund hab ich eine MS SQL CE Datenbank um die Zeiten, Startnummern usw... zu speichern.

    MfG bauerb

    P.S.: Ich weiß nicht, ob ich im richtigem Forum bin, aber das Thema hat am ehesten mit Spielen zu tun.



  • Zu vage formuliert. Da musst du schon mehr Details geben.
    Handelt es sich bei den Regeländerungen lediglich um Grenzwertë, z.b. "Man muss über 30 Punkte haben um zu gewinnen" (30 variabel), dann ist es ein einfaches config-File. (Empfehlung: Boost.Properties).
    Sind die Regeln und möglichen -Änderungen aber komplexer, dann muss wohl eine Script-sprache zum Einsatz kommen um die dynamisch ändern zu können. Scriptsprachen die sich zum "embedden" in C++ eignen sind zum Beispiel Lua, Python oder Javascript.



  • Hi!

    Es sieht so aus, dass es verschiedene Leisungsklassen gibt:
    * Schüler Einer
    * Jugend Einer
    * Allgemeine Klasse Einer
    * Altersklasse Einer

    Des weiteren gibt es Doppel. Da fahren immer 2 in einem Gefährt. Allerdings vom gleichen Verein:

    * Schüler Zweier
    * Jugend Zweier
    * Allgemeine Klasse Zweier
    * Altersklasse Zweier

    Das Auszuwerten ist eh kein Problem, da sich dieses Ergebnisse nur auf die Rundenzeit beziehen.

    Allerdings gibt es dann noch eine Mannschaft. Diese kann aus 3-4 aus der Allgemeinen Klasse und aus der Altersklasse im Einer und aus 1-2 aus der Allgemeinen Klasse und aus der Altersklasse im Zweier bestehen.

    Ausgeweertet wird diese so, dass die besten 3 Zeiten aus dem Einer und die beste Zeit aus dem Zweier zusammengezählt wird und dann gereiht. Wer die beste Zeit hat, hat gewonnen.

    Das kann sich aber ändern.

    Jetzt wäre es schön, wenn man einen Satz von Regeln in ein Script oder gleich in der Datenbank abbilden könnte.

    Ich weiß, dass das nicht so einfach ist, aber jedes Jahr das Programm anpassen ist auch nicht so toll.

    MfG Bernd



  • Ich denke mal das könntest du direkt im SQL berechnen lassen, Stored Procedures oder ähnliches. Kannst es auch per Scriptsprache lösen. Es bleibt nur eins zu bedenken:

    Irgendwo solltest du abspeichern wie du zu den Ergebnissen gekommen bist. Es nützt ja nix wenn du Jährlich den algorithmus anpasst und jemand fragt die Ergebnisse vom vorletzten Jahr ab, aver der jetzige Algorihmus spuckt komplett andere Werte aus.

    Ich würde warscheinlich versuchen eine allgemeingültige Formel für die Berechnung zu modellieren und in der Datenbank dann auch ablegen woher die Variablen für die Berechnung kommen. Damit bildest du sozusagen die Berechnungsgrundlage auch in der Datenbank ab.



  • Hi!

    Ich denke mal das könntest du direkt im SQL berechnen lassen, Stored Procedures oder ähnliches. Kannst es auch per Scriptsprache lösen.

    Meines Wissens unterstützt die SQL CE keine Stored Procedures. Ist eine Embedded Datenbank.

    Irgendwo solltest du abspeichern wie du zu den Ergebnissen gekommen bist. Es nützt ja nix wenn du Jährlich den algorithmus anpasst und jemand fragt die Ergebnisse vom vorletzten Jahr ab, aver der jetzige Algorihmus spuckt komplett andere Werte aus.

    Dass mit einem neuen Regelsatz die alten Ergebnisse nicht mehr stimmen, daran hatte ich noch gar nicht gedacht. Danke für den Tipp!

    Ich würde warscheinlich versuchen eine allgemeingültige Formel für die Berechnung zu modellieren und in der Datenbank dann auch ablegen woher die Variablen für die Berechnung kommen. Damit bildest du sozusagen die Berechnungsgrundlage auch in der Datenbank ab.

    Wie könnte so eine Abbildung in der DB aussehen? Hab echt keinen Plan.

    MfG Bernd



  • Das was ich jetzt schreibe ist nur ne grobe Idee. Nicht näher darüber nachgedacht aber ggf ist es so durchsetzbar.

    Mach eine weitere Tabelle bestehend aus folgenden Spalten:
    ID: Fremdschlüssel über den du einen Satz regeln referenzierst
    Order: Zahlen von 1-irgendwas der Angibt an welcher Stelle die Berechnung greift (der name ist blöd gewählt mir fällt nur gerade nix besseres ein)
    Source: Dies kann eine Konstante oder ein SQL Statement sein welcher die Berechnungsgrundlage liefert
    Operation: Dies wird eine Operation sein also ein art enum aus (Add, Sub, Mul, Div)
    Pseudocode:

    //holen aller entrys nach Order (gemeint ist die Spalte Order) sortiert
    Entrys = GetOrderedEntrysForId(IdForLastYear);
    //initialisierung des gesamtergebnis
    int curVal = 0;
    foreach(curEntry in Entrys) do
       //prüfen ob curEntry.Source eine Konstante ist 
       if (IsConstant(curEntry)) do
          //curVal neuberechnen, Calculate wertet nun die Operation aus und bekommt 
          //den alten Wert + den Konstanten Wert der hinzu gerechnet werden soll
          curVal = Calculate(curVal, GetConstantValue(curEntry), GetOperation(curEntry);
       else do
          //curVal neuberechnen, ähnlich wie oben nur das anstatt einer Konstante 
          //vorher ein Wert aus der Datenbank genommen wird.
          curVal = Calculate(curVal, GetDataBaseValue(curEntry), GetOperation(curEntry);
       end
    end
    ... Mach was mit curVal
    

    Du arbeitest also systematisch dein Regelwerk aus der Datenbank ab und veränderst dabei curVal in jeden Schritt bis alle Regeln abgearbeitet sind.
    Ändert sich der Regelsatz definierst du einen neuen der abgearbeitet wird. Alte Berechnungen können so noch auf den alten Regelsatz verweisen.

    Es geht sicherlich noch besser als dieser Ansatz, das wäre einfach meine erste Naive idee.

    Edit:
    Natürlich müsste man noch schauen das die Spalte Source. Sofern sie eine SQL Abfrage enthält ggf auch noch Parameter mitbekommen müsste. Solche feinheiten machden das ganze ja etwas Komplexer. Man könnte also noch irgendwelche Params dort einbauen die vor der Auswertung gesetzt werden, damit der Ausdurck wirklich auswertbar ist.



  • Hi!

    Ich muss mir das ganze nochmal durch den Kopf gehen lassen, aber das hört sich eh schon ganz gut an.

    Hat sowas sonst noch niemand versucht? Ich hoffe, dass noch jemand ein paar andere Ideen einbringt.

    MfG bauerb



  • Ich würde für sowas die Berechnung in eine andere Skriptaprache auslagern.
    Gut eignet sich hierfür LUA. Ist Open-Source, nicht zu komplex und sehr einfach.

    http://www.lua.org/ftp/
    http://de.wikipedia.org/wiki/Lua



  • Hallo zusammen,

    wie der OT geschrieben hat:

    bauerb schrieb:

    Das Programm ist in C# geschrieben und im Hintergrund hab ich eine MS SQL CE Datenbank...

    geht es hier also weder um C++ noch um eine Server-Datenbank, und daher sind Lua bzw. Stored Procedures hier überhaupt nicht hilfreich 😉

    Und hallo Bernd (bauerb),

    je nach dem wie groß jetzt schon dein Regelwerk (in C#) ist, hast du verschiedene Möglichkeiten.
    Wenn du das ganze sehr dynamisch haben willst, so könntest du den Code weiterhin mit C# programmieren, diesen dann aber (je nach Version) per "CodeDOM" einbinden, s. z.B.
    http://www.codeproject.com/KB/cs/cscompiler.aspx
    http://www.codeproject.com/KB/cs/MiniCompiler.aspx
    http://www.codeproject.com/KB/cs/DynamicCodeGeneration.aspx
    http://www.codeproject.com/KB/cs/codedom_assistant.aspx
    http://msdn.microsoft.com/en-us/library/650ax5cx.aspx (Dynamic Source Code Generation and Compilation ff.)

    Eine andere Möglichkeit wäre, du lagerst das Regelwerk (je nach Version) in verschiedene Assemblies aus und lädst dann die jeweilige Assembly beim Start (entweder einfach durch Umbenennen mittels einer Batch-Datei) oder aber mittels eines "Plugin"-Systems, z.B. MEF: http://mef.codeplex.com/

    Vllt. sollte ein Mod diesen Beitrag dann doch ins "C# und .NET"-Forum verschieben...



  • Th69 schrieb:

    Vllt. sollte ein Mod diesen Beitrag dann doch ins "C# und .NET"-Forum verschieben...

    Ich hab in dieses Forum gepostet, da ich mir dachte, dass so etwas am ehesten bei Spielen schon mal jemand gemacht hat. Sorry, falls ich falsch bin.


Log in to reply