问题及代码:
文件名称: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
根据文本数据生成迷宫: