Seite 1 von 1

Einfaches Schere,Stein,Papier Spiel

Verfasst: Mittwoch 8. Juni 2011, 20:49
von derrick
Hallo Leute,
es geht um ein einfaches Schere,Stein,Papier Spiel dessen Code ihr hier findet.
http://www.python-forum.de/pastebin.php?mode=view&s=193
Ich bin leider ein blutiger Programmieranfänger und freue mich daher über jeden Tipp
der den Code eleganter und das Programm stabiler macht.
Gültige Eingaben sind r,p oder s.

derrick

Re: Einfaches Schere,Stein,Papier Spiel

Verfasst: Mittwoch 8. Juni 2011, 21:06
von numerix
Da könnte man einiges zu sagen. Ich beschränke mich mal auf den Hinweis, dass return eine Anweisung und keine Funktion ist und infolgedessen ohne Klammern auskommt. Die Ermittlung des Gewinnners lässt sich erheblich kürzer fassen, etwa so:

Code: Alles auswählen

def winner(comp,user):
    if comp == user:
        return "draw"
    elif user+comp in ["rs","pr","sp"]:
        return "user"
    return "comp"

Re: Einfaches Schere,Stein,Papier Spiel

Verfasst: Mittwoch 8. Juni 2011, 21:15
von /me
derrick hat geschrieben:es geht um ein einfaches Schere,Stein,Papier Spiel dessen Code ihr hier findet.
http://www.python-forum.de/pastebin.php?mode=view&s=193
Ich bin leider ein blutiger Programmieranfänger und freue mich daher über jeden Tipp
der den Code eleganter und das Programm stabiler macht.
Gültige Eingaben sind r,p oder s.
Na dann fangen wir doch genau da an. Du hast die Eingabe sehr schön in die Funktion get_userinput gepackt. Es wäre sicher sinnvoll, in dieser Funktion dann auch zu überprüfen, ob ein gültiger Buchstabe eingegeben wurde. Ich habe ein "a" eingegeben und das Programm hat mich nicht zur Neueingabe aufgefordert und hat auch beim Vergleich nicht gemerkt, dass der Wert "a" eigentlich nicht vorkommen darf. Statt dessen hatte ich das Spiel verloren - und das wo "a" (Atom bomb) ja nun wirklich eigentlich alles schlägt.

In compare_input sehe ich sehr viele Aufrufe von show_result(). Den könnte man ein einziges Mal am Ende ausführen. Eigentlich würde ich das Ergebnis überhaupt nicht aus der Vergleichsfunktion heraus anzeigen.

show_result lügt - zumindest vom Namen der Funktion her. Es zeigt nicht nur Resultate sondern rechnet auch noch. Es rechnet vor allem anhand eines Textes, der in erster Linie für die Ausgabe relevant ist. Eine Übersetzung der Ausgabetexte in eine andere Sprache oder auch nur die minimale Veränderung eines in compare_input definierten Ausgabetextes würde plötzlich falsche Ergebnisse erzeugen. Hier muss eine andere Lösung her und bei der Gelegenheit sollte man auch direkt die globals entsorgen.

Allgemein noch zum Code: Bei Rückgaben mit return solltest du die folgenden Klammern weglassen.

Re: Einfaches Schere,Stein,Papier Spiel

Verfasst: Mittwoch 8. Juni 2011, 22:01
von /me
Mal auf die Schnelle ein paar kleine Veränderungen: http://www.python-forum.de/pastebin.php?mode=view&s=194. Man muss sich immer so zügeln, sonst entsteht gleich wieder ein Moloch der dann richtig ausgefuchst ist - und mit dem ein Anfänger nichts anfangen kann.

Mit dieser Variante ist es auf jeden Fall leichter möglich "Stein, Schere, Papier" durch "Stein, Schere, Papier, Spock, Echse" zu erweitern.

Re: Einfaches Schere,Stein,Papier Spiel

Verfasst: Mittwoch 8. Juni 2011, 22:10
von Hyperion
Man könnte auch noch einen "Computer vs. Computer" / "Mensch vs. Mensch"-Modus einbauen, indem man die Input-Funktionen übergibt bzw. den Code dafür auslegt, dass die Funktionen übergeben werden. Ich hatte das vor olims Zeiten mal in einem kleinen Script für das Ziegenproblem angewendet (Code ist nicht PEP8 konform!).

Dieses Spielchen ist nebenbei auch immer ein schönes Beispiel für eine nicht transitive Ordnung - schade, dass viele Lehrkräfte so etwas anschauliches nicht als Beispiel in diesem Kontext bringen. Ist bei mir zumindest nie vorgekommen ;-)

Re: Einfaches Schere,Stein,Papier Spiel

Verfasst: Mittwoch 8. Juni 2011, 22:43
von pillmuncher
/me hat geschrieben:Man muss sich immer so zügeln, sonst entsteht gleich wieder ein Moloch der dann richtig ausgefuchst ist - und mit dem ein Anfänger nichts anfangen kann.
Du meinst sowas, oder? Den etwas fortgeschritteneren kann man damit immerhin zeigen, dass man oft auch ganz ohne if-Statement auskommen kann.

