再探 游戏 《 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
再探 游戏 《 2048 》 —— AI方法—— 缘起、缘灭(1) —— Firefox浏览器下自动运行游戏篇的更多相关文章
- 跟k8s工作负载Deployments的缘起缘灭
跟k8s工作负载Deployments的缘起缘灭 考点之简单介绍一下什么是Deployments吧? 考点之怎么查看 Deployment 上线状态? 考点之集群中能不能设置多个Deployments ...
- 再探JS数组原生方法—没想到你是这样的数组
最近作死又去做了一遍javascript-puzzlers上的44道变态题,这些题号称"JS语言专业八级"的水准,建议可以去试试,这里我不去解析这44道题了, ...
- Android 带你玩转实现游戏2048 其实2048只是个普通的控件(转)
1.概述 博主本想踏入游戏开放行业,无奈水太深,不会游泳:于是乎,只能继续开发应用,但是原生Android也能开发游戏么,2048.像素鸟.别踩什么来着:今天给大家带来一篇2048的开发篇,别怕不分上 ...
- Android 带你玩转实现游戏2048 其实2048只是个普通的控件
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40020137,本文出自:[张鸿洋的博客] 1.概述 博主本想踏入游戏开放行业,无 ...
- 【再探backbone 02】集合-Collection
前言 昨天我们一起学习了backbone的model,我个人对backbone的熟悉程度提高了,但是也发现一个严重的问题!!! 我平时压根没有用到model这块的东西,事实上我只用到了view,所以昨 ...
- 再探jQuery
再探jQuery 前言:在使用jQuery的时候发现一些知识点记得并不牢固,因此希望通过总结知识点加深对jQuery的应用,也希望和各位博友共同分享. jQuery是一个JavaScript库,它极大 ...
- H5版俄罗斯方块(3)---游戏的AI算法
前言: 算是"long long ago"的事了, 某著名互联网公司在我校举行了一次"lengend code"的比赛, 其中有一题就是"智能俄罗斯方 ...
- [老老实实学WCF] 第五篇 再探通信--ClientBase
老老实实学WCF 第五篇 再探通信--ClientBase 在上一篇中,我们抛开了服务引用和元数据交换,在客户端中手动添加了元数据代码,并利用通道工厂ChannelFactory<>类创 ...
- Spark Streaming揭秘 Day7 再探Job Scheduler
Spark Streaming揭秘 Day7 再探Job Scheduler 今天,我们对Job Scheduler再进一步深入一下,对一些更加细节的源码进行分析. Job Scheduler启动 在 ...
- Andorid游戏2048开发(一)
最近有一款Android平台下的游戏很是火爆----2048.下面记录一下开发过程.由于笔者是Android开发的初学者,所以希望借以此文熟悉整个Android开发的流程. 首先创建Game2048的 ...
随机推荐
- VictoriaLogs 要凭什么革了各家日志存储的命
如果大家对时序指标的存储方案有些了解,那大概率会听过 VictoriaMetrics,VictoriaMetrics 号称 Prometheus 的升级版,在性能和成本方面也确实做得很好,如果是夜莺新 ...
- 大模型高效微调-LoRA原理详解和训练过程深入分析
博客首发于我的知乎,详见:https://zhuanlan.zhihu.com/p/702629428 一.LoRA原理 LoRA(Low-Rank Adaptation of LLMs),即LLMs ...
- 这个vue3的后台管理系统虽然简洁但不简单
今天介绍一个新的Vue后台管理框架,相比其他后台功能丰富管理系统,这个后台管理系统可以用干净简洁来形容--Nova-admin Nova-admin Nova-admin 是一个基于Vue3.Vite ...
- IDEA生成类和方法注释模板详细说明 绝对好用
吐槽 今天心血来潮,将使用了很久的IDEA旗舰版卸载了,想换社区版用一段时间,毕竟社区版开源免费.精简不卡顿,如果够用的话以后就省去了破解的烦恼,而且可以紧跟官网使用最新版 旧的IDEA配置忘记保存了 ...
- R 语言入门学习笔记:软件安装踩坑记录——删除所有包以及彻底解决库包被安装到 C 盘用户目录下的问题,以及一些其他需要注意的点
目录 R 语言入门学习笔记:软件安装踩坑记录--删除所有包以及彻底解决库包被安装到 C 盘用户目录下的问题,以及一些其他需要注意的点 软件版本及环境 遇到的问题描述 问题的分析和探究 最终的解决方案 ...
- FEDORA 显卡驱动安装
FEDORA 显卡驱动安装 在fedora中akmod-nvidia包可以自动的处理开源驱动屏蔽等各种问题, 强烈推荐用这个安显卡驱动. -1. 在 BIOS 中关闭安全启动 0. 切换桌面环境至 X ...
- Java常见的加密方式
前言 传说在古罗马时代,发生了一次大战.正当敌方部队向罗马城推进时,古罗马皇帝凯撒向前线司令官发出了一封密信:VWRS WUDIILF.这封密信被敌方情报人员翻遍英文字典,也查不出这两个词的意思. 此 ...
- yb课堂之跨域配置 《二十三》
CorsInterceptor.java package net.ybclass.online_ybclass.interceptor; import org.springframework.http ...
- Mybatis 二级缓存的使用
Mybatis二级缓存 简介:二级缓存是namesace级别的,多个SqlSession去操作同个namespace下的Mapper的sql语句,多个SqlSession可以共用二级缓存,如果两个ma ...
- JDK9之后 Eureka依赖
<!--Eureka添加依赖开始--> <dependency> <groupId>javax.xml.bind</groupId> <artif ...