Python/ Übungen/ SchereSteinPapier/ Lösung

Aus Wikibooks

Eine mögliche Lösung zur Übung Schere, Stein, Papier:

"""Schere Stein Papier"""
import random

print("Willkommen zu Schere Stein Papier!")

gesten = ["Schere", "Stein", "Papier"]
computer_geste = random.choice(gesten)

spieler_geste = None
while spieler_geste not in gesten:
    print("Verfügbare Gesten: ", *gesten)
    spieler_geste = input("Bitte wählen Sie eine Geste aus: ")

print(f"Sie haben {spieler_geste} gewählt, der Computer {computer_geste}: ", end="")
if spieler_geste == computer_geste:
    print("Unentschieden!")
elif (
    (spieler_geste == "Schere" and computer_geste == "Papier")
    or (spieler_geste == "Stein" and computer_geste == "Schere")
    or (spieler_geste == "Papier" and computer_geste == "Stein")
):
    print("Sie haben gewonnen!")
else:
    print("Leider verloren")

Anmerkungen[Bearbeiten]

Generell: Der Spielinhalt, also die Gesten, ist hier als Liste vercodet. Auch möglich wäre ein dict: gesten = {1:"Stein", 2:"Schere", 3:"Papier"} um intern mit Zahlen rechnen zu können.

Zeile 2: Für die Zufallsauswahl müssen wir das Modul random importieren (wir könnten uns natürlich auch auf .choice beschränken um nicht unnötig viel zu importieren).

Zeile 14: Wir nutzen end='' um den Zeilenumbruch zu unterdrücken. Damt wird das Ergebnis direkt hinter den "Auswahlsatz" gedruckt

Zur Validierung: Das spannende an Schere, Stein, Papier ist die intransitive Relation, d.h. aus "Stein ist besser als Schere, Papier ist besser als Stein" folgt nicht "Papier ist besser als Stein". Diese Logik umzusetzen (engl. "mapping") macht es zu einer spannenden Übung. Die obige Lösung ist quasi "brute-force" indem wir alle Möglichkeiten für den Spieler zu gewinnen, händisch vercoden. Für Sie als Anfänger möglicherweise nicht gleich klar: 1) Grundlage der Prüfungen sind die drei möglichen Ergebnisse (gewonnen/unentscheiden/verloren) die entsprechend zu drei verschiedenen Code-Zweigen führen. Gruppieren Sie Ihre Abfragen bitte immer unter diesem Aspekt. 2) Wir brauchen nur zwei Prüfungen (nämlich auf unentschieden, als die leichteste; und auf gewonnen mit drei Bedingungen mit geweils zwei Vergleichen) denn das dritte Ergebnis (der Spieler hat verloren) ist der logische Schluss aus den beiden Prüfungen.

Die Lösung lässt sich auch als modulo-Abfrage schreiben: ((gesten.index(spieler_geste) + 1) - (gesten.index(computer_geste) + 1)) % 3 == 1

Bonusaufgabe[Bearbeiten]

"""Schere Stein Papier - Bonusaufgaben"""
import random

print("Willkommen zu Schere Stein Papier!")

gesten = ["Schere", "Stein", "Papier"]

weiterspielen = True

punkte_Spieler = 0
punkte_Computer = 0

while weiterspielen:

    computer_geste = random.choice(gesten)
    
    spieler_geste = None
    while spieler_geste not in gesten:
        print("Verfügbare Gesten: ", *gesten)
        spieler_geste = input("Bitte wählen Sie eine Geste aus: ")
        
    print(f"Sie haben {spieler_geste} gewählt, der Computer {computer_geste}: ", end="")
    if spieler_geste == computer_geste:
        print("Unentschieden!")
    elif (
        (spieler_geste == "Schere" and computer_geste == "Papier")
        or (spieler_geste == "Stein" and computer_geste == "Schere")
        or (spieler_geste == "Papier" and computer_geste == "Stein")
    ):
        print("Sie haben gewonnen!")
        punkte_Spieler += 1
    else:
        print("Leider verloren")
        punkte_Computer += 1
    print(f"Sie: {punkte_Spieler} -- Der Computer: {punkte_Computer}")

    if input("Weiterspielen (j/n)? ") == "n":
        weiterspielen = False
