课程设计 广度优先探索—迷宫问题

问题及代码:

文件名称:main.cpp  maze.cpp  maze.h

作者:郑孚嘉

问题描述:实现生成迷宫(随机生成,用户输入数据生成,从文本中读取数据生成),输出迷宫(图案方式),探索迷宫路径(最短路径),输出迷宫路径(图案方式)


代码:

maze.h

/***********************************************
文件名称:maze.h
作者:郑孚嘉
完成日期:2015年12月25日
内容摘要:头文件,包含定义图数据结构的代码、宏定义、要实现算法的函数的声明
修改时间:2015年12月25日
修改内容:创建
***********************************************/

#include <iostream>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <stdio.h>
using namespace std;
#define M 20
#define N 20
extern int maze[M+2][N+2];                      //声明迷宫数组maze
extern int head,tail;                           //定义队列头和尾
void Interface();                               //界面
void create_automatic_maze(int m,int n);        //自动生成迷宫
void print_maze(int m,int n);                   //输出生成迷宫
void create_cin_maze(int m,int n);              //通过用户输入生成迷宫
void create_from_maze();                        //从文件读入数据生成迷宫
void enqueue(struct point p);                   //队列的入队操作
struct point dequeue();                         //队列的出队操作
void visit(int row,int col,int maze[22][22]);   //访问可走的节点并进队。
bool path(int maze[22][22],int m,int n);        //判断是否存在路径,同时输出迷宫路径的坐标
void result_maze(int m,int n);                  //在图中输出迷宫路径

maze.cpp

/***********************************************
文件名称:maze.cpp
作者:郑孚嘉
完成日期:2015年12月25日
内容摘要:源文件,包含实现各种算法的函数的定义
修改时间:2015年12月25日
修改内容:创建
***********************************************/

