Drucken Sie ein zufälliges Labyrinth


19

Schreiben Sie ein Programm, das mit dem Algorithmus Ihrer Wahl ein zufälliges Labyrinth erzeugt und druckt . Das Labyrinth sollte für mehrere Programmläufe unterschiedlich sein. Höhe und Breite werden als Befehlszeilenargumente angegeben. Verwenden Sie |für vertikale Wand, -für horizontale Wand und +für Ecke. Das Labyrinth ist von Mauern begrenzt und die Eingänge sind durch fehlende Mauern gekennzeichnet. Das Labyrinth enthält einen Schatz, #der von mindestens einem Eingang aus erreichbar sein muss.

$ python2 random-maze.py 4 5
+-+-+
  |#|
|   |
+---+

+1 Gute Frage. Ein paar Punkte. 1: Wie ist der Ausgang markiert? Ist es ein Symbol wie *oder gibt es zwei getrennte Eingänge? 2: Sie sollten wahrscheinlich angeben, dass der Ausgang erreichbar sein muss.
snmcdonald

1
@snmcdonald: lass es uns Spaß machen und einen Schatz hinzufügen :).
Alexandru

2
Ich kann ein Nachfolge-Golfspiel über das Lösen sehen ... :)
st0le

@st0le: Ich habe schon ein paar Ideen. Mailen Sie mir, wenn Sie diskutieren möchten.
Alexandru

1
Der Puzzletyp ist hier nicht spezifiziert. Ich sehe, dass die Leute darauf geantwortet haben, als wäre es ein [Code-Golf]. War das die Absicht? Wenn ja, kennzeichnen Sie es bitte als solches?
dmckee

Antworten:


5

Ich denke, dies ist technisch gesehen kein Labyrinthgenerator, aber es erzeugt ein Labyrinth-ähnliches Ergebnis: https://gist.github.com/803450 .

Ich weiß, dass dort ein schrecklicher Code steckt, der nur in weniger als der Hälfte der Zeit funktioniert, und das Ergebnis sieht nicht ganz richtig aus, wenn Wände aus anderen Wänden herausragen. Aber es ist nah genug, dass ich nicht die Mühe habe, den Rest zu reparieren.

Einige Beispielausgaben:

→ ruby random-maze.rb 30 30
+----+-+-----------++-+----+
|    + |           ++ |    |
++  +  | ++ ++   +    + ++ ++
|  ++ ++ |  |    +---+  +   |
| +      | +| +   +++  +  + |
|   +   +| +| +-+  |   + +  |
|        +  +    + + ++  |+ |
| + ++ +  ++   + |  +   ++| |
| |  | ++  + +----+ + +-+ | |
| +  |  +-+  |+        |  | |
|   +-+  +| ++  ++ + + |  | |
| ++   +  + |  ++|   + | ++ |
|  + + + +  +---++-+   +++  |
| +  |  +| +    |  ++   |   |
| | +++ +| + ++ +--+  + |---+
|#+ | |  |   +++     +  +   |
++  | ++ +-+  ++ +--+  +  + |
|  ++  |    +     ++| +  ++ |
| ++   +--------+  +| + +   |
| |     |      +++  |  +  +-+
| |     | +--+  |++ |+ | ++
| |     |  +--+ | | || |  |
| |     +-+     +-+ |+ |+ |
| | +---+   ++      +  |  |
| +-|     +    +      ++ ++
|   +       ++   +---+   |
|              ++   +  +-+
|                 +   ++
+-+ +-------------+---+

1
Gute Idee. Extra Punkte, wenn Sie es beheben;)
Alexandru

Dies war nur eine schnelle Änderung der Ausgabe für einen Algorithmus, mit dem ich ein Labyrinth für eine meiner Uni-Aufgaben erstellt habe . Der eigentliche Algorithmus wird hauptsächlich aus einem Blog-Beitrag von CHEVYRAY gestohlen . Ich bin mir nicht sicher, ob das Ausgabeformat vollständig funktioniert, da es kein echtes Labyrinth ist, aber ich werde versuchen, es so nah wie möglich zu bringen, während ich gut aussehe.
Nemo157

Scheint mir ein sehr gutes Labyrinth zu sein.
Alexandru

8

Python, 375 Zeichen

import random,sys
H,V=map(int,sys.argv[1:])
H-=1
V-=1
b,h,v,p=' -|+'
M=H/2*h
n=random.randint(1,(H/2)*(V/2-1))
for i in range(V/2):
 e=s=t='';N=v
 for j in range(H/2):
  if i and(random.randint(0,1)or j==0):s+=N+b;t+=v;N=v;M=M[1:]+p
  else:s+=M[0]+h;t+=b;N=p;M=M[1:]+h
  n-=1;t+=' #'[n==0]
 if H&1:s+=s[-1];t+=b;e=h
 print s+N+'\n'+t+v
if V&1:print t+v
print h.join(M)+e+h+p

