简体   繁体   English

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

[英]What's wrong with my maze checker??? (JAVA)

So we are given a maze with walls(W) open path(O) a start pt (S) and a finish pt (F). 所以我们给了一个迷宫,墙壁(W)开放路径(O)开始pt(S)和结束pt(F)。

I am trying to write an algorithm that takes the maze file and then turns it into a 2D array of points to make a grid. 我正在尝试编写一个算法,该算法接收迷宫文件,然后将其转换为2D点阵列以构成网格。

Once I have the grid, I want to start on the 'S' character in the maze and try to find whether or not it is possible to traverse through the O's to get to the F. (Return a boolean true/false) 一旦我有了网格,我想从迷宫中的'S'字符开始并尝试查找是否可以遍历O来到达F.(返回布尔值true / false)

I know that this maze is solvable, so why am I getting 'false'?? 我知道这个迷宫是可以解决的,为什么我会变'假'? There must be a complicate problem because all I get is the plain boolean false, not the "sorry, maze isnt traversable"... 必须有一个复杂的问题,因为我得到的只是普通布尔值假,而不是“对不起,迷宫不可穿越”......

Here is the Maze1.txt file: 这是Maze1.txt文件:

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

Here is my code(new attempt): 这是我的代码(新尝试):

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;          
        }
}

Here's the algorithm: 这是算法:

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)

Just wrote this in 5 min, let me know if there are bugs. 刚刚写了5分钟,请告诉我是否有错误。

EDIT (with respect to OP's edit): 编辑(关于OP的编辑):

Your canMove<direction> methods are too complicated, there's actually no need o make such functions, much less check the stack. 你的canMove<direction>方法过于复杂,实际上不需要制作这样的函数,更不用说检查堆栈了。 Also, either your traverseMaze function should take in a row and col argument for the starting position, or you should put such information inside your class as private variables. 此外,您的traverseMaze函数应该为行起始位置接受行和col参数,或者您应该将此类信息作为私有变量放在您的类中。

Simply do something like 简单地做一些事情

//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

Now all you have to do is put the above into the loop in the algorithm provided and it should work. 现在你所要做的就是将上面的内容放入提供的算法循环中,它应该可以工作。 Note that I changed the "mark current spot in the array as 'visited' line to "mark neighbors as visited" here because checking whether a point exists inside the stack is not efficient. Much easier to just mark them as visited as you push them into the stack. However, you still need to mark your starting position as visited when you begin your loop 请注意,我在这里更改了“将数组中的当前点标记为'访问'行以”将邻居标记为已访问“,因为检查堆栈中是否存在某个点效率不高。在推送它们时将其标记为已访问更容易但是,当你开始循环时,你仍需要将你的起始位置标记为已访问

Another thought using a stack. 使用堆栈的另一种想法。

psuedo code: 伪代码:

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
   }
}

in brief, you have a stack to store the path you have walked, and try every step in the sequence of up, right, down left. 简而言之,你有一个堆栈来存储你走过的路径,并按照向上,向右,向左的顺序尝试每一步。

This approach doesn't require you to flag cells in the maze. 这种方法不要求您在迷宫中标记细胞。

You asked in the comments of your question how to find the starting point. 您在问题的评论中询问如何找到起点。 You can find the starting point during the initiation of your mazePoints array 您可以在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;
        }
      }
    }

After initialization, follow one of the algorithms that are provided above. 初始化后,请遵循上面提供的算法之一。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM