# Pokergame + Datenbankanbindung (Wahrscheinlichkeiten)



## ChopstickZ (21. Jun 2010)

Moin alle zusammen,

ein paar Kommilitonen und ich entwickeln zur Zeit Texas Holdem software. Ich habe mich eine Weile mit Chancenberechnung etc auseinandergesetzt und festgestellt, dass es viele Möglichkeiten gibt, Poker Odds zu bestimmen.

Ich habe mich für folgendes entschieden: Zu jedem Zeitpunkt mit jeder Hand sollen die Prozente angezeigt werden, *mit welcher Wahrscheinlichkeit* man mit den gerade verfügbaren Karten am Ende des Spiels mit einer HighCard, einem pair, 2Pair, ThreeOfAKind,...,Straight Flush dasteht.

Man hat zB vor dem Flop die Starthand Kreuz Ass, Kreuz König:
HighCard: 18,22%
Pair: 43,25%
Two Pair: 22,16%
Three OAK: 4,34%
Straight: 3,09%
Flush: 6,52%
Full House: 2,23%
Four OAK: 0,13%
Straight Flush: 0,06%

Insgesamt sollte 100% rauskommen.

*Meine Idee zur Lösung* des Problems: Es gibt 133 Mio Möglichkeiten 7 Karten aus 52 auszuwählen. Ich speichere alle in eine Datenbank. Die Reihen heißen etwa "HoleCard1", "HoleCard2", "Flop1", "Flop2", "Flop3", "Turn", "River" und dann "WinType" (wo einer der 9 Typen HighCard bis Straight Flush drinsteht).

Bei PreFlop liegen zero Karten in der Mitte, d.h. alles was sichtbar ist, sind 2 Handkarten. Da mache ich dann folgendes: Ich lasse mir alle Zeilen ausgeben, in denen HoleCard1 und HoleCard2 übereinstimmen, summiere die Anzahl der Zeilen auf und rechne dann: AnzahlHighCard / Summe, AnzahlPair / Summe, ... um die korrekten Zahlen zu erhalten.

Bei Flop lasse ich mir dann bzgl 5 Karten alle Werte ausgeben und berechne danach.

usw.


Habe kaum Erfahrung was Java und Datenbankanbindung angeht. Nun wollte ich wissen, ob sich für so eine riesige Tabelle (133 Mio Zeilen, 8 Spalten) JDBC eignet und wenn ja, ob ihr mir irgendwelche Tipps diesbezgl geben könnt.
Ich würde dann also einmalig irgendwie diese Tabelle erstellen und dann mit dem Spiel 'mitliefern' (ist nur für Lernzwecke) um die Daten abzurufen.

Falls es einfachere Methoden gibt das Ganze zu realisieren, nur zu.. :bahnhof:


MfG Chop


PS: Beste hand berechnen ist schon Teil des Programms. Das stellt hier also kein Problem dar.


----------



## Gast2 (21. Jun 2010)

> Es gibt 133 Mio Möglichkeiten 7 Karten aus 52 auszuwählen. Ich speichere alle in eine Datenbank.



Ich denke es wäre sinnvoller die Chancen auszurechnen, spart dir erstens ne Menge Speicherplatz und zweitens sollte die Berechnung mit ein wenig Kombinatorik und w'keitsrechnung nicht allzulange dauern.


----------



## agentone (21. Jun 2010)

Ich glaube nicht, dass du dir 133 Mio. Möglichkeiten in einer Datenbank speichern willst.
Selbst wenn du pro Datensatz nur 1 Byte speicherst, ist die Datenbank ca. 130 MegaByte groß!

Und solche Kombinatorischen Sachen würde ich immer während der Laufzeit erstellen, dabei aber natürlich nicht alle Möglichkeiten gleichzeitig im Speicher haben, sondern immer nur den, den man gerade braucht.


----------



## dev-eth0 (21. Jun 2010)

Genau.... Irgend nen schönen Cache schreiben, der eine feste maximal Größe haben kann.
Wenn dann eine Wahrscheinlichkeit benötigt wird, schauen, ob diese im Cache ist und wenn nicht, ausrechnen und reinpacken.
Sobald der Cache voll wird, muss halt ein Eintrag überschrieben werden.

Falls du es dann noch was schöner machen willst, speicherst du noch irgendwo, wie oft eine Wahrscheinlichkeit gefragt wurde und überschreibst dann selten benutzte Einträge im Cache statt irgendwelchen, die vll öfter benötigt werden.

Läuft die Anwendung dann auf irgend nem Server, dann kannst du den Cache ja so groß wählen, dass die wichtigsten Einträge reinpassen und du dann nach einer gewissen Anlaufzeit nur noch im Cache nachgeschlagen werden muss.


----------



## ChopstickZ (21. Jun 2010)

Danke für eure Vorschläge!

