「兔了个兔」究极简化版多彩兔消消乐

493 阅读3分钟

我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛

创作缘由

活动一月五号就开始了,一直勾的我心痒痒,想参加活动搞点花里胡哨的震惊四座,奈何自己前端水平实在有限,CSS样式我看着就头疼,不知道怎么调出来炫酷的花样,只会纯HTML拼接。左思右想,看到评论区里运营同学说 “鸡兔同笼” 都算在里面,再加上这几天看着不少套着兔子外壳的技术文,终于想出来了一些头绪。 炫酷吊炸天的特效效果我做不出来,但是借着兔子的外壳搞点别的我还是很会的。于是想到了大一时候做过的消消乐游戏,用《三体》中的话来说,我这就是增援未来。 可惜那时的源码已经找不到了,不过凭借我的智慧迅速做出来一套简易的模型还是很容易的。

创作思路

三消类游戏的底层简单的来说就是一个二维数组,里面放了不同类型的元素,如果有接连几分相同的元素就计数或者记分增加结果,主体结构大纲确定下来后,剩下的就是逐步细分,一步步填坑就结束了。

填坑之路

初始化

初始化比较简单,搞个随机数先把棋盘遍历填充好,先不考虑去重的事情。如果这个时候就有满足条件的三连区域,就当给用户送福利积分了。

public static int[][] init(int x, int y) {
    int[][] arr = new int[x][y];
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < y; j++) {
            arr[i][j] = getRabbit();
        }
    }
    return arr;
}
public static int getRabbit() {
    return (int) (Math.random() * n);
}

打印棋盘

棋盘初始化后,要展示出来,这样才能有交互。用一个map记录来转换

public static void printBoard() {
    Map<Integer, String> desc = descMap();
    System.out.println("~~~~~~兔了个兔~~~~~~");
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr[0].length; j++) {
            System.out.print(desc.get(arr[i][j]) + " ");
        }
        System.out.println();
    }
    System.out.println("~~~~~~兔了个兔~~~~~~");
}

public static void printScore() {
    System.out.println("当前兔分:" + score);
}

public static Map<Integer, String> descMap() {
    Map<Integer, String> descMap = new HashMap<>();
    descMap.put(0, "红兔");
    descMap.put(1, "橙兔");
    descMap.put(2, "黄兔");
    descMap.put(3, "绿兔");
    descMap.put(4, "蓝兔");
    descMap.put(5, "靛兔");
    descMap.put(6, "紫兔");
    descMap.put(7, "黑兔");
    descMap.put(8, "白兔");
    descMap.put(9, "青兔");
    descMap.put(10, "褐兔");
    return descMap;
}

交换计数

这一步是最复杂的一步,因为第一步成功之后,后续还会可能产生消除的效果,怎么解决连续撞击是个问题。

public static int count(int x, int y) {
    exchange(x, y, x - 1, y);
    int c1 = scan();
    if (c1 > 0) {
        return c1;
    } else {
        exchange(x, y, x - 1, y);
    }
    exchange(x, y, x + 1, y);
    int c2 = scan();
    if (c2 > 0) {
        return c2;
    } else {
        exchange(x, y, x + 1, y);
    }
    exchange(x, y, x, y + 1);
    int c3 = scan();
    if (c3 > 0) {
        return c3;
    } else {
        exchange(x, y, x, y + 1);
    }
    exchange(x, y, x, y - 1);
    int c4 = scan();
    if (c4 > 0) {
        return c4;
    } else {
        exchange(x, y, x, y - 1);
    }
    return 0;
}

public static void exchange(int x1, int y1, int x2, int y2) {
    int temp = arr[x1][y1];
    arr[x1][y1] = arr[x2][y2];
    arr[x2][y2] = temp;
}

public static int scan() {
    int s = 0;
    for (int i = 0; i < arr.length; i++) {
        for (int j = 0; j < arr[0].length; j++) {
            s += test(i, j);
            if (s > 0) {
                return s;
            }
        }
    }
    return 0;
}

public static int test(int x, int y) {
    int r = 0, l = 0, u = 0, d = 0;
    for (int i = x - 1; i >= 0; i--) {
        if (arr[i][y] == arr[x][y]) {
            l++;
            arr[i][y] = getRabbit();
        } else {
            break;
        }
    }
    for (int i = x + 1; i < arr.length; i++) {
        if (arr[i][y] == arr[x][y]) {
            r++;
            arr[i][y] = getRabbit();
        } else {
            break;
        }
    }
    for (int i = y - 1; i >= 0; i--) {
        if (arr[x][i] == arr[x][y]) {
            u++;
            arr[x][i] = getRabbit();
        } else {
            break;
        }
    }
    for (int i = y + 1; i < arr.length; i++) {
        if (arr[i][y] == arr[x][y]) {
            d++;
            arr[i][y] = getRabbit();
        } else {
            break;
        }
    }
    int h = (r + l) >= 3 ? (r + l) : 0;
    int v = (u + d) >= 3 ? (u + d) : 0;
    return h + v;
}

拼接碎片

各个步骤需要的碎片都好了,下面就是拼接到一起了。

public static void main(String[] args) {
    arr = init(10, 10);
    Scanner sc = new Scanner(System.in);
    while (true) {
        printBoard();
        printScore();
        int cnt = scan();
        while (cnt != 0) {
            printBoard();
            printScore();
            score += cnt;
            cnt = scan();
        }
        System.out.println("输入可以消除的横坐标:");
        int x = sc.nextInt();
        System.out.println("输入可以消除的纵坐标:");
        int y = sc.nextInt();
        int cnt_score = count(x, y);
        if (cnt_score > 0) {
            score += cnt_score;
        }
    }
}

成果

这是最后做出来的成果,欢迎大家来玩。