寻路算法--迷宫寻路

该篇文章接上篇并查集应用——生成随机迷宫, 此时已经可以生成一个任意大小随机的迷宫

在这里插入图片描述
       但是看起来还缺点什么,对,就是路径,没有路径怎么证明这真的是个迷宫,因此现学现用把路径加上。首先寻路算法属于图论算法,要想寻路先得有图,什么是图,这个就不细讲了,很多专门讲这个的文章,简单的说图就是一些点再加上连接这些点的边就构成了图,只要把迷宫抽象成图就能应用图论算法了。

       具体来说每个方格可以看做一个点,相连的方格间有路径,被墙隔开的两格间不连通,也就没有路,简单起见先整一个小迷宫说明问题:

在这里插入图片描述
       这样看一目了然,假如左上角是起点,右下角是终点,则实际求解的问题是从左上角到右下角的最短路,当然对这类迷宫而言最短路差不多也就是唯一路。

在这里插入图片描述
       图有了,接下来就该选择寻路算法了,首先我们的迷宫图相连两点之间都是双向互通的,并且都是单位长度,因此这个图就是一个无向无权图,有好几种算法都能达到我们的目的, 可以选择的算法有:

  • DFS: 单源最短路算法,俗称深度优先算法,简单暴力,可以处理负权但是不能处理负权环,但是就是遇到大数据会超时。
  • BFS: 单源最短路算法,俗称广度优先算法,相比DFS不那么暴力,只能处理无权图
  • Dijkstra: 效率比较好的单源最短路算法,不能处理负权图

       还有其他的寻路算法就不一一列举了,上面说了我们的图是无权的,因此这三种算法都可以,DFS和BFS编码简单,理解起来也比较容易,Dijkstra相对编码复杂些,但是也比较简单,具体算法原理就不细说了,有很多讲的很好的文章。在这里我们用BFS实现,选择邻接表来存图,具体做法很简单,就是在Square类里加上三个字段:

private Integer dist;
private Square path;
private List<Square> adj = new ArrayList<>();

       adj是与该点临接的点的列表,初始为空,随着迷宫生成和墙壁被拆掉,越来越多的点被连通,被连通的两点互相将对方加入到自己的邻接表中:

//装方块的列表
private List<Square> slist = new ArrayList<>();

//更新邻接表
Square square1 = (Square)items.get(wallIndex);
Square square2 = (Square)items.get(otherWallIndex);
square1.addAdj(square2);
square2.addAdj(square1);

具体的BFS算法:

private void findWayByBfs(Square start){
        Queue<Square> q = new LinkedList<>();

        for (Square s : slist) {
            s.setDist(-1);
        }

        start.setDist(0);
        q.offer(start);

        while (!q.isEmpty()) {
            Square s = q.remove();
            for (Square w : s.getAdj()) {
                if (w.getDist() == -1) {
                    w.setDist(s.getDist() + 1);
                    w.setPath(s);
                    q.offer(w);
                }
            }
        }
    }

这里我们寻路后,要把路径显示出来置成别的颜色,这里置成绿色:

private void printPath(Square end) {
    if (end.getPath() != null) {
        printPath(end.getPath());
    }

    Item item = items.get(end.getIndex());
    item.setColor("green");
}

       在生成迷宫的基础上只加上这些代码就可以完成寻路了,是不是很简单,最终效果:
在这里插入图片描述

代码已传到github上:https://github.com/LLuckyHe/RandomLabyrinth.git,感兴趣的小伙伴可以拿来参考。

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页