Dies erzeugt ein Labyrinth mit einem Eingang und einem zufällig platzierten Schatz. Das Labyrinth ist ein einfaches binäres Baumlabyrinth .

$ ./maze.py 15 15
--------------+
              |
| | ----------+
| |           |
| +-----+ | --+
|       | |   |
| --+ --+ +---+
|   |   |     |
| --+-+ +---+ |
|     |     | |
| --+ +-+ --+ |
|   |   |   |#|
| | | --+ --+-+
| | |   |     |
+-+-+---+-----+

Vielleicht war es beabsichtigt, aber die oberste Reihe (direkt unter der Mauer) ist immer ein langer Korridor.
Alexandru

Ja, und die äußerste linke Spalte ist auch immer ein langer Korridor. Dies ist eine Eigenschaft der Art von Labyrinth, die ich generiere.
Keith Randall

Oh. Die Labyrinthe sind aber sehr schön :).
Alexandru

6

Ruby 1.9.2p136: 90

eval ARGV[0]
z=[l="+"+"-"*@w+"+"]
@h.times{z<<"|"+" "*@w+"|"}
z[rand(@h)+1]="|#"
puts z<<l

Ausgabe

$> ruby maze.rb "@h=8;@w=8;"

+------+
|      |
|      |
|      |
|      |
|#
|      |
+------+

Hey, niemand sagte, es müsse ein gutes Labyrinth sein. OK, OK, ich werde jetzt eine echte machen.


Gut, aber stellen Sie sicher, dass das Protokoll eingehalten wird (Höhe und Breite von der Befehlszeile, Labyrinth gedruckt bis stdout).
Alexandru

Tatsächlich sagt es nichts über stdout aus (dies ist auch keine vernünftige Bedingung, da möglicherweise jemand eine Sprache verwendet, die nicht zu stdout druckt), und es wird allgemein akzeptiert, dass Eingaben zu einer Funktion / Methode gehören. Für die Person, die dies abstimmt, löst es das Problem wie angegeben, also hasse den Labyrinth nicht.

Nicht wirklich so lange es in der Frage angegeben ist. Siehe meta.codegolf.stackexchange.com/questions/13/… . Außerdem unterstützt Ruby im Gegensatz zu JavaScript das Lesen und Schreiben von Argumenten in der Standardausgabe. Ihre Lösung ist Betrug im Vergleich zu anderen, die das Problem auf die richtige Weise gelöst haben.
Alexandru

Kann nicht bearbeitet werden. Ich meinte "unvollständig", nicht "betrügen". Ich mag die Idee des Labyrinths.
Alexandru

Dann müssen die anderen Sprachen den Code enthalten, den sie benötigen, um sie aufzurufen, oder sie #!/usr/bin/env pythonmüssen beispielsweise in ihren Code aufgenommen werden. Wie ich bereits sagte, schreibe ich auch eine echte Lösung, die nur auf die schlechte Qualität der Frage selbst (und vieler anderer) hinweist und zeigt, dass wir bessere Richtlinien brauchen. Wenn Sie schließlich auf eine Frage verweisen, entspricht die Antwort auf die Frage nicht den tatsächlichen Regeln für die Site. Aber gut, hier ist deine neue Version ...

3

C 844

#include <stdlib.h>
#include <time.h>
h,w,*m,y,x,z;d(t,b,l,r){int i=b-t,j=r-l;if(i>1&&j>1){i=(rand()%--i)|1;j=(rand()%--j)|1;z=rand()%4;x=rand()%i+t;x|=1;for(y=t;y<i+t;y++)if(y!=x||!z)m[y*w+j+l]=124;x=rand()%(b-i-t)+i+t;x|=1;for(y=t+i;y<b+1;y++)if(y!=x||!(z-1))m[y*w+j+l]=124;y=rand()%j+l;y|=1;for(x=l;x<j+l;x++)if(y!=x||!(z-2))m[(i+t)*w+x]=45;y=rand()%(r-j-l)+j+l;y|=1;for(x=l+j;x<r+1;x++)if(y!=x||!(z-3))m[(i+t)*w+x]=45;m[(i+t)*w+j+l]=43;m[(t-1)*w+l+j]=43;m[(b+1)*w+j+l]=43;m[(i+t)*w+l-1]=43;m[(i+t)*w+r+1]=43;d(t,t+i-1,l,l+j-1);d(t+i+1,b,l,l+j-1);d(t,t+i-1,l+j+1,r);d(t+i+1,b,l+j+1,r);}}main(int c,char**v){h=atoi(v[1]),w=atoi(v[2]),m=calloc(h*w,4);srand(time(0));while(y<h){while(x<w){m[y*h+x]=(!y||y==h-1)?(!x||x==w-1)?43:45:(!x||x==w-1)?124:32;x++;}y++;x=0;}d(1,h-2,1,w-2);z=rand()%(w-2);z|=1;m[z]=32;z=rand()%(w-2);z|=1;m[h*(w-2)+z]=35;}

Zu testen:

#include <stdio.h>//beginning
for(y=0;y<h;y++){for(x=0;x<w;x++){putchar(m[y*h+x]);}putchar('\n');}getchar();//end

3x3

+ +
| # |
+ - +

7x8

+ - + - - +
| |
+ + - + - +
| |
| + - + - +
| | # |
+ - + - + - +

18x20

+ - + - + + --- + --- + - + - +
| | | | |
| + + + - + --- + + - +
| | | |
+ + + - + --- + - + - + - +
| | | |
+ - + + - + - + - + --- + - + - +
| | | | | |
| + + + + - + - - + |
| | | | |
| | | + - + - + ---- + |
| | | | |
+ + + - + - + - + - - + - +
| | | | |
| + + - + - + - - + |
| | | | |
| | | | # | | |
+ - + - + - + --- + ----- + - +

Dies ist eine Code-Herausforderung , kein Code-Golf . Warum der kaum lesbare Code?
Braden Best

-1. Dieser Code ist nicht nur verschleiert, es gibt auch keine klaren Anweisungen, wie dies kompiliert werden sollte und wie die beiden Codeblöcke implementiert werden sollten. Gebrauchsanweisungen sind spärlich, wenn sie nicht gänzlich fehlen. Es ist offensichtlich, dass Ihre Antwort ein Code-Golf ist. Aber die Frage ist nicht . Der Code sollte also lesbar und für einfaches Kopieren / Einfügen / Kompilieren in sich geschlossen sein, damit andere überprüfen können, ob er tatsächlich funktioniert, ohne dass Sie erst entziffern müssen, wie Sie den Code zum Funktionieren gebracht haben.
Braden Best

0

Hier ist eine einfache Java-Lösung:

import java.util.*;

public class MazeGen {
    public static void main(String[]a){
        int w,l;
        Random rand=new Random(System.currentTimeMillis()%1000+System.nanoTime());
        if(a.length==2){
            w=Integer.parseInt(a[0]);
            l=Integer.parseInt(a[1]);
        }else{
            System.out.println("No command line arguments, taking from STDIN.");
            Scanner input=new Scanner(System.in);
            w=input.nextInt();
            l=input.nextInt();
            input.close();
        }
        char[][]maze=new char[w][l];
        for(int x=0;x<w;x++){
            for(int y=0;y<l;y++){
                maze[x][y]=' ';
            }
        }
        for(int x=0;x<w;x++){
            maze[x][0]=maze[x][l-1]='|';
        }
        for(int y=0;y<l;y++){
            maze[0][y]=maze[w-1][y]='-';
        }
        maze[0][0]=maze[w-1][0]=maze[w-1][l-1]=maze[0][l-1]='+';
        int dor=1+rand.nextInt(l-2);
        maze[0][dor]=' ';
        int tx=2+rand.nextInt(w-3),ty=1+rand.nextInt(l-2);
        maze[tx][ty]='#';
        if(ty<dor-1){
            maze[tx][ty+1]='|';
            if(tx==w-2){
                maze[tx+1][ty+1]='+';
            }
            if(tx==1){
                maze[0][ty+1]='+';
            }
        }
        if(ty>dor+1){
            maze[tx][ty-1]='|';
            if(tx==w-2){
                maze[tx+1][ty-1]='+';
            }
            if(tx==1){
                maze[0][ty-1]='+';
            }
        }
        if(ty==dor&&tx>3&&(maze[tx][ty+1]==' '||maze[tx][ty-1]==' ')){
            maze[tx-1][ty]='-';
        }
        if(dor>5){
            int z=2+rand.nextInt(dor-3);
            int q=1+rand.nextInt(w-3);
            for(int i=0;i<w;i++){
                if(i==0||i==w-1){
                    maze[i][z]='+';
                }else if(i!=q&&maze[i][z]==' '){
                    maze[i][z]='|';
                }
            }

        }
        if(l-dor>5){
            int z=dor+2+rand.nextInt(l-dor-3);
            int q=1+rand.nextInt(w-3);
            for(int i=0;i<w;i++){
                if(i==0||i==w-1){
                    maze[i][z]='+';
                }else if(i!=q&&maze[i][z]==' '){
                    maze[i][z]='|';
                }
            }

        }
        for(char[]row:maze){
            System.out.println(row);
        }
    }
}

Einige Beispielergebnisse:

3x3:

+ +
|#|
+-+

4x4:

+ -+
| #|
|  |
+--+

4x5:

+-+ +
|#| |
|   |
+---+

5x5:

+ --+
|   |
|   |
| |#|
+-+-+

5x8:

+ --+--+
|   |  |
|      |
| # |  |
+---+--+

8x15:

+---- ----+---+
|         |   |
|         |   |
|         |   |
|             |
| #|      |   |
|         |   |
+---------+---+
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.