Rastgele bir labirent yazdırın


19

İstediğiniz algoritmayı kullanarak rastgele bir labirent oluşturan ve yazdıran bir program yazın . Labirent, programın birden çok çalışması için farklı olmalıdır. Yükseklik ve genişlik komut satırı bağımsız değişkenleri olarak verilir. |Dikey duvar, -yatay duvar ve +köşe için kullanın . Labirent duvarlarla sınırlıdır ve girişler eksik duvarla işaretlenmiştir. Labirent, #en az bir girişten erişilebilmesi gereken bir hazine içerir .

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

+1 Harika Soru. Birkaç nokta olsa. 1: Çıkış nasıl işaretlenir? *İki ayrı giriş gibi bir sembol mü yoksa iki giriş mi var? 2: Muhtemelen çıkışın ulaşılabilir olması gerektiğini belirtmelisiniz.
snmcdonald

1
@snmcdonald: eğlenceli hale getirelim ve bir hazine ekleyelim :).
Alexandru

2
Onları çözme hakkında bir takip golf görebilirsiniz ... :)
st0le

@ st0le: Zaten bazı fikirlerim var. Tartışmak isterseniz bana mail atın.
Alexandru

1
Bulmaca türü burada belirtilmedi. İnsanların sanki bir [kod-golf] gibi cevap verdiğini görüyorum. Niyet miydi bu? Öyleyse, lütfen bu şekilde etiketleyin?
dmckee

Yanıtlar:


5

Bu teknik olarak bir labirent jeneratör değil, ama sonuç gibi bir labirent oluşturur düşünüyorum: https://gist.github.com/803450 .

Orada bazı korkunç kod biliyorum ve sadece yarıdan daha az çalışıyor ve sonuç diğer duvarlardan çıkmış duvarlarla yapmak pek doğru görünmüyor. Ama geri kalanını tamir etmekten rahatsız olamayacağım kadar yakın.

Bazı örnek çıktılar:

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

1
İyi fikir. Düzeltirseniz ekstra puan;)
Alexandru

Bu sadece uni ödevlerimden biri için bir labirent oluşturmak için kullandığım bir algoritma için hızlı bir sökme ve çıkış değişikliği oldu . Gerçek algoritma esas olarak CHEVYRAY tarafından yazılan bir blog yayınından çalınıyor . Bu hafta sonu düzeltmek için etrafta dolaşabilirim, çıktı formatının gerçek bir labirent olmadığından tamamen işe yarayıp yaramayacağından emin değilim, ama iyi bakarken mümkün olduğunca yakına getireceğim.
Nemo157

Bana çok iyi bir labirent gibi geliyor.
Alexandru

8

Python, 375 karakter

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

Bu, bir girişi ve rastgele yerleştirilmiş bir hazinesi olan bir labirent oluşturur. Labirent basit bir ikili ağaç labirentidir .

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

Belki amaçlanmıştı, ancak üst sıra (duvarın hemen altında) her zaman uzun bir koridor.
Alexandru

Evet, en soldaki sütun da her zaman uzun bir koridor. Bu, ürettiğim labirent türünün bir özelliğidir.
Keith Randall

Ah. Labirentler olsa çok güzel :).
Alexandru

6

Yakut 1.9.2p136: 90

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

Çıktı

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

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

Hey, kimse bunun iyi bir labirent olması gerektiğini söylemedi . Tamam, tamam, şimdi gerçek bir tane yapacağım.


İyi, ancak protokole uyduğundan emin olun (komut satırından yükseklik ve genişlik, stdout'a yazdırılan labirent).
Alexandru

Aslında stdout hakkında bir şey söylemez (bu da makul bir koşul değildir çünkü birisi stdout'a yazdırılmayan bir dil kullanıyor olabilir) ve girişlerin bir işleve / yönteme ait olduğu genellikle kabul edilir. Aşağıya oy veren kişiye, sorunu belirtilen şekilde çözer, bu yüzden labirentten nefret etmeyin labirentten nefret etmeyin.

Aslında soruda belirtildiği sürece değil. Bkz. Meta.codegolf.stackexchange.com/questions/13/… . Dahası, JavaScript'in aksine Ruby standart çıktıya argüman okuma ve yazmayı destekler. Sorunu doğru şekilde çözen diğerlerine kıyasla çözümünüz hile yapıyor.
Alexandru

Düzenlenemiyor. 'Hile' değil 'eksik' demek istedim. Labirent fikrini seviyorum.
Alexandru

Daha sonra diğer diller, onları aramak veya #!/usr/bin/env pythonörneğin kodlarına dahil etmek için gereken kodu eklemelidir. Dediğim gibi ben de gerçek bir çözüm yazacağım, bu sadece sorunun kendisinin (ve diğerlerinin) kalitesizliğine işaret ediyordu ve daha iyi rehberlere ihtiyacımız olduğunu gösteriyor. Ve son olarak bir soruya işaret etmek, sorunun cevabını site için gerçek kurallar yapmaz. Ama iyi, işte yeni versiyonun ...

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;}

Test etmek için:

#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

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

Bu bir kod mücadelesi , bir kod golfü değil . Neden zar zor okunabilir kod?
Braden Best

-1. Bu kod sadece gizlenmekle kalmaz, aynı zamanda bunun nasıl derlenmesi ve iki kod bloğunun nasıl uygulanması gerektiği konusunda net talimatlar yoktur. Tamamen eksik değilse, kullanım talimatları seyrektir. Cevabınızın bir kod golfü olduğu açık. Ama soru değil . Bu nedenle, kod, kolay kopyalama / yapıştırma / derleme için okunabilir ve kendi kendine yeten olmalıdır, böylece diğerleri, kodun ilk etapta nasıl çalıştığınızı deşifre etmeden gerçekten çalıştığını doğrulayabilir.
Braden Best

0

İşte basit bir java çözümü:

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);
        }
    }
}

Bazı örnek sonuçlar:

3x3:

+ +
|#|
+-+

4x4:

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

4x5:

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

5x5:

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

5x8:

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

8x15:

+---- ----+---+
|         |   |
|         |   |
|         |   |
|             |
| #|      |   |
|         |   |
+---------+---+
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.