由于“公司”限定开发语言为JAVA,故本人暂且将.NET,C#搁置一边。

近日抽空编写连连看游戏(同时也是“公司”的任务)。过去曾写过一些桌面程序,如简易贪吃蛇,五子棋与黑白棋,至于连连看还是头一回写,有不妥之处,见笑见笑。

开发环境:jdk1.6    MyEclipse 6.5

第一版,数字连连看。

LLK

第二版(感谢网友提供素材)。

llk_demo

第三版,添加提示、洗牌功能。

llk_alpha 

 

 

 

现对核心算法进行分析。

一、消除算法。

两个方块排布方式有以下几种

A、直线型 如   *----*    **                *

                                                    *

B、L型 如     *----+      *

                            |       |

                            *      +--------------------*

C、C型或Z型 如  +----------------*               *------+

                         |                                                     |

                         |                                                     |

                          +-----------*                                  +-------*

对于给定两个方块,设坐标为P(x1, y1),Q(x2, y2)(约定x表示行,y表示列)

如何判定P、Q是否能消除呢?可分别判断直线型、L型、C/Z型。对于直线型,只需检查P、Q之间的点有无障碍;对于L型、C/Z型,只需多次调用直线型检测即可。

有网友推荐依照以下顺序查找路径,效率更高。

令R(x0, y0)为P、Q的中点,即x0=(x1+x2)/2;    y0=(y1+y2)/2

以此点开始,分别向上下左右四个方向分别查找,这样在最坏的情况下会穷举的每一点,对于m行n列,时间复杂度为O(m*n*max(m, n)),三次方级。
此算法易于理解。不过具体实现起来还要细心,写完之后还要进行单元测试,以免出错。

二、提示算法(查找可消除的一对方块)

由于连连看游戏数据规模不大。本人暂且采用复杂度为O(m^2*n^2)四次方级的穷举法(不够优雅)

public boolean findAvailable() {
        // x for row, y for col
        Point pt1 = new Point(0, 0);
        Point pt2 = (Point) pt1.clone();

        for (int i = 1; i < row + 1; i++) {
            for (int j = 1; j < col + 1; j++) {
                pt1.x = i;     pt1.y = j;
                for (int k = i; k < row + 1; k++) {
                    for (int l = 1; l < col + 1; l++) {
                        pt2.x = k;     pt2.y = l;
                        if (checkRoute(pt1.x, pt1.y, pt2.x, pt2.y)) {
                            找到一对,成功
                            return;
                        }
                    }
                }
            }
        }
        未找到

        return;
    }

实际程序运行流畅。

三、洗牌算法

随机交换任意两点,如此进行多次,即可洗开。

public void shuffle() {
    // clear tip blocks
    tip1 = tip2 = null;
    for (int i = 1; i < row + 1; i++) {
        for (int j = 1; j < col + 1; j++) {
            int newRow = rnd.nextInt(row) + 1;
            int newCol = rnd.nextInt(col) + 1;
            int temp = array[i][j];
            array[i][j] = array[newRow][newCol];
            array[newRow][newCol] = temp;
        }
    }
    findAvailable();
    if (!isExistAvailable()) {
        shuffle();
    }
}

至于UI、绘图、声效代码,本人觉得没必要贴出来,实在是没什么意思。

第二期预计会在10月上中旬完成,届时不仅丰富的单机关卡,而且还会有局域网连机对战功能。

posted on 2010-09-18 18:04  Achtung  阅读(519)  评论(0编辑  收藏  举报