#include "maze.h"
int maze[M+2][N+2];
int head=0,tail=0;                      //定义队列头尾。
int m,n;
struct point                            //定义一个结构体
{                                       //包含坐标(row,col)和由先前的坐标
     int row,col,pre;
}queue[1000];                           //结构体数组
void Interface()                        //界面
{
    int exit = 0;
    int step;
    while (exit == 0)
    {
        cout<<"********************************************************************************\n";
        cout<<"                       WELCOME TO MAZE                          \n";
        cout<<"********************************************************************************\n";
        cout<<"                     Create New Maze (auto.)        please press 1\n";
        cout<<"                     Create New Maze (user input.)  please press 2\n";
        cout<<"                     Create New Maze (from data.)   please press 3\n";
        cout<<"                     Exit                           please press 4\n";
        cout<<"********************************************************************************\n";
        cout<<"\n\n>So your choice is ?\n";
        cin>>step;
        switch(step)
        {
        case 1:
            //自动生成迷宫
            system("cls");
            cout<<"\nPlease input row:\n";
            cin>>m;
            cout<<"\nPlease input col:\n";
            cin>>n;
            while( ( m<2 || m>20 ) || ( n<2 || n>20 ) )
            {
                cout<<"\nSorry ,The range of row or col is 0 to 20.Please input again\n\n";
                cout<<"\nPlease input row:\n";
                cin>>m;
                cout<<"\nPlease input col:\n";
                cin>>n;

            }
            srand((unsigned)time(0));           //随机函数,保证每次随机都不同
            create_automatic_maze(m,n);
            print_maze(m,n);
		    if(path(maze,m,n))
            {
                result_maze(m,n);
            }
		    cout<<"Press Enter Contiue!\n";
		    getchar();                          //接受一个字符,判断是否为回车,回车则继续
		    while(getchar()!='\n');
		    system("cls");
            break;
        case 2:
            //通过用户输入来生成迷宫
            system("cls");
            cout<<"\nPlease input row:\n";
            cin>>m;
            cout<<"\nPlease input col:\n";
            cin>>n;
            while( ( m<0 || m>20 ) || ( n<0 || n>20 ) )
            {
                cout<<"\nSorry ,The range of row or col is 0 to 20.Please input again\n\n";
                cout<<"\nPlease input row:\n";
                cin>>m;
                cout<<"\nPlease input col:\n";
                cin>>n;
            }
            create_cin_maze(m,n);
            print_maze(m,n);
		    if(path(maze,m,n))
            {
                result_maze(m,n);
            }
		    cout<<"\nPress Enter Contiue!\n";
            getchar();
		    while(getchar()!='\n');
            system("cls");
            break;
        case 3:
            //从文件读入数据生成迷宫
            system("cls");
            create_from_maze();
            print_maze(m,n);
            if(path(maze,m,n))
            {
                result_maze(m,n);
            }
            cout<<"\nPress Enter Contiue!\n";
            getchar();
            while(getchar()!='\n');
            system("cls");
            break;
        case 4:
            //退出
            exit=1;
            break;
        default:
            //输入错误
            cout<<"\n1nput error!\n\n\nPlease INPUT Again by press any key\n\n";
            system("pause>nul");
            system("cls");
            break;
        }
    }
}
void create_automatic_maze(int m,int n)
//自动生成迷宫
{
	int i,j;
	cout<<"Please wait\n";
	for(i=0;i<5;i++)
	{
	    cout<<".";
        for(j=0;j<100000000;j++);
	}
    cout<<"\n";
	for(i=0;i<m;i++)
    {
		for(j=0;j<n;j++)
        {
            maze[i][j]=rand()%2;
        }
    }
	maze[0][0]=0;                               //出口和入口设置为0
	maze[m-1][n-1]=0;                           //保证可走
}
void create_cin_maze(int m,int n)
//由用户输入来生成指定迷宫
{
    cout<<"Please cin your maze by row(1 means hinder,0 means path)\n";
    int i,j;
    for(i=0;i<m;i++)
    {
        for(j=0;j<n;j++)
        {
            cin>>maze[i][j];
        }
    }
    maze[0][0]=0;
	maze[m-1][n-1]=0;
	cout<<"\n\nPlease wait\n";
	for(i=0;i<5;i++)
	{
	    cout<<".";
        for(j=0;j<100000000;j++);
	}
	cout<<"\n";
}
void create_from_maze()
//从文件读入数据生成迷宫
{
    FILE *fp;
    int i,lines=0;
    fp = fopen("maze.txt", "r");//打开文件
    if(fp == NULL)//打开失败
    return;
    fscanf(fp, "%d",&m);
    fscanf(fp, "%d",&n);
    while(lines < m)
    {
            for(i = 0; i < n; i ++)
            {
                if(fscanf(fp, "%d",&maze[lines][i]) == EOF)
                {
                    break;//读取数据
                }
            }
            if(feof(fp))
            {
                break;//判断是否文件结束。
            }
            lines++;//读取一行成功,增加行数。
    }
    fclose(fp);//关闭文件。
}
void print_maze(int m,int n)
//打印生成的迷宫
{
    system("cls");
	int i,j,k;
	cout<<"MAZE Create!:\n\n";
	cout<<"Start\n";
	cout<<"  ↓\n";
	cout<<"■  ";
	for(k=0;k<n;k++)
	{
		cout<<"■";
	}
	for(i=0;i<m;i++)
	{
		cout<<"\n";
		cout<<"■";
		for(j=0;j<n;j++)
		{
			if(maze[i][j]==0)
            {
                cout<<"  ";
            }
			if(maze[i][j]==1)
            {
                cout<<"■";
            }
		}
		cout<<"■";
	}
	cout<<"\n";
	for(k=0;k<n;k++)
	{
		cout<<"■";
	}
	cout<<"  ■\n";
    for(i=0;i<n;i++)
	{	cout<<"  ";}
    cout<<"↓\n";
	for(i=0;i<n;i++)
	{
	    cout<<"  ";
    }
	cout<<"End\n";
}
void enqueue(struct point p)
//队列的入队操作
{
	queue[tail]=p;
	tail++;
}