Man kann die Chancen leider nicht mal eben so ausrechnen. Es gibt keine einfache Formel oder irgendetwas der Art. Das war meine erste Idee aber die ist seit 3 Wochen nicht mehr aktuell. Hab mich viel damit auseinandergesetzt und die einzigen möglichkeiten sind: Alles in einem riesigen Array (bzw DB) halten oder ein paar millionen zufallsspiele durchlaufen zu lassen und zu sehen wer damit am ende gewinnt. ich würde es gerne exakt machen 

Wie ihr das übern Cache lösen wollt, verstehe ich nicht so ganz. Also das Programm mal eben durchlaufen zu lassen während der laufzeit ist aus laufzeittechnischen gründen eher ungünstig. das berechnen selbst dauert ewig. selbst wenn man das nur von den aktuellen karten abhängig macht sind das zB mit 2 Handkarten immer noch 5 die dazukommen bis showdown. Das sind also 50 über 5 = 2 Mio möglichkeiten. da hätte man immer ein delay. und 2 millionen werte in ein array, am besten noch mehrdimensional, ich weiß nicht ob java da mitmacht (mit nicht so der crack..).

Eine Idee die mir vorhin noch kam:
Ich würde mehrere Datenbanken nutzen: eine für Preflop (1300 Einträge), eine für Flop (2,4 Mio Einträge), eine für Turn (20 Mio Einträge). Das ist speicherplatztechnisch okay. River ist unnötig, den kann ich auch einfach durch den evaluator hauen, da es keine zusätzlichen karten mehr gibt (nur einen wert mit 100%).

um diese datenbanken zu erstellen brauche ich aber erstmal eine 133 MByte DB. Die wird nicht im endprodukt dabei sein, das ist natürlich sehr groß, das stimmt. Für mich zum testen ist das aber okay.

deshalb würde ich gerne wissen ob jdbc okay ist oder es wegen der schieren größe zu problemen kommen könnte.


gruß chop


----------



## dev-eth0 (21. Jun 2010)

Beim Cachen bin ich davon ausgegangen, dass es möglich ist, die Wahrscheinlichkeiten eines bestimmten Zuges zu berechnen.

Wenn du sagst, dass geht nicht, bleibt dir wohl nichts außer einer Datenbank. Wobei dann natürlich noch rauszufinden ist, wie lange ein PC zum erstellen dieser DB benötigt...

JDBC ist da schon ok für, vielleicht aber noch einfacher Hibernate (ist aber Geschmackssache).


----------



## Michael... (21. Jun 2010)

Ich könnte mir vorstellen, dass man einfach nur die Wahrscheinlichkeiten der einzelnen Starthände speichert. Da kommt man so überschlagen auf unter 2500 - vielleicht auch unter 2000 - Kombinationen, für die man in den einzelnen Kategorien die Wahrscheinlichkeiten abspeichert.
Nach dem Flop, lassen sich die Wahrscheinlichkeiten für die letzten zwei offenen Karten ziemlich schnell durch simulieren.


----------



## Gast2 (21. Jun 2010)

> Man kann die Chancen leider nicht mal eben so ausrechnen. Es gibt keine einfache Formel oder irgendetwas der Art.


Sehe ich nicht so.
Beispiel Preflop: (Hand: Kreuz2, Pik2)
Hier weißt du dass du schon nen Paar auf der Hand hast. Kannst also Highcard ausschließen(= 0%).
Wenn du jetzt z.b. die Wahrscheinlichkeit für einen Drilling ausrechnen willst bestimmst du zunächst was für eine Karte du brauchst und wieviele Karten der Sorte es noch gibt: Du brauchst eine 2, es sind noch zwei 2er im Deck.
Die Wahrscheinlichkeit für GENAU einen 2er (aus 2) bei noch 5 aufzudeckenden Karten lässt sich leicht mit ein wenig kombinatorik bestimmen.

Die Wahrscheinlichkeiten für alle weiteren Fälle berechnest du analog, allein in die Bestimmung der Karten welche du für eine bestimmte Hand brauchst (flush, royal flush, etc.) musst du ein wenig hirnschmalz stecken.

Wer fügt dann eigentlich die Werte in die Datenbank ein?


----------



## dev-eth0 (21. Jun 2010)

Vielleicht findest du hierdrin ja ne Lösung:

Mathematics of Poker


----------



## ChopstickZ (21. Jun 2010)

@ dev-eth0: Also ich denke er braucht maximal ne Stunde um die DB zu erstellen  eher 30- min. Hängt davon ab wie geschickt ich code.. Jede zusätzliche Zeile wird 133 Mio mal ausgeführt...
Danke für den Buchtipp, aber die Zeit habe ich einfach nicht mehr. in knapp 2 wochen ist abgabe und diese woche wollte ich das fertigstellen.

