Python Programm (Schere, Stein, Papier) funktioniert nicht, (hab die frage nochmal gestellt weil man den Code nicht lesen konnte)?

4 Antworten

Es gibt einerseits Einrückungsfehler wie ja auch schon von Gameolputty angemerkt wurde bzgl. der Einrückung der return-Anweisungen und anderseits gibt es auch logische Fehler bei den if/elif-Statemens in der while-Schleife.

Ich bin nicht jede einzelne durchgegangen, aber bei den ersten Anweisungen kann man direkt einen logischen Fehler erkennen.

Du überprüfst da folgendes:
Im ersten if-Statement prüfst du: Falls der Nutzer r eingibt und der Computer r wählt, gib unentschieden raus. Soweit so gut.
Die folgenden Statements machen keinen Sinn, denn dort printest du unentschieden, unabhängig von der Wahl des Computers.

Mir ist auch ein Rätsel wieso du überprüfst, ob user_choice, bzw. user_choice gleich den Strings "sc", "st", etc. ist. Denn beide Funktionen geben nur "p", "r", oder "s" zurück.

Ich würde den Part mit den if/elif-Anweisungen nochmal komplett neu schreiben und da eine gewisse Struktur reinbringen (z.B. erstmal nur den user-input "p" abhandeln, dann "r", dann "s"). Denn so kannst du nur den "Zustand" unentschieden erreichen.


lilZeal 
Fragesteller
 28.03.2020, 16:21

Ich habs gefixt, ich hab einfach nen denkfehler gehabt, danke!

1

Du hast im Wesentlichen fünf größere semantische Fehler:

  1. Indentation: Sowohl Choose_Option(...), als auch Computer_Option(...) geben jeweils nur im else-Block einen Wert zurück (und sonst nichts!). Das ist sicher nicht, was du willst. Das return-Statement muss auf selber Höhe wie die if-Abfrage sein, damit immer etwas zurückgegeben wird. Analoges unten bei den Statistik-Ausgaben (die werden nur ausgeführt, wenn der letzte elif-Block betreten wird, du willst sie aber doch immer ausführen).
  2. Ungewollte Rekursion: In Choose_Option(...) und Computer_Option(...) rufst du die Methoden in sich selbst wieder auf. Der Gedanke dabei ist vermutlich, dass in dem Fall neu gewählt werden soll, was aber tatsächlich passiert, ist dass die Methoden ggf. nicht terminieren. Was du eigentlich willst: Die Choose_Option(...) soll bei einer invaliden Eingabe die Eingabe verwerfen und eine neue Eingabe erwarten. Bei der Computer_Option(...) verstehe ich selbst deinen Gedanken nicht, die Methode nochmal neu aufzurufen.
  3. randint(...): Die Methode randint(1, 3) gibt 1 oder 2 zurück, nie 3 (die obere Grenze ist exklusiv). Für eine zufällige 1, 2 oder 3 musst du randint(1, 4) aufrufen.
  4. if-Abfragen: In der while-Schleife möchtest du die Eingaben abfragen, vergleichen und damit einen Gewinner ermitteln. Stattdessen hast du aber eine einzelne if-Abfragen mit sehr vielen (teilweise redundanten) elif-Blöcken gebastelt.
  5. "st": Du prüfst unten auf den String "st". Den gibt es aber nie, sondern nur "r", "s" oder "p".

Was du eigentlich unten machen willst, ist doch das:

