Suche Hilfe bei meinem Code!

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
FinjaS
User
Beiträge: 4
Registriert: Montag 27. Februar 2017, 18:28

Hallo Leute,
ich habe heute mit Python angefangen und habe schon einen Taschenrechner geschrieben der funktioniert!
Jetzt habe ich ein Schere, Stein, Papier-Spiel geschrieben, aber das Fenster schließt sich sofort wenn ich es öffne.

Hoffe jemand kann mir helfen, hier der Code:

Code: Alles auswählen

import random
random.seed()

runden = 0
sollrunden = "start"
standspieler = 0
standpc = 0

def spiel():
        print("Sie haben folgende Möglichkeiten:")
        print("\"s\" für Schere")
        print("\"r\" für Stein")
        print("\"p\" für Papier")

        spielerwahl = input("Was nehmen sie? ")

        if spielerwahl = "s":
                if pcwahl = 0:
                        print("Sie haben beide Schere gewählt!")
                elif pcwahl = 1:
                        print("Der Stein des PCs stumpft ihre Schere!")
                        standpc += 1
                elif pcwahl = 2:
                        print("Ihre Schere schneidet das Papier des PCs!")
                        standspieler += 1
                else:
                        alert("Es gibt einen Fehler im Programm!")
                        
        elif spielerwahl = "r":
                if pcwahl = 0:
                        print("Ihr Stein stumpft die Schere des PCs!")
                        standspieler += 1
                elif pcwahl = 1:
                        print("Sie haben beide Stein gewählt!")
                elif pcwahl = 2:
                        print("Das Papier des PCs rollt ihr Stein ein!")
                        standpc += 1
                else:
                        alert("Es gibt einen Fehler im Programm!")
                        
        elif spielerwahl = "p":
                if pcwahl = 0:
                        print("Die Schere des PCs schneidet ihr Papier!")
                        standpc += 1
                elif pcwahl = 1:
                        print("Ihr Papier rollt den Stein des PCs ein!")
                        standspieler += 1
                elif pcwahl = 2:
                        print("Sie haben beide Papier gewählt!")
                else:
                        alert("Es gibt einen Fehler im Programm!")

        else:
                print("Ungültige Eingabe!")
                continue

while not sollrunden.isdigit():
        sollrunden = input("Wie viele Runden sollen gespielt werden?\n")
        
        if not sollrunden.isdigit():
                print("Bitte eine Zahl eingeben!\n")
                continue

while runden < int(sollrunden):
        runden += 1
        pcwahl = random.randint(0, 2)
        print("\nRunde " + str(runden) + " von " + str(sollrunden) + ".")
        
        if standspieler < standpc:
                verg = "für den PC!"
        elif standspieler == standpc:
                verg = ". Sie sind gleichauf mit dem PC!"
        elif standspieler > standpc:
                verg = "für sie!"
        print("Es steht " + str(standspieler) + ":" + str(standpc) + verg)

        spiel()

if standspieler == standpc:
        unentschieden = input("Es steht unentschieden! Soll eine Entscheidungsrunde gespielt werden? \"j\" für Ja, \"n\" für Nein.")

        if unentschieden = "n":
                alert("Das Spiel geht nach " + str(sollrunden) + " Runden unentschieden aus!")

        elif unentschieden = "j":
                spiel()

        else:
                alert("Es gibt einen Fehler im Programm!")

elif standspieler < standpc:
        alert("Sie haben nach " + str(sollrunden) + " Runden " + str(standspieler) + ":" + str(standpc) + " verloren!")

else:
        alert("Sie haben nach " + str(sollrunden) + " Runden " + str(standspieler) + ":" + str(standpc) + " gewonnnen!")
Zuletzt geändert von Anonymous am Montag 27. Februar 2017, 18:58, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das deutet auf einen Fehler hin, und ich sehe eine Reihe: du benutzt zB nur ein einfach Gleich (=) fuer Vergleiche - da brauchst du aber ein doppeltes (==).

Und dein Folgeproblem - das schliessende Fenster - ist eine unschoene Eigenart von Windows, bzw. der Art, wie du dein Programm startest.

Statt Doppelklick auf eine Datei solltest du lieber eine Eingabeaufforderung oeffnen, und von dort dein Programm per

