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

 更新时间:2019年02月20日 14:25:38   作者:严洋羽  
今天小编就为大家分享一篇关于Java基于深度优先遍历的随机迷宫生成算法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧

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

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

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

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

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

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

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

package maze;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Stack;
public class Maze 
{
 int len = 11; //迷宫长度
 int wid = 11; //迷宫宽度
 char wall = '■'; //代表墙
 char blank = '○'; //代表空地
 char[][] maze; //迷宫
 boolean[][] visit; //用来标记某一格是否被访问过
 Node start = new Node(0,0); //开始节点
 Node exit = new Node(len - 1, wid - 1); //出口,其实现在也没什么用,因为没有交互只是生成了一个迷宫而已
 Node cur; //当前格
 Node next; //下一格
 Stack<Node> path = new Stack<Node>(); //表示路径的栈
 int[][] adj = {
  {0,2},{0,-2},{2,0},{-2,0}
 }; //用来计算邻接格
 /**
 * 迷宫的格子类
 * @author Yan
 */
 class Node
 {
 int x,y;
 public Node(){}
 public Node(int x, int y)
 {
  this.x = x;
  this.y = y;
 }
 public String toString() {
  return "Node [x=" + x + ", y=" + y + "]";
 }
 }
 /**
 * 初始化,初始化迷宫参数
 */
 void init()
 {
 maze = new char[len][wid];
 visit = new boolean[len][wid];
 for(int i = 0; i < len; i++)
 {
  for(int j = 0; j < wid; j++)
  {
  maze[i][j] = wall;
  visit[i][j] = false;
  }
 }
 visit[start.x][start.y] = true;
 maze[start.x][start.y] = blank;
 cur = start; //将当前格标记为开始格
 }
 /**
 * 打印结果
 */
 void printMaze()
 {
 for(int i = 0; i < len; i++)
 {
  for(int j = 0; j < wid; j++)
  {
  System.out.print(maze[i][j] + " ");
//  if(maze[i][j] == '○')
//  {
//   System.err.print(maze[i][j] + " ");
//  }
//  else
//  {
//   System.out.print(maze[i][j] + " ");
//  }
//  try {
//   Thread.sleep(100);
//  } catch (InterruptedException e) {
//   e.printStackTrace();
//  }
  }
  System.out.println();
 }
 System.out.println("==========================================");
 }
 /**
 * 开始制作迷宫
 */
 void makeMaze()
 {
 path.push(cur); //将当前格压入栈
 while(!path.empty())
 {
  Node[] adjs = notVisitedAdj(cur);//寻找未被访问的邻接格
  if(adjs.length == 0)
  {
  cur = path.pop();//如果该格子没有可访问的邻接格,则跳回上一个格子
  continue;
  }
  next = adjs[new Random().nextInt(adjs.length)]; //随机选取一个邻接格
  int x = next.x;
  int y = next.y;
  //如果该节点被访问过,则回到上一步继续寻找
  if(visit[x][y])
  {
  cur = path.pop();
  }
  else//否则将当前格压入栈,标记当前格为已访问,并且在迷宫地图上移除障碍物
  {
  path.push(next);
  visit[x][y] = true;
  maze[x][y] = blank;
  maze[(cur.x + x) / 2][(cur.y + y) / 2] = blank; //移除当前格与下一个之间的墙壁
  cur = next;//当前格等于下一格
  }
 }
 }
 /**
 * 判断节点是否都被访问
 * @param ns
 * @return
 */
 boolean allVisited(Node[] ns)
 {
 for(Node n : ns)
 {
  if(!visit[n.x][n.y])
  return false;
 }
 return true;
 }
 /**
 * 寻找可访问的邻接格,这里可以优化,不用list
 * @param node
 * @return
 */
 Node[] notVisitedAdj(Node node)
 {
 List<Node> list = new ArrayList<Node>();
 for(int i = 0; i < adj.length; i++)
 {
  int x = node.x + adj[i][0];
  int y = node.y + adj[i][1];
  if( x >= 0 && x < len && y >= 0 && y < wid)
  {
  if(!visit[x][y])
   list.add(new Node(x,y));
  }
 }
 Node[] a = new Node[list.size()];
 for(int i = 0; i < list.size(); i++)
 {
  a[i] = list.get(i);
 }
 return a;
 }
 /**
 * 入口方法
 * @param args
 */
 public static void main(String[] args) {
 Maze m = new Maze();
 m.init();
 m.makeMaze();
 m.printMaze();
 }
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对脚本之家的支持。如果你想了解更多相关内容请查看下面相关链接

相关文章

  • Spring Data JPA框架的核心概念与Repository接口详解

    Spring Data JPA框架的核心概念与Repository接口详解

    Spring Data JPA是Spring基于JPA规范的基础上封装的⼀套 JPA 应⽤框架,可使开发者⽤极简的代码即可实现对数据库的访问和操作,本篇我们来了解Spring Data JPA框架的核心概念与Repository接口
    2022-04-04
  • 浅析Java验证码生成库JCaptcha

    浅析Java验证码生成库JCaptcha

    JCaptcha 是一个用来生成验证码的开源Java类库,使用起来也是非常的简单方便。本文通过代码实例介绍了JCaptcha类库。
    2016-07-07
  • Java8 HashMap遍历方式性能探讨

    Java8 HashMap遍历方式性能探讨

    JDK8之前,可以使用keySet或者entrySet来遍历HashMap,JDK8中引入了map.foreach来进行遍历
    2021-09-09
  • Eclipse中导入Maven Web项目并配置其在Tomcat中运行图文详解

    Eclipse中导入Maven Web项目并配置其在Tomcat中运行图文详解

    这篇文章主要介绍了Eclipse中导入Maven Web项目并配置其在Tomcat中运行图文详解,需要的朋友可以参考下
    2017-12-12
  • resubmit渐进式防重复提交框架示例

    resubmit渐进式防重复提交框架示例

    这篇文章主要为大家介绍了resubmit渐进式防重复提交框架示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • java 线程中start方法与run方法的区别详细介绍

    java 线程中start方法与run方法的区别详细介绍

    这篇文章主要介绍了java 线程中start方法与run方法的区别详细介绍的相关资料,在java线程中调用start方法与run方法的区别在哪里? 这两个问题是两个非常流行的初学者级别的多线程面试问题,这里进行详细说明,需要的朋友可以参考下
    2016-11-11
  • Java中初始化List的5种方法示例

    Java中初始化List的5种方法示例

    这篇文章主要给大家介绍了关于Java中初始化List的5种方法,文中通过示例代码介绍的非常详细,对大家学习或使用java具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • Gradle的SpringBoot项目构建图解

    Gradle的SpringBoot项目构建图解

    这篇文章主要介绍了Gradle的SpringBoot项目构建图解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Java中的魔法类:sun.misc.Unsafe示例详解

    Java中的魔法类:sun.misc.Unsafe示例详解

    Java是一个安全的开发工具,它阻止开发人员犯很多低级的错误,而大部份的错误都是基于内存管理方面的。如果你想搞破坏,可以使用Unsafe这个类。下面这篇文章主要给大家介绍了关于Java中魔法类:sun.misc.Unsafe的相关资料,需要的朋友可以参考下
    2018-05-05
  • java 实现局域网文件传输的实例

    java 实现局域网文件传输的实例

    这篇文章主要介绍了java 实现局域网文件传输的实例的相关资料,这里提供了实现代码可以帮助大家理解TCP及文件读写的知识,需要的朋友可以参考下
    2017-07-07

最新评论