--->Kartenspiel programmieren<----

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.
AphrodiTe
User
Beiträge: 22
Registriert: Dienstag 18. September 2007, 12:48
Wohnort: Göttingen
Kontaktdaten:

Dienstag 18. September 2007, 13:07

Hallo,
Bin neulich auf das Forum gestoßen und fand, dass es vielleicht hilfreich für mich ist wenn ich mien problem hier rein poste anstatt im internet die ganze zeit zu suchen.
Wir haben neulich in der schule mit python angefangen.
ich habe einige fragen:

wie kann ich eine liste mit karten erstellen,10 karten an drei spieler austeilen und die karten des "Spielers" anzeigen lassen.Die andern aber nciht.

--->ich habe mir gedacht dass ich in eine liste erstmal alle Karten schreibe: z.b. Kartedeck = ["herz 7",Herz 8",.....,"Kreuz Ass"]
--->Dann wollte ich mit einem random.randint(0-31) eine zufallsauswahl treffen, aus den 32 karten.
---->Danach musste ich die Karten die gezogen wurde(verteilt wurden) aus dem Kartendeck löschen damit sie nciht doppelt oder dreifach im spiel vorkommen.Wollte es eigentlich mit einem del Kartendeck[x] amchen. x ist dabei die zuvor gezogene zahl.
---->Mit einem if x in Kartendeck wollte ich überprüfen ob die gezogene Karte überhaupt noch im deck drinne ist und evtl. neu ziehen lassen.

kann mir jemand helfen?? und mir sagen wie ich dann für drei spieler austeile?

Vielen Dank
Die Aussage eines Satzes ist reziprok zur Anzahl der kumulierenden Satzzeichen.
EyDu
User
Beiträge: 4871
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Dienstag 18. September 2007, 13:13

Schau dir mal im Modul "random" die Funktion "shuffle" an, damit kannst du deine Karte ganz einfach mischen. Dem ersten Spieler gibst du dann die ersten Karten:
karten[0:8]

dem zweiten Spieler die nächsten acht:
karten[8:16]

usw.

Bei "karten" handelt es sich hierbei übrigens um eine Liste welche mit "shuffle" gemischt wurde.
AphrodiTe
User
Beiträge: 22
Registriert: Dienstag 18. September 2007, 12:48
Wohnort: Göttingen
Kontaktdaten:

Dienstag 18. September 2007, 13:15

Danke,
....
denke ich werde hier demnächst öffter reinposten weil ich ja n kartenspiel programmieren will...bin halt noch n anfänger...aber das gibt sich hoffentlich mit der zeit.

AphrÒ.ó
Die Aussage eines Satzes ist reziprok zur Anzahl der kumulierenden Satzzeichen.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Dienstag 18. September 2007, 13:17

Mit der shuffle-Methode aus dem random-Modul kannst du dein Kartendeck mischen. Danach kannst du einfach fuer den ersten Spieler vom Ende der Kartendeck-Liste die Karten weg nehmen, danach fuer den naechsten Spieler und so weiter. Einen Listeneintrag vom Ende einer Liste entfernen und zurueckgeben lassen kannst du mit: karte = kartendeck.pop().
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
AphrodiTe
User
Beiträge: 22
Registriert: Dienstag 18. September 2007, 12:48
Wohnort: Göttingen
Kontaktdaten:

Dienstag 18. September 2007, 14:26

habe es jetzt glaube ich.mien problem ist, dass pythno den run-mode nciht ausführen will weil es iwie connectionfehler gibt.
naja hier bisher mein ergebniss...übrigens danke dass ihr mir helf...weil ich echt grade erst angefangen habe.

Code: Alles auswählen

import random


#Kartendeck inklusive mischen
karten = ["Karo 7","Karo 8","Karo 9","Karo 10","Karo Bube","Karo Dame","Karo Koenig","Karo Ass",
          "Herz 7","Herz 8","Herz 9","Herz 10","Herz Bube","Herz Dame","Herz Koenig","Herz Ass",
          "Pik 7","Pik 8","Pik 9","Pik 10","Pik Bube","Pik Dame","Pik Koenig","Pik Ass",
          "Kreuz 7","Kreuz 8","Kreuz 9","Kreuz 10","Kreuz Bube","Kreuz Dame","Kreuz Koenig","Kreuz Ass",]
random.shuffle(karten)

#Kartenausteilen
spielerkarten = karten[0:9]
gegnerkarten1 = karten[10:19]
gegnerkarten2 = karten[20:29]
skat = karten[30:31]
print spieler
bitte rückmeldungen
Die Aussage eines Satzes ist reziprok zur Anzahl der kumulierenden Satzzeichen.
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Dienstag 18. September 2007, 14:35

Moin,
AphrodiTe hat geschrieben: ... run-mode nciht ausführen will ...
was heißt das?

Code: Alles auswählen

#Kartenausteilen
spielerkarten = karten[0:9]
...
print spieler
Die Variable spieler gibt es nicht - muss spielerkarten heißen.

Gruß,
Manuel
Benutzeravatar
Michael Schneider
User
Beiträge: 567
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Dienstag 18. September 2007, 14:41

Hallo und willkommen!

Von shuffle bin ich nicht so begeistert, da es immer zwei beliebige Elemente gegeneinander vertauscht (so habe ich das jedenfalls verstanden) und deshalb entweder bei vielen Durchläufen Zeit verschwendet wird und bei wenigen Durchläufen vielleicht nicht alle Elemente gemischt werden.

Viel besser finde ich die pop-Methode, deren Argument angibt, welches Element Du entfernen möchtest:

Code: Alles auswählen

from random import randint

def draw_card(lKarten):
	if not lKarten: 
		return ()
	return lKarten.pop(randint(0, len(lKarten)-1))
	
lFarben = ["Kreuz", "Pik", "Herz", "Karo"]
lWerte = ["7", "8", "9", "10", "Bube", "Dame", "Koenig", "Ass"]
lKarten = [(sFarbe, sWert) for sWert in lWerte for sFarbe in lFarben]

print "\nziehe 10 Karten"
for i in xrange(10):
	print "gezogene Karte: %s %s" % draw_card(lKarten)
Grüße,
Michael
Zuletzt geändert von Michael Schneider am Dienstag 18. September 2007, 17:54, insgesamt 1-mal geändert.
Diese Nachricht zersört sich in 5 Sekunden selbst ...
Benutzeravatar
Michael Schneider
User
Beiträge: 567
Registriert: Samstag 8. April 2006, 12:31
Wohnort: Bremen
Kontaktdaten:

Dienstag 18. September 2007, 14:47

Hi!
AphrodiTe hat geschrieben:

Code: Alles auswählen

#Kartenausteilen
spielerkarten = karten[0:9]
gegnerkarten1 = karten[10:19]
gegnerkarten2 = karten[20:29]
skat = karten[30:31]
Die Obergrenzen sind exklusiv, also wie in Mathe
[ Startwert .. Endwert [
Das heißt bei karten[0:9] werden nur die Karten 0-8 herausgeschnitten. Es sollte also karten[0:10], karten [10:20], ... heißen.

Grüße,
Michel
Diese Nachricht zersört sich in 5 Sekunden selbst ...
AphrodiTe
User
Beiträge: 22
Registriert: Dienstag 18. September 2007, 12:48
Wohnort: Göttingen
Kontaktdaten:

Dienstag 18. September 2007, 15:29

ich verstehe das nciht

Code: Alles auswählen

def draw_card(lKarten):
    if not lKarten:
        return ()
    return lKarten.pop(randint(0, len(lKarten)))
was amcht python da??
Die Aussage eines Satzes ist reziprok zur Anzahl der kumulierenden Satzzeichen.
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Dienstag 18. September 2007, 15:44

Moin,

Code: Alles auswählen

    if not lKarten:
        return ()
wenn lKarten leer ist, dann wir eine leere Tupel zurückgegeben. Ist eigentlich unnötig und kann weggelassen werden. Im Code-Beispiel rennt das ganze dann eh in eine Exception. Da ist es IMHO besser die Exception von pop im Falle einer leeren Liste abzufangen. Aber darauf wirst du schon noch kommen :-)

Code: Alles auswählen

    return lKarten.pop(randint(0, len(lKarten)))
Die Funktion randint gibt eine Zufallszahl zurück. Der Bereich, aus dem die Zahl genommen werden soll, ist 0 bis Anzahl der Karten.

Siehe auch hier: http://docs.python.org/lib/module-random.html

Gruß,
Manuel
merlin_emrys
User
Beiträge: 110
Registriert: Freitag 3. März 2006, 09:47

Dienstag 18. September 2007, 16:08

Ich habe mich auch schon mit einem Kartenspiel beschäftigt. Bei mir sieht das Kartenziehen ganz einfach so aus:

Code: Alles auswählen

def takeItem(Itemstapel):
    """ takeItem entfernt ein Item aus dem Itemstapel und gibt es heraus"""
    return (Itemstapel.pop(random.randrange(len(Itemstapel))))
Da ich sowohl die Anzahl der zu ziehenden Karten wie auch die Größe der Spielrunde nicht vorher festlege, sondern im Spiel abfrage, sieht der Aufruf der Definition wie folgt aus:

Code: Alles auswählen

    for items in range(start_with_items):
        for memb in range(1, len(members)+1):
            taken_item = takeItem(Itemstapel)
            if memb == 1:
                memb1_has_items.append(taken_item)
                memb1_has_items.sort()
            ...
Noch ein paar Erklärungen hintendran:
Codeschnipsel 2, Zeile 2: Dort frage ich ab, wieviele Karten denn ausgeteilt werden sollen. Sooft, wie Karten vorhanden sein sollen, wird der folgende Programmteil durchlaufen - ich gebe also die Karten "reihum" aus, erst bekommt Spieler 1, dann Spieler 2, usw.
Zeile 3: Diese Zeile sorgt dafür, daß ich jeweils die ganze Spielrunde mit Karten bedenke (memb steht für member). Ich beginne in dem Falle die Zählung mit 1 und ende mit "members+1", da bei der Funktion range() die Obergrenze außerhalb der Wiederholung liegt. Auf die Weise habe ich keinen "Spieler0". War mehr so ein ästhetisches Problem :-) .
Zeile 4 ruft den ersten Codeschnipsel auf und nimmt sein Ergebnis entgegen, d.h. die gezogene Karte. Itemstapel ist der anfangs in Frage kommende Kartenstapel; ich kann mehrere davon bilden und muß deshalb sagen, welcher es sein soll.
Zeile 5 bis 7 sind "unpythonisch", weil ich dann jeweils abfrage, welcher Spieler diese Karte bekommen soll (if memb = ...) und sie dann jenem Spieler "in die Hand" (memb1_has_items) gebe. Dort wird sie dann gleich einsortiert.
Codeschnipsel 1, Zeile 2: Mit def leitet man einen eigenen, kleinen Programmteil ein, den man aus anderen Programmteilen heraus aufrufen kann. Ich kann also meine Definition "takeItem" jederzeit, wenn irgendwo eine Karte gezogen werden soll, aufrufen.
Zeile 3 ist eine Erklärung bezüglich dessen, was dieser Programmteil machen soll. Auf die Weise muß ich nicht immer den ganzen Text durchlesen, wenn ich später mal wieder wissen will, was ich denn damals so zurechtgebastelt habe :-) .
Zeile 4: "return" bedeutet, daß die Definition am Ende etwas an das Programm "zurückgibt", d.h. man kann das Ergebnis an eine Zeichenkette weitergeben. In meinem Fall ist diese Zeichenkette "taken_item", oder auch die gezogene Karte.
len(Itemstapel) stellt fest, wie "groß" der aktuelle Stapel noch ist, damit nur die Positionszahl einer vorhandenen Karte ausgewählt wird. random.randrange wählt aus diesem Bereich zufällig eine Karte aus, und "pop" bedeutet, daß aus einer Liste ein einzelnes Element entfernt wird (d.h. es ist anschließend nicht mehr in der Liste) und "zurückgegeben" wird, d.h. im Programm an eine Variable weitergegeben werden kann.
Zuletzt geändert von merlin_emrys am Dienstag 18. September 2007, 16:13, insgesamt 1-mal geändert.
AphrodiTe
User
Beiträge: 22
Registriert: Dienstag 18. September 2007, 12:48
Wohnort: Göttingen
Kontaktdaten:

