Mastermind. Ein erster geh Versuch mit Python

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
Caliban
User
Beiträge: 2
Registriert: Freitag 18. Juni 2010, 10:58

Hallo, ich möchte mich hier im Forum gleich mit einem Code vrostellen.
Habe vor etwas mehr als einer Woche begonnen mich mit Pyhton zu beschäftigen und wollte das gelernt mal ein wenig in die Tat umsetzten. Herausgekommen ist dabei eine einfache Version von Mastermind.

Vielleicht kanns wer brauchen. Würde mich aber auch sehr über Kritik in jeder Form freuen.

http://www.python-forum.de/pastebin.php?mode=view&s=36
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Beim ersten überfliegen fällt auf, dass du dir mal PEP-8 anschauen solltest.

Und du solltest ifmain benutzen :).
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Und die beiden inneinander verschachtelten "while True"-Schleifen würde ich in jeweils eine Funktion packen. So sieht das irgend wie unhandlich aus. Letztlich sind es ja auch zwei Funktionalitäten.

Interessant wäre es zudem, alle möglichen Paarungen zu erlauben (also Mensch - KI, Mensch-Mensch & KI-KI). Das ist imho ein schönes Lernbeispiel für "Funktionen sind auch Objekte".

Dazu noch Konfiguration per Kommandozeilenparameter und schon hat man ein rundes Gesamtpaket geschaffen :-)

@Code: Die Klasse "mastermind" ist imho obsolet. Das kann man genauso gut mit Funktionen realisieren - zumindest in der derzeitigen Form.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Du kannst dir bei dem Mehrzeiligen String die ganzen Backslashes sparen, wenn du ihn in drei Anfuehrungszeichen setzt:

Code: Alles auswählen

print """hallo
welt"""
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Ich hab das überarbeitbare Design so gelassen und ein paar Sachen verändert: http://paste.pocoo.org/show/226893/

Du könntest für jede Runde ein neues MasterMind objekt erstellen und damit dann arbeiten.


grr, was vergessen: http://paste.pocoo.org/show/226894/
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
BlackJack

Caliban: Als erstes fällt die Namensgebung ins Auge die nicht dem Style-Guide entspricht.

Die `MasterMind`-Objekte hätte ich nicht wiederverwendbar entworfen. Neues Spiel -- neues Objekt. Bei Objekten die man "reset"ten kann, muss man einfach auf mehr aufpassen, wenn man sie irgendwann einmal erweitern möchte. Alles was neu dazu kommt, muss bei einem Rücksetzen potentiell auch berücksichtigt werden und kann vergessen werden. Farben und Länge könnte man als Argumente der `__init__()` übergeben. Mit Default-Werten damit man es nicht *muss*, aber die Möglichkeit wäre ganz nett und auch unkompliziert und einfach zu realisieren.

Der `random.seed()`-Aufruf ist überflüssig. Das wird schon beim importieren des `random`-Moduls gemacht, ein weiterer Aufruf hat "statistisch" keinen Effekt. Dafür bietet das `random`-Modul praktische Funktionen die den Code wesentlich vereinfachen können. Das Erzeugen des Geheimcodes lässt sich recht kompakt in einer Zeile ausdrücken:

Code: Alles auswählen

    return ''.join(random.choice(self.farben) for _ in xrange(self.laenge))
Wobei das Längenattribut eigentlich unnötig sein sollte, denn spätestens wenn der Code festgelegt ist, kann man die Länge aus dem Code ermitteln -- die Information ist also redundant.

Die `_check()`-Methode liesse sich mit einem `set()` ausdrücken:

Code: Alles auswählen

        return (len(code) == len(self.code)
                and len(set(code).difference(self.farben)) != 0)
Bei `Raten()` sind die Namen nicht gut gewählt. Weder `Weisz`, `Schwarz` und noch weniger `List1`, `List2` sagen etwas über die Bedeutung der Objekte hinter den Namen aus. Der Code ist teilweise auch nicht so einfach zu durchschauen und verwendet mehr Indexe als er müsste. Die Anzahl der richtigen Farben auf der richtigen Position lässt sich zum Beispiel ganz einfach ausdrücken:

Code: Alles auswählen

        schwarz = sum(a == b for a, b in zip(self.code, code))
Das Hauptprogramm auf Modulebene sollte noch in einer Funktion verschwinden und über folgendes Idiom aufgerufen werden, damit man das Modul für die verschiedensten Zwecke auch importieren kann, ohne dass das Programm gleich ausgeführt wird:

Code: Alles auswählen

if __name__ == '__main__':
    main()
Warum heisst das Exemplar von `MasterMind` denn `KI`? Ich sehe da keine "Intelligenz"?

Statt des ``continue`` bei einer Fehleingabe in der inneren ``while``-Schleife hätte ich den folgenden Quelltext eher in einen ``else``-Zweig gesteckt. So ein ``continue`` ist eine "Sprunganweisung" die den Quelltext etwas schwerer durchschaubar macht.

Das Ergebnis von `raten()` hätte man dort auch an zwei sprechende Namen binden können statt im Weiteren auf ``ergebnis[0]`` und ``ergebnis[1]`` zuzugreifen.
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Freut mich gerade, dass ich fast alle Sachen, die BlackJack angesprochen hat umgesetzt hatte :)


@BJ: random.choice ist glaube ich nicht richtig, da man jede Farbe nur einmal nehmen darf.


Das mit dem set.difference kannte ich noch gar nicht.

Edit: Warum eigentlich der Umweg über die Länge des Sets?
Zuletzt geändert von jbs am Samstag 19. Juni 2010, 15:41, insgesamt 1-mal geändert.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

jbs hat geschrieben:@BJ: random.choice ist glaube ich nicht richtig, da man jede Farbe nur einmal nehmen darf.
Ich habe mein Spiel nicht hier, aber wir spielen immer so wie BlackJack. Die Farbwahl einzuschraenken macht das Spiel natuerlich einfacher und ich glaube, solche Varianten werden in der Anleitung auch vorgeschlagen. Das koennte man natuerlich in das Programm mit einbauen. :)
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
BlackJack

@jbs: Ausser in sehr einfachen Fällen finde ich das implizite verwenden des Wahrheitswertes nicht so toll. Hier wäre das IMHO ziemlich undurchsichtig für jemanden der das nicht kennt und man kann wenn man es nicht versteht, auch schlecht gezielt danach in der Dokumentation suchen.
Caliban
User
Beiträge: 2
Registriert: Freitag 18. Juni 2010, 10:58

Ich möchte mich mal bei allen bedanken für die vielen Tipps und Hinweise.
Am Montag hab ich dann wieder mehr Zeit und werde das dann nochmal genauer durcharbeiten.
Antworten