Java - 使用独特的解决方案创建迷宫

时间:2016-04-05 16:02:42

标签: java path maze

所以我现在正在尝试制作一个通过迷宫找到单一解决方案的java程序。为此,我使用了一种创建迷宫的创建方法,该迷宫具有独特的解决方案:

private void Create ( int x, int y, int val ) {
        int[] perm = randPerm( 4 );
        m[x][y] ^= val;  
        for (int i=0; i<4; ++i) {
            int p = perm[i];
            if (m[x+DX[p]][y+DY[p]] == 15) {
                m[x][y] ^= TWO[p];  
                Create( x+DX[p], y+DY[p], TWO[p^2] );
            }
        }
    }

所以在我开始制作解决迷宫的方法之前,我试图弄清楚上面的方法总是如何创建一个具有独特路径的迷宫(比如什么?^ p ^ 2 用于)。那么上面的方法是如何工作的呢?

 private int[][] m;   // maze representation
   private int rows;    // number of rows in the maze
   private int cols;    // number of columns in the maze
   private final static byte[] TWO = { 1, 2, 4, 8, 16};
   private final static byte[] DX  = { 0,+1, 0,-1};
   private final static byte[] DY  = {-1, 0,+1, 0};
   private boolean done;  // used in finding a single solution.
   private long   count;  // used in finding the number of solutions.
   private Random r;      // for generating random integers.

public Maze ( int nr, int nc, int seed ) {
      r = new Random( seed );
      rows = nr;  cols = nc;
      m = new int[nr+2][nc+2];
      for (int r=1; r<=nr; ++r )
         for (int c=1; c<=nc; ++c )
            m[r][c] = 15;
      for (int r=0; r<nr+2; ++r )
            m[r][0] = m[r][nc+1] = 16;
      for (int c=0; c<nc+2; ++c )
         m[0][c] = m[nr+1][c] = 16;
      Create( nr/2+1, nc/2+1, 0 );
   }

private int[] randPerm( int n ) {
      int[] perm = new int[n];
      for (int k=0; k<n; ++k) perm[k] = k;
      for (int k=n; k>0; --k) {
         int rand = r.nextInt(k);
         int t = perm[rand];  perm[rand] = perm[k-1];  perm[k-1] = t;
      }
      return( perm );
   }

1 个答案:

答案 0 :(得分:0)

好吧花了一点时间,但这就是我所拥有的。

首先,Maze的构造函数创建一个大小为nc +2 x nr +2的网格,使用16填充所有边框单元格,并使用{填充所有内部单元格{1}}。然后它以网格中间单元格坐标开始递归调用15

Create()首先调用Create(),它会创建一个包含整数int[] perm = randPerm( 4 );的长度为4的数组,并在其上执行简单的随机随机播放。 0 - 3的内容用于从perm[]DX[]中选择一对值。

此方法使用DY[]运算符(^XOR函数来修改调用该方法的单元格的值,并以随机顺序修改其相邻单元格如果单元格的内容为Exclusive Or,则由perm[]DX[]DY[]的内容决定。通过仅检查15,先前修改的单元格不会改变,并且边界周围的墙壁保持不变。此外,使用此方法无法将任何中间单元格更改为15

包含值16的每个单元格都是15,其值为XOR'd,也是随机选择的,不包括TWO[],因为16来自p的内容,约束在perm之间。通过这样做,包含0 - 3的每个单元格都会更改为不同的数字 - 但这些数字可以提前知道,因为中间单元格的可能值受{{1}的所有可能结果的约束}。

由于15对象15 ^ TWO[p]初始化为Random变量,我相信每次初始化JVM时,使用相同的r都会产生相同的迷宫。因此,通过更改seed的值,您将生成与seed的其他每个值不同的不同迷宫。不过,我在这一点上可能是错的,无论seed的值如何,它每次都可能不同。我不熟悉seed的内部运作方式。

至于如何知道迷宫是否真的可以解决每个实例,我不能不知道每个可能的值在迷宫中代表什么。我想象有些数字被认为是无法通行的,有些则不是吗?

鉴于已经提供的内容,我认为无法保证每个 有效的解决方案,因为这个实现确实如此只是创建一组随机的图块,肯定会出现不是解决方案的情况。但是,你并没有规定每个迷宫必须是可以解决的;只是独一无二如果你想每次都保证一条可解决的路径,那么就必须在这里插入一些额外的逻辑来实现这一目标。