Gruß,
Mick.

Re: Einfaches Schere,Stein,Papier Spiel

Verfasst: Mittwoch 8. Juni 2011, 22:56
von Hyperion
pillmuncher hat geschrieben:Du meinst sowas, oder? Den etwas fortgeschritteneren kann man damit immerhin zeigen, dass man oft auch ganz ohne if-Statement auskommen kann.
Nice :-)

So, ich denke der Thread hat das Potenzial für Lösungen in verschiedenen Sprachen! Wer zeigt die erste Scheme / Lisp-Lösung? :mrgreen:

Re: Einfaches Schere,Stein,Papier Spiel

Verfasst: Donnerstag 9. Juni 2011, 15:28
von derrick
Danke euch für euren Code!
Hab mir jetzt einiges abgeschaut und die Eingaben werden auch geprüft.
Das mit der Matrix ist genial, habe es aber mal mit numerix Vorschlag gemacht,
auch wenn das dann schwerer zu erweitern ist.
Also hier ist der neue Code(http://www.python-forum.de/pastebin.php?mode=view&s=196).
Was haltet ihr davon?

Re: Einfaches Schere,Stein,Papier Spiel

Verfasst: Freitag 10. Juni 2011, 11:08
von Hyperion
Also mal ein paar Anmerkungen:

- In Zeile 11 hast Du ein Klammerpaar zu viel

- `return` ist in Python ein Statement und keine Funktion; also solltest Du das nicht klammern (Zeilen 12 & 17)

- Operatoren sollten immer durch Leerzeichen getrennt werden (außer innerhalb von Funktionsaufrufen):

Code: Alles auswählen

# falsch
score['human']+=1
# richtig
score['human'] += 1
- die Funktion `get_computerinput` kann man einfacher fomulieren:

Code: Alles auswählen

def get_computer_input():
    return random.choice('rps')
Das Binden an eine lokale Variable ist hier unnötig, da der Name nur für das return-Statement aufgegriffen wird. Faustregel ist dabei (imho), dass man Objekte nur dann an Namen bindet, wenn man diesen Namen auch wirklich benötigt.

- in der Funktion `get_userinput` fände ich eine Fehlermeldung gut, wenn der Benutzer ein falsches Zeichen eingibt.

- Du verwendest `allowed_input` nicht konsequent (`get_computerinput`); damit ist der Vorteil einer globalen Definition quasi dahin ;-)

- in `show_winner` empfinde ich die Leerzeilen als störend.

- Shebang und Kodierungsangabe fehlen - muss natürlich nicht sein, aber bei einem "kompletten" Script gehört das imho dazu.

- Den Code ab Zeile 46 würde ich von Modulebene wegnehmen und in eine Funktion packen. Diese kann man dann über eine `main`-Funktion aufrufen.

Code: Alles auswählen

def main_loop():
    win_score = get_winscore()
    # ...

def main():
    # sys.args parsen o.ä.
    main_loop()

if __name__ == "__main__":
    main()
Darüber hinaus würde ich als nächsten Schritt weg vom statischen Mensch vs. Computer und die Funktionen aus der neuen `main`-Funktion an die `main_loop`-Funktion übergeben. Damit hast Du einfach zwei Funktionen, die die Entscheidung eines Spielers ermitteln - ob das nun ein Mensch ist, oder der PC oder eben zwei Menschen ist ja für das Spiel (also die Auswertung, das Scoring usw) egal.

Falls Du das noch nicht gesehen hast, verweise ich noch mal auf meinen obigen Post und das dort verlinkte Script. Du kannst Funktionen - wie jedes Objekt in Python - an einen Namen binden oder als Parameter übergeben.

Code: Alles auswählen

In [11]: def foo():
   ....:     print "Hallo"
   ....:     
   ....:     

In [12]: def bar():
   ....:     print "Ciao"
   ....:     
   ....:     

In [13]: def logic(func):
   ....:     func()
   ....:     
   ....:     

In [14]: logic(foo)
Hallo

In [15]: logic(bar)
Ciao

In [16]: f = foo

In [17]: f()
Hallo
Du brauchst also keine komplizierte Logik, um zu prüfen, welche Funktion Du für einen Spieler aufrufen musst, sondern übergibst einfach die gewünschte(n) Funktion(en) an Deine Spiellogik-Funktion und gut ist.

Die Namen `user_input` und `computer_input` passen dann natürlich nicht mehr; könnte man dann neutral `user_a` und `user_b` nennen¹ oder in eine Liste / Dict verpacken. Da Du ja bereits ein `score`-Dict hast, könnte man das um die Funktion erweitern? Ich würde dann noch `argparse` nutzen, um den `winscore` optional übergeben zu können und vor allem die Funktionen, welche die beiden Spielereingaben bestimmen.

Re: Einfaches Schere,Stein,Papier Spiel

Verfasst: Montag 13. Juni 2011, 10:50
von BlackJack
Vielleicht passend zum Thema: Schere, Stein, Papier Programmierwettbewerb.