Ein Labyrinth erstellen (hilfeeeee!)

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7472
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Dienstag 27. Mai 2008, 18:54

vimy hat geschrieben: hey ich bins mal wieder...
1. das random.shuffle hatten wir noch nicht.. und ich hab versucht es einzubauen und es hat mich überfordert :oops:
Dann experimentiere damit einfach mal in einer Konsole! Es gibt auch sicherlich zig Code-Scnipsel damit im netz oder hier im Board zu finden.
2. steh ich vor vielen neuen problemen
zum beispiel wo muss ich das time.sleep einbauen, damit einzelnd angezeigt wird welche linie nach einander gelöscht wird?
Du weißt ja sicherlich, wo Du eine "Linie" löscht? Dann sollte das nicht so schwer sein, denke ich mal!
oder muss ich das mit update() machen? das hab ich auf jedenfall nicht hingekriegt.. wäre nett wenn ihr mir das sagen könntet..
Keine Ahnung! Aber es klingt nach Grafik-Dingen ;-)
außerdem versteht ich nicht wie ich das speichern soll..
weil ein "pickle-modul" oder sowas hatten wir noch nicht..
wöre lieb wenn ihr näher darauf eingehen könntet..
liebe grüße und dank im vorraus
Schau Dir doch mal an, was dazu im Tutorial steht! Desweiteren gilt auch hier, einfach mal googlen! Durch das Angucken von Code-Snippets lern man viel!
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Dienstag 27. Mai 2008, 19:05

Ich bin mir nicht sicher, ob ich den Sinn des Programms (also der eigentlichen Aufgabenstellung) schon richtig verstanden habe:

Man hat ein rechteckiges Feld, dass in lauter gleich große rechteckige Felder unterteilt ist, das sind die Räume.
Jetzt soll Schritt für Schritt jeweils ein Trennwand = Linie zwischen zwei benachbarten Rechtecken (Räumen) entfernt werden (zufällig ausgewählt), die beiden Räume werden zu einem neuen Raum. (Nummerierung etc. ist klar).
Das wird so lange gemacht, bis alle Räume weg sind, also nur noch das umgebende Rechteck da ist.
Dieser Vorgang soll graphisch veranschaulicht werden. Richtig?

Warum heißt das dann "Labyrinth"?

Und: Du schreibst mehrfach von Dingen, die ihr noch nicht im Unterricht behandelt habt. Es wäre für potentielle Helfer darum hilfreich zu wissen, WAS ihr gemacht habt, damit du nicht weitere Hilfsangebote bekommst, die dir nicht helfen, weil du sie nicht umsetzen kannst/darfst.

Soll der Wändeentfernungsprozess automatisch ablaufen oder soll der Anwender jeweils den nächsten Schritt manuell einleiten.
Und: Welche Daten sollen gespeichert werden? Ein bestimmter Zustand des Labyrinths oder der gesamte Ablauf?
Da der Lehrer das Speichern verlangt, habt ihr sicherlich mit sequentiellen Dateien gearbeitet, oder nicht?

Und: Du hast im Laufe des Threads die Empfehlung bekommen, die Programmlogik von der Darstellung (GUI) zu trennen. Das hast du nicht gemacht, wäre aber schlau das zu tun.
Versuch doch die Simulation zunächst mal ganz ohne graphische Darstellung, nur den Prozess mit der Speicherung etc.

Dazu brauchst du eben eine geeignete Datenstruktur - aber nicht unbedingt eine dargestellte Zeichnung.
BlackJack

Dienstag 27. Mai 2008, 21:13

@pütone: Falsch verstanden. Es sollen zufällig Wände entfernt werden bis es nur noch einen Raum gibt. Der muss nicht rechteckig sein, sondern nur zusammenhängend. Und man darf auch nicht beliebige Wände entfernen, sondern nur solche die zwei unterschiedliche Räume voneinander trennen. Und wenn man das befolgt kommt am Ende ein Labyrinth heraus.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Dienstag 27. Mai 2008, 22:01

Aaaahhhhh :idea:
Danke BlackJack, jetzt hab ich's begriffen.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Mittwoch 28. Mai 2008, 18:19

Nachdem ich die Aufgabenstellung nun endlich verstanden hatte, hat es mich schon gereizt, die Aufgabe auch zu lösen und ich muss sagen, trivial fand ich das nicht.

