临近期末,各种大作业要交,都怪前段时间一直太懒,最近才开始来做。今天看了一下安卓的作业,要求做一个连连看的小游戏,立马动手了。
连连看相信大家都玩过,也知道游戏规则:随机生成游戏的小图标,如果相同的两个可以通过一至三段直线连接起来,便可以消去,如图所示
具体的代码我就不给出,这里只是说一下一些核心的代码。
- 生成随机图标
我的方法跟其他的可能有些雷同,就是建立一个 (n+1)(m+1) 的二维数组,其中 n m 分别是图标的列数和行数;接着生成 1到N (N指图标的种类) 的随机数,每生成一个往数组里添加两个值,这样能够保证游戏最后不会出现单个图标的情况;然后再将数组打乱,这样看起来就是随机分布了。
// 对 Map 进行第一步填充,此时只填充数字
private void FullMap() {
//GameInfo.ROW GameInfo.COLLUMN 静态全局变量,分别指图标的行数和列数
for (int i = 1; i <= GameInfo.ROW / 2; i++) {
for (int j = 1; j < GameInfo.COLUMN + 1; j++) {
//GameInfo.ICONNUM 图标的种类
int temp = (int) (Math.random() * GameInfo.ICONNUM + 1);
this.MapItems[i][j] = temp;
this.MapItems[i + GameInfo.ROW / 2][j] = temp;
}
}
}
// 对 Map 进行随机化,二维数组最外层的都为0,表示没有图标,其他的随机填充
private void RandomMap() {
int temp;
for (int i = 1; i < GameInfo.ROW + 1; i++) {
for (int j = 1; j < GameInfo.COLUMN + 1; j++) {
int x = (int) (Math.random() * GameInfo.ROW + 1);
int y = (int) (Math.random() * GameInfo.COLUMN + 1);
temp = this.MapItems[i][j];
this.MapItems[i][j] = this.MapItems[x][y];
this.MapItems[x][y] = temp;
}
}
}
上面提到的,我们图标是 n*m,为什么数组要 (n+1)*(m+1)呢?这是为了在连线的时候,外部的边缘也可以连。
2. 消去算法
如上图所示,我们只要写出直线连接的算法,就可以根据它得出其他两个的算法了
private static boolean XTwoPointsLink(int[][] map, int y1, int y2, int x) {
int tempy1,tempy2;
tempy1 = y1>y2?y2:y1;
tempy2 = y1>y2?y1:y2;
if (y2 - y1 == 1) {
return true;
} else {
for (int i = tempy1 + 1; i <= tempy2; i++) {
if (i == tempy2) {
return true;
}
if (map[x][i] != 0) {
return false;
}
}
}
return false;
}
//垂直两点(一段直线)之间能否连接
private static boolean YTwoPointsLink(int[][] map, int x1, int x2, int y) {
// Log.i("TwoPointsLink", "" + x1 + " " + x2 + " " + y);
int tempx1,tempx2;
tempx1 = x1>x2?x2:x1;
tempx2 = x1>x2?x1:x2;
if (tempx2 - tempx1 == 1) {
return true;
} else {
for (int i = tempx1 + 1; i <= tempx2; i++) {
if (i == tempx2) {
return true;
}
if (map[i][y] != 0) {
return false;
}
}
}
return false;
}
//三点(两段直线)之间是否能连接
private static boolean ThreePointsLink(int[][] map, int x1, int y1, int x2,
int y2) {
if (map[x2][y1] == 0 && YTwoPointsLink(map, x1, x2, y1)
&& XTwoPointsLink(map, y1, y2, x2)) {
return true;
} else {
if (map[x1][y2] == 0 && YTwoPointsLink(map, x1, x2, y2)
&& XTwoPointsLink(map, y1, y2, x1)) {
return true;
}
}
return false;
}
//四点(三段直线)之间能否连接
private static boolean FourPointsLink(int[][] map, int x1, int y1, int x2,
int y2) {
for (int i = 0; i < map.length; i++) {
if (i != x1 && i != x2) {
if (map[i][y1] == 0 && map[i][y2] == 0
&& YTwoPointsLink(map, i, x1, y1)
&& YTwoPointsLink(map, i, x2, y2)
&& XTwoPointsLink(map, y1, y2, i)) {
return true;
}
}
}
for (int j = 0; j < map[0].length; j++) {
if (j != y1 && j != y2) {
if (map[x1][j] == 0 && map[x2][j] == 0
&& XTwoPointsLink(map, y1, j, x1)
&& XTwoPointsLink(map, y2, j, x2)
&& YTwoPointsLink(map, x1, x2, j)) {
return true;
}
}
}
return false;
}