《2048》游戏在线试玩地址:

https://play2048.co/

如何解决《2048》游戏源于外网的一个讨论帖子,而这个帖子则是讨论如何解决该游戏的最早开始,可谓是“缘起”:

What is the optimal algorithm for the game 2048?

关于该游戏的相关内容前面已经写过一些内容:

再探 游戏 《 2048 》 —— AI方法—— 缘起、缘灭(1) —— Firefox浏览器下自动运行游戏篇

========================================

自己为游戏《2048》编写了python版本的运行环境,没多久就又发现网上有其他网友也写了Python版本的《2048》游戏环境,也是出于好奇,想着看看到底是自己写的版本性能更好还是网友写的更好,于是做了一下对比,结果虽然要自己汗颜但还是有所收获的。

网友的实现版本:

https://github.com/moporgic/2048-Demo-Python

=================================================

我所实现的版本:

https://gitee.com/devilmaycry812839668/td-tuple-net-for-2048/tree/master/environ

其中,env_5bits_2048.py为单环境运行版本,env_vec.py为多环境矢量运行版本。

自己实现的这两个环境代码性能比网友的2048-Demo-Python要差上不止几倍速度。

为了更好的进行对比,又新开了一个代码库:

https://gitee.com/devilmaycry812839668/2048-Demo-Python

下面的讨论所用到的算法代码均在该代码库中。

=================================================

在项目https://gitee.com/devilmaycry812839668/2048-Demo-Python中共有4个《2048》游戏环境的实现,分别为文件:

py2048.py

py2048_1.py

py2048_2.py

env_5bits_2048.py

除此之外,还有调用这四个实现进行测试的主文件为main.py。

说明一下,虽然自己也编写过多环境矢量运行的代码env_vec.py,但是在实际运行过程中发现该代码运行效率十分低,远远低于其他版本的实现,因此这里就没有在项目库中将其加入。

py2048.py代码为moporgic编写的原始环境,通过下面的运行测试可以知道其性能是最好的。该版本实现用python的list类型来表示棋盘状态,同时对每一次的移动和所获奖励都是事实计算的,并没有采用缓存的机制。

py2048_1.py代码为移动缓存表方法,其在py2048.py的基础上将所有可能存在的行的移动后状态和所获奖励使用缓存表保存了下来,每一次对棋盘进行移动时部队下次棋盘状态和奖励进行计算而是直接从内存中的缓存表中取出对应行移动后的行和奖励值。与py2048.py最大的不同就是该实现将棋盘变化后的行状态通过预计算的方法保存到了缓存表中,通过对缓存表中数据的读取减少了计算量。但是非常不幸的是通过下面的测试我们知道该种实现并不能提升性能,甚至该版本远不如py2048.py版本。

py2048_2.py代码为移动缓存表改进后的方法py2048_1.py对移动后的每行计算奖励后对其加和并减去惩罚值才可以得到真正的得分数,在py2048_1.py中每行在一次移动后需要两次循环遍历棋盘状态的各个行,以来读取缓存中移动后的行状态而奖励值,而在py2048_2.py中对移动后行状态及奖励的读取只需要在一次移动后遍历一次棋盘状态的各行即可,减少了对内存的读取。

env_5bits_2048.py 代码为个人设计的缓存表方法,该方法和py2048_1.py类似,都是在每次移动后对棋盘各行进行两次遍历,但与py2048_1.py最大的不同就是这里没有使用list类型来表示棋盘状态而是使用numpy.array,而这个方法也是性能最差的。
 
 
对于测试结果个人给出的解释(特指python语言中):
1. 对于计算量较小的操作,使用预计算的方式缓存起来并不划算,因为对内存读取是要耗费较大时间的,而这个时间有可能已经大于了CPU重新计算这个结果所需的时间;
2. 循环操作是比较耗时的,尤其是频繁的循环操作,如果能降低循环操作的次数(使用for遍历的次数)可以一定程度上减少运算时长;
3. 在数据量较小的情况下,对list类型数据进行按索引读取和相等比较操作的性能要远远优于numpy.array类型。
 
 

----------------------------------------------------

测试平台:

Ubuntu22.04系统,i7-10700k CPU 工作频率为5.0Ghz

性能测试:

moporgic原始环境万次游戏的平均用时: 73.3795, 总步数:26108430

移动缓存表方法万次游戏的平均用时: 132.7472, 总步数:26115191
移动缓存表改进后方法万次游戏的平均用时:115.6608, 总步数:26129569
个人设计的缓存表方法万次游戏的平均用时:342.4837, 总步数:25777707

-----------------------------------------------------------------------

