当前位置: 首页 > 知识库问答 >
问题:

我的迷宫检测器怎么了???(JAVA)

秦时铭
2023-03-14

所以我们有一个迷宫,有墙(W ),开放路径(O ),起点点(S)和终点点(F)。

我试图编写一个算法,采取迷宫文件,然后把它变成一个二维数组的点,使网格。

一旦我有了网格,我想从迷宫中的“S”字符开始,并尝试找到是否有可能穿过“O”到达“f”。(返回布尔值true/false)

我知道这个迷宫是可以解决的,那么为什么我得到了“假”??一定有一个复杂的问题,因为我得到的只是简单的布尔假,而不是“对不起,迷宫不可穿越”...

以下是Maze1.txt文件:

WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW
WSOOOOOOOOOOOOOOWOOOOOOOOOOOOOOOOOWOOOOOOOOOOOOOOOWOOOOOOW
WWOOOOOOOOOOOOOWWWWWWWWWWWWWOOOOOOOOOOWWWWWWWWWWWWWOOOOOOW
WWWWWWOOOOOOOOOOOOWWWWWWWOOOOOOOOOOOOWWWWWWWWWWWWWWWWOOOOW
WOOOOOOWWWWWWWWWWWWWWOOOOOOOOOOOWWWWWWWWOOOOOOOOOOOOOOOWWW
WOOOOWWWWWWWOOOOOOWWWWOOOOOOWWWWWWWWWWWOOOOWWWWWWWWWOWWWWW
WOOOWWWWWWWWWWWWOOWWWWWWWWWWWWOOOOOOOOOOOOWWWWWWWWWOOOOOWW
WOOWWWWWWWWWWWWWOOWWWWWWWWWWWWWWWWWOOOOOOOWWWWWWWWWWWWOOOW
WOWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWOOOOOOOWWWWWWWWWWWOOW
WOWWWWWWWWWWWWWOOOOOOOOOOOOOOOOOOOOOOOOOOOOWWWWWWWWWWWWOOW
WOOOOOOOOOOOOOOOOWWWWOOOOOOOOWWWWWWWOOOOOOWWWWWWWWWWWWWOFW
WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW

这是我的代码(新尝试):

import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Stack;
import java.awt.Point;

public class MazeExplorer {
    static Point startPoint = new Point();
    static Point finishPoint = new Point();
    final static int mazeHeight = 12;
    final static int mazeWidth = 58;
    static char[][] mazePoints = new char[mazeHeight][mazeWidth];
    Stack<Point> pointsNotTraversed = new Stack<Point>();
    Point pt = new Point();
    static HashSet<Point> previousLocations = new HashSet<Point>();
    static Stack<Point> nextPoints = new Stack<Point>();

    public static void main(String[] args) throws FileNotFoundException{

        System.out.println("Please enter the file name of your Maze");
        Scanner console = new Scanner(System.in);
        File f = new File(console.nextLine());
        Scanner sc = new Scanner(f);

        if(!sc.hasNextLine()){
            System.out.println("Sorry, please enter a file name with the extension, that contains a maze!");
        }
        System.out.println("So, you want to know if your maze is solvable.....?");

        for (int row = 0; row < mazeHeight && sc.hasNext(); row++) {
            final String mazeRow = sc.next(); //Get the next row from the scanner.
            mazePoints[row] = mazeRow.toCharArray(); //Convert the row into a char[].
        }
            //identify the finish point
        for(int i = 0; i < mazeHeight; i++){
            for(int j = 0; j<mazeWidth; j++){
                if(mazePoints[i][j] == 'F'){
                    finishPoint = new Point(i, j);
                }       
            }
        }
        // Identify the start point
       for(int i = 0; i< mazeHeight; i++){
           for(int j = 0; j < mazeWidth; j++){
               if(mazePoints[i][j] == 'S'){
                 startPoint = new Point(i , j);
               }
           }
       }
       isTraversable(startPoint);    
    }
        public static  boolean isTraversable(Point current){
            boolean isSolvable = false;
            do {
                mazePoints[current.x][current.y] = ' ';

                if (mazePoints[current.y - 1][current.x] == 'O'){ //up dir
                   nextPoints.push(new Point(current.y - 1, current.x));
                    mazePoints[current.y - 1][current.x] = ' ';  //'X' marks where you've already been          
                }
                if(mazePoints[current.y + 1][current.x] == 'O'){ // below direction
                    nextPoints.push(new Point(current.y + 1, current.x));
                    mazePoints[current.y + 1][current.x] = ' ';        
                }
                if(mazePoints[current.y][current.x + 1] == 'O'){ // to the right
                    nextPoints.push(new Point(current.y, current.x + 1));
                    mazePoints[current.y][current.x + 1] = ' ';
                }
                if(mazePoints[current.y][current.x - 1] == 'O'){ // to the left
                    nextPoints.push(new Point(current.y, current.x - 1));
                    mazePoints[current.y][current.x - 1] = ' ';             
                }
                if(mazePoints[current.y][current.x] == 'F'){
                    isSolvable = true;
                    System.out.println("MAZE IS SOLVABLE, YAHOOOOOO!!!!");
                }
                current = nextPoints.peek();
                nextPoints.pop();
                isTraversable(current);         
            } while(!current.equals('F') && !nextPoints.isEmpty());         
            return isSolvable;          
        }
}

共有3个答案

西门淮晨
2023-03-14

使用堆栈的另一个想法。

伪代码:

