连连看算法分析

临近期末,各种大作业要交,都怪前段时间一直太懒,最近才开始来做。今天看了一下安卓的作业,要求做一个连连看的小游戏,立马动手了。

连连看相信大家都玩过,也知道游戏规则:随机生成游戏的小图标,如果相同的两个可以通过一至三段直线连接起来,便可以消去,如图所示

具体的代码我就不给出,这里只是说一下一些核心的代码。

  1. 生成随机图标
我的方法跟其他的可能有些雷同,就是建立一个 (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;
	}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值