易码技术论坛

 找回密码
 加入易码
搜索
查看: 489219|回复: 16

[分享]一个迷宫生成程序的源代码

[复制链接]
发表于 2004-8-29 16:41:00 | 显示全部楼层
//接上
void DrawPath(const Maze & m)
{
int i,j;
int mw,mh,left,top;
mw=m.GetWidth();
mh=m.GetHeight();
left=LEFT;
top=TOP;
setcolor(PATHCOLOR);
for (j=0;j<mh;j++) /* horz */
  for (i=0;i<mw-1;i++)
  {
   if (m.GetPath(i,j)&&m.GetPath(i+1,j)&& (m.GetMaze(i,j) & 0x2 ) )
    line(left+(i+0)*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
     top+(j+0)*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
     left+(i+1)*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
     top+(j+0)*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2);
  }
for (j=0;j<mh-1;j++)
  for (i=0;i<mw;i++)
  {
   if (m.GetPath(i,j)&&m.GetPath(i,j+1)&& (m.GetMaze(i,j) & 0x1 ) )
    line(left+(i+0)*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
     top+(j+0)*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
     left+(i+0)*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
     top+(j+1)*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2);
  }
}
int TraceMaze(TwoDimensionArray & tr,Point & cur,const Maze & m,direction dir)
{
int left,top;
left=(639-m.GetWidth()*MAZE_CELL_SIZE)/2;
top=(479-m.GetHeight()*MAZE_CELL_SIZE)/2+2;;
switch(dir)
{
case west:
  if (cur.x>0 && (m.GetMaze(cur.x-1,cur.y) & 0x2))
  {
   if (tr.Get(cur.x-1,cur.y)==0)
   {
    tr.Set(cur.x-1,cur.y,1);
    setcolor(TRACECOLOR);
   }
   else
   {
    tr.Set(cur.x,cur.y,0);
    setcolor(BADCOLOR);
   }
   line(left+((cur.x-1))*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
    top+cur.y*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
    left+cur.x*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
    top+cur.y*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2);
   cur.x-=1;
  }
  break;
case north:
  if (cur.y>0 && (m.GetMaze(cur.x,cur.y-1) & 0x1))
  {
   if (tr.Get(cur.x,cur.y-1)==0)
   {
    tr.Set(cur.x,cur.y-1,1);
    setcolor(TRACECOLOR);
   }
   else
   {
    tr.Set(cur.x,cur.y,0);
    setcolor(BADCOLOR);
   }
   line(left+cur.x*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
    top+(cur.y-1)*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
    left+cur.x*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
    top+cur.y*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2);
   cur.y-=1;
  }
  break;
case east:
  if (cur.x<m.GetWidth() && (m.GetMaze(cur.x,cur.y) & 0x2))
  {
   if (tr.Get(cur.x+1,cur.y)==0)
   {
    tr.Set(cur.x+1,cur.y,1);
    setcolor(TRACECOLOR);
   }
   else
   {
    tr.Set(cur.x,cur.y,0);
    setcolor(BADCOLOR);
   }
   line(left+(cur.x+1)*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
    top+cur.y*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
    left+cur.x*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
    top+cur.y*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2);
   cur.x+=1;
  }
  break;
case south:
  if (cur.y<m.GetHeight() && (m.GetMaze(cur.x,cur.y) & 0x1))
  {
   if (tr.Get(cur.x,cur.y+1)==0)
   {
    tr.Set(cur.x,cur.y+1,1);
    setcolor(TRACECOLOR);
   }
   else
   {
    tr.Set(cur.x,cur.y,0);
    setcolor(BADCOLOR);
   }
   line(left+cur.x*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
    top+(cur.y+1)*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
    left+cur.x*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2,
    top+cur.y*MAZE_CELL_SIZE+MAZE_CELL_SIZE/2);
   cur.y+=1;
  }
  break;
}
if (cur.x==m.GetEnd().x&&cur.y==m.GetEnd().y)
{
  sound(700);
  delay(100);
  nosound();
  return 1;
}
return 0;
}

