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

C#控制台井字棋如何重启Main方法修复胜负判定逻辑Bug

问题根因
  • 胜负判定无拦截逻辑:O玩家落子后你虽然调用了CheckTheWinner(),但没有接收返回值做流程拦截,代码会继续执行X玩家的落子逻辑,直到本轮while循环体执行完才会回到循环条件判断,这就导致O获胜后X还能落子,甚至出现双方同时满足获胜条件的异常。
  • 重置逻辑设计错误:递归调用Main方法重置游戏会持续占用调用栈内存,玩家多次重开后会触发栈溢出,不是可行的重置方案。
  • 胜负判定返回值设计缺陷:原方法只返回布尔值,无法识别具体是哪个玩家获胜,无法输出准确的结果提示。
  • 存在冗余无效代码:两处只执行1次的for循环没有任何逻辑意义,只会增加代码复杂度。
  • 缺失平局判定:棋盘被填满后如果没人获胜,原逻辑会进入死循环。
修复方案
  • 每次玩家落子完成后立刻执行胜负检查,一旦检测到获胜方,立刻终止当前回合流程,不再执行后续玩家的落子逻辑。
  • 抽离独立的棋盘初始化方法,重置游戏时直接调用该方法清空棋盘状态,用外层循环控制游戏重开,完全不需要递归调用Main。
  • 改造CheckTheWinner()方法,直接返回获胜玩家的字符标识,无获胜方时返回空字符串,方便结果输出。
  • 删除无意义的单次循环代码,用步数奇偶性切换当前回合玩家,简化回合流程。
  • 增加平局判定,棋盘填满(最多9步)仍无获胜方时判定平局,避免死循环。
修正后可运行代码
class Program
{
    // 3*3棋盘全局数组
    static string[,] position = new string[3, 3];

    static void Main()
    {
        // 外层循环控制游戏重开
        while (true)
        {
            // 初始化棋盘为1-9的位置编号
            InitBoard();
            string winner = string.Empty;
            bool gameEnd = false;

            // 单局游戏最多9步,棋盘填满自动结束
            for (int step = 0; step < 9; step++)
            {
                Console.Clear();
                BoardPlay();
                // 偶数步是O回合,奇数步是X回合
                string currentPlayer = step % 2 == 0 ? "O" : "X";
                Console.Write($"Player {currentPlayer}: Choose your field(1-9):");
                string input = Console.ReadLine().Trim();

                // 执行对应玩家落子
                if (currentPlayer == "O")
                {
                    Player1Choice(input);
                }
                else
                {
                    Player2choice(input);
                }

                // 落子后立刻检查胜负,获胜就跳出回合循环
                winner = CheckTheWinner();
                if (!string.IsNullOrEmpty(winner))
                {
                    gameEnd = true;
                    break;
                }
            }

            // 展示最终结果
            Console.Clear();
            BoardPlay();
            if (gameEnd)
            {
                Console.WriteLine($"Player {winner} wins!");
            }
            else
            {
                Console.WriteLine("Draw! No winner.");
            }

            // 询问是否重开
            Console.Write("Play again? (Y/N):");
            string restart = Console.ReadLine().Trim().ToUpper();
            if (restart != "Y")
            {
                break;
            }
        }
    }

    // 初始化/重置棋盘
    static void InitBoard()
    {
        int posNum = 1;
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                position[i, j] = posNum.ToString();
                posNum++;
            }
        }
    }

    public static void Player1Choice(string P1)
    {
        const string o = "O";
        for (int i = 0; i < position.GetLength(0); i++)
        {
            for (int j = 0; j <= 2; j++)
            {
                if (position[i, j] == P1)
                {
                    position[i, j] = o;
                }
            }
        }
    }

    public static void Player2choice(string P2)
    {
        const string x = "X";
        for (int i = 0; i < position.GetLength(0); i++)
        {
            for (int j = 0; j <= 2; j++)
            {
                if (position[i, j] == P2)
                {
                    position[i, j] = x;
                }
            }
        }
    }

    // 胜负判定,返回获胜玩家标识,无胜者返回空字符串
    static string CheckTheWinner()
    {
        // 横向连线判定
        for (int i = 0; i < 3; i++)
        {
            if (position[i, 0] == position[i, 1] && position[i, 1] == position[i, 2])
            {
                return position[i, 0];
            }
        }
        // 纵向连线判定
        for (int i = 0; i < 3; i++)
        {
            if (position[0, i] == position[1, i] && position[1, i] == position[2, i])
            {
                return position[0, i];
            }
        }
        // 斜向连线判定
        if (position[0, 0] == position[1, 1] && position[1, 1] == position[2, 2])
        {
            return position[1, 1];
        }
        if (position[0, 2] == position[1, 1] && position[1, 1] == position[2, 0])
        {
            return position[1, 1];
        }
        return string.Empty;
    }

    // 棋盘绘制方法(补全原代码缺失部分)
    static void BoardPlay()
    {
        Console.ForegroundColor = ConsoleColor.Red;
        Console.WriteLine($" {position[0,0]} | {position[0,1]} | {position[0,2]} ");
        Console.WriteLine("---+---+---");
        Console.WriteLine($" {position[1,0]} | {position[1,1]} | {position[1,2]} ");
        Console.WriteLine("---+---+---");
        Console.WriteLine($" {position[2,0]} | {position[2,1]} | {position[2,2]} ");
        Console.ResetColor();
    }
}

补充说明:你还可以在落子逻辑里增加输入合法性校验,比如判断用户输入的是不是1-9的数字、对应位置有没有被占用,避免输入非法值导致的异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 01:24:21