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

C#开发井字棋游戏时如何避免玩家落子覆盖已有棋子?

问题根因

  • 之前的修改仅覆盖了(1,1)对应第一个格子的空位校验,其余8个落子位置没有任何判断,直接赋值覆盖原有棋子
  • Main方法中玩家切换逻辑存在严重错误:每次循环都将player变量初始化为2,随后直接判定player==2改为1,导致全程只有玩家1(X)可以落子
  • 没有落子失败的重试逻辑,哪怕校验到位置被占用,依然会消耗当前回合、切换玩家,不符合游戏规则

修复方案

第一步:修改XorO方法,增加全局空位校验并返回落子结果

将方法返回值改为bool,落子成功返回true,位置已被占用返回false,同时简化坐标到数组下标的转换逻辑,无需重复写9个判断:

private static bool XorO(int player, int[] input)
{
    // 坐标转数组下标公式:(行-1)*3 + (列-1)
    int index = (input[0] - 1) * 3 + (input[1] - 1);
    // 全局空位校验,只要不是空格就判定为已占用
    if (board[index] != ' ')
    {
        Console.WriteLine("该位置已被占用,请重新选择!");
        return false;
    }
    // 落子逻辑
    playerSignature = player == 1 ? 'X' : 'O';
    board[index] = playerSignature;
    return true;
}

第二步:修复Main方法的玩家切换和落子重试逻辑

把玩家变量移到循环外部,落子失败时直接重试,不切换玩家、不增加回合数:

public static void Main()
{
    Introduction();
    // 玩家变量移到循环外部,初始为玩家1先手
    int player = 1;
    while(true)
    {
        bool isrow = false;
        bool iscol = false;
        int row = 0;
        int col = 0;
        while (!isrow)
        {
            Console.WriteLine($"玩家{player},请选择行号(1-3): ");
            try
            {
                row = Convert.ToInt32(Console.ReadLine());
            }
            catch
            {
                Console.WriteLine("请输入1-3之间的数字。");
            }
            if (row is >=1 and <=3)
            {
                isrow = true;
            }
            else
            {
                Console.WriteLine("\n无效行号!");
            }
        }
        while (!iscol)
        {
            Console.WriteLine($"玩家{player},请选择列号(1-3): ");
            try
            {
                col = Convert.ToInt32(Console.ReadLine());
            }
            catch
            {
                Console.WriteLine("请输入1-3之间的数字。");
            }
            if (col is >=1 and <=3)
            {
                iscol = true;
            }
            else
            {
                Console.WriteLine("\n无效列号!");
            }
        }
        int[] input = { row, col };
        // 落子失败直接进入下一轮循环,不切换玩家不计数
        if(!XorO(player, input))
        {
            continue;
        }
        DrawBoard(board);
        turns++;
        // 原有胜负校验逻辑保持不变
        CheckForDiagonal();
        CheckForVertical();
        CheckForHorizontal();
        // 简化平局判断:回合数到9说明棋盘已满
        if (turns == 9)
        {
            Draw();
        }
        // 落子成功后切换玩家
        player = player == 1 ? 2 : 1;
    }
}

第三步:优化平局判断逻辑

原有平局判断逻辑冗余,turns累计到9时棋盘已经被占满,无需额外判断所有格子都是玩家标识,直接触发平局即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:15:04