python.exe meinscript.py

starten. Dann siehst du, was schief geht.
FinjaS
User
Beiträge: 4
Registriert: Montag 27. Februar 2017, 18:28

Ah, ok danke.

Was heißt das?

Traceback (most recent call last):
File "C:\Users\Finja\Desktop\ssp.py", line 76, in <module>
spiel()
File "C:\Users\Finja\Desktop\ssp.py", line 37, in spiel
standpc += 1
UnboundLocalError: local variable 'standpc' referenced before assignment
BlackJack

@FinjaS: Das heisst Du versuchst 1 zum Wert von `standpc` zu addieren, wozu `standpc` aber vorher irgendwann einmal einen Wert zugewiesen bekommen haben muss, denn sonst weiss Python ja nicht *zu was* 1 addiert werden soll. Wenn man eine Zuweisung innerhalb einer Funktion vornimmt, und dazu gehört auch ``+=``, dann ist der Name *lokal* in der Funktion. Das ist also ein anderes `standpc` als das auf Modulebene, das nur solange da ist wie die Funktion abgearbeitet wird.

Die Variablen auf Modulebene haben dort aber auch gar nichts zu suchen. Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. Und Funktionen (und Methoden) sollten nur auf Werte zugreifen (ausser Konstanten) die als Argumente übergeben wurden, und Ergebnisse als Rückgabewerte an den Aufrufer zurückgeben.

Zwei Dinge die Du einfach rauslöschen solltest sind der `random.seed()`-Aufruf und alle ``continue``-Anweisungen. Der `seed()`-Aufruf ist nicht nötig, und kann unter bestimmten Umständen sogar für weniger zufällige Zufallswerte sorgen. Und die ``continue``-Anweisungen sind allesamt dort wo sie stehen ohne beobachtbaren Effekt. Zudem kann das vorhandensein von ``continue`` ein paar Einschränkungen zur Folge haben wenn man den Code weiterentwickelt, und es ist ein eher versteckter Sprung zum Schleifenanfang den man nicht an der Einrückstruktur erkennen kann. Es gibt fast immer einen Weg des Code so zu strukturieren das man kein ``continue`` benötigt.
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na, eigentlich ist die Fehlermeldung doch recht klar: du referenzierst eine Variable, bevor die existiert. Das wird etwas klarer, wenn du den entsprechenden Ausdruck mal "richtig" hinschreibst:

Code: Alles auswählen

standpc = standpc + 1
Bevor es zu der Zuweisung kommen kann, wird zuerst die rechte Seite ausgefuehrt. Wenn man das isoliert betrachtet, oder du zB hinschreibst

Code: Alles auswählen

pillepalle = standpc + 1
klappt es auch. Brauchst du nur so nicht. Warum also meckert Python? Python kennt keine explizite Variablendeklaration, wie in anderen Sprachen (zb C) gebraeuchlich. Das heisst du musst nicht etwas in der Art schreiben

Code: Alles auswählen

def meine_funktion():
     var standpc
     ...
Damit waere klar, dass standpc eine lokale variable innerhalb von "meine_funktion" ist, und wenn das *fehlt*... ist es etwas anderes.

Stattdessen behilft sich Python anders: wann immer es einen Ausdruck sieht innerhalb einer Funktion der so aussieht

Code: Alles auswählen

<name> = ...
merkt es sich, dass <name> eine in dieser Funktion lokale Variable ist. Das passiert implizit, und *BEVOR* der code irgendwie gelaufen ist.

Und jetzt wird auch klar, warum der Ausdruck oben nicht geht: standpc ist durch die Gestalt deines Ausdrucks auf der linken Seite eines Gleichheitszeichens als "lokal" markiert worden. Und jetzt hast du aber einen Ausdruck auf der rechten Seite, der diese Variable, die jetzt erst angelegt werden soll, schon referenziert. Das klappt halt nicht.

Was du hier willst (auch wenn es generell verpoent ist, aber das ist eine andere Diskussion), ist standpc explizit als global zu markieren.

Code: Alles auswählen

def meine_funktion():
      global standpc
      standpc += 1
Damit hast du Python mitgeteilt, dass es standpc nicht lokal definieren soll, sondern aus dem umgebenden globalen Modul-Scope nehmen soll.
Antworten