迷宫生成


41

我知道有一个与此(此处)类似的(旧)线程,但是我想进行一些修改来重新启动它。

目标:使用您选择的算法生成外观随机的迷宫,然后以图形方式输出迷宫(打印计数)。

  • 宽度和高度由您确定。
  • 从至少一个入口到至少一个出口应该有至少一条路径。
  • 迷宫的格式(如何显示,标记入口或出口)也取决于您。
  • 越漂亮越好。
  • 不鼓励琐碎的迷宫(例如空白迷宫,格子迷宫,大小为1x1的迷宫)。
  • 如果结果合理,则允许并鼓励迷宫中的循环。
  • 鼓励语言滥用。
  • 迷宫应该看起来相当随机(但是完全确定性的(例如混沌)算法也可以)。

编辑:这里的主要重点是使最小的实现。但是,我想在此限制范围内留出一些余地,以鼓励保持柔韧性。我故意留下了迷宫开放式的“特征”,但是作为一个粗略的指导原则,您应该尝试将最多的爆炸归入最小的词汇量。


4
同样,“更漂亮,更好”似乎很难与代码高尔夫挑战相提并论(或根本不相关)。如果您对漂亮的结果感兴趣,也许参加人气比赛是更好的选择。
Martin Ender 2014年

5
那么,它真的是代码高尔夫吗?还是颇受欢迎的比赛?
l0b0

2
另一个建议是,如果您想同时激励短代码和整洁的迷宫,则可以将其设置为代码挑战,并声明将以代码长度和投票的混合得分来选择优胜者-尽管这样做会由您来确定每个答案的总分,因为在帖子中包含当前的投票数是没有用的。
Martin Ender 2014年

3
我认为每个答案都应解释每个迷宫中的入口和出口(以及什么是墙和什么是通道)的构成,以便我们评估第二个项目符号。
LarsH 2014年

2
@Geobits我不太介意,但是我的建议是将代码长度和投票综合评分,使其真正成为代码挑战。这确实会鼓励OP想要的东西:有趣的迷宫的短代码。
Martin Ender

Answers:


10

C:265个 253字节

#define f(v)for(v=0;v<k;++v)
#define d(q,n)case q:r(c+n,c+2*n);
z[4225],i,j,k=65;r(p,c){if(!z[c]){z[p]=z[c]=1;f(p)switch(rand()%4){d(0,-k)d(1,k)d(2,-1)d(3,1)}}}main(){f(i)z[i]=z[i+4160]=z[i*k]=z[i*k+64]=z[4157]=1;r(67,132);f(i)f(j)putchar(33-z[i*k+j]);}

(需要65个字符的终端)生成一个相对随机的31x31迷宫,从入口到出口都有一条保证路径。

