请问C中怎样随机生成一个迷宫,又要保证只有一条出路?

superever 2004-03-27 09:17:28
我想用C语言做一走迷宫的小游戏,现在其他模块都完成,就是随机生成的地图,我不能保证始终有出路,请问有什么办法可以随机生成一条出路?
...全文
740 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
hanyimath 2004-03-30
  • 打赏
  • 举报
回复
up
longj 2004-03-29
  • 打赏
  • 举报
回复
这样吧!

1。 先在全是墙壁的数组里开出一条通路,不分叉,不形成环,可以有弯曲
2。 再在这条路上随机选取一些点
3。 以这些点为基础生成一条死路,该死路不出迷宫,不与已经同的点连通。


superever 2004-03-29
  • 打赏
  • 举报
回复
我还没有完全明白bshaozi(耗子)朋友的意思,你可不可以说详细些,谢谢你了!
我的迷宫是40*40的,我用board[x][y]=1表示墙壁块,board[x][y]=0表示通道块
rorot 2004-03-29
  • 打赏
  • 举报
回复
俺试试用数学算一下看行不行,不过俺数学学的不好。唉..~
f123 2004-03-28
  • 打赏
  • 举报
回复
象以前玩的炸弹人里面那样,迷宫的复杂度会升高的。
横排和竖排的墙壁的打开概率也不同,自己尝试,也会增高迷宫的复杂度。
f123 2004-03-28
  • 打赏
  • 举报
回复
用着色法验证,凡是已经连成一片用同样的颜色标记。在打穿墙壁的时候记着不要将同色的空白连起来就行了。
程序很简单的,我以前初中的时候就用学习机编过类似的程序。

最初的迷宫这样设置:
OOOOOOOOOOOOOOO
O O O O O O O O
OOOOOOOOOOOOOOO
O O O O O O O O
OOOOOOOOOOOOOOO
UEYS
f123 2004-03-28
  • 打赏
  • 举报
回复
不用这么麻烦,先画一个满是墙壁的迷宫,再直接用随机数打穿墙壁。在打穿墙壁的时候用记着验证一下,不要重现环路就行了。
rorot 2004-03-28
  • 打赏
  • 举报
回复
思路不错。。。。
bshaozi 2004-03-28
  • 打赏
  • 举报
回复
可以用随即函数设置i,j
因为要保证有一条道路,那么在每一列(或者每一行)只有一个1(或者0)
先将迷宫数组的元素全设置0(或者是1);
然后将随即取到的i,j设置为1(或者是0);
看看这样行不行~
superever 2004-03-28
  • 打赏
  • 举报
回复
就算是能够生成通路,但是总是存在一条通路,他出现的概率很大,也就是说,n次开局生成的n条通路中,它们的走向总是会趋向于定值,比如,这n条通路的走向大部分都是先向下然后向右,这就造成了一种必然结果了,没有达到随机的目的,不知道该怎样解决?
superever 2004-03-28
  • 打赏
  • 举报
回复
看起来没有什么问题,可是怎么会不能开辟正确的通路呢?
superever 2004-03-28
  • 打赏
  • 举报
回复
我的部分代码:(请帮忙看一下!拜托了!)

堆栈相关代码如下:
enum bool{false,true};
typedef struct
{
int x;
int y;
int di;
}SElemType;

typedef struct
{
SElemType *base;
SElemType *top;
int stacksize;
}Stack;

enum bool InitStack(Stack* s)
{
s->base=(SElemType*)malloc(sizeof(SElemType)*STACK_INIT_SIZE);
if(!(s->base))
{
printf("Can't alloc space for satck!\n");
exit(-1);
}
s->top=s->base;
s->stacksize=STACK_INIT_SIZE;
return true;
}

enum bool StackEmpty(Stack s)
{
if(s.top==s.base)
return true;
return false;
}

