点击上方蓝色字体,关注程序员zhenguo

你好,我是 zhenguo
这是我的第493篇原创
今天是Python项目系列第二期,与大家一起动手制作2048游戏。
这个游戏当年风靡全球,游戏规则极其简单,玩起来也是相当简单,但是要想最后拼出2048,也绝非是一件容易的事。并且玩起来,也很有意思,总想一把一把的挑战。
2048游戏风格相似的是,它的代码实现起来也是非常简洁,代码只有区区不到200行,并且是纯Python,不用任何第三方包的情况下。

1 Python实现的2048游戏界面

我们先来一览最终实现的游戏界面,顺带帮助不了解2048游戏的读者,熟悉下它。
游戏主界面:
游戏基本规则:
  1. 键盘中上、下、左、右四个箭头,对应4个漂流方向
  2. 合并。数值相等的两个方格可以合并为1个方格,且值乘以2,如下图左下角,两个2方格可合并为一个4方格
合并后,最左下角就是4方格:
但是为什么它的上方又多了2方格呢?注意,这是第三个规则:
  1. 随机2方格。发生合并操作时,会从灰色的单元格中随机选择一个,并创建出2方格
  2. 漂流。再有1个好玩的操作,我称它为漂流,紧邻上图,我如果按下右箭头,两个左下角的4方格根据规则2首先合并为8方格。同时,所有方格整体向右漂流(沿着箭头方向)。因为发生了合并操作,根据规则3,再生成一个2方格。因此得到了如下界面:
这就是游戏的规则,大家下载我的完整代码后,玩耍一下后,理解规应该会更深,玩起来真的贼爽。

2 项目环境

本项目不使用任何第三方包,全都是Python自带的模块,且只用到2个模块,可见2048游戏的魅力,实现的代码都毫不费力。
一个模块是Tkinter,用来做界面,还用到的随机模块random

3 项目代码讲解

不到200行代码,是个小框架。主要包括2个类:
  • Board
  • Game
下面逐一介绍。

3.1 Board

主要提供三个能力,分别对应上面的三个规则:
  • 合并规则,对应Board类的方法merge_grid
  • 随机创建2方格,对应Board类的方法random_cell
  • 漂流,对应Board类的方法drifting_left

3.2 Game

主要提供Tkinter的键盘消息和事件处理能力,对应方法event_handlers,比较简单,所以主要讲解Board
merge_grid方法
编写merge_grid方法的逻辑,假定是在按下左箭头时,为什么这样假定,后面我会重点分析,这是理解这套代码的核心。基于此,合并邻近的两个非零相等单元格,实现逻辑很简单:
defmerge_grid(self):
"""

        向左移动,合并邻近的两个非零相等单元格

        :return:

        """

        self.merge = 
False
for
 i 
in
 range(
4
):

for
 j 
in
 range(
3
):

if
 self.grid_cell[i][j] == self.grid_cell[i][j + 
1
and
 self.grid_cell[i][j] != 
0
:

                    self.grid_cell[i][j] *= 
2
                    self.grid_cell[i][j + 
1
] = 
0
                    self.score += self.grid_cell[i][j]

                    self.merge = 
True
random_cell方法
实现random_cell方法就更简单了,随机从灰色(没有数字的方格)方格中,挑选一个,并赋值为2就行:
defrandom_cell(self):
"""

        从零单元格中随机产生一个2号单元格

        :return:

        """

        i, j = random.choice([(i, j) 
for
 i 
in
 range(
4
for
 j 
in
 range(
4
if
 self.grid_cell[i][j] == 
0
])

        self.grid_cell[i][j] = 
2
drifting_left方法
实现漂流drifting_left方法,使用的是最基本的快慢指针,cnt是慢指针,j是快指针。
defdrifting_left(self):
"""

        向左偏流,消除0方格

        :return:

        """

        self.compress = 
False
        temp = [[
0
] * 
4for
 _ 
in
 range(
4
)]

for
 i 
in
 range(
4
):

# cnt:慢指针,j: 快指针
            cnt = 
0
for
 j 
in
 range(
4
):

if
 self.grid_cell[i][j] != 
0
:

                    temp[i][cnt] = self.grid_cell[i][j]

if
 cnt != j:

                        self.compress = 
True
                    cnt += 
1

        self.grid_cell = temp

3.3 代码核心

2048游戏会有4个漂流方向,分别为上、下、左、右。
而上面代码,假定漂流是向左,并基于此编写了向左漂流的逻辑。
这正是此套代码实现的高明之处,其他上、下、右三方向的漂流,经过reverse(反转)或transpose(转秩)后,都可以转成向左漂流的逻辑。这两个中间操作也都在Board类里提供了。
比如,实现向右漂流时,先执行一次reverse,然后执行drifting_left,再执行一次reverse,就实现了右漂。
实现上漂时,先转秩,再左漂,再转秩。
这个变化思路,大家纸上画一画,一看便知。
还是有疑问的,留言区交流。

4 项目代码讲解

上面完整py代码文件,在我的公众号后台回复:c,即可下载
同时过往或后面的Python项目代码,我也会同步到这个文件夹中。
长按关注,回复c
不用打赏,点个赞或在看

就心满意足了
zhenguo原创精华PDF,倾情奉献给你,后台回复对应关键词下载
继续阅读
阅读原文