brauche Hilfe bei Spielprogrammierung

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.
Antworten
Miralem23
User
Beiträge: 10
Registriert: Sonntag 21. November 2010, 19:03

Hallo, ist mein erster Beitrag hier.
Vllt. sollte ich mich mal kurz vorstellen: Bin 21, Student der Informatik (1.Sem), und lerne gerade Python. Ich komme hobby-mäßig aus der iOS Entwicklung (iPhone/iPad) und betreibe dazu auch einen Blog mit vielen Tutorials (http://www.miralemcebic.de/Miralem_Cebic/Blog/Blog.html)

Nun zu meinem Anliegen.

Wir sollen ein bekanntes Kinder-Kartenspiel programmieren.
Mein Problem ist, dass ich nicht weiterkomme - ich brauch mal einen Denkanstoß

Also der Benutzer gibt ein wie viele reale Spieler und wie viele virtuelle Spieler es geben soll.
So weit so gut.

Dies klappt.

Dann habe ich eine Liste mit 31 Karten, davon 15 Paare und einen Joker.
Jetzt muss ich die Karten auf die Spieler verteilen.

Nun ist hier mein Problem, wie löse ich das am besten? Soll ich Listen benutzen?
Ich würde das gerne eindeutig haben, also sowas wie SpielerX hat ["Karte1", "Karte4", "Karte7", "Karte8"] auf der Hand

Kann mir da jemand helfen?
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Spontan wuerde ich eine Klasse fuer Karten, eine fuer Spieler, eine Subklasse von Spieler fuer virtuelle Spieler und eine Klasse/Funktion die das Spiel selbst abbildet machen. Die Details haengen natuerlich von den Regeln etc. ab.
Miralem23
User
Beiträge: 10
Registriert: Sonntag 21. November 2010, 19:03

OOP sowie Klassen hatten wir noch nicht. Das würde die Sache sehr viel leichter machen.

Wir müssen es quasi mit den Basics machen.

Funktionen, Listen, Tupel + den numerischen Datentypen

Und das Modul random sowie os dürfen wir benutzen

random, wegen der Zufälligen Kartenverteilung an jeden Spieler,
os, weil es im Terminal (cmd) laufen soll, wir brauchen da den Befehl "clear"

ja, und das macht die Sache schwieriger als es ist -.-*
lunar

Nun, dann denke darüber nach, welche Daten Du speicherst, und welche Datenstrukturen für den jeweiligen Zweck geeignet wären. Wo liegt da jetzt das Problem? Man braucht für dieses Problem nicht einmal Klassen, vor allem nicht für eine einzelne Karte.
Miralem23
User
Beiträge: 10
Registriert: Sonntag 21. November 2010, 19:03

Ich hatte es mir so gedacht dass ich globale liste erstelle

jeder Spieler stellt eine Liste da
In der Liste stehen die Karten des jeweiligen Spielers

Meine Frage war ob man das so lösen kann/soll oder es mit den bereits erwähnten basics eine elegantere Methode zur Lösung des Problem gibt
BlackJack

@Miralem23: Zeichenketten und Dictionaries sind nicht erlaubt? Die hast Du nämlich nicht in Deiner Aufzählung. :-)

Die Daten für "Objekte" kannst Du notfalls ja auch in Dictionaries zusammenfassen wenn Tupel oder Listen mit zuvielen Indexen zu unübersichtlich werden. Letztlich sind Objekte ja auch nur Dictionaries die Attributnamen auf Attributwerte abbilden und ein wenig "Magie" und syntaktischem Zucker.

Ansonsten teil das auf schön einfache, in sich geschlossene Funktionen auf. Du kannst da auch von einem "objektbasierten" Ansatz dran gehen. Das man keine Klassen benutzen darf, heisst ja nicht, dass man das nicht halbwegs objektorientiert umsetzen kann. Wo man vielleicht eine Klasse für's Kartenspiel haben würde, mit einer `__init__`-Methode, einer Methode zum Mischen und einer zum Verteilen der Karten auf `n` Spieler, kann man ja auch eine Funktion schreiben, die eine Liste mit Karten erstellt, eine welche die Karten mischt, und eine welche die Karten auf `n` spieler verteilt. Das steckt dann halt alles nicht in einer Klasse, aber das Prinzip von OOP ist ja nicht an Klassen gebunden.
Miralem23
User
Beiträge: 10
Registriert: Sonntag 21. November 2010, 19:03

Okay, bin nun etwas weiter
aber stecke noch in der Klemme

ich hab

Code: Alles auswählen

g1, g2, g3, g4 = {"g1":[]}, {"g2":[]}, {"g3":[]}, {"g4":[]}
und ich habe eine Liste names mit 4 Namen

Code: Alles auswählen

names = ["John", "Bill", "Konrad", "Paul"]
und eine dritte Liste die alle Karten enthält

Code: Alles auswählen

