C 语言 迷宫解法——递归寻路

使用博文 C 语言 prim(深度优先改进)算法 生成迷宫 中的算法生成迷宫:
C 语言 迷宫解法——递归寻路_第1张图片
使用 递归寻路算法 得到的路径:
C 语言 迷宫解法——递归寻路_第2张图片

  • 算法思想

    从起点出发,下一步都有四种选择(上下左右),先选择一个方向,如果该方向能够走下去,那么就往这个方向走,当前位置切换为下一个位置。如果不能走,那么换个方向走,如果所有方向都走不了,那么退出当前位置,到上一步的位置去,当前位置切换为上一步的位置。一直这样执行下去,如果当前位置是终点,那么结束。如果走过了所有的路径都没能到达终点,那么无解。
     
  • 具体实现

    1、使用一个二维数组存储迷宫地图数据,使用一个二维数组存储生成地图的访问标识,另使用一个二维数组存储寻路时的访问标识。因为每两堵墙之间应有一条通道,因此迷宫行列值应为奇数:
    #include
    #include
    #include
    #include
    //行列应设置为奇数
    /**********************
    //宏定义符号常量
    #define L 25//每行单位数
    #define W 25//每列单位数
    #define R 16
    **********************/
    enum{L=37,W=31,R=14};//枚举类型
    bool Road[L+2][W+2];//路径状态数组,false:障碍;true:通路
    bool Visit[L+2][W+2];//访问标志数组,true:已访问;false:未访问
    int Pass[L+2][W+2];
    int success=0;

    2、构建一个单链表存储已访问的迷宫单元:

    //template
    struct point
    {
    	int x;
    	int y;
    };
    struct Node		//结构体类型描述单链表的结点
    {
    	point data;
    	Node* next;
    };
    class LinkList
    {
    	private:
    	Node* first;//单链表的头指针
    	public:
    	LinkList()//无参构造函数,建立只有头结点的空链表
    	{
    		first=new Node;//生成头结点 
    		first->next=NULL;//头结点的指针域置空 
    	} 
    	LinkList(point x)//有参构造函数,建立有1个元素的单链表
    	{
    		//头插法建立单链表
    		first=new Node;
    		first->next=NULL;//初始化一个空链表
    		Node* s=new Node;
    		s->data=x;//为每个数组元素建立一个结点
    		s->next=first->next;
    		first->next=s;//将结点s插入到头结点之后 
    	} 
    	~LinkList()//析构函数
    	{
    		while(first!=NULL)//释放单链表的每一个结点的存储空间
    		{
    			Node* q=first;//暂存被释放结点
    			first=first->next;//first指向被释放结点的下一个结点
    			delete q; 
    		} 
    	} 
    	int Length()//求单链表的长度
    	{
    		Node* p=first->next;
    		int count=0;//工作指针p和累加器count初始化
    		while(p!=NULL)
    		{
    			p=p->next;
    			count++;
    		} 
    		return count;//注意count的初始化和返回值之间的关系 
    	} 
    	point Get(int i)//按位查找,在单链表中查找第i个结点的元素值
    	{
    		Node* p=first->next;
    		int count=1;//工作指针p和累加器count初始化
    		while(p!=NULL&&countnext;
    			count++; 
    		} 
    		if(p==NULL)	throw"位置";
    		else return p->data;
    	} 
    	
    	void Insert(int i,point x)//插入操作,在第i个位置插入元素值为x的结点
    	{
    		Node* p=first;
    		int count=0;//工作指针p应指向头结点
    		while(p!=NULL&&countnext;//工作指针p后移
    			count++; 
    		} 
    		if(p==NULL)	throw"位置";//没有找到第i-1个结点
    		else{
    			Node* s=new Node;
    			s->data=x;//申请一个结点s,其数据域为x
    			s->next=p->next;
    			p->next=s;//将结点s插入到结点p之后 
    		} 
    	} 
    	
    };

    3、生成迷宫数据:

    void Map3()
    {
    	int i,n;
    	point p1;
    	point p[4];
    	p1.x=1;p1.y=1;//起点坐标
    	LinkList Link(p1);
    	Visit[p1.x][p1.y]=true;
    	Road[p1.x][p1.y]=true;
    	int num=1;//已访问个数
    	while(num<(L/2+1)*(W/2+1))
    	{
    		p[0].x=p1.x;p[0].y=p1.y-2;//上邻元
    		p[1].x=p1.x;p[1].y=p1.y+2;//下邻元
    		p[2].x=p1.x-2;p[2].y=p1.y;//左邻元
    		p[3].x=p1.x+2;p[3].y=p1.y;//右邻元
    		for(n=0,i=0;i<4;i++){
    			if(p[i].x>=1&&p[i].x<=L&&p[i].y>=1&&p[i].y<=W)
    				if(Visit[p[i].x][p[i].y]==false)
    					n++;}
    		if(n>=1)
    		{
    			do{
    				i=rand()%4;
    			}while(p[i].x<1||p[i].x>L||p[i].y<1||p[i].y>W||Visit[p[i].x][p[i].y]==true);
    			Link.Insert(1+rand()%Link.Length(),p[i]);
    			switch(i)
    			{
    			case 0:Road[p1.x][p1.y-1]=true;break;
    			case 1:Road[p1.x][p1.y+1]=true;break;
    			case 2:Road[p1.x-1][p1.y]=true;break;
    			case 3:Road[p1.x+1][p1.y]=true;break;
    			}
    			Visit[p[i].x][p[i].y]=true;
    			num++;
    			p1=p[i];//可设置为随机取位
    			Road[p1.x][p1.y]=true;
    		}
    		else
    			p1=Link.Get(1+rand()%Link.Length());
    	}
    
    }

    4、递归寻路:

    int Search(int i,int j)//自动寻路
    {
    	int endI=L,endJ=W;
    	Pass[i][j]=-1;
    	if(i==endI&&j==endJ)
    		success=1;
    	if(success!=1&&Pass[i][j+1]==1)
    		Search(i,j+1);
    	if(success!=1&&Pass[i+1][j]==1)
    		Search(i+1,j);
    	if(success!=1&&Pass[i][j-1]==1)
    		Search(i,j-1);
    	if(success!=1&&Pass[i-1][j]==1)
    		Search(i-1,j);
    	if(success!=1)
    		Pass[i][j]=1;
    	return success;
    }

    5、根据生成的地图绘制迷宫,并绘制寻得的通路路径:

    void main()
    {
    	initgraph(L*R+2*R,W*R+2*R);
    	srand(time(NULL));
    	
    	int i,j;
    	/*********
    	for(i=1;i<=L+1;i++)
    		line(i*R,R,i*R,W*R+R);
    	for(j=1;j<=W+1;j++)
    		line(R,j*R,L*R+R,j*R);
    	*********/
    	//初始化Road数组,Visit数组
    	for(i=0;i

     

你可能感兴趣的:(C/C++,C,迷宫,递归寻路)