1.通过浏览器的前进后退理解栈( 四 )


如果我们想获取方格信息,如第三行、第四列方格,代码如下:
int row = 2;int column = 3;// 第 3 行,第 4 列信息char content = map[row][column]
? 我们将整个游戏用Game来表示,在Game这个类中设置一个map属性 。
? 紧接着,那应该如何表示起始和结束点位置呢?
从上面的代码我们知道每个方格有两个属性:row和,用来表示每个方格的位置,因此我们可以新建Point类用于存储位置信息 。
整合上面的思路,整个Game的代码如下:
public class Game {private char[][] map;public Game(char[][] map) {this.map = map;}// 寻找路径public ArrayList findPath(Point start, Point end) {ArrayList path = new ArrayList<>();return path;}}
Point的代码如下:
public class Point {private int row = 0;private int column = 0;.....}
注意其中的方法,返回的是一条从起点到终点的路径 。
在这个地图的基础上,我们再来考虑如何寻找路径 。
寻找路径
? 我们假设一个迷宫场景,现在我们自己站在某一个方格上(并且不是上帝视角的情况下),我们应该怎么尝试找到出口呢?
? 从我们的题目基本信息得知,当我们站在某一个方格上都有4 个方向可以进行探索:上下左右 。我们可以考虑一个思路:
当站在某个方格上时候,初始我们都选中一个方向,比如右进行探索 。如果右侧元素不是障碍物,则我们移动到右侧方格上,继续进行1步骤 。如果右侧元素为障碍物或者已经遍历过的方格,则按下、左、上方向进行探索 。如果 4 个方向都不能进一步探索,那没办法了,我们只能回退上一个方格,从新选择方向 。
因为我们知道目标终点在起点的右下角,所有我们用这个方向,可以避免很多额外的步骤 。
第一个问题:如何描述方向?
? 我们使用向量来描述方向:假定方向为(0,0),将第一位当作row上的增量, 第二位当做上的增量,那么右下左上分别表示为:
右侧:row 不变,加 1,所以向量表示为:{0, 1} 下侧:row 加 1,不变,所以向量表示为:{1, 0} 左侧:row 不变,减 1,所以向量表示为:{0, -1} 上侧:row 减 1,不变,所以向量表示为:{-1, 0}
? 因此我们在Game中添加如下代码,按顺序存储 右下左上 四个方向,代码如下
// 存储4个方向private int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
第二个问题:怎么存储探索的路径呢?还要非常方便我们回退?

1.通过浏览器的前进后退理解栈

文章插图
大家试想一下这个场景和栈的模式非常像,最开始的起点在栈底,每探索一个方格,则往栈里push一个元素,如果遇到一条死路,则pop回退到上一个元素并且换个方向继续探索 。
【1.通过浏览器的前进后退理解栈】第三个问题:怎么标记方格是否访问过?方格是否是死路?
为了区分#和空格,我们可以用*表示方格已经被访问过,用@表示方格为死路 。
? 因此我们新建一个Tile对象,表示在栈中的信息,包括方格位置和遍历的方向,代码如下:
public class Tile {// 方格位置private Point point;// 方格当前遍历的方向private int direction = 0;}
? 继续在Game中添加变量steps,利用栈存储探索路径中的方格,代码如下:
public class Game {private char[][] map;// 利用栈存储探索的路径节点,元素为Tile对象private YKDStack steps = new YKDStack