2009-10-06 155 views
1

我想写一个给予迷宫的程序,并试图找到出路。 M是入口,E是出口,1是墙壁,0是通道。它应该找到每个路径并将P放在路径中。它应该找到所有可用的路径。现在它找到了路径的一部分。如何找到所有可用的迷宫路径?

下面是代码:

public class Maze 
{ 
    private int size; 
    private String[][] board; 
    private int total; //# of boards 
    private int eX; 
    private int eY; 
    private int mX; 
    private int mY; 

    public Maze(int size, String[][] board) 
    { 
     this.size = size; 
     this.board = board; 
     total = 0; 

    } 

    private void find(String c) 
    { 
     int x=0, y=0; 
     for(int i = 0; i < size; i++) 
     { 
      for(int j = 0; j < size; j++) 
      { 
       if(board[i][j].equals(c)) 
       { 
        x = i; 
        y = j; 
       } 
      } 
     } 
     if(c.equals("M")) 
     { 
      mX = x; 
      mY = y; 
     } 
     else if(c.equals("E")) 
     { 
      eX = x; 
      eY = y; 
     } 
    } 

    public void findPath() 
    { 
     find("M"); 
     find("E"); 
     findNext(mX, mY); 
    } 

    public void findNext(int x, int y) 
    { 
     String last = board[x][y]; 
      if(board[x][y].equals("P")) board[x][y] = "1"; 
     board[x][y] = "P"; 

     if(rightAvailability(x,y)) 
     { 
      findNext(x+1, y); 
     } 
     else if(leftAvailability(x,y)) 
     { 
      findNext(x-1, y); 
     } 
     else if(aboveAvailability(x,y)) 
     { 
      findNext(x, y+1); 
     } 
     else if(belowAvailability(x,y)) 
     { 
      findNext(x, y-1); 
     } 
     else 
     { 
      total++; 
      printBoard(); 
     } 

     board[x][y]= last; 
    } 

    public boolean rightAvailability(int x, int y) 
    { 
     if(x+1 >= size) return false; 
     else if(board[x+1][y].equals("1")) return false; 
     else if(board[x+1][y].equals("P")) return false; 
     else return true; 
    } 
    public boolean leftAvailability(int x, int y) 
    { 
     if(x-1 < 0) return false; 
     else if(board[x-1][y].equals("1")) return false; 
     else if(board[x-1][y].equals("P")) return false; 
     else return true; 
    } 
    public boolean aboveAvailability(int x, int y) 
    { 
     if(y+1 >= size) return false; 
     else if(board[x][y+1].equals("1")) return false; 
     else if(board[x][y+1].equals("P")) return false; 
     else return true; 
    } 
    public boolean belowAvailability(int x, int y) 
    { 
     if(y-1 < 0) return false; 
     else if(board[x][y-1].equals("1")) return false; 
     else if(board[x][y-1].equals("P")) return false; 
     else return true; 
    } 

    public void printBoard() 
    { 
     System.out.println("The board number " +total+ " is: "); 
     for(int i=0; i< size; i++) 
     { 
      for(int j=0; j< size; j++) 
      { 
       if((i==mX) && (j==mY)) 
       { 
        System.out.print("M"); 
       } 
       else if((i==eX) && (j==eY)) 
       { 
        System.out.print("E"); 
       } 
       else if(board[i][j].equals("1")) 
       { 
        System.out.print("1"); 
       } 
       else if(board[i][j].equals("0")) 
       { 
        System.out.print("0"); 
       } 
       else 
       { 
        System.out.print("P"); 
       } 
      } 
      System.out.println(); 
     } 
    } 
} 

下面是测试仪:

public class MazeTester 
{ 
    public static void main(String[] args) 
    { 
     int size = 11; 
     String[][] board = new String[][] 
      { 
       {"1","1","1","1","1","1","1","1","1","1","1"}, 
       {"1","0","0","0","0","0","1","0","0","0","1"}, 
       {"1","0","1","0","0","0","1","0","1","0","1"}, 
       {"E","0","1","0","0","0","0","0","1","0","1"}, 
       {"1","0","1","1","1","1","1","0","1","0","1"}, 
       {"1","0","1","0","1","0","0","0","1","0","1"},  
       {"1","0","0","0","1","0","1","0","0","0","1"}, 
       {"1","1","1","1","1","0","1","0","0","0","1"}, 
       {"1","0","1","M","1","0","1","0","0","0","1"}, 
       {"1","0","0","0","0","0","1","0","0","0","1"}, 
       {"1","1","1","1","1","1","1","1","1","1","1"}, 
      }; 


     Maze m = new Maze(size, board); 
     m.findPath(); 
    } 
} 

