--->Kartenspiel programmieren<----
@Michael Schneider: Der Realität kommt `shuffle()` und `pop()` ohne Index am nächsten, also das was ich vorgeschlagen habe. Nach dem Slicen gibt's die Objekte nicht mehrfach, nur mehr Referenzen darauf. Und natürlich kann man die Slices in der Originalliste auch löschen. Man muss die Realität auch nicht bis ins kleinste Detail nachbilden wenn es einfachere oder zweckmässigere Modellierungen gibt.
@AphrodiTe: `append()` ist eine Methode auf Listen. Hast Du schon das Tutorial in der Python-Dokumentation durchgearbeitet? Das ist für die Grundlagen zu empfehlen.
Und gewöhn Dir bitte die ungarische Notation bei Namen ab. Das ist schrecklich und irreführend wenn man den Typ mal ändern sollte und nicht die Namen anpasst.
@AphrodiTe: `append()` ist eine Methode auf Listen. Hast Du schon das Tutorial in der Python-Dokumentation durchgearbeitet? Das ist für die Grundlagen zu empfehlen.
Und gewöhn Dir bitte die ungarische Notation bei Namen ab. Das ist schrecklich und irreführend wenn man den Typ mal ändern sollte und nicht die Namen anpasst.
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Hallo,
von mir aus kann man auch Shuffle verwenden. Aber wenn ich das hier eingebe:
Bekomme ich nur eine Liste mit 28 Karten, statt 32. Warum?
Ich habe mal noch eine Funktion geschrieben, die zu jedem Stich die gueltige Werteliste der Karten berechnet. Den Index der Karte innerhalb dieser Liste kann man verwenden, um den Rang der Karte innerhalb des Stiches zu ermitteln. Die Liste respektiert neben der Farbe und dem Wert auch die Art des Spiels (Grand, Null, Farbe) und die ausgespielte Karte:
Geht aber bestimmt auch einfacher und besser für Anfänger geeignet.
@BlackJack, hast wieder mal recht. Ich dachte Du wärst kategorisch gegens Poppen.
Grüße,
Michael
von mir aus kann man auch Shuffle verwenden. Aber wenn ich das hier eingebe:
Code: Alles auswählen
shuffle(lKarten)
print len(lKarten)
Ich habe mal noch eine Funktion geschrieben, die zu jedem Stich die gueltige Werteliste der Karten berechnet. Den Index der Karte innerhalb dieser Liste kann man verwenden, um den Rang der Karte innerhalb des Stiches zu ermitteln. Die Liste respektiert neben der Farbe und dem Wert auch die Art des Spiels (Grand, Null, Farbe) und die ausgespielte Karte:
Code: Alles auswählen
from random import randint
# Initialisierung
lFarbspiel = ["Ass", "10", "Koenig", "Dame", "9", "8", "7"]
lNullspiel = ["Ass", "Koenig", "Dame", "Bube", "10", "9", "8", "7"]
lFarben = ["Kreuz", "Pik", "Herz", "Karo"]
lKarten = [(sFarbe, sWert) for sWert in lFarbspiel for sFarbe in lFarben]
def draw_card(lKarten):
if not lKarten:
return ()
return lKarten.pop(randint(0, len(lKarten)-1))
def create_order_list(tAusgespielt, sSpiel="Grand"):
"""Erzeugt eine Liste, die die Reihenfolge der Kartenwerte darstellt.
tAusgespielt - erwartet ein Kartentupel aus (Farbe, Wert)
sSpiel - die Spielart: "Grand", "Null", "Kreuz", "Pik", "Herz", "Karo"
"""
lOrder = []
# die Karte wird zerlegt in Farbe und Wert
sAusspielFarbe, sAusspielWert = tAusgespielt
# Beim Grand gilt die Wertordnung des Farbspiels, Buben sind Trumpf
if sSpiel == "Grand":
# Trumpf (Buben) einfuegen
lOrder.extend([(sFarbe, "Bube") for sFarbe in lFarben])
# Farbe der ausgespielten Karte einfuegen
lOrder.extend([(sAusspielFarbe, sWert) for sWert in lFarbspiel])
# Sonstige Karten einfuegen
lOrder.extend([(sFarbe, sWert) for sFarbe in lFarben
for sWert in lFarbspiel
if not sFarbe==sAusspielFarbe])
# Beim Nullspiel reihen sich 10 und Bube ein
elif sSpiel == "Null":
# Farbe der ausgespielten Karte einfuegen
lOrder.extend([(sAusspielFarbe, sWert) for sWert in lNullspiel])
# Sonstige Karten einfuegen
lOrder.extend([(sFarbe, sWert) for sFarbe in lFarben
for sWert in lNullspiel
if not sFarbe==sAusspielFarbe])
# Bei Farbspielen ist 10 > Koenig, Buben sind hoechste Trumpf
elif sSpiel in lFarben:
# Buben einfuegen
lOrder.extend([(sFarbe, "Bube") for sFarbe in lFarben])
# Trumpffarbe (= Spielfarbe) einfuegen
lOrder.extend([(sSpiel, sWert) for sWert in lFarbspiel])
# Farbe der ausgespielten Karte einfuegen, wenn sie nicht Trumpf ist
if not sSpiel == sAusspielFarbe:
lOrder.extend([(sAusspielFarbe, sWert) for sWert in lFarbspiel])
# Sonstige Karten einfuegen
lOrder.extend([(sFarbe, sWert) for sFarbe in lFarben
for sWert in lFarbspiel
if not sFarbe in (sAusspielFarbe, sSpiel)])
else:
print "Spielart '%s' ist nicht bekannt" % sSpiel
return lOrder
# erzeugt 3 Kartensets a 10 Karten ('Spieler 1', 'Spieler 2', 'Spieler 3') und den Skat
dKartenSets = {}
for iSpieler in xrange(1, 4):
dKartenSets["Spieler %i" % iSpieler] = [draw_card(lKarten) for i in xrange(10)]
dKartenSets["Skat"] = lKarten
################################################################################
# Auswertung/Test
print "Deine Hand"
for tKarte in sorted(dKartenSets["Spieler 1"]):
print "gezogene Karte: %s %s" % tKarte
# einen Stich zusammenstellen und fuer verschiedene Spiele gegenueberstellen
t1, t2, t3 = ("Karo", "Dame"), ("Karo", "10"), ("Kreuz", "Ass")
lStich = [t1, t2, t3]
print "="*60
print "Karten des Stichs:", lStich
print "%s %s wird ausgespielt" % t1
for sSpiel in ("Grand", "Null", "Karo", "Kreuz", "Pik"):
print "\nbeim %s:" % sSpiel
lKartenWert = create_order_list(tAusgespielt=t1, sSpiel=sSpiel)
print sorted(lStich, key=lKartenWert.index)
@BlackJack, hast wieder mal recht. Ich dachte Du wärst kategorisch gegens Poppen.
Grüße,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
-
- User
- Beiträge: 110
- Registriert: Freitag 3. März 2006, 09:47
Das kann ich nicht reproduzieren; bei mir sind es nach dem shufflen noch immer 32 Karten... Welche fehlen denn? (Bein Pokern würde ich ja zuerst gezielt nachsehen, ob noch alle Asse dasind, aber ich nehme an, das ist beim Skat nicht so relevant...? Andernfalls würde ich mit der KI mal über Mogeln beim Kartenspiel reden wollen ...)Michael Schneider hat geschrieben:Aber wenn ich das hier eingebe:Bekomme ich nur eine Liste mit 28 Karten, statt 32. Warum?Code: Alles auswählen
shuffle(lKarten) print len(lKarten)
- Rebecca
- User
- Beiträge: 1662
- Registriert: Freitag 3. Februar 2006, 12:28
- Wohnort: DN, Heimat: HB
- Kontaktdaten:
Ich auch nicht.Michael Schneider hat geschrieben:Deine Abneigung gegenüber Poppen kann ich nicht nachvollziehen.
SCNR
Offizielles Python-Tutorial (Deutsche Version)
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Ich wurde ja auch falsch verstanden. Ich bin nur gegen wildes, zufälliges poppen, anstelle eines effizienten poppens immer schön der Reihe nach, von hinten.
- mkesper
- User
- Beiträge: 919
- Registriert: Montag 20. November 2006, 15:48
- Wohnort: formerly known as mkallas
- Kontaktdaten:
Kommt dieser Unsinn etwa vom Lehrer? Dann sollte ihn schleunigst mal jemand ans Forum oder zumindest an PEP0008 verweisen.BlackJack hat geschrieben:Und gewöhn Dir bitte die ungarische Notation bei Namen ab. Das ist schrecklich und irreführend wenn man den Typ mal ändern sollte und nicht die Namen anpasst.
AphrodiTe hat geschrieben:Wir haben neulich in der schule mit python angefangen.
-
- User
- Beiträge: 22
- Registriert: Dienstag 18. September 2007, 12:48
- Wohnort: Göttingen
- Kontaktdaten:
kann ich mit
fragen ob was in der liste ist??
Code: Alles auswählen
x=["a","b","c"]
if a in x:
print "a ist in der liste"
Die Aussage eines Satzes ist reziprok zur Anzahl der kumulierenden Satzzeichen.
Probier' es doch einfach aus, aber um einem Mißverständnis vorzubeugen, das aus Deinem Snippet glänzt:
Gruß,
Christian
Code: Alles auswählen
>>> l = ['a', 'b', 'c']
>>> a in l
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> 'a' in l
True
>>> x = 'a'
>>> x in l
True
Christian
-
- User
- Beiträge: 22
- Registriert: Dienstag 18. September 2007, 12:48
- Wohnort: Göttingen
- Kontaktdaten:
Tut mir leid dass ich es nciht raffe aber iwie will es nciht in meinen kopf rein.
ich ahbe eine liste in der 10 karten drinne stehen.
und dann will ich fragen welche karte der benutzer spielen möchte und überprüfen ob die karte in der liste vorhanden ist.
und was kommt dann?
if x in karten = true ???
vielen dank
kai
ich ahbe eine liste in der 10 karten drinne stehen.
und dann will ich fragen welche karte der benutzer spielen möchte und überprüfen ob die karte in der liste vorhanden ist.
Code: Alles auswählen
karten=["herz 7",...."karo 8"]
x=raw_input("Welche Karte willst du spielen?")
if x in karten = true ???
vielen dank
kai
Die Aussage eines Satzes ist reziprok zur Anzahl der kumulierenden Satzzeichen.
-
- User
- Beiträge: 110
- Registriert: Freitag 3. März 2006, 09:47
Man könnte es so machen, aber das Problem ist in meinen Augen die Tippfehleranfälligkeit. Python ist da ziemlich "pinibel". Ich würde dem Nutzer daher nur eine Auswahl von 1-10 stellen:
Edit:
"zu_legende_Karte" war oben nicht gut eingesetzt. Es ist
zu_legende_Karte = karten[Kartennummer-1]
Der Term -1 ist wieder nur ästhetischen Kriterien geschuldet - ich bin es gewöhnt, Karten von "1" an zu zählen, eine "Karte 0" finde ich einfach irritierend.
Code: Alles auswählen
# -*- coding: cp1252 -*-
karten = ['herz 7', 'karo 9', 'pik dame']
print "Welche Karte möchtest Du spielen? Bitte gibt ein:"
for karte_nummer in range(1,len(karten)+1):
print "%i für %s" % (karte_nummer, str(karten[karte_nummer-1]))
Kartennummer = raw_input("Bitte nur die Nummer eingeben: ")
"zu_legende_Karte" war oben nicht gut eingesetzt. Es ist
zu_legende_Karte = karten[Kartennummer-1]
Der Term -1 ist wieder nur ästhetischen Kriterien geschuldet - ich bin es gewöhnt, Karten von "1" an zu zählen, eine "Karte 0" finde ich einfach irritierend.
-
- User
- Beiträge: 22
- Registriert: Dienstag 18. September 2007, 12:48
- Wohnort: Göttingen
- Kontaktdaten:
Vielen dank merlin emrys
und danach setzte ich einfach ein append() befehl ein um die karte aus der eigenen hand zu löschen.
danach wollte ich mit einem split() die karte splitten in wert und farbe.damit der computer bedienen kann und damit man am ende karten vergleichen kann.
melde mich dann eh ncohmal
kai
und danach setzte ich einfach ein append() befehl ein um die karte aus der eigenen hand zu löschen.
danach wollte ich mit einem split() die karte splitten in wert und farbe.damit der computer bedienen kann und damit man am ende karten vergleichen kann.
melde mich dann eh ncohmal
kai
Die Aussage eines Satzes ist reziprok zur Anzahl der kumulierenden Satzzeichen.
-
- User
- Beiträge: 110
- Registriert: Freitag 3. März 2006, 09:47
Noch ein Nachtrag:
"raw_input()" ist immer ein bisschen riskant, wie ich hier im Forum gelernt habe. Daher folgender Vorschlag:
Zur Erklärung:
while True leitet eine Endlosschleife ein, die nur verlassen wird, wenn das Probramm einem "break" begegnen. Das tut es in diesem Fall erstmal nur, wenn es schafft, aus dem raw_input()-Ergebnis eine Zahl zu machen, denn das ist die Aufgabe von int(). Wenn das nicht hinhaut, wird die Eingabe nicht weiter behandelt - das heißt, auch wenn jemand da Python-Code eingibt, macht das Programm korrekt weiter, indem es sich einfach weigert, mit dieser Eingabe irgendetwas zu machen.
Und dann sorgt die if-Anweisung dafür, daß nicht eine Zahl genommen wird, die außerhalb der Kartenmenge liegt. Erst, wenn alles okay zu sein scheint, wird die Schleife verlassen und das Programm läuft weiter.
"raw_input()" ist immer ein bisschen riskant, wie ich hier im Forum gelernt habe. Daher folgender Vorschlag:
Code: Alles auswählen
# -*- coding: cp1252 -*-
karten = ['herz 7', 'karo 9', 'pik dame']
print "Welche Karte möchtest Du spielen? Bitte gibt ein:"
for karte_nummer in range(1,len(karten)+1):
print "%i für %s" % (karte_nummer, str(karten[karte_nummer-1]))
while True:
try:
Kartennummer=int(raw_input("Nur die Nummer von 1 - %i bitte: " % len(karten) ))
except ValueError:
print "Bitte gibt nur eine Nummer im angegebenen Bereich ein!"
if Kartennummer in range(1,len(karten)+1):
break
while True leitet eine Endlosschleife ein, die nur verlassen wird, wenn das Probramm einem "break" begegnen. Das tut es in diesem Fall erstmal nur, wenn es schafft, aus dem raw_input()-Ergebnis eine Zahl zu machen, denn das ist die Aufgabe von int(). Wenn das nicht hinhaut, wird die Eingabe nicht weiter behandelt - das heißt, auch wenn jemand da Python-Code eingibt, macht das Programm korrekt weiter, indem es sich einfach weigert, mit dieser Eingabe irgendetwas zu machen.
Und dann sorgt die if-Anweisung dafür, daß nicht eine Zahl genommen wird, die außerhalb der Kartenmenge liegt. Erst, wenn alles okay zu sein scheint, wird die Schleife verlassen und das Programm läuft weiter.
Beide male ist das `range()` ungünstig.
Im ersten Fall ist direktes iterieren über die Karten in Verbindung mit `enumerate()` idiomatischer. Selbst mit `xrange()` würde man beim Angeben der Grenzen 0 und ``len(karten)``, wobei die erste dann wegfallen kann, nur an einer Stelle die Korrektur im 1 machen müssen.
Beim zweiten `range()` wird nur für eine Bereichsüberprüfung eine Liste mit Zahlen erzeugt und in der dann linear gesucht. Das geht auch effizienter/schöner:
Das ganze liesse sich auch in eine Funktion verpacken, die den Anwender aus einer Liste von Objekten eines auswählen lässt, und wäre damit wiederverwendbar.
Die Modellierung einer Karte als Zeichenkette in der zwei mehr oder weniger unabhängige Informationen, Farbe und Bild/Wert, zusammengefügt sind, ist äusserst ungünstig.
Im ersten Fall ist direktes iterieren über die Karten in Verbindung mit `enumerate()` idiomatischer. Selbst mit `xrange()` würde man beim Angeben der Grenzen 0 und ``len(karten)``, wobei die erste dann wegfallen kann, nur an einer Stelle die Korrektur im 1 machen müssen.
Beim zweiten `range()` wird nur für eine Bereichsüberprüfung eine Liste mit Zahlen erzeugt und in der dann linear gesucht. Das geht auch effizienter/schöner:
Code: Alles auswählen
def main():
karten = ['herz 7', 'karo 9', 'pik dame']
for i, karte in enumerate(karten):
print '%d für %s' % (i + 1, karte)
while True:
try:
nummer = int(raw_input('Nummer von 1 - %d bitte:' % len(karten)))
karte = karten[nummer - 1]
break
except (ValueError, IndexError):
print 'Bitte nur eine Nummer im angegebenen Bereich!'
print 'Gewaehlt:', karte
Die Modellierung einer Karte als Zeichenkette in der zwei mehr oder weniger unabhängige Informationen, Farbe und Bild/Wert, zusammengefügt sind, ist äusserst ungünstig.
- Michael Schneider
- User
- Beiträge: 569
- Registriert: Samstag 8. April 2006, 12:31
- Wohnort: Brandenburg
Natürlich Referenzen. "Gibt es mehrfach" meinte ich in dem Sinne, wie es z.B. Baupläne eines Hauses im Kopf und gleichzeitig auf Papier geben kann. Sonst hätte ich geschrieben, dass neue Objekte erzeugt werden.BlackJack hat geschrieben:Nach dem Slicen gibt's die Objekte nicht mehrfach, nur mehr Referenzen darauf.
Gruß,
Michael
Diese Nachricht zersört sich in 5 Sekunden selbst ...
-
- User
- Beiträge: 22
- Registriert: Dienstag 18. September 2007, 12:48
- Wohnort: Göttingen
- Kontaktdaten:
vielen dank,
soll ich die befehle append() und del() in die wile-schleife mit einbauen oder eher anch der schleife schreiben?
wollten die karte die man gelegt hat aus der liste jetzt löschen mit del()
und eine neue liste erstellen mit appand()
vielen dank
kai
soll ich die befehle append() und del() in die wile-schleife mit einbauen oder eher anch der schleife schreiben?
wollten die karte die man gelegt hat aus der liste jetzt löschen mit del()
und eine neue liste erstellen mit appand()
vielen dank
kai
Die Aussage eines Satzes ist reziprok zur Anzahl der kumulierenden Satzzeichen.
-
- User
- Beiträge: 110
- Registriert: Freitag 3. März 2006, 09:47
Es geht beides. Ich würde es eher nach der Schleife machen, aber ich kann nicht genau erklären, warum eigentlich.AphrodiTe hat geschrieben:vielen dank,
soll ich die befehle append() und del() in die wile-schleife mit einbauen oder eher anch der schleife schreiben?
-
- User
- Beiträge: 22
- Registriert: Dienstag 18. September 2007, 12:48
- Wohnort: Göttingen
- Kontaktdaten:
ja ich ahbe es jertzt anch der Schleife eingebaut..
das funktioniert super.
nur wenn ich angeben will dass er in eine neue liste die karte reinschreiben soll macht er es nciht.
habe mir das gedacht:
stich ist die neue liste die ich vorher schon erstellt ahbe
kai
Code: Alles auswählen
del Deine_Karten[nummer-1]
print Deine_Karten
nur wenn ich angeben will dass er in eine neue liste die karte reinschreiben soll macht er es nciht.
habe mir das gedacht:
Code: Alles auswählen
stich.append(Deine_Karten[nummer-1])
kai
Die Aussage eines Satzes ist reziprok zur Anzahl der kumulierenden Satzzeichen.
-
- User
- Beiträge: 110
- Registriert: Freitag 3. März 2006, 09:47
Was kommt denn für eine Fehlermeldung?
Ich habe die beiden Befehle jetzt mal in meine letzte Schleifenversion eingebaut (habe keine Lust, sie umzutexten... ), und da scheint es zu funktionieren:
Dann bekomme ich:
Edit:
Noch eine Frage an BlackJack: Du hast geschrieben, meine zweite range()-Anwendung sei ungünstig. Ich habe jetzt doch mal meinen Code umgetextet, weil ich mir ein bestimmtes Phänomen nicht erklären konnte. Aber wenn ich die range()-Funktion weglasse, bricht das Programm bei einer zu hohen Zahleneingabe mit einer Fehlermeldung ab, was ich als eher störend empfinde. Jetzt bin ich verwirrt... Wie könnte man falsche Zahleneingaben noch "abfangen"?
(Das erwähnte Phänomen ist leider nicht reproduzierbar: Als ich bei ein paar Testläufen nur die Eingabetaste gedrückt habe, wurde immer zunächst die Meldung "Bitte gibt nur ...." angezeigt und dann der Auswahltext wieder angezeigt, aber sofort (d.h. ohne weitere Eingabe von mir) die Karte 'pik dame' ausgewählt. Jetzt passiert es nicht mehr... Weiß irgendwer, was da los war? Ich verwende zum Testen python 2.4 mit IDLE.)
Ich habe die beiden Befehle jetzt mal in meine letzte Schleifenversion eingebaut (habe keine Lust, sie umzutexten... ), und da scheint es zu funktionieren:
Code: Alles auswählen
# -*- coding: cp1252 -*-
karten = ['herz 7', 'karo 9', 'pik dame']
stich = []
print "Welche Karte möchtest Du spielen? Bitte gibt ein:"
for karte_nummer in range(1,len(karten)+1):
print "%i für %s" % (karte_nummer, str(karten[karte_nummer-1]))
while True:
try:
Kartennummer=int(raw_input("Nur die Nummer von 1 - %i bitte: " % len(karten) ))
except ValueError:
print "Bitte gibt nur eine Nummer im angegebenen Bereich ein!"
if Kartennummer in range(1,len(karten)+1):
print "Gewählt wurde: ", karten[Kartennummer-1]
stich.append(karten[Kartennummer-1])
del karten[Kartennummer-1]
break
print stich
print karten
Code: Alles auswählen
>>>
Welche Karte möchtest Du spielen? Bitte gibt ein:
1 für herz 7
2 für karo 9
3 für pik dame
Nur die Nummer von 1 - 3 bitte: 2
Gewählt wurde: karo 9
['karo 9']
['herz 7', 'pik dame']
Noch eine Frage an BlackJack: Du hast geschrieben, meine zweite range()-Anwendung sei ungünstig. Ich habe jetzt doch mal meinen Code umgetextet, weil ich mir ein bestimmtes Phänomen nicht erklären konnte. Aber wenn ich die range()-Funktion weglasse, bricht das Programm bei einer zu hohen Zahleneingabe mit einer Fehlermeldung ab, was ich als eher störend empfinde. Jetzt bin ich verwirrt... Wie könnte man falsche Zahleneingaben noch "abfangen"?
(Das erwähnte Phänomen ist leider nicht reproduzierbar: Als ich bei ein paar Testläufen nur die Eingabetaste gedrückt habe, wurde immer zunächst die Meldung "Bitte gibt nur ...." angezeigt und dann der Auswahltext wieder angezeigt, aber sofort (d.h. ohne weitere Eingabe von mir) die Karte 'pik dame' ausgewählt. Jetzt passiert es nicht mehr... Weiß irgendwer, was da los war? Ich verwende zum Testen python 2.4 mit IDLE.)
Zuletzt geändert von merlin_emrys am Mittwoch 19. September 2007, 18:40, insgesamt 2-mal geändert.
-
- User
- Beiträge: 419
- Registriert: Sonntag 3. September 2006, 15:11
- Wohnort: in den weiten von NRW
- Kontaktdaten:
Was passiert denn? Gibts ne Fehlermeldung?
-
- User
- Beiträge: 22
- Registriert: Dienstag 18. September 2007, 12:48
- Wohnort: Göttingen
- Kontaktdaten:
hi merlin emrys,
das prob hatte ich auch als ich es ohne die def main(): kopiert habe...alle tabs müssen stimmen...
hab es dann ncoh hinbekommen...
hoffe es geht danach
kai
das prob hatte ich auch als ich es ohne die def main(): kopiert habe...alle tabs müssen stimmen...
hab es dann ncoh hinbekommen...
hoffe es geht danach
kai
Die Aussage eines Satzes ist reziprok zur Anzahl der kumulierenden Satzzeichen.