再探 游戏 《 2048 》 —— AI方法—— 缘起、缘灭(1) —— Firefox浏览器下自动运行游戏篇
四年前曾经写过一过博客:
对 游戏 《 2048 》 的一些思考
虽然过去几年了,但是这个游戏一直没有搞懂该怎么使用AI算法来进行求解,这里再次对这个问题进行一些探索。
========================================
首先说明下,这个《2048》游戏确实很火,自己当年也是好一通研究,最后还是无疾而终,最近无意间又想起这个东西来了,正好这几年也是在从事AI方面的事情,想想自己这么长时间的一些积累或许可以再次尝试这个游戏的AI解决了。
这个《2048》游戏的AI解决难易适中,不想围棋那种需要Alpha go这种庞大的算法和计算平台要求,但是又不能依靠简单的遍历搜索来训练较好的解决方案,在一定level上来说这个游戏的难易度很适合个人AI玩家来尝试和练手的。
AI算法并不同于机器学习算法,应该说AI算法是包括机器学习算法的,或者说机器学习算法是AI算法的一个子集。只要可以替代人类脑力或体力去自动化解决问题的算法我们都可以认为是AI算法,也就是说AI算法就是可以模仿人类功能的计算机算法,而机器学习算法是指通过数据不断训练来使算法学习到适合的模型参数或模型结构的方法,机器学习主要体现在两个点:一个是原来训练和学习的数据;一个是可以根据数据来进行训练的学习,学习模型参数或模型结构。
外网对于《2048》游戏的AI解法早有讨论,比较有代表性的为:
What is the optimal algorithm for the game 2048?
其中,投票率最高的解决方法是启发式AI算法:
该启发式AI方法的github代码地址:
https://github.com/nneonneo/2048-ai
该代码clone在国内gitee代码库上:
https://gitee.com/devilmaycry812839668/highest_vote_2048_ai
=========================================================
我们这里主要是针对投票率最高的对应的启发式算法 鬼&泣 / 2048-ai 进行分析。
启发式算法,某种程度上我们可以将其理解为基于预设规则的算法。人类解决某件事情所采用的方法可以理解为人类的策略或规则,但是人类针对某件事情所采用的策略或规则很难翻译成计算机语言,那么如何把人类的策略翻译成计算机可以识别并执行的策略呢?根据计算机可以识别并执行的策略或规则所设计的算法我们一般叫做启发式算法。
在《2048》游戏中人类在打游戏时所采用的策略一般有:
参考:https://soft.zol.com.cn/jingyan/59663.html
高分法则:
最大数尽可能放在角落。
数字按顺序紧邻排列。
首先满足最大数和次大数在的那一列/行是满的。
时刻注意活动较大数(32以上)旁边要有相近的数。
以大数所在的一行为主要移动方向
不要急于“清理桌面”。
需要注意的是,为了保持最大数在角落,所有最大数可能移动的方向都不能再操作了,比如选择了左上角,那么就不能向右和向下移动其他的方块,这样操作的灵活性会相对减少,难度就会增加。这时,建议玩家除了选定一个角以外,再固定一条边,将大的数字放这条边上,这样就可以朝三个方向移动,比如选定左上角,填满最大数右边的所有方块,就可以朝上,左,右三个方向移动了。
经过分析可以知道在《2048》游戏中我们人类在操作时所遵循的规则一般有:保证最大的数字和第二大的数字在角落上不动,这边我们需要保证最大数字的一边被其他数字填满,这样的话保证最大数字不动的前提下可以有三个方向可以被用来操作。
根据 https://stackoverflow.com/questions/22342854/what-is-the-optimal-algorithm-for-the-game-2048 中最高投票率的回帖,我们需要遵守的规则还可以有:保证最大可能性有空格出现,最大可能性有一行或一列中有相同数字挨着的出现(可以在下一步中被合并),尽量保证每行或每列都是保证单调增或减的数字排列等。
可以看到人类的策略虽然人类用来理解还是可以的,但是如何翻译成计算机可以理解的语言呢,从而根据计算机可以理解的语言或规则编写出启发式算法呢。在 鬼&泣 / 2048-ai 中则把不同情况的游戏画面(数字排序顺序)根据刚才人类的评价和遵循规则给出评分,并根据某步操作后获得的后续操作得到的画面加权值最高(最高得分)来给出下一步的操作,该种方式所设计的启发式算法被证明可以有效的解决《2048》游戏。
============================================
下面给出在 鬼&泣 / 2048-ai 中对在Firefox浏览器下自动运行游戏《2048》。
具体见: https://gitee.com/devilmaycry812839668/highest_vote_2048_ai/tree/devilmaycry
在Firefox浏览器中自动运行游戏,其原理就是利用浏览器调试模式下可以自动运行传入的js脚本,从而实现在浏览器中调试js程序的目的。由于《2048》游戏一般均为js语言编写的,我们打开游戏的原始页面则会自动在浏览器中加载《2048》游戏的js代码,然后我们在Firefox浏览器开启调试模式情况下为该页面注入自己编写的js代码来实现获得《2048》游戏的状态信息和得分情况,同时我们还可以通过注入JS代码的方式模拟键盘操作来实现自动操控《2048》页面游戏的目的。
使用Firefox浏览器进行调试需要设置浏览器:
浏览地址框中输入 about:config
设置选项:
- devtools.debugger.prompt-connection 为 false
- devtools.debugger.remote-enabled 为 true
- devtools.chrome.enabled 为 true
============================================
设置好Firefox后需要关闭浏览器。
再次打开Firefox需要采用运行命令行的方式启动Firefox:
firefox --start-debugger-server 32000
使用Firefox浏览器运行一次:
brower_autorun/2048_demo.py -b firefox
使用Firefox浏览器运行100次: (把100次的运行结果保存在调用命令执行的当前目录下的result.log)
brower_autorun/2048_100times_evalue.py -b firefox
执行上面命令结果将被保存在highest_vote_2048_ai文件夹下面result.log文件中:
result.log 中保存的结果格式为:score, maxval, elapse_time, moveno
含义为:
得分,最大数,总运行时长(秒),总执行步数
=============================================
在 2048_100times_evalue.py 中:
如果返回的游戏状态字段为"ended",那么则意味则游戏是结束状态。
游戏表现形式为:
如果游戏状态为“ended”后需要调用 gamectrl.restart_game() 方法来获取新一局的游戏。
对于游戏状态为 “win” 时需要调用 gamectrl.continue_game() 方法,该方法的使用意义并不是很了解,因为是follow其他人的工作,所以也就这样承接下来这个操作了。
获取当前游戏的得分值:
获取当前游戏的状态值:
获得的board为16个元素的列表,每个元素取值范围为0~15,形式如:
[
[3,0,1,2],
[4,5,6,7],
[8,9,10,11],
[12,13,14,15],
]
如果进行状态打印的话我们需要把每个元素x 进行2**x 操作。
如果进行算法可以识别的形式,需要如下操作:
=============================================
在《2048》游戏中, 行为2 2 2 2,右移得 0 0 4 4, 再次右移得 0 0 0 8 。
=============================================
在maser分支中,编译代码( ubuntu系统中 ):
./configure make
posted on 2021-12-17 09:35 Angry_Panda 阅读(1277) 评论(0) 编辑 收藏 举报