基于深度优先遍历的随机迷宫算法

 这两天因为要做一个随机的地图生成系统,所以一直在研究随机迷宫生成算法,好吧,算是有一点小小的成果。

随机迷宫生成我自己的理解简而言之分为以下几步:

1、建立一张地图,我用的二维数组表示,地图上全是障碍物。然后再创建一个用来表示每个格子是否被访问过的二维数组。再创建一个用来表示路径的栈结构。

2、随机选择地图上的一点,呃为了方便我初始点直接取的是左上角即坐标表示为0,0的格子。终点的话因为不涉及到交互就暂时没有。

3、查找当前格子的邻接格(注意,这里的邻接格子都是还未被访问的,下面的代码里有写)。随机选择一个邻接格子为下一格,当前格移动到下一格,标记当前格为已访问,将当前格压入路径栈中。一直重复第三步操作。

4、在第三步操作中,如果当前格子不存在可访问的邻接格,则将栈顶的元素弹出,即退回上一步操作,如果栈为空,则结束程序,打印结果。

附上结果和源码,这是基于JAVA控制台来写的。

        


[java]  view plain  copy
  1. package maze;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5. import java.util.Random;  
  6. import java.util.Stack;  
  7.   
  8. public class Maze   
  9. {  
  10.     int len = 11//迷宫长度  
  11.     int wid = 11//迷宫宽度  
  12.       
  13.     char wall =  '■'//代表墙  
  14.     char blank = '○'//代表空地  
  15.       
  16.     char[][] maze; //迷宫  
  17.     boolean[][] visit; //用来标记某一格是否被访问过  
  18.       
  19.     Node start = new Node(0,0); //开始节点  
  20.     Node exit = new Node(len - 1, wid - 1); //出口,其实现在也没什么用,因为没有交互只是生成了一个迷宫而已  
  21.     Node cur; //当前格  
  22.     Node next; //下一格  
  23.       
  24.       
  25.     Stack<Node> path = new Stack<Node>(); //表示路径的栈  
  26.       
  27.     int[][] adj = {  
  28.             {0,2},{0,-2},{2,0},{-2,0}  
  29.     }; //用来计算邻接格  
  30.       
  31.     /** 
  32.      * 迷宫的格子类 
  33.      * @author Yan 
  34.      * 
  35.      */  
  36.     class Node  
  37.     {  
  38.         int x,y;  
  39.         public Node(){}  
  40.         public Node(int x, int y)  
  41.         {  
  42.             this.x = x;  
  43.             this.y = y;  
  44.         }  
  45.         public String toString() {  
  46.             return "Node [x=" + x + ", y=" + y + "]";  
  47.         }  
  48.           
  49.     }  
  50.   
  51.     /** 
  52.      * 初始化,初始化迷宫参数 
  53.      */  
  54.     void init()  
  55.     {  
  56.         maze = new char[len][wid];  
  57.         visit = new boolean[len][wid];  
  58.         for(int i = 0; i < len; i++)  
  59.         {  
  60.             for(int j = 0; j < wid; j++)  
  61.             {  
  62.                 maze[i][j] = wall;  
  63.                 visit[i][j] = false;  
  64.             }  
  65.         }  
  66.         visit[start.x][start.y] = true;  
  67.         maze[start.x][start.y] = blank;  
  68.           
  69.         cur = start; //将当前格标记为开始格  
  70.     }  
  71.       
  72.     /** 
  73.      * 打印结果 
  74.      */  
  75.     void printMaze()  
  76.     {  
  77.         for(int i = 0; i < len; i++)  
  78.         {  
  79.             for(int j = 0; j < wid; j++)  
  80.             {  
  81.                 System.out.print(maze[i][j] + "  ");  
  82. //                
  83. //              if(maze[i][j] == '○')  
  84. //              {  
  85. //                  System.err.print(maze[i][j] + "  ");  
  86. //              }  
  87. //              else  
  88. //              {  
  89. //                  System.out.print(maze[i][j] + "  ");  
  90. //              }  
  91. //              try {  
  92. //                  Thread.sleep(100);  
  93. //              } catch (InterruptedException e) {  
  94. //                  e.printStackTrace();  
  95. //              }  
  96.             }  
  97.             System.out.println();  
  98.         }  
  99.         System.out.println("==========================================");  
  100.     }  
  101.       
  102.     /** 
  103.      * 开始制作迷宫 
  104.      */  
  105.     void makeMaze()  
  106.     {  
  107.         path.push(cur); //将当前格压入栈  
  108.         while(!path.empty())  
  109.         {  
  110.             Node[] adjs = notVisitedAdj(cur);//寻找未被访问的邻接格  
  111.             if(adjs.length == 0)  
  112.             {  
  113.                 cur = path.pop();//如果该格子没有可访问的邻接格,则跳回上一个格子  
  114.                 continue;  
  115.             }  
  116.               
  117.             next = adjs[new Random().nextInt(adjs.length)]; //随机选取一个邻接格  
  118.               
  119.               
  120.             int x = next.x;  
  121.             int y = next.y;  
  122.               
  123.             //如果该节点被访问过,则回到上一步继续寻找  
  124.             if(visit[x][y])  
  125.             {  
  126.                 cur = path.pop();  
  127.             }  
  128.             else//否则将当前格压入栈,标记当前格为已访问,并且在迷宫地图上移除障碍物  
  129.             {  
  130.                 path.push(next);  
  131.                 visit[x][y] = true;  
  132.                 maze[x][y] = blank;  
  133.                 maze[(cur.x + x) / 2][(cur.y + y) / 2] = blank; //移除当前格与下一个之间的墙壁  
  134.                 cur = next;//当前格等于下一格  
  135.             }  
  136.         }  
  137.     }  
  138.       
  139.     /** 
  140.      * 判断节点是否都被访问 
  141.      * @param ns 
  142.      * @return 
  143.      */  
  144.     boolean allVisited(Node[] ns)  
  145.     {  
  146.         for(Node n : ns)  
  147.         {  
  148.             if(!visit[n.x][n.y])  
  149.                 return false;  
  150.         }  
  151.         return true;  
  152.     }  
  153.       
  154.     /** 
  155.      * 寻找可访问的邻接格,这里可以优化,不用list 
  156.      * @param node 
  157.      * @return 
  158.      */  
  159.     Node[] notVisitedAdj(Node node)  
  160.     {  
  161.         List<Node> list = new ArrayList<Node>();  
  162.         for(int i = 0; i < adj.length; i++)  
  163.         {  
  164.             int x = node.x + adj[i][0];  
  165.             int y = node.y + adj[i][1];  
  166.             if( x >= 0 && x < len && y >= 0 && y < wid)  
  167.             {  
  168.                 if(!visit[x][y])  
  169.                     list.add(new Node(x,y));  
  170.             }  
  171.         }  
  172.         Node[] a = new Node[list.size()];  
  173.         for(int i = 0; i < list.size(); i++)  
  174.         {  
  175.             a[i] = list.get(i);  
  176.         }  
  177.         return a;  
  178.     }  
  179.       
  180.     /** 
  181.      * 入口方法 
  182.      * @param args 
  183.      */  
  184.     public static void main(String[] args) {  
  185.         Maze m = new Maze();  
  186.         m.init();  
  187.         m.makeMaze();  
  188.         m.printMaze();  
  189.     }  
  190. }  




https://blog.csdn.net/y378076136/article/details/19832659



猜你喜欢

转载自blog.csdn.net/varyall/article/details/80498784
今日推荐