Frage zur Pokeraufgabe

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.
Nickl
User
Beiträge: 8
Registriert: Dienstag 27. Oktober 2009, 10:12

Die Aufgabe ist
1.Karten Spiel (Poker) erzeugen
2.Karten mischen
J3.e 5 Karten ausgeben an 2 oder mehr Spieler
Bis jetzt alles gelöst
nur die 4 Aufgabe war das man feststellen soll dass das Beste Blatt gewonnen hat

Die rangfolge ist siehe LINK

http://de.wikipedia.org/w/index.php?tit ... 0917215816

Code: Alles auswählen

import random
def Pokern():
    Farbe=["K","P","H","C"]
    Wert=["A","K","D","B","10","9","8","7","6","5","4","3","2"]
    Liste=[i+"-"+j for i in Farbe for j in Wert]
    print "Kartenspiel sortiert"
    print Liste
    print
    Anzahl=input("Bitte geben Sie die Anzahl der Spieler ein (<=10):")
    print
    for i in range(52):
        a=random.randint(0,51)
        b=random.randint(0,51)
        Liste[a],Liste[b]=Liste[b],Liste[a]
    print "Gemischte Karten"
    print Liste
    print
    e=51
    for i in range(Anzahl):
        Karten=[]
        for f in range(5):
            e=e-1
            a=random.randint(0,e)
            Karten=Karten+[Liste[a]]
            del Liste[a]
        Karten.sort()
        print "Spieler ",i+1,Karten



Bis jetzt haben wir ja alles bis zur 3. Aufgabe gelöst nur jetzt stehen wir vor dem Problem, dass wir nicht weiter wissen !!!!

Wir wollten eine Count funktion benutzen sind da aber auch nicht weiter gekommen
wir wären dankbar für eure Hilfe

Liebe Grüße

Edit (BlackJack): Quelltext in Code-Tags gesetzt.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Bitte benutze code tags, dann kann man das Programm auch lesen.
In specifications, Murphy's Law supersedes Ohm's.
Nickl
User
Beiträge: 8
Registriert: Dienstag 27. Oktober 2009, 10:12

pillmuncher hat geschrieben:Bitte benutze code tags, dann kann man das Programm auch lesen.
Haben das Ausprobiert aber bekommen das iwie nicht hin!
Hilfe???? :?:
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Code: Alles auswählen

[code=py]
der code
[/code]

:wink:
yipyip
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

zB so:

Code: Alles auswählen

 def foo(bar):
    return bar + "hallo"
Dabei einfach die Leerzeichen nach [ und vor ] weglassen:

[ code=py ] def foo(bar):
return bar + "hallo"[ /code ]

(vor return stehen vier spaces, aber ohne gültige code tags sieht man das nicht)
Mick.
In specifications, Murphy's Law supersedes Ohm's.
Nickl
User
Beiträge: 8
Registriert: Dienstag 27. Oktober 2009, 10:12

wurd schon von jmd verändert!
Danke
BlackJack

@Nickl: `Liste` ist ein nichtssagender Name. Die beiden Bestandteile, die eine Karte ausmachen in einer Zeichenkette zusammenzufügen ist keine gute Idee, weil man die zum Auswerten dann wieder mühsam trennen muss.

Schau nochmal ins Wörterbuch was "mischen" auf English heisst und lies Dir dann noch einmal die Dokumentation zum `random`-Modul durch.

Das Verteilen der Karten ist zu kompliziert und sicher auch nicht das was Du am Ende brauchst. Nach dem verteilen brauchst Du pro Spieler 5 Karten. Das musst Du Dir *merken* wer welche Karten bekommen hat. Also zum Beispiel in einer Liste mit Listen zu je 5 Karten. Beim Verteilen der Karten ziehst Du zufällig Karten aus einem bereits gemischten Kartenstapel -- Warum!? Die Karten sind doch schon gemischt, also kann man da einfach fünf aufeinanderfolgende Karten an die Spieler verteilen. Entweder per Slicing fünf auf einmal, oder vielleicht einfach mit der `pop()`-Methode die Karten einzeln vom Kartenstapel entfernen. Würde man real ja auch so machen.

Du müsstest eine Bewertungsfunktion für eine Hand schreiben, die als Ergebnis irgend etwas liefert was man mit anderen Bewertungen vergleichen kann. Also zum Beispiel ein Tupel aus Kombinationswert und Zahlenwert der "high card", wobei Kombinationswert den höchsten Wert für Royal Flush, den zweihöchsten für Straight Flush usw. haben müsste.

