You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言俄罗斯方块:方块下落函数陷入无限循环无法正常下落

问题

我正在为大一计算机科学项目编写俄罗斯方块游戏,目前方块下移函数存在问题。我使用二维数组表示游戏状态(示例为方形 Tetromino):

0 0 0 0 0 0 0 0 0 0 
0 0 0 0 1 1 0 0 0 0 
0 0 0 0 2 1 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 

我期望该函数能将游戏状态修改为:

0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 0 0 0 0 0 0 
0 0 0 0 1 1 0 0 0 0 
0 0 0 0 2 1 0 0 0 0 

但实际该函数并未将方块下移至最后一行后退出循环,而是直接陷入无限循环。以下是负责方块下移的函数代码:

void block_falling(int gamestate[NO_BLOCKS_FOR_GAP][NUMBER_OF_BLOCKS_HORIZONTALLY])
{
    int temporary_storage;

    bool is_falling = true;

    while (is_falling)
    {
        for (int row_counter = 0; row_counter < NO_BLOCKS_FOR_GAP; row_counter++)
        {
            for (int column_counter = 0; column_counter < NUMBER_OF_BLOCKS_HORIZONTALLY; column_counter++)
            {
                if ((gamestate[row_counter][column_counter] == 1) || (gamestate[row_counter][column_counter] == 2))
                {
                    if (row_counter != NO_BLOCKS_FOR_GAP - 1)
                    {
                        temporary_storage = gamestate[row_counter][column_counter];
                        gamestate[row_counter][column_counter] = gamestate[row_counter - 1][column_counter];
                        gamestate[row_counter - 1][column_counter] = temporary_storage;
                    }
                    if (row_counter == NO_BLOCKS_FOR_GAP - 1)
                    {
                        is_falling = false;
                    }
                }
            }
        }
    }
}

我确认下移逻辑本身是正确的,因为将如下代码片段重复执行10次,方块会下移10格:

for (int row_counter = 0; row_counter < NO_BLOCKS_FOR_GAP; row_counter++)
{
    for (int column_counter = 0; column_counter < NUMBER_OF_BLOCKS_HORIZONTALLY; column_counter++)
    {
        if ((gamestate[row_counter][column_counter] == 1) || (gamestate[row_counter][column_counter] == 2))
        {
            temporary_storage = gamestate[row_counter][column_counter];
            gamestate[row_counter][column_counter] = gamestate[row_counter - 1][column_counter];
            gamestate[row_counter - 1][column_counter] = temporary_storage;
        }
    }
}

修复方案

你的代码存在三个核心问题:

  • 行遍历方向错误:从第0行开始遍历,交换当前行和上一行元素,本质是让方块上移,测试时的下移只是意外效果,逻辑完全错误。
  • 交换逻辑颠倒:要实现下移,应该把当前行的方块和下一行(row_counter+1)交换,而不是上一行。
  • 退出条件无效:仅在遍历到最后一行时停止循环,但此时方块根本没到达底部,导致无限循环。正确的退出条件是判断方块是否还能继续下移。

修改后的函数代码如下:

void block_falling(int gamestate[NO_BLOCKS_FOR_GAP][NUMBER_OF_BLOCKS_HORIZONTALLY])
{
    int temporary_storage;
    bool can_fall;

    do {
        can_fall = false;
        // 从倒数第二行向上遍历,避免覆盖未处理的方块
        for (int row_counter = NO_BLOCKS_FOR_GAP - 2; row_counter >= 0; row_counter--)
        {
            for (int column_counter = 0; column_counter < NUMBER_OF_BLOCKS_HORIZONTALLY; column_counter++)
            {
                if ((gamestate[row_counter][column_counter] == 1) || (gamestate[row_counter][column_counter] == 2))
                {
                    // 检查下一行是否为空,允许下移
                    if (gamestate[row_counter + 1][column_counter] == 0)
                    {
                        // 交换当前行与下一行元素,实现下移
                        temporary_storage = gamestate[row_counter][column_counter];
                        gamestate[row_counter][column_counter] = gamestate[row_counter + 1][column_counter];
                        gamestate[row_counter + 1][column_counter] = temporary_storage;
                        can_fall = true; // 标记本次循环仍可下移
                    }
                }
            }
        }
    } while (can_fall); // 直到无法下移为止
}

关键修改说明:

  • 从下往上遍历行:从倒数第二行开始向上处理,确保下方的方块先完成下移,不会被上方未处理的元素覆盖。
  • 正确的下移交换:将当前行方块与下一行的空位置交换,真正实现向下移动。
  • 动态判断下落状态:每次循环后检查是否发生了下移操作,若没有则说明方块已到底或被阻挡,自动退出循环。

这样修改后,方块会自动下落至底部,不会陷入无限循环,完全符合预期效果。

内容的提问来源于stack exchange,提问作者user21105733

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 18:44:56