int main(void)
{
int mazewidth=8,mazeheight=6,success=0;
int oldw,oldh;
randomize();
TwoDimensionArray trace(mazewidth,mazeheight);
Point cur(0,0);
Maze m(mazewidth,mazeheight);
int i,j,key;
trace.Set(0,0,1);
Draw();
DrawMaze(m);
DrawSize(m.GetWidth(),m.GetHeight());
for(;;)
{
  oldw=mazewidth;
  oldh=mazeheight;
  while (bioskey(1)==0);
  key=bioskey(0);
  switch(key)
  {
  case ESC:
   goto exit;
  case F1:
   DrawPath(m);
   break;
  case F2:
   m.SetSize(mazewidth,mazeheight);
  case F3:
   DrawMaze(m);
   trace.SetSize(mazewidth,mazeheight);
   trace.Set(0,0,1);
   cur.x=0;
   cur.y=0;
   success=0;
   break;
  case HOME:
   if (mazewidth>2) mazewidth--;
   break;
  case END:
   if (mazewidth<MAZE_MAX_WIDTH) mazewidth++;
   break;
  case PAGEUP:
   if (mazeheight>2) mazeheight--;
   break;
  case PGDOWN:
   if (mazeheight<MAZE_MAX_HEIGHT) mazeheight++;
   break;
  case LEFTKEY:
   if (!success)
    success=TraceMaze(trace,cur,m,west);
   break;
  case UPKEY:
   if (!success)
    success=TraceMaze(trace,cur,m,north);
   break;
  case RIGHTKEY:
   if (!success)
    success=TraceMaze(trace,cur,m,east);
   break;
  case DOWNKEY:
   if (!success)
    success=TraceMaze(trace,cur,m,south);
   break;
  }
  if (oldw!=mazewidth||oldh!=mazeheight)
   DrawSize(mazewidth,mazeheight);
}
exit:
return 0;
}
 楼主| 发表于 2004-8-29 16:43:00 | 显示全部楼层
程序的简单注释:
程序是用C++写的,因此明白了里边几个类和结构的作用,整个程序就不难理
解了。
☆图形类Graph,实际上是为了简化设置图形模式而设的。
class Graph
{
public:
Graph();   /* 图形模式初始化 */
~Graph();  /* 关闭图表模式,恢复文本模式 */
};
这个Graph类仅定义了一个全局实例G。
☆表示方向的枚举类型direction:
enum direction {west,north,east,south};
☆用来表示坐标的类Point:
class Point
{
public:
int x,y;       /* 横、纵坐标 */
Point();       /* default constructor */
~Point(){}     /* destructor */
Point(int,int);  /* constructor */
Point & operator=(const Point &);     /* 赋值运算符重载 */
};
☆一个可以动态申请内存的二维数组类TwoDimensionArray:
class TwoDimensionArray
{
private:
int width,height;        /* 二维数组的宽度和高度 */
int **pM,*spM;           /* 指向动态申请的内存的指针 */
void Clear();            /* 释放动态申请的内存 */
public:
TwoDimensionArray();            /* default constructor */
TwoDimensionArray(int,int);     /* destructor */
~TwoDimensionArray();           /* destructor */
int SetSize(int,int);           /* 设置二维数组的宽度和高度 */
int Get(int x,int y) const;         /* 得到二维数组(x,y)处的值 */
int Set(int x,int y,int v);         /* 设置二维数组(x,y)处的值为v */
int GetWidth() const {return width;}   /* 得到二维数组的宽度 */
int GetHeight() const {return height;} /* 得到二维数组的高度 */
};
二维数组在程序中多次用到。
☆迷宫类Maze。这个类是最复杂的,也是本程序的核心。
class Maze
{
private:
int width,height;   /* 迷宫的宽度和高度 */
Point start,end;    /* 迷宫的起点和终点 */
/* 表示迷宫和路线的二维数组 */
TwoDimensionArray maze,path;
/* 判断在位置p处的格子是否可以向dir方向延伸 */
int ExtendableInDir(
  const TwoDimensionArray & m,
  const Point & p,
  direction dir);

/* 判断在位置p处的格子是否可以延伸 */
int Extendable(const TwoDimensionArray &,const Point &);
/* 在迷宫中“可延伸格子”中,随机选一个格子 */
Point FindExtendablePosition(const TwoDimensionArray &);
/* 在向左、上、右、下可延伸的方向中随机选一个方向 */
direction RandDirection(int,int,int,int);
/* 根据迷宫的宽度和高度,随机生成一个新迷宫 */
void GenerateMaze();
/* 生成迷宫从入口到出口的路线 */
void GeneratePath();
/* 用深度优先算法探路 */
void DetectPath(TwoDimensionArray &,Point &,int &);
public:
Maze();         /* default constructor */
Maze(int,int);  /* constructor */
int SetSize(int,int);           /* 设置迷宫的宽度和高度 */
void SetStart(const Point &);   /* 设置迷宫的起点 */
void SetEnd(const Point &);     /* 设置迷宫的终点 */
const Point & GetStart() const; /* 返回迷宫的起点 */
const Point & GetEnd() const;   /* 返回迷宫的终点 */
int GetMaze(int x,int y) const;      /* 返回迷宫中(x,y)格子的状态 */
int GetPath(int x,int y) const;      /* 返回路线数组中(x,y)处的值 */
int GetWidth() const{return width;}  /* 返回迷宫的宽度 */
int GetHeight()const{return height;} /* 返回迷宫的宽度 */
};
☆下面是几个全局函数:
/* 绘制界面 */
void Draw()
/* 绘制迷宫的宽度和高度 */
void DrawSize(int width,int height)
/* 绘制迷宫m */
void DrawMaze(const Maze & m)
/* 绘制迷宫m的正确路线 */
void DrawPath(const Maze & m)
/* 在迷宫m的位置p处向方向dir走一步
   tr为走过的路线标记
   新走过的路和回头路用不同的颜色标记 */
