前言: 在 第一篇文章 中,我们讨论了 如何用 pygame 写一个小游戏,并用键盘交互控制 。接下来,我们将分别用 DFS 、BFS 、DRL 实现自动控制。DFS 已经在 这篇文章 中讨论过,现在来看 BFS 。

使用广度优先搜索方法实现游戏的自动控制

本文涉及一个 .py 文件:

bfs_play.py


如上图,我们将使用“广度优先搜索”的方法,来控制黑色方块自动闯关。

所谓“广度优先搜索”,即:

  • 搜索:精准预测行一步操作后,黑色方块将到达什么位置;并再次精准预测在这个位置进行操作后,黑色方块将到达什么位置…直到触发终止条件,即找到最终得分的路径;
  • 广度优先:假设黑色方块有两个动作可以选择:A与B,那么黑色方块做出“选择A后应该到达的位置”的预测后,不继续接着这条路径预测;而是去预测在初始状态下“选择B后应该到达的位置”。具体原理如下图。


图片生成自:https://visualgo.net/zh/dfsbfs

为了更好地了解 BFS 的特性,你可以用 DFS(深度优先搜索) 进行对比:

如何用 BFS 匹配我们的小游戏

在我写的小游戏(小游戏项目地址,小游戏代码结构详解)中,我们的小方块时刻面临三个选择:

  • 给自己一个左上的力;
  • 给自己一个右上的力;
  • 什么也不做,这一时刻任由自己受重力牵制而掉落。

因此,我们每层也就有三个结点,如下图:

但是因为算法本身的时间复杂度过大,我们可以不考虑“什么也不做”这一动作。这样,每层的父结点就只有两个子结点,大大减少需要遍历的空间。否则,需要搜索的结点过多,导致程序运行过慢或内存溢出。

使用队列的实现

我使用队列来实现 BFS 算法,我大概描述一下这个过程。数据结构不够硬的同学,应该静下心来读读我的源码、或者其他经典的 BFS 教程、或者刷刷 LeetCode 。

我的源码见:https://github.com/PiperLiu/Amazing-Brick-DFS-and-DRL/bfs_play.py

Node = namedtuple("Node", ['sta' , 'act', 'father'])game_state = GameState(True)
# 为了避免搜索空间过大
# 这里调高了游戏的力学参数
game_state.player.velMaxY = 20
game_state.player.AccY = 5ACTIONS = (0, 1, 2)def bfs_forward(root_state, show=False):# 保存结点的队列q = Queue()for action in ACTIONS:node = Node(root_state.copy(), action, None)q.put(node)while True:# 如果队列为空# 则说明所有可行结点已经遍历if q.empty():breakfather_node = q.get()father_state = father_node.staif check_for_score(father_state):# 如果得分# 说明可行路径已经找到# 跳出循环if show:pygame.draw.rect(SCREEN, (0, 0, 255), \(father_state['x'] - game_state.s_c.x, father_state['y'] - game_state.s_c.y, game_state.player.width, game_state.player.height))pygame.display.update()break# 只考虑动作 1 和 2for action in ACTIONS[1:]:# father_state = move_forward(father_state, ACTIONS[0])new_state = move_forward(father_state, action)if check_crash(new_state):if show:pygame.draw.rect(SCREEN, (255, 0, 0), \(new_state['x'] - game_state.s_c.x, new_state['y'] - game_state.s_c.y, game_state.player.width, game_state.player.height))pygame.display.update()else:if show:pygame.draw.rect(SCREEN, (100, 100, 100), \(new_state['x'] - game_state.s_c.x, new_state['y'] - game_state.s_c.y, game_state.player.width, game_state.player.height))pygame.display.update()node = Node(new_state, action, father_node)q.put(node)return father_node

我这里 BFS 算法效果不好:

python bfs_play.py

输入参数 --display 可以查看寻路过程:

python bfs_play.py --display

源码:https://github.com/PiperLiu/Amazing-Brick-DFS-and-DRL

欢迎 star 。

