Linux系统中玩到让你停不下来的命令行游戏

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux系统中玩到让你停不下来的命令行游戏相关的知识,希望对你有一定的参考价值。

参考技术A

大家好,我是良许。

在使用 Linux 系统时,命令行不仅可以让我们在工作中提高效率,它还可以在生活上给我们提供各种 娱乐 活动,因为你可以使用它玩许多非常有意思的 游戏 ,这些 游戏 可都不需要使用专用显卡。

命令行 游戏 尽管比较简单,看上去只是一行行枯燥的代码,但有,还是有不少的 Linux 系统 游戏 却要复杂和有趣一些。实际上,命令行 游戏 一个重要的功能就是需要我们发挥想象力和创造力,在空白的纸上描绘出动人的景象,这非常有利于开发我们的大脑。

下面,我们将介绍几款可以在 Linux 系统中用命令行也能玩的 游戏 。

网络黑客 于1987年首次发布,这款 游戏 还在一直在不停的开发中(3.6.6版本于2020年3月8日发布)。

在一些网友眼中,这款 游戏 被看作是所有流氓类 游戏 的鼻父。尤其是近年来类似的 游戏 也大受欢迎,诸如超越光速、以撒的结合、盗贼遗产、节奏地牢、暗黑地牢等。

这类 游戏 围绕着 探索 和生存展开, 游戏 开始时,你要创造自己的角色,扮演一个传统的梦幻性角色,比如骑士或巫师,然后 游戏 会给你介绍你所扮演角色的主要目标,那就是在地牢的最底层找到尽可能多的护身符,剩下的目标取决于你自己了,可以任意地在 游戏 中任意发挥。

矮人要塞 是在这个名单中唯一一个没有开源的 游戏 ,不过我们任然选择把它放入此次名单中,因为它的影响力和受欢迎程度实在太大了。

在矮人要塞这个 游戏 中,你要么负责控制一个矮人玩要塞模式,挖地洞、种田、狩猎等,要么玩冒险模式,在一个随机产生的大世界里玩耍,这个世界是由首都、村庄、地下墓穴、迷宫、强盗营地等组成的。

要塞模式包括很多面,从手工生产到与邻居交易,再到防御敌人;冒险模式虽然依赖于传统的流氓 游戏 机制,但是其开发深度远远超过像网络黑客这样的 游戏 。

弗罗茨 其实并不是一款真正意义的 游戏 ,它是 Infocom 公司的 游戏 和其他 Z-machine 游戏 (如佐克)的解释器。 佐克 是有史以来最流行的文本冒险 游戏 之一,与上世纪80年代发布的其他文本冒险 游戏 不同,佐克可以解释相当复杂的文本命令(用水晶钥匙开门),就凭这个,它大大提高了 游戏 的可玩性,会给你带来栩栩如生的感觉。

佐克分为三部 游戏 (佐克 l:伟大的地下帝国,佐克 II:罗博兹的巫师,佐克 III:地牢大师),你可以直接从Infocom网站免费下载所有 游戏 。 为了找到更有趣的 Z-machine 游戏 ,下面介绍几场不容错过的 游戏 比赛:

迷路的猪 :是一款非常有趣的 游戏 , 游戏 难度适中。 游戏 大致的内容是你跟随一个兽人,你们必须找回一头逃走的猪。这款 游戏 于2007年发布,在2007年的互动小说大赛中名列第一。

蜘蛛网 :这个 游戏 大致是让你扮演一个被俘间谍的角色,你的目标是向审问者讲述一个似是而非的故事。可别小看这个 游戏 ,你在 游戏 中说的每一句话、每一个细节都会被质疑,你需要发挥聪明才智去和审问者博弈。

见证者 :这个 游戏 由 Infocom 公司创建,它是一个谋杀类的文本 游戏 ,充满神秘和冒险,故事发生在洛杉矶一个安静的郊区,玩家扮演一个侦探,负责调查一个叫 Freeman Linder 的有钱人,他害怕自己的生命受到威胁,玩家需要根据所提供的线索解开谜团。

当我们在等待程更新下载或者安装时,有几个简单的 游戏 来打发时间是很不错的,BSD 游戏 就是不错的选择。BSD 游戏 包含有一个数量相当大的 Linux 系统 游戏 命令行,它们有些最初是与一些BSD 游戏 一起分发的。

BSD 游戏 包括冒险,算术,双陆棋,五子棋,黑客,智力竞赛,俄罗斯方块等。

要启动任何包含在BSD 游戏 中的 游戏 包,只需在终端中输入其名称并按下 enter 键。

大灾变:黑暗之日 是一款基于回合制的生存 游戏 ,在这个 游戏 中,幸存者必须为看到另一个日出而战斗,因为僵尸、杀人机器人、巨型昆虫和其他致命的敌人无处不在。

