目录
项目介绍:
一个网格迷宫由n行m列的单元格组成,每个大院个要么是空地(用0表示),要么是障碍物(用1表示)。你的任务是找一条从起点到终点的移动序列,其中只能上下左右移动到相邻单元格。任何时候都不能在有障碍物的单元格中,也不能走到迷宫之外。起点为左上角和终点右下角。
项目功能:
- 寻找一条从左上角迷宫入口到右下角迷宫出口的一条有效路径。
- 0代表可走,1代表不能行走,8代表行走的路径。
- 找到请输出最终的迷宫和路径信息,找不到请输出不存在有效路径。
项目知识点:
采用Java面向对象思想,二维数组以及非递归栈进行实现
项目思路:
- 定义一个迷宫节点类型(MazeNode)的二维数组
- 初始化每个格子中的value值。给二维数组每个格子存放对象。对象的value值只能为0(当前格子可以走)或者1(当前格子不能走)
- 初始化每个格子四个方向(东南西北)是否是可走状态。根据当前节点周围四个方向格子中的value值,判断当前节点的东南西北四个方向是否可走(0是可走,1不可走)。
- 开始走迷宫。采用栈操作,记录行走的路径,将左上角元素入栈,判断当前栈顶元素的哪个方向可走,将其中一个可走方向进行入栈操作,直到右下角元素停止。栈中保存走过的路径。
注意:如果遇到走入死胡同问题,此时需要将是栈顶元素并且栈顶元素的四个方向都不能行走,此时将其出栈,选择新方向再次入栈,直到右下角元素停止。
测试数据及分析:
1.直接走出
2.需要回退,重新找路
3.不通,回退直到栈为空
代码:
Maze.java
import java.util.Scanner;
import java.util.Stack;
public class Maze {
private MazeNode[][] mazeNodes;//节点数组
private int row;//数组的行个数
private int column;//列
private Stack<MazeNode> stack;
public Maze( int row, int column) {
this.row = row;
this.column = column;
mazeNodes = new MazeNode[row][column];
stack=new Stack<MazeNode>();
}
//初始化value值
public void initValue() {
System.out.println("请输入迷宫路径:(0表示可走,1表示不可走)");
Scanner sc=new Scanner(System.in);
for(int i=0;i<row;i++)
for(int j=0;j<column;j++)
{
mazeNodes[i][j]=new MazeNode(sc.nextInt(),i,j);
}
}
//初始化每个结点的行走状态
//--------->j |
// 上北 |
//左西 右东 \|/
// 下南 i
private void initWayState() {
for(int i=0;i<row;i++)
for(int j=0;j<column;j++){
//为1像墙不可达,故不用 判断墙的四周
//四周都要判断,不要用else if
if(mazeNodes[i][j].getValue() == 0) {
//东 为0可走就置able)
if(j+1<column && mazeNodes[i][j+1].getValue() == 0) {
mazeNodes[i][j].setWayState(Maze_Constant.WAY_EAST,Maze_Constant.WAY_ABLE);
}
//南
if(i+1<row && mazeNodes[i+1][j].getValue() == 0) {
mazeNodes[i][j].setWayState(Maze_Constant.WAY_SOUTH,Maze_Constant.WAY_ABLE);
}
//西
if(j-1>=0 && mazeNodes[i][j-1].getValue() == 0) {
mazeNodes[i][j].setWayState(Maze_Constant.WAY_WEST,Maze_Constant.WAY_ABLE);
}
//北
if(i-1>=0 && mazeNodes[i-1][j].getValue() == 0) {
mazeNodes[i][j].setWayState(Maze_Constant.WAY_NORTH,Maze_Constant.WAY_ABLE);
}
}
}
}
//从左上角找右下角的出路
//找到一条就行
public void goMaze() {
initValue();
initWayState();
if(mazeNodes[0][0].getValue()!=0) {
System.out.println("没有路径");
return;
}
//用栈保存行走路线信息
stack.push(mazeNodes[0][0]);
while(!stack.isEmpty()) {
MazeNode top=stack.peek();//获取栈顶端的元素
//到右下角了
if(top.getxPos()==row-1 && top.getyPos()==column-1) {
break;
}
//获取栈顶元素位置
int xPos=top.getxPos();
int yPos=top.getyPos();
//不用看越界,已经初始化过各方向状态了
//避免成环
//注意每次while循环 只走一步路,所以搭配else if
if(top.getWayState(Maze_Constant.WAY_EAST)) {
//向东走
stack.push(mazeNodes[xPos][yPos+1]);
//将当前结点(x,y)的走过方向(东)封掉
mazeNodes[xPos][yPos].setWayState(Maze_Constant.WAY_EAST, Maze_Constant.WAY_DISABLE);
//将东边结点(x,y+1)的回路,西边方向封掉
mazeNodes[xPos][yPos+1].setWayState(Maze_Constant.WAY_WEST, Maze_Constant.WAY_DISABLE);
}else if(top.getWayState(Maze_Constant.WAY_SOUTH)) {
//南
stack.push(mazeNodes[xPos+1][yPos]);
mazeNodes[xPos][yPos].setWayState(Maze_Constant.WAY_SOUTH, Maze_Constant.WAY_DISABLE);
mazeNodes[xPos+1][yPos].setWayState(Maze_Constant.WAY_NORTH, Maze_Constant.WAY_DISABLE);
}else if(top.getWayState(Maze_Constant.WAY_WEST)) {
//西
stack.push(mazeNodes[xPos][yPos-1]);
mazeNodes[xPos][yPos].setWayState(Maze_Constant.WAY_WEST, Maze_Constant.WAY_DISABLE);
mazeNodes[xPos][yPos-1].setWayState(Maze_Constant.WAY_EAST, Maze_Constant.WAY_DISABLE);
}else if(top.getWayState(Maze_Constant.WAY_NORTH)) {
//北
stack.push(mazeNodes[xPos-1][yPos]);
mazeNodes[xPos][yPos].setWayState(Maze_Constant.WAY_NORTH, Maze_Constant.WAY_DISABLE);
mazeNodes[xPos-1][yPos].setWayState(Maze_Constant.WAY_SOUTH, Maze_Constant.WAY_DISABLE);
}else if(!top.getWayState(Maze_Constant.WAY_EAST)&&!top.getWayState(Maze_Constant.WAY_WEST)&&!top.getWayState(Maze_Constant.WAY_NORTH)&&!top.getWayState(Maze_Constant.WAY_SOUTH)) {
//说明进入死胡同结点(四周都不能走),从栈中删除栈顶元素,重找
stack.pop();//删除栈顶元素
}
}
show();
}
//找到路径后,需要将栈中的元素值改为可识别的
private void show() {
// TODO Auto-generated method stub
if(stack.isEmpty()) {
System.out.println("没有迷宫路径");
return;//退出
}
while(!stack.isEmpty()) {
MazeNode top=stack.peek();
top.setValue(8);
stack.pop();
}
System.out.println("路径已找到,如下(2代表行走 的路径):");
for(int i=0;i<row;i++) {
for(int j=0;j<column;j++){
System.out.print(mazeNodes[i][j].getValue()+" ");
}
System.out.println();
}
}
}
Maze_Constant.java
public class Maze_Constant {
public static final int WAYSIZE=4;
public static final int WAY_EAST=0;//东南西北
public static final int WAY_SOUTH=1 ;
public static final int WAY_WEST=2 ;
public static final int WAY_NORTH=3 ;
public static final boolean WAY_ABLE=true ;
public static final boolean WAY_DISABLE=false ;
}
MazeNode.java
public class MazeNode {
private int value;//0或1
//当前对象在二维数组中的位置
private int xPos;//行
private int yPos;//列
private boolean[] WayState;//4个元素代表4个方向
public MazeNode(int value, int xPos, int yPos) {
WayState =new boolean[Maze_Constant.WAYSIZE];
this.value = value;
this.xPos = xPos;
this.yPos = yPos;
}
public int getValue() {
// TODO Auto-generated method stub
return value;
}
public void setWayState(int direction, boolean isAble) {
// TODO Auto-generated method stub
this.WayState[direction]=isAble;
}
public int getxPos() {
return xPos;
}
public int getyPos() {
return yPos;
}
public boolean getWayState(int direction) {
// TODO Auto-generated method stub
return WayState[direction];
}
public void setValue(int i) {
// TODO Auto-generated method stub
value=i;
}
}
MazeTest.java
import java.util.Scanner;
import javax.xml.soap.SAAJResult;
public class MazeTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("请输入行列数");
Scanner sc=new Scanner(System.in);
int row =sc.nextInt();
int column=sc.nextInt();
Maze maze=new Maze(row,column);
maze.goMaze();
}
}