cards = ["A1", "A2", "B1", "B2", "C1", "C2", "D1", "D2", "E1", "E2", "F1", "F2", "G1", "G2", "Joker"]
wie schaffe ich es nun, das die vier Namen die keys der 4 Dictionaries werden und das alle 15 Karten verteilt und als values der dictionaries werden?

Soll man das mit for-Schleifen lösen??

das hab ich schon herausgefunden
g1["g1"] = "A1" --> {"g1" : "A1"}

Wie setze ich die Keys neu? gibt es sowas wie setKey("g1", "John")
BlackJack

@Miralem23: Was soll denn die erste Zeile bewirken? Wieso hast Du da durchnummerierte Namen? Das ist oft ein Zeichen, dass man da eigentlich eine Liste oder ein Dictionary verwenden sollte, insbesondere wenn Du anscheinend über den Namen `g1` usw. etwas an dem Objekt ändern möchtest, das an den Namen gebunden ist.

Und was sollen die Schlüssel 'g1' usw. innerhalb der Dictionaries? Das sind ja nun nicht gerade sprechende Bezeichner.

Du musst Dir genau wie bei OOP überlegen was so ein Dictionary repräsentieren soll. Ist `g1` ein Spieler?
Miralem23
User
Beiträge: 10
Registriert: Sonntag 21. November 2010, 19:03

Was soll denn die erste Zeile bewirken?
4 globale Variablen vom Typ Dictionary

Diese wollte ich dann mit den entsprechenden Namen versehen.

Also dass wenn 2 Spieler spielen, der erste "Thomas" und der zweite "Karl" heißt
Dann soll aus g1 = {"g1" : []} --> g1 = {"Thomas" : ["A1", "D1", "D2", ... ]}
und aus g2 analog zu g1

da

Code: Alles auswählen

names = ["John", "Bill", "Konrad", "Paul"]
nicht konstant ist, sonder immer neu abgefragt wird, wie viele Spieler es gibt und wie diese heißen, daher erstmal "Platzhalter" "g1", "g2", ... für den key gewählt

Denk ich zu blöd? sollte ich das besser angehen?
Du musst Dir genau wie bei OOP überlegen was so ein Dictionary repräsentieren soll. Ist `g1` ein Spieler?
Hoffe es ist klar geworden was das dict repräsentieren soll. :? Oder?
Benutzeravatar
DaMutz
User
Beiträge: 202
Registriert: Freitag 31. Oktober 2008, 17:25

Miralem23 hat geschrieben:Dann soll aus g1 = {"g1" : []} --> g1 = {"Thomas" : ["A1", "D1", "D2", ... ]}
und aus g2 analog zu g1
warum denn nicht so:

Code: Alles auswählen

spieler = {"Thomas": ["A1", "D1", "D2", ... ], "Karl": ["A2", ...]}
damit sparst du dir die durchnummerierten Variablen. Ausserdem musst du dieses dict auch erst erstellen wenn es nötig ist, also wenn du die Spielernamen weisst.
Miralem23
User
Beiträge: 10
Registriert: Sonntag 21. November 2010, 19:03

ahhh^^ super

ich hab das jetzt so gemacht

Code: Alles auswählen

cards = ["A1", "A2", "B1", "B2", "C1", "C2", "D1", "D2", "E1", "E2", "F1", "F2", "G1", "G2", "Joker"]

spieler = {"Thoams" : [cards[0], cards[3]]}
spieler.update({"Paul" : [cards[4], cards[6]]})

print(spieler)
kann man das so machen?
BlackJack

@Miralem23: Eine Liste wäre IMHO besser, denn bei Dictionaries ist die Reihenfolge der Einträge nicht garantiert und der Name gehört IMHO auch in das Spielerdictionary, denn das ist ja eine Eigenschaft des Spielers. Sonst kann man keine Funktionen schreiben, die nur einen Spieler bekommen, ohne das man den Namen extra übergeben muss, sollte der benötigt werden.

Ich hätte hier auch schon ein paar Funktionen geschrieben. Zum Beispiel eine um die Karten zu erzeugen. Das ist doch so nur fehleranfällige stupide Tipparbeit. Und dabei sind's noch nicht einmal 31 Karten. Im `string`-Modul gibt's konstante Zeichenketten mit verschiedenen Zeichenbereichen wie zum Beispiel auch alle ASCII-Grossbuchstaben.

Wie verteilt man denn 31 Karten auf 4 Spieler? Werden die letzten 3 Karten zerschnitten und verteilt? :-)

Das verteilen machst Du hoffentlich auch als Funktion und schreibst das da nicht fest rein!?
Miralem23
User
Beiträge: 10
Registriert: Sonntag 21. November 2010, 19:03

Und dabei sind's noch nicht einmal 31 Karten.
doch eigentlich schon^^
Wie verteilt man denn 31 Karten auf 4 Spieler? Werden die letzten 3 Karten zerschnitten und verteilt?
Das verteilen machst Du hoffentlich auch als Funktion und schreibst das da nicht fest rein!?
Meine Idee ist es eigentlich per random.randint eine zufällige stelle randint(0, len(cards)) zu treffen diese einem Spieler nach der Reihe zu übergeben

Es muss auf jeden Fall jeder Spieler min 2 Karten auf der Hand haben, ergo max 15 Spieler
BlackJack

@Miralem23: Also gezeigt hast Du hier nur 15 Karten. Und die sahen per Hand getippt aus.

Das mit dem Verteilen der Karten kann man so machen, man könnte die Karten aber auch mischen und dann gleich jedem die entsprechende Anzahl davon kopieren. Schau Dir mal die Funktionen im `random`-Modul und die Möglichkeiten auf Listenelemente zuzugreifen an.

Dann soll also jeder Spieler so viele Karten bekommen wie möglich und jeder gleich viele!?
Miralem23
User
Beiträge: 10
Registriert: Sonntag 21. November 2010, 19:03

Also gezeigt hast Du hier nur 15 Karten. Und die sahen per Hand getippt aus.
Dann habe ich eine Liste mit 31 Karten, davon 15 Paare und einen Joker.
Jetzt muss ich die Karten auf die Spieler verteilen.
Ich hab eben nur zu Zeitersparnis 15 genommen.

Es sind 31 Karten
Dann soll also jeder Spieler so viele Karten bekommen wie möglich und jeder gleich viele!?
Nein nicht gleich viele. Es können maximal 15 Spieler mitspielen, da jeder min. 2 Karten zum spielen braucht, und am Ende hat einer immer ein mehr

Das Spiel heißt Schwarzer Peter.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Hier mein Vorschlag, 31 Karten (repräsentiert durch Buchstaben-Strings) auf sechs Spieler (repräsentiert durch Zahlen-Strings) zu verteilen. Man kann's auch mit einer dict-comprehension machen, habe ich mir aber verkniffen, damit es bei Grundfunktionen bleibt.

Code: Alles auswählen

# ich mag's ja lieber funktional...
def shuffled(l): import random; l = list(l); random.shuffle(l); return l

cards = shuffled(list("ABCDEFGHIJKLMNO") * 2 + ["?"])
players = list("123456")
i, n = 0, len(cards) // len(players)
hands = {}
for player in players:
    hands[player] = cards[i:i + n]
    i += n
print(hands)
Stefan
BlackJack

@sma: Da werden aber nicht alle Karten verteilt. Insbesondere kann der Schwarze Peter übrig bleiben und dann müsste man sich bei der Implementierung des Spiels auch mit dem Fall herumschlagen, dass keiner verlieren könnte. Das Spiel heisst ja aber so weil am Ende auf jeden Fall einer mit der "Arschkarte" sitzen bleibt. :-)

Meine Kartenerstellung sieht übrigens fast genau so aus:

Code: Alles auswählen

JOKER = '*'


def create_card_deck(number_of_pairs=15):
    return [JOKER] + list(string.ascii_uppercase[:number_of_pairs] * 2)
Für's Verteilen habe ich dann auf `izip()` und `cycle()` aus den `itertools` zurückgegriffen. :-)
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Das Karten über bleiben ist mir klar, aber ich kann nun mal nicht 31 Karten gleichmäßig auf mehr als einen Spieler verteilen, weil das eine Primzahl ist. Ich hatte eine Gleichverteilung unter den Spielern angenommen. Vollständiges Verteilen, ohne irgendwelche iter-Funktionen, die laut Aufgabenstellung ja nicht benutzt werden sollen, aber ohne Extra-Schleife, bittesehr:

Code: Alles auswählen

for i, player in enumerate(players):
    hands[player] = cards[i::len(players)]
Stefan
BlackJack

@sma: Letztendlich gibt's ja keine Gleichverteilung, selbst wenn es aufgehen würde, weil bevor das Spiel beginnt, alle ihre Paare, die sie auf der Hand haben, abwerfen. Spätestens dann haben alle sehr wahrscheinlich nicht mehr die gleiche Anzahl von Karten auf der Hand. Letztendlich ist das sowieso ein Glücksspiel, solange die Leute nicht allzu offensichtlich reagieren wenn man eine verdeckte Karte von ihnen zieht, oder wenn man sich überlegt wie die Chancen stehen, ob und wie derjenige von dem man zieht, sein Blatt wohl sortiert haben mag.

Mit jeder zusätzlich zugeteilten Karte besteht ja auch eine Chance das man damit ein Paar bilden kann und so eine Karte los wird, statt eine zu bekommen. Wer Spass an Mathematik hat, kann ja mal ausrechnen ob das Risiko einer zusätzlichen Karte unter bestimmten Bedingungen die Chance ein Paar zu vervollständigen, aufwiegt.
Antworten