java - 使用回溯算法测试鼠标是否可以逃离矩形迷宫

标签 java arrays linked-list stack nodes

该程序旨在通过读取文本文件来创建和解决鼠标从迷宫逃生的路线。有一个 Maze 类,它基本上是 MazeElements 的 2D 数组,MazeElements 包含一个 char 变量和一个位置目的; Position 保存二维数组上每个元素的坐标。 到目前为止,程序有效地读入并创建了二维数组。问题出在backTracking算法上。我正在使用堆栈来实现回溯,但回溯似乎只从输出循环一次。不知道你是否能从下面的代码中发现一些东西: 导入 java.io.; 导入java.util.;

public class MazeSolver
{
  public static void main (String [] parms)
  {

    Maze maze = new Maze();
    maze.displayMaze();
    maze.backTracking();
    maze.displayMaze();
  }
}
//**********************************
//*******Position class*************
//**********************************
class Position
{
  private int row;
  private int col;

  public Position()
  {
    row =0;
    col =0;
  }
  public Position (int x, int y)
  {
    row = x;
    col = y;
  }
  public void setRow(int x)
  {
    row = x;
  }
  public void setCol(int y)
  {
    col = y;
  }
  public int getRow()
  {
    return row;
  }
  public int getCol()
  {
    return col;
  }
  //NOTE: wrote for testing purposes, to see the mouse and exit positions
  public String getPosition()
  {
    return row + ", " + col;
  }
}//end Position
//**********************************
//*******Maze element class*********
//**********************************
class MazeElement
{
  private char letter;
  private Position prevPosition;

  public MazeElement(char c, Position p)
  {
    this.letter = c;
    this.prevPosition = p;
  }
  public char getLetter()
  {
    return letter;
  }
  public Position getPosition()
  {
    return prevPosition;
  }
  public void setPosition(Position p)
  {
    this.prevPosition = p;
  }
  public void setLetter(char c)
  {
    this.letter = c;
  }
  public void printElement()
  {
    System.out.print(letter + " ");
  }
}//end MazeElement

//**********************************
//*******Maze class*****************
//**********************************
class Maze
{
  private MazeElement [][] maze;
  private int  numRows;
  private int numCols;
  private Position start;
  private Position exit;



  BufferedReader inFile;
  Scanner kbd = new Scanner(System.in);
  String inLine;
  String fileName;
  String [] tokens;

  public Maze()
  {
    try
    {
      System.out.println("Input file name");
      fileName = kbd.next();
      inFile = new BufferedReader(new FileReader(fileName));
      inLine = inFile.readLine();

      tokens = inLine.trim().split("\\s+");
      numRows = Integer.parseInt(tokens[0]);
      numCols = Integer.parseInt(tokens[1]);
      maze = new MazeElement[numRows][numCols];

      for(int row = 0; inLine != null && row < numRows; row++)
      {
        inLine = inFile.readLine();
        tokens = inLine.trim().split("\\s+");
        for(int col = 0; col < numCols; col++)
        {
          maze[row][col] = new MazeElement(tokens[col].charAt(0),null);
        }
      }
      inFile.close();

      //finding m and e from the maze
      for (int i = 0; i < maze.length; i++) 
      {
        for (int j = 0; j < maze[i].length; j++) 
        {
          char letter = maze[i][j].getLetter();
          if(letter == 'm')
          {
            start = new Position(i,j);
          }
          if(letter == 'e')
          {
            exit = new Position(i,j);
          }
        }
      }
    }//end try block
    catch (IOException ioe)
    {
      System.out.println(ioe.getMessage());
    }

  }//end public Maze()
  public void backTracking()
  {
    Stack<Position> theStack = new Stack<Position>();//initialise stack
    Position goal = exit;
    Position curr;
    MazeElement north, south, east, west;
    int currRow, currCol;
    curr = null;
    boolean foundGoal = false;

    theStack.push(start);

    while((!foundGoal) && (!theStack.isEmpty()))
    {
      curr = theStack.pop();
      currRow = curr.getRow();
      currCol = curr.getCol();

      //check neighbouring positions
      east = maze[currRow][currCol+1];
      south = maze[currRow+1][currCol];
      west = maze[currRow][currCol-1];
      north = maze[currRow-1][currCol];

      //searching clockwise
//setting visited positions to '.', open = '0', wall = '1', exit==goal = 'e'
      if(isValidPosition(east))
      {
        if(east.getLetter() == 'e')
        {
          east.setPosition(curr);
          theStack.push(east.getPosition());
          foundGoal = true;
        }
        else if((!foundGoal)&&(east.getLetter() == '0')&& (east.getLetter() != '.'))
        {
          east.setLetter('.');
          east.setPosition(curr);
          theStack.push(east.getPosition());
        }
      }
      else if(isValidPosition(south))
      {
        if(south.getLetter() == 'e')
        {
          south.setPosition(curr);
          theStack.push(south.getPosition());
          foundGoal = true;
        }
        else if((!foundGoal)&&(south.getLetter() == '0')&& (south.getLetter() != '.'))
        {
          south.setLetter('.');
          south.setPosition(curr);
          theStack.push(south.getPosition());
        }
      }
      else if(isValidPosition(west))
      {
        if(west.getLetter() == 'e')
        {
          west.setPosition(curr);
          theStack.push(west.getPosition());
          foundGoal = true;
        }
        else if((!foundGoal)&&(west.getLetter() == '0')&& (west.getLetter() != '.'))
        {
          west.setLetter('.');
          west.setPosition(curr);
          theStack.push(west.getPosition());
        }
      }
      else if(isValidPosition(north))
      {
        if(north.getLetter() == 'e')
        {
          north.setPosition(curr);
          theStack.push(north.getPosition());
          foundGoal = true;
        }
        else if((!foundGoal)&&(north.getLetter() == '0')&& (north.getLetter() != '.'))
        {
          north.setLetter('.');
          north.setPosition(curr);
          theStack.push(north.getPosition());
        }
      }
    }//end while

  }
  public void displayMaze()
  {
    for (int i = 0; i < maze.length; i++) 
    {
      for (int j = 0; j < maze[i].length; j++) 
      {
        maze[i][j].printElement();
      }
      System.out.println();
    }
    System.out.println("start is at " + start.getPosition());
    System.out.println("exit is at " + exit.getPosition()); 
  }//displayMaze()