再探 游戏 《 2048 》 —— AI方法—— 缘起、缘灭(6) —— Python版本实现的《2048》游戏环境运行性能对比的更多相关文章

  1. 跟k8s工作负载Deployments的缘起缘灭

    跟k8s工作负载Deployments的缘起缘灭 考点之简单介绍一下什么是Deployments吧? 考点之怎么查看 Deployment 上线状态? 考点之集群中能不能设置多个Deployments ...

  2. 再探JS数组原生方法—没想到你是这样的数组

    最近作死又去做了一遍javascript-puzzlers上的44道变态题,这些题号称"JS语言专业八级"的水准,建议可以去试试,这里我不去解析这44道题了, ...

  3. 【再探backbone 02】集合-Collection

    前言 昨天我们一起学习了backbone的model,我个人对backbone的熟悉程度提高了,但是也发现一个严重的问题!!! 我平时压根没有用到model这块的东西,事实上我只用到了view,所以昨 ...

  4. 再探jQuery

    再探jQuery 前言:在使用jQuery的时候发现一些知识点记得并不牢固,因此希望通过总结知识点加深对jQuery的应用,也希望和各位博友共同分享. jQuery是一个JavaScript库,它极大 ...

  5. [老老实实学WCF] 第五篇 再探通信--ClientBase

    老老实实学WCF 第五篇 再探通信--ClientBase 在上一篇中,我们抛开了服务引用和元数据交换,在客户端中手动添加了元数据代码,并利用通道工厂ChannelFactory<>类创 ...

  6. Spark Streaming揭秘 Day7 再探Job Scheduler

    Spark Streaming揭秘 Day7 再探Job Scheduler 今天,我们对Job Scheduler再进一步深入一下,对一些更加细节的源码进行分析. Job Scheduler启动 在 ...

  7. 第四节:SignalR灵魂所在Hub模型及再探聊天室样例

    一. 整体介绍 本节:开始介绍SignalR另外一种通讯模型Hub(中心模型,或者叫集线器模型),它是一种RPC模式,允许客户端和服务器端各自自定义方法并且相互调用,对开发者来说相当友好. 该节包括的 ...

  8. 深入出不来nodejs源码-内置模块引入再探

    我发现每次细看源码都能发现我之前写的一些东西是错误的,去改掉吧,又很不协调,不改吧,看着又脑阔疼…… 所以,这一节再探,是对之前一些说法的纠正,另外再缝缝补补一些新的内容. 错误在哪呢?在之前的初探中 ...

  9. 再探Redux Middleware

    前言 在初步了解Redux中间件演变过程之后,继续研究Redux如何将中间件结合.上次将中间件与redux硬结合在一起确实有些难看,现在就一起看看Redux如何加持中间件. 中间件执行过程 希望借助图 ...

  10. c++再探string之eager-copy、COW和SSO方案

    在牛客网上看到一题字符串拷贝相关的题目,深入挖掘了下才发现原来C++中string的实现还是有好几种优化方法的. 原始题目是这样的: 关于代码输出正确的结果是()(Linux g++ 环境下编译运行) ...

随机推荐

  1. golang reflect 反射机制的使用场景

    Go语言中的 reflect 包提供了运行时反射机制,允许程序在运行时检查和操作任意对象的数据类型和值. 以下是 reflect 包的一些典型使用场景: 1. 动态类型判断与转换:当需要处理多种类型的 ...

  2. idea导入maven项目发现有jar或插件无法下载检查idea中的maven配置,maven配置文件中需配置阿里云的镜像地址

    D:\apache-maven-3.2.3\conf\settings.xml <mirrors> <mirror> <id>nexus-public-snapsh ...

  3. 仓颉语言HelloWorld内测【仅需三步】

    2024年6月21日,华为仓颉正式公开发布.还记的19年和王学智的团队做过接触,他们反馈说16年我出版的<自己动手构造编译系统>一书对他们的研发很有帮助,身为作者听到这个消息还是很开心的. ...

  4. 使用Github Action来辅助项目管理

    Github action 是一个Github官方提供的非常流行且速度集成 持续集成和持续交付(CI/CD)的工具.它允许你在GitHub仓库中自动化.定制和执行你的软件开发工作流.你可以发现.创建和 ...

  5. (Java)常用类库

    Spring 常用工具类 Spring作为常用的开发框架,在Spring框架应用中,排在ApacheCommon.Guava.Huool等通用库后,第二优先级可以考虑使用Spring-core-xxx ...

  6. VS2017 error CS0234: 命名空间“Microsoft”中不存在类型或命名空间名“Office”问题的一种解决方案

    最近需要使用VS2017编辑C#,但在编译时软件报错:error CS0234: 命名空间"Microsoft"中不存在类型或命名空间名"Office" 在网上 ...

  7. Linux 鉴定故障

    导读 进入linux,输入root账户,密码输入是正确的,提示"鉴定故障",刚开始以为是系统挂了,后来百度说,需要重置root密码,具体步骤如下. 重置root密码 重启Linux ...

  8. windows下使用dockerdesktop进行部署

    Docker部署springboot项目 环境准备 要在windows上使用docker需要确认系统的需求 需要启用虚拟化支持的CPU 启用适用于windows的Linux子系统功能 保证足够的内存 ...

  9. git将某个开发分支最近的提交合并成一个提交

    你可以使用 `git merge --squash` 命令将某个开发分支最近的提交合并成一个提交. 具体步骤如下: 1. 切换到你想要合并的分支上,比如 `develop` 分支: `git chec ...

  10. 基于Java+SpringBoot+vue+element助农平台设计和实现

    \n文末获取源码联系 感兴趣的可以先收藏起来,大家在毕设选题,项目以及论文编写等相关问题都可以给我加好友咨询 系统介绍: 随着互联网大趋势的到来,社会的方方面面,各行各业都在考虑利用互联网作为媒介将自 ...