Ein Labyrinth erstellen (hilfeeeee!)

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
vimy
User
Beiträge: 10
Registriert: Dienstag 15. April 2008, 12:42
Wohnort: borken
Kontaktdaten:

hey..
ich habe da ein problem :oops: ... wir haben anstatt eine zweite klassenarbeit zu schreiben, eine aufgabe zum oop bekommen...
naja und mein problem ist, das ich keine ahnung habe wie ich das machen soll.. da es bei mir beim programmieren im moment etwas harkt...
vielleicht könnt ihr mir ja helfen.. wäre echt nett :)..
also die aufgabe:

Aufgabe 8: Labyrinth erstellen

1. ausgangspunkt ist ein rechteckt aus gleich großen kästchen (räumen).
2. jeder raum bekommt eine Nummer. die reihenfolge ist egal, muss aber eindeutig sein.
3. Man verbindet zwei räume, indem man zufällig eine belibiege trennwand zwischen den zwei zu verbindenen räumen entfernt.
4. dann bekommt der neue, verbundene raum die nidrigere nummer der beiden gerade verbundenen räume.
5. die beiden vorangegangenen schritte werden nun solange wiederholt, bis nur noch ein raum übrig ist. dieser hat die nummer 1.

die aufgabe besteht nun darin, in einem eingabefeld länge und breite eines solchen labyrinthes aubzufragen und dann in einem grafikfenster den aufbau eines solchen labyrinthes nachvollziehbar zu machen.

im anschluss daran soll das labyrinth unter einem dateinamen speicherbar sein. dazu muss man sich noch eine geeignete art ausdenken, das labyrinth so zu speichern, dass es wieder in dem grafikfenster eingelesen und rekonstruiert werden kann.

beispiel:

-----------------
I 1 I 2 I 3 I 4 I
-----------------
I 5 I 6 I 7 I 8 I
-----------------
I 9 I10I11I12I
----------------

-----------------
I 1 I 3 I 4 I
-----------------
I 5 I 6 I 7 I 8 I
-----------------
I 9 I10I11I12I
----------------

-----------------
I 1 I 3 I 4 I
-----------------
I 5 I 6 I 7 I 8 I
-----------------
I 9 I10I 11 I
----------------

und so weiter bis:
-----------------
I I I
-----------------
I 1 I I
-----------------
I I I
----------------

versteht ihr das? .. also die abbildung.. wird deutlich was ich meine?

wäre echt lieb wenn mir jemand helfen könnte...

lieben gruß...
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Und was ist jetzt deine Frage?
vimy
User
Beiträge: 10
Registriert: Dienstag 15. April 2008, 12:42
Wohnort: borken
Kontaktdaten:

meine frage?...
ob ihr mir denk anstöße daüpfr geben könnt..

und wie man das labyrinth das speichern kann.. weil dafür finde ich nicht den passenden befehl ;)

es geht hier nicht darum das ihr mir ein programm schrieben sollt..
ich glaube das kam falsch rüber...
BlackJack

Du wirst Dir eine Datenstruktur ausdenken müssen, die die Räume repräsentiert und dann das Problem in immer kleinere Teilprobleme zerlegen, bis sie relativ einfach lösbar sind.

Bei Schritt 5. würde ich die Raumnummer 1 durch 0 ersetzen. In der Informatik fängt man für gewöhnlich bei 0 an zu zählen.

GUI und Programmlogik solltest Du trennen, also erst einmal das ganze ohne GUI implementieren.

Speichern und laden von (nahezu) beliebigen Python-Objekten geht am einfachsten mit dem `pickle`-Modul.
vimy
User
Beiträge: 10
Registriert: Dienstag 15. April 2008, 12:42
Wohnort: borken
Kontaktdaten:

mhh.. ich denke eher nicht das das mit pickle funktioniert..
mein lehrer meinte irgendwas von mit 1001001 speichern...
achja..
habt ihr zufällig ne ahnung wie ich das hinkriege das der aus dem rechteckt mit kleine vierecken drin immer eine (zufällige) linie entfernen kann?

ich hab mir das so gedacht.. ich mach einfach alle linien einzeln und bennene sie als 1, 2 usw.. und wenn dann bei random.randint z.b 1 rauskommt soll die linie gelöscht werden.. jetz ergibt sich nur ein problem.. der speichert die linien nicht unter 1 = zeichnen.create_line()
damit hat der irgendwie ein problem.. wisst ihr zufällig wieso??
lg...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