Wenn man es vergleicht mit dem, was sonst so hier an Informatikhausaufgaben (Schule, nicht Uni) präsentiert wird, fand ich das schon recht anspruchsvoll.
Ich habe insgesamt ca. 3 Stunden gebraucht, von den ersten Überlegungen bis das Programm fertig war, wovon ca. 50% für reine Vorüberlegungen zur Datenstruktur und Programmlogik draufgegeangen sind, ca. 1 Stunde für die Implementierung der Programmlogik und die restlichen 30 min für die graphische Umsetzung.

Ist schon interessant, wenn man so davor sitzt und sieht, wie ein Labyrinth entsteht, wobei echtes Labyrinth-Gefühl erst aufkommt, wenn man die Anzahl der Zeilen und Spalten ordentlich hochsetzt (das kann bei meiner Umsetzung der Anwender frei wählen).

Danke nochmal an den unbekannten Informatiklehrer für die interessante Aufgabe! :)
vimy
User
Beiträge: 10
Registriert: Dienstag 15. April 2008, 12:42
Wohnort: borken
Kontaktdaten:

Mittwoch 28. Mai 2008, 19:26

okey.. hab ich mittlerweile schon alles lösen können was ich gefragt habe :D
bin sogar relativ stolz drauf auch wenn ihr warscheinlich alles anders machen würdet.. naja abe rjetz hab ich wieder ein problem..
und zwar.. wenn ich auf den "neu"-button drücke öffnet sich ein neues fenster.. und das alte bleibt offen.. ich würde jetzt gerne mal wissen wie ich das alte automatisch schließen kann.. ich meine sowas mpüsste mit kill gehen.. aber ich weiß nicht wie das fenster dann heißt.. wäre nett wenn ihr mir diesmal helfen könntet.. liebe grüße

Code: Alles auswählen

        self.new = Button(self.frame_3)
        self.new['bg'] = "yellow"
        self.new['text'] = "Neu"
        self.new['command'] = self.__init__
        self.new.pack(side="left",expand=1,fill="both")
ich weiß ist einfach umgangen.. könnte man auch anders machen..aber ich hätte das gerne so..und dann automatisch das alte gelöscht..
vimy
User
Beiträge: 10
Registriert: Dienstag 15. April 2008, 12:42
Wohnort: borken
Kontaktdaten:

Mittwoch 28. Mai 2008, 19:35

"Danke nochmal an den unbekannten Informatiklehrer für die interessante Aufgabe! "

herr schulz heißt es .. und danken kann man ihm dafür wohl kaum..ich zumindest nicht..

pütone könntest du mir vielleicht erklären wie du da smit den "zahlen in den räumen" umgesetzt hast?.. also das der wirklich nur linien löscht die verschiedene räume von einander trennen? ich hab zwar ein programm was linien löscht geschrieben..aber ein wirkliches labyrinth kommt nicht dabei raus... weil das unterprogramm halt belibiege linien löscht (außer die außenwande)[/code]
BlackJack

Mittwoch 28. Mai 2008, 19:57

@pütone: Stimmt, so ganz trivial ist es nicht. Ich habe auch 'ne Weile überlegt, wie ich die Räume/Wände modelliere. Bin dann an einer "2D-Liste" mit "Zellen" angekommen, die eine Nummer und eine rechte und untere Wand haben.

GUI habe ich nicht drauf gesetzt.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Mittwoch 28. Mai 2008, 20:14

vimy hat geschrieben:pütone könntest du mir vielleicht erklären wie du da smit den "zahlen in den räumen" umgesetzt hast?.. also das der wirklich nur linien löscht die verschiedene räume von einander trennen? ich hab zwar ein programm was linien löscht geschrieben..aber ein wirkliches labyrinth kommt nicht dabei raus... weil das unterprogramm halt belibiege linien löscht (außer die außenwande)
vimy hat geschrieben:pütone könntest du mir vielleicht erklären wie du da smit den "zahlen in den räumen" umgesetzt hast?.. also das der wirklich nur linien löscht die verschiedene räume von einander trennen? ich hab zwar ein programm was linien löscht geschrieben..aber ein wirkliches labyrinth kommt nicht dabei raus... weil das unterprogramm halt belibiege linien löscht (außer die außenwande)
Schon deiner Formulierung kann man entnehmen, dass du immer noch keine Trennung von Programmlogik und graphischer Darstellung vorgenommen hast.
Das Problem ist doch nicht, irgendwelche Linien zu löschen, sondern sich zu überlegen, in welcher Art von Datenstruktur man die Informationen - Räume und Trennwände - sinnvollerweise speichert und wie man das Entfernen von Trennwänden rein logisch umsetzt.
Daraus dann später Linien zu machen, die wieder entfernt werden, ist der leichteste Teil der ganzen Arbeit.

