二维迷宫解算器:最后的迷宫无法打印

时间:2017-09-29 18:10:42

标签: java arrays printing solver maze

我正在开发一个程序来解决在迷宫中寻找路径的问题。迷宫由0,1和E表示,表示退出。迷宫用20x30表示(0代表路径,1代表墙壁)。我正在使用堆栈来跟踪以前可用的位置。

我想我已经找到了大部分代码,但是当我运行它并进入起始位置时,最终的迷宫不会打印出来。

我的代码如下:

import java.util.*;
import java.io.*;
public class MazeGenerator {

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

        Scanner sc = new Scanner(System.in);
        int userRow, userCol;

        MazeGenerator maze = new MazeGenerator();
        maze.fillArray();
        maze.print();

        System.out.println();

        //asking for user starting position
        System.out.print("What row would you like to start in?: " );
        userRow = sc.nextInt();
        while(userRow > 29 || userRow < 0) {
            System.out.print("INVALID INPUT! PLEASE ENTER VALUES BETWEEN 0 - 
29 INCLUSIVE: " );
            userRow = sc.nextInt();
        }
        System.out.println();

        System.out.print("What column would you like to start in? ");
        userCol = sc.nextInt();
        while(userCol > 19 || userCol < 0) {
            System.out.print("INVALID INPUT! PLEASE ENTER VALUES BETWEEN 0 - 
19 INCLUSIVE: " );
            userCol= sc.nextInt();
        }


        System.out.println("\n\nFind a path using a stack: ");
        //maze.userStart(userRow,userCol);

        maze.setUserRow(userRow);
        maze.setUserColumn(userCol);


        maze.solveStack();
        //solveStack(maze);
 }

//methods for creating maze
public static final int ROW = 30;
public static final int COLUMN = 20;
public int userRow = 0;
public int userColumn = 0;
private static String[][] maze = new String[ROW][COLUMN];

public void fillArray() throws IOException {
    File file = new File("maze.txt");
    FileReader reader = new FileReader(file);
    BufferedReader buff = new BufferedReader(reader);

    for(int counter1 = 0; counter1 < ROW; counter1++) {

        String l = buff.readLine();

        for(int counter2 = 0; counter2 < COLUMN; counter2++) {

            maze[counter1][counter2] = String.valueOf(l.charAt(counter2));
        }
    }

    buff.close();
}

public void print() throws IOException {

    System.out.printf("%-4s", ""); //spaces column
    for (int counter = 0; counter < COLUMN; counter++){

         System.out.printf("%-4d",counter); //print the column number

    }
    System.out.println();

    for(int counter1 = 0; counter1 < maze.length; counter1++) { //loop for 
printing rows

        System.out.printf("%-4d",counter1); //print row number

        for(int counter2 = 0; counter2 < maze[counter1].length; counter2++) 
{ //loop for printing columns

            System.out.printf("%-4s", maze[counter1][counter2]); //printing 
values of maze
        }
        System.out.println(); // new line
    }
}

public int getWidth(){
    return maze[0].length;
}

public int getHeight(){
    return maze.length;
}


public void setUserRow (int userRow) {
    this.userRow = userRow;
}

public void setUserColumn (int userColumn) {
    this.userColumn = userColumn;
}

public int getUserRow() {
    return userRow;
}

public int getUserColumn() {
    return userColumn;
}

public String mark(int row, int col, String value) {
    assert(inMaze(row,col)); 
    String temp = maze[row][col];
    maze[row][col] = value;
    return temp;
    }

public String mark (MazePosition pos, String value) {
    return mark(pos.row(), pos.col(), value); 
}

public boolean isMarked(int row, int col) {
    assert(inMaze(row,col)); 
    return (maze[row][col].equals("+"));
}

public boolean isMarked(MazePosition pos) {
    return isMarked(pos.row(), pos.col());
}

public boolean Clear(int row, int col) {
    assert(inMaze(row,col)); 
    return (maze[row+1][col+1] != "1" && maze[row+1][col+1] != "+");
}

public boolean Clear(MazePosition pos) {
     return Clear(pos.row(), pos.col());
 }

//true if cell is within maze 
public boolean inMaze(int row, int col) {
    if (row >= 0 && col >= 0 && row < getWidth() && col < getHeight() ) {
        return true; 
    }
    return false;
}

//true if cell is within maze 
public boolean inMaze(MazePosition pos) {
    return inMaze(pos.row(), pos.col());
} 

public boolean Done( int row, int col) {
    return (maze[row][col].equals("E"));
}

public boolean Done(MazePosition pos) {
    return Done(pos.row(), pos.col());
}

public String[][] clone() {

    String[][] copy = new String[ROW][COLUMN]; 

    for (int counter1 = 0; counter1 < ROW; counter1++) {

        for (int counter2 = 0; counter2 < COLUMN; counter2++) {

            copy[counter1][counter2] = maze[counter1][counter2];
        }
    }
    return copy; 
    }

public void restore(String[][] savedMaze) {
    for (int i=0; i< ROW; i++) 
        for (int j=0; j<COLUMN; j++)
        maze[i][j] = savedMaze[i][j];
    }

public MazeGenerator clone(MazeGenerator m) {
    MazeGenerator maze = new MazeGenerator();
    maze = m;
    return maze;
}

//**************************************************
//this solution uses a stack to keep track of possible
//states/positions to explore; it marks the maze to remember the
//positions that it's already explored.
public void solveStack() throws IOException {

//save the maze
//MazeGenerator savedMaze = new MazeGenerator();
//savedMaze.clone(m);
String[][] savedMaze = clone();

//declare the locations stack 
Stack<MazePosition> candidates = new Stack<MazePosition>(); 

//insert the start 
candidates.push(new MazePosition(userRow,userColumn)); 

MazePosition current, next;
while (!candidates.empty()) {

    //get current position
    current = candidates.pop();

    if (Done(current)) { 
        break;
    }

    //mark the current position 
    mark(current, "+");

    //put its neighbors in the queue
    next = current.north(); 
    if (inMaze(next) && Clear(next)) candidates.push(next);

    next = current.east(); 
    if (inMaze(next) && Clear(next)) candidates.push(next);

    next = current.west(); 
    if (inMaze(next) && Clear(next)) candidates.push(next);

    next = current.south(); 
    if (inMaze(next) && Clear(next)) candidates.push(next);
}

if (!candidates.empty()) {
    System.out.println("You got it!");
}
else System.out.println("You're stuck in the maze!");

//savedMaze.print();
print();

restore(savedMaze);

}

class MazePosition {
    public int row; 
    public int col;

    public MazePosition(int row, int col) {
        this.row = row; 
        this.col = col;
    }

    public int row() { return row; }

    public int col() { return col; }

    public void print() {
        System.out.println("(" + row + "," + col + ")");
    }

    //positions
    public MazePosition north() {
        return new MazePosition(row-1, col);
    }

    public MazePosition south() {
        return new MazePosition(row+1, col);
    }

    public MazePosition east() {
        return new MazePosition(row, col+1);
    }

    public MazePosition west() {
        return new MazePosition(row, col-1);
    }
}; 

    }

1 个答案:

答案 0 :(得分:0)

没有maze.txt的好处,我根据您的描述创建了一个。这是我发现的......

简答:

你的程序在搜索退出时遇到无限循环,所以它永远不会到达打印出来的代码。

答案很长:

我在2行代码中看到3个问题:

1)一个简单的拼写错误:

if (row >= 0 && col >= 0 && row < getWidth() && col < getHeight() ) {
应该交换

getHeight()和getWidth():

if (row >= 0 && col >= 0 && row < getHeight() && col < getWidth() ) {

2)在Java使用0-based indices的情况下,您使用的是基于1的索引:

在这一行:

return (maze[row+1][col+1] != "1" && maze[row+1][col+1] != "+");

java中的数组索引从0开始。你的行和col变量也从0开始。但是你要为它们添加一个,从而将它们转换为基于1的索引。所以,你想要:

return (maze[row][col] != "1" && maze[row][col] != "+");

3)你正在使用!= like!equals(),但在Java中,== is not the same as .equals()

在上面的代码行中,您将两个字符串与!=运算符进行比较。但是这不像String.equals()方法那样工作,所以你的Clear()方法总是返回true。

这是你陈述的问题的症结所在。搜索例程,找到每个单元格清晰,进入角落,然后永远搜索相同的两个相邻单元格。

所以,你真正想要的是:

return (!maze[row][col].equals("1") && !maze[row][col].equals("+"));