int TraceMaze(
TwoDimensionArray & tr,
Point & cur,
const Maze & m,
direction dir)

 楼主| 发表于 2004-8-29 16:43:00 | 显示全部楼层
☆主函数很短,我就把它贴在下边,来个全解吧。
int main(void)
{
/* mazewidth和mazeheight为新迷宫的宽度和高度 */
/* success标记玩家是否到达迷宫终点 */
int mazewidth=8,mazeheight=6,success=0;

/* oldw和oldh表示迷宫原有的大小 */
int oldw,oldh;
/* 随机初始化 */
randomize();
/* trace记录玩家在迷宫中走过的路线 */
TwoDimensionArray trace(mazewidth,mazeheight);
/* cur记录玩家在迷宫中的位置 */
Point cur(0,0);
/* 新建一个迷宫 */
Maze m(mazewidth,mazeheight);
int i,j,key;
/* 设置玩家在迷宫的左上角(起点) */
trace.Set(0,0,1);

/* 绘制界面 */
Draw();
/* 绘制迷宫 */
DrawMaze(m);
/* 绘制迷宫的宽高 */
DrawSize(m.GetWidth(),m.GetHeight());
for(;;)
{
  oldw=mazewidth;        /* 记录迷宫原来的宽度 */
  oldh=mazeheight;       /* 记录迷宫原来的高度 */
  while (bioskey(1)==0); /* 等待按键 */
  key=bioskey(0);        /* 获取按键 */
  switch(key)
  {
  case ESC:              /* Escape 键退出游戏 */
   goto exit;
  case F1:               /* F1 显示迷宫路线 */
   DrawPath(m);
   break;
  case F2:               /* F2 键按当前宽、高生成新迷宫 */
   m.SetSize(mazewidth,mazeheight);
  case F3:               /* F3 键绘制迷宫 */
   DrawMaze(m);
    /* 玩家走过的路线归位 */
   trace.SetSize(mazewidth,mazeheight);
   /* 玩家回到迷宫左上角(起点) */
   trace.Set(0,0,1);
   /* 玩家位置回到迷宫左上角(起点) */
   cur.x=0;
   cur.y=0;
   /* 标记玩家没有到达迷宫终点 */
   success=0;
   break;
  case HOME:             /* HOME 键迷宫宽度减1 */
   if (mazewidth>2) mazewidth--;
   break;
  case END:              /* HOME 键迷宫宽度加1 */
   if (mazewidth<MAZE_MAX_WIDTH) mazewidth++;
   break;
  case PAGEUP:           /* PAGEUP 键迷宫高度减1 */
   if (mazeheight>2) mazeheight--;
   break;
  case PGDOWN:           /* PAGEDOWN 键迷宫高度加1 */
   if (mazeheight<MAZE_MAX_HEIGHT) mazeheight++;
   break;
  case LEFTKEY:          /* 玩家在迷宫中向左走一步 */
   if (!success)
    success=TraceMaze(trace,cur,m,west);
   break;
  case UPKEY:            /* 玩家在迷宫中向上走一步 */
   if (!success)
    success=TraceMaze(trace,cur,m,north);
   break;
  case RIGHTKEY:         /* 玩家在迷宫中向右走一步 */
   if (!success)
    success=TraceMaze(trace,cur,m,east);
   break;
  case DOWNKEY:          /* 玩家在迷宫中向下走一步 */
   if (!success)
    success=TraceMaze(trace,cur,m,south);
   break;
  }
  /* 如果迷宫大小被改变,重绘迷宫大小 */
  if (oldw!=mazewidth||oldh!=mazeheight)
   DrawSize(mazewidth,mazeheight);
}
exit:
return 0;
}
 楼主| 发表于 2004-8-29 16:47:00 | 显示全部楼层
[attachment:17]
这个文件里包含了整个程序源代码和作者写的程序设计思路及编译好的程序

56_192_17.rar

47 KB, 下载次数: 1532

发表于 2004-8-29 18:34:00 | 显示全部楼层
N长~看晕了~
发表于 2004-9-8 05:40:00 | 显示全部楼层
真的,很长.
发表于 2004-9-10 08:58:00 | 显示全部楼层
C++代码
还用了那么多类,有必要吗?我看用lava做的又简单有快,换了C++不是更简单了吗?
太长了啊!
发表于 2004-12-9 20:08:00 | 显示全部楼层
了不起
传说中的笨蛋 该用户已被删除
发表于 2005-4-5 10:50:00 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
mirsalijan 该用户已被删除
发表于 2005-4-24 18:18:00 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
发表于 2005-4-25 17:44:00 | 显示全部楼层
我用BASIC都写过~使用遍历的算法~
lenghong 该用户已被删除
发表于 2005-4-26 11:36:00 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
发表于 2005-5-10 08:28:00 | 显示全部楼层
高手!
bitfly 该用户已被删除
发表于 2005-6-13 20:41:00 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
 楼主| 发表于 2005-6-14 15:53:00 | 显示全部楼层
以下是引用mirsalijan在2005-4-24 18:18:51的发言:

麻烦你,给我告诉一下原代码的运行环境

用那一个编译器来编译
[em04]

好像是用DEV C++,不然就是TC

7757_11895_3229.rar

492 KB, 下载次数: 156

liudengkun 该用户已被删除
发表于 2005-6-17 19:56:00 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
 楼主| 发表于 2004-8-29 16:40:12 | 显示全部楼层 |阅读模式
//作者:上海财经大学图书馆  陈畅

#include <graphics.h>
#include <time.h>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#include <bios.h>
#include <dos.h>

#define MAZE_MAX_WIDTH  48
#define MAZE_MAX_HEIGHT 36
#define MAZE_TOP        24
#define MAZE_CENTER    320
#define MAZE_CELL_SIZE  12
#define LEFT (639-mw*MAZE_CELL_SIZE)/2;
#define TOP  (479-mh*MAZE_CELL_SIZE)/2+2;
#define BGCOLOR     BLACK
#define MAZECOLOR   WHITE
#define PATHCOLOR  YELLOW
#define TRACECOLOR  GREEN
#define BADCOLOR      RED

#define ESC      283
#define F1     15104
#define F2     15360
#define F3     15616
#define HOME   18176
#define END    20224
#define PAGEUP 18688
#define PGDOWN 20736
#define LEFTKEY  19200
#define UPKEY    18432
#define RIGHTKEY 19712
#define DOWNKEY  20480

char caption[]="Maze 2002  http://shchenchang.top263.net";
char prompt1[]="F1=Show Path  F2=New Maze  F3=Redraw Maze  ArrowKeys=Move  Esc=Exit";
char prompt2[]="Home/End=Change Width  PageUp/PageDown=Change Height  ";

enum direction {west,north,east,south};

class Point
{
public:
int x,y;
Point();
~Point(){}
Point(int,int);
Point & operator=(const Point &);
};
Point:oint()
{
x=y=0;
}
Point:oint(int ax,int ay)
{
x=ax;
y=ay;
}
Point & Point:perator=(const Point &p)
{
x=p.x;
y=p.y;
return *this;
}