【广度优先搜索】一个实例+两张动图彻底理解 BFS | 思路+代码详解 | 用 DFS 自动控制我们的小游戏相关推荐

  1. 【深度优先搜索】一个实例+两张动图彻底理解 DFS | DFS 与 BFS 的区别 | 用 DFS 自动控制我们的小游戏

    前言: 在第一篇文章中(link),我们讨论了 如何用 pygame 写一个小游戏,并用键盘交互控制 .接下来,我们将分别用 DFS .BFS .DRL 实现自动控制.这篇文章讨论了什么是深度优先搜索 ...

  2. Qt开发技术:Q3D图表开发笔记(三):Q3DSurface三维曲面图介绍、Demo以及代码详解

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/130264470 各位读者,知识无穷而人力有穷,要么改需 ...

  3. [动图演示]Redis 持久化 RDB/AOF 详解与实践

    Redis 是一个开源( BSD 许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件.它支持的数据类型很丰富,如字符串.链表.集 合.以及散列等,并且还支持多种排序功能. 什么叫持 ...

  4. [动图演示]Redis 持久化 RDB/AOF 详解与实践 1

    Redis 是一个开源( BSD 许可)的,内存中的数据结构存储系统,它可以用作数据库.缓存和消息中间件.它支持的数据类型很丰富,如字符串.链表.集 合.以及散列等,并且还支持多种排序功能. 什么叫持 ...

  5. qchart折现图_Qt开发技术:QCharts(二)QCharts折线图介绍、Demo以及代码详解

    若该文为原创文章,未经允许不得转载 各位读者,知识无穷而人力有穷,要么改需求,要么找专业人士,要么自己研究 敬请期待- 红胖子,来也! 介绍了整体框架,开始动手码代码,按照顺序,从折线图开始. QCh ...

  6. 做折线图_python的visvis库做折线图(line.py)代码详解

    1 说明: ===== 1.1 visvis库:是Python视觉库,非常强大. 1.2 visvis库:今天讲折线图(line.py)的代码讲解. 1.3 安装: pip install visvi ...

  7. 彻底明白TCP的三次握手与四次挥手的两张动图

    常用的熟知端口号 应用程序 FTP TFTP TELNET SMTP DNS HTTP SSH MYSQL 熟知端口 21,20 69 23 25 53 80 22 3306 传输层协议 TCP UD ...

  8. 两张动图,彻底明白TCP的三次握手与四次挥手

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"书",获取 来源:22j.co/bVws 通过上一篇中 网络模型中的IP层 的介绍,我 ...

  9. 你们要的动图来了:2张动图快速理解高内聚与低耦合

    模块 模块就是从逻辑上将系统分解为更细微的部分, 分而治之, 复杂问题拆解为若干简单问题, 逐个解决. 耦合主要描述模块之间的关系, 内聚主要描述模块内部. 模块的粒度可大可小, 可以是函数, 类, ...

最新文章

  1. 使用Python,OpenCV检测摄像机到标记对象的距离
  2. 一文让你完全弄懂回归问题、激活函数、梯度下降和神经元模型实战《繁凡的深度学习笔记》第 2 章 回归问题与神经元模型(DL笔记整理系列)
  3. sfdisk命令的使用技巧
  4. php$后面加点有什么用,css和js后加问号和数字有什么用
  5. 求连通块个数(使用并查集)
  6. 大型DCI网络智能运营实践
  7. 全站仪和手机连接软件_全站仪各方面应用的原理、操作及计算,看这篇就对了...
  8. git学习笔记-(3-linux基本命令)
  9. Ring Buffer 原理
  10. tcp转发器使用说明
  11. 不知道如何录音转文字?分享两个实用方法
  12. MAC无法重装anaconda3
  13. C++ 安妮的宠物小屋 练习
  14. 数字信号与模拟信号的区别(转载)
  15. NVIDIA GTC 明日如约举行,持续 15 天,三万人已报名
  16. 我的择偶标准(丫咧,看清楚了啊)
  17. 人脸识别实名认证在景区门禁系统中的应用
  18. 秒杀系统(SecKillGoods)
  19. 笔记本题目 复习(一)
  20. 网络蚂蚁与FlashGet的文件多线程下载原理

热门文章

  1. 计算机专业教学实施,中职计算机专业教学项目的设计与实施
  2. 怎样解决jsp:include标签在包括html文件时遇到的乱码问题
  3. 异常处理--“System.BadImageFormatException”类型的未经处理的异常在 DataTest.exe 中发生
  4. selenium 无法启动IE浏览器的解决方法
  5. app内嵌h5页面在ios手机端滑动卡顿的解决方法
  6. 报告一个IE很奇葩的滚动条问题——百分比计算宽度为浮点数时的滚动条显示异常
  7. EF异常:“System.InvalidOperationException”类型的未经处理的异常在 mscorlib.dll 中发生
  8. tomcat报错:This is very likely to create a memory leak问题解决
  9. IDEA出现Module ** must not contain source root **. The root already belongs to module **这类错误的解决方法
  10. 如何在隐藏视图时使用自动布局移动其他视图?