Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【参赛经验分享】一个全程DFS的解题总结(内部赛道)

【参赛经验分享】一个全程DFS的解题总结(内部赛道)

原创
作者头像
CarsonZ
发布于 2021-08-19 15:15:32
发布于 2021-08-19 15:15:32
7381
举报

TL;DR: 主要思路是基于“残局”(地基)的启发式dfs。第一版用python实现(GUI+solver)大概是70W+,后面把solver部分移植到了rust上,结合一些性能优化和各种限制条件后达到100W+,再优化感觉就比较难提升了。最后分数是1060356,内部赛道第8名。

初探

第一件事是确定方块序列怎么生成的,看了下js有很友好的给出源文件地址,随机数生成核心: return (v * a + C) % M;`,种子也是固定的,就放弃了RL的想法。

然后用pygame根据js的逻辑先写了一个简陋的本地客户端辅助调试,功能上能让方块不主动下降,可以向上,可以悔棋(但此时悔棋是通过重放序列到倒数第二个N实现的),打印调试信息等,同时根据玩的过程可以生成序列。

这时手动大概玩了500多个方块,3.8W分左右,按比例算的话全完成也就70多W。(膜拜一下前面TAS方法的大佬)

于是就决定还是要实现求解器。以前给Shenzhen IO的纸牌小游戏solitaire和Opus Magnum的minigame sigmar's garden实现bot时使用的都是基于启发式的DFS方法,就按照相同的思路实现了。核心思路其实就是通过评估函数给行动排序,“引导”、“启发”程序进行搜索。几个实现的细节:

  • 这时已经发现可以直接通过"N"让方块悬空,但生成possible moves考虑到空间太大,就先只考虑"落地"的情况。生成方法是先对每种形状(0~3的形状state,重复的不考虑)列出地上的目标位置,通过bfs寻路看能不能通过操作达成,得到实际可到达的moves
  • 给possible moves排序(heuristic score),也就是所说的“评估函数”,优先搜索“更好”的move。初始时以高度和作为评判标准。
  • 从零开始进展缓慢,于是改用“残局”模式,手动玩了30~40块左右,再让求解器在这个基础上继续执行。这样不好的move很快就会因为游戏结束而回退
UI示例
UI示例

图上两个红色的数字上面是brick_count(方块序号),下面是分数。提交时由另一个脚本对序列文件生成相应的js代码,复制到浏览器console中提交。

这种方式很容易就能玩到10000块不死,大概70W左右

优化

花了2晚把求解器移植到了rust(期间有个形状的坐标复制错了,还调了近一晚bug),再结合一些其它的优化:

  • 之前dfs探索时使用的是复制整个游戏状态的方式,改为了in-placed的方式,并改回退的实现方式从“重放序列”为真正的”回退“(直接恢复上一方块状态),显著减小了大量的allocation消耗
  • 优化前,见过的状态用类型HashMap<u32, HashSet<String>>保存(String是游戏当前“棋盘”的一种编码形式),key为当前的brick_count,这样内存过大时可以释放掉一些brick_count较小的entry。运行时发现内存占用过大,意识到由于只用判断存在与否,改成了HashMap<u32, HashSet<u64>>的类型,显著降低了内存需求(计算hash使用了fxhash)
  • 用hashbrown的HashSet方法替换了std的HashSet以节省一些内存
  • 修改heuristic score评估函数返回Option,也就是其它语言的OptionalMaybe类型。这样可以在评估函数里通过返回None告诉上层直接放弃掉不想要的状态

此外还手动玩了几个比较好的”残局“,使低层每行只有一个空洞。同时一直在调整heuristic score的策略。尝试过使用PD算法,但看上去没有什么效果,又加上了一些其它的策略:

  • 把只消一行的方案直接放弃(最后的序列基本上是消2行,少数3行和4行,提升较大)
  • 把只消二行的方案概率性放弃(少许提升)
限制消除的行数不要太少
限制消除的行数不要太少
  • 有消除时判断现有方块总数,少于164的放弃(168的试了几轮,很快会失败)
  • 少于168的概率性放弃
限制剩余的方块不要太少
限制剩余的方块不要太少

这时大概103W

最后的小优化

因为序列固定,生成了一些间隔比较大的"I"和"J"的序号列表(HashSet),在评估函数中判断如果在这些方块时没有达到3消或4消,就概率性放弃。这个改动显著增加了运行时间(体感跑完大概要1天),但最终只提升了3W+左右,到达106W+

总结

  • 和前几名的差距还是很大的,要有显著提升可能还是得换搜索效率更高的一些方法(结合更好的剪枝方案)
  • 当前评估函数对全局的的分数计算还是基于高度、空洞等的加权和(差),感觉引入其它思路还有优化空间
  • 感谢组委会的这次比赛,学习到很多也见识到很多,过程也十分有趣。期待下一次的比赛。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
1 条评论
热度
最新
感谢选手带来的参赛经验分享!云加社区欢迎有技术比赛获奖经历的竞赛爱好者,入驻赛事俱乐部,首批成员可直接领取「限量礼包」。复制链接在浏览器查看「活动详情」:https://cloud.tencent.com/developer/article/1860760
感谢选手带来的参赛经验分享!云加社区欢迎有技术比赛获奖经历的竞赛爱好者,入驻赛事俱乐部,首批成员可直接领取「限量礼包」。复制链接在浏览器查看「活动详情」:https://cloud.tencent.com/developer/article/1860760
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
【参赛经验分享】【极客-腾讯内部赛道】一个菜鸡的解题思路
tetris是参加【极客技术挑战赛第四期】鹅罗斯方块 的项目,这个项目是给定一个俄罗斯方块的固定序列,看看谁能消除的分数最高。
esrrhs
2021/08/16
1K1
【参赛经验分享】【极客-腾讯内部赛道】一个菜鸡的解题思路
【参赛经验分享】鹅罗斯方块解题报告: 遗传算法+分段策略
月初看到TEG公众号推送的极客挑战赛, 主题居然是完成俄罗斯方块的游戏, 顿时来了精神. 想起当初编写各种QQ游戏大厅外挂的快乐时光, 已经快十年了吧.
UME
2021/08/14
2.3K1
【参赛经验分享】鹅罗斯方块解题报告: 遗传算法+分段策略
【参赛经验分享】外部赛道Rank 2解题报告:状态取舍下的动态规划
在七月末,出于偶然了解到腾讯极客挑战赛这个充满趣味性和挑战性的竞赛,于是便报名参加。这次第四期的赛题叫做“鹅罗斯方块”,要求参赛者用所能尽到的各种方式,在一个JS开发的俄罗斯方块游戏中取得尽可能高的分数。经过一周多的持续思考与努力优化,最终通过动态规划+状态取舍,拿到1378178分,获得外部赛道银奖,也算是如愿以偿。下面是我的比赛经过:
Max.D.
2021/08/17
1.1K1
Go程序GC优化经验分享
最近一段时间对《仙侠道》的服务端进行了一系列针对GC的调优,这里跟各位分享一下调优的经验。
李海彬
2018/07/26
6K0
Go程序GC优化经验分享
首篇极客解题报告意外泄出!亚军竟有神操作?
导语 | 腾讯云+社区联合腾讯码客、腾讯安全平台部全新打造的创新赛事【腾讯极客挑战赛 | 鹅罗斯方块】正式落幕。玩鹅罗斯方块,玩点不一样!在短暂10天内,4570名参赛者或以自己的硬核技术诠释着 “代码无所不能”;或坚持游戏主义,手玩出一片天。 最终11263次有效提交中,涌现出一批出众的作品。快跟上团队!一睹大牛精心贡献的解题报告。 本期为大家带来亚军大佬——北航研究生陈铭煊的报告。看完他的解题过程,小编直呼“我的强迫症治好了!”(请看下方视频) 大佬这样说 在七月末,出于偶然了解到腾讯极客挑战赛这
腾讯云开发者
2021/08/23
3080
【参赛经验分享】腾讯内部赛道139万分解题报告
我参加的是腾讯内部赛道,最后得分 1395326,在内部赛道排名第一。将内网的解题报告搬运一份到云+社区:
chys
2021/08/16
9551
【参赛经验分享】论 1,413,876 分的成绩是怎么打出来的
七月末的时候看到了腾讯极客挑战赛第四期,发现这不是俄罗斯方块嘛,是之前 Botzone 玩过的 AI 游戏,于是决定来玩玩。没想到一玩玩了好几天,最后的程序也和之前在 Botzone 写的 AI 完全不一样了,最后以 1413876 的分数拿到了外网赛道的第一,同时该分数也是内外网赛道的最高分。
Nano
2021/08/12
1.9K4
【参赛经验分享】论 1,413,876 分的成绩是怎么打出来的
【参赛经验分享】俄罗斯方块的Rust解题记录(腾讯内部赛道第7名)
最近一直在学习 Rust。想起以前每次学习新语言,都会实现一个俄罗斯方块来验证对语言的掌握,但是从来没有尝试去实现其AI。正好这次碰到这个挑战,所以没有多想就使用 Rust 来做此题了。
INmouse
2021/08/20
1.1K1
【参赛经验分享】俄罗斯方块的Rust解题记录(腾讯内部赛道第7名)
【参赛经验分享】腾讯极客挑战赛第四期俄罗斯方块比赛复盘
七月底的时候在网络上看到了这样一个赛事,赛题大概总结起来就是用代码玩一款十分经典的游戏俄罗斯方块,通过游戏得分来排名评比,觉得挺有意思,抱着随便试试的想法就参加了,结果最后获得了全国第49名,最终获得的最高分数是31万多一点,虽然和第一名的一百多万还是有不小的差距,需要改进反省的地方还有很多,但这一成绩还是基本达到了我的预期的,同时我也是成功获得了腾讯招聘的绿色通道,丰富了自己的履历。
HellloWrold-Ian
2021/08/16
1.6K1
【参赛经验分享】鹅罗斯方块内部赛道Rank5——硬搜
前言 首先简要概括一下题目,是一个序列完全固定为10000个的俄罗斯方块游戏,需要给出一个操作序列来最大化得分,得分的多少与单次消除的行数和场上已有方块数有关。 主要使用到的算法有: 贪心 单步dfs搜索 蒙特卡罗搜索 除了搜索我还能会点啥嘛,就硬搜 先上代码仓库:https://github.com/Suikasxt/tetris 内容主要在以下两个文件中: GameController.cpp:游戏主体逻辑 tetris.cpp:策略算法 因为代码本来也不是奔着分享写出来的,就不要指望有多好看。 贪心
用户5556120
2021/08/20
7921
【参赛经验分享】外部赛道rank3,手打+AI的同时尝试解题
AI与手打同时尝试打分,最后提交的最高成绩是手打成绩,主要思路是尽可能堆高后进行消4,依据序列的情况妥协进行消3.2,通过本地实现一个模拟器提供各种信息来辅助整个流程。AI算法思路与内部赛道的139w分大佬类似,手打最终117.9w分
whoisdiao
2021/08/20
1.1K2
【参赛经验分享】中年男人写的俄罗斯方块AI外挂,47W分只为爱妻拿一个腾讯视频会员卡
在盆友圈里收到消息,鹅厂举办了一场俄罗斯方块的刷分比赛,私聊一下发图的同学拿到了体验连接,好像还挺简单的嘛,遂决定抽空参赛。
熬夜拧魔方
2021/08/22
2.3K4
【参赛经验分享】中年男人写的俄罗斯方块AI外挂,47W分只为爱妻拿一个腾讯视频会员卡
【参赛经验分享】[腾讯内部赛道破解大师]俄罗斯方块难?直接破解最简单!
前言:后面有事没时间打比赛怎么办?那当然是把游戏破解了啊。安全人,安全魂,安全人偏不走寻常路~
FDrag0n
2021/08/20
2.8K0
【腾讯内部赛道-极客挑战赛第四期季军】GPU动态规划鹅罗斯方块
鹅罗斯方块挑战是由10000个方块序列构成的鹅罗斯方块游戏,其中包含了大量的s型和z型,以及少数的I型方块。
用户8813955
2021/08/20
8110
【参赛经验分享】含可以手玩的网页版(带AI)
简单看了一下游戏源代码,可以发现:(1)游戏里面共有10000块;(2)游戏里面每一块都是确定的,和操作无关。
用户8875579
2021/08/22
1.1K1
【参赛经验分享】[腾讯内部赛道Rank6]鹅罗斯方块半手打(TAS)心得
参与这个比赛的时候,最初的想法也是想依靠算法去实现的,毕竟手打得无论多好,最优解肯定得依靠算法实现,但是由于种种原因(比如大学被ACM折磨过一段时间之类的...)不想写算法,就以最单纯的玩家心态去解决这个问题了。
ZeroNinEX
2021/08/20
9943
【参赛经验分享】[腾讯内部赛道Rank6]鹅罗斯方块半手打(TAS)心得
【参赛经验分享】腾讯内部赛道-鹅罗斯方块赛事笔记
我在过去,写过不少游戏AI,所以当看到公司有这样一个比赛很是高兴。不巧比赛的两周刚好项目组特别忙,但我仍希望能在有限的时间来做得更好。
Agent
2021/08/20
1K1
【参赛经验分享】腾讯内部赛道-鹅罗斯方块赛事笔记
【参赛经验分享】无需关心算法的渐进式解题思路
这是一篇 腾讯极客挑战赛第四期:鹅罗斯方块 的参赛经验分享。这个参赛的主要内容大致是玩俄罗斯方块,最后比较得分。和正常俄罗斯方块不太一样的是这个比赛随机种子被固定了,方块落下的顺序是固定的(方块数量也固定了 10000 的上限),而且得分和你消行时场地上存在的方块数量有关。
白水
2021/08/16
1.4K1
【参赛经验分享】无需关心算法的渐进式解题思路
【参赛经验分享】分析js代码开启游玩新世界与Pierre Dellacherie算法本地验证
以下仅是我对于这个比赛的思考过程,可能是拿高分的技巧,但我并没有因此拿高分,本人算法水平有限大佬勿喷,对文章中的问题欢迎指出。
一颗小树
2021/08/13
2.8K2
【参赛经验分享】分析js代码开启游玩新世界与Pierre Dellacherie算法本地验证
Python 人工智能:6~10
在本章中,我们将学习集成学习以及如何将其用于预测分析。 在本章的最后,您将对这些主题有更好的理解:
ApacheCN_飞龙
2023/04/23
1.5K0
推荐阅读
【参赛经验分享】【极客-腾讯内部赛道】一个菜鸡的解题思路
1K1
【参赛经验分享】鹅罗斯方块解题报告: 遗传算法+分段策略
2.3K1
【参赛经验分享】外部赛道Rank 2解题报告:状态取舍下的动态规划
1.1K1
Go程序GC优化经验分享
6K0
首篇极客解题报告意外泄出!亚军竟有神操作?
3080
【参赛经验分享】腾讯内部赛道139万分解题报告
9551
【参赛经验分享】论 1,413,876 分的成绩是怎么打出来的
1.9K4
【参赛经验分享】俄罗斯方块的Rust解题记录(腾讯内部赛道第7名)
1.1K1
【参赛经验分享】腾讯极客挑战赛第四期俄罗斯方块比赛复盘
1.6K1
【参赛经验分享】鹅罗斯方块内部赛道Rank5——硬搜
7921
【参赛经验分享】外部赛道rank3,手打+AI的同时尝试解题
1.1K2
【参赛经验分享】中年男人写的俄罗斯方块AI外挂,47W分只为爱妻拿一个腾讯视频会员卡
2.3K4
【参赛经验分享】[腾讯内部赛道破解大师]俄罗斯方块难?直接破解最简单!
2.8K0
【腾讯内部赛道-极客挑战赛第四期季军】GPU动态规划鹅罗斯方块
8110
【参赛经验分享】含可以手玩的网页版(带AI)
1.1K1
【参赛经验分享】[腾讯内部赛道Rank6]鹅罗斯方块半手打(TAS)心得
9943
【参赛经验分享】腾讯内部赛道-鹅罗斯方块赛事笔记
1K1
【参赛经验分享】无需关心算法的渐进式解题思路
1.4K1
【参赛经验分享】分析js代码开启游玩新世界与Pierre Dellacherie算法本地验证
2.8K2
Python 人工智能:6~10
1.5K0
相关推荐
【参赛经验分享】【极客-腾讯内部赛道】一个菜鸡的解题思路
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档