代码地址如下:
http://www.demodashi.com/demo/14547.html

需求

使用深度优先算法求解迷宫路径,使用Java实现求解过程的可视化,可单步运行,形象直观。

演示效果

红色格子为迷宫终点,迷宫可放大缩小,为了录屏选择了较小的尺寸,有多种不同难度的迷宫可以加载。

  1. 简单迷宫

  2. 复杂迷宫

项目运行

文件中有两个运行脚本,Windows下直接双击win运行.bat即可,linux和Mac运行sh文件中的命令即可,喜欢用IDE的也可自行创建项目。

运行项目后,点击菜单栏左上角的Map加载迷宫地图, 点击右下角的Run开始解迷宫,Step可单步运行,可通过速度进度条调节速度。

项目结构

Maze
├── classes # 存放编译生成的class文件
├── lib.jar # 打包好的gui库
├── map # 迷宫地图文件
│ ├── EasyMaze.txt
│ ├── FinalMaze01.txt
│ ├── FinalMaze02.txt
│ ├── FinalMaze03.txt
│ ├── FinalMaze04.txt
│ └── FinalMaze05.txt
├── src
│ ├── MazeBug.java
│ └── MazeBugRunner.java
├── linux运行.sh # 运行脚本
└── win运行.bat # 运行脚本

原理方法

使用深度优先算法,每个格子下一步都有上下左右4种走法,但是这4种走法并不是都是合法的,比如有些格子有障碍物,有些格式在边界之外,去掉这些剩下的才是合法的走法。

深度优先算法的思想就是:

  1. 找出当前位置A下一步合法的的格子,选择其中一个,往前走一步到达B。
  2. 如果B相邻的有合法格子,重复第1步;如果没有合法的,后退一步回到A,选择A的其他合法格子走;
  3. 重复以上方法,直到找到迷宫终点;

算法优化:上面的方法选择下一步走的方向是随机的,或者按照上下左右的顺序选择。但是很多迷宫都有偏向性,比如如果有右偏向性,那么每次都优先往右走可以更快走出迷宫。所以在实现的时候,记录每个方向走的次数,每往一个方向走一步就加1,如果回退就该方向减1,每次走都优先走次数最多的方向,当迷宫有偏向性时,该方法效率更高。

以项目中的迷宫为例,大部分情况下偏向性所需步数更少。

 普通方法:   534 1175 350 973 1052
偏向性: 552 761 330 175 420

代码实现

/*
* 节点:存储方向和该方向所走的次数
* 往一个方向前进则加1,后退则减1
*/
class Node {
private int dir; // 方向,角度值
private int ct; // 该方向所走次数 public Node(int initdir, int initct) {
dir = initdir;
ct = initct;
} public int getDir() {
return dir;
} public int getCt() {
return ct;
} public void setCt(int deta) {
ct += deta;
}
} // 深度优先算法解迷宫,并且以小甲虫的形式呈现
public class MazeBug extends Bug {
private Location next; // 下一步要走的格子
private Integer stepCount = 0; // 所走的步数
private boolean isEnd = false; // 是否到达迷宫出口
private boolean hasShown = false; // 是否显示了结束信息
private Stack<Location> path = new Stack<>(); // 存储走过的路径
private ArrayList<Node> arr = new ArrayList<>(); public MazeBug() {
setColor(Color.GREEN);
arr.add(new Node(0, 0));
arr.add(new Node(90, 0));
arr.add(new Node(270, 0));
arr.add(new Node(180, 0));
} // 周期性执行
public void act() {
boolean willMove = canMove(); // 是否还能继续移动 if (isEnd) { // 是否结束
if (!hasShown) { // 是否显示结束消息
String msg = stepCount.toString() + " steps";
JOptionPane.showMessageDialog(null, msg);
hasShown = true;
}
return;
} else if (willMove) { // 向前移动一个,步数加1
move();
++stepCount;
} else { // 不能移动,后退一步,将该方向的计数器减1
Grid<Actor> grid = getGrid();
Location loc = this.getLocation();
Location top = path.pop();
++stepCount;
grid.remove(top);
this.setDirection(loc.getDirectionToward(top));
this.moveTo(top);
// 在走过的死路留下一朵白花
Flower flower = new Flower(Color.WHITE);
flower.putSelfInGrid(getGrid(), loc); // 方向计数器减1
int dir = 180 + ((getDirection() / 90) % 2) * 180 - getDirection();
for (Node node : arr)
if (node.getDir() == dir) {
node.setCt(-1);
return;
}
}
} // 找出和当前位置相邻的、合法的并且从未走过的格子
public Location getValid(Location loc) {
Grid<Actor> gr = getGrid();
if (gr == null)
return null; // 将每个方向走过的次数从大到小排序,下一步优先选次数多的方向走
Location adjLocation;
arr.sort(new Comparator<Node>() {
@Override
public int compare(Node a, Node b) {
return (a.getCt() < b.getCt()) ? 1 : -1;
}
}); for (Node node : arr) {
adjLocation = this.getLocation().getAdjacentLocation(node.getDir());
if (gr.isValid(adjLocation)
&& (gr.get(adjLocation) == null || gr.get(adjLocation).getColor().equals(Color.RED))) {
node.setCt(1);
return adjLocation;
}
}
return null;
} // 判断当前位置是否可以继续移动
public boolean canMove() {
Grid<Actor> gr = getGrid();
Actor adj;
Location loc = this.getValid(this.getLocation());
if (loc != null) {
adj = gr.get(loc);
next = loc;
isEnd = adj != null && adj.getColor().equals(Color.RED);
return true;
}
return false;
} // 将甲虫的方向转向下一格,往前移动一步,将原来的位置压栈,并放置一朵绿花,表示走过的路径
public void move() {
Grid<Actor> gr = getGrid();
if (gr == null)
return;
Location loc = this.getLocation();
path.push(loc);
this.setDirection(loc.getDirectionToward(next));
this.moveTo(next);
Flower flower = new Flower(this.getColor());
flower.putSelfInGrid(gr, loc);
}
}

