Moin zusammen,
also ich hab da ein kleines problem, ich wollte mir ein einfaches schere, stein, papier programm schreiben, ich hab angefangen und die GUI über Tkinter geschrieben, nach dem die fertig war hab ich sie getestet und siehe, da 3 Knöpfe und oben wird der Punkte stand in in Variablen angezeigt alles so wie es sein soll, ich schreib also die funktion das je nachdem für welches man sich entscheidet der gegner eine zufällige wahl trifft, dann sollte eine pop-up message kommen welche sagt ob du gewonnen verloren oder das gleiche gewählt hast und den punkte stand der variable dann ändern. als ich es testen wollte ist die konsole kurz aufgegangen und hat sich direkt wieder geschlossen und das wars, ich bekomm zwar die fehler meldung von wegen glaobal variable undefined module level aber ich kann damit nichts mehr wirklich anfangen.
Hier einmal mein Code:
from tkinter import *
from tkinter import messagebox
from tkinter.ttk import Notebook
import random
root = Tk()
root.wm_title("Schere, Stein, Papier")
root.config(background="#E0E0F8", width=50, height=50)
mypoint = 0
yourpoint = 0
genger = 0
def gewinner():
global mypoint
tkinter.messagebox.showinfo("Sieger", "Du hast Gewonnen!")
mypoint = mypoint + 1
def verlierer():
global yourpoint
tkinter.messagebox.showinfo("Verlierer", "Du hast Verloren!")
yourpoint = yourpoint + 1
def unentschieden():
tkinter.messagebox.showinfo("Unentschieden", "Ihr habt das gleiche gewählt!")
def sieger():
if wahl == 1:
if gegner == 1:
unentschieden()
if gegner == 2:
verlierer()
if gegner == 3:
gewinner()
if wahl == 2:
if gegner == 1:
gewinner()
if gegner == 2:
unentschieden()
if gegner == 3:
verlierer()
if wahl == 3:
if gegner == 1:
verlierer()
if gegner == 2:
gewinner()
if gegner == 3:
unentschieden()
def gegner():
global gegner
gegner = random.uniform(1, 3)
def schere():
global wahl
wahl = 1
sieger()
def stein():
global wahl
wahl = 2
sieger()
def papier():
global wahl
wahl = 3
sieger()
punkte = Label(root, text=str(mypoint) + " : " + str(yourpoint))
punkte.grid(row=0, column=1, padx=10, pady=5)
schere = Button(root, text="Schere", bg="#F78181", width=5, height=3, command=schere())
schere.grid(row=1, column=0, padx=8, pady=8)
stein = Button(root, text="Stein", bg="#F78181", width=5, height=3, command=stein())
stein.grid(row=1, column=1, padx=8, pady=8)
papier = Button(root, text="Papier", bg="#F78181", width=5, height=3, command=papier())
papier.grid(row=1, column=2, padx=8, pady=8)
root.mainloop()
ich sag dann schonmal Danke
Ich finde den Fehler nicht!
Bitte formatiere deinen Code auch als Code, er ist sonst unmöglich sinnvoll zu lesen. Ist dir das nach dem Abschicken des Posts nicht aufgefallen? Zum Formatieren gitbt es im Editor oberhalb des Editfeldes sogar einen Button der mit </> beschriftet ist.
-
- User
- Beiträge: 31
- Registriert: Samstag 16. Mai 2020, 18:52
Benutze bitte die Codetags.
random.uniform gibt eine Float Zahl aus. random.randint() wolltest du sicherlich benutzen,
aber das beste ist vermutlich random.choice(["Schere", "Stein", "Papier"]).
Und dann kann die Funktion diesen Wert mit return zurückgeben.
Abgesehen davon, dass die Sieger Funktion einen schlechten Namen hat, könntest du dort auch Elif und Else benutzen.
Du fragst in der Funktion ständig die Gegner Variable ab, aber nirgends wird sie verändert.
Ausserdem wäre es doch schlau, wenn du die Funktion mit der Spieler_Auswahl aufrufen würdest.
Am Ende der Funktion könnte stehen und es würde funktionieren.
Deine Buttons haben die selben Namen wie die Funktionen.
Und die Klammer muss entfernt werden bei Button(......command=....()), sonst wird die Funktion jedesmal sofort aufgerufen.
Hier noch etwas nützliches:
Code: Alles auswählen
def gegner():
global gegner
gegner = random.uniform(1, 3)
aber das beste ist vermutlich random.choice(["Schere", "Stein", "Papier"]).
Und dann kann die Funktion diesen Wert mit return zurückgeben.
Abgesehen davon, dass die Sieger Funktion einen schlechten Namen hat, könntest du dort auch Elif und Else benutzen.
Du fragst in der Funktion ständig die Gegner Variable ab, aber nirgends wird sie verändert.
Ausserdem wäre es doch schlau, wenn du die Funktion mit der Spieler_Auswahl aufrufen würdest.
Am Ende der Funktion könnte
Code: Alles auswählen
punkte.configure(text=f"{mypoint}:{yourpoint}")
Deine Buttons haben die selben Namen wie die Funktionen.
Und die Klammer muss entfernt werden bei Button(......command=....()), sonst wird die Funktion jedesmal sofort aufgerufen.
Hier noch etwas nützliches:
Code: Alles auswählen
WIN_CHOICES = {"Schere": "Papier", "Stein": "Papier", "Stein": "Schere"}
spieler_auswahl = "Papier"
computer_auswahl = "Schere"
if spieler_auswahl == computer_auswahl:
print("Unentschieden.")
else:
if WIN_CHOICES[spieler_auswahl] == computer_auswahl:
print("Spieler gewinnt.")
else:
print("Computer gewinnt.")
- pillmuncher
- User
- Beiträge: 1484
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Warum nicht so?
Code: Alles auswählen
if ...:
...
elif ...:
...
else:
...
In specifications, Murphy's Law supersedes Ohm's.
Bevor Du mit GUIs anfängst, solltest Du lernen, was Funktionen sind. Funktionen bekommen alles was sie brauchen über ihre Argumente und geben Ergebnisse per `return` zurück.
`global` hat in einem ordentlichen Programm nichts verloren.
Und drumrum kann man dann ein Programm aufbauen:
Wenn Du jetzt noch eine GUI draufsetzen willst, brauchst Du erstmal Kenntnisse in Klasse-Definitionen. Denn irgendwo mußt Du ja den Zustand (also hier die Punkte) speichern.
`global` hat in einem ordentlichen Programm nichts verloren.
Code: Alles auswählen
def ermittle_sieger(wahl, gegner):
if wahl == gegner:
return "unentschieden"
elif (wahl, gegner) in [(1,3), (2,1), (3,2)]:
return "gewonnen"
else:
return "verloren"
Code: Alles auswählen
def main():
mypoints = 0
yourpoints = 0
while True:
wahl = int(input("1: Schere\n2: Stein\n3: Papier\n>"))
gegner = random.randint(1,3)
ergebnis = ermittle_sieger(wahl, gegner)
print(ergebnis)
if ergebnis == "gewonnen":
mypoints += 1
else:
yourpoints += 1
print(f"Punkte: {mypoints}:{yourpoints}")
if __name__ == '__main__':
main()
Moin einmal ein kurzes update, bisher läuft alles auser das mit dem punkte zählen, wenn ich in der funktion winner das
und das
entferne läuft alles, ich verstehe aber nicht warum er wenn ich die variablen mypoint und yourpoint in der funktion global setze er mir die werte immernoch nicht speichert.
Code: Alles auswählen
mypoint = mypoint + 1
Code: Alles auswählen
yourpoint = yourpoint + 1
Code: Alles auswählen
from tkinter import *
from tkinter import messagebox
from tkinter.ttk import Notebook
import random
root = Tk()
root.wm_title("Schere, Stein, Papier")
root.config(background="#E0E0F8", width=50, height=50)
Win_Choice = {"Schere": "Papier", "Stein": "Schere", "Papier": "Stein"}
mypoint = 0
yourpoint = 0
def winner(spieler_wahl, gegner_wahl):
if spieler_wahl == gegner_wahl:
messagebox.showinfo("Unentschieden", "Unentschieden")
else:
if Win_Choice[spieler_wahl] == gegner_wahl:
messagebox.showinfo("Gewonnen", "Du hast Gewonnen!")
mypoint = mypoint + 1
else:
messagebox.showinfo("Verloren", "Du hast Verloren!")
yourpoint = yourpoint + 1
def schere():
spieler_wahl = "Schere"
gegner_wahl = random.choice(["Schere", "Stein", "Papier"])
winner(spieler_wahl, gegner_wahl)
punkte.configure(text=f"{mypoint}:{yourpoint}")
def stein():
spieler_wahl = "Stein"
gegner_wahl = random.choice(["Schere", "Stein", "Papier"])
winner(spieler_wahl, gegner_wahl)
punkte.configure(text=f"{mypoint}:{yourpoint}")
def papier():
spieler_wahl = "Papier"
gegner_wahl = random.choice(["Schere", "Stein", "Papier"])
winner(spieler_wahl, gegner_wahl)
punkte.configure(text=f"{mypoint}:{yourpoint}")
punkte = Label(root, text=str(mypoint) + " : " + str(yourpoint))
punkte.grid(row=0, column=1, padx=10, pady=5)
schere = Button(root, text="Schere", bg="#F78181", width=5, height=3, command=schere)
schere.grid(row=1, column=0, padx=8, pady=8)
stein = Button(root, text="Stein", bg="#F78181", width=5, height=3, command=stein)
stein.grid(row=1, column=1, padx=8, pady=8)
papier = Button(root, text="Papier", bg="#F78181", width=5, height=3, command=papier)
papier.grid(row=1, column=2, padx=8, pady=8)
root.mainloop()
Benutze keine *-Importe. global solltest Du erst gar nicht verwenden. Für GUIs brauchst Du Klassen. Notfalls kann man für einfache Programme auch mit Argumenten arbeiten.
In Deinem Programm hast Du viel kopierten Code. Schere, Stein und Papier sollten am besten nur einmal vorkommen.
In Deinem Programm hast Du viel kopierten Code. Schere, Stein und Papier sollten am besten nur einmal vorkommen.
Code: Alles auswählen
import tkinter as tk
from tkinter import messagebox
import random
from functools import partial
WIN_CHOICES = {"Schere": "Papier", "Stein": "Schere", "Papier": "Stein"}
def click(spieler_wahl, punkte):
gegner_wahl = random.choice(list(WIN_CHOICES))
mypoints, yourpoints = map(int, punkte['text'].split(':'))
if spieler_wahl == gegner_wahl:
messagebox.showinfo("Unentschieden", "Unentschieden")
elif WIN_CHOICES[spieler_wahl] == gegner_wahl:
messagebox.showinfo("Gewonnen", "Du hast Gewonnen!")
mypoints += 1
else:
messagebox.showinfo("Verloren", "Du hast Verloren!")
yourpoints += 1
punkte['text'] = f"{mypoints}:{yourpoints}"
def main():
root = tk.Tk()
root.wm_title("Schere, Stein, Papier")
root.config(background="#E0E0F8", width=50, height=50)
punkte = tk.Label(root, text="0:0")
punkte.grid(row=0, column=1, padx=10, pady=5)
for column, symbol in enumerate(WIN_CHOICES):
button = tk.Button(root, text=symbol, bg="#F78181", width=5, height=3, command=partial(click, symbol, punkte))
button.grid(row=1, column=column, padx=8, pady=8)
root.mainloop()
if __name__ == '__main__':
main()
-
- User
- Beiträge: 31
- Registriert: Samstag 16. Mai 2020, 18:52
Entweder benutzt du bei jeder Funktion ein:
oder die vernünftige Lösung um das global zu vermeiden, man schreibt eine Klasse für das Spiel.
Meiner Meinung nach müsste ich hier die wichtigsten Python-Konventionen eingehalten haben.
Code: Alles auswählen
global mypoint
global yourpoint
Code: Alles auswählen
import tkinter
from tkinter import messagebox
import random
class SchereSteinPapier():
def __init__(self):
self.root = tkinter.Tk()
self.root.wm_title("Schere, Stein, Papier")
self.root.config(background="#E0E0F8", width=50, height=50)
self.computer_punkte = 0
self.spieler_punkte = 0
self.punkte = tkinter.Label(self.root, text="0:0")
self.punkte.grid(row=0, column=1, padx=10, pady=5)
self.button_schere = tkinter.Button(self.root, text="Schere", bg="#F78181",
width=5, height=3,
command= lambda: self.turn("Schere"))
self.button_schere.grid(row=1, column=0, padx=8, pady=8)
self.button_stein = tkinter.Button(self.root, text="Stein", bg="#F78181",
width=5, height=3,
command= lambda: self.turn("Stein"))
self.button_stein.grid(row=1, column=1, padx=8, pady=8)
self.button_papier = tkinter.Button(self.root, text="Papier", bg="#F78181",
width=5, height=3,
command= lambda: self.turn("Papier"))
self.button_papier.grid(row=1, column=2, padx=8, pady=8)
self.root.mainloop()
def turn(self, spieler_auswahl):
WIN_CHOICES = {"Schere": "Papier", "Stein": "Papier", "Papier": "Schere"}
computer_auswahl = random.choice(["Schere", "Stein", "Papier"])
if spieler_auswahl == computer_auswahl:
messagebox.showinfo("Unentschieden", "Ihr habt dasselbe gewählt!")
elif WIN_CHOICES[spieler_auswahl] == computer_auswahl:
messagebox.showinfo("Sieger", "Du hast Gewonnen!")
self.computer_punkte += 1
else:
messagebox.showinfo("Verlierer", "Du hast Verloren!")
self.spieler_punkte += 1
self.punkte.configure(text=f"{self.computer_punkte}:{self.spieler_punkte}")
def main():
SchereSteinPapier()
if __name__ == "__main__":
main()
kurze frage nochmal, dein code kann ich soweit lesen und verstehen, ich werds gleich mal versuchen, ich versteh nur nicht ganz was das mit der _Main_ auf sich hat und was meinst du mit was ich über klassen wissen sollte für eine GUI? also ich hab ganz schön dicken schicken zu python3 rein lesen könnte ich mich da ohne probleme nur ich weis nicht genau wo ich anfangen soll