struct point dequeue()
//队列出队操作
//返回值为point
{
	head++;
	return queue[head-1];
}

int is_empty()
//判断队列是否为空
{
	return head==tail;
}

void visit(int row,int col,int maze[22][22])
//访问可通过的坐标,并将其入队
{
	struct point visit_point={row,col,head-1};            //head-1就是pre,row和col由pre所探索的节点
	maze[row][col]=2;                                     //将访问过的点位标记为2
	enqueue(visit_point);
}
bool path(int maze[22][22],int m,int n)
 //判断是否存在路径并输出路径的坐标
{
    head=tail=0;
	struct point p={0,0,-1};                    //设定队列的第一个point
    maze[p.row][p.col]=2;                              //标记为已访问
    enqueue(p);
	while(!is_empty())
	{
              p=dequeue();                             //出队操作,head++,如果没有路径,head=tail
			  if((p.row==m-1)&&(p.col==n-1))           //如果当前坐标为出口坐标,则跳出while
				  break;
		                                               //定义8个走位方向
			  if((((p.row-1)>=0)&&((p.row-1)<m)&&((p.col+0)<n))&&(maze[p.row-1][p.col+0]==0))
				  visit(p.row-1,p.col+0,maze);             //上
			  if((((p.row-1)>=0)&&((p.row-1)<m)&&((p.col+1)<n))&&(maze[p.row-1][p.col+1]==0))
				  visit(p.row-1,p.col+1,maze);             //右上
			  if((((p.row+0)<m)&&((p.col+1)<n))&&(maze[p.row+0][p.col+1]==0))
				  visit(p.row+0,p.col+1,maze);             //右
			  if((((p.row+1)<m)&&((p.col+1)<n))&&(maze[p.row+1][p.col+1]==0))
				  visit(p.row+1,p.col+1,maze);             //右下
			  if((((p.row+1)<m)&&((p.col+0)<n))&&(maze[p.row+1][p.col+0]==0))
				  visit(p.row+1,p.col+0,maze);             //下
			  if((((p.row+1)<m)&&((p.col-1)<n)&&((p.col-1)>=0))&&(maze[p.row+1][p.col-1]==0))
				  visit(p.row+1,p.col-1,maze);             //左下
			  if((((p.row+0)<m)&&((p.col-1)<n)&&((p.col-1)>=0))&&(maze[p.row+0][p.col-1]==0))
				  visit(p.row+0,p.col-1,maze);             //左
              if((((p.row-1)>=0)&&((p.row-1)<m)&&((p.col-1)<n)&&((p.col-1)>=0))&&(maze[p.row-1][p.col-1]==0))
				  visit(p.row-1,p.col-1,maze);            //左上
	}
	if(p.row==m-1&&p.col==n-1)                             //输出路径坐标
	{
	      cout<<"THE PATH HAS ALREADY FOUND!\n\n";
	      cout<<"Please Wait\n";
	      int i,j;
	      for(i=0;i<5;i++)
          {
                cout<<".";
                for(j=0;j<100000000;j++);
          }
          cout<<"\n";
          cout<<"==================================================================\n";
	      cout<<"PATH:\n\n";
          cout<<"END\n";
		  cout<<" ↑\n";
	      cout<<"("<<p.row+1<<","<<p.col+1<<")\n";
		  cout<<" ↑\n";
	      maze[p.row][p.col]=3;                              //将路径坐标在maze中赋值为3
		  while(p.pre!=-1)                                   //通过pre来找路径中的坐标
		  {
			  p=queue[p.pre];
			  cout<<"("<<p.row+1<<","<<p.col+1<<")\n";
			  cout<<" ↑\n";
			  maze[p.row][p.col]=3;
		  }
		  cout<<"START\n\n";
		  cout<<"==================================================================\n\n";
		  return true;
	}
	else                                    //head=tail表示没有路径
	{
          int i,j;
          for(i=0;i<5;i++)
          {
              cout<<".";
              for(j=0;j<100000000;j++);
          }
          cout<<"\n";
		  cout<<"==================================================================\n\n";
	      cout<<"This Maze has No path!\n\n";
	      return false;
	}

}
void result_maze(int m,int n)
//在图中输出迷宫的路径
{
	cout<<"Now we Print PATH in GRAPH!\n\n\n";
	cout<<"Please Wait\n";
	int i,j;
	for(i=0;i<5;i++)
    {
            cout<<".";
            for(j=0;j<100000000;j++);
    }
	cout<<"\nPATH:\n\n";
	cout<<"Start\n";
	cout<<"  ↓\n";
	for(i=0;i<n+2;i++)
	{
        if(i==1)
        {
            cout<<"  ";
        }
        else
		{
		    cout<<"■";
		}
	}
	cout<<"\n";

	for(i=0;i<m;i++)
	{
	    cout<<"■";
		for(j=0;j<n;j++)
		{
			if(maze[i][j]==0||maze[i][j]==2)       //2是队列中访问过的点
            {
                cout<<"  ";
            }
			if(maze[i][j]==1)
            {
                cout<<"■";
            }
			if(maze[i][j]==3)                      //3是标记的可以走通的路径
			{
			    cout<<"☆";
            }
		}
		cout<<"■\n";

	}
	for(i=0;i<n+2;i++)
	{
	    if(i==n)
        {
            cout<<"  ";
        }
		else
		{
		    cout<<"■";
		}
	}
	cout<<"\n";
	for(i=0;i<n;i++)
	{
	    cout<<"  ";
    }
    cout<<"↓\n";
    for(i=0;i<n;i++)
	{
	    cout<<"  ";
    }
	cout<<"End\n\n";
	cout<<"==================================================================\n\n";
}