游戏 以一种相当典型的流氓式的方式开始:你醒来时没有记忆,你的直接目标包括保证食物安全、 探索 你的周围环境等,你的目的是在这个过程中不被杀死。

大灾变:黑暗之日 可以在终端软件上玩,也可以用图形化的 tileset 玩。除了 Linux 系统,它还可在 Windows、macOS、iosandroid 上运行。


2014年,意大利网络开发商加布里埃尔·西鲁利(Gabriele Cirulli)发布了《2048》,互联网立刻爱上了它,因为这个 游戏 虽然简单却让人着迷。这个 游戏 的目的是移动有编号的瓷砖,使两个具有相同编号的瓷砖相互接触,从而使它们合并为一个瓷砖,按照这个方式,直到玩家创建一个编号为2048的瓷砖。

GitHub 页面虽然提供了有关如何下载和安装2048客户端的说明,但实际上只需要两个命令:


​ 受最初投币 游戏 的启发,贪吃蛇是一款多人玩家的 Linux 系统命令行 游戏 , 游戏 屏幕上最多有四条由 游戏 玩家控制的蛇,其他的蛇是系统生成。​ 如果您的系统上安装了贪吃蛇,您可以在终端中输入以下命令开始 游戏 :

该 游戏 由 WASD 方向键或 vim 键绑定控制,您可以随时按 Escape 或 Ctrl+C 退出 游戏 。

Flappy Paddle现身江湖!使用强化学习DQN让你划船划到停不下来


【飞桨开发者说】韩磊,台湾清华大学资讯工程学系硕士,现创业公司算法工程师,百度强化学习7日营学员


Flappy Paddle现身江湖!使用强化学习DQN让你划船划到停不下来


强化学习7日打卡营AI Studio课程主页:

https://aistudio.baidu.com/aistudio/course/introduce/1335


B站课程链接:

https://www.bilibili.com/video/BV1yv411i7xd


《Flappy Bird》相信大家都玩过或者看过,这款游戏在2014年火遍全球。其操作非常简单,只需要点击屏幕,让主角小鸟顺利地穿过水管之间的缝隙而不碰触任何障碍物。小鸟穿过的水管越多,得到的分数也就越高。


Flappy Paddle现身江湖!使用强化学习DQN让你划船划到停不下来


今天我们也来玩一玩这个游戏,不过我们使用强化学习的算法来让主角小鸟自己学会穿过水管躲避障碍,进而魔改环境,制作特殊的三人环境,让游戏进阶为《Flappy Paddle》。别愣着,看下去,看完我们一起划船。


学习这篇文章,你可以做出下面视频中的效果。这里在红黑两支队伍被淘汰之后,结束了录制。因为蓝色的算法可以跑很久,这里只是作为展示,所以没有继续录下去。



飞桨有众多方便好用的开发工具套件,其中PARL就是在强化学习方向的一个高性能、灵活的框架,目前已经在Github上开源。PARL支持大规模并行计算,同样提供了算法的可复现性保证。PARL的框架逻辑清晰,容易上手,从Model到Algorithm再到Agent,逐步构建智能体。同时PARL也提供了一些经典的强化学习算法代码示例,如PG、DDPG、A2C等,方便开发者的调研和验证。不仅如此,PARL还提供了比较完善的算法基类,这使得PARL的扩展性也很好,开发更为轻松快捷。


在我们这个项目中,使用的就是PARL这个开发工具套件。PARL的仓库,针对很多经典的强化学习方法也提供了对应的例子。本项目使用的DQN方法,也是在PARL的实现上的变化。



环境解析




对于强化学习问题,一般是智能体(Agent)和环境(Environment)的一个交互问题。智能体需要对环境或部分环境做出观测(Observation),并根据环境做出动作(Action),而环境对这个动作做出奖惩(Reward)。


我们从《Flappy Bird》这个小游戏开始。我们使用PyGame-Learning-Environment这个环境,你可以在Github上轻松的找到这个仓库。下面来分析一下上述的几个元素。
  • 对于观测值,我们可以通过getGameState函数得到一个观测字典,其中包含了8个字段,包括了玩家(游戏里是一个小鸟)的坐标信息、速度信息、玩家距离下一水管和再下一根水管的位置信息。当然你也可以直接使用getScreenRGB函数得到画面,并以它为观测值。这里为了简单操作,我们以观测字典为例。同时,我们也能发现这个观测值是连续的。
  • 对于动作,我们可以通过getActionSet函数得到环境所支持的动作。在《Flappy Bird》这个游戏里,只有两个动作:1、点击屏幕让小鸟展翅高飞,2、什么都不做让小鸟自由滑翔。由此我们可以知道环境接受的动作是离散有限的。
  • 在奖惩方面,环境是这样定义:reward = 当前帧的总分 - 前一帧的总分。总分的变化有两种情况:1、玩家通过管子,得一分。2、玩家撞天花板、地板,管子则游戏失败,扣五分。