输出示例(带有模拟的65个字符的端子):

 ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
 !     !       !   !       !     !           !             !   ! 
 !!!!! !!! !!! ! !!! ! !!! ! !!! !!!!!!! !!! !!!!!!!!! !!! ! ! ! 
 !   !   !   ! !     ! ! ! ! ! ! !       !   !         !   ! ! ! 
 ! !!!!! !!! ! !!!!!!! ! ! ! ! ! ! !!!!!!! !!! ! !!!!!!! !!! ! ! 
 !     !     !         ! !   !   !     !   !   ! !     !   ! ! ! 
 ! !!! !!!!!!!!!!!!!!!!! !!!!! !!! !!! !!! ! ! !!! !!! !!! !!! ! 
 !   !         !     !   !     !     !   ! ! ! !     !   !   ! ! 
 !!!!!!!!!!! ! ! !!! !!! ! !!!!!!!!!!!!! ! !!! ! !!!!!!! !!! ! ! 
 !           !   !       ! !             !   !     !     !     ! 
 ! !!!!!!! !!!!!!! !!!!!!! ! !!!!!!!!!!!!!!! !!!!!!! !!!!!!!!!!! 
 ! !     ! !   !     !   ! !           !   !       ! !         ! 
 ! !!! ! ! ! ! !!!!!!! ! ! ! !!!!!!!!! ! ! !!!!!!! ! ! !!!!!!! ! 
 !   ! !   ! !       ! !   ! !         ! !       ! ! !   !   ! ! 
 !!! ! !!!!! !!!!!!! ! !!!!!!! !!!!!!!!! !!! !!!!! ! !!! ! !!! ! 
 !   !   ! ! !       !   !     !   !     ! !           ! !   ! ! 
 ! !!!!! ! ! ! !!!!!!!!! ! !!!!! !!! !!!!! !!!!!!!!!!! ! ! ! ! ! 
 ! !       ! !   !   !   ! !       ! !       !   !     ! ! ! ! ! 
 ! !!!!!!!!! !!! ! ! ! !!! !!!!!!! ! !!!!!!! ! ! !!!!!!! !!! ! ! 
 !             !   ! !   !       ! !     !   ! !             ! ! 
 !!!!!!!!!!!!!!!!!!! !!! !!!!!!! ! !!!!! ! !!! !!!!!!!!!!!!!!! ! 
 !               !   !   !       !         !   !     !   !     ! 
 ! !!!!!!!!!!!!! ! ! ! !!! !!!!!!! !!!!!!!!! !!! !!! !!! ! !!! ! 
 ! !   !       !   ! ! ! !     ! ! ! !     !     !   !   !   ! ! 
 ! ! ! !!!!! !!!!!!! ! ! ! !!! ! ! ! ! !!! !!!!!!! !!! !!!!! !!! 
 !   ! !   !       ! ! !     ! !     ! ! !     !   !       !   ! 
 !!!!! ! ! !!! !!! ! ! !!!!!!! !!!!!!! ! ! !!! ! !!!!!!!!! !!! ! 
 !     ! !   !   !   !       !       ! ! ! !   !   !         ! ! 
 ! !!!!! !!! !!! !!!!!!!!!!! !!!!!!! ! ! ! !!!!!!! ! !!!!!!! ! ! 
 !         ! !           !   !       ! ! !     !   ! !       ! ! 
 !!!!!!!!!!! !!!!!!!!!!! ! !!! !!!!!!! ! !!!!! ! !!! !!!!!!!!! ! 
 !         !     !     ! ! !       !   !     ! !     !         ! 
 ! !!!!!!! !!!!! ! !!! !!! !!!!!!! ! !!!!! ! ! !!!!! ! !!!!!!!!! 
 ! !     !     !   ! !   !       ! !       ! !       !         ! 
 ! ! !!! !!!!! ! !!! !!! !!!!!!! ! !!!!!!!!! !!!!!!!!!!!!!!!!! ! 
 !     !     ! !   !   ! !     ! !       !   ! !     !         ! 
 !!!!!!!!!!! ! !!! !!! ! ! ! !!! ! ! !!!!! !!! ! !!! ! !!!!!!! ! 
 !           ! !       !   ! !   ! !       !   ! ! ! !     !   ! 
 ! !!!!!!!!!!! !!!!!!!!!!!!! ! !!! !!!!!!!!!!! ! ! ! ! !!! ! !!! 
 !       !   !             ! ! ! !   !         ! !   !   ! ! ! ! 
 !!!!!!! !!! !!!!!!!!!!!!! ! ! ! !!! ! !!!!!!! ! !!! !!!!! ! ! ! 
 !       !         !     ! ! ! !   !   !     ! !   !       !   ! 
 ! !!!!!!! !!!!!!! ! !!!!! ! ! !!! !!!!!!! ! ! !!! !!!!!!!!!!!!! 
 !   !         ! !   !       ! !           ! !   !             ! 
 ! ! ! !!!!!!! ! ! !!! !!!!!!! ! !!!!!!!!!!! ! !!!!!!!!!!!!!!! ! 
 ! ! ! !     ! !   !   ! !     !   !   !     ! !               ! 
 ! ! !!! !!! ! !!!!! !!! ! !!!!! ! ! ! !!!!!!! ! !!!!!!!!!!!!! ! 
 ! !   !   ! !   !       !   !   !   !         ! !         !   ! 
 !!!!! !!! ! !!! ! !!!!!!!!! !!!!!!! !!!!!!!!!!! !!!!! !!!!! !!! 
 !     !   !   !   !       !       !       !   !     !       ! ! 
 ! !!!!! !!!!! !!!!! !!!!! !!!!!!! !!!!!!!!! ! !!!!! !!!!!!! ! ! 
 !           !     ! !   !   !   !           !   !   !     !   ! 
 ! !!!!!!!!! !!!!! ! !!! ! !!! ! !!!!!!!!!!!!!!! ! !!! !!! !!! ! 
 ! !     !       ! !     !     !     !         ! !       !   ! ! 
 !!! !!! !!!!!!!!! !!!!! !!!!!!!!! ! !!!!!!! !!! ! !!!!!!!!! ! ! 
 !   !     !   !   !   ! !       ! !         !   ! !         ! ! 
 ! !!!!!!! ! ! ! ! !!! ! !!!!!!! ! !!!!!!!!! ! !!!!! !!!!!!!!! ! 
 !       !   !   ! !   !         !   ! !   ! ! !     !       ! ! 
 ! !!!!! !!!!!!!!! ! !!!!!!!!!!! !!! ! ! ! ! ! ! !!!!! !!!!! ! ! 
 ! !     !           !         ! ! ! !   !   ! !   !   !     ! ! 
 ! ! !!!!!!!!!!!!!!!!! !!! !!!!! ! ! !!!!!!!!! !!! ! !!!!!!!!! ! 
 ! !                     !         !               !           ! 
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ! 