@ EikeB: Tja, soweit war ich auch schon..  Hab einen ganzen Abend und ne halbe Nacht drüber gebrütet und am Ende alles verworfen. Pair, 2Pair allgemein geht noch aber mit farben/wertabhängigen Flush, Straight etc wirds so kompliziert nachher, kA ob oder wie das geht. Selbst Master-Mathematikabsolventen haben dieses Problem nicht gelöst bekommen.

@ Michael: Das ist natürlich eine Möglichkeit. Kann gut sein, dass das Sinn macht, aber erstmal zu dieser Preflop DB kommen. Optimieren kann ich danach immer noch. Danke aber für die Idee, werde ich mal durchrechnen und rumprobieren. Es sind übrigens genau 1326 einträge.

Okay, dies wird ein langer Abend. Mal sehen wie ich mit JDBC klarkomme.. :/


----------



## Michael... (21. Jun 2010)

hatte was mit 13xx im Kopf, war mir aber nicht mehr sicher.
Die 1326 möglichen Starthandvarianten könnte man zur Not mal durchsimulieren, die paar Tage Aufwand sind ja nur einmalig ;-)
Berechnen kann man das bestimmt auch, aber da muss ich passen.


----------



## ice-breaker (21. Jun 2010)

agentone hat gesagt.:


> Ich glaube nicht, dass du dir 133 Mio. Möglichkeiten in einer Datenbank speichern willst.
> Selbst wenn du pro Datensatz nur 1 Byte speicherst, ist die Datenbank ca. 130 MegaByte groß!



nicht nur der Speicherplatz, das Abfragen der Daten aus der Datenbank könnte auch Ewigkeiten dauern.


----------



## ChopstickZ (22. Jun 2010)

Update: Hab mit dem Projektleiter gesprochen, wir dürfen gar keine externe DB nutzen. Das mit der Dauer der Abfrage kann gut sein. xD
Ich arbeite momentan mit txt Dateien, die ich dann mehr oder weniger parse. 4,2 GB für die komplette Liste (133 Mio x 7 karten und WinType), wenn alle Werte als Zahlen geschrieben werden.  Naja, ein Glück kommt das nicht mit ins Release... Damit habe ich auch nicht gerechnet.

Hab auch schon die Vorberechnung geschrieben für die Starthände. Scheint zu funzen.

@Michael: Dein Vorschlag scheint übrigens unentbehrlich. Hab mich voll und ganz drauf konzentriert nur die Starthände vorzuberechnen (auch wenn sich gerade da am wenigsten tut was Prozente angeht). Die Datei ist am Ende höchstens ein paar 100 kB groß.
Eine Flop Tabelle wäre schätzungsweise mindestens 200MB groß.

Also danke nochmal, wirklich hilfreich.


----------



## ARadauer (22. Jun 2010)

Ok, ich schalte mich hier mal ein... ich hab sowas schon mal gemacht... ich hab aber jede Hand simuliert...
Was ich simuliert habe waren die Gewinnwahrscheinlichkeiten von zwei oder mehreren Händen... also die Prozent Werte die man bei den Händen im Fernsehen immer sieht....

Ich hatte mal eine Quelle wie mans errechnet aber das war mir zu komplex... 

Das hab ich bentutz um die Hand zu evaluieren http://spaz.ca/poker/UofAHandEval.zip und hier gibts die Doku dazu Generated Documentation (Untitled)

Hände und Community Cards vorbereiten... 
   10000 mal -> restliche Karten austeilen -> wer hat gewonnen 

ist an die errechneten Werte von Rechnern im Internet auf die 0,1 - 0,5 % ran gekommen... gutes Ergebnis finde ich... und war so ca unter 2 Sekunden fertig...

Also ist das eine Möglichkeit? 138 Mio Datensätze in einer MySql oder in Textdatein zu halten, finde ich nicht sehr gut... und wenn mans nicht errechnen kann, würde ich es einfach simulieren...


----------



## dev-eth0 (22. Jun 2010)

ice-breaker hat gesagt.:


> nicht nur der Speicherplatz, das Abfragen der Daten aus der Datenbank könnte auch Ewigkeiten dauern.



Naja, dank Caching in der Datenbank sollte das kein Problem sein...


----------



## ChopstickZ (22. Jun 2010)

Aber die Werte im TV sind doch aus allen sichtbaren Karten aller Spieler errechnet oder? Das wäre ja Cheating, da man nur seine eigenen Karten sehen soll und die Werte auch nur aus den eigenen Karten errechnet werden.


----------



## ARadauer (22. Jun 2010)

ChopstickZ hat gesagt.:


> Aber die Werte im TV sind doch aus allen sichtbaren Karten aller Spieler errechnet oder? Das wäre ja Cheating, da man nur seine eigenen Karten sehen soll und die Werte auch nur aus den eigenen Karten errechnet werden.



naja ob du jetzt simulierst wie oft du gegen eine andere Hand gewinnst  oder wie oft du welche Hand triffst ist ja egal.. vom prinzip her ists ja das selbe...


----------

