Archiv verlassen und diese Seite im Standarddesign anzeigen : Poker-Algorithmus
ich habe das wochende mit einem eingeklemmten nerv verbrigen müssen, und hab vor lauter langeweile ein pokerspiel in javascript angefangen, wo ein spieler gegen "den computer" antritt. jetzt stehe ich vor folgendem problem.
"der computer" zieht fünf karten und muss nun auswählen, welche er davon behalten will. leider habe ich absolut keinen plan wie ich das mache, ohne mit zigtausend schleifen zu arbeiten. gibt es da irgendeine matrix, mit der man eine kleine ki aufbauen kann?
im moment werkel ich hier mit einem literal-objekt herum, das ungefär so aufgebaut ist.
var poker =
{
...
cards :
{
'karo' :
{
0: '2', 1: '3', 2: '4', 3: '5', 4: '6', 5: '7', 6: '8', 7: '9', 8: '10', 9: 'b', 10: 'd', 11: 'k', 12: 'a'
},
'herz' :
{
0: '2', 1: '3', 2: '4', 3: '5', 4: '6', 5: '7', 6: '8', 7: '9', 8: '10', 9: 'b', 10: 'd', 11: 'k', 12: 'a'
},
'pik' :
{
0: '2', 1: '3', 2: '4', 3: '5', 4: '6', 5: '7', 6: '8', 7: '9', 8: '10', 9: 'b', 10: 'd', 11: 'k', 12: 'a'
},
'kreuz' :
{
0: '2', 1: '3', 2: '4', 3: '5', 4: '6', 5: '7', 6: '8', 7: '9', 8: '10', 9: 'b', 10: 'd', 11: 'k', 12: 'a'
}
},
level :
{
0: 'karo', 1: 'herz', 2: 'pik', 3: 'kreuz'
},
rank :
{
0: '2', 1: '3', 2: '4', 3: '5', 4: '6', 5: '7', 6: '8', 7: '9', 8: '10', 9: 'b', 10: 'd', 11: 'k', 12: 'a'
},
...
}
peter
Ist nicht schwer :D ... Also du musst einfach auf mögliche Kombinationen testen, d.h. folgende Test musst durchgeführt werden:
- pair
- two pairs
- three of a kind
- straight
- flush
- fullhouse
- four of a kind
- straight flush
- royal flush
Teste von unten nach oben dann weisst du was der Computer hat, anschliessend kannst du entscheiden, was getauscht werden muss.
Die Tests kannst du in einzelne Function unterbringen und geschickt kombinieren, z.B. Fullhouse = 3 of a kind + pair, etc.
Ist nicht schwer :D ...
hab ich anfangs auch gedacht.
Also du musst einfach auf mögliche Kombinationen testen, d.h. folgende Test musst durchgeführt werden:
...
Teste von unten nach oben dann weisst du was der Computer hat, anschliessend kannst du entscheiden, was getauscht werden muss.
Die Tests kannst du in einzelne Function unterbringen und geschickt kombinieren, z.B. Fullhouse = 3 of a kind + pair, etc.
das ist mir auch schon klar. mir geht es nur um das wie. bisher wusel ich mich mit zig schleifen durch die karten. aber das muss doch besser zu lösen sein. gibt es hier keinen mathematiker?
peter
Blackgreetz 10-05-2009, 19:59 so einfach ist das normale poker ansich nicht.
Es kann ja auch sein, dass du kein paar hast, aber 3x Herz und zwar 4 6 7 ... ...dann tauschst du ansich nur die anderen beiden, in einer gewissen Hoffnung.
Gleiches bei Highcards.
mfg
so einfach ist das normale poker ansich nicht.
Es kann ja auch sein, dass du kein paar hast, aber 3x Herz und zwar 4 6 7 ... ...dann tauschst du ansich nur die anderen beiden, in einer gewissen Hoffnung.
Gleiches bei Highcards.
mfg
weiß ich alles. aber wie kann ich das in einen algorithmus mit einer entsprechenden matrix packen? das ist mein problem. ich will einfach nicht mit zig funktionen und schleifen arbeiten. der code soll so einfach wie möglich sein. und da hapert es bei mir.
peter
ps. vielleicht rede ich auch blödsinn, bin im moment ziemlich vollgepumpt mit schmerztabletten
onemorenerd 10-05-2009, 21:21 Ich kenne die Poker-Regeln leider nicht. Hab kurz bei Wikipedia geschaut und jetzt weiß ich zumindest, dass du dir da einen harten Brocken vorgenommen hast. :)
Pokern ist anscheinend nur sehr schwer algorithmisch umzusetzen, da man das Blatt des Gegners nicht kennt. Man weiß eigentlich nur, welche Karten er auf keinen Fall haben kann, nämlich die eigenen. Die Güte Blattes des Gegners muss man anhand seines Setzverhaltens abschätzen. Diese psychologische Komponente ist nicht berechenbar. Da muss man heuristisch rangehen.
Du willst jetzt erstmal die absolute* Güte deines eigenen Blattes ermitteln. Wie gesagt kenne ich die Regeln nicht. Aber es gibt knapp 2,6 Mio. Hände (52 über 5). Man kann die nicht alle vorab bewerten und speichern. Vor allem nicht in JS. ;)
Deshalb war mein erster Gedanke "Graph"! Ein vollständiger Graph, jede Karte als Knoten vertreten, gewichtete Kanten ...
Wäre das eine Möglichkeit? Ich weiß halt nicht, ob man überhaupt Kantengewichte bestimmen kann und wie viele Pfadschritte durchschnittlich zu berechnen wären.
Ich habe etwa folgendes im Kopf:
Finde eine Karte aus deiner Hand im Graphen.
Bilde jeden möglichen 5er-Pfad ausgehend von diesem Knoten. Damit das halbwegs performant geht, würde ich die Pfade sukzessiv verlängern und in jedem Schritt schauen, ob ich den neuen Knoten als Karte auf der Hand habe. Ausgehend davon und dem Gewicht der Kante wird die Güte des Pfades angepasst. Unterhalb einer bestimmten Güte wird ein Pfad nicht weiter verfolgt.
Wenn die Regeln das hergeben, muss man deutlich weniger als die 2,6 Mio. möglichen Pfade berechnen. Durch geschickte Auswahl des Startknotens lässt sich eventuell auch noch was einsparen.
Let me google that for you (http://lmgtfy.com/?q=javascript+poker+game) :D
ps. vielleicht rede ich auch blödsinn, bin im moment ziemlich vollgepumpt mit schmerztabletten
Wir wissen alle schon, dass du drogen abhängig bist :p
Man weiß eigentlich nur, welche Karten er auf keinen Fall haben kann, nämlich die eigenen. Die Güte Blattes des Gegners muss man anhand seines Setzverhaltens abschätzen. Diese psychologische Komponente ist nicht berechenbar. Da muss man heuristisch rangehen.
ach so toll soll das garnicht werden. der "computer" muss nur sein eigenes blatt beurteilen.
Let me google that for you (http://lmgtfy.com/?q=javascript+poker+game) :D
Wir wissen alle schon, dass du drogen abhängig bist :p
1. danke für den hinweis, schau ich mir morgen mal an
2. komm du mir noch mal zwischen die finger :D
peter
Blackgreetz 10-05-2009, 23:56 Meine erste Antwort war auch an asp2php gerichtet siehe "so einfach ist das nicht".
Du könntest ansonsten auch ein Punktesystem machen. >10 bekommt dann 3 punkte, unter 10 1 .. zusammenhängende +2 .. welche mit nur 1 karte dazwischen +1 usw. (farben.,..,..)
Und dann kannst du gucken, welche Kartenkombi die am meisten Punkte hat, die anderen tauschst du. Überprüfen kann man das Ganze aber mit Wenigen schleifen, die einfach immer nur eine karte zu einer anderen hinzunimmt etc und dann die Punkte dafür ausrechnet. Die höchste Kombi gewinnt und der Rest fliegt.
Bin mir nun nicht sicher, ob das System so funktioniert, aber viel mir gerade ein^^
mfg
Nennt sich hutchinson und gibt es somit schon. Hat aber wie jedes System seine Macken -man kann erfolgreiches Pokerspiel eben kaum berechnen.
Blackgreetz 11-05-2009, 03:18 Nennt sich hutchinson und gibt es somit schon.
Danke. Wusste zwar, dass ich öfter mal von dem Prinzip gelesen habe, aber kannte keinen Namen.
Ich denke, dass diese Methode da doch nen guter Ansatz für ist.
eintrachtemil 11-05-2009, 10:41 Hier gibt es noch ein paar Wahrscheinlichkeiten, die dir eventuell bei Kartenbewertungen helfen könnten: Texas Hold'em Poker Statistiken Startblätter Flops Wahrscheinlichkeit holdem-poker.ch (http://www.holdem-poker.ch/texas_holdem_karten_statistik.htm)
eintrachtemil 11-05-2009, 10:44 Hier noch eine Poker-Engine in PHP: PHP Poker Engine - Official Website (http://www.phppokerengine.com/)
Vielleicht kannst du da was rausziehen.
danke euch allen. hätte ich geahnt, wie aufwendig das ist, hätte ich es bleiben lassen. sch***ß langeweile
peter
Ach komm schon. Die 5 Karten durchzulaufen ist doch nichts ... 5 von 52 Karten sind doch bloß nur 2.598.296 Kombinationen ... streng dich an :D
Ach komm schon. Die 5 Karten durchzulaufen ist doch nichts ... 5 von 52 Karten sind doch bloß nur 2.598.296 Kombinationen ... streng dich an :D
ja, ja. unser dipl. mathematiker sagte, ich soll eine selbstlernende engine programmieren. HALLO? gehts euch gut? ich habe auch noch ein leben. :)
peter
[ot]Naja, wenn du das Fußballspielen endlich an den Nagel hängen würdest hättest du Zeit. Und gesünder wäre es auch... :)
Hallo Peter.
Wie ich die Aufgabe verstanden habe, geht es darum, zu ermitteln, welche Karten das Programm behalten und welche es ablegen soll.
Dann würde ich mich auch genau darum kümmern. Dann spielen nähmlich erstmal die anderen Karten keine Rolle.
Ich würde ein Array mit den einzelnen Treffern aufbauen und die erhaltenen Karten der Programms damit abgleichen.
Im Array sind also alle Treffer enthalten, also auch alle gültigen Kombinationen einer Straße oder eines Full House usw.
Die gültigen Kombinationen kann ja ein Programm erstellen und das Array füllen.
Das Array soll aufsteigend der Wertigkeiten der Pokerregeln sortiert sein.
Dann wird ein Vergleich der Hand mit dem Array durchgeführt.
Die höchste Wertigkeit wird ermittelt und behalten, der Rest abgelegt.
Wenn kein Treffer( ab Paarung/ Ass kann auch ein Treffer sein oder auch jedes als sinnvoll erscheinende unvollständige Ausgangsblatt) vorhanden, soll die Überprüfung nicht auf 100%ige Übereinstimmung, sondern auf -1 Karte geprüft werden.
Der höchste key wird ausgewählt, die Karten, die nicht beteiligt sind, werden abgelegt.
Wenn immer noch kein Treffer, nochmal auf -2/-3 Karten prüfen.
Wenn immer noch kein Treffer und ein Spieler setzt x/Pott = passen.
Damit sollte die Anforderung erfüllt sein.
Die Wahrscheinlichkeiten kommen ins Spiel, wenn es darum geht, das aktuelle Blatt ins Verhältnis zum Pott, zur Anzahl der Mittspieler und zum aktuellen Setzen eines Mitspielers zu setzen.
Gruß
Estrela
ich habs schon fertig. trotzdem danke
peter
Gerne.
Aber das führt mich zur folgenden Frage:
Gibt es die Funktion, Beiträge als erledigt zu kennzeichnen?
Wenn nicht, sei dies ein Verbesserungsvorschlag.
Was mich zum Thema Poker interessieren würde ist die Frage der Wahrscheinlichkeiten.
Sagen wir mal, wir spielen Online Poker und haben nebenbei ein Programm laufen, das die Wahrscheinlichkeiten meines Blattes auf Gewinn berechnet bzw wie hoch die Wahrscheinlichkeit zum erhalten einer bestimmten Karte ist bzw wie hoch die Wahrscheinlichkeit ist, das Mitspieler höhere Blätter haben wie wir.
Das währe ein nützliches Tool für Pokerspieler.
Gruß
Estrela
welche form von poker meinst du. dieses deppige texas hold 'em? oder die einzig vernünftige variante five card draw? btw. das war für ein tutorial über literal-objekte gedacht. mehr nicht :)
peter
Am besten währe ein solches Tool, das die verschiedenen Pakervarianten berechnen kann.
Aber da es ja nur für ein Tutorial gedacht war...
Gruß
Estrela
Am besten währe ein solches Tool, das die verschiedenen Pakervarianten berechnen kann.
ich stelle dir gerne meinen code zur verfügung, dann kannst du das ja machen :)
peter
Tut mir leid, meine Stärken sind eher im konzeptionellen Bereich.
Das Konkrete bzg. php lerne ich gerade.
Dank für die Hilfe
und Gruß
Estrela
Das Problem an Poker ist, dass ein normaler Server viiiiel zu wenig Leistung dafür hat. Ansonsten wäre es ziemlich einfach ein von der Wahrscheinlichkeit her gesehen perfektes Pokerspiel zu erstellen.
Estrela, dein Vorschlag mit einer Datenbank ist eine einfache Variante, aber hast du bereits einmal die Anzahl Möglichkeiten berechnet? Selbst bei einem Bitfeld brauchst du noch mindestens 8 Byte pro Möglichkeit und das ist für heutige PCs immer noch viiiel zu viel.
Hallo jmc.
Ich weiß jetzt nicht, ob du mich richtig verstanden hast.
Mein Vorschlag ging dahin, ein gewissermaßen holographisches Abbild aller möglichen sinnvollen Hände einmalig von einem Programm zusammenstellen zu lassen und dieses in einer Datei oder auch in einer Datenbank abzuspeichern.
Zur Laufzeit des Scriptes braucht dann nur noch verglichen zu werden, mit welcher gespeicherten Hand die aktuelle am besten übereinstimmt und die zur Übereinstimmung nicht benötigten Karten einfach ablegt.
Das wird doch nicht so eine hohe Auslastung des Arbeitsspeichers benötigen.
Gruß
Estrela
onemorenerd 05-06-2009, 12:01 Jmc hat ziemlich übertrieben. ;)
Es gibt 1.302.540 sinnvolle Hände à 5 Karten. Bei 52 Karten braucht man nur 6 Bit pro Karte (fixed width alignment). Das "Hologramm" benötigt im Idealfall nur 7.815.240 Bit bzw. rund 950 KB. Wenn man wie bei PHP für jeden Wert gleich 32 Bit ver(sch)wendet und nicht gezielt in den Speicher greifen kann, sondern Datenstrukturen wie Arrays nutzen muss, braucht das "Hologramm" schon über 10 MB. Das ist zwar deutlich mehr, aber für "heutige PCs" kein Problem.
Dein "Hologramm" ist übrigens der Idee mit dem Graphen sehr ähnlich.
Also erstmals muss ich zugeben, dass ich nicht alles durchgelesen habe...
Ich dachte es gehe um die Wahrscheinlichkeitsrechnung beim Pokern also um eine von der Wahrscheinlichkeit her gesehen perfekte AI. Und das ist für Texas Holdem nicht möglich.
Die Möglichkeit ein "Hologramm" zu erstellen bezweifle ich jedoch nicht deine Rechnung hingegen ist jedoch meiner Meinung nach etwas falsch.
Mit 6 bit kannst du zwar eine ein Bitfeld für eine Karte erstellen, aber nicht für eine Hand.
Pro Hand brauchst du für das Bitfeld mindestens 52 bits.
Man käme mit einem numerischen Feld zwar sogar bereits mit 20 bits aus, 30 für eines mit geteilten sektoren, aber dabei ist nr 1 extrem langsam und nummer 2 auch immer noch sehr langsam. Dann wäre sogar ein zweidimensionales Array noch schneller. Aber insbesonder bei 64bit Maschinen, aber auch bei 32Bit zeigt sich der Nachteil des Arrays gegenüber dem Bitfeld, welches zwischen den einzelnen Karten nicht nach impliziten Sprüngen verlangt.
onemorenerd 06-06-2009, 10:13 Mit 6 bit kannst du zwar eine ein Bitfeld für eine Karte erstellen, aber nicht für eine Hand.
Hab ich auch nicht behauptet. Gemeint war 2^5 = 32 < 52 < 64 = 2^6.
Pro Hand brauchst du für das Bitfeld mindestens 52 bits.
Man käme mit einem numerischen Feld zwar sogar bereits mit 20 bits aus, 30 für eines mit geteilten sektoren ...
Was redest du denn da? Eine Hand sind 5 Karten. 5 mal 6 Bit sind 30 Bit, nicht 52 oder 20!
Mit geteilten Sektoren meinst du wahrscheinlich das selbe wie ich mit fixed width alignment.
Hab ich auch nicht behauptet. Gemeint war 2^5 = 32 < 52 < 64 = 2^6.Das hab ich mir auch gedacht, aber dann hast du kein Bitfeld der Karten und es wird wie gesagt um einiges langsamer sein.
Beim Bitfeld hättest du für jede Kart genau ein Bit zur Verfügung also mindestens 52. Das bewirkt, dass eine Menge weniger Sprünge nötig sind und ausserdem wirst du weniger Male auf den RAM zugreifen müssen und weniger Prozessorfunktionen benötigen.
Und sry du hast recht, ich habe einen Rechnungsfehler gemacht bei 20 bits, es sind 22: 2^21 < (52!/(5!*47!)) < 2^22. Das wäre ein Extrem der numerischen Feldes, welches noch einiges mehr an Rechenaufwand benötigen würde.
|
-
- |