Seite 1 von 1

Poker game ohne Grafik

Verfasst: Samstag 24. Januar 2009, 16:07
von INFACT
Liebes Python Forum,
Auf euer Raten habe ich ein kleineres Projekt anfgefangen und habe mich für ein Texas Holdem Poker-spiel mit 2 Gegnern entschieden.
Ich muss noch sehr an den Feinheiten arbeiten, weil es unteranderem noch auf Random läuft, dass die Gegner raisen, aufgeben oder checken.
Aber mein eigentliches Problem ist, dass wenn nicht beide anderen Spieler aufgegeben haben, ich das Geld, was ich gewettet habe sofort verliere, ohne dass kontrolliert wird, wer die besseren Karten hat:

http://paste.pocoo.org/show/101128/

Ich will erstmal klein anfangen mit High Card und 1Paar. Hier hab ich auch die Berechnungen:

http://paste.pocoo.org/show/101129/
(Das gehört noch dazu:

Code: Alles auswählen

WETTRUNDE=preflop+river+turn
def countele(what,dict):
    zahl=0
    for keys,values in dict:
        if keys==what:
            zahl+=1
        if values==what:
            zahl+=1
    return zahl
)
Bei High fehlt mir noch, welche Karte höher ist und insgesamt will ich wissen, wie ich das hinbekommen kann, dass für jeden Spieler, sofern mindestens 2 da sind, das durgeführt wird und wenn der eine High habt und der andere 1Paar, der mit 1.Paar gewinnt und wenn der eine ein High As hat und der andere einen High König, der mit dem As gewinnt.
Kann mir jemand helfen? :roll: :oops:
Vielen Dank ich freue mich auf Antworten! :lol:

Verfasst: Samstag 24. Januar 2009, 17:19
von DasIch
dict.__iter__ yielded nur Keys. Die gezeigte Funktion kann in Zeile 4 also schon nur noch scheitern es sei den dass ist gar kein dict, dann ist allerdings die Benennung überhaupt nicht gebrauchen.

Halte dich an PEP 8 wenn du willst dass jemand sich ernsthaft deinen Code ansieht oder mit dir arbeitet.
Flat is better than nested.
oder kurz ausgedrückt deine Datenstruktur ist nicht zu gebrauchen. Zumindest für Player wäre es schon sinnvoll eine Klasse einzuführen.

Das du eine high Funktion brauchst zeigt imho dass schon irgendwas schief geht. Karten könnten auch einfach Konstanten sein die man mit < oder > vergleichen kann.

Verfasst: Samstag 24. Januar 2009, 20:34
von HerrHagen
Ich muss DasIch leider Recht geben. Es macht wenig Sinn sich mit deinem Spiel im jetzigen Stand auseinander zu setzen. Deine Datenstrukturen und die Strukturierung des Codes sind einfach nicht sehr sinnvoll. Bevor du den kompletten Spielalauf schreibst, würd ich erstmal versuchen ein ordentliches Grundgerüst zu erstellen, auf dem du aufbauen kannst.

Du könntest erstmal folgendes machen:
Mach dir Klassen für die Karten, so das eine Karte ein Objekt ist. Das könnte in etwa so aussehen (war mal aus nem Black Jack Spiel, deswegen passen die Werte der Karten nicht):

Code: Alles auswählen

values = {'2':2, '3':3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9, '10':10,
          'J':10, 'K':10, 'Q':10, 'A':11}
suits = ('spades', 'hearts', 'diamonds', 'clubs')

class card:
    def __init__(self, suit, face):
        if suit not in suits:
            raise ValueError, "suit must be one of %s" % suits
        if face not in values.keys():
            raise ValueError, "value must be one %s" % values

        self.suit = suit
        self.face = face
        self.value = values[face]

# komplettes Deck erzeugen
deck = [] 
for suit in suits:
    deck += [card(suit, face) for face in values.keys()]

# mischen
random.shuffle(deck)
In der Klasse solltest du dann noch entsprechende Methoden wie __cmp__ definieren um die Karten mit Operatoren wie <,>,== vergleichbar zu machen.
Dann seh ich als wesentliches Element des Spiels die Frage: wer hat die besseren Karten? (Vgl. 5 gegen 5 Karten)
Du musst also dann Funktionen schreiben wie:
- Straße?
- Vierling?
- Drilling?
usw.
Du kannst das recht einfach umsetzen indem du die Karten auf der Hand des Spielers erst sortierst (dafür brauchst du die __cmp__ Funktion) und dann nach einem Muster suchst (dreimal hintereinander gleicher Wert -> Drilling).
Wenn diese Funktionen hast, kannst du auch leicht ne KI schreiben. Eine sehr einfache Variante wäre, sich 100 zufällige Blätter zu erzeugen, gegen die man dann virtuell spielt. Die Anzahl der gewonnenen Spiele entspräche in etwa der Stärke des Blattes.

MFG HerrHagen

Verfasst: Samstag 24. Januar 2009, 20:53
von DasIch
@HerrHagen Auch hier wieder PEP 8 ;) Statt card ist Card zu bevorzugen.

