Schiffe versenken Problem

Fragen zu Tkinter.
Antworten
mari123
User
Beiträge: 2
Registriert: Freitag 27. Mai 2011, 17:04

Hallo,
ich arbeite zurzeit an einem Spiel-Projekt für die Schule. Das Programm findet ihr hier:
http://www.python-forum.de/pastebin.php?mode=view&s=191

Jedes mal, wenn ich im Unterprogramm "getroffenSpieler()" Parameter übergeben will kommt folgende Fehlermeldung:

Traceback (most recent call last):
File "C:\Users\Marilena\Desktop\Schule\Informatik\Python\Projekt Spiel\hauptprogramm3.py", line 339, in <module>
spielfeldGegner(computerIstDran)
File "C:\Users\Marilena\Desktop\Schule\Informatik\Python\Projekt Spiel\hauptprogramm3.py", line 233, in spielfeldGegner
xy.config(bg="lightblue", cursor = "target", activebackground = "lightblue", highlightcolor = "blue", command = getroffenSpieler(y, spalte))
File "C:\Users\Marilena\Desktop\Schule\Informatik\Python\Projekt Spiel\hauptprogramm3.py", line 294, in getroffenSpieler
xKoordinate = buttons[(mouse_x-432)//24]
IndexError: list index out of range

Könnt ihr mir sagen, woran das liegt, und was ich ändern muss, dass es funktioniert?
Dankeschön! :)
BlackJack

@mari123: Grundsätzlich kann man den Spielverlauf so nicht machen. Wenn ich das richtig sehe rufen sich `eigenesSpielfeld()` und `computerAmZug()` immer gegenseitig auf, und das bevor der Kontrollfluss jemals zum Aufruf der Hauptschleife Zufall wenn Du überhaupt eine GUI zu Gesicht bekommst. So funktionieren GUIs und ereignisbasierte Programmierung nicht.

Zum konkreten Fehler: Du versuchst auf ein Listenelement zuzugreifen das es nicht gibt. Lass Dir doch mal den Inhalt der Liste ausgeben und den Index der da berechnet wird und kläre ab warum das so passiert wie es passiert.

Docstrings, also Zeichenketten die eine Funktion beschreiben, gehören übrigens hinter die die ``def``-Anweisung und nicht davor.
mari123
User
Beiträge: 2
Registriert: Freitag 27. Mai 2011, 17:04

[...]Wenn ich das richtig sehe rufen sich `eigenesSpielfeld()` und `computerAmZug()` immer gegenseitig auf [...]
Ja, die rufen sich immer gegenseitig auf. Aber das Unterprogramm "computerAmZug()" wird nur durchlaufen, wenn "computerIstDran" True ist. Wenn dann per Zufall ein Kästchen ausgewählt wurde, auf das der Computer zielt, muss das Spielfeld ja neu erstellt werden, dass die Farbe vom Kästchen aktualisiert wird. Und das Programm funktioniert auch eigentlich.

Was ich nicht verstehe ist: Das mit dem Listenelement aufrufen ist eigentlich kein Problem, wenn ich keine Parameter in das Unterprogramm übergebe. Aber was haben die Paramater mit dem Aufrufen vom Listenelement zu tun?
Docstrings, also Zeichenketten die eine Funktion beschreiben, gehören übrigens hinter die die ``def``-Anweisung und nicht davor.
Vielen Dank für den Hinweis! :)
BlackJack

@mari123: Du rufst das ja selber auf. Typischer Anfängerfehler. Du willst das diese Funktion aufgerufen wird, wenn jemand auf den Button klickt, aber Du rufst sie selber schon auf statt eine Funktion als `command`-Argument zu übergeben die dann aufgerufen wird. Schau Dir mal `functools.partial()` an um eine Funktion aus einer Funktion und Argumenten zu erstellen.

Das ganze ist furchtbar unübersichtlich und verwirrend. In dem Programm wimmelt es von Zugriffen auf globale Variablen und trotz der ganzen Funktionen gibt es nur ein einziges ``return``. Das die Funktionen in den Kommentaren als ”Unterprogramme” bezeichnet werden, passt da schon ganz gut, erinnert aber auch irgendwie an Pascal-Programme oder vielleicht sogar BASIC-Programme aus den 80ern.

Die ellenlangen Kommentare sind auch eher schädlich als nützlich. Entweder kann man sie nicht lesen weil sie rechts ”verschwinden” oder sie werden umgebrochen und zerstören die Übersicht über die Quelltextformatierung ziemlich gründlich.
Antworten