由于“公司”限定开发语言为JAVA,故本人暂且将.NET,C#搁置一边。
近日抽空编写连连看游戏(同时也是“公司”的任务)。过去曾写过一些桌面程序,如简易贪吃蛇,五子棋与黑白棋,至于连连看还是头一回写,有不妥之处,见笑见笑。
开发环境:jdk1.6 MyEclipse 6.5
第一版,数字连连看。
第二版(感谢网友提供素材)。
第三版,添加提示、洗牌功能。
现对核心算法进行分析。
一、消除算法。
两个方块排布方式有以下几种
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月上中旬完成,届时不仅丰富的单机关卡,而且还会有局域网连机对战功能。