  public boolean isValidPosition(MazeElement element)
  {
    char wall = '1';
    return (element.getLetter() != wall);
  }
}


//**********************************
//*******Stack<E> class*************
//**********************************
class Stack<E> 
{
  protected Node<E> head; 
  public Stack() 
  {
    head = null;
  } 
  public boolean isEmpty() 
  { 
    return (head == null);
  } 
  public void push(E item) 
  {
    head = new Node<E>(item, head);
  } 
  public E top() 
  { 
    E topItem = null; 
    if (head != null) topItem = head.getData(); 
    return topItem; 
  }
  public E pop() 
  {
    E topItem = top(); 
    if (head != null) head = head.getNext(); 
    return topItem; 
  }
}
//**********************************
//*******Node class*****************
//**********************************
class Node <E>
{
  private E data;
  private Node<E> next;

  public Node ()
  {
    //initializing everything to null at first
    next = null;
    data = null;
  }
  public Node(E data, Node <E> n)
  {
    this.data = data;
    this.next = n;
  }
  public E getData()
  {
    return data;
  }
  public Node <E> getNext()
  {
    return next;
  }
  public void setNext(Node <E> next)
  {
    this.next = next;
  }
}

我的输入文件如下:

6 5
1 1 1 1 1
1 0 0 e 1
1 1 1 0 1
1 m 1 0 1
1 0 0 0 1
1 1 1 1 1

当我在调用 backTrack() 方法后打印迷宫时,我的迷宫(具有 m 和 e 位置)变为:

1 1 1 1 1 
1 0 0 e 1 
1 1 1 0 1 
1 m 1 0 1 
1 . 0 0 1 
1 1 1 1 1 
start is at 3, 1
exit is at 1, 3

问题是我不明白为什么我的 curr 没有超出点“。”在输出中。请帮忙?

最佳答案

这里:

if(isValidPosition(east))
{
    if(east.getLetter() == 'e')
    {
        east.setPosition(curr);
        theStack.push(east.getPosition());
        foundGoal = true;
    }
    else if((!foundGoal)&&(east.getLetter() == '0')&& (east.getLetter() != '.'))
    {
        east.setLetter('.');
        theStack.push(east.getPosition());
    }
}

原文: 据我所知,唯一被插入 theStack 的是 start。因此,curr == start。然后,在您的条件下,如果它符合您所做的指示:

east.setPosition(curr); theStack.push(east.getPosition());

(或者无论它测试哪个方向,在本例中它实际上是南)。

请记住,第一次 curr == start,因此您要设置 east.setPosition == curr == start,这意味着您推回堆栈start

现在,代码再次运行,theStack 中只有 1 个内容,并且与之前相同,除了 start 下面的字符现在是“.”,因此没有有效的方向和您的 while 循环中断。

要修复代码,您必须将一个 Position 推送到 theStack ,其值为方向的值,并且不更新方向位置。

关于java - 使用回溯算法测试鼠标是否可以逃离矩形迷宫,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26499484/

相关文章:

python - 如何解析数据集之间变化的数组?

javascript - 由许多数组组成的映射 JSON 对象中的表

javascript - 从复选框选择更改 AJAX jQuery url

go - 如何在链表的给定索引处插入节点

java - 为什么 Integer.parseInt ("1")++ 在 Java 中不起作用?

Java 正则表达式以条件替换器开头和结尾

java - 使用 JSEFA 将不同类的 java 对象序列化为 CSV 中的一行

java - SharedPref 在重新启动应用程序时不保存更改

java - 递归大小法链表

java - java中将一个链表添加到另一个链表