java实现寻找迷宫路径

迷宫描述:一个网格迷宫由n行m列的单元格组成,每个单元格要是空地(用0表示),或者是障碍物(用1表示)。寻找一条从起点到终点的移动序列,只能上下左右移动到相邻单元格。任何时候都不能在有障碍物的单元格中,也不能走到迷宫之外。起点为左上角和终点右下角。

问题:解决迷宫路径查找问题,寻找一条从左上角迷宫入口到右下角迷宫出口的一条有效路径,0代表可走,1代表不能行走,找到请输出最终的迷宫和路径信息,找不到请输出不存在有效路径。
迷宫示例

0 1 1 1 1
0 1 1 1 1
0 0 0 0 1
1 1 1 0 1
1 1 1 0 0

问题分析
迷宫可以用二维数组表示,迷宫的起点和终点已经确定,为左上角到右下角。现在需要设计一个程序,可以让它自动从左上角走到右下角,如果走进死路了,可以退回去,换一条路走。需要解决的问题有:

  • 如何确定哪个方向可以走,如果有多个方向可以走,怎么确定走哪个?
  • 如何让程序一直走下去?进入死路了如何退出来?
  • 如何让程序停下来?

显然可走的方向有四个,上下左右。走的顺序可以提前设定,比如顺序为:→ ↓ ← ↑。什么方向不能走?节点为1的,和来的方向的节点。
可以用栈来存储当前走过的节点,如果这个节点四个方向都不能走,则将栈顶节点出栈,回退到上一个位置。
如何让程序一直走下去?这里需要一个循环结构,首先想到的就是while循环,现在需要设计的是内部的处理过程和循环条件。
在这里插入图片描述

现在已经有了一个大致的思路,还未解决的问题有:

  • 如何让节点不会回到来的位置。
  • 如何让节点不会又走进之前走过的死路。

判断节点可以走的条件是该位置为0,所以可以把节点走过的位置的值改为2,走入死路后,回退时可以将该位置改为1,这样就不会再次走进这条路。
现在基本解决了大多数的问题,可以开始写了。
首先需要一个节点类,它要存储当前节点的位置。

public class Point {
    public int[] pointArray;//存储当前位置坐标
 
    public Point(int x,int y){
        pointArray=new int[2];
        pointArray[0]=x;
        pointArray[1]=y;
    }
}

一个节点操作类

public class Labyrinth {
    Scanner scanner=new Scanner(System.in);
    Stack<Point> stack=new Stack<>();
    int[][] arr;
    public  Labyrinth(){


    }

    public   int[][] inputNum(){

        System.out.println("请输入迷宫行列数:");
        int line = scanner.nextInt();//行
        int row = scanner.nextInt();//列

        System.out.println("请输入迷宫:");

        int[][] arr=new int[line][row];

        for(int i=0;i<line;i++){
            for(int k=0;k<row;k++){
                arr[i][k]=scanner.nextInt();
            }
        }
        return  arr;

    }

    public  void  show(){
        for(int i=0;i<arr.length;i++){
            System.out.println(Arrays.toString(arr[i]));
        }
    }


    public void findPath(){//核心方法
        int line=arr.length;
        int row=arr[0].length;
        boolean flag=true;
        Point point=new Point(0,0);
        stack.push(point);
        boolean anser=true;
        while (flag){
            if(stack.empty()){
               anser=false;
               break;
            }
           Point point1=stack.peek();
           int x=point1.pointArray[0];
           int y=point1.pointArray[1];
           if(x==line-1&&y==row-1&&arr[line-1][row-1]==0){
               arr[line-1][row-1]=2;
               break;
           }
           int index=canRun(x,y);
           operation(index,x,y);
       
        }

    }
    //找到可以走的方向后,对该方向的节点做入栈操作,若该节点四个方向都走不了,则出栈该节点
    public void operation(int index,int x,int y){
        switch (index){
            case 1:
                Point point1=new Point(x,y+1);
                stack.push(point1);
                arr[x][y]=2;
                break;
            case 2:
                Point point2=new Point(x+1,y);
                stack.push(point2);
                arr[x][y]=2;
                break;
            case 3:
                Point point3=new Point(x,y-1);
                stack.push(point3);
                arr[x][y]=2;
                break;
            case 4:
                Point point4=new Point(x-1,y);
                stack.push(point4);
                arr[x][y]=2;
                break;
            case 5://四个方向都走不了
                arr[x][y]=1;
                stack.pop();
                break;

        }
    }
//判断哪个方向可以走
    public int canRun(int x,int y){
      if(y+1<arr[0].length&&arr[x][y+1]==0){
          return 1;
      }
      if(x+1<arr.length&&arr[x+1][y]==0){
          return 2;
      }
      if(y-1>=0&&arr[x][y-1]==0){
          return 3;
      }
      if(x-1>=0&&arr[x-1][y]==0){
            return 4;
      }
      return 5;//四个方向都走不了
    }

    public static void main(String[] args) {
        Labyrinth labyrinth=new Labyrinth();
       labyrinth.arr=labyrinth.inputNum();
       labyrinth.findPath();
       labyrinth.show();

    }



}

测试:
在这里插入图片描述
结果:
在这里插入图片描述
该方法缺点:只能找到一条路径,后续会更新优化后的方法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值