while True:
    print("")
    user_choice = Choose_Option()
    comp_choice = Computer_Option()
    print("")

    if user_choice == "r":
        if comp_choice == "s":
            print("Du hast gewonnen!")
            player_wins += 1
        elif comp_choice == "r":
            print("Unentschieden")
        elif comp_choice == "p":
            print("Du hast verloren!")
            comp_wins += 1
    elif user_choice == "p":
        if comp_choice == "r":
            print("Du hast gewonnen!")
            player_wins += 1
        elif comp_choice == "p":
            print("Unentschieden")
        elif comp_choice == "s":
            print("Du hast verloren!")
            comp_wins += 1
    elif user_choice == "s":
        if comp_choice == "p":
            print("Du hast gewonnen!")
            player_wins += 1
        elif comp_choice == "s":
            print("Unentschieden")
        elif comp_choice == "r":
            print("Du hast verloren!")
            comp_wins += 1

    print("")
    print("Du hast gewonnen: " + str(player_wins))
    print("Du hast verloren: " + str(comp_wins))
    print("")

    user_choice = input("Möchtest du nochmal spielen? (j/n)")
    if user_choice in ["j", "J", "JA", "ja", "Ja", "jA"]:
        pass
    elif user_choice in ["n", "N", "Nein","nein", "Nö", "nö", "ne", "Ne", "NE", "NÖ", "NEIN"]:
        break
    else:
        break

Schau dir die Einrückungen genau an: In jedem elif-Statement verbirgt sich nochmal ein if-elif-elif-Statement, das die User-Eingabe mit der Computer-Eingabe vergleicht.

Zur Choose_Option-Methode - wenn du wirklich auf invalide Eingaben prüfen willst, dann würde ich es so lösen:

def Choose_Option():
    user_choice = input("Rock, Paper oder Scissors: ")
    
    if user_choice in ["Rock", "rock", "r", "R"]:
        user_choice = "r"
    elif user_choice in ["Paper", "paper", "p", "P"]:
        user_choice = "p"
    elif user_choice in ["Scissors", "scissors", "s", "S"]:
        user_choice = "s"
    else:
        print("In Schere, Stein, Papier kann man nur Schere, Stein oder Papier nehmen du Kek.")
        return None
    
    return user_choice

Im Fall einer falschen Eingabe gibst du None zurück. Dann musst du aber natürlich oben in der while-Schleife nochmal prüfen, ob user_choice None ist - und falls ja mittels continue den aktuellen Schleifendurchlauf beenden und einen neuen starten. In der Computer_Option(...) muss einfach der Selbstaufruf raus. Dann funktioniert es.

Eine elegantere Alternative der Choose-Methoden:

def Choose_Option():
    user_choice = input("Rock, Paper oder Scissors: ")
    
    if user_choice in ["Rock", "rock", "r", "R"]:
        return "r"
    elif user_choice in ["Paper", "paper", "p", "P"]:
        return "p"
    elif user_choice in ["Scissors", "scissors", "s", "S"]:
        return "s"
    else:
        print("In Schere, Stein, Papier kann man nur Schere, Stein oder Papier nehmen du Kek.")
        return None

def Computer_Option():
    rand_index = random.randint(0, 3) # zufälligen Index 0, 1 oder 2
    choices = ["r", "p", "s"]
    # choices[0] = "r", choices[1] = "p", choices[2] = "s"
    
    return choices[randindex] # gibt "r", "p" oder "s" zurück

LG


lilZeal 
Fragesteller
 28.03.2020, 16:48

scheiße... so viel aufwand... DANKE!

1

Guck dir die return-Anweisung in Choose_Option() und Computer_Option() noch einmal näher an. Wann genau wird diese Anweisung ausgeführt?

Woher ich das weiß:Studium / Ausbildung – Abgeschlossenes Informatik-Studium

lilZeal 
Fragesteller
 28.03.2020, 15:53

Ich komm mir ein wenig blöd vor, ich habs zwar probiert, aber irgendwas funktioniert trotzdem nicht

0
Gambolputty  28.03.2020, 15:57
@lilZeal

In Python bestimmt die Einrückung einer Zeile, zu welchen Block die Zeile gehört. Die return-Anweisungen werden also nur im else-Fall jeweils aufgerufen. Das heißt, Choose_Option() zum Beispiel wird nie einen Wert zurückgeben.

1

Du musst die beiden Funktionen ausserhalb ihrer Definition aufrufen also z.B. mach dem while True

Woher ich das weiß:Hobby

lilZeal 
Fragesteller
 28.03.2020, 15:49

Ich kriegs trotzdem nicht hin, aber eigentlich sollte es jetzt funktionieren, ich meine der input in der funktion funktioniert, aber alles andere nicht

0