Dienstag 18. September 2007, 16:09

ich habe das jetzt mit der methode von micheal gemacht.da stieß ich dann aber auf ein problem.für z.b. skat werden jedem spieler 10 karten gegeben.aber als ich das machen wollte aht er mir beim dritten spieler gesagt:

Code: Alles auswählen

Traceback (most recent call last):
  File "C:\Python25\neues projekt2", line 23, in <module>
    print "gezogene Karte: %s %s" % draw_card(lKarten)
  File "C:\Python25\neues projekt2", line 6, in draw_card
    return lKarten.pop(randint(0, len(lKarten)))
IndexError: pop index out of range
hab jetzt einfach ncoh 2 andere spieler und ein skat eingefügt:

Code: Alles auswählen

from random import randint

def draw_card(lKarten):
    if not lKarten:
        return ()
    return lKarten.pop(randint(0, len(lKarten)))
   
lFarben = ["Kreuz", "Pik", "Herz", "Karo"]
lWerte = ["7", "8", "9", "10", "Bube", "Dame", "Koenig", "Ass"]
lKarten = [(sFarbe, sWert) for sWert in lWerte for sFarbe in lFarben]

print "Deine Hand"
for i in xrange(10):
    print "gezogene Karte: %s %s" % draw_card(lKarten)


