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

C语言井字棋游戏循环异常及棋盘打印正确性排查请求

井字棋程序问题分析与修复

核心问题排查

1. 玩家名称输入错误

  • 原代码用scanf("%c", n1)读取玩家名称,%c仅能读取单个字符,还会捕获输入后的换行符,导致第二个玩家名称直接被赋值为换行符,后续逻辑完全混乱。
  • 修正:改用%s读取字符串,配合scanf(" %s", n1)(前置空格跳过换行等空白字符)。

2. 棋盘打印逻辑错误

  • functionboard函数内重新定义了局部space数组,覆盖全局棋盘数组,导致永远打印初始状态,无法显示玩家落子后的变化。
  • 修正:删除局部space数组定义,直接使用全局数组;同时补全printf的格式占位符,比如将printf(" ", space[0][0], ...)改为printf(" %c | %c | %c \n", space[0][0], space[0][1], space[0][2]);,让棋盘内容正常输出。

3. 输入处理错误

  • scanf("&d", &dight)格式符错误,应为scanf("%d", &dight);存在拼写错误prinf,需改为printf。
  • 玩家提示语句printf(n1, "please enter")格式错误,正确写法是printf("%s, please enter your move (1-9): ", n1);。
  • functionOne中dight的范围判断逻辑混乱:多个独立if后接else if,导致dight为1-9时该分支不会触发;若dight未被正确赋值(比如输入失败),row/column会是全局未初始化的随机值,访问棋盘时触发"There is no empty space!"提示。

4. 递归调用导致无限循环

  • functionOne末尾无条件递归自身,无论输入是否有效都会无限递归,既导致栈溢出,又会在错误输入时反复触发错误提示。
  • 修正:去掉递归,改用循环处理输入直到有效。

5. 胜负判断逻辑优化

  • functionDraw命名不准确,实际是判断胜负和平局,可改为checkGameStatus;当前逻辑中tie变量的全局依赖可以优化,整合到返回逻辑中。

修正后的完整代码

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <stdbool.h>

char space[3][3] = {
    {'1', '2', '3'},
    {'4', '5', '6'},
    {'7', '8', '9'},
};
int row;
int column;
char token = 'x';
bool tie = false;
char n1[256];
char n2[256];

void functionboard()
{
    printf("        |        |        \n");
    printf("  %c     |  %c     |  %c     \n", space[0][0], space[0][1], space[0][2]);
    printf("________|________|________\n");
    printf("        |        |        \n");
    printf("  %c     |  %c     |  %c     \n", space[1][0], space[1][1], space[1][2]);
    printf("________|________|________\n");
    printf("        |        |        \n");
    printf("  %c     |  %c     |  %c     \n", space[2][0], space[2][1], space[2][2]);
    printf("        |        |        \n");
}

void functionOne()
{
    int dight;
    bool validInput = false;

    while (!validInput) {
        if (token == 'x') {
            printf("%s, please enter your move (1-9): ", n1);
            if (scanf("%d", &dight) != 1) {
                printf("Invalid input! Please enter a number.\n");
                while (getchar() != '\n');
                continue;
            }
        } else {
            printf("%s, please enter your move (1-9): ", n2);
            if (scanf("%d", &dight) != 1) {
                printf("Invalid input! Please enter a number.\n");
                while (getchar() != '\n');
                continue;
            }
        }

        row = -1;
        column = -1;

        if (dight >= 1 && dight <= 9) {
            row = (dight - 1) / 3;
            column = (dight - 1) % 3;

            if (space[row][column] != 'x' && space[row][column] != '0') {
                if (token == 'x') {
                    space[row][column] = 'x';
                    token = '0';
                } else {
                    space[row][column] = '0';
                    token = 'x';
                }
                validInput = true;
            } else {
                printf("There is no empty space! Try again.\n");
                functionboard();
            }
        } else {
            printf("Invalid !!! Please enter a number between 1 and 9.\n");
            functionboard();
        }
    }
}

bool checkGameStatus()
{
    for (int i = 0; i < 3; i++) {
        if ((space[i][0] == space[i][1] && space[i][0] == space[i][2]) || 
            (space[0][i] == space[1][i] && space[0][i] == space[2][i])) {
            return true;
        }
    }
    if ((space[0][0] == space[1][1] && space[1][1] == space[2][2]) || 
        (space[0][2] == space[1][1] && space[1][1] == space[2][0])) {
        return true;
    }

    tie = true;
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            if (space[i][j] != 'x' && space[i][j] != '0') {
                tie = false;
                return false;
            }
        }
    }
    return true;
}

int main()
{
    printf("Enter the name of the first player : \n");
    scanf(" %s", n1);
    printf("Enter the name of the second player : \n");
    scanf(" %s", n2);
    printf("%s is player1, so you will play first (using 'x')\n", n1);
    printf("%s is player2, so you will play second (using '0')\n", n2);

    while (!checkGameStatus()) {
        functionboard();
        functionOne();
    }

    functionboard();

    if (!tie) {
        if (token == 'x') {
            printf("%s Wins!!\n", n2);
        } else {
            printf("%s Wins!!\n", n1);
        }
    } else {
        printf("It's a draw!!\n");
    }

    return 0;
}

说明

  • 修复了玩家名称输入问题,支持读取完整字符串
  • 棋盘打印现在会正确显示玩家落子状态
  • 增加了输入有效性校验,包括非数字输入的处理
  • 移除无限递归,改用循环处理输入直到有效
  • 优化了胜负和平局判断逻辑,游戏结束时打印最终棋盘

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:50:18