俄罗斯方块游戏可以说是一个非常古老的游戏了,而游戏 AI 这个话题也已经被人反复研究多次,特别是最近几年机器学习和深度学习大火特火,二者的结合显然不言而喻。不过在早期,貌似即使最先进的算法也无法超过专业人员在没有时间压力下的水平。

不过目前我随便在网上搜一搜,发现在 2013 年的时候,就有算法可以达到5千万级别的消行量,显然这已经比一般人强得多了,前提是你能玩那么久……😂

算法列表

咱们今天不讲复杂的算法,而是讲一种普通 AI 算法的实现过程,该算法是 Pierre Dellacherie 的改进版,被原作者称作 El-Tetris,原始出处如下:El-Tetris – An Improvement on Pierre Dellacherie’s Algorithm

1. 传统 AI 的逻辑

事实上不要一听到 AI 就感觉很高大上,普通的 AI 算法是非常简单的,就是枚举所有可能发生的场景,根据一些特征对这些场景打分,分数越高(越低)就越好,El-Tetris 就是这套思路。这种传统的 AI 算法关键点在于如何寻找这些特征点,以及如何确定这些特征点的比例系数。

假设俄罗斯方块在游戏的过程中可以抽象出几个特征点,分别用 $x_0、x_1、x_2 ... x_n $ 来表示, 而这些特征在游戏中所占的重要比例是不同的,假设它们所占的比例分别是 ${\beta_0}、{\beta_1}、{\beta_2} ... {\beta_n}$ 这时候我们可以用多元线性回归的方式将它们组织起来:
$$
y = {\beta_0}x_0 + {\beta_1}x_1 + {\beta_2}x_2 + {\beta_3}x_3 ... {\beta_n}x_n
$$
这里有一点需要说明,这些 $ x $ 变量之间应该是相互独立的,相关性不能太强。举个例子,假设 $ x_0 $ 代表方块落下后的容器高度,$ x_1 $ 代表方块落下后距离容器上方的高度,这两个变量就可以看作强相关,因为你可以通过它们中的任何一个推算出另一个,也就是说二者其实在式子中是可以合并的,既然可以合并,显然没有必要用两个变量来表示这个特征。

在这个式子中,我们可以用向量 $X$ 表示所有的特征点,即 $(x_0,x_1,x_2, ..., x_n)$,这些特征点是可以根据当前方块的状态推导出来,可以算作已知条件。对应的向量 $({\beta_0}, {\beta_1}, {\beta_2} ... {\beta_n})$ 也可以用 ${\beta}$ 表示,这个 ${\beta}$ 是一个经验值,是使用数学方法或者机器学习方法等手段推算出的经验值,这个值也是已知的。所以最后,我们总是可以通过向量 $X$ 和向量 ${\beta}$ 算出最后的结果 $y$,总结即:
$$
y = {\beta}X
$$

2. El-Tetris 算法的特征

看过上面的公式,你可能仍然一脸懵逼,但是没关系,理论说起来复杂的一逼,但是实战起来,你就会发现简单的难以置信,先让我们看一看上面的向量 $X$ 是如何计算的。在 El-Tetris 算法中,向量 $X$ 是一个六维向量,每个分量代表一个特征点,下面我们就分别介绍一下它们的具体含义。

首先第一个特征点是 Landing Height。表示当前方块放置之后的高度。这个高度的计算方法是使用当前容器内方块的高度加上当前下落方块的一半。

第二个特征点是 Rows eliminated。表示当前方块落下后被消减的行数。

第三个特征点是 Row Transitions。代表容器中水平方向上变换的次数。举个例子:

水平变换图示

看图上的最后一行左边数第三列是个洞,所以第二列到第三列这种从有方块到无方块的变化算作一次行变换。对应的第三列到第四列从无方块到有方块也算作一次行变化,所以最后一行的行变换可以算作 2。而我们最终要求的是所有行的变化次数,从上到下一次可得:

2 + 4 + 2 + 2 + 2 + 2 + 2

最后在上图中的情况,第三个特征点最后求得的值是 16。这里注意从上到下第一行是 2 的原因在于,默认情况下,图的左边越界的部分和图的右边越界的部分算作有方块的情况,所以第一行是从有到无到有,所以记作 2 。

第四个特征点是 Column Transitions。和第三个特征点类似,只不过这一次算的是列变换而已。

第五个特征点是 Number of Holes。代表图中空洞的个数。如下图所示,空洞的个数是 6 。

空洞示例

第六个特征点是 Well Sums。表示 “井” 深的连加和。一个 “井” 代表左右都有方块,而中间为空洞的形状,例如下图中可以看作两个 “井”:

井字演示

其中左边的 “井” 深为 2,右边的 “井” 深为 1。所以最后的结果:

(1 + 2) + 1

等于 4。

3. El-Tetris 算法的权重

知道如何计算特征向量 $ X $ 之后,我们需要知道如何获得向量 $ {\beta} $ 。前面我们说到向量 ${\beta} $ 表示特征值的重要比例,这个比例一般被称为权重,说白了就是有多重要,具体指的就是这些分量对应的特征分量的重要程度。

在原文中,这些参数是作者通过粒子群优化算法计算出来的,这些值最后都是常量:

Feature Weight
Landing Height -4.500158825082766
Rows eliminated 3.4181268101392694
Row Transitions -3.2178882868487753
Column Transitions -9.348695305445199
Number of Holes -7.899265427351652
Well Sums -3.3855972247263626

我们这里直接使用即可。通过前面的公式,输入 $X$ 、${\beta}$ 就可以求出当前状态下的一个综合得分,在 El-Tetris 中得到的分数越大,代表方块下落的位置越好。