main.cpp

/***********************************************
文件名称:main.cpp
作者:郑孚嘉
完成日期:2015年12月25日
内容摘要:在同一项目(project)中建立一个源文件,编制main函数,完成相关的测试工作。
修改时间:2015年12月25日
修改内容:创建
***********************************************/
#include "maze.h"
int main()
{
    Interface();
    return 0;
}


运行结果:

界面:

创建完成后输出迷宫:

输出路径:


没有路径的情况:

同目录下的文本maze.txt

根据文本数据生成迷宫:




  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
回答: 广度优先算法可以用来解决迷宫问题。在迷宫问题中,我们可以使用一个二维数组来表示迷宫的状态,其中墙的位置用1表示,可以走的位置用0表示。通过设置一个vis\[\]数组来记录每个顶点是否被访问过,vis\[i\]为0表示未被访问,vis\[i\]为1表示已被访问。通过广度优先搜索算法,我们可以找到从出口到入口的路径。具体步骤是将起点加入队列,然后不断从队列中取出顶点,并将其周围未访问过的顶点加入队列,直到找到出口。同时,我们可以使用一个pre指针来指向每个顶点的前一个顶点,以便最后找出完整的路径。\[1\] 引用\[2\]中提到了如何用一个二维数组初始化迷宫,并归定不同的迷宫数组状态。例如,maze\[i\]\[j\]=0表示可以走,maze\[i\]\[j\]=1表示墙,maze\[i\]\[j\]=2表示无法继续走,maze\[i\]\[j\]=3表示已经走过的路径。 需要注意的是,迷宫问题可能会遇到时间限制,因此在实际应用中需要考虑算法的效率和优化。\[3\] #### 引用[.reference_title] - *1* [利用广度优先搜索(bfs)来解决迷宫问题](https://blog.csdn.net/weixin_45843077/article/details/104383595)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [利用广度优先和深度优先算法解决迷宫问题【算法设计与分析】图搜索问题>](https://blog.csdn.net/weixin_50400808/article/details/122571191)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [广度优先搜索(BFS)——迷宫问题(POJ 4127)](https://blog.csdn.net/weixin_44572229/article/details/119679593)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值