这里是电流输出:

The board number 1 is: 
11111111111 
1PPPPP1PPP1 
1P1PPP1P1P1 
EP1PPPPP1P1 
101111101P1 
10101PPP1P1 
10001P1PPP1 
11111P1PP01 
101M1P1PP01 
100PPP1PP01 
11111111111 
The board number 2 is: 
11111111111 
1PPPPP1PPP1 
1P1PPP1P1P1 
EP100PPP1P1 
101111101P1 
10101PPP1P1 
10001P1PPP1 
11111P1PP01 
101M1P1PP01 
100PPP1PP01 
11111111111 
The board number 348 is: 
11111111111 
1PPPPP10001 
1P1PPP10101 
EP1PPPPP101 
1011111P101 
10101PPP101 
10001P10001 
11111P10001 
101M1P10001 
100PPP10001 
11111111111 

编辑:我添加如果(板[X ] [y] .equals(“P”))board [x] [y] =“1”;在findIndex开始。我也修复了x < = 0的问题。我更新了输出到我现在得到的(它实际上是打印348个类似的板)。

+0

当你说它需要找到“所有可能的路径”时,这是否意味着迷宫将包含循环?在循环存在的情况下对“所有可能的路径”进行严格的解释可能需要无数的路径 - 你是指所有不访问节点两次的路径? – bdonlan

+0

正确 - 它会访问一个节点两次。 –

+0

在leftAvailability中,您仍然使用y-1而不是x-1。 – CoderTao

回答

1

我把一个局部猜测行:

else if(belowAvailability(x,y)) 
{ 
     findNext(x, x-1); 
} 

X-1应该是Y-1

,你会发现另一个问题是事实,你正在使用否则,如果块。如果你遇到一个分支,比方说

1E1 
101 
1P0 
1P1 

你会尽量向右走,然后再当失败草草收场,也不会尝试去了。您实际上可以看到在测试输出中,

_._._789_._ 
_..._6_A54_ 
_____5_B23_ 
_._M_4_C10_ 
_..123_DEF_ 
___________ 

以十六进制编号方便阅读。它进入右下角,然后卡住;没有其他地方可以打印纸板,递归结束时不会回溯到未经测试的正方形。

再次编辑。仍然在寻找,但在左/右可用性方面,你有另一个x/y不匹配,你可能只想在x-1 < 0(或y-1)时拒绝可用性。作为目标节点在y = 0。

有了这些改变,并且只有当打印触发器只有当x == eX & & y == eY,我得到的解决方案的输出。许多解决方案,但解决方案。

编辑计数的另一个幽默的事实:你有左/右和上/下倒退。 x坐标指定您正在查看的输入行,并且y坐标指定列。在这种情况下使用r/c是相当普遍的。

+0

这并没有解决我的问题,但感谢捕捉! –

+0

我已经尝试每一个如果,那么\t如果((x ==除息)&&(Y == EY))为printBoard(),但是,这并不给我任何输出 –

+0

你不会想到,如果(X = = eX && y == eY)给出任何输出,因为它从来没有真正达到终点。 – CoderTao

1

标准路径查找算法应该可以工作,您需要修改它们以符合您的世界定义。

但A *或D *算法工作得很好。他们使用图表,您应该能够从您的世界定义中定义图表。 (http://en.wikipedia.org/wiki/A *)

也Dijstra的算法应该找到一个路径(再次使用图)。它通常用于网络路由 - 但它也适用于正常路径查找。(http://en.wikipedia.org/wiki/Dijkstra%27s_algorithm

基本上我的方法是将你的迷宫定义变成一个图形(节点是“连接点”,边缘是“走廊”),然后使用其中一种算法。