tictactoe(anfänger)
@marlene: Dazu ist ein `dict` dann wohl die falsche Datenstruktur, weil die Elemente eben keine Reihenfolge haben.
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Kapiere ich so noch nicht! Was bedeutet "nächster" Spieler? Die Reihenfolge eines Dicts ist ja letztlich zufällig, da sie von den Daten und der Implementierung des Python-Interpreters abhängt. Wenn Du die Reihenfolge von dict.keys() als Referenz nimmst, könnte ich Dir folgen. Aber: Was passiert, wenn man Spieler 3 "erwischt", dann nimmt man vier und dann? Geht es bei 1 weiter? Worin besteht der Vorteil gegenüber einer rein zufällugen Mischung, wie ich sie zuvor vorgeschlagen habe? Was passiert nach einer Runde? Soll in der darauffolgenden exakt die gleiche Reihenfolge eingehalten werden, oder wechselt das wieder?marlene hat geschrieben: Nur der erste soll zufällig gewählt werden, ab da soll das wie bei einer "echten Würfelrunde" nach der Reihe weiter gehen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
Ich hatte vorher eine Liste in dem die Teilnehmer gespeichert waren z.B players = ["hans“, "uwe“, "peter“]. Aus dieser Liste habe ich per Zufallszahl einen Index gezogen z.B. 1, was dann „uwe“ wäre. Soweit funktioniert das mit dem ‚dict‘ ja auch. Das Spiel würde jetzt so "laufen", uwe fängt an, danach kommt peter und danach hans dann wieder uwe usw. bis einer gewonnen hat. Bei einer Liste hab ich das erreicht einfach durch raufsetzen des Index um 1, beim ‚dict‘ hab ich jetzt aber ein Problem, weil ich nicht weiss wie ich das mit einem ‚dict‘ realisieren kann, oder ob das überhaupt möglich ist so wie ich mir das vorstelle?
Die Anregung dazu kam von Dauerbaustelle:
Die Anregung dazu kam von Dauerbaustelle:
Was mir bei genauerem Hinsehen noch auffällt: Die von dir gewählte Datenstruktur für das Speichern der Spieler und des Punktestandes ist nicht besonders gut. Was du willst ist ein "Spieler-Punktestand"-Mapping. Schau dir mal Dictionaries an.
- cofi
- Python-Forum Veteran
- Beiträge: 4432
- Registriert: Sonntag 30. März 2008, 04:16
- Wohnort: RGFybXN0YWR0
Ich glaube du suchst ein OrderedDict: http://docs.python.org/library/collecti ... rderedDict
Michael Markert ❖ PEP 8 Übersetzung ❖ Tutorial Übersetzung (3.x) ⇒ Online-Version (Python 3.3) ❖ Deutscher Python-Insider ❖ Projekte
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Du hast also bei einem "Zug" nur immer einen Spieler bzw. das Objekt dahinter in Benutzung? Dann brauchst Du kein Dictionary, da Du ja das Objekt einfach durch iterieren bekommst und nicht nebenbei (schnellen) Zugriff auf andere Spieler benötigst. Da wäre eine Liste besser geeignet. Darauf wendest Du eben wie oben gezeigt shuffle an und iterierst über die Liste.
Meine Idee oben setzt das ja letztlich auch um, außer, dass im Hintergrund ein Dict die eigentlichen Daten beinhaltet und die Liste nur für das Iterieren und den zufälligen Zugriff angelegt wird.
Meine Idee oben setzt das ja letztlich auch um, außer, dass im Hintergrund ein Dict die eigentlichen Daten beinhaltet und die Liste nur für das Iterieren und den zufälligen Zugriff angelegt wird.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
@Hyperion: ja ich glaub du hast recht.
Ich habe es jetzt so gemacht.
Ich habe es jetzt so gemacht.
Code: Alles auswählen
def next_player_index(player, players):
next_player = list(players.keys())
index = (next_player.index(player) + 1) %len(next_player)
return next_player[index]
Ich hab das ganze jetzt verbessert und galube das ich alle Verbesserungen(Anrgungen), verändert oder eingebaut habe.
User Teil:
logik modul:
User Teil:
Code: Alles auswählen
from time import sleep
import logik
def game(players, win_points):
win = False
print
print('Es wird ausgewuerfelt wer anfaengt')
player = logik.pick_first_player(players)
print('%s feangt an.') % (player)
while win is False:
print
print('Punktestand: %s ') % (players)
print
print('%s ist dran.') % (player)
raw_input('Enter druecken zum weurfeln.')
cache_dices = logik.roll_dices()
for dice in cache_dices:
sleep(0.8)
print('wuerfeln.... %s') % (dice)
if dice == 1:
print('Sie haben 1 gewuerfelt, und bekommen 0 Punkte.')
cache_dices = [0]
break
players = logik.add_points_to_player(players, player, cache_dices)
if logik.check_winner(players, win_points):
print('%s hat gewonnen.') % (player)
print
print players
print
win = True
player = logik.next_player_index(player, players)
def main():
while True:
choice = raw_input("Neues Spiel (yes/no)? ")
if choice == "no":
break
players = {}
rules = raw_input('Spielregeln anzeigen ja(j) nein(n): ')
if rules == 'j':
print("""
Es wird reihum gewuerfelt. Wer die hoechste Augenzahl
in der ersten Runde hat darf anfangen.
Nun darf jeder Spieler viermal wuerfeln.
Die Augen werden immer addiert, wuerfelt man eine
Eins wird der gesamte Wurf ungueltig und der naechste ist dran.
""")
players_number = int(raw_input('Spieleranzahl: '))
for number in range(players_number):
player = raw_input('Name Spieler: ')
players[player] = 0
win_points = int(raw_input('Punkte zum Gewinn angeben: '))
game(players, win_points)
if __name__ == '__main__':
main()
Code: Alles auswählen
from random import randint
from random import choice
def pick_first_player(players):
return choice(players.keys())
def roll_dices(count=4):
return [randint(1, 6) for _ in xrange(count)]
def add_points_to_player(players, player, cache_dices):
players[player] += sum(cache_dices)
return players
def check_winner(players, win_points):
for points in players.values():
if points >= win_points:
return True
def next_player_index(player, players):
next_player = list(players.keys())
index = (next_player.index(player) + 1) %len(next_player)
return next_player[index]
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Hui... das ist jetzt nicht wirklich toll!marlene hat geschrieben:@Hyperion: ja ich glaub du hast recht.
Ich habe es jetzt so gemacht.Code: Alles auswählen
def next_player_index(player, players): next_player = list(players.keys()) index = (next_player.index(player) + 1) %len(next_player) return next_player[index]
Wieso nutzt Du nicht shuffle()? Das hatte ich Dich doch in diesem Post beschrieben: http://www.python-forum.de/viewtopic.ph ... 53#p191553
Du musst Dir dann eben die zufällig gewürfelte Spielerliste merken und der Spiel-Funktion übergeben. Aber das ist imho besser, als in einer Funktion für den nächsten Spieler immer so ein Brimborium zu machen und der neben dem aktuellen Spieler auch noch das gesamte Dict zu übergeben.
Kurze Anmerkung noch:
Code: Alles auswählen
next_player = list(players.keys())
# exakt das gleiche wie
next_player = players.keys()

Du kannst anschließend itertools.cycle() benutzen, um nacheinander alle Spieler-Keys durchzugehen. Anhand des Keys kannst Du dann über das players-Dictionary an den Punktestand kommen.
Alternativ könnte Deine Spieler-Struktur auch so aussehen:
Code: Alles auswählen
players = [
["Chris", 0],
["Marlene", 35],
...
]
Deine Hauptschleife sähe dann so aus:
Code: Alles auswählen
for player in cycle(players):
print "Spieler {0} ist ander Reihe.".format(player[0])
print "Punkte: {0}".format(player[1])
Code: Alles auswählen
# auf Modulebene
from operator import itemgetter
name, points = itemgetter(0), itemgetter(1)
# und dann später
print "Name: {0}, Punkte: {1}".format(name(player), points(player))
Code: Alles auswählen
players = [
{"name": "Chris", "points": 0},
{"name": "Marlene", "points": 34},
...
]
Als letzte Anmerkung: Mir gefällt die Auslagerung von Code in dieses logik-modul nicht! Zum einen steckt viel Spiellogik ja auch in der game()-Funktion, zum anderen ist das alles so wenig Code, dass man da kein eigenes Modul zu benötigt. Und generisch genug, als dass man ihn wiederverwenden könnte ist er imho auch nicht. Also würde ich das bei einem Modul belassen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
-
- User
- Beiträge: 996
- Registriert: Mittwoch 9. Januar 2008, 13:48
@Hyperion: Sowohl Dictionary als auch separates Modul waren meine Idee. Die Diskussion muss also gegen mich gerichtet sein ;-)
Ad Dictionary: Ich denke schon, dass da ein Dict her sollte, weil sie hat eben ein Mapping in eine Richtung (Spieler->Punktestand). Wenn es da jetzt Probleme mit dem Shuffeln gibt, könnte man einfach die ``.keys()`` nehmen und die dann eben randomisieren (vorausgesetzt es kommen im Laufe des Spieles keine weiteren Spieler dazu).
Modul: Das habe ich empfohlen zu Lernzwecken. Pragmatisch gesehen macht es natürlich bei so wenig Code keinen Sinn, das auszulagern. Alledings hatte sie Schwierigkeiten, Benutzerinteraktion und Spiellogik zu trennen, und da ist ein Modul doch ein ganz gutes "Werkzeug", eben weil man gezwungen wird, das Ganze schön zu trennen.
Anstatt den imo hässlichen itemgettern würde ich dann lieber ein ``collections.namedtuple`` nehmen (oder gleiche eine Klasse, wenn man die Elemente ändern möchte).
Ad Dictionary: Ich denke schon, dass da ein Dict her sollte, weil sie hat eben ein Mapping in eine Richtung (Spieler->Punktestand). Wenn es da jetzt Probleme mit dem Shuffeln gibt, könnte man einfach die ``.keys()`` nehmen und die dann eben randomisieren (vorausgesetzt es kommen im Laufe des Spieles keine weiteren Spieler dazu).
Modul: Das habe ich empfohlen zu Lernzwecken. Pragmatisch gesehen macht es natürlich bei so wenig Code keinen Sinn, das auszulagern. Alledings hatte sie Schwierigkeiten, Benutzerinteraktion und Spiellogik zu trennen, und da ist ein Modul doch ein ganz gutes "Werkzeug", eben weil man gezwungen wird, das Ganze schön zu trennen.
Anstatt den imo hässlichen itemgettern würde ich dann lieber ein ``collections.namedtuple`` nehmen (oder gleiche eine Klasse, wenn man die Elemente ändern möchte).
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Hehe... naja "gegen" klingt jetzt imho negativ!Dauerbaustelle hat geschrieben:@Hyperion: Sowohl Dictionary als auch separates Modul waren meine Idee. Die Diskussion muss also gegen mich gerichtet sein![]()

Das war dann ja auch mein erster Vorschlag. Allerdings sehe ich hier den Einsatz von Mappings eher begrenzt. Richtig wertvoll werden diese imho erst dann, wenn man öfter ein Objekt über einen Key finden muss. Dieses "finden" ist hier ja ziemlich unnötig, weil man über eine Spielerdatenstruktur iteriert und damit das Objekt direkt vorliegen hat. Insofern kann man hier auch auf eine Liste von Listen oder Dicts zurückgreifen und spart sich damit beim randomisieren die separate Liste von Keys. Aber ok, geht damit ja auchDauerbaustelle hat geschrieben: Ad Dictionary: Ich denke schon, dass da ein Dict her sollte, weil sie hat eben ein Mapping in eine Richtung (Spieler->Punktestand). Wenn es da jetzt Probleme mit dem Shuffeln gibt, könnte man einfach die ``.keys()`` nehmen und die dann eben randomisieren (vorausgesetzt es kommen im Laufe des Spieles keine weiteren Spieler dazu).

encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert