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

C语言井字棋程序异常输出求助:输入6或8时误判获胜

井字棋游戏异常获胜问题的解决方案

核心问题:获胜判断逻辑错误

你代码里的获胜条件写法完全错误,比如if(arr[0]&&arr[1]&&arr[2]=='X')这种表达式,并非检查三个格子都是'X'。在C语言中,单个字符变量参与逻辑判断时,只要不是'\0'就会被视为真。所以当arr[2]是'X'时,不管arr[0]和arr[1]是什么(只要不是空字符),整个条件都会成立,这就导致只下一个棋子就触发获胜提示。

比如输入6时,arr[5]被设为'O',此时检查arr[3]&&arr[4]&&arr[5]=='O',arr[3]是'4'、arr[4]是'5',都是非零值,加上arr[5]=='O'为真,整个条件成立,错误判定玩家2获胜。输入8时同理,arr[7]是'O',会触发arr[1]&&arr[4]&&arr[7]=='O'这类条件。

修正步骤

1. 修复获胜判断条件

所有获胜判断都要明确检查每个格子是否等于目标字符,比如玩家1的横排获胜条件应该写成:

if(arr[0] == 'X' && arr[1] == 'X' && arr[2] == 'X')

同理,所有X和O的获胜条件都要改成这种形式。

2. 移除嵌套函数(符合C标准)

C标准不允许在函数内部定义另一个函数,把drawboard函数移到main外面,并传递棋盘数组作为参数。

3. 优化游戏流程(单步玩家操作)

原代码每次循环同时处理两个玩家输入,会导致玩家1获胜后玩家2还能输入,应该每轮只处理一个玩家的操作,检查是否获胜或平局,然后切换玩家。

4. 添加输入合法性检查

防止输入无效数字(比如0、10)或者已被占据的格子,避免数组越界和非法覆盖。

修正后的完整代码

#include <stdio.h>

void drawboard(char arr[]) {
    printf("%c|%c|%c\n", arr[0], arr[1], arr[2]);
    printf("-----\n");
    printf("%c|%c|%c\n", arr[3], arr[4], arr[5]);
    printf("-----\n");
    printf("%c|%c|%c\n", arr[6], arr[7], arr[8]);
}

// 检查是否获胜
int checkWin(char arr[], char player) {
    // 横排
    if(arr[0] == player && arr[1] == player && arr[2] == player) return 1;
    if(arr[3] == player && arr[4] == player && arr[5] == player) return 1;
    if(arr[6] == player && arr[7] == player && arr[8] == player) return 1;
    // 竖排
    if(arr[0] == player && arr[3] == player && arr[6] == player) return 1;
    if(arr[1] == player && arr[4] == player && arr[7] == player) return 1;
    if(arr[2] == player && arr[5] == player && arr[8] == player) return 1;
    // 对角线
    if(arr[0] == player && arr[4] == player && arr[8] == player) return 1;
    if(arr[2] == player && arr[4] == player && arr[6] == player) return 1;
    return 0;
}

// 检查是否平局
int checkDraw(char arr[]) {
    for(int i=0; i<9; i++) {
        if(arr[i] != 'X' && arr[i] != 'O') {
            return 0;
        }
    }
    return 1;
}

int main() {
    int choice;
    char arr[] = {'1','2','3','4','5','6','7','8','9'};
    char currentPlayer = 'X';

    while(1) {
        drawboard(arr);
        printf("Player %c, enter your choice:\n", currentPlayer);
        scanf("%d", &choice);

        // 检查输入合法性
        if(choice < 1 || choice >9) {
            printf("Invalid input! Please enter a number between 1-9.\n");
            continue;
        }
        if(arr[choice-1] == 'X' || arr[choice-1] == 'O') {
            printf("This spot is already taken! Choose another one.\n");
            continue;
        }

        arr[choice-1] = currentPlayer;

        // 检查获胜
        if(checkWin(arr, currentPlayer)) {
            drawboard(arr);
            printf("Player %c won!\n", currentPlayer);
            break;
        }

        // 检查平局
        if(checkDraw(arr)) {
            drawboard(arr);
            printf("It's a draw!\n");
            break;
        }

        // 切换玩家
        currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
    }
    return 0;
}

额外说明

  • 新增了checkWin和checkDraw函数,让代码更简洁易维护,避免重复的条件判断。
  • 单步处理玩家输入,每走一步就检查状态,符合正常游戏流程。
  • 输入合法性检查避免了数组越界和重复落子的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 21:15:36