Seite 1 von 1

Pokerhände/kombinationen erkennen?

Verfasst: Donnerstag 24. April 2008, 16:05
von Karl
Hallo.
Ich bin gerade dabei ein Pokerprogramm zu schreiben und das beinhaltet natürlich unweigerlich die Aufgabe, eine Funktion/Klasse, was auch immer zu schreiben, die die Pokerhände auswertet. Full House, Straight Flush, ... usw.
Naja meine Frage: Wie würdet ihr das machen, bzw wenn ihr's schonmal gemacht habt, wie habt ihr's gemacht?
Also ich würde natürlich erstmal die Karten nach dem Rang sortieren (und einmal nach der Farbe wegen Flush) und dann für jede mögliche Kombination eine Funktion erstellen, die über if's und Schleifen überprüft, ob die Karten eine bestimmte Kombination überprüfen ...

Aber es gibt doch bestimmt noch Möglichkeiten die nicht so ... nunja, nervig sind :p Vielleicht auch etwas eleganter ...
Ich erwarte keinen fertigen Code sondern nur ein paar Ideen oder notfalls auch ein: Mach's so, wie du's gesagt hast.

Verfasst: Donnerstag 24. April 2008, 16:32
von ivka_sto
Also ich würde die ersten 2 Karten der aktuellen Hand vergleichen, und anhand dessen bestimmen, ob es sich überhaupt noch lohnt weiter zu überprüfen, bzw. welche Kombinationen, die was wert sind, noch in Frage kommen (z. B., wenn die ersten 2 Karten Dame Karo und 6 Herz sind, dann entfallen schonmal die Möglichkeiten, daß ein Flush und/oder ein Straight dabei sind) Wenn ich richtig verstanden habe was du meinst :)

VG

Verfasst: Donnerstag 24. April 2008, 16:40
von Karl
ivka_sto hat geschrieben:Also ich würde die ersten 2 Karten der aktuellen Hand vergleichen, und anhand dessen bestimmen, ob es sich überhaupt noch lohnt weiter zu überprüfen, bzw. welche Kombinationen, die was wert sind, noch in Frage kommen (z. B., wenn die ersten 2 Karten Dame Karo und 6 Herz sind, dann entfallen schonmal die Möglichkeiten, daß ein Flush und/oder ein Straight dabei sind) Wenn ich richtig verstanden habe was du meinst :)

VG
Prinzipiell richtig, nur:
1. hat das ja an sich nicht's mit der Problemstellung zu tun, weil ich ja danach gefragt hab, wie ich die Hände am besten überprüfe. Deine Ergänzung nimmt mir die Überprüfung einiger Kombinationen zwar in manchen Fällen ab, aber implementieren muss ich sie trotzdem, da sie durchaus ab und zu mal vorkommen :p
2. Was du nicht wissen konntest, sind's eigentlich 7 Karten, da es sich um Texas Hold 'Em handelt -> 2 Karten auf der Hand, die frei kombinierbar mit den 5 in der Mitte sind (aber trotzdem kann man nur aus 5 Karten eine Kombination bilden)

Verfasst: Donnerstag 24. April 2008, 17:23
von Y0Gi
Eine einfache Möglichkeit besteht darin, alle Kombinationen von Händen als Sets vorzuberechnen. Nimmt man dafür `frozenset()`s, die immutable sind, könnte man die möglichen Hände als Dictionarykeys benutzen und die Klassen (Flush, Straight, Zwei Paare usw.) als Werte zuweisen. Schlauer wäre evtl., das umgekehrt zu machen: Händeklassen als Schlüssel und die möglichen Kombinationen dafür als dessen Werte.
Während des Spiels dann die sieben Karten des Spielers damit vergleichen bzw. darin suchen.

Verfasst: Freitag 25. April 2008, 14:17
von maxip
Hm,

ich wuerde von unten Anfangen, High Card machen, dann das hoechtse Pair bauen, dann 2 Pair, dann drilling, d.h. ich wuerde versuchen, mit diesen 7 Karten von unten nach oben alle Kombinationen versuchen zu bauen, die letzte Kombi ist dann die hoechste

Is zumindest die Moeglichgkeit, die mir am einfachsten erscheint, vielleicht hat ja jmd. ne andere idee


Ich wurd halt die Karten als Objekte machen, mit vergleichsfunktionen usw, damit du so sachen hast wie karte1 < kart2 bzw. sogar karte1.istVorgaengerVon(Karte2) oder karte1.hatGleicheFarbe(karte2)