class TwoDimensionArray
{
private:
int width,height;
int **pM,*spM;
void Clear();
public:
TwoDimensionArray();
TwoDimensionArray(int,int);
~TwoDimensionArray();
int SetSize(int,int);
int Get(int,int) const ;
int Set(int,int,int);
int GetWidth() const {return width;}
int GetHeight() const {return height;}
};
TwoDimensionArray::TwoDimensionArray()
{
width=height=0;
spM=NULL;
pM=NULL;
}
TwoDimensionArray::~TwoDimensionArray()
{
Clear();
}
int TwoDimensionArray::SetSize(int w,int h)
{
int i,j;
Clear();
width=w;
height=h;
spM=new int[w*h];
if (spM==NULL)
{
  printf("Not enough memory!\n");
  exit(1);
  return 0;
}
pM=new int* [w];
if (pM==NULL)
{
  delete []spM;
  printf("Not enough memory!\n");
  exit(1);
  return 0;
}
for (j=0;j<w;j++)
  pM[j]=spM+j*h;
for (i=0;i<w;i++)
  for (j=0;j<h;j++)
   pM[j]=0;

return 1;
}
TwoDimensionArray::TwoDimensionArray(int w,int h):spM(NULL),pM(NULL)
{
SetSize(w,h);
}
void TwoDimensionArray::Clear()
{
if (pM!=NULL)
  delete []pM;
if (spM!=NULL)
  delete []spM;
width=height=0;
}
int TwoDimensionArray::Get (int x,int y) const
{
return pM[x][y];
}
int TwoDimensionArray::Set(int x,int y,int v)
{
pM[x][y]=v;
return v;
}


class Graph
{
public:
Graph();
~Graph();
};
Graph G;
Graph::Graph()
{
int gdriver = VGA, gmode=VGAHI, errorcode;

errorcode = registerbgidriver(EGAVGA_driver);

/* report any registration errors */
if (errorcode < 0)
{
  printf("Graphics error: %s\n", grapherrormsg(errorcode));
  printf("Press any key to halt:");
  getch();
  exit(1); /* terminate with an error code */
}
errorcode = registerbgifont(triplex_font);
/* report any registration errors */
if (errorcode < 0)
{
  printf("Graphics error: %s\n", grapherrormsg(errorcode));
  printf("Press any key to halt:");
  getch();
  exit(1); /* terminate with an error code */
}


   /* initialize graphics mode */
   initgraph(&gdriver, &gmode, "e:\\tc\\bgi");

   /* read result of initialization */
   errorcode = graphresult();

   if (errorcode != grOk)  /* an error occurred */
   {
   printf("Graphics error: %s\n", grapherrormsg(errorcode));
   printf("Press any key to halt:");
   getch();
   exit(1);             /* return with error code */
   }

}
Graph::~Graph()
{
closegraph();
}

class Maze
{
private:
int width,height;
Point start,end;
TwoDimensionArray maze,path;
int ExtendableInDir(const TwoDimensionArray &,const Point &,direction);
int Extendable(const TwoDimensionArray &,const Point &);
Point FindExtendablePosition(const TwoDimensionArray &);
direction RandDirection(int,int,int,int);
void GenerateMaze();
void GeneratePath();
void DetectPath(TwoDimensionArray &,Point &,int &);

public:
Maze();
Maze(int,int);
int SetSize(int,int);
void SetStart(const Point &);
void SetEnd(const Point &);
const Point & GetStart() const;
const Point & GetEnd() const;

int GetMaze(int,int) const;
int GetPath(int,int) const;
int GetWidth() const{return width;}
int GetHeight()const{return height;}
};
Maze::Maze()
{
width=height=0;
}
int Maze::GetMaze(int x,int y) const
{
return maze.Get(x,y);
}
int Maze::GetPath(int x,int y) const
{
return path.Get(x,y);
}
int Maze::SetSize(int w,int h)
{
int i;
if (w<=1||h<=1)
{
  printf("Meanless size!");
  return 0;
}
if (w>MAZE_MAX_WIDTH)
{
  printf("Width is too large!");
  return 0;
}
if (h>MAZE_MAX_HEIGHT)
{
  printf("Height is too large!");
  return 0;
}
width=w;
height=h;
start.x=0;
start.y=0;  /* entrance of the maze is at upper left corner */
end.x=w-1;
end.y=h-1;  /* exit of the maze is at lower right corner */
maze.SetSize(w,h);
path.SetSize(w,h);

GenerateMaze();
GeneratePath();


return 1;
}
Maze::Maze(int w,int h)
{
SetSize(w,h);
}