vimy hat geschrieben:damit hat der irgendwie ein problem.. wisst ihr zufällig wieso??
Ja, weil Variablennamen nicht mit Zahlen beginnen dürfen.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

vimy hat geschrieben:mhh.. ich denke eher nicht das das mit pickle funktioniert..
mein lehrer meinte irgendwas von mit 1001001 speichern...
Klar, geht das mit pickle...
Du kannst natürlich auch das per Hand machen...
speichern mit ",".join(zahlenliste)
laden mit zahlenliste = data.split(",")

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@vimy: Einzelnen Linien einen Namen geben ist keine Datenstruktur. Ausserdem solltest Du das wie gesagt erst einmal ohne GUI lösen. Dein Ansatz funktioniert so auch nicht, weil Du nicht *irgendwelche* Wände löschen darfst, sondern nur solche, die auch wirklich zwei verschiedene Räume voneinander trennen.

Wenn Du nicht weisst, dass und warum ``1 = irgendwas`` nicht funktioniert, solltest Du vielleicht erst einmal das Tutorial aus der Dokumentation durcharbeiten. Und Du hast dann noch einen ganz schönen Weg vor Dir wenn das eine OOP-Lösung werden soll.

`pickle` funktioniert ganz wunderbar um Objekte zu speichern. Dazu ist das Modul ja da.
vimy
User
Beiträge: 10
Registriert: Dienstag 15. April 2008, 12:42
Wohnort: borken
Kontaktdaten:

ja..ist schon peinlich nach 2 jahren informatik am gymnasium sowas nicht zu wissen/können :D:D
oke danke.. jetz weiß ich das das nicht geht..

und wenn ich ein array mache wo die zahlen von eins bis zwölf drinstehen..
und der aus dem array dann zufällig auswählt.. und diese dann löscht?

@jens..danke das werde ich versuchen...

@blackjack.. ja mir ist bewusst das die außenwände nicht gelsöcht werden dürfen... deshalb dachte ich mir die außenwände werden einfach ein reckteck.. so werden dann nur die wänder gelöscht die auch wirklich einen raum verbinden...
BlackJack

Es ging mir nicht um die Aussenwände, sondern dass man auch keine Wand löschen darf, wo auf beiden Seiten der gleiche Raum ist, sondern nur welche wo beim Löschen der Wand wirklich aus vorher zwei verschiedenen, getrennten Räumen ein neuer Raum wird.
vimy
User
Beiträge: 10
Registriert: Dienstag 15. April 2008, 12:42
Wohnort: borken
Kontaktdaten:

bin bis jetzt so weit : http://paste.pocoo.org/show/45080/

kannt mir jemand sagen wo der fehler ist?

Traceback (most recent call last):
File "C:\Dokumente und Einstellungen\schleifentest.py", line 116, in <module>
del linien[zufallszahl2]
IndexError: list assignment index out of range
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Könntest du deinen Code bitte noch in Code-Tag setzen, dann kann man es auch vernünftig lesen.

Der Fehler liegt in Zeile 116. Und zwar hat die Liste "linien" kein "zufallszahl2"-tes Element. Aber überhaupt sieht der Code noch recht wirr aus. So viele kurze Bezeichner, Redundanz und ich meine sogar einen *-Import gesehen zu haben ;-)
vimy
User
Beiträge: 10
Registriert: Dienstag 15. April 2008, 12:42
Wohnort: borken
Kontaktdaten:

Code: Alles auswählen

from Tkinter import *

import random
import thread
from time import *

##########################################
###     erstellt Fenster
##
#

fenster = Tk()

frame_1 = Frame(fenster)
frame_1.pack(side="top", expand=1, fill="both")

pro_info = Label(frame_1)
pro_info['bg'] = "yellow"
pro_info['text'] = "Ein Labyrinth erstellen"
pro_info.pack(side="left", expand=1, fill="both")

hilfe = Button(frame_1)
hilfe['bg'] = "yellow"
hilfe['text'] = "Hilfe"
#hilfe['command'] = pass
hilfe.pack(side="left",expand=1,fill="both")

frame_2 = Frame(fenster)
frame_2.pack(side="top", expand=1, fill="both")

zeichnen = Canvas(frame_2)
zeichnen['width']  = 500
zeichnen['height'] = 500
zeichnen['bg'] = "white"
zeichnen.pack(side="top", expand=1, fill="both")

frame_3 = Frame(fenster)
frame_3.pack(side="top", expand=1, fill="both")

laenge = Entry(frame_3)
laenge['bg'] = "yellow"
laenge['text'] = "Länge"
laenge.pack(side="left",expand=1,fill="both")

breite = Entry(frame_3)
breite['bg'] = "yellow"
breite['text'] = "Breite"
breite.pack(side="left",expand=1,fill="both")

stop_play = Button(frame_3)
stop_play['bg'] = "yellow"
stop_play['text'] = "Stop"
#hilfe['command'] = pass
stop_play.pack(side="left",expand=1,fill="both")

new = Button(frame_3)
new['bg'] = "yellow"
new['text'] = "Neu"
#hilfe['command'] = pass
new.pack(side="left",expand=1,fill="both")

save = Button(frame_3)
save['bg'] = "yellow"
save['text'] = "Speichern"
#hilfe['command'] = pass
save.pack(side="left",expand=1,fill="both")

#####################################
###     Au�enlinien
##
#



waagerechtoben = zeichnen.create_line(450,70,30,70)
waagerechtunten = zeichnen.create_line(450,370,30,370)
senkrechtlinks = zeichnen.create_line(30,370,30,70)
senkrechtrechts = zeichnen.create_line(450,370,450,70)

##############################
###     Innenlinien
##
#


linien = []
x = 0
a = 450
b = 70
c = 30 
d = 70

while(x < 3):
    temp = zeichnen.create_line(a,b,c,d)
    linien.append(temp)
    b = b + 100
    d = d + 100
    x = x + 1

y = 0
z = 370
g = 30 
d = 70
f = 30

while(y < 4):
    temp = zeichnen.create_line(g,z,f,d)
    linien.append(temp)
    g = g + 105
    f = f + 105
    y = y + 1

zufallszahl1 = random.randint(1,17)
while(zufallszahl1 > 0):
    zufallszahl2 = random.randint(1,17)
    del linien[zufallszahl2]
    zufallszahl1 = zufallszahl1 - 1


fenster.mainloop()

so besser?

ja.. zufallszahl2 ist der ordner in dem ja eine zufallszahl produziert wird.. logischer weiser. und diese zufallszahl (also die stelle in der liste) soll dann aus der liste gelöscht werden. deshalb das "del linien[zufallszahl2]"
wie kann man das denn anders machen wenn es so nicht geht?
BlackJack

Vielleicht solltest Du Dir mal in der Schleife die Liste und `zufallszahl2` ausgeben lassen, dann siehst Du was schief läuft. Wobei die Namensgebung wirklich nicht so toll ist. `random.shuffle` und "slicing" bekommt man das auch ohne explizite Schleife etwas kürzer hin.
vimy
User
Beiträge: 10
Registriert: Dienstag 15. April 2008, 12:42
Wohnort: borken
Kontaktdaten:

Code: Alles auswählen

from Tkinter import *

import random
import thread
from time import *
import os
import time

