200行Python代码实现2048

2048 是我读大学的时候火起来的一门游戏,没有玩过的童鞋可以亲自体验一下:http://gabrielecirulli.github.io/2048/

前一段时间又出来了个 博士版,嗯,玩起来很有代入感,完美诠释了读博生活的苦逼和不易:http://www.cl.cam.ac.uk/~yf261/2048/?from=timeline

那么今天,我们就用200行左右的Python代码,自己实现一下2048吧!

游戏逻辑

首先不妨考虑一下游戏的运行逻辑。

游戏有以下4个状态:初始化、游戏中、胜利、游戏结束、退出。

  • 初始化是指游戏刚开始,屏幕上只有两个2的状态;
  • 游戏中是指用户可以继续操作的状态;
  • 胜利是指成功合成了一个2048的状态;
  • 游戏结束是指用户已经无法操作、屏幕上的数字无法进一步合成的状态;
  • 退出是指用户选择了退出、程序退出的状态。

所以游戏的运行逻辑可以用一个有限状态机(FSM)来描述,从初始化出发,根据用户的当前操作进入下一状态,直到退出。

用户可以执行6种操作:上、下、左、右、重置、退出。

  • 上、下、左、右会触发相应的移动和合并操作,并随机再生成一个2或4;
  • 重置会将游戏变为初始化状态;
  • 退出会直接结束游戏。

想清楚了以上的主逻辑,我们再来讨论下应该实现哪些功能性模块。

棋盘存储

如果游戏界面是一个4行4列的棋盘,那么我们需要用一个4*4的二维矩阵记录棋盘上当前的数字,用0表示对应位置为空,用2、4、8等值表示对应位置存在相应的数字。

随机生成一个2或4

不妨写一个函数,用于在当前棋盘上的随机一个空余位置生成一个2或4。游戏初始化时调用两次该函数,用户每次操作之后也需要再调用一次。

移动和合并

当用户执行操作之后,棋盘上的数字需要全部往该方向上移动,并且进行可能的合并。

举个例子,用户往左划之后,每一行的数字都需要向左移动和合并,可以分解为以下三个步骤:

  • 将非零块全部“压”到左边;
  • 如果相邻的块大小相同,则合并,一个用0代替,另一个用2倍数字代替;
  • 再次把非零块全部“压”到左边。

想清楚了这些,另外三个方向上的操作也是类似的。

是否成功

处理完用户的操作之后,判断棋盘上是否已经有2048,如果已经合成了,表示用户成功,重开一盘。

是否失败

处理完用户的操作之后,判断棋盘在上、下、左、右四个方向上,是否还存在任何移动可能。

举个例子,对于左,判断每一行:

  • 是否存在0,即存在空余位置;
  • 是否存在两个相邻且大小相同的数字。

以上两个条件只要成立一个,就可以认为在该方向上仍有移动可能。

最高分

每次合成数字时记录总分数,例如合成一个4加4分。当Gameover时,比较总数据是否超过最高分,如果超过了则更新最高分即可。

游戏界面

写一些代码在屏幕上画一个4*4的棋盘,并且在每次处理完用户操作之后,根据棋盘矩阵的数值,在相应的位置填写数字或保留空白即可。

最后的样子

想清楚以上各个模块的功能之后,我们用200行左右的代码,就可以自己实现一个2048。

界面当然不好看,但是都是进一步润色和修改的事情了。如果有兴趣的话,还可以再实现一个网页版,毕竟游戏的主逻辑都是一样的~

博士版 把纯数字换成了想法、代码、深度学习、见导师、实验、paper、会议、答辩、博士、薄厚等,并且加入了垃圾、恋爱、分手等元素,很有创意、直达人心!

那么,你有别的想法吗?快去实现一个属于自己的独具特色的2048吧~

整理自实验楼(www.shiyanlou.com)课程

原文发布于微信公众号 - 宏伦工作室(HonlanFarm)

原文发表时间:2016-12-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏逍遥剑客的游戏开发

VR中对带有约束的物理对象的交互

32160
来自专栏小白课代表

[Android/IOS] | 把微博秒拍Twitter的视频装进口袋里的...

12120
来自专栏逍遥剑客的游戏开发

Bullet的最小化功能封装

18530
来自专栏上善若水

007尝试使用UML图

尝试使用uml图来帮助自己快速的构建稳健的程序 uml对理清自己的思路,应该是很有帮助的了

11520
来自专栏恰童鞋骚年

自己动手写游戏:飞机大战

  要说微信中最火爆的小游戏是哪款,可能既不是精心打造的3D大作,也不是《植物大战僵尸2》,而是微信5.0刚开启时的《飞机大战》。

46910
来自专栏jouypub

Redis百亿级Key存储方案

该应用场景为DMP缓存存储需求,DMP需要管理非常多的第三方id数据,其中包括各媒体cookie与自身cookie(以下统称supperid)的mapping关...

25360
来自专栏哲学驱动设计

090609 T 领域建模

领域建模的重要性     以数据为中心的应用程序开发,面向过程分析方法的核心在于对数据库的设计。     而现在以面向对象的方式进行分析(OOA,OOD)时,领...

20080
来自专栏数据结构与算法

博弈论入门之nim游戏

nim游戏 nim游戏 有两个顶尖聪明的人在玩游戏,游戏规则是这样的: 有n堆石子,两个人可以从任意一堆石子中拿任意多个石子(不能不拿),没法拿的...

1.1K90
来自专栏思考的代码世界

Python网络数据采集之处理自然语言|第07天

在之前我们了解了如何把文本内容分解成 n-gram 模型,或者说是n个单词长度的词组。从最基本的功能上说,这个集合可以用来确定这段文字中最常用的单词和短语。另外...

37370
来自专栏ThoughtWorks

改善单元测试的新方法|洞见

鄢倩 ThoughtWorks 我们为什么要写单元测试? "满足需求"是所有软件存在的必要条件,单元测试一定是为它服务的。从这一点出发,我们可以总结出写单元测试...

29750

扫码关注云+社区

领取腾讯云代金券