if(labyrinth[elem.x][elem.y+1] == YES && elem.direction != EAST) { direction = EAST; all_direction[i++] = EAST; }坐标是按照二维数组的行列来规定的,这里给出的是判断当前坐标的东向是可通,YES表明可通,当坐标的东邻坐标([elem.x][elem.y+1])值为YES的时候,我们并不能
(2)根据方向的数目来走迷宫
case 1:先看只有一个方向可走到时候
这种情况很好解决,按着扫描的方向走一步就OK,让移动后的坐标入栈即可,这里我遇到了一个小问题,就是由于很多次的往回走,每一次都要入栈或出栈,貌似这样可能
造成路径栈中存在几个相同的坐标,并且这些坐标在栈中都是相邻的,所以我在每次入栈的时候都判断了一下,如果和栈顶元素相同,就不入栈了,以免最后弹出正确路径的
时候出现多个重复的坐标
case 2:这个条件是程序的关键部分,总的来说就是先走一个方向,若未遇到终点,就返回到交岔路结点,再走向另一条路,反复直到走到终点
case 2: { Push_Stack(&cross_point,position); GetElem_Stack(&path,&top_path); if(top_path.x != position.x || top_path.y != position.y) Push_Stack(&path,position); Print_Position(position); Move_Path(&position,all_direction[0],&path,&cross_point,labyrinth); if(position.x == (LINE-2) && position.y == (ROW-2)) break; Move_Path(&position,all_direction[1],&path,&cross_point,labyrinth); } break;首先让交岔路结点入栈(交叉点栈),让这个点入路径栈
接下来就是走向第一个方向,进入这个方向后,position将先通过all_direction[0]方向移动一格,然后利用递归,对新坐标进行扫描,判断出可通方向个数(0,1,2三种),
接着就开始重复昨天的故事,也就是递归了,当这一个方向走完后,这个Move_Path就结束了,然后判断是否到了终点,如果不是终点就进入第二个Move_Path,继续递归,
知道走到终点
这种递归过程,完全可以利用二叉树的图形来理解,先走完一个方向,再走另一个方向,二叉树如图:
箭头代表单通道,X代表死路
路线;
起点-->1-->3-->(弹出3)1-->4-->(弹出4、1)-->起点....
这是左方向的走法,右方向按着这个方法走下去就能找到终点。
case 0:
当我们到了交叉点3的时候,会发现它是一个死胡同,即可通方向为0,这个时候就需要不断的弹出路径栈的元素,一直到交叉点1,进入交叉点4的方向。
(3)封掉已经确定的死路
当我们弹出交叉点1,返回到起点时,我们就可以确定从交叉点1走到方向的所有路都不可能走到终点,这个时候,我们就可以封掉交叉点1,即
把此坐标的值从1变为0
其实进行第二次Move_Path的时候,坐标已经到了交叉点2了,也就是说在交叉点2处扫描的时候,是不会检测交叉点1的,这样看来封掉死路似乎
没有必要,确实是的,但是如果你设计的Move_Path没有一进入就将坐标移到下一个位置的话,这个东西就必要了,也就是你再次在起点扫描可能
会又把交叉点1扫描进去,就造成了一个无限的函数嵌套了。。。
封掉死路只是一个我们思考的一个常识,根据个人而定。
(4)走迷宫循环的第一步(关键):
if(count_direction != 0) { count_direction = Scan_Direction(position,all_direction,labyrinth); } else { break; }这个代码应该算得上短小精悍,if条件语句表示在上一次循环中不是在case 0的switch语句中结束的,因为case 0本身就表示扫描的方向为0,如果这里没有这个判断,