class Spielfeld():

    def spielfeld_erstellen(self):


        self.frame_1 = Frame(self.fenster)
        self.frame_1.pack(side="top", expand=1, fill="both")

        self.pro_info = Label(self.frame_1)
        self.pro_info['bg'] = "yellow"
        self.pro_info['text'] = "Ein Labyrinth erstellen"
        self.pro_info.pack(side="left", expand=1, fill="both")

        self.hilfe = Button(self.frame_1)
        self.hilfe['bg'] = "yellow"
        self.hilfe['text'] = "Hilfe"
        self.hilfe['command'] = self.showHelp
        self.hilfe.pack(side="left",expand=1,fill="both")

        self.frame_2 = Frame(self.fenster)
        self.frame_2.pack(side="top", expand=1, fill="both")

        self.zeichnen = Canvas(self.frame_2)
        self.zeichnen['width']  = 500
        self.zeichnen['height'] = 500
        self.zeichnen['bg'] = "white"
        self.zeichnen.pack(side="top", expand=1, fill="both")

        self.frame_3 = Frame(self.fenster)
        self.frame_3.pack(side="top", expand=1, fill="both")

        self.laenge_text = Label(self.frame_3)
        self.laenge_text['bg'] = "yellow"
        self.laenge_text['text'] = "Länge"
        self.laenge_text.pack(side="left",expand=1,fill="both")

        self.laenge = Entry(self.frame_3)
        self.laenge['bg'] = "yellow"
        self.laenge['text'] = "Länge"
        self.laenge.pack(side="left",expand=1,fill="both")

        self.breite_text = Label(self.frame_3)
        self.breite_text['bg'] = "yellow"
        self.breite_text['text'] = "Breite"
        self.breite_text.pack(side="left",expand=1,fill="both")


        self.breite = Entry(self.frame_3)
        self.breite['bg'] = "yellow"
        self.breite['text'] = "Breite"
        self.breite.pack(side="left",expand=1,fill="both")

        self.stop_play = Button(self.frame_3)
        self.stop_play['bg'] = "yellow"
        self.stop_play['text'] = "Stop"
        #self.hilfe['command'] = pass
        self.stop_play.pack(side="left",expand=1,fill="both")

        self.new = Button(self.frame_3)
        self.new['bg'] = "yellow"
        self.new['text'] = "Neu"
        #self.hilfe['command'] = pass
        self.new.pack(side="left",expand=1,fill="both")


        self.save = Button(self.frame_3)
        self.save['bg'] = "yellow"
        self.save['text'] = "Speichern"
        #self.hilfe['command'] = pass
        self.save.pack(side="left",expand=1,fill="both")

        waagerechtoben = self.zeichnen.create_line(450,70,30,70)
        waagerechtunten = self.zeichnen.create_line(450,370,30,370)
        senkrechtlinks = self.zeichnen.create_line(30,370,30,70)
        senkrechtrechts = self.zeichnen.create_line(450,370,450,70)

    def innenlinien_erstellen(self):

        self.linien = []
        x = 0
        a = 30
        b = 170
        d = 170

        while(x < 2):
            y=0
            while(y<4):  
                temp = self.zeichnen.create_line(a,b,a+105,d)
                self.linien.append(temp)
                a=a+105
                y=y+1
            a=30
            b = b + 100
            d = d + 100
            x = x + 1



        y = 0
        z = 70
        g = 135 
        d = 70
        f = 135

        while(y < 3):
            x=0
            while(x<3):
                temp = self.zeichnen.create_line(g,z,f,z+100)
                self.linien.append(temp)
                z=z+100
                x = x+1
            z = 70
            g = g + 105
            f = f + 105
            y = y + 1

        

    def linien_loeschen(self):

        zufallszahl1 = random.randint(1,12)
        zahlen=[1,4,-1,-4]
        zufallszahl2 = zufallszahl1+zahlen[random.randint(0,3)]



        zufallszahl1 = random.randint(0,16)
        while(zufallszahl1 > 0):
            zufallszahl2 = random.randint(0,16)
            self.zeichnen.delete(self.linien[zufallszahl2])
            time.sleep(0.5)
            zufallszahl1 = zufallszahl1 - 1
            
        
    def showHelp(self):
       
        # online hilfe datei lesen*
        f = open(os.getcwd() + '/help.txt', 'r')
        message = f.read()
        f.close()

        textliste = message.split('\n')
        
        # im Fenster anzeigen
        hilfe = Tk()
        scrollbar = Scrollbar(hilfe)
        scrollbar.pack(side="right", fill= "y")
        meldung = Listbox(hilfe, yscrollcommand=scrollbar.set)
        meldung['width']  = 62
        meldung['height'] = 20
        meldung['bg'] = "white" 
        meldung.pack(side="top", expand=1, fill="both")
        scrollbar.config(command=meldung.yview)

        i = 0
        while ( i < len(textliste)):
            meldung.inse

    def __init__(self):
        
        self.fenster = Tk()
        self.spielfeld_erstellen()
        self.innenlinien_erstellen()
        self.linien_loeschen()
        

        self.fenster.mainloop()

app = Spielfeld()

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:
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?
oder muss ich das mit update() machen? das hab ich auf jedenfall nicht hingekriegt.. wäre nett wenn ihr mir das sagen könntet..
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
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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

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

@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

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

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! :)
Antworten