算法选择




前一小节中,我们发现环境的观测是连续的,环境接受的动作是离散有限的。对于这种情况,可以选用Deep Q-Network(以下简称DQN)或是Policy Gradient(以下简称PG)。DQN作为查表法的扩展,把观测值从有限离散扩展到了连续空间,PG也有处理连续空间观测值的能力。两者的区别在于,DQN对观测值对应的每个动作计算Q值,并选择相应的动作;而PG则直接给出动作,省略了中间步骤


那在这个任务中应该选择DQN还是PG呢?笔者两者都尝试了,而DQN可以轻松的训练出不错的效果,而PG却不能。我觉得可以从以下角度分析。 DQN针对每一个观测的每一个动作做出评价 ,也就是说每一个动作都会有其价值。而在训练PG的时候,需要先跑完一个episode,然后将奖惩回传到这局游戏中的每一个动作上。

对于这个过程中的每一个动作,在这个任务中这种回传不是一个好的反馈方法。举一个例子:现在玩家在第五根管子前,真正影响面对第五根管子时动作的,是经过第四根管子之后的动作(以及第五根第六根的管子的位置,这属于观测值)。而更早之前的经过第一根、第二根、第三根管子的动作是不影响经过第五根管子的,那么这个奖惩回传的方法在这个任务中就很有问题。


搭建DQN及训练




这里再简单的介绍一下DQN。DQN作为Q-learning在连续观测值上的扩展,使用网络来代替传统的表格,增加了泛化的能力。DQN的训练和Q-learning一样,不断的让Q(s,a)逼近TargetQ=r+γmaxQ(s’,*)。这里利用的是神经网络的拟合能力。由于TargetQ在不断变化,DQN中使用了固定Q目标的方法,让算法更新更为平稳。除此之外,DQN中还使用了经验池的方法,提高了样本的利用率。同时这一机制也可以用来打散数据,消除样本之间的关联性。


鉴于PARL清晰的框架结构和完整的基类,我们构建Agent也更加容易。按照先model,再Algorithm,最后定义Agent的步骤来。这个项目的代码都是基于PARL中的DQN的例子的。

这里附上样例链接:
https://github.com/PaddlePaddle/PARL/tree/develop/examples/DQN

首先我们简单地设计一个包含三个隐层的网络,在PARL中的model需要继承parl.Model这样的基类。

  
    
    
  
class Model(parl.Model):
     def __init__(self, act_dim):
        hid0_size =  64
        hid1_size =  32
        hid2_size =  16
         self.fc 0 = layers.fc(size=hid0_size, act= 'relu', name= "fc0")
         self.fc1 = layers.fc(size=hid1_size, act= 'relu', name= "fc1")
         self.fc2 = layers.fc(size=hid2_size, act= 'relu', name= "fc2")
         self.fc3 = layers.fc(size=act_dim, act=None, name= "fc3")

     def value(self, obs):
        h 0 =  self.fc 0(obs)
        h1 =  self.fc1(h 0)
        h2 =  self.fc2(h1)
        Q =  self.fc3(h2)
         return Q

有一点动态图构建模型的感觉是不是?所以在模型方面你可以有更多的想法和设计,例如我还设计了以下这种模型:

  
    
    
  
class catModel(parl.Model):
     def __init__(self, act_dim):
        hid0_size =  64
        hid1_size =  32
        hid2_size =  16

         self.fc 0 = layers.fc(size=hid0_size, act= 'relu', name= "catfc0")
         self.fc1 = layers.fc(size=hid1_size, act= 'relu', name= "catfc1")
         self.fc2 = layers.fc(size=hid2_size, act= 'relu', name= "catfc2")
         self.fc3 = layers.fc(size=act_dim, act=None, name= "catfc3")

     def value(self, last_obs, obs):
        oobs = fluid.layers.concat(input=[last_obs, obs], axis=- 1, name= 'concat')
        h 0 =  self.fc 0(oobs)
        h1 =  self.fc1(h 0)
        h2 =  self.fc2(h1)
        Q =  self.fc3(h2)
         return Q

可以看出来,这里是将last_obs和obs直接concat到一起作为全连接层的输入。这里的last_obs,是上一帧的观测值,obs是当前帧的观测值。也许这种模型的效果并不会更好,但仍是一个值得尝试的想法。

接下来是algorithm,PARL中已有DQN的实现,我们直接使用PARL中提供的DQN类。像样例中一样,我们直接import算法就可以。

  
    
    
  
from parl.algorithms  import DQN

