#include <stdio.h>//包含了printf(),scanf()函数
#include <stdlib.h>//包含了srand(),rand(),system()函数
#include <malloc.h>//包含了malloc()函数
#include <time.h>//包含了time()函数
#include <conio.h>
#define M 50
#define N 50
typedef struct node{
int row; //行
int col; //列
struct node * next;
}Mlink;
Mlink * stack;//定义一个栈
int backup[M+2][N+2]; //备份数组
//下面这个函数为我们建立迷宫矩阵
void create(int maze[M+2][N+2] , int maze_row , int maze_col){
int i , j , k;
/*我们知道在产生随机数的时候,需要一个叫做种子seed的值作为产生随机数算法的初始值。
而C/C++库中的srand就是为这一次的随机数生成设置种子。s代表的就是seed的意思。
time_t time(time_t *time);该函数返回自计算机计时的某个时刻起到现在所过去的秒数。
一般是返回自1970年1月1日00:00:00以来,到调用函数的时刻所累积的秒数。
这语句的含义就是以自1970年1月1日00:00:00以来,到调用函数的时刻所累积的秒数作为产生随机数算法的种子seed。
没有语句会对程序产生什么影响:
如果在程序运行时没有自主设置种子的话,用函数rand产生的随机数序列会是一样的。
而用srand设置随机数种子后,可能产生不同的随机序列(概率很大)。
之所以说以很大的概率产生不同的随机数序列,是因为从上面的解释可以看到,
srand是以秒数为单位的。一旦程序多次运行的时间间隔少于1s。那么srand设置种子也没有什么用处。
所以库函数产生随机数有一定的缺陷。不知道我解释明白了没有!
*/
srand((unsigned)time(NULL));
for(i = 0 ; i <= maze_row + 1 ; i++)
for(j = 0 ; j <= maze_col + 1 ; j++)
maze[i][j] = 1;//初始化矩阵元素全部为1
for(i = 1 ; i <= maze_row ; i++)
for(j = 1 ; j <= maze_col ; j++)
backup[i][j] = 0;//初始化备份矩阵全部有效元素为0
for(k = 1 ; k <= maze_row * maze_col ; k++){//随机选择位置赋予一个随机的0或1,
i = (int)(rand() % maze_row) + 1;//rand()会返回一随机数值
j = (int)(rand() % maze_col) + 1;
maze[i][j] = (int)(rand() % 2);//随机矩阵这样可以产生更多的"0"即通路
}
printf("自动生成中……\n");
//system就是调用从程序中调用系统命令,system("pause")就是从程序里调用“pause”命令
//而“pause”这个系统命令的功能很简单,就是在命令行上输出一行"按任意键继续. . ."的字,等待用户按一个键,然后返回。
system ("pause");
for(i = 1 ; i <= maze_row ; i++)
for(j = 1 ; j <= maze_row ; j++)
backup[i][j] = maze[i][j];//备份数组矩阵
}
//下面这个函数为我们打印迷宫矩阵
void print(int maze[M+2][N+2] , int maze_row , int maze_col){
int i , j , k;
printf("\n打印迷宫矩阵如下(0可通,1不可通): \n");
//在矩阵上方标明列号
for(k = 1 ; k <= maze_col ; k++){
if(k < 10)
printf("%d " , k);
else
printf("%d " , k);
}
//矩阵左方标明行号,并打印矩阵
for(i = 1 ; i <= maze_row ; i++){
printf("\n");
if(i < 10)
printf("%d " , i);
else
printf("%d " , i);
for(j = 1 ; j <= maze_col ; j++)
printf("%d " , maze[i][j]);
}
printf("\n\n迷宫图形如下(白色可通): \n");
printf(" ");
for(k = 1 ; k <= maze_col ; k++){//在图形上方标明列号
if(k < 10)
printf("%d " , k);
else
printf("%d" , k);
}
for(i = 1 ; i <= maze_row ; i++){
printf("\n");
if(i < 10)
printf("%d " , i); //矩阵左方标明行号
else
printf("%d" , i);
for(j = 1 ; j <= maze_col ; j++){//打印图形
if(maze[i][j] == 0)
printf("□");
if(maze[i][j] == 1)
printf("■");
}
}
}
int Mazepath(int maze[M+2][N+2] , int x1 , int x2 , int y1 , int y2){
Mlink * p;
if(maze[x1][y1] == 0){
p = (Mlink *)malloc(sizeof(Mlink));
p -> row = x1;
p -> col = y1;
p -> next = NULL;
stack = p; //将入口放入堆栈
maze[stack -> row][stack -> col] = 1;//标志入口已访问
while((!(stack->row==NULL&&stack->col==NULL))&&(!(stack->row==x2&&stack->col==y2)))//未找到出口并且堆栈不空
{
if(maze[stack->row+1][stack->col]==0) //下面可通
{
p=(Mlink *)malloc(sizeof(Mlink));
p->row=stack->row+1;
p->col=stack->col;
p->next=stack; //入栈
stack=p;
maze[stack->row][stack->col]=1; //标记已访问
}
else if(maze[stack->row][stack->col+1]==0) //右面位置可通
{
p=(Mlink *)malloc(sizeof(Mlink));
p->row=stack->row;
p->col=stack->col+1;
p->next=stack; //入栈
stack=p;
maze[stack->row][stack->col]=1;//标记已访问
}
else if(maze[stack->row-1][stack->col]==0) //左面可通
{
p=(Mlink *)malloc(sizeof(Mlink));
p->row=stack->row-1;
p->col=stack->col;
p->next=stack; //入栈
stack=p;
maze[stack->row][stack->col]=1;//标记已访问
}
else if(maze[stack->row][stack->col-1]==0)//上面可通
{
p=(Mlink *)malloc(sizeof(Mlink));
p->row=stack->row;
p->col=stack->col-1;
p->next=stack; //入栈
stack=p;
maze[stack->row][stack->col]=1;//标记已访问
}
else //不可通 返回上一点
{
if (stack->next!=NULL)
{ //堆栈里布置一个顶点则出栈并返回循环
p=stack;
stack=stack->next; //出栈
free(p); //释放空间
}
else //堆栈里只有一个顶点即入口,此时若释放空间出栈会使循环
{ //控制语句无法比较(因为stack->col,stack->row都已不存在,)
stack->row=NULL;
stack->col=NULL;
stack->next=NULL;
}
}
}
if (stack->row==x2&&stack->col==y2) return (1);
else return (0);
}
else return(0);
}
/****************************输出坐标通路*******************/
void printonglu1()
{
Mlink *q;
int i=1;
printf("其中的一条通道为:\n");
q=stack;
printf(" 出口<--");
while (q!=NULL)
{
if(i%5==0)
printf("\n");
printf("[%d%3d]<--",q->row,q->col);
q=q->next;
i++;
}
printf("入口\n");
}
/*******************************分割线**********************/
/**********************输出图形通路**************************/
//2时输出↑,3时输出←,4时输出→,5时输出↓
void printonglu2(int a,int b)
{
printf("图形通路如下:\n");
int z;
printf(" ");
for(z=1;z<=b;z++) //图形上方标明列号
{if(z<10)
printf("%d ",z);
else
printf("%d",z);
}
int i,j;
Mlink *p;
p=stack;
backup[p->row][p->col]=6;
while (p->next!=NULL)
{
if(p->next->col!=NULL)
{
if( p->row > p->next->row ) backup[p->next->row][p->next->col]=5;//下一节点在下
else if(p->row<p->next->row) backup[p->next->row][p->next->col]=2;//下一节点在上
else if(p->col>p->next->col) backup[p->next->row][p->next->col]=4;//下一节点在右
else backup[p->next->row][p->next->col]=3;//下一节点在左
}
else ;
p=p->next;
}
for(i=1;i<=a;i++)
{
printf("\n");
if(i<10) printf("%d ",i); //图形左方标明行号
else printf("%d",i);
for(j=1;j<=b;j++)
{
if(backup[i][j]==0)
printf("□");
if(backup[i][j]==1)
printf("■");
if(backup[i][j]==2)
printf("↑");
if(backup[i][j]==3)
printf("←");
if(backup[i][j]==4)
printf("→");
if(backup[i][j]==5)
printf("↓");
if(backup[i][j]==6)
printf("㊣");
}
}
}
/*
颜色属性由两个十六进制数字指定 -- 第一个为背景,第二个则为
前景。每个数字可以为以下任何值之一:
0 = 黑色 8 = 灰色
1 = 蓝色 9 = 淡蓝色
2 = 绿色 A = 淡绿色
3 = 湖蓝色 B = 淡浅绿色
4 = 红色 C = 淡红色
5 = 紫色 D = 淡紫色
6 = 黄色 E = 淡黄色
7 = 白色 F = 亮白色
*/
void main(){
//背景为黑色,前景为绿色
system("color 02");
//a为迷宫的行数,b为迷宫的列数
int k = 1 , maze_row , maze_col;
//迷宫矩阵
int maze[M+2][N+2];
//备份数组以重复使用迷宫
int back_up[M+2][N+2] , p , q;
printf("我们开始建立迷宫!\n");
printf("请输入迷宫矩阵的行数: maze_row = ");
scanf("%d" , &maze_row);
printf("请输入迷宫矩阵的列数: maze_col = ");
scanf("%d" , &maze_col);
//下面这个函数为我们建立迷宫矩阵
create(maze , maze_row , maze_col);
for(p = 0 ; p <= maze_row + 2 ; p++)
for(q = 0 ; q <= maze_col + 2 ; q++)
back_up[p][q] = maze[p][q];
while(k != 0){
int x , x1 , x2 , y1 , y2;
//下面这个函数为我们打印迷宫矩阵
print(maze , maze_row , maze_col);
printf("\n\n输入迷宫入口(横坐标x1,纵坐标y1): \n");
scanf("%d%d" , &x1 ,&y1);
printf("输入迷宫出口(横坐标x2,纵坐标y2): \n");
scanf("%d%d" , &x2 , &y2);
x = Mazepath(maze , x1 , x2 , y1 , y2);
if(x==1) //迷宫可通
{
printonglu1(); //打印坐标通路
printonglu2(maze_row , maze_col);//打印图形通路
printf("\n");
}
else
{
printf("无通路! \n");//不可通
getch();
system("cls");
main();
}
for(p=0;p<=maze_row+2;p++)
for(q=0;q<=maze_col+2;q++){
backup[p][q]=back_up[p][q];
maze[p][q]=back_up[p][q];
}
printf("输入任意键返回首页:\n");
getch();
system("cls");
main();
}
}