Parse-Codestyle verbessern?
-
Wie gesagt, das setzt voraus, dass ich überhaupt erst die Formate kenne.

Gut, ich könnte einfach alle ausprobieren und somit den Identifizierungsprozess auf der Strecke liegen lassen. Wer keine Exception wirft, gewinnt!
-
Kannst du nicht anhand der Programmversion das HH Format bestimmen?
Das sollte wesentlich zuverlässiger funktionieren, als erst beim Parsen zu versuchen, das Format zu erkennen.
Dann würde ich für jeden unterstützten Client/Version einen Parser bauen, der das Format der jeweiligen Version lesen kann. Wenn sich am HH Format nichts ändert kann der HH Reader natürlich auch HH Dateien anderer Programmversionen lesen.
-
Version welchen Programms denn? Des Programms, das die Datenbank verwaltet? Das ist halt nur eine Determinante und ich weiß gar nicht, welchen Einfluss die auf das HH-Format hat.
Oder meinst Du, dass der Benutzer selbst auswählen soll, von welcher Seite die HH kommt? Das wäre zwar möglich, jedoch bietet andere Software eben an es ohne diese Abfrage zu tun, d.h. hier hätte man etwas Komfortverlust. Wobei der verschmerzbar sein sollte, das ist richtig. Nur wäre es ggü. dem, was jetzt gerade ist, ein Rückschritt. Den Code sauberer zu machen, indem ich den Benutzer-Komfort senke, halte ich für ein teures Geschäft.
-
OK, dann halt andersherum:
Deine HH Reader Software liest ja bestimmte Verzeichnisse aus. Bei den HH Readern, die ich kenne, erkennt die Software automatisch den Pfad und weiß, zu welcher Pokersoftware dieser Pfad gehört. Wenn sie weiß, zu welcher Pokersoftware der Pfad gehört, dann kann sie auch die Versionsinformationen der Pokersoftware auslesen.
Abhängig davon kann dann das HH Reader Objekt erzeugt und benutzt werden.
Es gibt allerdings einige Fallstricke (gemischte Formate in einem Verzeichnis nach einem Update der Pokersoftware, doofer Benutzer hat mehrere Pokerclients und schreibt alle HH in ein Verzeichnis, etc. )
-
Achso. Ne, bei mir kommt der Input eh aus der Zwischenablage, welcher wiederum aus der jeweiligen Datenbank-HH-Verwaltungssoftware kommt (nutzt nämlich eh jeder). Da habe ich also leider kein Verzeichnis. Und die Fallstricke sind in der Tat verheerend, zumal die HHs selbst oft aus den Verzeichnissen der Seiten gelöscht werden (oder verschoben), wenn besagte DB-HH-Verwaltungssoftware sie importiert hat. Dann landen sie in einem Sammelverzeichnis, aus dem es kein Entkommen mehr gibt.

