《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. Mybatis 动态 sql 是做什么的?都有哪些动态 sql?能简述一下动态 sql 的执行原理不?

    a.Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能. b.Mybatis 提 供 了 9 种 动 态 sql 标 ...

  2. 项目管理--PMBOK 读书笔记(10)【项目沟通管理】

      1.沟通技术 1)交互式沟通:双方多方之间的多项信息沟通,确保全体参与者对特定话题达成共识,回馈. 2)推式沟通:将信息发送给接收方,不确保受众理解. 3)拉式沟通:自主自行反问信息   2.沟通 ...

  3. Linux chmod -bash: ./xx.sh: Permission denied的解决方案

    Linux -bash: ./xx.sh: Permission denied的解决方案启动tomcat命令:./startup.sh之后提示-bash: ./startup.sh: Permissi ...

  4. windows 安装mysql 非常之详细

    安装 1.下载安装包 2.解压包  3.文件夹内创建my.ini配置文件,并添加内容 # For advice on how to change settings please see # http: ...

  5. uniapp 使用z-paging 分页组件 写在头部插槽内的单选按钮无法点击

    这个问题是因为组件层级太低 <z-paging ref="paging" v-model="dataList" @query="queryLis ...

  6. mysql5.7msi安装

    本文介绍的是只安装MySQL数据库的过程,并不包含各种其他附加工具.安装完成之后通常使用Navicat或SQLyog进行可视化操作. 清华的镜像网站只保存最新的几个MySQL版本,所以直链可能已经失效 ...

  7. admission-controllers

    WebHook是什么  官方文档: https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/admission-controller ...

  8. invalid comparison: java.util.Date and java.lang.String异常的原因

    mybatis查询时使用date类型与""比较导致的 例 <if test="params.applicationEndTime != null and param ...

  9. RabbitMQ 3.7.9版本中,Create Channel超时的常见原因及排查方法

    在RabbitMQ 3.7.9版本中,Create Channel超时的常见原因及排查方法如下: 常见原因 网络问题: 网络延迟或不稳定可能导致通信超时. 网络分区(network partition ...

  10. python基础-数据容器的通用操作

    五种数据容器的特性   列表list[]  元组tuple()  字符串str""   集合set{}   字典dict{key:value} 元素数量 支持多个 支持多个 支持多 ...