Verfasst: Freitag 25. April 2008, 17:02
von Karl
maxip hat geschrieben:Hm,

ich wuerde von unten Anfangen, High Card machen, dann das hoechtse Pair bauen, dann 2 Pair, dann drilling, d.h. ich wuerde versuchen, mit diesen 7 Karten von unten nach oben alle Kombinationen versuchen zu bauen, die letzte Kombi ist dann die hoechste

Is zumindest die Moeglichgkeit, die mir am einfachsten erscheint, vielleicht hat ja jmd. ne andere idee


Ich wurd halt die Karten als Objekte machen, mit vergleichsfunktionen usw, damit du so sachen hast wie karte1 < kart2 bzw. sogar karte1.istVorgaengerVon(Karte2) oder karte1.hatGleicheFarbe(karte2)
Ja, ich hab dafür extra die Klasse ``Card``, die das kann.
Ich weiß aber jetzt nicht genau, was du mit deinem "Lösungsvorschlag" meinst.
Ich würde erst versuchen die höchste Kombination zu bauen, da man von oben nach unten irgendwann sagen kann: Stopp, ... Von unten nach oben funtkioniert das allerdings nicht, wenn man ein Paar hat, kann man immer noch ein Full House haben. Oder sogar ein Royal Flush, da es 7 Karten sind.
Aber konkret mit meinem Problem hat das ja immer noch nichts zu tun, da es mir darum geht, _wie_ man am besten die Kombinationen überprüft, nicht, in welcher Reihenfolge oder sonstiges.
Also praktisch, wie eine Funktion ermittle_höchste_kombination() aufgebaut sein könnte. Natürlich würde ich das nicht alles in eine Funktion schreiben ;p
Yogi's Methode war, wenn ich das richtig verstanden habe, eine Liste (oder set, oder dict, oder sonstetwas) zu bauen, die bereits alle Kombinationen vorberechnet hat.
Aber das gefällt mir irgendwie nicht.
Dann hab ich ja allein für ein Full House schon 2 * 8 * 8 = 128 Einträge.
Aber einfach wär's schon ;)
Was ich richtig stylisch finden würde, wäre, wenn ich mir für jedes Blatt irgendwie sowas wie:
n, n+1, n+2, n+3, n+4 (n = Rang - Straight) oder (n, o), (n, o), (m, p), (m, p), (m, p) [also -> (rang, farbe) - Full House] notieren könnte und dann irgendwie nach diesem Muster suchen könnte, anstatt über massenhaft Schleifen abzufragen, ob die nächste Karte ins Schema für eine bestimmte Kombination passt.

Verfasst: Freitag 25. April 2008, 20:33
von keppla
Ich hoffe, ich treffe die Aufgabenstellung, ich werde wohl etwas abschweifen.
Möglichkeit besteht darin, alle Kombinationen von Händen als Sets vorzuberechnen
hatte ich mir auch zuerst gedacht, aber dürfte ineffizient sein: 5 karten aus 52, ohne wiederholdung, ohne beachtung der reihenfolge sind, wenn ich mich nicht vertan habe, 2.598.960 Möglichkeiten. Das liegt zwar noch im berechenbaren bereich, aber mal so zum Spass:

Jeder Kartenkombination lässt sich eine rangfolge zuordnen. Einer Rangfolge lassen sich mehrere Kartenkombinationen zuordnen (split pot).

Man bräuchte also eine Funktion, die aus einer Hand die Rangfolge ermittelt, danach kann man die Rangfolgen der Spielerhände vergleichen, die beste Rangfolge gewinnt.

4 * Royal flush => 1
4 * Royal flush, highcard K => 2
4 * Royal flush, highcard Q => 3
...

Der Einfachheit halber kann man diese Rangfolge in ein Tupel (Kombination, Kriterium) aufteilen, python kann ja auch tupel vergleichen und wir wissen spätestens seit cantor dass die auch nur eine spezielle Darstellungsform von Zahlen sind ;)

Für Texas hold 'em kann man einfach annehmen, der Spieler hätte 10 Hände (2 verdeckt und 3 von 5 aus dem Pot)

Verfasst: Samstag 26. April 2008, 11:14
von Y0Gi
Klar, da kommt Einiges zusammen.

Ich kann mir jedoch vorstellen, dass man optimieren könnte, indem man separat auf (Royal) Flushs prüft und dann die Vorberechnungen ohne die Farben anlegt. Da dürfte schon ein gewaltiger Teil wegfallen. Wenn dann ein `Card`-Objekt (oder -Tupel) existiert, das aus Wert und Farbe besteht, kann man daraus leicht je ein separates Set für Werte und Farben erstellen.