其他:

跟算法无关的代码,比如GUI方面的都打包成lib.jar了,如果想要自己更改可以自行解压。Java实现可视化迷宫

代码地址如下:
http://www.demodashi.com/demo/14547.html

注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权

Java实现可视化迷宫的更多相关文章

  1. 超级好用的 Java 数据可视化库:Tablesaw

    本文适合刚学习完 Java 语言基础的人群,跟着本文可了解和使用 Tablesaw 项目.示例均在 Windows 操作系统下演示 本文作者:HelloGitHub-秦人 HelloGitHub 推出 ...

  2. 【JAVA】可视化计算器

    import java.awt.Color; import java.awt.Font; import java.awt.GridLayout; import java.awt.event.Actio ...

  3. java的WindowBuilder可视化插件

    一直做在安卓用xml作界面,对于java的控件不熟悉,也不习惯用代码做UI尤其是布局. 找了一下发现可以安装windowbuilder来实现java的可视化编程,但是很多资料里的连接都失效了. 刚自己 ...

  4. java可视化编程-eclipse安装windowbuilder插件(转载)

    原文地址:http://blog.csdn.net/jason0539/article/details/21219043 一直做在安卓用xml作界面,对于java的控件不熟悉,也不习惯用代码做UI尤其 ...

  5. 基于Java visualvm的可视化监控的使用

    1 Java visualVM可视化监控工具打开方式 ctrl + r 快捷键调出运行窗口,输出 jvisualvm指令,即可打开java visualVM工具.详情如下图: 2 Java Visua ...

  6. 归并排序算法 java 实现

    归并排序算法 java 实现 可视化对比十多种排序算法(C#版) [直观学习排序算法] 视觉直观感受若干常用排序算法 算法概念 归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Di ...

  7. [2]R语言在数据处理上的禀赋之——可视化技术

    本文目录 Java的可视化技术 R的可视化技术 二维做图利器plot的参数配置 *权限机制 *plot独有的参数 *plot的type介绍 *title介绍 *公共参数集合--par *par的权限机 ...

  8. 7个Java项目,或许你的大学老师就会布置

    前言: 有天吃饭和朋友聊天,说到大学老师布置的开发项目,结果我们一干人说出来的都基本一样,入门级别的计算器啦,稍微大一点的记事本啦,然后到后面的图书管理系统啊,购物网站啊-- 发现这些项目都是大学老师 ...

  9. 并发编程 || Java线程详解

    通用线程模型 在很多研发当中,实际应用是基于一个理论再进行优化的.所以,在了解JVM规范中的Java线程的生命周期之前,我们可以先了解通用的线程生命周期,这有助于我们后续对JVM线程生命周期的理解. ...

随机推荐

  1. JVM内存模型及垃圾回收算法

    国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...

  2. @selector 如何调用在另一个类中的静态函数?

    可以在同一个类的methodName这个函数中再调用另一个类中的静态方法

  3. ie不支持max-height的解决之法

    .div{ max-height: 100px; _height:expression(this.scrollHeight > 100 ? "100px" : "a ...

  4. Java开发工具全面比较

    1.JDK (Java Development Kit)Java开发工具集 从初学者角度来看Java开发工具,采用JDK开发Java程序能够很快理解程序中各部分代码之间的关系,有利于理解Java面向对 ...

  5. 解决sqoop导入报错:Caused by: java.sql.SQLException: Protocol violation

    报错信息: -- ::, INFO [main] org.apache.hadoop.mapred.MapTask: Ignoring exception during close for org.a ...

  6. Jquery源码分析之匿名函数的自执行

    匿名函数的格式: 格式: (function(){ //代码 })(); //和这个基于jQuery的比较下: $(function(){ alert("this is a test&quo ...

  7. Coursera课程《Python数据结构》中课件

    You can access the Google Drive containing all of the current and in-progress lecture slides for thi ...

  8. 3D屏保:N皇后

    前几天园子里有人发表关于8皇后的算法.只有代码,没有能运行的DEMO多枯燥.于是我这两天抽时间写了个N皇后的屏保程序.程序启动后会从4皇后到14皇后显示其所有排列,每隔0.5秒自动切换一次.按下空格键 ...

  9. Nginx zabbix 的监控

    Nginx zabbix 的监控 Nginx 配置 Nginx 必须包含:http_stub_status_module 模块 ./nginx -V |grep http_stub_status_mo ...

  10. Android -- uses-sdk:minSdkVersion 10 cannot be smaller than version L declared in library com.android.support:appcompat-v7:21.0.0-rc1

    这是一个报错,是我在Android Studio上添加完Support-v4和v7包之后爆出的错误,百度了好久也没有百度到.当时我的项目有minSdkVersion 19. 设置版本最小为L的时候也会 ...