void Maze::SetStart(const Point &p)
{
start=p;
}
void Maze::SetEnd(const Point &p)
{
end=p;
}
const Point & Maze::GetStart() const
{
return start;
}
const Point & Maze::GetEnd() const
{
return end;
}

int Maze::ExtendableInDir(const TwoDimensionArray & ta,const Point & p,direction dir)
{
switch (dir)
{
case west:
  if (p.x>0 && (ta.Get(p.x-1,p.y)==0))
   return 1;
  return 0;
case north:
  if (p.y>0 && (ta.Get(p.x,p.y-1)==0))
   return 1;
  return 0;
case east:
  if (p.x<(ta.GetWidth()-1) && (ta.Get(p.x+1,p.y)==0))
   return 1;
  return 0;
default: /* south */
  if (p.y<(ta.GetHeight()-1) && (ta.Get(p.x,p.y+1)==0))
   return 1;
}
return 0;
}

int Maze::Extendable(const TwoDimensionArray & ta,const Point & p)
{
if ( ((ExtendableInDir(ta,p, west)) ||
  (ExtendableInDir(ta,p,north)) ||
  (ExtendableInDir(ta,p, east)) ||
  (ExtendableInDir(ta,p,south))) && ta.Get(p.x,p.y) )
  return 1;
return 0;
}
Point Maze::FindExtendablePosition(const TwoDimensionArray & ta)
{
int i,j,w,h,select;
Point *tp,rp;
int count=0;

w=ta.GetWidth();
h=ta.GetHeight();

tp=new Point[w*h];

for (i=0;i<w;i++)
  for (j=0;j<h;j++)
  {
   if ( Extendable(ta,Point(i,j)) )
   {
    tp[count].x=i;
    tp[count].y=j;
    count++;
   }
  }
if (count==0)
  rp.x=rp.y=-1;
else
{
  select=rand()%count;
  rp=tp[select];
}
delete []tp;

return rp;
}

direction Maze::RandDirection(int w,int n,int e,int s)
{
direction dir[4];
int count=0,select;
if (e)
{
  dir[count]=east;
  count++;
}
if (w)
{
  dir[count]=west;
  count++;
}
if (s)
{
  dir[count]=south;
  count++;
}
if (n)
{
  dir[count]=north;
  count++;
}


select=rand()%count;
return dir[select];
}

void Maze::GenerateMaze()
{
int w,n,e,s;
direction dir;
Point pos(rand()%width,rand()%height);
TwoDimensionArray temp(width,height);
temp.Set(pos.x,pos.y,1); /* mark the position */
for (;;)
{
  pos=FindExtendablePosition(temp);

  if (pos.x==-1&&pos.y==-1) break; /* constructing maze complete */
  for (;;)
  {

   w=ExtendableInDir(temp,pos, west);
   n=ExtendableInDir(temp,pos,north);
   e=ExtendableInDir(temp,pos, east);
   s=ExtendableInDir(temp,pos,south);
   dir=RandDirection(w,n,e,s);

   switch(dir)
   {
   case  west:
    pos.x-=1;
    maze.Set(pos.x,pos.y,2);
    break;
   case north:
    pos.y-=1;
    maze.Set(pos.x,pos.y,1);
    break;
   case  east:
    if (maze.Get(pos.x,pos.y)==0)
     maze.Set(pos.x,pos.y,2);
    else
     maze.Set(pos.x,pos.y,3);
     pos.x+=1;
    break;
   case south:

    if (maze.Get(pos.x,pos.y)==0)
     maze.Set(pos.x,pos.y,1);
    else
     maze.Set(pos.x,pos.y,3);
    pos.y+=1;
   }
   temp.Set(pos.x,pos.y,1); /* mark the position */
   if (!Extendable(temp,pos))
    break;
  }
}
}

