• J2SE连连看


    由于“公司”限定开发语言为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月上中旬完成,届时不仅丰富的单机关卡,而且还会有局域网连机对战功能。

  • 相关阅读:
    POJ 3356 水LCS
    POJ 2250 (LCS,经典输出LCS序列 dfs)
    POJ 1080( LCS变形)
    整数划分问题之最大乘积
    进程调度之FCFS算法(先来先运行算法)
    c模拟银行家资源分配算法
    c模拟内存分配算法(首次适应算法,最佳适应算法,最坏适应算法)
    HDU 2602 Bone Collector(经典01背包问题)
    NYOJ 44 字串和 (最大字串和 线性dp)
    匈牙利游戏(codevs 1269)
  • 原文地址:https://www.cnblogs.com/daxia319/p/1830309.html
Copyright © 2020-2023  润新知