2

我正在实现一个俄罗斯方块游戏,通常棋子的放置效果很好。然而,有时在放置棋子时,表示游戏状态的 2d 数组的一整列会被填满。例如:

由此:

|           |
|           |
|           |
|           |
|           |
|           |
|           |
|           |
|           |
|           |
|           |
|           |
|           |
|           |
|           |
|           |
|           |
|           |
|  X XX   XX|

对此:

|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|       X   |
|  X XXXXXXX|

其中 X 是俄罗斯方块。

通过检查各个点的块总数,我将其缩小到本节:

int total = 0;
for (int i = 0; i < world.length - 1; i++) {
    for (int j = 0; j < width; j++) {
        if (world[i][j]) {
            total++;
        }
    }
}
System.out.println("total1 = " + total);

// add piece into environment
for (int i = 0; i < pieces[p.piece - 1][p.rotation].length; i++) {
    for (int j = 0; j < pieces[p.piece - 1][p.rotation][i].length; j++) {
        // if there is a piece block here
        if (pieces[p.piece - 1][p.rotation][i][j]) {
            world[depth + i][p.position + j] = true;
            System.out.println((depth+i) + ", " + (p.position + j));
        }
    }
}
total = 0;
for (int i = 0; i < world.length - 1; i++) {
    for (int j = 0; j < width; j++) {
        if (world[i][j]) {
            total++;
        }
    }
}
System.out.println("total2 = " + total);

这是上一个示例的输出:

total1 = 5
17, 7
18, 6
18, 7
18, 8
total2 = 26

如您所见,世界数组唯一可以更新的点仅更改了 4 次,但之后,世界总数大幅增长。

我无法弄清楚为什么会发生这种情况。

哦,pieces 数组只是一个恒定的 4d 数组

编辑:

经过大量测试后,我认为这与我删除行的代码有关,它是在前面的代码之后:

boolean fullRow;
    latestCleared = 0;
    // check for completed lines
    // for each row
    for (int i = 0; i < world.length - 1; i++) {
        fullRow = true;
        for (int j = 0; j < width; j++) {
            if (!world[i][j]) {
                fullRow = false;
                break;
            }
        }
        if (fullRow) {
            for (int j = 0; j < width; j++) {
                world[i][j] = false;
            }
            for (int k = i; k > 0; k--) {
            world[k] = world[k - 1];
            }

        }
        latestCleared++;
    }

当我注释掉: for (int k = i; k > 0; k--) { world[k] = world[k - 1];

问题不会发生。只是不明白这会如何影响它。

此外,无论输入哪种移动组合,它都会发生相同数量的迭代。

4

1 回答 1

3

在你的代码的抑制部分,你有一个问题:

for (int k = i; k > 0; k++) {
    world[k] = world[k - 1];
}

你在那里做的是复制行的引用,而不是复制前一行中包含的值。您应该执行以下操作:

for (int k = i; k > 0; k++) {
    for (int j = 0; j < width; j++) {
        world[k][j] = world[k - 1][j];
    }
}
// Adding a new blank row on the top of the world
for (int j = 0; j < width; j++) {
    world[0][j] = false;
}

此代码将复制前一行中包含的行值(而不是行的引用)。

只是为了清理您的代码,您可以抑制该部分:

for (int j = 0; j < width; j++) {
    world[i][j] = false;
}

因为您将在这一行的值中复制前一行的值。

我想在您的示例中,您在添加产生问题的部分之前抑制了行。由于行的引用是完全不可预测的,它会给你带来不可预测的行为。

我希望这个简单的修改能解决整个问题,但是如果你有类似的代码,请检查你的项目。

编辑:我很确定你所有的行,除了最后一行,实际上都指向同一个引用。因此,当您在第 2 行中添加至少包含一个元素的作品时,该元素将在每一行中重复,直到世界顶部。

EDIT2:您可以打印行的引用以确认问题:

StringBuilder builder = new StringBuilder();
for (int i = 0; i < world.length; i++) {
    builder.append(world[k]).append("\n");
}
System.out.println(builder.toString());
于 2013-05-24T11:13:55.477 回答