Am einfachsten wäre es wohl, wenn man für jede dieser Kombinationen eine Funktion schreibt, die testet, ob die Karten diese Kombination erfüllen, und in der Bewertungsfunktion dann von "oben" nach "unten" diese Testfunktionen aufruft und bei der ersten abbricht, die `True` ergibt.
Nickl
User
Beiträge: 8
Registriert: Dienstag 27. Oktober 2009, 10:12

BlackJack hat geschrieben:@Nickl: `Liste` ist ein nichtssagender Name. Die beiden Bestandteile, die eine Karte ausmachen in einer Zeichenkette zusammenzufügen ist keine gute Idee, weil man die zum Auswerten dann wieder mühsam trennen muss.

Schau nochmal ins Wörterbuch was "mischen" auf English heisst und lies Dir dann noch einmal die Dokumentation zum `random`-Modul durch.

Das Verteilen der Karten ist zu kompliziert und sicher auch nicht das was Du am Ende brauchst. Nach dem verteilen brauchst Du pro Spieler 5 Karten. Das musst Du Dir *merken* wer welche Karten bekommen hat. Also zum Beispiel in einer Liste mit Listen zu je 5 Karten. Beim Verteilen der Karten ziehst Du zufällig Karten aus einem bereits gemischten Kartenstapel -- Warum!? Die Karten sind doch schon gemischt, also kann man da einfach fünf aufeinanderfolgende Karten an die Spieler verteilen. Entweder per Slicing fünf auf einmal, oder vielleicht einfach mit der `pop()`-Methode die Karten einzeln vom Kartenstapel entfernen. Würde man real ja auch so machen.

Du müsstest eine Bewertungsfunktion für eine Hand schreiben, die als Ergebnis irgend etwas liefert was man mit anderen Bewertungen vergleichen kann. Also zum Beispiel ein Tupel aus Kombinationswert und Zahlenwert der "high card", wobei Kombinationswert den höchsten Wert für Royal Flush, den zweihöchsten für Straight Flush usw. haben müsste.

Am einfachsten wäre es wohl, wenn man für jede dieser Kombinationen eine Funktion schreibt, die testet, ob die Karten diese Kombination erfüllen, und in der Bewertungsfunktion dann von "oben" nach "unten" diese Testfunktionen aufruft und bei der ersten abbricht, die `True` ergibt.
Wie bitte :?:
Wir sind total die laien
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Nickl hat geschrieben: Wie bitte :?:
Wir sind total die laien
Was versteht ihr denn daran nich? Ein pauschales "Wie bitte" zeigt eher, dass ihr kein Interesse oder Motivation dazu habt... BalckJack hat das doch recht plastisch beschrieben - wo genau hakt es?
Nickl
User
Beiträge: 8
Registriert: Dienstag 27. Oktober 2009, 10:12

Hyperion hat geschrieben:
Nickl hat geschrieben: Wie bitte :?:
Wir sind total die laien
Was versteht ihr denn daran nich? Ein pauschales "Wie bitte" zeigt eher, dass ihr kein Interesse oder Motivation dazu habt... BalckJack hat das doch recht plastisch beschrieben - wo genau hakt es?
an den funktionen die wir noch nicht kennen
und das mitm mischen is doch voll ok und kein problem so wie wir es gemacht haben!
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Das ganze hört sich nach einer Aufgabe an, die bewertet wird. Deshalb noch ein paar Tipps (sind natürlich auch sinnvoll, wenn das nicht bewertet wird!).
  • Verwende aussagekräftige Variablennamen.
  • Halte dich an die PEP8 (Variablen - und Funktionsnamen werden klein_und_mit_unterstrich geschrieben, Klassenname CamelCase).
  • Verwende random.shuffle zum Mischen.
  • Es wäre hier auch sinnvoll, OO einzusetzen, vorallem wenn das später noch erweitert werden soll. Spontan fallen mir die Klassen "Karte", "Hand" und "Kartenstapel" ein.
Vielleicht erklärst du auch noch, welche Teile von BlackJack's Hilfe ihr nicht verstanden hat, dann kann man noch einmal genauer darauf eingehen.

P.S. Vergesst beim Ranking nicht, dass Karten mit höherem Wert auch einen höheren Rang haben. Und bei Pair und TwoPair zählt dabei eventuell auch noch eine der 3 anderen bzw. die 1 andere Karte ;)
Zuletzt geändert von ms4py am Mittwoch 28. Oktober 2009, 14:32, insgesamt 1-mal geändert.
Nickl
User
Beiträge: 8
Registriert: Dienstag 27. Oktober 2009, 10:12