Die Aufteilung in mehrere Hände zu je fünf Karten anstatt vorberechneten Händen mit sieben Karten ist sicherlich effizienter, ja.

Verfasst: Samstag 26. April 2008, 16:56
von Karl
Erstmal zu deinen Royal-Flushs, bevor ich's vergesse:
Ein Royal Flush ist eine Straight Flush, die sich dadurch auszeichnet, das Ass als Highcard zu haben. Also kann ein Royal Flush, das ja eigentlich eine Straight Flush ist, keine Highcard K haben ;p Oder hab ich da irgendwas falsch verstanden und du meintest was anderes?
Naja dann will ich nochmal kurz anmerken, dass meine Berechnung von 2* 8 * 8 als Anzahl von möglichen verschiedenen Full Houses auf den 2. Blick auch falsch ist. Aber keine Lust mir jetzt die korrekte Formel herzuleiten.

Also meine Idee war eigentlich gar nicht, die Hände irgendwie vorherzuberechnen, sondern wie ich gesagt habe, die Hände mittels Funktionen auf ein bestimmtes Muster hin zu überprüfen.
Aber so schlecht hört's sich eigentlich auch nicht an, einfach alles vorherzuberechnen ;)
Wenn man aber die 7 Karten der Reihenfolge nach sortieren würde, hätte man auch kein Problem mit den 10 Händen (wenn man jetzt nicht alles vorherberechnet, sondern meine Idee nimmt), weil man ja alles schön geordnet hat.
Dass man Flushs seperat prüft, ist mir auch schon in den Sinn gekommen.
Man prüft's einfach vorher oder nacher und fügt entweder ein Flush hinter den Namen (Bei Royal Flush und Straight Flush) oder, wenn das Flush höher als die anderen Kombinationen ist (zB wenn man ein Paar hat), dann nimmt man eben das Flush. So kann man die Farbe schön vom Rang trennen und hat sich einen erheblichen Aufwand gespart.
Was mir noch nicht ganz klar ist, ist, was keppla mit dem Tupel"(Kombination, Kriterium)" meinte.
Kriterium?
Sprecht ihr eigentlich nocht von der Methode, alle Kartenkombinationen vorherzuberechnen (bzw, wie wir gerade festgestellt haben, reicht es ja schon, wenn man nur den Rang vorherberechnet, das mit der Farbe kann man leicht noch als Zusatz einfügen), oder davon, die Hände der Spieler mit einer Funktion nach einem Muster zu überprüfen? Also praktisch die Regel für ein Straight Flush zu implementieren, nicht jede Kombination für ein Straight Flush.

Sorry für meinen unstrukturierten Beitrag .. Ich bin grad etwas komisch im Kopf :p

Verfasst: Samstag 26. April 2008, 17:34
von keppla
Karl hat geschrieben:Erstmal zu deinen Royal-Flushs, bevor ich's vergesse:
Ein Royal Flush ist eine Straight Flush, die sich dadurch auszeichnet, das Ass als Highcard zu haben. Also kann ein Royal Flush, das ja eigentlich eine Straight Flush ist, keine Highcard K haben ;p Oder hab ich da irgendwas falsch verstanden und du meintest was anderes?
ne, stimmt schon. Eigentlich meinte ich auch ab der zweiten Zeile keine Royal, sondern nur noch Straight fushs.
Also meine Idee war eigentlich gar nicht, die Hände irgendwie vorherzuberechnen, sondern wie ich gesagt habe, die Hände mittels Funktionen auf ein bestimmtes Muster hin zu überprüfen.
also eher sowas in die Richtung: Was kann aus dieser (noch nicht vollständig gezogenen Hand) noch werden?
Ich befürchte, ich kenne mich zu wenig mit Pokern aus, könntest du vielleicht deine Aufgabenstellung etwas präzisieren?
Was mir noch nicht ganz klar ist, ist, was keppla mit dem Tupel"(Kombination, Kriterium)" meinte.
Ich meinte, dass man, anstatt jede Hand im Voraus zu berechnen, und sie nach "Beste zuerst" zu sortieren, ein Verfahren entwickeln kann, was einem zu jeder beliebigen Hand in recht kurzer Zeit "52.-beste Hand" sagen kann.
Und, um das noch zu vereinfachen, kann man das ganze aufteilen in "Combination, Entscheidungskriterium", wobei das Entscheidungskriterium z.B. die Highcard beim Flush ist.