Nach einer ganzen Zeit des Experimentierens mit Papier und Buntstiften (hast du sowas auch gemacht? Wenn nein: Tu das!) habe ich mich dafür entschieden, mit Trennwand-Objekten zu arbeiten.
Erst wollte ich mit Raum-Objekten arbeiten, aber das schien mir weniger günstig, weil jeder Raum unterschiedliche viele Trennwände haben kann und mir das komplizierter in der Umsetzung erschien.
Anstelle von Objekten könnte man aber auch einfach eine Liste oder ein Dictionary verwenden, weil die Trennwand-Objekte nur Datenattribute haben.

Jedes dieser Objekte erhält eine fortlaufende Nummer (ID) und die Information über beiden Räume, die durch diese Wand getrennt werden; die Räume sind ebenfalls durchnummeriert. Aus der ID einer Trennwand lässt sich ermitteln, ob es eine senkrechte oder waagerechte Trennwand ist und an welcher Stelle im (graphischen) Labyrinth sie positioniert ist. Das ist nicht ganz so einfach, und lässt sich durch - im Prinzip redundante - Informationen über die Lage und Ausrichtung auch einfacher gestalten.

Alle Trennwandobjekte werden nach der Erzeugung in einer Liste gehalten, aus der dann zufällig jeweils eine Trennwand ausgewählt und auch entfernt wird (das geht z.B. mit shuffle() und pop(), aber auch unter Verzicht auf diese beiden Funktionen, falls du sie nicht einsetzen willst/kannst/darfst).

Durch das Entfernen der Trennwand fällt ja ein Raum weg (der mit der höheren Nummer). Da es noch andere Trennwände geben kann, die an den selben Raum (der wegfällt) angrenzen, muss man für diese Trennwandobjekte diese Raumnummer auch auf die niedrigere Raumnummer des neu entstandenen Raums setzen.
Anschließend muss man noch prüfen, ob dadurch eine Trennwand entstanden ist, die nicht mehr zwei, sondern faktisch nur noch einen Raum (= gleiche Raumnummer) voneinander trennt. Dann ist das eine der Trennwände, die bis zum Schluss stehen bleiben. Da sie nicht entfernt werden soll, muss sie aus der Liste der noch zum Entfernen vorgesehenen Trennwände entfernt werden.

Das ist nicht alles, aber ein wichtiger Teil der Programmlogik.

Ich habe auf diese Weise eine neue Liste der zufällig entfernten Trennwände (ohne die unentfernbaren Trennwände) erstellt, womit das Problem eigentlich gelöst ist.

Die graphische Umsetzung ist dann einfach: Rohlabyrinth mit allen Trennwänden zeichnen und dann die in der Liste gesammelten entfernen.

Auch die Datenspeicherung ist dann kein Problem mehr: Wenn du es mit pickle() nicht kannst/darfst/willst, dann genügt es auch, die Anzahl der Zeilen und Spalten des Labyrinths sowie die IDs der zu entfernenden Trennwände in einer sequentiellen Datei zu speichern. Daraus lässt sich das Labyrinth dann wieder eindeutig rekonstruieren.
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Mittwoch 28. Mai 2008, 20:20

BlackJack hat geschrieben:@pütone: Stimmt, so ganz trivial ist es nicht. Ich habe auch 'ne Weile überlegt, wie ich die Räume/Wände modelliere. Bin dann an einer "2D-Liste" mit "Zellen" angekommen, die eine Nummer und eine rechte und untere Wand haben.
Dann muss man natürlich darauf achten, dass die rechte und untere Wand der Räume in der unteren Zeile und rechten Reihe grundsätzlich nicht entfernbar sind. Für mich war das aber ein Grund, es anders zu modellieren - siehe Beitrag davor.

Ich habe mich von Anfang an nur auf die Trennwände beschränkt, die potentiell auch entfernbar sind. Den äußeren Rahmen habe ich bei der Modellierung ganz weggelassen - bei der graphischen Umsetzung einfach ein Rechteck gezeichnet.
BlackJack

Mittwoch 28. Mai 2008, 21:05

Beim Test ob eine Wand zwei verschiedene Räume trennt gibt's bei denen ganz rechts und ganz unten einen `IndexError` beim Versuch auf die nicht vorhandene Nachbarzelle zu zu greifen. Den fange ich ab und die Antwort des Tests ist dann `False`.