void Maze::GeneratePath()
{
Point cur=start;
int success=0;
path.Set(cur.x,cur.y,1); /* mark start position */
DetectPath(path,cur,success);

}
void Maze:etectPath(TwoDimensionArray & ta,Point & cur,int & success)
{
if (cur.x==end.x&&cur.y==end.y)
{
  success=1;
  return;
}
if (cur.x>0 && (maze.Get(cur.x-1,cur.y) & 0x2) && (ta.Get(cur.x-1,cur.y)==0)) /* west */
{
  cur.x-=1;
  ta.Set(cur.x,cur.y,1);
  DetectPath(ta,cur,success);
  if (success) return;
  ta.Set(cur.x,cur.y,0);
  cur.x+=1;
}
if (cur.y>0 && (maze.Get(cur.x,cur.y-1) & 0x1) && (ta.Get(cur.x,cur.y-1)==0)) /* north */
{
  cur.y-=1;
  ta.Set(cur.x,cur.y,1);
  DetectPath(ta,cur,success);
  if (success) return;
  ta.Set(cur.x,cur.y,0);
  cur.y+=1;
}
if ((maze.Get(cur.x,cur.y) & 0x2) && (ta.Get(cur.x+1,cur.y)==0)) /* east */
{
  cur.x+=1;
  ta.Set(cur.x,cur.y,1);
  DetectPath(ta,cur,success);
  if (success) return;
  ta.Set(cur.x,cur.y,0);
  cur.x-=1;
}
if ((maze.Get(cur.x,cur.y) & 0x1) && (ta.Get(cur.x,cur.y+1)==0)) /* south */
{
  cur.y+=1;
  ta.Set(cur.x,cur.y,1);
  DetectPath(ta,cur,success);
  if (success) return;
  ta.Set(cur.x,cur.y,0);
  cur.y-=1;
}
}
void DrawSize(int width,int height)
{
int left=textwidth(prompt2)+24;
char w[]="Width:";
char h[]=" Height:";
char buffer[8];
setfillstyle(SOLID_FILL,BGCOLOR);
bar(left,472,left+textwidth(w)+textwidth(h)+textwidth(" ")*6,479);
settextjustify(LEFT_TEXT,CENTER_TEXT);
setcolor(GREEN);
outtextxy(left,476,w);
sprintf(buffer,"%3d",width);
left+=textwidth(w);
setcolor(BGCOLOR);
outtextxy(left,476,"   ");
setcolor(YELLOW);
outtextxy(left,476,buffer);
left+=textwidth(buffer);
setcolor(GREEN);
outtextxy(left,476,h);
left+=textwidth(h);
setcolor(BGCOLOR);
outtextxy(left,476,"   ");
sprintf(buffer,"%3d",height);
setcolor(YELLOW);
outtextxy(left,476,buffer);
}
void Draw()
{
int style,size;
settextjustify(CENTER_TEXT, CENTER_TEXT);
cleardevice();
size = 1;
style=TRIPLEX_FONT;
settextstyle(style, HORIZ_DIR, size);
outtextxy(320,9,caption);
style=DEFAULT_FONT;
settextstyle(style, HORIZ_DIR, size);
settextjustify(LEFT_TEXT, CENTER_TEXT);
outtextxy(24,467,prompt1);
outtextxy(24,476,prompt2);
}
void DrawMaze(const Maze & m)
{
int style,size,i,j,border;
int mw,mh,left,top;
setfillstyle(SOLID_FILL,BGCOLOR);
bar(0,24,639,456);
mw=m.GetWidth();
mh=m.GetHeight();
left=LEFT;
top=TOP;
setcolor(MAZECOLOR);
line(left,top,left+mw*MAZE_CELL_SIZE,top);
line(left,top,left,top+mh*MAZE_CELL_SIZE);
for (j=0;j<mh;j++)
  for (i=0;i<mw;i++)
  {
   border=m.GetMaze(i,j);
   border=~border;
   if ( border & 0x1) /* bottom */
    line(left+(i+0)*MAZE_CELL_SIZE,
     top+(j+1)*MAZE_CELL_SIZE,
     left+(i+1)*MAZE_CELL_SIZE,
     top+(j+1)*MAZE_CELL_SIZE);
   if ( border & 0x2) /* right */
    line(left+(i+1)*MAZE_CELL_SIZE,
     top+(j+0)*MAZE_CELL_SIZE,
     left+(i+1)*MAZE_CELL_SIZE,
     top+(j+1)*MAZE_CELL_SIZE);
  }
}

//未完接下
您需要登录后才可以回帖 登录 | 加入易码

本版积分规则

Archiver|手机版|小黑屋|EMAX Studio

GMT+8, 2024-4-23 14:16 , Processed in 0.015159 second(s), 21 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表