Labyrinth generieren mit Python

Code-Stücke können hier veröffentlicht werden.
Antworten
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

Ich habe am Wochenende eine Funktion zum generieren von Irrgärten/Maps für mein Zombie Spiel entwickelt.

Den Sourcecode findet ihr in meinem Blog:
http://29a.ch/2009/9/7/generating-maps- ... ith-python

Beispiel:

Code: Alles auswählen

#############################################################
#     #           #              #        #           #     #
#     #           #              #        #           #     #
#  ####  ####  #  #  ##########  #  #  #  #  #######  #  ####
#     #  #     #     #           #  #  #     #     #  #     #
#     #  #     #     #           #  #  #     #     #  #     #
####  #  #  ##########  #############  #######  #  #  ####  #
#     #  #  #  #     #     #           #     #  #  #        #
#     #  #  #  #     #     #           #     #  #  #        #
#  #######  #  #  #  ####  #######  ####  ####  #  #######  #
#           #     #  #     #        #  #     #  #        #  #
#           #     #  #     #        #  #     #  #        #  #
#############  ####  #  ####  #######  #  #  #  #  #######  #
#                 #           #           #     #           #
#                 #           #           #     #           #
#############################################################
Über Feedback würde ich mich natürlich Freuen.

Gruss,
Jonas
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo!

Ich habe den Code jetzt nicht im Detail angeschaut, aber für so wenig Text scheinen ganz vernünftige Ergebnisse rauszukommen. Gibt es für die erzeugten Labyrinthe irgendwelche Garantien: Immer einen Weg von einer freien Zelle zu einer anderen freien, keine doppelten Wände, ...?

Vorschlag:

Code: Alles auswählen

if dx > 0:
    index = lambda offset : -1+field_width*offset
elif dx < 0:
    index = lambda offset : cellsize+field_width*offset
elif dy > 0:
    index = lambda offset : -field_width+offset
else:
    index = lambda offset : cellsize*field_width+offset

for offset in xrange(cellsize):
    field[fi+index(offset)] = 1
Die Schleife danach sieht mir auch etwas komisch aus.

Man könnte aus

Code: Alles auswählen

if nx < 0 or nx >= width or ny < 0 or ny >= height:
    continue
auch folgendes machen:

Code: Alles auswählen

if nx//width or ny//height:
    continue
Ob hier kürzer auch besser ist, ist natürlich fraglich.

Bei so einem kleinen Script nicht so schlimm, aber die Berechnung von x- und y-Koordinaten sind natürlich überall doppelt.

Hat es eigentlich einen tieferen Sinn, dass die Karte als eindimensionale Liste gespeichert wird?
Das Leben ist wie ein Tennisball.
BlackJack

Das sieht insgesamt mehr nach BASIC oder nach einer Low-Level-Sprache aus, bei der man dem Compiler nicht vertraut, dass er effizienten Code für verschachtelte Arrays erzeugt. Da passt natürlich EyDu's ``if``-Variante ganz gut rein. Lesbar ist anders. ;-)

Ich hätte das zum Beispiel so ausgedrückt:

Code: Alles auswählen

if not (0 <= nx < width or 0 <= ny < height):
    continue
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Aber wenn es doch um jede Millisekunde geht...! ^^
Das Leben ist wie ein Tennisball.
Redprince
User
Beiträge: 128
Registriert: Freitag 22. Oktober 2004, 09:22
Wohnort: Salzgitter
Kontaktdaten:

Gehts ja nicht: ;)

Code: Alles auswählen

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
I am not part of the allesburner. I am the [url=http://allesburner.de]allesburner[/url].
Benutzeravatar
veers
User
Beiträge: 1219
Registriert: Mittwoch 28. Februar 2007, 20:01
Wohnort: Zürich (CH)
Kontaktdaten:

EyDu hat geschrieben:Ich habe den Code jetzt nicht im Detail angeschaut, aber für so wenig Text scheinen ganz vernünftige Ergebnisse rauszukommen. Gibt es für die erzeugten Labyrinthe irgendwelche Garantien: Immer einen Weg von einer freien Zelle zu einer anderen freien, keine doppelten Wände, ...?
Das ganze Labyrinth ist ein Vollständig verbundener Graph. Es gibt zwischen zwei Zellen immer genau einen Weg.
EyDu hat geschrieben: Vorschlag:

Code: Alles auswählen

if dx > 0:
    index = lambda offset : -1+field_width*offset
elif dx < 0:
    index = lambda offset : cellsize+field_width*offset
elif dy > 0:
    index = lambda offset : -field_width+offset
else:
    index = lambda offset : cellsize*field_width+offset

for offset in xrange(cellsize):
    field[fi+index(offset)] = 1
Finde ich ehrlich gesagt nicht schöner.
Ich hab es nun so angepasst:

Code: Alles auswählen

        # tear down walls
        if dx > 0:
            a = -1
            b = field_width
        elif dx < 0:
            a = cellsize
            b = field_width
        elif dy > 0:
            a = -field_width
            b = 1
        else:
            a = cellsize*field_width
            b = 1
        for offset in xrange(cellsize):
            field[fi+a+b*offset] = 1
EyDu hat geschrieben:Hat es eigentlich einen tieferen Sinn, dass die Karte als eindimensionale Liste gespeichert wird?
Ist eine (schlechte?) Angewohnheit von mir.

BlackJack, Verschachtelte Listen in Python sind nicht sonderlich effizient. 8) Das If habe ich auch angepasst. Viel mehr Abstraktion halte ich bei einem so einfachen Script eigentlich nicht für sinnvoll. :)

Gruss,
Jonas
[url=http://29a.ch/]My Website - 29a.ch[/url]
"If privacy is outlawed, only outlaws will have privacy." - Phil Zimmermann
Antworten