print "andere hand"
for i in xrange(10):
    print "gezogene Karte: %s %s" % draw_card(lKarten)

print "dritte hand"
for i in xrange(10):
    print "gezogene Karte: %s %s" % draw_card(lKarten)

print "der skat"
for i in xrange(2):
    print "gezogene Karte: %s %s" % draw_card(lKarten)

gibts dafür ne lösung?
vielen dank
kai
Die Aussage eines Satzes ist reziprok zur Anzahl der kumulierenden Satzzeichen.
merlin_emrys
User
Beiträge: 110
Registriert: Freitag 3. März 2006, 09:47

Dienstag 18. September 2007, 16:24

Die Fehlermeldung kommt genau dann, wenn randint(0, len(lKarten)) die höchstmögliche Zahl auswirft. Dann taucht offenbar das Problem auf, daß die Obergrenze von len() ein nicht existierendes Element angibt. Wenn Du randint(0, len(lKarten)-1) schreibst, läuft das Programm bis zum Ende durch.

Noch eine Anmerkung zu "Wie finde ich den Fehler?":
Ich habe die Funktion einfach "auseinandergenommen", jeden Schritt mit einer Variable ausgestattet und die Werte auf den Bildschirm schreiben lassen:

Code: Alles auswählen

def draw_card(lKarten): 
    if not lKarten: 
        return ()
    Kartennummer = randint(0, len(lKarten))
    print Kartennummer
    print len(lKarten)
    Karte = lKarten.pop(Kartennummer)
    return Karte
Dann sieht man, daß immer bei gleichen Zahlen das Programm nicht weiterkommt.
rafael
User
Beiträge: 189
Registriert: Mittwoch 26. Juli 2006, 16:13

Dienstag 18. September 2007, 17:19

Schau dir auch mal das hier und das darauffolgende Kapitel an, wo ein Kartenspiel tutorialweise erklärt wird.
BlackJack

Dienstag 18. September 2007, 17:29

Nimm um Himmels willen `shuffle()`. Dieses gepoppe ist ja nicht mit anzusehen.

@Michael: Was immer Du da über `shuffle()` denkst ist mit Sicherheit falsch. Das ist zum Mischen einer Sequenz gedacht und tut auch genau das. Wenn es solche Funktionalität schon in der Standardbibliothek gibt, muss man das ja nicht nochmal ineffizient selbst erfinden.
Antworten