2
您甚至都不需要int p,int cp,c够了……
chubakueno 2014年

啊,谢谢你指出这一点
Dendrobium

34

Mathematica,144 132个字节

自从盗版以来,我们都知道绘制迷宫的最有效方法

c=0;Graphics@Most[Join@@{Circle[{0,0},i,{a=c-(r=Random[](d=2Pi-1/i)&)[],a+d}],Line[{{i},{i+1}}.{{Cos[c=a+r[]],Sin@c}}]}~Table~{i,9}]

取消示例输出:

在此处输入图片说明

当然,线条是墙壁。你是牛头怪,从中心开始,需要下车。


4
这很漂亮,代码也很短,但是我想说的是,这是频谱的“琐碎迷宫”。
LarsH 2014年

2
您说得对,将其放大不会改变其琐碎性。关键是解决这个迷宫是一个线性过程:在每个关头,您都可以快速找出自己是否走错了方向,而不必“递归”到更深的分支中。另一方面,伊恩(Ian)和阿莱夫(aleph)的答案是“真实的”迷宫:它们无法以这种线性方式解决。由于不建议使用琐碎的迷宫,因此我很乐意拒绝这一迷宫,但是我没有足够的代表。
LarsH 2014年

1
@LarsH是的,我们对此表示同意。这就是为什么我说这是绘制迷宫的最“有效”方式,而不是最“有效”的一种方式。;)也许很简单,但是我不认为它属于“空白”或“ 1x1”之类的排除类别。当然,OP因其简单性而有权取消此提交的资格,但只要他不这样做或更改挑战的类型,我就没有动力使其变得更加复杂/有趣。
马丁·恩德

1
话虽这么说,@ LarsH,我不确定这是由于他们的算法还是仅仅是他们发布的特定示例的功能,但是他们的答案都不需要多次回溯到深度“ 1”以上。因此,尽管它们确实包含很多复杂性,但它们全都与路径无关。
马丁·恩德

1
我认为,即使很容易,迷宫也不是一件小事(下面的圆形迷宫更是琐碎的)。我真的只是想防止blank-canvas / size-1 / etc。“迷宫”。
imallett 2014年

33

C:364字节

#define I int
m[1600],i=0,r;f(I x,I y,I l){m[80*y+x]|=l;I d[]={x-1,y,2,1,x+1,y,1,2,x,y-1,8,4,x,y+1,4,8},
s[]={5,5,5,5},j=0;for(;j<4;){L:r=rand()%4;for(I k=0;k<4;)if(s[k++]==r)goto L;s[j]=r;I*p=d+
4*s[j++],X=p[0],Y=p[1];if(!(X<0|X>79|Y<0|Y>19|m[80*Y+X])){f(X,Y,p[2]);m[80*y+x]|=p[3];}}}
main(){f(0,0,4);m[9]|=4;for(;i<1600;)putchar("#5FMP<HJR;IK:9LN"[m[i++]]+128);}