Außerdem wäre da noch die Sache mit den New Style Classes, solange man nicht Python 3 benutzt sollte man von object erben.

Desweiten sind rich comparision methods laut Doku "in preference to __cmp__".

Statt diese ganzen Funktionen für die Kartenkombinationen zu implementieren könnte man auch eine Klasse benutzen.

Verfasst: Samstag 24. Januar 2009, 21:22
von HerrHagen
Desweiten sind rich comparision methods laut Doku "in preference to __cmp__".
Dort steht das die rich-comparison-Methoden aufgerufen werden, wenn sowohl diese als auch __cmp__ definiert sind (called in preference = in Vorzug aufgerufen).
Ich empfehle dir an deinen Englisch-Kenntnissen zu feilen bevor du solche Kommentare gibst.
Auserdem was solls bringen? Bei __cmp__ kannst du jeden Wert (Ass, Zehn,..) ne Reihenfolge zuweisen und kannst diese mit dem builtin cmp vergleichen und das Ergebnis zurückgeben. Bei den rich comparisons musst du jede Funktion einzeln definieren.
Statt diese ganzen Funktionen für die Kartenkombinationen zu implementieren könnte man auch eine Klasse benutzen.
Wie soll das ohne den entsprechenden Funktionsaufruf der von mir vorgeschlagenen Methoden denn bitte gehen? Ich versteh nicht worauf du hinaus willst. Ein Beispiel bitte. Klar kann die Kombination dann auch wieder in Klassen packen (um die dan mit __cmp__ zu vergleichen :wink: ), dass hab ich aber auch nie abgestritten.

Verfasst: Samstag 24. Januar 2009, 21:32
von DasIch
HerrHagen hat geschrieben:Auserdem was solls bringen? Bei __cmp__ kannst du jeden Wert (Ass, Zehn,..) ne Reihenfolge zuweisen und kannst diese mit dem builtin cmp vergleichen und das Ergebnis zurückgeben. Bei den rich comparisons musst du jede Funktion einzeln definieren.
Ich finde es schöner die Funktionen für jeden Vergleichstyp zu definieren statt den Code für jeden Vergleichstyp in einer Funktion zu packen aber dass ist Ansichtssache.
Klar kann die Kombination dann auch wieder in Klassen packen (um die dan mit __cmp__ zu vergleichen :wink: ), dass hab ich aber auch nie abgestritten.
Das ist was ich gemeint habe und zumindest die Formulierung hat sich nicht so angehört als ob du die Variante mit einer Klasse in Erwägung gezogen hättest, sondern eher als ob du dort den gleichen Ansatz wie INFACT beschreiten wolltest.

Verfasst: Samstag 24. Januar 2009, 22:07
von Birne94
http://paste.pocoo.org/show/101204/

Ich hab auch mal nen paar Klassen dazu geschrieben. Was sagt ihr dazu??

Verfasst: Samstag 24. Januar 2009, 22:15
von Nocta
Birne94 hat geschrieben:http://paste.pocoo.org/show/101204/

Ich hab auch mal nen paar Klassen dazu geschrieben. Was sagt ihr dazu??
Dazu frage ich mich, warum du für jede Karte eine Klasse erstellst?
Die haben doch alle dieselben Eigenschaften, außer denen, die eh schon abstrahiert sind (Farbe, Rang). Das ist imho völlig sinnlos.
Eine Karten-Klasse und eine Kartenpaket-Klasse (also Stapel und Spielerhand zb) würden wohl reichen.

Edit: Außerdem machen die Klassen eh nichts anderes als den Konstruktor aufzurufen, weshalb sie überflüssig sind.
2. Stell dir mal vor, wenn dich jemand fragt: Nach welchem realem Vorbild hast du die Karten modelliert?
Ein Königs-Objekt ist meiner Meinung nach weniger sinnvoll als ein Karten-objekt, welches die Eigenschaften hat, ein König zu sein und zB die Farbe Pik zu haben.
Genauso könnte man sich auch fragen, wieso die Karten dann keine Pik-Objekte sondern Königs-Objekte sind, obwohl sie doch die Farbe Pik haben ;)

Verfasst: Samstag 24. Januar 2009, 22:19
von INFACT
Vielen Dank, genauso mach' ich's! :mrgreen:
Ich glaube, jetzt komme ich allein zurecht.
Wenn ich fertig bin, werde ich es mal bei den Codesnippets posten :idea:
DANKE!

Verfasst: Samstag 24. Januar 2009, 22:38
von BlackJack
Die "rich comparison"-Methoden sind leider auch zu bevorzugen wenn man "zukunftssicher" bleiben möchte, da `__cmp__()` in Python 3.0 wegfällt. Find' ich persönlich ziemlich blöd, weil ich schon sehr oft `__cmp__()` implementiert habe, aber noch *nie* "rich comparison" benötigt habe, das also in meinen Augen in 99,9% der Fälle nur unnötige Mehrarbeit bedeutet.