push starting point to path stack
lastStepValid = true
while (stack is not empty && goal not found) {
  lastStep = peek the top of path stack


  if (lastStep == goal) {
      goal found = true
  } else if (not lastStepValid) {
    leave last step poped
    if (path stack is not empty) {
      pop path stack
      lastStepValid = true
      if (lastStep is UP of top of path stack) {
          push RIGHT of top of path stack to path stack 
      } else if (lastStep is RIGHT of top of path stack) {
          push DOWN of top of path stack to path stack
      } else if (lastStep is DOWN of top of path stack) {
          push LEFT of top of path stack to path stack
      } else {
          lastStepValid = false
      }
    }
  } else if (lastStep is wall || lastStep exists more than once in the stack) {
      lastStepValid = false;
   } else {  // last step is valid
      push the UP of lastStep to path stack
   }
}

简而言之,你有一个堆栈来存储你走过的路径,并尝试按向上、向右、向下、向左的顺序走每一步。

这种方法不需要你在迷宫中标记细胞。

陶征
2023-03-14

您在问题的评论中询问了如何找到起点。您可以在启动mazePoints阵列时找到起点

    Stack<Point> stack = new Stack<Point>();
    Point start;
    File f = new File("Maze1.txt");
    final Scanner sc = new Scanner(f);
    for (int row = 0; row < mazeHeight && sc.hasNext(); row++) {
      final String mazeRow = sc.next(); //Get the next row from the scanner.
      mazePoints[row] = mazeRow.toCharArray(); //Convert the row into a char[].
      for (int i = 0; i < mazeRow.length(); i++) {
        if (mazeRow.charAt(i) == 'S') {
          start = new Point(row, i);
          stack.push(start);
          break;
        }
      }
    }

初始化后,遵循上面提供的算法之一。

芮瑾瑜
2023-03-14

这是算法:

do
    mark current spot in the array as "visited" (can use any symbol you want)
    push all of the neighbors not yet visited onto the stack
    current spot <-- top of the stack to visit the next spot
    pop the stack
while (exit is not found && stack is not empty)

刚刚在5分钟内写了这个,让我知道是否有错误。

编辑(相对于OP的编辑):

您的<代码>可以移动

简单地做类似的事情

//assuming that current spot is at r,c
if (mazePoints[r-1][c] == 'O'){ //up dir
    pointsInMaze.push(new Point(r, c));
    mazePoints[r-1,c] = '';  //empty char marks where you've already been
}
//other directions ommitted here

现在您所要做的就是将上述内容放入提供的算法中的循环中,它应该可以工作。请注意,我在这里将“将数组中的当前点标记为‘已访问’行”更改为“将邻居标记为已访问”,因为检查堆栈内是否存在一个点效率不高。在将它们推入堆栈时将它们标记为已访问要容易得多。但是,当您开始循环时,您仍然需要将您的起始位置标记为已访问

 类似资料:
  • 如何让我的球从屏幕上的物体上反弹? 下图是一个很好的例子,说明一旦球碰到障碍物,程序应该如何工作。 我让球从墙上反弹,但剩下的是让它也从物体上反弹。谢谢你的帮助! 以下是源代码:

  • 我正在尝试制作我的第一个Pacman游戏,但我遇到了一堵我自己似乎无法打破的墙:( 这是关于如何在我的游戏中检测碰撞,所以步行者不能穿过障碍物/墙壁。我已经使它不能去屏幕外与此代码: ,但如果我在屏幕中间的电路板上有一个矩形,我不知道如何编程,这样它就会在墙前停止。 我需要阻止我的pacman移动到竞技场内的墙上,如你所见(左上方的矩形) 我的Board类代码: 希望有人能告诉我该怎么做...似乎

  • 我想用递归法解迷宫。在下面的代码中,MazeCord是程序员创建的类型,它存储坐标类型位置。格式为mazecord(int x,int y)。现在编译时,我的程序会到达方法的某些部分,而忽略另一部分,因此在所有情况下都会显示“未找到路径”,并且只在LinkedList mazePath中存储开始位置。search()方法中有一个被注释掉的部分,这是我尝试的另一种方法,但我很确定它是错误的,不是这样

  • 因此,我的任务是创建一个带有队列、集合、位置对象和Cell对象的迷宫求解器,最终形成一个迷宫对象。 要快速了解我的所有代码在完成后都会做些什么: 对此: 到目前为止,我所做的一切都很好,但是当我在我的Maze对象中实际编码findPath()方法时,我的代码会生成一个无效的路径。当我接收一个文件来读取迷宫时,我将该迷宫转换为多维字符数组,然后我将该字符数组转换为多维单元格数组,并使用布尔值映射每个

  • 我正在使用html5画布和javascript开发一个迷宫游戏(我更喜欢使用jquery库进行编码)这个游戏是为移动设备而设计的,我对使用触摸事件是完全陌生的 在画布上,我添加了迷宫图像-黑白gif迷宫。 我将使用trouch在迷宫中导航。 以下是我所做的: > 为触摸添加事件侦听器: window.add事件监听器(触摸移动,句柄移动,假); 添加了处理移动的功能: 函数handleMove(e

  • 主要内容:回溯算法解决迷宫问题迷宫问题指的是:在给定区域内,找到一条甚至所有从某个位置到另一个位置的移动路线。举个简单的例子,如图 1 所示,在白色区域内找到一条(甚至所有)从起点到终点的路线。 图 1 迷宫问题 迷宫问题就可以采用 回溯算法解决,即从起点开始,采用不断“回溯”的方式逐一试探所有的移动路线,最终找到可以到达终点的路线。 回溯算法解决迷宫问题 以图 1 所示的迷宫为例,回溯算法解决此问题的具体思路是: 从当前位置