解决方案

解决迷宫问题

在这些注释的顶部,您将看到一个下载NetBeans项目的按钮,该项目包含我对迷宫实验室问题的解决方案。

这些笔记将带您了解该解决方案的一些关键方面。

寻找开放的邻居-处理边缘情况

下面是Maze类中用于查找给定单元格的开放邻居的方法的代码。

public Cell findOpenNeighbor(Cell fromCell) {int row = fromCell. getrow ();int col = fromCell.getColumn();if(row -1 >= 0 && grid[row-1][col].isOpen())) return grid[row-1][col];if(col -1 >= 0 && grid[row][col-1].isOpen())返回grid[row][col-1];如果(row + 1) < grid。length && grid[row+1][col].isOpen()) return grid[row+1][col];如果(col + 1 < grid[row]。length && grid[row][col+1].isOpen()) return grid[row][col+1];返回null;}

这段代码首先询问给定的Cell它位于哪一行和哪一列。此单元格的四个近邻将位于此位置的上下行和左右列中。

我们必须注意的一个重要的特殊情况是位于迷宫边缘的细胞。入口细胞曾经就是这样的例子:这个细胞位于迷宫的左侧边缘。在迷宫边缘的细胞将失去一个或多个邻居,所以我们必须添加额外的逻辑来测试这些情况,而不是试图在细胞可能没有邻居的方向上寻找。在编程中,这类特殊情况的通称是边缘情况。考虑任何特定算法中的赢博体育边缘情况是编程任务的重要组成部分。

上面的代码通过向四个if语句中的每个语句添加一个额外的测试来处理边缘情况。这个额外的测试决定了我们将要研究的方向是否是一个合法的方向。

Path类——使用数组列表

Path类将一个单元格列表存储在一个单元格数组列表中。Path类中的赢博体育方法都必须使用该ArrayList,因此编写这些方法中的大多数都是一种练习,如果找到合适的ArrayList方法来使用的话。

public class Path{/*成员变量*/ private ArrayList<Cell> cells;//保存路径cells /*构造一个初始空路径*/ public path () {cells = new ArrayList<Cell>();} /*访问方法*/ //返回路径上的最后一个单元格。public Cell lastCell(){返回Cell .get(cells.size()-1);} //打印路径上的每个cell public void Print () {for(cell c: cells) System.out.println(c);} /* Mutator方法*/ //将给定的cell添加到路径的末尾public void addCell(cell toAdd) {cells.add(toAdd);} //从路径中移除最后一个单元格公共void removeCell() {int lastIndex = cells.size() - 1;cells.remove (lastIndex);}}

写作测试方法

为了测试我编写的每个类,我还编写了包含测试程序的简短主方法。下面是Maze类的测试程序:

public static void main(String args[])抛出异常{Maze m = new Maze("test.maze");m.print ();System.out.println ();Cell入口= m.findEntrance();system . out。println(“入口是” +入口);单元格邻居= m.findOpenNeighbor(入口);system . out。println(“邻居是”+邻居);}

下面是Path类的测试程序:

public static void main(String args[]) {Path p = new Path();Cell 1 = new Cell(1,2,' 0 ');Cell 2 = new Cell(1,3,'o');p.addCell(一);p.addCell(两个);system . out。println(“移除前的路径:”);p.print ();p.removeCell ();system . out。println(“移除后的路径:”);p.print ();}

为创建的每个类编写测试程序是一个非常有用的实践。这样做将允许您在将多个类组合成完整的解决方案之前单独调试类的方法。

编写解决迷宫的程序

一旦赢博体育的类都就位了,并且我们已经测试了它们,以确保它们正常工作,最后一步就是编写迷宫解决程序本身。为此,我创建了第四个类,并为它配备了一个main方法。下面是该类的代码。

public class Search {public static void main(String[] args) {Maze m = new Maze("test.maze");路径p = new Path();Cell end = m.findEntrance();p.addCell(结束);while(end. isexit () == false) {Cell next = m.findOpenNeighbor(end);if(next == null) {p.removeCell();end = p.lastCell();} else {next.markVisited();p.addCell(下);End = next;}} p.print();}}

该解决方案在一系列回合中运行。在每一轮中,我们通过在当前路径的末端搜索Cell的开放邻居来寻求向前移动路径。如果我们能找到一个开放的邻居,我们就把它添加到路径中。如果我们找不到一个开放的邻居,我们知道我们需要返回。在这种情况下,我们将简单地从路径的末端删除一个Cell,然后使用新的路径末端再次尝试。