-
Was genau hast du eigentlich vor? Wenn die HH aus einer db kommt, vielleicht stehen in der db ja verwertbare Daten, die du benutzen kannst?
-
Das wäre eine Idee, wenn die DB genormt wäre, aber auch hier gibt es unterschiedliche Formate. Es gibt zwei große Softwares, die zum Verwalten der HHs (und vielem mehr) verwendet werden: PokerTracker (4) und Holdem Manager (2). Jedoch gibt es ein paar kleinere. Und die Datenbanken ändern sporadisch auch Mal ihr Format, daher werde ich wohl nicht viel weniger Arbeit haben (darüber hinaus hat ein Überfliegen vor kurzem ergeben, dass die Daten soo verwertbar nicht sind, aber kann gut sein, dass ich etwas übersehen habe).
Mein Vorhaben mit den Daten ist, dass man unter Eingabe der fehlenden Daten (Vermutung darüber, welche Hände der jeweilige Gegner genau spielt) für jede Aktion den Erwartungswert berechnen kann. Funktioniert ja auch hervorragend.
-
Du könntest dir mal monadisches Parsen anschauen. Damit kannst du zumindest deinen Code übersichtlicher und leichter erweiterbar gestalten. Soweit ich weiß gibt es allerdings keine Bibliotheken im C++ Bereich. Google: c++ monadic parsing liefert eine paar grundlegende Infos und Ansätze.
Eisflamme schrieb:
Mögliche Abweichungen:
- die ersten zwei Zeilen können fehlen oder komplett anders aussehen
- Statt "Seat 1: Spielername" kann da auch einfach "Spielername" stehen
- diverse Leerzeichen zwischen ( und $ sind möglich
- statt $ kann überall auch ein anderes Währungszeichen stehen; es kann auch fehlen
- Die Blind-Postings-Lines können fehlen; es werden dann dennoch Blinds geposted, das aber nicht angezeigt (sind Pflichtbeträge)
- "*** HOLE CARDS ***" und die anderen haben ein paar Alternativbezeichnungen je nach Seite
- "Dealt to Player1" kann anders heißen oder fehlen, kommt manchmal auch in der "*** HOLE CARDS ***"-Zeile vor
- Die Aktionen, die hier immer die Form "Spieler: does" hat kann ohne Doppelpunkt dargestellt werden
- Die Aktionen (siehe
können bei raise ohne das "$x to $y" erfolgen, also einfach nur "to $y" - Die Aktionen können statt in unterschiedlichen Zeilen auch in einer Zeile mit Komma separiert vorkommen; auch dann mit und ohne Doppelpunkt
- Auch die Karten von "*** FLOP ***" können statt in eckigen Klammern ohne eckige Klammern dort stehen
- Es können 2-10 Spieler mitspielen
- Das Spiel kann vorbei sein, bevor Flop/Turn/River überhaupt erscheinen
- Spielernamen können eine große Menge an Sonderzeichen enthalten; welche hängt vom Seitenbetreiber ab
Im Prinzip behandelst du die ganzen Eventualitäten, indem du alle Möglichkeiten durch kleine Parser implementierst und einen Parser für einen "Block" dann durch entsprechende Kombinatoren zusammensetzt.
grobes Beispiel für Geldbeträge:
parseBetrag = (parseWährungszeichen && parseWert) || parseWertWenn du dich ein wenig mit Haskell auskennst, kann du dir ja mal Parsec anschauen.
-
Vorallem kann so ein Lexer durchaus Sinn machen. Ob da dann nämlich USD, $ oder was auch immer steht, ist dann egal, weil der Scanner alles in ein Token überführt.
-
wyfrn:
Das klingt ganz interessant! Wenn es wiederum keine C++-Bibliothek gibt, nützt mir das nicht so viel. Andere Sprachen mit einzuflechten erscheint mir (zurzeit) noch sehr aufwendig.jhkhjkhjk:
Aber wenn USD im Namen vorkommt, habe ich schon verloren, oder? Ein Name wie USD12315 ist nämlich nicht verboten. Und je nach Seite kann es auch sein, dass EUR (hab das Zeichen gerade nicht) als Spielwährung gar nicht angezeigt wird und daher im Nickname erlaubt ist oder so.
-
Eisflamme schrieb:
wyfrn:
Das klingt ganz interessant! Wenn es wiederum keine C++-Bibliothek gibt, nützt mir das nicht so viel. Andere Sprachen mit einzuflechten erscheint mir (zurzeit) noch sehr aufwendig.Der erste Treffer in dem Google Link stellt einen Implementation in C++ vor und das ganze gibts auch als Lib auf github. Vielleicht kannst du ja damit was anfangen bzw. für dich anpassen. Kostet zwar jetzt ne Ecke an Arbeit, aber wenn deine Daten wirklich so schlecht strukturiert sind und sich häufig ändern, wirst du im Nachhinein davon profitieren.