注意:在上面,我添加了换行符以使其适合页面。预期输出(在80个字符的终端上)(注意左上角的开始和结束): 在此处输入图片说明


8
@bwoebi MSPaint进行了救援!图像
壁虎天花板

6
请注意,我的意图是使路径位于管道内部(如此处所示)
imallett 2014年

1
@IanMallett我认为Ceiling Gecko知道了这一点,但是用一种颜色在左墙中填充颜色会为您提供一条沿着左墙的(非最佳)路径,直到找到出口为止。;)
Martin Ender 2014年

1
如果您有时间,我想看看这段代码的非公开版本。
LarsH 2014年

4
在您撰写本文时,您是一个迷宫式编码员。
totymedli 2014年

24

Mathematica,134,130个字符

Graph[Range@273,Reap[Do[c@n/._c:>#0[Sow[#<->n];n],{n,RandomSample@AdjacencyList[g=GridGraph@{13,21},c@#=#]}]&@1][[2,1]],Options@g]

迷宫


实际上,我们可以使用此算法从任何(无向)图生成迷宫。

例如,根据8 * 8 骑士的游览图KnightTourGraph[8,8])生成一个迷宫:

骑士的游览图

Graph[Range@64,Reap[Do[c@n/._c:>#0[Sow[#<->n];n],{n,RandomSample@AdjacencyList[g=KnightTourGraph[8,8],c@#=#]}]&@1][[2,1]],Options@g]

迷宫2


7
迷宫不错...但是我看不到与出口相连的任何入口...?
bwoebi 2014年

9
我相信这个想法是选择一个随机节点(例如左上)作为入口,选择另一个节点(右下)作为出口。Mathematica确保所有节点都与所有其他节点连接,但是-尤其是在第二个迷宫中-查找如何连接是更困难的部分。
EagleV_Attnam 2014年

线条(图形边缘)应该是迷宫墙还是通道?我以为我知道,但是现在我不确定。
LarsH 2014年

@LarsH他们是段落。
alephalpha 2014年

1
@LarsH该图已连接,因此您可以只取两个任意节点,一个作为入口,另一个作为出口。
alephalpha 2014年

13

Bash,53个字节

w=(╱ ╲);while true;do echo -n ${w[RANDOM%2]};done

与C64代码类似的想法。使用Unicode字符作为斜杠,因为它们在支持Unicode的终端中看起来更好。OS X终端上的示例输出(Menlo字体):

样品迷宫输出


2
有一次,我想通了这一点:yes 'c=(╱ ╲);printf ${c[RANDOM%2]}'|bash。看到这个帖子
gniourf_gniourf 2014年

5
这是基于一种无法保证自身可解决的算法,这种算法已有很长时间了。
Isiah Meadows 2014年

9

JavaScript(ES6),第174页

这是建设者我使用的迷宫这个其他的挑战,只是golfed。该函数具有2个参数:行和列。迷宫完全没有环连接,因此任何位置都可以作为起点或终点。

(r,c,o=2*c+2,i=2*r*o+o,z=[],F=(p,i=Math.random()*4)=>[o,1,-o,-1].map((s,j,d)=>z[s=p+2*d[j+i&3]]>0&&(z[s]=z[(p+s)/2]=' ',F(s))))=>{for(;i--;)z[i]=i%o?8:`\n`;F(o+2);return''+z}

f(7,10)

输出量

,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
,8, , , ,8, , , , , ,8, , , , , , , , , ,8,
,8, ,8, ,8,8,8, ,8, ,8,8,8,8,8,8,8, ,8, ,8,
,8, , , ,8, , , ,8, , , ,8, , , , , ,8, ,8,
,8, ,8,8,8, ,8,8,8,8,8, ,8, ,8,8,8,8,8, ,8,
,8, ,8, , , , , ,8, ,8, ,8, ,8, , , , , ,8,
,8, ,8, ,8,8,8, ,8, ,8, ,8, ,8, ,8,8,8,8,8,
,8, ,8, ,8, , , ,8, , , , , ,8, ,8, , , ,8,
,8, ,8, ,8, ,8,8,8,8,8,8,8,8,8, ,8, ,8,8,8,
,8, ,8, ,8, , , , , , , ,8, , , ,8, , , ,8,
,8, ,8, ,8,8,8,8,8,8,8, ,8,8,8, ,8,8,8, ,8,
,8, ,8, , , , , , , ,8, , , ,8, , , , , ,8,
,8, ,8,8,8,8,8,8,8,8,8,8,8, ,8,8,8,8,8, ,8,
,8, , , , , , , , , , , , , ,8, , , , , ,8,
,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8

测试

f=
(r,c,o=2*c+2,i=2*r*o+o,z=[],F=(p,i=Math.random()*4)=>[o,1,-o,-1].map((s,j,d)=>z[s=p+2*d[j+i&3]]>0&&(z[s]=z[(p+s)/2]=' ',F(s))))=>{for(;i--;)z[i]=i%o?8:`\n`;F(o+2);return''+z}
    
function update() {    
  O.textContent='';
  [r,c]=I.value.match(/\d+/g)
  O.textContent=f(r,c)
}  

update()
pre { line-height: 0.8em }
Rows,Columns <input id=I oninput='update()' value='8,12'>
<pre id=O></pre>


我不确定...迷宫是浅色还是深色?如果天黑了,那就有一个很大的循环,选择任何一点作为进/出点时,都可以呆在外面。如果灯亮,则应添加出口/入口。
圣保罗Ebermann

1
@PaŭloEbermann当然是光,黑暗的地方是墙壁。
再说一遍

哇,真是太神奇了!削掉一些字节,然后减少到133字节:twitter.com/aemkei/status/889587308894326785 但是所有功劳应该归您所有!
aemkei

@aemkei 8而不是'#',我不敢相信我当时错过了
edc65

8

ZX Basic-54个字符

a$="/\":for i=1 to 24*32:print a$(1+int(rnd*2));:next

输出量

这是迷宫,显示通过它的路线(线之间的间隔)

路径

还有几年前我刚开始做此操作时的一小段代码,并花了一些时间来制作更好的图形。

更好的图形


2
嗯,厚脸皮。^^那里是什么开始和结束?斜线是路径还是墙壁?我可以通过的最小间隙尺寸是多少?
Martin Ender 2014年

2
“从至少一个入口到至少一个出口应该至少有一条路径。” 我没有任何迹象表明符合此条件。随机的墙壁不一定会造成迷宫。
LarsH 2014年

1
@ m.buettner:我猜斜线是墙,我们应该将其可视化,好像行与列之间的空间为零。因此,左下角的2x2字符形成一个完全封闭的菱形(正方形)形状。
LarsH 2014年

@LarsH是的,我是这么认为的。在OP的问题上,这应该为您的案例提供另一点,即人们应该指出开始和结束的时间。另外,该方案甚至不允许结点。您只能使用那些闭合的正方形或曲折的路径(也可能是闭合的回路)。
Martin Ender 2014年

+1用于改进图形并显示路线。我想如果有这么多潜在的入口和出口,那么“从至少一个入口到至少一个出口的至少一条路径”的可能性非常高!
LarsH 2014年

8

BBC BASIC,18字节

@nneonneo对23字节C64无限循环版本的长度进行了改进。VDU将单个字符发送到VDU控制器:2 + 1 * 45 = ASCII 47 /或2 + 2 * 45 = ASCII 92\

  VDU2+RND(2)*45:RUN

BBC BASIC,35字节/ 107 95字节

35字节仅用于最后一行,它以40列的布局提供了25行迷宫。MODE1确保线路之间没有多余的空间。该程序的其余部分是可选的,可以改善格式。VDU23语句重新定义了字符47和92(8个字节构成一个8x8位图)的字体。我在所有四个角中都包含一个亮像素,以防止笔直奔跑。这样做的副作用是在空钻石中出现一个点。总共107个字节,其中包括2个换行符。

  VDU23,47,131,7,14,28,56,112,224,193
  VDU23,92,193,224,112,56,28,14,7,131
  MODE9FORa=0TO999VDU2+RND(2)*45:NEXT

编辑这个程序可以通过编码部分8位VDU码成16被缩短为95个字节位(后他们而不是逗号用分号表示)小端值和表示MODE语句作为对VDU码,如下。

VDU23,47,1923;7182;28728;49632;23,92,57537;14448;3612;33543;22,9:FORa=0TO999VDU2+RND(2)*45:NEXT

输出量

从bbcbasic.co.uk为Windows使用BBC Basic

仅最后一行,35个字节

在此处输入图片说明

整个程序,107 95字节

当我评论@Brian的答案时,斜线将正方形分为2个黑色三角形,每个三角形都有2个入口/出口。这保证了从迷宫边缘上的任何点到迷宫边缘上的其他点的(简单的,无分支的)路径。其中许多很短,但是似乎总是有些长。当然,在迷宫中间也有一些循环。

正如其他答案没有提到的那样,我想对亮区进行一下很好的了解。这些区域以暗区为边界,因此,作为上述陈述的推论,外部有N个暗区为界的亮区在N个点(恰好是许多个)上接触了场的边缘。因此,会出现一些相当大的光线区域,这些区域会形成有趣的分支迷宫。

在下面的示例中,您可以从我的程序中看到原始输出(单色)。在此之下(使用Windows Paint),我将两个最长的深色区域涂成蓝色。然后,我将最大的亮色区域染成黄色,并将两个区域分别用红色和绿色染成蓝色。黄色,绿色(甚至红色)的迷宫非常有趣且微不足道。

在此处输入图片说明

编辑-自动选择迷宫和选择开始/结束

对于另外一行(59个字符),该程序可以通过随机选择正方形并自动填充红色,绿色,黄色,蓝色,洋红色和青色的颜色自动选择多达6个迷宫。它并不总是找到完整的6,因为如果它选择一个已经着色的随机正方形,则它什么也不做。

下面的其余代码通过从上至下,从左至右扫描各列,并选择遇到的第一个正方形,为每种颜色选择一个起点。它通过沿相反方向扫描来选择一端。

这产生了一组彩色的,相互交织的迷宫。有时它们是如此交织在一起,看起来迷宫必须穿过某个地方。但是,当然不!

附加代码并输出59 + 187 = 246附加字符要添加到原始程序的末尾(用于超出问题说明的增强)。

  GCOL135FORa=1TO6GCOLa FILLRND(40)*32-16,RND(25)*32+208:NEXT   :REM set background to grey so fill can identify. For each colour 1 to 6, pick a point in the centre of a character and flood fill (characters are logically 32x32 although they are physically only 8x8 pixels.)
  f=126:g=126                                                   :REM flags 1111110 to indicate which starts and ends have not been allocated yet
  FORx=0TO39FORy=0TO24                                          :REM maze is 40x25. There is some blank space at the bottom of the screen (32 rows total)
  p=POINT(x*32+16,1008-y*32)                                    :REM check start point. Text origin is at top of screen, Graphics origin is at bottom, 1280x1024 logical. therefore y offset is 1024-32/2=1008.
  IFf AND2^p f=f-2^p:VDU31,x,y,17,p,79                          :REM if start for colour P has not been allocated yet, allocate it now. VDU31,X,Y go to that square. VDU 17,p select text colour. VDU 79 print an "O"                 
  p=POINT(1264-x*32,240+y*32)                                   :REM check end point
  IFg AND2^p g=g-2^p:VDU31,39-x,24-y,17,p,79                    :REM if end for colour P has not been allocated yet, allocate it now.
  NEXT:NEXT
  VDU31;26                                                      :REM get the cursor off the board. Move to (0,26). Semicolon used instead of comma here indicating that 31 is a 16 bit small endian value, equivalent to VDU31,0,26 or PRINTTAB(0,26)

在此处输入图片说明


7

C:235字节

#define P(X,Y)M[(Y+40)*80+X+40]=rand()%49/6;
#define B(X,Y)P(X,Y)P(Y,X)
M[6400],r,i;main(){for(i=0;i<40;i+=2){int x=i,y=0,e=1-x;while(x>=y)
{B(x,y)B(-x,y)B(-x,-y)B(x,-y)++y;e+=e<0?2*y+1:2*(y-x--);}}for(i=0;
i<6400;)putchar(64>>!M[i++]);}

注意:在上面,我添加了换行符以使其适合页面。预期输出(在80个字符的终端上):在此处输入图片说明

我感到遗憾的是,这并不是一个非常困难的迷宫(实际上,不需要回溯到内圈(并且您应该能够轻松地找到从周界到中心的路径)。但是,它可以很好地实现布雷森汉姆圆绘图算法为核心。


很难看到您可以通过和无法通过的地方。我不得不说,我更喜欢管道;)(对此以及我的通函都没有)。
Martin Ender 2014年

@ m.buettner:我真的同意。如果将更i+=2改为i+=3,可能会更清楚发生了什么。
imallett 2014年

6

我帮助我的孩子做到了这一点,学习了一些编程知识:http : //jsfiddle.net/fs2000/4KLUC/34/ 您感觉如何?


17
如果您可以将代码放入该帖子中,请执行此操作。此外,还包括#Language(s)-Bytecount之类的标头。如果您仅在代码中使用ASCII字符,则可以在此处获得一个不错的字节数。有关您的代码功能,您可能拥有的任何见解或您所做的任何聪明的事情的摘要,可能对您的帖子有所帮助。顺便说一句,达斯·维达(Darth Vader)很难看清其中一些线条。最后,欢迎来到Code Golf!
Rainbolt 2014年

您与孩子一起学习了一些编程,而我也学到了一些高尔夫。这是我第一次打高尔夫球,结果仍然很长。字节数:原始:55 + 6822 = 6877。 重组:39 + 3131 = 3170 高尔夫:39 + 1593 = 1632
BartekChom

6

Commodore 64 BASIC-38字节

10 PRINT CHR$(205.5+RND(1)); : GOTO 10

这不是我的发明,我只是重复过去的一段非常漂亮而简短的程序。实际上,有一整本书都在10 PRINT CHR$(205.5+RND(1)); : GOTO 10庆祝这段代码!

您可以在此YouTube视频上看到输出;这是一个屏幕截图:

YouTube屏幕截图

这是这个StackOverflow问题,是这个迷宫生成器程序的更多实现。该程序的最短实现是该问题的作者发布的以下23字节​​C64 BASIC程序:

1?cH(109.5+rN(1));:gO1

其中按原样输入小写字母,并使用Shift键输入大写字母(在实际的C64屏幕上,它们具有不同的外观)。


这不是Brian的陈述吗?(短一点)那么Bash的答案也是吗?那么这里的问题也是,没有连接的迷宫还是迷宫吗?
Martin Ender 2014年

nneonneo,+ 1是对这个好主意的正确诚实的归因。@ m.buettner如您所指出,未打印的区域会产生未分支的迷宫。但是(令我惊讶的是,没有其他人展示过这个)印刷区域形成了一些有趣的,非平凡的,分支的迷宫(请参阅我的回答。)我也正在迷宫,因为它具有最佳的开始和结束位置。在这些对角迷宫上定义起点和终点并不容易。
等级河圣

@ m.buettner 1. x86二进制文件最小为10个字节。2.这是一种完善的算法,既不是原始算法,也不是要创建可解决的迷宫。
Isiah Meadows 2014年

5

爪哇:700

这是一个递归墙加法器。该算法在此站点上概述:

public class Z{int i,j,u=20,v=u,g[][]=new int[v][u];public static void main(String[]a){new Z().d(0,0,20,20,0).p();}int q(int m){return(int)(Math.random()*m);}<T>void z(T m){System.out.print(m);}void p(){for(i=0;i++<u*2;z("_"));for(i=0;i<v;i++){z("\n|");for(j=0;j<u;j++){boolean b=i+2>v,s=g[i][j]%2>0||b;z(s?"_":" ");z(g[i][j]>1||j+2>u?"|":s&(j+1<u&&g[i][j+1]%2>0||b)?"_":" ");}}}Z d(int x,int y,int w,int h,int o){int a=x,b=y,c=a,d=b,e,f;boolean t=o<1;if(t){b+=q(h-2);c+=q(w);}else{a+=q(w-2);d+=q(h);}for(i=t?w:h;i-->0;j=t?a++:b++)if(a!=c&&b!=d)g[b][a]|=t?1:2;e=t?w:a-x+1;f=t?b-y+1:h;if(e>2&&f>2)d(x,y,e,f,e<f?0:1);e=t?w:x+w-a-1;f=t?y+h-b-1:h;if(e>2&&f>2)d(t?x:a+1,t?b+1:y,e,f,e<f?0:1);return this;}}

基本上,它将每个矩形与墙壁(和通道)一分为二,然后将其一分为二,依此类推。它生成一个“完美的”迷宫-一个没有循环的迷宫-迷宫般的路径从每个点到另一个点。大量死角,因此对于较大的迷宫在任何意义上都不是“琐碎的”。

因此,入口和出口可以任意确定。如果我必须选择一个,它只会说上/左和下/右。

它以双倍宽度的ascii绘制,因此,如果您要执行任何大小的操作,最好将输出通过管道传输到文件。这是20x20的控制台:

20x20

还有一个100x100的记事本++(我必须缩小以获取所有信息,所以有点... ):

100x100

带换行符的代码:

public class Z{
    int i,j,u=20,v=u,g[][]=new int[v][u];
    public static void main(String[]a){
        new Z().d(0,0,20,20,0).p();
    }

    int q(int m){return(int)(Math.random()*m);}
    <T>void z(T m){System.out.print(m);}

    void p(){
        for(i=0;i++<u*2;z("_"));
        for(i=0;i<v;i++){
            z("\n|");
            for(j=0;j<u;j++){
                boolean b=i+2>v,s=g[i][j]%2>0||b;
                z(s?"_":" ");
                z(g[i][j]>1||j+2>u?"|":s&(j+1<u&&g[i][j+1]%2>0||b)?"_":" ");
            }
        }
    }

    Z d(int x,int y,int w,int h,int o){
        int a=x,b=y,c=a,d=b,e,f;
        boolean t=o<1;
        if(t){
            b+=q(h-2);
            c+=q(w);
            }
        else{
            a+=q(w-2);
            d+=q(h);
        }

        for(i=t?w:h;i-->0;j=t?a++:b++)
            if(a!=c&&b!=d)
                g[b][a]|=t?1:2;

        e=t?w:a-x+1;f=t?b-y+1:h;
        if(e>2&&f>2)d(x,y,e,f,e<f?0:1);
        e=t?w:x+w-a-1;f=t?y+h-b-1:h;
        if(e>2&&f>2)d(t?x:a+1,t?b+1:y,e,f,e<f?0:1);
        return this;
    }
}

2

ZX Basic-281个字符

这更像是一个“适当的”迷宫,高尔夫球手更少,但迷宫效果更大。所谓的二进制迷宫算法,每个单元可以有一个向下或向右的出口,但不能同时出口。(现在包括标记为“ S”和“ E”的开始,以防止仅沿一侧笔直移动)。

ZXB的“ ::”是将Spectrum图形字符输入到文本文件中的方式,等同于出售的块字符。

randomize:border 1:paper 1:ink 6:cls
for x=0 to 30 step 2
 for y=0 to 20 step 2
  r=1+int(rnd*2)
  if x=30 and r=1 then 
   r=2
  end if
  if y=20 and r=2 then
   r=1
  end if
  print at y,x;"\::"
  print at y+(r=2),x+(r=1);"\::"
 next
next
print inverse 1;at 0,0;"S";at 20,31;"E"

迷宫


2
不,我实际上是说您应该互换起点和终点(起点右下,终点左上)。就目前而言,它是微不足道的,因为由于规则的限制,您必须一直走下去,一直走到最后。
Martin Ender 2014年

1
即使起点和终点相反,迷宫也具有(也许很有趣)的特性,即正确的路径只会向上和向左移动。但是,迷宫不再是微不足道的了,因为在很多地方您可以采用以下两种方法之一。
凯文-恢复莫妮卡2014年

1

C- 244

#include <unistd.h>
#include <windows.h>
int main(i,j,rv,rs){srand( time(0));for (i = 0; i < 80; i++)for (j = 0; j <50 ; j++){rv = rand() %10;rs = rand() %100;if(rs < 10 || rs  > 90)continue;if(rv<4){gotoxy(i,j);printf("%c", '#');}}return 0;}

看起来是这样的:

迷宫

注意:此解决方案的灵感来自不受信任的 8级游戏:进入树林。

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.