红魔咖啡馆

头发越掉越多,头发越掉越少

0%

【CS61B】Project0-2048

Project0 - 2048

Hard Mode

项目结构

1
2
3
4
5
6
7
8
9
10
proj0_hardmode
├── game2048logic
|   ├── GameLogic.java
|   ├── MatrixUtils.java
├── game2048rendering
    ├── Board.java
    ... (some other files) ...
    ├── Main.java
    ├── Side.java
    ├── Tile.java

分为了两个包:负责逻辑与负责渲染的,主要更改在负责逻辑的包中

Task1:游戏原理

2048的核心规则为Tilting,项目需要主要实现该功能

当两个方格发生融合时,遵循以下规则

  1. 两相同值的方格融合为一个,数值翻倍

  2. 由合并产生的新方块在该次移动中不会再次合并。例如,当[X, 2, 2, 4](X 代表空格)向左移动时,结果应为[4, 4, X, X]而非[8, X, X, X]。这是因为最左侧的 4 已参与过合并,故不应二次合并

  3. 当融合方向上有三个相邻同值方块时,仅该方向最前方的两个方块会合并,第三个方块保不变。例如[X, 2, 2, 2]左移后应为[4, 2, X, X],而非[2, 4, X, X]。

  4. 推论:若有四个相邻同值方块,则会合并出两个同值方块,如[2, 2, 2, 2]左移后应该为[4, 4, X, X],但合并出的两个同值方块不会合并

Task2:实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public static void compress(int[][] board, int c){
    int n = board.length;
    int[] comp = new int[n];
    int index = 0;
    for (int[] ints : board) {
        if (ints[c] != 0) {
            comp[index++] = ints[c];
        }
    }
    for (int i = 0; i<n; i++){
        board[i][c] = comp[i];
    }
}
public static void merge(int[][] board, int c){
    int n = board.length;
    for (int i = 0; i<n-1; i++){
        if(board[i][c]!=0 && board[i][c]==board[i+1][c]){
            board[i][c] *= 2;
            board[i+1][c] = 0;
            i++;

        }
    }

}
public static void moveColumn(int[][] board, int c){
   compress(board, c);
   merge(board, c);
   compress(board, c);


}
public static void moveUp(int[][] board){
    for (int i = 0; i<board.length; i++){
        moveColumn(board, i);
    }
}

compress函数用于压缩,即将所有数都移动到顶上,而不进行合并

merge函数用于将相邻的数进行合并

每次移动一列,然后循环处理每列,处理一列时移动后合并,合并后可能会出现中间合并剩下的空位置,需要再进行压缩