Aber nur die Trennwände zu modellieren ist wohl sauberer.
vimy
User
Beiträge: 10
Registriert: Dienstag 15. April 2008, 12:42
Wohnort: borken
Kontaktdaten:

Mittwoch 28. Mai 2008, 21:15

pütone???
du erwarte4st doch nicht im ernst das ich auch nur ansatzweise irgendetwas davon verstanden habe was du da geschrieben hast...
ich bin im 2. jahr informatik.. an einer schule.. das is diff fach und erste jahr haben wir nur html und so gemacht..
ich bedanke mich wirklci hdafür das du dir so eine mühe gegeben hast das so ausführlich aufzuschreiben und für die mühe jmir das zu erklären..
aber ich denk den text muss ich mir jetz erstmal irgendwie übersetzen..:D
ich melde mcih dann zurück..
wäre tortzdem nett wenn auf meine anderen fragen noch eingegangen werden könnte.. danke im vorraus..
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Mittwoch 28. Mai 2008, 21:32

vimy hat geschrieben:du erwarte4st doch nicht im ernst das ich auch nur ansatzweise irgendetwas davon verstanden habe was du da geschrieben hast...
Das war eigentlich schon meine Erwartung ... :roll:
vimy hat geschrieben:ich bin im 2. jahr informatik.. an einer schule.. das is diff fach und erste jahr haben wir nur html und so gemacht..
Heißt also max. 1 Jahr Programmieren, mit Start bei Null.
Dann würde ich einfach mal sagen, du bist - eine durchschnittliche Begabung vorausgesetzt - mit der Aufgabenstellung überfordert, es sei denn es gibt noch irgendeinen genial einfachen Weg, den bisher nur noch keiner entdeckt hat. Aber, wenn selbst BlackJack schreibt "so ganz trivial ist es nicht", dann würde ich diesen Fall einfach mal ausschließen.

Ist natürlich blöd für dich und wird dir auch wenig helfen, wenn du Herrn Schulz darauf hinweist, dass irgendein "pütone" im Python-Forum der Meinung ist, es sei eine Überforderung nach 1 Jahr Informatik in der Schule diese Aufgabe adäquat lösen zu können.
vimy hat geschrieben:wäre tortzdem nett wenn auf meine anderen fragen noch eingegangen werden könnte.. danke im vorraus..


Was mich angeht, so sehe ich da wenig Sinn drin, bei diesem Herumgefrickel an der GUI irgendeine Hilfestellung zu leisten. Das Entscheidende ist die Modellierung/Programmlogik, d.h. die Abbildung des Labyrinthproblems auf eine geeignete Datenstruktur und einen passenden Algorithmus. Die graphische Darstellung wird am Ende nur oben draufgesetzt - sozusagen das Sahnehäubchen, damit das Auge auch was davon hat.
BlackJack

Donnerstag 29. Mai 2008, 13:36

@pütone: Ich habe Deinen Ansatz mal in Io umgesetzt, ohne GUI. Alle Informationen wie Position und Ausrichtung der Wände in ganzen Zahlen zu kodieren hat irgendwie wieder etwas von guter alter C oder Assemblerprogrammierung. :-)

Weil "Lodge It!" den Io-Highlighter noch nicht anbietet, hab ich's mal hier rein gestellt: http://pygments.org/demo/801/
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Donnerstag 29. Mai 2008, 17:25

BlackJack hat geschrieben:@pütone: Ich habe Deinen Ansatz mal in Io umgesetzt, ohne GUI.


Was es alles gibt. Bis eben wusste ich noch gar nicht, dass es eine Programmiersprache Namens Io gibt. Diese Wissenslücke habe ich natürlich schnell gefüllt und auch dein Programm beguckt.
Auch wenn ich Io nicht kenne, wenn man weiß, was programmiert wurde, ist es nicht ganz unverständlich. Die Ausrichtung der Wände habe ich auch so kodiert (nur andersrum: ungerade = vertikal).
BlackJack hat geschrieben:Alle Informationen wie Position und Ausrichtung der Wände in ganzen Zahlen zu kodieren hat irgendwie wieder etwas von guter alter C oder Assemblerprogrammierung.
Man könnte es ja in diese Richtung noch weiter verfeinern: Warum die Informationen über die beiden Raumnummern als zwei Ganzzahlen speichern - eine täte es ja auch :D
Antworten