很久之前写的了,新人第六篇博客
默认从(1,1)开始走,默认方向是往右(0)走,准备往右走时先提前计算出往右走后落点处坐标,也就是(1,2),然后通过判断(1,2)是不是墙(判断是否为0),如果是墙就换个方向测试直到下一个落脚点不是墙,如果4个方向都是墙那就直接退出外循环,现在当测到往下的方向(1)时可以走那就退出内循环然后把当前位置(1,1)入栈,再把下一个落脚点的坐标变成当前位置,也就是新的当前位置是(2,1),然后再把上一个落脚点堵住(置1),然后把方向改回默认方向(0),回到判断下一个是否为落脚点的语句里,像之前那样个个方向都判断,直到下一个落脚点不是墙为止,判断过后可以发现下一个落脚点就是(2,2),所以故技重施,把当前位置(2,1)入栈,再把下一个落脚点的坐标变成当前位置,也就是新的当前位置是(2,2),再把上一个落脚点堵住(置1),然后方向也改回默认方向,重复上面步骤,然后判断过后可以发现下一个落脚点就是(2,3),所以故技重施,把当前位置(2,2)入栈,再把下一个落脚点的坐标变成当前位置,也就是新的当前位置是(2,3),然后继续当到出口时把(2,3)入栈,然后此时坐标是(3,3)已经是地图的右下角故不满足循环条件退出循环把(3,3)入栈。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define R 3//出口
#define C 3
//数组里面去寻路:位置- ->行和列
struct position
{
int row;//行
int cols;//列
};
struct position pathStack[100];//存放路径-->栈内存
int stackTop = -1;//栈顶标记
int** maze = NULL;//二维数组去描述地图
int size = 0;//迷宫大小
int** makeArray(int row, int cols)
{
int** array = (int**)malloc(sizeof(int) * row);
for (int i = 0; i < cols; i++)
{
array[i] = (int*)malloc(sizeof(int) * cols);
}
return array;
}
//用户输入一个迷宫
void createMaze()
{
printf("输入迷宫大小:\n");
scanf("%d", &size);
maze = makeArray(size + 2, size + 2);//加2 表示边框
printf("输入迷宫:\n");
for (int i = 1; i <= size; i++)
{
for (int j = 1; j <= size; j++)
{
scanf("%d", &maze[i][j]);
}
}
//加边框:1 表示不可以走
for (int i = 0; i <= size; i++)
{
maze[0][i] = maze[size + 1][i] = 1;//上下两行
maze[i][0] = maze[i][size + 1];//左右两列
}
}
//找路径
int findPath()
{
//偏移属性描述出来
struct position offset[4];//0-3表示四个方向
//往右走
offset[0].row = 0;
offset[0].cols = 1;
//往左走
offset[2].row = 0;
offset[2].cols = -1;
//往下走
offset[1].row = 1;
offset[1].cols = 0;
//往上走
offset[3].row = -1;
offset[3].cols = 0;
//选定入口
struct position here = { 1,1 };//当前位置
//走迷宫:记录走过的路
//走过ID路标记为1
maze[1][1] = 1;
int option = 0;//下一个移动方向
int endOption = 3;//终止方向
while (here.row != R || here.cols != C)
{
//相邻的位置做移动
int rowNum, colsNum;//记录下标变化
while (option <= endOption)
{
//行的变化=原位置+偏移量 ,偏移量由方向决定
rowNum = here.row + offset[option].row;
colsNum = here.cols + offset[option].cols;
//一旦确定一个方向可以走,就需去下一步
if (maze[rowNum][colsNum] == 0)
break;//退出循环走另一边
//不能走就换方向测试
option++;
}
//可以走
if (option <= endOption)
{
//走到下一个
pathStack[++stackTop] = here;
//改变当前位置
here.row = rowNum;
here.cols = colsNum;
//走过的路标记--->堵上
maze[rowNum][colsNum] = 1;
option = 0;//置0 去找下一个位置
}
else//option==4;表示没有可走的地方
{
//回到上一步去
if (stackTop == -1)
return 0;//无路可走表示没有路径
//出栈方式去回退到上一步
struct position next = pathStack[stackTop];
stackTop--;
//方向的处理
if (next.row == here.row)//行没变,左右走的
{
//逆过来偏移公式
option = 2 + next.cols - here.cols;
}
else
{
option = 3 + next.row - here.row;
}
here = next;//当前位置变成回退后的位置
}
}
if (here.row == R && here.cols == C)
{
pathStack[++stackTop] = here;
}
//打印到出口后的地图
printf("\n");
for (int i = 1; i <= size; i++)
{
for (int j = 1; j <= size; j++)
{
printf("%d ", maze[i][j]);
}
printf("\n");
}
printf("\n");
return 1;
}
//打印路径
void printPath()
{
printf("路径方式:\n");
struct position curPos;
while (stackTop != -1)
{
curPos = pathStack[stackTop];
stackTop--;
printf("(%d ,%d)--->", curPos.row, curPos.cols);
}
printf("\n");
}
int main()
{
createMaze();
if (findPath())
{
printPath();
}
else
{
printf("没有路径\n");
}
return 0;
}