打印随机迷宫


19

编写一个程序,使用您选择的算法生成并打印随机迷宫。对于程序的多次运行,迷宫应该不同。高度和宽度作为命令行参数给出。使用|垂直墙,-用于水平壁和+拐角。迷宫被墙壁所包围,入口被缺少的墙壁所标记。迷宫中的宝藏#必须从至少一个入口进入。

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

+1好问题。几点。1:出口如何标记?是像这样的符号,*还是有两个单独的入口?2:您可能应该指定出口必须可到达。
snmcdonald 2011年

1
@snmcdonald:让它变得有趣并添加一个宝藏:)。
Alexandru

2
我可以看到有关解决这些问题的后续高尔夫... :)
st0le 2011年

@ st0le:我已经有了一些想法。如果您想讨论,请给我发邮件。
亚历山德鲁

1
此处未指定拼图类型。我看到人们回答的方式就好像是[代码高尔夫]。那是意图吗?如果是这样,请这样标记吗?
dmckee 2011年

Answers:


5

我认为从技术上讲这不是迷宫生成器,但是会生成类似结果的迷宫:https : //gist.github.com/803450

我知道那里有一些可怕的代码,而且只用了不到一半的时间,并且结果与从其他墙壁伸出来的墙壁看起来不太合适。但是它的距离足够近,我不介意修复其余部分。

一些示例输出:

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

1
好主意。如果您修复它,则加分;)
Alexandru

对于我用于为我的一个单作业生成迷宫的算法来说,这只是快速的删除和输出的改变。实际的算法主要是从CHEVYRAY博客文章中窃取的。我可能会在这个周末修正它,我不确定输出格式是否会完全正常,因为它不是一个真正的迷宫,但是我会尽力使它看起来更美观。
Nemo157

对我来说似乎是一个很好的迷宫。
亚历山德鲁

8

Python,375个字符

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

这将生成一个带有一个入口和一个随机放置的宝藏的迷宫。迷宫是一种简单的二叉树迷宫

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

也许是故意的,但最上面一排(正好在墙下)总是很长的走廊。
亚历山德鲁

是的,最左边的列也总是很长的走廊。这是我正在生成的迷宫类型的属性。
基思·兰德尔

哦。迷宫虽然很好:)。
亚历山德鲁(Alexandru)

6

红宝石1.9.2p136:90

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

输出量

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

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

嘿,没人说这一定是个迷宫。好,好,我现在做一个真实的。


很好,但是请确保它遵守协议(从命令行,从迷宫打印到stdout的高度和宽度)。
亚历山德鲁(Alexandru)

实际上,它没有说出任何关于stdout的信息(这也不是一个合理的规定,因为有人可能正在使用一种不会打印到stdout的语言),并且通常认为输入是针对函数/方法的。对于对此表示反对的人,它解决了指定的问题,因此不要讨厌迷宫者讨厌迷宫。

并非真正地只要它在问题中指定。参见meta.codegolf.stackexchange.com/questions/13/…。此外,与JavaScript不同,Ruby支持对标准输出进行参数读取和写入。与以正确方式解决问题的其他人相比,您的解决方案是作弊的。
亚历山德鲁

无法编辑。我的意思是“不完整”而不是“作弊”。我喜欢迷宫的主意。
亚历山大(Alexandru)

然后,其他语言必须包含调用它们所需的代码,或者#!/usr/bin/env python在其代码中包含。正如我说的那样,我也将写一个真正的解决方案,这只是指出问题本身(以及许多其他问题)的质量很差,并且表明我们需要更好的指导原则。最后指向问题并不能使问题的答案成为站点的实际规则。很好,这是您的新版本...

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

去测试:

#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

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

这是代码挑战,而不是代码高尔夫。为什么几乎不可读的代码?
Braden Best 2014年

-1。不仅会混淆该代码,而且也没有明确说明如何进行编译以及如何实现这两个代码块。使用说明很少,甚至不能完全丢失。显然,您的答案是一个代码高尔夫。但是问题不是。因此,代码应易于阅读,并具有独立性,以便于复制/粘贴/编译,以便其他人可以验证它确实有效,而不必首先弄清楚代码的工作方式。
Braden Best 2014年

0

这是一个简单的java解决方案:

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

一些样本结果:

3x3:

+ +
|#|
+-+

4x4:

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

4x5:

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

5x5:

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

5x8:

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

8x15:

+---- ----+---+
|         |   |
|         |   |
|         |   |
|             |
| #|      |   |
|         |   |
+---------+---+
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.