利用电脑玩Android版“天天连萌”刷高分(三)——连连看消除搜索
差点忘了写接下来的这两篇博客了,这篇如果接不上上一篇,请勿见怪啊,因为我自己都忘了。
上两篇分别提到了截图和图像识别,接下来这一篇是说一下连连看的消除算法。
这个算法看似很厉害,其实我在这里采用的是很笨拙的方法,就是枚举。
在上一篇已经连游戏里的方块转换成一个二维数组,所以就通过一个两层循环,遍历每一个元素,看能不能跟其他元素消除,代码如下:
for (int i = 1; i < CODE_ROW - 1; i++) {for (int j = 1; j < CODE_COL - 1; j++) {if (imageCodes[i][j] != 0) {Point point = search(i, j);if (point == null) {continue;}touch(new Point(i, j));touch(point);imageCodes[i][j] = 0;imageCodes[point.x][point.y] = 0;anyClear = true;System.out.println(String.format("消除 %d:%d %d:%d", i, j, point.x, point.y));}}/** * 搜索,返回最优点。 * * @return */public Point search(int x, int y) {return LianlianKan.twoCornerSearch(imageCodes, x, y);}/** * 连连看搜索算法。 * * @author Geek_Soledad */public static class LianlianKan {/** * 水平搜索 * * @param datas * 数组 * @param row * 对比数值所在的行 * @param col * 对比数值所在的列 * @param atRow * 进行水平搜索时所在的行 * @return */private static Point moveHorizon(int[][] datas, int row, int col, int atRow, int atCol) {// 再拐左for (int k = atCol - 1; k >= 1; k--) {if (datas[atRow][k] == datas[row][col]) {return new Point(atRow, k);} else if (datas[atRow][k] != 0) {break;}}// 再拐右for (int k = atCol + 1; k < CODE_COL - 1; k++) {if (datas[atRow][k] == datas[row][col]) {return new Point(atRow, k);} else if (datas[atRow][k] != 0) {break;}}return null;}/** * 竖直搜索 * * @param datas * 数组 * @param row * 对比数值所在的行 * @param col * 对比数值所在的列 * @param atCol * 进行水平搜索时所在的列 * @return */private static Point movePortrait(int[][] datas, int row, int col, int atRow, int atCol) {// 再拐上for (int k = atCol - 1; k >= 1; k--) {if (datas[k][atCol] == datas[row][col]) {return new Point(k, atCol);} else if (datas[k][atCol] != 0) {break;}}// 再拐下for (int k = atCol + 1; k < CODE_ROW - 1; k++) {if (datas[k][atCol] == datas[row][col]) {return new Point(k, atCol);} else if (datas[k][atCol] != 0) {break;}}return null;}/** * 两个角搜索 * * @param datas * 数组 * @param x * 纵坐标 * @param y * 横坐标 * @return */public static Point twoCornerSearch(int[][] datas, int x, int y) {// 向左进行搜索for (int i = y - 1; i >= 0; i--) {// 向左进行直线搜索if (datas[x][i] == datas[x][y]) {return new Point(x, i);} else if (datas[x][i] != 0) {break;}// 向左,然后拐上进行直角搜索for (int j = x - 1; j >= 0; j--) {if (datas[j][i] == datas[x][y]) {return new Point(j, i);} else if (datas[j][i] != 0) {break;}// 向左,拐上,再水平搜索Point point = moveHorizon(datas, x, y, j, i);if (point != null) {return point;}}// 向左,然后拐下进行直角搜索for (int j = x + 1; j < CODE_ROW; j++) {if (datas[j][i] == datas[x][y]) {return new Point(j, i);} else if (datas[j][i] != 0) {break;}// 向左,拐下,再水平搜索Point point = moveHorizon(datas, x, y, j, i);if (point != null) {return point;}}}// 横向往右搜索for (int i = y + 1, length = CODE_COL; i < length; i++) {// 向右直线搜索if (datas[x][i] == datas[x][y]) {return new Point(x, i);} else if (datas[x][i] != 0) {break;}// 向右,然后拐上进行直角搜索。for (int j = x - 1; j >= 0; j--) {if (datas[j][i] == datas[x][y]) {return new Point(j, i);} else if (datas[j][i] != 0) {break;}// 向右,拐上,再水平搜索Point point = moveHorizon(datas, x, y, j, i);if (point != null) {return point;}}// 向右,然后拐下进行直角搜索for (int j = x + 1; j < CODE_ROW; j++) {if (datas[j][i] == datas[x][y]) {return new Point(j, i);} else if (datas[j][i] != 0) {break;}// 向右,拐下,再水平搜索。Point point = moveHorizon(datas, x, y, j, i);if (point != null) {return point;}}}// 纵向往上搜索for (int i = x - 1; i >= 0; i--) {if (datas[i][y] == datas[x][y]) {return new Point(i, y);} else if (datas[i][y] != 0) {break;}// 向上,然后拐左进行直角搜索。for (int j = y - 1; j >= 0; j--) {if (datas[i][j] == datas[x][y]) {return new Point(i, j);} else if (datas[i][j] != 0) {break;}// 向上,拐左,再竖直搜索Point point = movePortrait(datas, x, y, i, j);if (point != null) {return point;}}// 向上,然后拐右进行直角搜索for (int j = y + 1; j < CODE_COL; j++) {if (datas[i][j] == datas[x][y]) {return new Point(i, j);} else if (datas[i][j] != 0) {break;}// 向上,拐右,再竖直搜索Point point = movePortrait(datas, x, y, i, j);if (point != null) {return point;}}}// 纵向往下搜索for (int i = x + 1, length = CODE_ROW; i < length; i++) {if (datas[i][y] == datas[x][y]) {return new Point(i, y);} else if (datas[i][y] != 0) {break;}// 向下,然后拐左进行直角搜索。for (int j = y - 1; j >= 0; j--) {if (datas[i][j] == datas[x][y]) {return new Point(i, j);} else if (datas[i][j] != 0) {break;}// 向下,拐右,再竖直搜索Point point = movePortrait(datas, x, y, i, j);if (point != null) {return point;}}// 向下,然后拐右进行直角搜索for (int j = y + 1; j < CODE_COL; j++) {if (datas[i][j] == datas[x][y]) {return new Point(i, j);} else if (datas[i][j] != 0) {break;}// 向下,拐右,再竖直搜索Point point = movePortrait(datas, x, y, i, j);if (point != null) {return point;}}}return null;}}public boolean startSearch(BufferedImage image) throws InterruptedException {boolean anyClear = false;do {anyClear = false;for (int i = 1; i < CODE_ROW - 1; i++) {for (int j = 1; j < CODE_COL - 1; j++) {if (imageCodes[i][j] != 0) {Point point = search(i, j);if (point == null) {continue;}touch(new Point(i, j));touch(point);imageCodes[i][j] = 0;imageCodes[point.x][point.y] = 0;anyClear = true;System.out.println(String.format("消除 %d:%d %d:%d", i, j, point.x, point.y));}}}} while (anyClear && !isEmpty());return anyClear;}