enum bool Push(Stack *s,SElemType e)
{
if(s->top-s->base>=s->stacksize)
{
s->base=(SElemType*)realloc(s->base,
(s->stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!(s->base))
{
printf("Can not alloc space for stack!\n");
exit(-1);
}
s->top=s->base+s->stacksize;
}
/* *((s->top)++)=e;*/
((s->top)++)->x=e.x;
(s->top-1)->y=e.y;
(s->top-1)->di=e.di;
return true;
}

enum bool Pop(Stack *s,SElemType *e)
{
if(!StackEmpty(*s))
{
e->x=(--(s->top))->x;
e->y=(s->top)->y;
e->di=(s->top)->di;
return true;
}
return false;
}

我生成地图用的以下函数:
enum bool MakeOut(int x,int y) /*x和y为入口坐标,出口坐标为(40,40)*/
{
SElemType e;
Stack in;
InitStack(&in);
e.x=x;
e.y=y;
e.di=rand()%2;
do
{
if(Enable(e.x,e.y))
{
Push(&in,e);
board[e.x][e.y]=2;
if(e.x>=40&&e.y>=40)
break;
e.di=rand()%4;
e.x+=move[e.di];
e.y+=move[e.di+4];
}
else
{
if(!StackEmpty(in))
{
Pop(&in,&e);
while((!Enable(e.x+1,e.y))&&(!Enable (e.x,e.y+1))&&(!Enable(e.x-1,e.y))&&(!Enable(e.x,e.y-1))&&
!StackEmpty(in))
{
board[e.x][e.y]=-1;
Pop(&in,&e);
}
e.di=rand()%4;
Push(&in,e);
e.x+=move[e.di];
e.y+=move[e.di+4];
}
}
}while(e.x<40&&e.y<40);
if(StackEmpty(in))
{
printf("Faliure!");
return false;
}
while(!StackEmpty(in))
{
Pop(&in,&e);
board[e.x][e.y]=0;
}
return true;
}

Enable函数:
enum bool Enable(int x,int y)
{
if(x>=1&&x<=40&&y>=1&&y<=40&&board[x][y]!=2&&board[x][y]!=-1)
return true;
return false;
}
aid666 2004-03-27
  • 打赏
  • 举报
回复
我觉得也应该先生成一条路,然后对路进行随机修改。
superever 2004-03-27
  • 打赏
  • 举报
回复
后狼大哥你的想法很好,我开始考虑了从入口出开始,改变x和y(坐标)的值,但是没有想到从两端同时进行,我去试试看,我想堆栈可能不需要了,因为我想边开辟路边改变迷宫中当前位置的状态,通路开辟完后,重新生成有通路的地图。
backspray 2004-03-27
  • 打赏
  • 举报
回复
1.用2维数组表示迷宫,
2.就两个值 1,一个表示路.0一个表示墙,(开始全为墙)
3.确定出口和入口.
4.从两口同时开辟路.(5.用两个指针表示新开辟路的地址,比较新开辟指针是否相同.
6.如果相同的话,则表示正确的路被开辟出来.如果不同的话,则表示不通,可以继续开辟.
回到5循环;

注意点:
用用堆栈来开辟路;
每开一一个单位新路就压入栈,当正确的路被开辟出来后就出栈开辟死路,
开辟路只需一个0~2地随机数,判断从那个方向走.当可开辟路时在判断开辟这条路是否造成双路.
还有要是最后无法造成正确的路,则从置数组,从新开辟.
最外层的要弄成围墙,不能弄成路.
算法就是这个样子,我没写过,但直觉上觉得可行.
看了这些你要还不懂,跟我说一下,我帮你解!


chenkuizhong 2004-03-27
  • 打赏
  • 举报
回复
我也觉得这样开销很大
柯本 2004-03-27
  • 打赏
  • 举报
回复
抄来的一段小程序,作参考

#define N 22
#define M 22
int bg[M][N];

/* 随机生成代表迷宫地图的数组 */
void makebg(int a,int b){
int i,j;
int ran;
int direc;
/* 初始化迷宫地图 */
for(i=0;i<a;i++)
for(j=0;j<b;j++)
bg[i][j]=1;

/* 随机生成迷宫通路 */
randomize();
i=j=0;direc=2;
while(1){
bg[i][j]=0;
if(i>=M-1&&j>=N-1)break;
ran=(int)rand()*4;
if(ran<1){
if(direc!=1&&i<a-1){
i++;
direc=3;
}
}
else if(ran<2){
if(direc!=2&&j>0){
j--;
direc=0;
}
}
else if(ran<3){
if(direc!=3&&i>0){
i--;
direc=1;
}
}
else {
if(direc!=0&&j<b-1){
j++;
direc=2;
}
}
}
/* 随机生成迷宫其余部分 */
for(i=0;i<a;i++)
for(j=0;j<b;j++)
if(bg[i][j]==1){
ran=(int)rand()*10;
if(ran<7)bg[i][j]=0;
}
}


winco 2004-03-27
  • 打赏
  • 举报
回复
那就先生成一条路,然后再随机布置其它东西
superever 2004-03-27
  • 打赏
  • 举报
回复
我还是不怎么明白,而且我想这样的算法可能会造成很大的开销吧!我用我的方法能够开辟出正确的通路,但是结果是地图过于简单,有很多的通道块,这是因为我在开辟通路时,只要下一个方向可达,我就将它的状态设为了通道块
我现在脑子里都乱了,不知道该怎样做!
superever 2004-03-27
  • 打赏
  • 举报
回复
各位大虾,帮帮我吧!给个提示也好!

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