90行代码写一个游戏?教你用90行HasKell代码实现2048游戏

Posted python猿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了90行代码写一个游戏?教你用90行HasKell代码实现2048游戏相关的知识,希望对你有一定的参考价值。

前言

赖斯大学的mooc计算机规则公开课首次在Coursera上开讲,他们之前的课程 Python中的交互式编程介绍 所有优良的东西: 演示文稿做的很不错,也有大量的支持可用, 而布置的作业也很有趣. 第一个作业就是编写 2048 游戏的逻辑.


正文

为游戏的逻辑编写代码是相当直接的。归因于使用Python作为教学语言的计算原则课程, 对于在我的最初版本中的一个错误是由于python发生了改变,我不会感到奇怪. 我想着用Haskell写这个东西可能会更有趣, 随后就着手开始用这个语言编写了2048的一个完整实现, 包括 I/O 处理. 整个代码可以在 我的git账号 上找到. 最终结果证明,更加完整的Haskell方案所需要的代码比使用Python的程序逻辑要少几行.

作为说明,如果你到这个页面来只是为了找寻计算规则这门课程的Python作业的解决方案,那你就是在浪费时间. Haskell的实现和Python的实现很不同,使用的编程语言构造也不能在Python上用. 换言之,如果你正纠结这个作业,Haskell的源代码将不会对你有所帮助.

在这篇文章中,我仅想着重强调游戏逻辑的核心部分,因为它很好地显示了函数式编程的力量。首先,我定义一个数据类型,用于展示网格中的数字移动的方向,还有一个用于存放整数列表的列表的类型同义词,用来提高类型特征的可读性。从函数‘move’的命名可以明显看出函数的作用;再下一步,将输入作为一个网格的数字和移动方向,并产生新的网格。

90行代码写一个游戏?教你用90行HasKell代码实现2048游戏


2048这个游戏是在一个4x4的棋盘上进行的。开始位置在我的实现中是固定的:

90行代码写一个游戏?教你用90行HasKell代码实现2048游戏


棋盘上可以在4个方向上对数字进行移动,意味着所有的数字的移动都会向着一个指定的方向,如果是2个数字,移动相同的方向,以彼此相临而告终,则他们合并到一起。举例来说,在如下所示的起始位置,移动方向为‘Up’,结果棋盘变成了下面所示:

90行代码写一个游戏?教你用90行HasKell代码实现2048游戏


如果网格中的起始位置移动方向为向右,则不会有任何变化。如果网格变化了,则一个新的数字会在任何空的格子中产生,这个数字可能是2或者4.

我们看这种方法,问题在于其如何更有效的建模。在网格中的任何行列,都可被理解为一个列表。行和列表之间的关系是简单明了的。列将不得不提取、 修改,或虽然再,插入。或者他们不需要?

我写了一个函数来合并一行或一列,表示为一个列表。首先,所有的0要被移动,然后该列表将被处理,合并相邻元素,如果它们包含相同的数字,接着如果必要的话,为结果中填充0.

90行代码写一个游戏?教你用90行HasKell代码实现2048游戏


当棋盘中的移动方心为左时,这个合并函数可以立刻被应用。其他方向的移动,然而,需要进行一些考虑,如果希望代码保持简洁。向右移动网格是通过采取反转它之前将它提交给函数merge的每一行完成的,然后再次反转结果:

90行代码写一个游戏?教你用90行HasKell代码实现2048游戏


对于网格向上或者向下移动,如果你想提取出一列,对其应用合并函数,然后产生新的网格进行列的插入,这是极其痛苦的。相反,虽然一点点的线性代数知识,却导致一个更优雅的解决方案。如果你不能立即明确如何移调导致所期望的结果,请看看下面的插图。

90行代码写一个游戏?教你用90行HasKell代码实现2048游戏


我Haskell的实现使用终端作为输出。它不像Gabriele Cirulli版本的javascript前端一样令人印象深刻,但它是可维护的,如下两个屏幕截图展示:



总体来讲,我对于这个原型还是很满意的。当然有几个可能的改进。一个分数跟踪器的添加将是微不足道的,虽然一个 GUI 将是一个更加耗时的努力。如果有立即响应键盘输入的程序,我会觉得这个很有趣。当前,每个通过 WASD的输入 需要点击回车键进行确认。如果只按一个键将触发程序执行的下一步,那么游戏玩法会加快很多。在研究这一问题时,我没有找到任何快速的解决办法。尽管Haskell库NCurses包含键盘事件。我可能会深入探究一下,如果我用ASCII 图形进行编程使之成为一个“独立”游戏。


以上是关于90行代码写一个游戏?教你用90行HasKell代码实现2048游戏的主要内容,如果未能解决你的问题,请参考以下文章

明明做了很多,老板啥也看不到?教你用10分钟写出90分汇报,收藏

500行代码,教你用python写个微信飞机大战

不用写代码神器!教你用4行命令轻松使用nnUNet训练自己的医学图像分割模型

“数万行代码“教你用html和css编写一个精美的网页

“数万行代码“教你用html和css编写一个精美的网页

教你用两行代码给PHP7添加一个“非空合并”语法糖