3.3.2 获取周围的方格
根据上面的介绍,我们已经知道open_block()函数是用来打开方块的,但是怎样表示方块被打开了呢?其实从图2.1可以看到,我们事先准备了多张图片来表示打开的方块,即minesweep_number0.png至minesweep_number8.png文件名所对应的图片。你会发现,除了minesweep_number0.png图片之外,其他8张图片分别显示了1至8的数字,这表示什么意思呢?
事实上,按照扫雷游戏的规则,如果打开的方块没有埋地雷,则要将它周围各方块的地雷总数显示出来。而资源图片中的数字正是用于表示不同的地雷数量。需要明确一点,所谓方块的周围,不仅是指上下左右相邻的四个方块,还包含斜向相邻的四个方块,因此总共是8个方块,如图3.4所示。当方块被打开时,若它的周围没有地雷,则显示minesweep_number0.png图片,否则根据其周围的地雷数量来显示相应的数字图片。
图3.4 方块周围示意图
看来问题的关键在于,首先要弄清楚某方格周围相邻的是哪些其他方格,这样才便于执行进一步的判断。为此,不妨再专门定义一个get_neighbours()函数,用来获取指定方块周围的其他方块,并以列表的形式将它们返回。因为地雷仅埋藏在未曾打开的方块中,所以实际上只需获取没有打开的方块即可。代码如下所示:
可以看到,get_neighbours()函数传入一个参数bk,表示某个指定的方块。然后在函数体内执行for循环,来遍历列表blocks中的各个方块。对于某个方块block,若它已经打开了,程序便执行continue语句跳过本次循环;否则,程序将分别从8个不同的方向来检查block与指定方块bk的位置关系。由于相邻方块的坐标仅仅相差SIZE值所代表的距离,所以程序用bk的横坐标或纵坐标对SIZE进行简单的加减运算,就可以确定它在某个方向上相邻的其他方块。
上述代码中if语句的条件很长,因此使用反斜杠“\”将其分为几行来显示,其中的8个关系表达式通过逻辑运算符or相连,表示只要列表blocks中的某个方块符合8个条件之一,则可判定它和指定的方块bk相邻。对于满足条件的方块,程序将其加入另一个列表nblocks,并在函数的末尾调用return语句将nblocks作为返回值提交。