print(f"Endstand! Sie: {punkte_Spieler} -- Der Computer: {punkte_Computer}")

Bonusanmerkungen[Bearbeiten]

Wir brauchen garnicht viel zu ändern, um Ihnen den unbegrenzten Spielspaß mit Schere, Stein, Papier zu ermöglichen.

Zeile 8 und 13: wir nutzen eine while-Schleife um mehrere Spiele zu ermöglichen. Dabei wird alles zwischen den Zeilen 15 und 38 immer wieder wiederholt. Der Unterschied zu while True:: wir können die Wiederholungen elegant stoppen, da wir die Variable ändern können. Ansonsten bleibt nur, dass Programm komplett zu beenden. Diese Nutzung einer while-Schleife wird auch als game-loop (englisch "Spiel-Schleife") bezeichnet, da sie typischerweise in Spielen genutzt wird.

Zeile 10 und 11: Anfangs haben beide Spieler null Punkte. Wir müssen die 0 vor der while-Schleife zuweisen, damit die Punkte nicht mit jedem Durchlauf wieder auf Null gesetzt werden (beliebter Fehler!). Anders gesagt: wir müssen alle Startbedingungen, also alle einmaligen Bedingungen, vor dem Start der game-loop setzen!

Zeile 31 und 34: Das eigentliche Punktezählen ist trivial: da wir für jeden Spieler nur einen Programmzweig haben, in dem dieser einen Punkt erzielt, brauchen wir auch nur an zwei Stellen die Punkte zu erhöhen.

Zeile 37 und 38: Die Abfrage hier ist ewas geschummelt (getreu dem Gedanken: "Nerv den Nutzer nicht, wenn er gerade Spaß hat"), da wir alles außer "n" als "weiterspielen" werten. Sie können natürlich auch korrekt prüfen!

Zeile 39: Dient dazu, Ihnen den Bereich der game-loop deutlicher zu machen und Ihnen zu zeigen, dass Sie das Spiel nicht sang- und klanglos beenden müssen.

Expertenaufgabe[Bearbeiten]

"""Schere Stein Papier - Expertenaufgabe"""
import random

print("Willkommen zu Schere, Spock, Echse, Stein, Papier!")

gesten = ["Schere", "Spock", "Echse", "Stein", "Papier"]

weiterspielen = True

punkte_Spieler = 0
punkte_Computer = 0

while weiterspielen:

    ergebnis = ""
    computer_geste = random.choice(gesten)
    
    spieler_geste = None
    while spieler_geste not in gesten:
        print("Verfügbare Gesten: ", *gesten)
        spieler_geste = input("Bitte wählen Sie eine Geste aus: ")
    print(f"Sie haben {spieler_geste} gewählt, der Computer {computer_geste}: ", end="")
    
    if spieler_geste == computer_geste:
        ergebnis = "Unentschieden!"
    elif gesten.index(spieler_geste) % 2 == gesten.index(computer_geste) % 2:
        gewonnen = min(gesten.index(spieler_geste), gesten.index(computer_geste))
    else:
        gewonnen = max(gesten.index(spieler_geste), gesten.index(computer_geste))
        
    if ergebnis != "Unentschieden!":
        if gewonnen == spieler_geste:
            ergebnis = "Sie haben gewonnen!"
            punkte_Spieler += 1
        else:
            ergebnis = "Leider verloren"
            punkte_Computer += 1            

    print(ergebnis)        
    print(f"Sie: {punkte_Spieler} -- Der Computer: {punkte_Computer}")

    if input("Weiterspielen (j/n)? ") == "n":
        weiterspielen = False
print(f"Endstand! Sie: {punkte_Spieler} -- Der Computer: {punkte_Computer}")

Zu guter Letzt[Bearbeiten]

Schlußendlich will ich Ihnen diese, fast schon philosophische, Lösung nicht vorenthalten:

import random

print(random.choice(["Du gewinnst", "Du verlierst", "Unentschieden"]))