ice2k3 hat geschrieben:Das ganze hört sich nach einer Aufgabe an, die bewertet wird. Deshalb noch ein paar Tipps (sind natürlich auch sinnvoll, wenn das nicht bewertet wird!).
  • Verwende aussagekräftige Variablennamen.
  • Halte dich an die PEP8 (Variablen - und Funktionsnamen werden klein_und_mit_unterstrich geschrieben, Klassenname CamelCase).
  • Verwende random.shuffle zum Mischen.
  • Es wäre hier auch sinnvoll, OO einzusetzen, vorallem wenn das später noch erweitert werden soll. Spontan fallen mir die Klassen "Karte", "Hand" und "Kartenstapel" ein.
Vielleicht erklärst du auch noch, welche Teile von BlackJack's Hilfe ihr nicht verstanden hat, dann kann man noch einmal genauer darauf eingehen.
wird nicht bewertet aber wir würden die aufgabe trotzdem gerne lösen und verstehen!
BlackJack

@Nickl: Dann ist die Aufgabe vielleich ein wenig zu kompliziert für den Anfang.

Worauf genau bezieht sich denn das "Wie bitte?"? Wenn man so eine doch schon recht komplexe Aufgabe lösen möchte, sollte man mindestens die Grunddatentypen von Python kennen und halbwegs sicher damit umgehen können. Desweiteren muss man Funktionen kennen. Das hier ist sogar eine Aufgabe, bei der Klassen schon sehr nützlich sind. Ohne Klassen sehe ich da viele "magische" Zahlenwerte und Tupel bei denen man kommentieren und/oder wissen muss was die einzelnen Elemente bedeuten sollen.

Also auf jeden Fall sollte man das Tutorial in der Python-Dokumentation durchgearbeitet haben.

Da ich nicht weiss, was genau Du nicht verstanden hast, gehe ich noch einmal auf den ersten Absatz meines Beitrags ein.

Wenn man den Namen `Liste` liest, hat man keine Ahnung was sich hinter diesem Namen eigentlich verbirgt. Gut, eine Liste, aber eine Liste von *was*!? Viel wichtiger ist doch die Information, was die Liste enthält. In diesem Fall wäre zum Beispiel `kartenstapel` ein Name, der viel mehr über den Sinn verrät.

Und dann habe ich noch die Modellierung einzelner Karten als Zeichenkette angesprochen. Bisher ist das im Programm noch klein Problem, aber später wirst Du Karten vergleichen müssen, und zwar nach ihrem Wert, ohne die Farbe zu berücksichtigen, zum Beispiel um zu sehen, ob die Karten im Sinne eines Paars gleich sind, oder umgekehrt nur die Farbe, um das "Royal" bei einem "Royal Flush" zu überprüfen. Und da wird's ungünstig, wenn beide Informationen erst wieder aus einer Zeichenkette extrahiert werden müssen. Hier ist eine Modellierung als Tupel besser. Eigentlich sogar als Klasse. Ich würde auch zumindest für die Werte Zahlen statt Zeichen verwenden, weil die Zeichen, wenn man sie sortiert oder vergleicht, nicht dem Ordnungswert entsprechen.

@ice2k3: Ich kenne eigentlich die Entscheidung über die "high card", die ist auch IMHO mit am einfachsten umzusetzen. Also wenn jemand 3,3,7,8,A auf der Hand hat und der andere 3,4,D,D,K dann gewinnt der mit dem 3er-Pärchen weil das As als "high card" mehr zählt als der König.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

BlackJack hat geschrieben:@ice2k3: Ich kenne eigentlich die Entscheidung über die "high card", die ist auch IMHO mit am einfachsten umzusetzen. Also wenn jemand 3,3,7,8,A auf der Hand hat und der andere 3,4,D,D,K dann gewinnt der mit dem 3er-Pärchen weil das As als "high card" mehr zählt als der König.
Nein! Zuerst zählt der Rang der Kombination (in diesem Fall das Paar) und nur wenn dieser gleich ist, die High Card. Der mit dem Damenpaar würde also gewinnen.
Benutzeravatar
/me
User
Beiträge: 3555
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

Nickl hat geschrieben:und das mitm mischen is doch voll ok und kein problem so wie wir es gemacht haben!
Ja, es funktioniert. Den Kartenstapel erst zu mischen und dann noch zufällig Karten aus dem Stapel zu ziehen ist allerdings überflüssig. Deine Lösung verbessert das Ergebnis nicht und macht das Programm nur komplizierter.

Da du offensichtlich noch Probleme mit der Programmiersprache hast, verweise ich mal auf die Dokumentation unter http://docs.python.org/library/random.html. Schau dir dort mal random.shuffle an.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Nickl hat geschrieben:und das mitm mischen is doch voll ok und kein problem so wie wir es gemacht haben!
Du bezeichnest dich als Laien, hast hier die Chance, kostenlos Expertenrat zu bekommen und bügelst das einfach weg, weil es "voll ok" ist, wie du es als Laie gemacht hast. :roll:

Der von dir gezeigte Code ist ganz überwiegend so, dass jemand, der kein Laie (mehr) ist, es so nicht machen würde.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

Zu dem, was BlackJack bereits geschrieben hat vielleicht noch folgendes.

Es ist fast immer besser, Funktionen aus der standard lib zu verwenden, als selber etwas zu stricken. Das ganze geloope mit randint kann man sicht sparen, wenn man itertools verwendet:

Code: Alles auswählen

from itertools import product, tee, izip

def poker():
    Farbe = ["K","P","H","C"]
    Wert = ["A","K","D","B","10","9","8","7","6","5","4","3","2"]
    bewerted = product(Farbe, enumerate(reversed(Wert)))
    Liste = [(b,f,w) for f,(b,w) in bewerted]
    ...
BlackJack hat auch angesprochen, dass Zahlenwerte günstiger sind, als Strings. Mit enumerate + reversed kann man einfach die Einträge in Wert auf solche Zahlen mappen, das hilft später beim Schreiben der Bewertungsfunktion. Man kann dann zB. leichter feststellen ob jemand eine Straße hat:

Code: Alles auswählen

    ...
    for i in range(Anzahl):
        ...
        if straight_flush(Karten):
            print "Straight Flush"
        elif straight(Karten):
            print "Straight"
        ...

def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

def straight(hand):
    for a,b in pairwise(hand):
        if a[0]+1 != b[0]:
            return False
    return True

def flush(hand):
    return len(set(f for b,f,w in hand)) == 1

def straight_flush(hand):
    return straight(hand) and flush(hand)
HTH,
Mick.
In specifications, Murphy's Law supersedes Ohm's.
ms4py
User
Beiträge: 1178
Registriert: Montag 19. Januar 2009, 09:37

Interessanter Variablennamen: ``bewerted``
SCNR :D

Ansonsten netter Beitrag, schau ich mir auch mal noch genauer an. Wobei das für einen Anfänger vermutlich nicht so geignet ist.

Edit: Das funktioniert aber nur, wenn ``hand`` nach dem Wert aufsteigend sortiert ist, oder hab ich was übersehen?
yipyip
User
Beiträge: 418
Registriert: Samstag 12. Juli 2008, 01:18

Danke! Mal wieder was ueber itertools.tee() gelernt. :)

Obwohl ich die Funktion 'pairwise' gestrichen und einfach nur

Code: Alles auswählen

def straight(hand):
  return all(a[0]+1 == b[0] for a, b in izip(hand, hand[1:]))
geschrieben haette.

:wink:
yipyip
Zuletzt geändert von yipyip am Mittwoch 28. Oktober 2009, 17:37, insgesamt 1-mal geändert.
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

ice2k3 hat geschrieben:Interessanter Variablennamen: ``bewerted``
Stimmt schon, ist ein rechter Blödsinn. Normalerweise würde diese Variable in meinem Code auch gar nicht auftauchen, weswegen sie dann auch keinen Namen hätte ;)

Code: Alles auswählen

    Liste = [(b,f,w) for f,(b,w) in product(Farbe,enumerate(reversed(Wert)))]
oder gleich:

Code: Alles auswählen

from collections import namedtuple
from random import shuffle
Card = namedtuple("Card", ["face", "suit"])
Wert = reversed(Wert)
...
    deck = [Card(face=f, suit=s) for f,s in product(xrange(13),xrange(4))]
    shuffle(deck)
    card = deck.pop()
    print Farbe[card.suit] + "-" + Wert[card.face]
ice2k3 hat geschrieben:Ansonsten netter Beitrag, schau ich mir auch mal noch genauer an. Wobei das für einen Anfänger vermutlich nicht so geignet ist.
Danke 8) Meinst du algorithmisch oder die Verwendung von Tupeln statt einer Karten-Klasse? Falls ersteres, damit wollte ich ein bisserl pädagogisch werden, denn um es zu verstehen muss man set, len, itertools und generator expressions kennen (-lernen). Für idiomatischen Python-Code unter Verwendung der std lib ist es IMO nie zu früh. Ob es vom Abstraktions-Level zu hoch ist, weiß ich natürlich nicht. Ich hoffe, der OP gibt ggf. Laut.

Vielleicht hab ich auch in letzter Zeit zu viele Essays von Paul Graham gelesen :roll:
ice2k3 hat geschrieben:Edit: Das funktioniert aber nur, wenn ``hand`` nach dem Wert aufsteigend sortiert ist, oder hab ich was übersehen?
Hast du nicht, aber da im Originalcode ja schon sortiert wurde, habe ich das vorausgesetzt.

Gruß,
Mick.
In specifications, Murphy's Law supersedes Ohm's.
Antworten