题目描述
设有一个由8X8的方格构成的迷宫如图所示(用1表示墙,用0表示空格),试设计并实现@从迷宫上方的入口处走到下方出口处的C语言程序。程序中使用的特殊字符串是█和@(每个汉字是都2个字符的字符串)。
1@111111
10010001
11000111
10010001
11110111
10000001
10101001
11111101
具体实现
- 迷宫可以用下列二维数组实现:其中1表示墙;0表示路;2表示入口;3表示出口;4表示已经试探过的路(建议使用枚举类型表示数据)。如图-1的迷宫的初始状态可以用下列数组表示:
int maze[8][8]={{1,2,1,1,1,1,1,1},
{1,0,0,1,0,0,0,1},
{1,1,0,0,0,1,1,1},
{1,0,0,1,0,0,0,1},
{1,1,1,1,0,1,1,1},
{1,0,0,0,0,0,0,1},
{1,0,1,0,1,0,0,1},
{1,1,1,1,1,1,3,1}}; - 使用结构构建一个双向链表记录已经试探成功的路径如下:
struct PATH
{
int m;//地图数组的行下标
int n;//地图数组的列下标
PATH *next;
PATH *prev;
}; - 迷宫探路规则:
- 先试着往下走,如果下一格有墙或走过,则试着往右走;
- 如果右一格有墙或者走过,则试着往左走;
- 如果左一格有墙或者走过,则试着往上走;
- 如果上一格有墙或走过,此时表示上、下、左、右都没有未走过的路,便必须后退,并删除目前的节点。
- 程序的基本流程:
- 构建地图数组;
- 构建路径双向链表;
- 找到地图中的入口位置;
- 寻路直到出口;
- 程序结束;
代码实现
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
struct PATH
{
int m;//地图数组的行下标
int n;//地图数组的列下标
struct PATH *next;
struct PATH *prev;
};
int main()
{
int i,j,flag=0;
int maze[8][8]={{1,0,1,1,1,1,1,1},
{1,0,0,1,0,0,0,1},
{1,1,0,0,0,1,1,1},
{1,0,0,1,0,0,0,1},
{1,1,1,1,0,1,1,1},
{1,0,0,0,0,0,0,1},
{1,0,1,0,1,0,0,1},
{1,1,1,1,1,1,3,1}};//利用布尔数组设置迷宫,1代表墙壁,0代表通路,2代表小人,3代表出口
struct PATH *head=NULL,*p=NULL,*pr=NULL,*k1=NULL,*k2=NULL;
head=(struct PATH*)malloc(sizeof(struct PATH));
head->next=NULL,head->m=0,head->n=1;
maze[head->m][head->n]=2;//头节点与初始界面单独设置
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
if(maze[i][j]==1)
{
printf("█");
}
else if(maze[i][j]==2)
{
printf("@");
}
else
{
printf(" ");
}
}
printf("\n");
}
Sleep(1000);//调用Sleep函数延时1000*1毫秒=1秒
system("cls");
while(1)
{
p=(struct PATH*)malloc(sizeof(struct PATH));
pr=head;
while(pr->next!=NULL)
{
pr=pr->next;
}
pr->next=p;
p->next=NULL,p->prev=pr;//创建新节点,并使指针P指向这个节点
if(maze[(pr->m)+1][pr->n]==0)// 先试着往下走,
{
maze[(pr->m)+1][pr->n]=2;
maze[(pr->m)][pr->n]=4;
p->m=(pr->m)+1,p->n=pr->n;
}
else if(maze[(pr->m)+1][pr->n]==3)
{
maze[(pr->m)+1][pr->n]=2;
maze[(pr->m)][pr->n]=4;
flag=1;
}
else//如果下一格有墙或走过,则试着往右走
{
if(maze[(pr->m)][(pr->n)+1]==0)
{
maze[(pr->m)][(pr->n)+1]=2;
maze[(pr->m)][(pr->n)]=4;
p->m=pr->m,p->n=(pr->n)+1;
}
else if(maze[(pr->m)][(pr->n)+1]==3)
{
maze[(pr->m)][(pr->n)+1]=2;
maze[(pr->m)][(pr->n)]=4;
flag=1;
}
else//如果右一格有墙或者走过,则试着往左走;
{
if(maze[(pr->m)][(pr->n)-1]==0)
{
maze[(pr->m)][(pr->n)-1]=2;
maze[(pr->m)][(pr->n)]=4;
p->m=pr->m,p->n=(pr->n)-1;
}
else if(maze[(pr->m)][(pr->n)-1]==3)
{
maze[(pr->m)][(pr->n)-1]=2;
maze[(pr->m)][pr->n]=4;
flag=1;
}
else//3) 如果左一格有墙或者走过,则试着往上走
{
if(maze[(pr->m)-1][(pr->n)]==0)
{
maze[(pr->m)-1][(pr->n)]=2;
maze[(pr->m)][(pr->n)]=4;
p->m=(pr->m)-1,p->n=pr->n;
}
else if(maze[(pr->m)-1][pr->n]==3)
{
maze[(pr->m)-1][pr->n]=2;
maze[(pr->m)][pr->n]=4;
flag=1;
}
else/* 如果上一格有墙或走过,此时表示上、下、左、右都没有未走过的路
便必须后退,并删除目前的节点*/
{
maze[(pr->m)][(pr->n)]=4;
pr=pr->prev;//删除目前节点,也即使寻节指针指向前驱节点,并将前驱节点的next指针指向NULL
maze[(pr->m)][(pr->n)]=2;
pr->next=NULL;
}
}
}
}
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
if(maze[i][j]==1)
{
printf("█");
}
else if(maze[i][j]==2)
{
printf("@");
}
else
{
printf(" ");
}
}
printf("\n");
}
if(flag==1)
{
printf("祝贺你已经走出迷宫,请按回车键结束!");
break;
}
else
{
Sleep(1000);
system("cls");
}
}
k1=head,k2=NULL;
while(k1!=NULL)//释放内存
{
k2=k1;
k1=k1->next;
free(k2);
}
}