python矩阵增加一行_用python写游戏之 2048

b8edcfb5a2a39742a222e11950e25d1d.png

2048这个游戏相信大家都不陌生吧

游戏的规则很简单,你需要控制所有方块向上下左右的某一方向运动,方向上两个相同数字合并会相加,每次移动后在空白处生成一个2或者4,最终得到一个“2048”的方块就算胜利了。

虽然简单但却虐心,今天我们就来分析这个游戏的算法原理,并用python把这个游戏写出来。

ok,我们分析的思路就是给这个游戏来一个二向箔,降维打击,如何做,可以往下看。

首先我们把游戏4*4的方格,称之为棋盘,然后忽略棋盘的背景和颜色,使之变成4*4的田字格,田字格里是对应的数字,空白的方格用0填充,如下图

c0a34402910c3c95b9b1b37fac5fe716.png

图变成了一个4*4的方格,接下来去除方格,把每一行提取出来写到python的列表里,比如第一行变成 [2, 0, 2, 0], 那么这个4*4的方格,就变成了一个4*4的二维矩阵

3c0ab23bb576df55578edb51c327d524.png

抽象成python的数据格式之后,我们看数字移动和数字加减的操作。

以向左移动为例,移动的结果,第一行会变成[4, 0, 0, 0 ], 第三行会变成[8, 0, 0, 0],即

19d0a2d59fbc3d3a0ffb37404a17363e.png

可以想象每一行计算的方法是一致的,只要搞定了一行数字的移动算法,那么整体4行就是把这个算法执行4遍即可。所以我们就完成了初步的降维,把4*4的计算,变成了4*1的计算。

那么接下来我们以第一行的数字的移动为例,介绍数字该怎么移动。

还看移动之前该矩阵的第一行 [2, 0, 2, 0], 向左移动时,需要把不为零的数字,一起向左移动,第一位的2不需要移动,第二位是0,不看,第三位的2,需要往左一位。那么我们换个思路,2向左移动,是不是可以看成是第二位的0向后移动,如果我们把第二位的0先删掉,[2, 0, 2, 0] 变成 [2, 2, 0], 然后再把0在最后添加进去,[2, 2, 0]变成[2, 2, 0, 0],这样2就向左移动了,神奇不神奇?

那我们完成了移动,怎么完成相同的数字相加呢

其实只要从行的第一位开始,比较它和它后边的那一位,如果一样,就把它乘以2,然后把它后边的那一位删掉,最后在行的末尾添加一个0,保证矩阵的shape一直是 4*4。

操作可以看下图

3e33acf4f154160941b64a026bd31b7b.png

ok,到这里完成了一行的向左移并相加的算法,那么四行的算法是一致的,也就完成了整个4*4矩阵左移并相加的操作。

那么问题来了,向右移该怎么做呢?

其实右移和左移的操作很相似,只在行的方位上移动数字,行与行之间没有什么直接操作,那么在右移时,先把每一行逆序一下,也就是 [2, 0, 2, 0]变成 [0, 2, 0, 2], 再做左移的操作,完成之后,把结果再逆序一下,是不是就ok了呢?

我们来看一下

1a16e42a6fa30b6cd323d21f3a757229.png

再问你一遍,神奇不神奇?

更神奇的还在后边呢,目前完成了左移和右移的操作,那么上移和下移呢?接下来我们要给这个游戏来第二次降维打击。

这里要用到一个我们学过的线代的知识,矩阵的转置,什么?你说不知道。ok,意思就是行转列,列转行的操作。

什么?还不知道?看图理解

45cb7933857399842be239e3f32ada67.png

这下清楚了吧。

细心观察之后,你会发现,原本矩阵数字上移的操作,经过转置之后就变成了左移的操作。又可以用我们之前的算法了。(鼓掌)

那么上移的操作就变成了 转置-->左移-->再转置

那么下移呢,聪明的你肯定已经猜出来了。

没错下移就是 转置-->右移-->再转置

ok,至此,2048游戏核心逻辑,分析完毕,来个总结:

1. 以左移为基础,把4行的操作看成1行的操作。

2. 左移的操作,先把0全部移到行的末尾

3. 然后从行第一位开始,判断与后一位是否相等且不等0,若相等该位乘以2,删除后一位,末尾添加0

4. 右移操作是 行逆序--左移--再逆序

5. 上移操作是 矩阵转置--左移--再转置

6. 下移操作是 矩阵转置--右移--再转置

下边开始撸代码,let's go。

22a1dcf9528d7b6e839abda7530feaff.png
92a1bd3a99b35d2176e29a43bac7d05a.png

这里只展示核心逻辑的代码实现,其余代码就不一一展示了,有兴趣的私信回复 2048 即可获取完整的源代码

效果展示:

d53efd6e7831d401114fc65d08706873.gif

好的,装x完毕,撤(完)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值
>