当然这种写法并不适合于我刚才的第二种做法,因为第二种方法的value函数,接受的是last_obs, obs两个参数。所以这里你可以继承基类DQN或是直接重构一个。放心,有了PARL提供的样例,这个过程会非常的简单。基本上重写predict和learn两个成员函数就好。这两个函数也是之后“暴露”给Agent使用的。

predict函数用来拿到模型的输出,也就是所谓的Q值。而learn函数则是根据模型的输出和Agent拿到的经验数据去构建模型的cost,并使用优化器来最小化它,从而达到训练模型的目的。

最后是Agent,如果你使用的是我刚才第一种model,那么你可以直接使用样例中Agent的定义,但如果你使用了第二种,那当然也要修改对应的build_program、sample、predict、learn几个成员函数以能够成功的构建模型并调用Algorithm定义的函数。

接下来就可以训练我们的模型了,大概几百个episode之后,我们的Agent就能够拿到正的分数(其实这个时候,分值已经超过5分了)

Flappy Paddle现身江湖!使用强化学习DQN让你划船划到停不下来



修改贴图资源,制作三人环境




现在让我们来划船吧,其实最简单的就是替换一下贴图资源,在PyGame-Learning-Environment

/ple/games/flappybird/assets文件夹中。把这个小bird换成我们的划船选手~


但是一个队伍划船总有一些孤单,能不能让多个Agent在同一环境下一起“比赛”呢?与其说把环境写“死”,每次读取来评判不同的Agent,不如就让他们在同一环境下一起出发,这种方式更加直观。

这个地方需要修改的是PyGame-Learning-Environment/ple/games/flappybird下的__init__.py文件,这个文件中定义了整个游戏的逻辑。

这里就不更具体的说了,因为涉及的更多的是pygame的知识。__init__.py中需要修改的地方大概有:
  1. 初始化定义三个player。
  2. 为每个player添加score和live属性及每个player对应的得分和死亡处理,以及游戏的score和结束条件。
  3. 设计新的actionset, 以能接受三个输入(实际上是一个输入包含三个Agent的三个action)。
  4. 设计新的observation。在此之前只返回一个观测值,但现在要针对每个player返回其对应的观测值。
  5. 图像绘制。在原来的基础上多绘制两个player。
在仓库中提供了修改好了__init__.py以及图像资源,提供了一些设计环境的想法。


成果




结果已经展示在文章的开篇视频中。这里训练了三个模型,两个隐层的模型,拿到了均分147分;拼接的模型,拿到了157分,而三个隐层的模型,则拿到了2000分左右的平均成绩。当然,针对不同的参数量的模型应该有对应的学习率等超参数层面的调整,这里仅是为了展示,并没有在这方面做更多的探索和优化。



总结




那么在哪里能学到以上酷炫又有趣的知识呢?AI Studio上现有一门课程:《强化学习7日打卡营-世界冠军带你从零实践》,通过学习,你可以对强化学习有一个初步的了解,学到Q-learning、Sarsa、DQN、Policy Gradient等。几个清晰有趣的案例和作业,在充满趣味的同时,加强对算法和代码实现的理解。当然,也可以和我一样扩展思路,魔改环境,开发更多有趣又有技术的项目。

视频预览 :
https://www.bilibili.com/video/BV1KV411674k
AI Studio项目链接 : 
https://aistudio.baidu.com/aistudio/projectdetail/609617


百度AI Studio课程平台




扫码加入课程,即可观看《世界冠军带你从零实践强化学习》的完整课节内容,动手实践案例和代码,遇到作业问题还可以到讨论区寻找答案。

最后,别忘了加入微信学习群,风里雨里我们在群里等你~


如在使用过程中有问题,可加入飞桨官方QQ群进行交流: 1108045677

如果您想详细了解更多飞桨的相关内容,请参阅以下文档。

官网地址:
https://www.paddlepaddle.org.cn

飞桨开源框架项目地址:
GitHub: 
https://github.com/PaddlePaddle/Paddle
Gitee:  
https://gitee.com/paddlepaddle/Paddle

飞桨生成对抗网络项目地址:
GitHub:
https://github.com/PaddlePaddle/PARL
Gitee:
https://gitee.com/paddlepaddle/PARL

END


以上是关于Linux系统中玩到让你停不下来的命令行游戏的主要内容,如果未能解决你的问题,请参考以下文章

如此丝滑的按钮交互效果

ubuntu中ping停不下来的解决

Flappy Paddle现身江湖!使用强化学习DQN让你划船划到停不下来

游戏知识科普:啥是肉鸽?为何玩肉鸽游戏会让人停不下来?

将 k8s 制作成 3D 射击游戏,好玩到停不下来 | 文末福利

Pygame实战:升级后的2048小游戏—解锁新花样!根本停不下来!附源码