“连”的魅力──热门小游戏《连连看》制作指南
软件世界
前言:《连连看》是一个不错的小游戏,在繁忙的工作学习之余,玩上一把,令人身心愉快。在玩过这个游戏后大家是否也想过自己做一个简单的《连连看》,并把自己感兴趣的图片放上去,看着图片消失在鼠标之下,是否更有成就感呢?
这个游戏一般是在一个A×B的矩阵图里,里面每一个小图案各有不同,游戏规则是通过连线,在不经过别的图案的情况下把相同的图案连起来,且连线只允许转两道弯,并使相同图案消除(如图1)。
在玩过《连连看》后,大家会发现,要想做出程序,首先要找到可靠的算法,能让电脑判断出我们选择的图案是否能连上,以及那条折线是否符合规则。那么如何实现呢?这就需要能让电脑进行简单的“寻路”。在《连连看》中的寻路并不是太复杂,所要绕开的障碍物也都是在一个矩阵中事先能被预知的,而其运行轨迹也是被规定成横竖2种。因此,平时游戏中的法则“人类总是喜欢走直线”也要被改成只能走经线和纬线了。
张艺谋的电影《英雄》里,残剑通过书法领悟出了一套剑招。而在这次的《连连看》程序设计中,我们也希望通过文字领悟到一种算法。
“井”中蕴涵的解法
由于路径已经被规定成了横竖2种,而且我们都知道书法之中的笔画也无非是横竖撇捺折,现在来看看哪个字能悟出这套“独孤剑法”。
既然只能选横竖两种笔画,马上让人想到了“十”字,但“十”字毕竟变数太少,如果将十字的横竖两笔分别变成两横两竖,就能得到“口”和“井”,而更合适的非“井”字不可。这个字变数很多,而且其中还包含了“口”字,它笔画上的4个交点也正代表了《连连看》中两个相同图案可能的位置。下面我们就来看看如何利用它。
我们把“井”字笔画交叉的4个点中任意两点看成《连连看》中的两个相同图案的话,不难发现,你在游戏中所能走的轨迹几乎完全包含在这个字里了。你再把井字的那两组平行线看成是长长的铁轨,既然是铁轨,当然要有枕木啦。加上间距相等且平行的枕木(如图2),再取那些间距相等的截点作为《连连看》中其他可能出现障碍的图案,则可能的路径形式就那么几种。
在实际《连连看》的寻路中,当众多的连线中有一条满足上面的那些截点上的图案在前面都已经被消除掉的条件时,就能说明这条路是通的,那么这两个相同的图案就能被消除掉。
基本解法
在实际编程中,比如对一个2×2的矩阵,其中每一个值代表一种图案,相同图案采用相同的值,那么在其外围加上一圈全0的数。当有相同图案能消掉,消失后的图案位置用0标记(如表1)。而在寻找路径时,只有全0的路径才能连通,如果有非0的数存在,即表示在路径上有别的图案还存在,那这条线路就不能通过。
在具体编程时,假设开始图案为下面的矩阵,在4×3的矩阵图中有3种不同图案。先在外层套上一圈0(如表2)
如果把表2中第二行第五列和第四行第三列的两个3作为研究对象,先标记其为X、Y,然后对应穿过这两点画出4条线:AC、BD、EG、FH,组成一个“井”字(表3)。如果要判断从X到Y是否存在无障碍的连线,可以分两步来做:即先看AC、BD之间是否存在通路,再看EG、FH之间。
两个过程原理相同,那么就先单独来看竖直方向的ABCD组成的区域是否存在通路,可以采用最直观的遍历方法,即循环从最上的AB两点开始依次向下取点到最下的CD,每个循环体中分别判断所取两点,分别再判断两点之间和两点分别到XY的连线中是否有障碍。
如取AB两点为例,通过循环判断AB之间的坐标中的点的值是否都为0,并判断AY连线和BX连线中的点是否都为0,如果只要存在一个不为0的点就跳出循环,就再以AB下面的点为基础,分别按上面的方法来做。
简化算法
前面讲的遍历算法虽然比较直观,但计算量较大。比如AY中如果存在一个不为0的点的话,却需要把Y上的每对点都按一定的算法判断,这显然不是很合理。现在就来简化这套算法。即不从AB两个最高点来开始判断,而是以XY两个相同图案为基本点开始。具体原理如下:
分别对X、Y向上向下的点的坐标进行记录,如:Y向上的一个点,先判断它的值是否为0,若为0,记录这个点的坐标。并继续向上看Y上的第2个点,直到达到A或发现有不为0的点为止,而转为向下找寻能为0的点。X的竖直方向也采用相同方法。这里需要注意的是X、Y的坐标也要记录下来,姑且把X、Y当成0来看,这样就能得到一组通过X、Y竖直方向连续为0的点的坐标。
完整的程序及代码的下载地址:http://www.cpcw.com/41/game.rar。






