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

井字棋(Tic-Tac-Toe)游戏代码逻辑错误排查求助

井字棋无限循环问题排查与解决方案

一、输入缓冲区残留无效数据(最常见诱因)

当用户输入非数字字符(如字母、符号)时,scanf("%d", ...)会读取失败,这些无效字符会滞留在输入缓冲区中。后续调用scanf时会反复尝试读取这些无效数据,导致程序陷入无限循环,持续弹出玩家1的输入提示。

解决方案

  • 每次输入后清空输入缓冲区:
    // 清空缓冲区直到读取到换行符
    while (getchar() != '\n');
    
  • 校验输入有效性,确保读取到1-9的整数:
    int input;
    while (scanf("%d", &input) != 1 || input < 1 || input > 9) {
        printf("无效输入!请输入1-9之间的数字。\n");
        while (getchar() != '\n'); // 清空错误输入残留
    }
    

二、玩家切换逻辑错误

如果game_logic函数未正确切换玩家标记(X/O),会导致程序一直停留在玩家1的输入流程中。比如玩家标记变量未在每次有效输入后更新,或切换逻辑被错误条件跳过。

解决方案

  • 在game_logic中维护当前玩家状态,每次有效输入后切换玩家:
    void game_logic(char board[3][3]) {
        int current_player = 1; // 1代表X,2代表O
        int win_result = 0;
        
        while (win_result == 0) {
            printf("Player %d, Please select the number = ", current_player);
            int input;
            // 这里加入上文的输入校验逻辑
            // ...
            
            // 将输入转换为棋盘坐标(1-9对应3x3的行和列)
            int row = (input - 1) / 3;
            int col = (input - 1) % 3;
            // 检查位置是否为空
            if (board[row][col] == ' ') {
                board[row][col] = (current_player == 1) ? 'X' : 'O';
                // 切换玩家
                current_player = (current_player == 1) ? 2 : 1;
                // 判断胜负
                win_result = game_win(board);
            } else {
                printf("该位置已被占用,请重新选择!\n");
            }
        }
    }
    

三、胜负判断逻辑失效

如果game_win函数未正确返回胜负/平局结果,会导致循环无法终止。比如函数始终返回0(游戏未结束),但实际已分出胜负或棋盘已满。

解决方案

  • 完善game_win的判断逻辑,覆盖行、列、对角线的胜负条件,以及平局判断:
    int game_win(char board[3][3]) {
        // 检查行胜负
        for (int i = 0; i < 3; i++) {
            if (board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ') {
                return (board[i][0] == 'X') ? 1 : 2;
            }
        }
        // 检查列胜负
        for (int i = 0; i < 3; i++) {
            if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ') {
                return (board[0][i] == 'X') ? 1 : 2;
            }
        }
        // 检查对角线胜负
        if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ') {
            return (board[0][0] == 'X') ? 1 : 2;
        }
        if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ') {
            return (board[0][2] == 'X') ? 1 : 2;
        }
        // 检查平局
        int is_full = 1;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (board[i][j] == ' ') {
                    is_full = 0;
                    break;
                }
            }
            if (!is_full) break;
        }
        return is_full ? 3 : 0; // 3代表平局,0代表游戏继续
    }
    

四、主循环条件错误

如果main函数或game_logic中的循环条件设置错误(比如永远为真),会直接导致无限循环。

解决方案

  • 在main函数中根据game_win的返回值控制循环生命周期:
    int main() {
        char board[3][3] = {{' ', ' ', ' '}, {' ', ' ', ' '}, {' ', ' ', ' '}};
        int result;
        
        do {
            game_logic(board);
            result = game_win(board);
        } while (result == 0);
        
        // 输出最终结果
        if (result == 1) {
            printf("玩家1(X)获胜!\n");
        } else if (result == 2) {
            printf("玩家2(O)获胜!\n");
        } else {
            printf("平局!\n");
        }
        return 0;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 21:11:25