Pokerhände/kombinationen erkennen?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Donnerstag 24. April 2008, 16:05

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.
ivka_sto
User
Beiträge: 63
Registriert: Dienstag 11. Dezember 2007, 23:13

Donnerstag 24. April 2008, 16:32

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
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Donnerstag 24. April 2008, 16:40

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)
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Donnerstag 24. April 2008, 17:23

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.
maxip
User
Beiträge: 61
Registriert: Dienstag 11. März 2008, 09:43

Freitag 25. April 2008, 14:17

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)
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Freitag 25. April 2008, 17:02

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.
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Freitag 25. April 2008, 20:33

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)
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Samstag 26. April 2008, 11:14

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.
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Samstag 26. April 2008, 16:56

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
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Samstag 26. April 2008, 17:34

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.
Antworten