欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C#写简单井字棋

程序员文章站 2022-05-19 15:09:55
...

【1】前言

原本下了一个井字棋原码,可是突然发现有点小问题(好吧,其实是判断函数,下一颗棋子判断有漏洞),然后改造了下。

【2】实现

就用了一个界面而已,但就简单来考虑,足够了。

【1】界面初始化

C#写简单井字棋

C#写简单井字棋

主体用9个按钮来表示9个格子,也好,这样就不必要画图了。当然按钮排版和样式如上图。

用按钮的 Text 属性来表示是否下棋子的图形展示(O、X分别表示两种样式的棋子)当然要改字体的样式啦!

【2】私有成员以及界面初始化

        //模式表示(1 人VS人且玩家1先攻,2 人VS人且玩家2先攻,3 人VS电脑且人先攻,4 人VS电脑且电脑先攻)
        int type = 0;//取1,2,3,4值
        //表示两种类型的棋子,ture表示玩家1的棋子,false表示玩家2的棋子
        bool turn = true;
        //初始化按钮数组,0-未按下,1-“X”(玩家),2-"O"(电脑)
        int[,] ButtonArray = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };

        public Form()
        {
            InitializeComponent();
        }

【3】模式选择时的初始化

        //以下为 模式选择时的初始化
        private void 玩家1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            type = 1;//1 人VS人且玩家1先攻
            模式ToolStripMenuItem.Enabled = false;
            turn = true;
        }

        private void 玩家2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            type = 2;//2 人VS人且玩家2先攻
            模式ToolStripMenuItem.Enabled = false;
            turn = false;
        }

        private void 人ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            type = 3;//3 人VS电脑且人先攻
            模式ToolStripMenuItem.Enabled = false;
        }

        private void 电脑ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            type = 4;//4 人VS电脑且电脑先攻
            模式ToolStripMenuItem.Enabled = false;
            //ComputerTurn();//简单固定位置起步

            //电脑随机下第一颗棋子
            Random ro = new Random();
            int x = ro.Next(1, 10);
            switch (x)
            {
                //Turn为一个函数,下一个棋子(棋子类型,第几排,第几列)
                case 1: Turn(2, 0, 0); break;
                case 2: Turn(2, 0, 1); break;
                case 3: Turn(2, 0, 2); break;
                case 4: Turn(2, 1, 0); break;
                case 5: Turn(2, 1, 1); break;
                case 6: Turn(2, 1, 2); break;
                case 7: Turn(2, 2, 0); break;
                case 8: Turn(2, 2, 1); break;
                case 9: Turn(2, 2, 2); break;
                default:MessageBox.Show("Error!", "信息提示!", MessageBoxButtons.OK, MessageBoxIcon.Error);break;
            }
        }

【4】当点击重新开始时,ReSet相关属性

        //恢复初始情况
        private void Restart()
        {
            #region 将按钮数组还原
            for (int x = 0; x <= 2; x++)
                for (int y = 0; y <= 2; y++)
                    ButtonArray[x, y] = 0;
            #endregion

            #region 将按钮控件还原
            Button00.Text = "";
            Button00.Enabled = true;
            Button01.Text = "";
            Button01.Enabled = true;
            Button02.Text = "";
            Button02.Enabled = true;
            Button10.Text = "";
            Button10.Enabled = true;
            Button11.Text = "";
            Button11.Enabled = true;
            Button12.Text = "";
            Button12.Enabled = true;
            Button20.Text = "";
            Button20.Enabled = true;
            Button21.Text = "";
            Button21.Enabled = true;
            Button22.Text = "";
            Button22.Enabled = true;
            #endregion
            //模式选项还原
            模式ToolStripMenuItem.Enabled = true;
            type = 0;
        }

        //重新开始
        private void ToolStripMenuItem_Restart_Click(object sender, EventArgs e)
        {
            Restart();
        }

【5】当跟电脑下的时候需要自动下棋,这是一个在参订位置下一颗棋子的函数(棋子类型,第几行,第几列)

此处有个地方需要解释一下,原码用按钮的名称命名方式来默许了行和列

例如按钮的命名的方式为Button00,button01,button02,button10···如上图,分别最后两位数字隐含了行列信息。

        /// <summary>
        /// 输入玩家、X和Y坐标进行回合处理
        /// </summary>
        /// <param name="Player">玩家为1,电脑为2</param>
        /// <param name="X">X坐标</param>
        /// <param name="Y">Y坐标</param>
        private void Turn(int Player, int X, int Y)
        {
            string Graph;
            if (Player == 1) Graph = "X";
            else Graph = "O";

            //修改对应按钮数组中对应位置
            ButtonArray[X, Y] = Player;

            //将被点击按钮上的文字改为“X”
            ((Button)Controls.Find("Button" + X + Y, true)[0]).Text = Graph;

            //将被点击按钮禁用
            ((Button)Controls.Find("Button" + X + Y, true)[0]).Enabled = false;

            //判断是否获胜
            if (JudgeWin(Player) == 0)
                if (Player == 1&&(type==3||type==4)) ComputerTurn();//人机模式自动让机器下棋
        }

【6】判断输赢的函数

        private int JudgeWin(int Player)
        {
            int Result = 0;

            #region 进行判断
            //判断第一横排
            if (ButtonArray[0, 0] == Player && ButtonArray[0, 1] == Player && ButtonArray[0, 2] == Player) Result = Player;

            //判断第二横排
            else if (ButtonArray[1, 0] == Player && ButtonArray[1, 1] == Player && ButtonArray[1, 2] == Player) Result = Player;

            //判断第三横排
            else if (ButtonArray[2, 0] == Player && ButtonArray[2, 1] == Player && ButtonArray[2, 2] == Player) Result = Player;

            //判断第一纵排
            else if (ButtonArray[0, 0] == Player && ButtonArray[1, 0] == Player && ButtonArray[2, 0] == Player) Result = Player;

            //判断第二纵排
            else if (ButtonArray[0, 1] == Player && ButtonArray[1, 1] == Player && ButtonArray[2, 1] == Player) Result = Player;

            //判断第三纵排
            else if (ButtonArray[0, 2] == Player && ButtonArray[1, 2] == Player && ButtonArray[2, 2] == Player) Result = Player;

            //判断左上到右下
            else if (ButtonArray[0, 0] == Player && ButtonArray[1, 1] == Player && ButtonArray[2, 2] == Player) Result = Player;

            //判断右上到左下
            else if (ButtonArray[0, 2] == Player && ButtonArray[1, 1] == Player && ButtonArray[2, 0] == Player) Result = Player;
            #endregion

            #region 报出结果
            if (Result == 1)//棋子 在数组中表示值为1的一方胜利
            {
                if(type==3||type==4)MessageBox.Show("玩家获胜");//人机模式
                else MessageBox.Show("玩家1获胜");//人对战人
                Restart();
                return 1;
            }
            if (Result == 2)//棋子 在数组中表示值为2的一方胜利
            {
                if (type == 3 || type == 4) MessageBox.Show("电脑获胜");//人机模式
                else MessageBox.Show("玩家2获胜");//人对战人
                Restart();
                return 2;
            }
            #endregion
            //判断是否下满棋盘
            #region 格子已满,打成平局
            bool full = true;
            foreach (int item in ButtonArray)
            {
                if (item == 0) full = false;//在数组中站位值为0,说明此处没有棋子
            }
            if (full)
            {
                MessageBox.Show("平局");
                Restart();
            }
            #endregion
            //如果没有获胜的结果,返回0
            return 0;
        }

【7】当人点击任意按钮的时候,需要执行下棋的操作

private void Button_Click(object sender, EventArgs e)
        {
            //首先得选择游戏模式
            if (type == 0)
            {
                MessageBox.Show("请先选择游戏模式!", "信息提示!", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            #region 获取被点击按钮及其Name、X、Y坐标
            Button ClickedButton = (Button)sender;
            string ClickedButtonName = ClickedButton.Name;
            //根据按钮的名字来分析出当前所点击处是哪一行那一列的格子
            int ClickedButtonX = Convert.ToInt32(ClickedButtonName.Substring(6, 1));
            int ClickedButtonY = Convert.ToInt32(ClickedButtonName.Substring(7, 1));
            #endregion
            //若为人机模式
            if(type==3||type==4)Turn(1, ClickedButtonX, ClickedButtonY);
            //人和人对战模式
            else if (turn==true)
            {
                Turn(1, ClickedButtonX, ClickedButtonY);//该函数上面已经介绍
            }
            else if (turn == false)
            {
                Turn(2, ClickedButtonX, ClickedButtonY);
            }
            turn = !turn;//换棋子
        }

【8】当人机对战的时候,电脑智能下棋就麻烦点了

我将有的毛病的原码改了改,至少逻辑改对了,但沉余代码(不想一个个单词改,所以就改了改一些汇总的地方,导致,有点反复扭转的感觉,容易晕,那些 Player ,Opponent 的值的设置啥的,懒得重写简洁明了版的了。但原码条理还是很清晰的。

private void ComputerTurn()
        {
            #region 调用寻找缺口的函数
            //寻找电脑的缺口
            int Result = FindBreach(1);

            //未找到电脑的缺口,寻找玩家的缺口
            if (Result == 0) Result = FindBreach(2);
            #endregion
            //找是否有条件更好的四个角落位置
            if (Result == 0) Result = FindBreach2(1);

            #region 未找到玩家的缺口,随便寻找四角是否被占
            if (Result == 0)
                if (ButtonArray[0, 0] == 0) Turn(2, 0, 0);
                else if (ButtonArray[0, 2] == 0) Turn(2, 0, 2);
                else if (ButtonArray[2, 0] == 0) Turn(2, 2, 0);
                else if (ButtonArray[2, 2] == 0) Turn(2, 2, 2);
                //寻找中心是否被占
                else if (ButtonArray[1, 1] == 0) Turn(2, 1, 1);
                //寻找是否有空位
                else if (ButtonArray[0, 1] == 0) Turn(2, 0, 1);
                else if (ButtonArray[1, 0] == 0) Turn(2, 1, 0);
                else if (ButtonArray[1, 2] == 0) Turn(2, 1, 2);
                else if (ButtonArray[2, 1] == 0) Turn(2, 2, 1);
            #endregion
        }

【9】寻找两个棋子的情况

/// <summary>
        /// 寻找缺口,寻找是否有一条线上已经有两个同样的棋子,并补上第三个,用于防止对方连成一条线或者使自己连成一条线
        /// </summary>
        /// <param name="Player">玩家为1,电脑为2</param>
        /// <returns></returns>
        private int FindBreach(int Player)
        {
            int Result = 0, Opponent = 0;

            #region 分配自己和对手的Player值
            if (Player == 1) Opponent = 2;
            else Opponent = 1;
            #endregion

            #region 判断并执行缺口
            //判断第一横排
            if (ButtonArray[0, 0] + ButtonArray[0, 1] + ButtonArray[0, 2] == 2 * Opponent &&
                ButtonArray[0, 0] != Player && ButtonArray[0, 1] != Player && ButtonArray[0, 2] != Player)
            {
                //寻找该排是否有空位
                if (ButtonArray[0, 0] == 0)
                {
                    Turn(2, 0, 0);
                    Result = 1;
                }
                else if (ButtonArray[0, 1] == 0)
                {
                    Turn(2, 0, 1);
                    Result = 1;
                }
                else if (ButtonArray[0, 2] == 0)
                {
                    Turn(2, 0, 2);
                    Result = 1;
                }
            }

            //判断第二横排
            else if (ButtonArray[1, 0] + ButtonArray[1, 1] + ButtonArray[1, 2] == 2 * Opponent &&
                     ButtonArray[1, 0] != Player && ButtonArray[1, 1] != Player && ButtonArray[1, 2] != Player)
            {
                if (ButtonArray[1, 0] == 0)
                {
                    Turn(2, 1, 0);
                    Result = 1;
                }
                else if (ButtonArray[1, 1] == 0)
                {
                    Turn(2, 1, 1);
                    Result = 1;
                }
                else if (ButtonArray[1, 2] == 0)
                {
                    Turn(2, 1, 2);
                    Result = 1;
                }
            }

            //判断第三横排
            else if (ButtonArray[2, 0] + ButtonArray[2, 1] + ButtonArray[2, 2] == 2 * Opponent &&
                     ButtonArray[2, 0] != Player && ButtonArray[2, 1] != Player && ButtonArray[2, 2] != Player)
            {
                if (ButtonArray[2, 0] == 0)
                {
                    Turn(2, 2, 0);
                    Result = 1;
                }
                else if (ButtonArray[2, 1] == 0)
                {
                    Turn(2, 2, 1);
                    Result = 1;
                }
                else if (ButtonArray[2, 2] == 0)
                {
                    Turn(2, 2, 2);
                    Result = 1;
                }
            }

            //判断第一纵排
            else if (ButtonArray[0, 0] + ButtonArray[1, 0] + ButtonArray[2, 0] == 2 * Opponent &&
                     ButtonArray[0, 0] != Player && ButtonArray[1, 0] != Player && ButtonArray[2, 0] != Player)
            {
                if (ButtonArray[0, 0] == 0)
                {
                    Turn(2, 0, 0);
                    Result = 1;
                }
                else if (ButtonArray[1, 0] == 0)
                {
                    Turn(2, 1, 0);
                    Result = 1;
                }
                else if (ButtonArray[2, 0] == 0)
                {
                    Turn(2, 2, 0);
                    Result = 1;
                }
            }

            //判断第二纵排
            else if (ButtonArray[0, 1] + ButtonArray[1, 1] + ButtonArray[2, 1] == 2 * Opponent &&
                     ButtonArray[0, 1] != Player && ButtonArray[1, 1] != Player && ButtonArray[2, 1] != Player)
            {
                if (ButtonArray[0, 1] == 0)
                {
                    Turn(2, 0, 1);
                    Result = 1;
                }
                else if (ButtonArray[1, 1] == 0)
                {
                    Turn(2, 1, 1);
                    Result = 1;
                }
                else if (ButtonArray[2, 1] == 0)
                {
                    Turn(2, 2, 1);
                    Result = 1;
                }
            }

            //判断第三纵排
            else if (ButtonArray[0, 2] + ButtonArray[1, 2] + ButtonArray[2, 2] == 2 * Opponent &&
                     ButtonArray[0, 2] != Player && ButtonArray[1, 2] != Player && ButtonArray[2, 2] != Player)
            {
                if (ButtonArray[0, 2] == 0)
                {
                    Turn(2, 0, 2);
                    Result = 1;
                }
                else if (ButtonArray[1, 2] == 0)
                {
                    Turn(2, 1, 2);
                    Result = 1;
                }
                else if (ButtonArray[2, 2] == 0)
                {
                    Turn(2, 2, 2);
                    Result = 1;
                }
            }

            //判断左上到右下
            else if (ButtonArray[0, 0] + ButtonArray[1, 1] + ButtonArray[2, 2] == 2 * Opponent &&
                     ButtonArray[0, 0] != Player && ButtonArray[1, 1] != Player && ButtonArray[2, 2] != Player)
            {
                if (ButtonArray[0, 0] == 0)
                {
                    Turn(2, 0, 0);
                    Result = 1;
                }
                else if (ButtonArray[1, 1] == 0)
                {
                    Turn(2, 1, 1);
                    Result = 1;
                }
                else if (ButtonArray[2, 2] == 0)
                {
                    Turn(2, 2, 2);
                    Result = 1;
                }
            }

            //判断右上到左下
            else if (ButtonArray[0, 2] + ButtonArray[1, 1] + ButtonArray[2, 0] == 2 * Opponent &&
                     ButtonArray[0, 2] != Player && ButtonArray[1, 1] != Player && ButtonArray[2, 0] != Player)
            {
                if (ButtonArray[0, 2] == 0)
                {
                    Turn(2, 0, 2);
                    Result = 1;
                }
                else if (ButtonArray[1, 1] == 0)
                {
                    Turn(2, 1, 1);
                    Result = 1;
                }
                else if (ButtonArray[2, 0] == 0)
                {
                    Turn(2, 2, 0);
                    Result = 1;
                }
            }
            #endregion

            return Result;
        }

【10】寻找一个棋子的情况(特指找赢的几率大的四角)

        //判断是否有 创造两个一排的良好机会
        private int FindBreach2(int Player)
        {
            int Result = 0, Opponent = 0;

            #region 分配自己和对手的Player值
            if (Player == 1) Opponent = 2;
            else Opponent = 1;
            #endregion
            //判断第一横排
            if (ButtonArray[0, 0] + ButtonArray[0, 1] + ButtonArray[0, 2] == Opponent&&
                ButtonArray[0, 0] != Player && ButtonArray[0, 1] != Player && ButtonArray[0, 2] != Player)
                if(ButtonArray[0, 0] == Opponent)
                {
                    Turn(2, 0, 2);
                    return Result = 1;
                }
                else if(ButtonArray[0, 2] == Opponent)
                {
                    Turn(2, 0, 0);
                    return Result = 1;
                }
            //判断第三横排
            if (ButtonArray[2, 0] + ButtonArray[2, 1] + ButtonArray[2, 2] == Opponent &&
                ButtonArray[2, 0] != Player && ButtonArray[2, 1] != Player && ButtonArray[2, 2] != Player)
                if (ButtonArray[2, 0] == Opponent)
                {
                    Turn(2, 2, 2);
                    return Result = 1;
                }
                else if (ButtonArray[2, 2] == Opponent)
                {
                    Turn(2, 2, 0);
                    return Result = 1;
                }
            //判断第一纵排
            if (ButtonArray[0, 0] + ButtonArray[1, 0] + ButtonArray[2, 0] == Opponent &&
                ButtonArray[0, 0] != Player && ButtonArray[1, 0] != Player && ButtonArray[2, 0] != Player)
                if (ButtonArray[0, 0] == Opponent)
                {
                    Turn(2, 2, 0);
                    return Result = 1;
                }
                else if (ButtonArray[2, 0] == Opponent)
                {
                    Turn(2, 0, 0);
                    return Result = 1;
                }
            //判断第三纵排
            if (ButtonArray[0, 2] + ButtonArray[1, 2] + ButtonArray[2, 2] ==  Opponent &&
                ButtonArray[0, 2] != Player && ButtonArray[1, 2] != Player && ButtonArray[2, 2] != Player)
                if (ButtonArray[0, 2] == Opponent)
                {
                    Turn(2, 2, 2);
                    return Result = 1;
                }
                else if (ButtonArray[2, 2] == Opponent)
                {
                    Turn(2, 0, 2);
                    return Result = 1;
                }
            //判断左上到右下
            if (ButtonArray[0, 0] + ButtonArray[1, 1] + ButtonArray[2, 2] ==  Opponent &&
                ButtonArray[0, 0] != Player && ButtonArray[1, 1] != Player && ButtonArray[2, 2] != Player)
                if (ButtonArray[0, 0] == Opponent)
                {
                    Turn(2, 2, 2);
                    return Result = 1;
                }
                else if (ButtonArray[2, 2] == Opponent)
                {
                    Turn(2, 0, 0);
                    return Result = 1;
                }
            //判断右上到左下
            if (ButtonArray[0, 2] + ButtonArray[1, 1] + ButtonArray[2, 0] ==  Opponent &&
                ButtonArray[0, 2] != Player && ButtonArray[1, 1] != Player && ButtonArray[2, 0] != Player)
                if (ButtonArray[0, 2] == Opponent)
                {
                    Turn(2, 2, 0);
                    return Result = 1;
                }
                else if (ButtonArray[2, 0] == Opponent)
                {
                    Turn(2, 0, 2);
                    return Result = 1;
                }
            return Result;
        }

【3】运行效果

C#写简单井字棋

C#写简单井字棋

【4】缺点

代码过于反复沉余,关键地方有些值设置的有点晕圈,不清晰,目的不太明确等等。界面也不太美观。

【5】优点

原本代码就只有人机这一种模式,关键还电脑的走法以及判断输赢有点小逻辑缺陷。改造后相对好了很多,有人机,人VS人多种模式了。

【6】感想

我好菜啊~

【7】附上全码

仅供参考学习,不是用来贪图方便交作业实验等···

自己去慢慢拼凑调试吧,想直接能运行就交作业是不可能的。

using System;
using System.Windows.Forms;

namespace 井字棋
{
    public partial class Form : System.Windows.Forms.Form
    {
        //模式表示(1 人VS人且玩家1先攻,2 人VS人且玩家2先攻,3 人VS电脑且人先攻,4 人VS电脑且电脑先攻)
        int type = 0;//取1,2,3,4值
        //表示两种类型的棋子,ture表示玩家1的棋子,false表示玩家2的棋子
        bool turn = true;
        //初始化按钮数组,0-未按下,1-“X”(玩家),2-"O"(电脑)
        int[,] ButtonArray = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } };

        public Form()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, EventArgs e)
        {
            //首先得选择游戏模式
            if (type == 0)
            {
                MessageBox.Show("请先选择游戏模式!", "信息提示!", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            #region 获取被点击按钮及其Name、X、Y坐标
            Button ClickedButton = (Button)sender;
            string ClickedButtonName = ClickedButton.Name;
            //根据按钮的名字来分析出当前所点击处是哪一行那一列的格子
            int ClickedButtonX = Convert.ToInt32(ClickedButtonName.Substring(6, 1));
            int ClickedButtonY = Convert.ToInt32(ClickedButtonName.Substring(7, 1));
            #endregion
            //若为人机模式
            if(type==3||type==4)Turn(1, ClickedButtonX, ClickedButtonY);
            //人和人对战模式
            else if (turn==true)
            {
                Turn(1, ClickedButtonX, ClickedButtonY);
            }
            else if (turn == false)
            {
                Turn(2, ClickedButtonX, ClickedButtonY);
            }
            turn = !turn;//换棋子
        }

        private int JudgeWin(int Player)
        {
            int Result = 0;

            #region 进行判断
            //判断第一横排
            if (ButtonArray[0, 0] == Player && ButtonArray[0, 1] == Player && ButtonArray[0, 2] == Player) Result = Player;

            //判断第二横排
            else if (ButtonArray[1, 0] == Player && ButtonArray[1, 1] == Player && ButtonArray[1, 2] == Player) Result = Player;

            //判断第三横排
            else if (ButtonArray[2, 0] == Player && ButtonArray[2, 1] == Player && ButtonArray[2, 2] == Player) Result = Player;

            //判断第一纵排
            else if (ButtonArray[0, 0] == Player && ButtonArray[1, 0] == Player && ButtonArray[2, 0] == Player) Result = Player;

            //判断第二纵排
            else if (ButtonArray[0, 1] == Player && ButtonArray[1, 1] == Player && ButtonArray[2, 1] == Player) Result = Player;

            //判断第三纵排
            else if (ButtonArray[0, 2] == Player && ButtonArray[1, 2] == Player && ButtonArray[2, 2] == Player) Result = Player;

            //判断左上到右下
            else if (ButtonArray[0, 0] == Player && ButtonArray[1, 1] == Player && ButtonArray[2, 2] == Player) Result = Player;

            //判断右上到左下
            else if (ButtonArray[0, 2] == Player && ButtonArray[1, 1] == Player && ButtonArray[2, 0] == Player) Result = Player;
            #endregion

            #region 报出结果
            if (Result == 1)//棋子 在数组中表示值为1的一方胜利
            {
                if(type==3||type==4)MessageBox.Show("玩家获胜");//人机模式
                else MessageBox.Show("玩家1获胜");//人对战人
                Restart();
                return 1;
            }
            if (Result == 2)//棋子 在数组中表示值为2的一方胜利
            {
                if (type == 3 || type == 4) MessageBox.Show("电脑获胜");//人机模式
                else MessageBox.Show("玩家2获胜");//人对战人
                Restart();
                return 2;
            }
            #endregion
            //判断是否下满棋盘
            #region 格子已满,打成平局
            bool full = true;
            foreach (int item in ButtonArray)
            {
                if (item == 0) full = false;//在数组中站位值为0,说明此处没有棋子
            }
            if (full)
            {
                MessageBox.Show("平局");
                Restart();
            }
            #endregion
            //如果没有获胜的结果,返回0
            return 0;
        }

        private void ComputerTurn()
        {
            #region 调用寻找缺口的函数
            //寻找电脑的缺口
            int Result = FindBreach(1);

            //未找到电脑的缺口,寻找玩家的缺口
            if (Result == 0) Result = FindBreach(2);
            #endregion
            //找是否有条件更好的四个角落位置
            if (Result == 0) Result = FindBreach2(1);

            #region 未找到玩家的缺口,随便寻找四角是否被占
            if (Result == 0)
                if (ButtonArray[0, 0] == 0) Turn(2, 0, 0);
                else if (ButtonArray[0, 2] == 0) Turn(2, 0, 2);
                else if (ButtonArray[2, 0] == 0) Turn(2, 2, 0);
                else if (ButtonArray[2, 2] == 0) Turn(2, 2, 2);
                //寻找中心是否被占
                else if (ButtonArray[1, 1] == 0) Turn(2, 1, 1);
                //寻找是否有空位
                else if (ButtonArray[0, 1] == 0) Turn(2, 0, 1);
                else if (ButtonArray[1, 0] == 0) Turn(2, 1, 0);
                else if (ButtonArray[1, 2] == 0) Turn(2, 1, 2);
                else if (ButtonArray[2, 1] == 0) Turn(2, 2, 1);
            #endregion
        }

        /// <summary>
        /// 寻找缺口,寻找是否有一条线上已经有两个同样的棋子,并补上第三个,用于防止对方连成一条线或者使自己连成一条线
        /// </summary>
        /// <param name="Player">玩家为1,电脑为2</param>
        /// <returns></returns>
        private int FindBreach(int Player)
        {
            int Result = 0, Opponent = 0;

            #region 分配自己和对手的Player值
            if (Player == 1) Opponent = 2;
            else Opponent = 1;
            #endregion

            #region 判断并执行缺口
            //判断第一横排
            if (ButtonArray[0, 0] + ButtonArray[0, 1] + ButtonArray[0, 2] == 2 * Opponent &&
                ButtonArray[0, 0] != Player && ButtonArray[0, 1] != Player && ButtonArray[0, 2] != Player)
            {
                //寻找该排是否有空位
                if (ButtonArray[0, 0] == 0)
                {
                    Turn(2, 0, 0);
                    Result = 1;
                }
                else if (ButtonArray[0, 1] == 0)
                {
                    Turn(2, 0, 1);
                    Result = 1;
                }
                else if (ButtonArray[0, 2] == 0)
                {
                    Turn(2, 0, 2);
                    Result = 1;
                }
            }

            //判断第二横排
            else if (ButtonArray[1, 0] + ButtonArray[1, 1] + ButtonArray[1, 2] == 2 * Opponent &&
                     ButtonArray[1, 0] != Player && ButtonArray[1, 1] != Player && ButtonArray[1, 2] != Player)
            {
                if (ButtonArray[1, 0] == 0)
                {
                    Turn(2, 1, 0);
                    Result = 1;
                }
                else if (ButtonArray[1, 1] == 0)
                {
                    Turn(2, 1, 1);
                    Result = 1;
                }
                else if (ButtonArray[1, 2] == 0)
                {
                    Turn(2, 1, 2);
                    Result = 1;
                }
            }

            //判断第三横排
            else if (ButtonArray[2, 0] + ButtonArray[2, 1] + ButtonArray[2, 2] == 2 * Opponent &&
                     ButtonArray[2, 0] != Player && ButtonArray[2, 1] != Player && ButtonArray[2, 2] != Player)
            {
                if (ButtonArray[2, 0] == 0)
                {
                    Turn(2, 2, 0);
                    Result = 1;
                }
                else if (ButtonArray[2, 1] == 0)
                {
                    Turn(2, 2, 1);
                    Result = 1;
                }
                else if (ButtonArray[2, 2] == 0)
                {
                    Turn(2, 2, 2);
                    Result = 1;
                }
            }

            //判断第一纵排
            else if (ButtonArray[0, 0] + ButtonArray[1, 0] + ButtonArray[2, 0] == 2 * Opponent &&
                     ButtonArray[0, 0] != Player && ButtonArray[1, 0] != Player && ButtonArray[2, 0] != Player)
            {
                if (ButtonArray[0, 0] == 0)
                {
                    Turn(2, 0, 0);
                    Result = 1;
                }
                else if (ButtonArray[1, 0] == 0)
                {
                    Turn(2, 1, 0);
                    Result = 1;
                }
                else if (ButtonArray[2, 0] == 0)
                {
                    Turn(2, 2, 0);
                    Result = 1;
                }
            }

            //判断第二纵排
            else if (ButtonArray[0, 1] + ButtonArray[1, 1] + ButtonArray[2, 1] == 2 * Opponent &&
                     ButtonArray[0, 1] != Player && ButtonArray[1, 1] != Player && ButtonArray[2, 1] != Player)
            {
                if (ButtonArray[0, 1] == 0)
                {
                    Turn(2, 0, 1);
                    Result = 1;
                }
                else if (ButtonArray[1, 1] == 0)
                {
                    Turn(2, 1, 1);
                    Result = 1;
                }
                else if (ButtonArray[2, 1] == 0)
                {
                    Turn(2, 2, 1);
                    Result = 1;
                }
            }

            //判断第三纵排
            else if (ButtonArray[0, 2] + ButtonArray[1, 2] + ButtonArray[2, 2] == 2 * Opponent &&
                     ButtonArray[0, 2] != Player && ButtonArray[1, 2] != Player && ButtonArray[2, 2] != Player)
            {
                if (ButtonArray[0, 2] == 0)
                {
                    Turn(2, 0, 2);
                    Result = 1;
                }
                else if (ButtonArray[1, 2] == 0)
                {
                    Turn(2, 1, 2);
                    Result = 1;
                }
                else if (ButtonArray[2, 2] == 0)
                {
                    Turn(2, 2, 2);
                    Result = 1;
                }
            }

            //判断左上到右下
            else if (ButtonArray[0, 0] + ButtonArray[1, 1] + ButtonArray[2, 2] == 2 * Opponent &&
                     ButtonArray[0, 0] != Player && ButtonArray[1, 1] != Player && ButtonArray[2, 2] != Player)
            {
                if (ButtonArray[0, 0] == 0)
                {
                    Turn(2, 0, 0);
                    Result = 1;
                }
                else if (ButtonArray[1, 1] == 0)
                {
                    Turn(2, 1, 1);
                    Result = 1;
                }
                else if (ButtonArray[2, 2] == 0)
                {
                    Turn(2, 2, 2);
                    Result = 1;
                }
            }

            //判断右上到左下
            else if (ButtonArray[0, 2] + ButtonArray[1, 1] + ButtonArray[2, 0] == 2 * Opponent &&
                     ButtonArray[0, 2] != Player && ButtonArray[1, 1] != Player && ButtonArray[2, 0] != Player)
            {
                if (ButtonArray[0, 2] == 0)
                {
                    Turn(2, 0, 2);
                    Result = 1;
                }
                else if (ButtonArray[1, 1] == 0)
                {
                    Turn(2, 1, 1);
                    Result = 1;
                }
                else if (ButtonArray[2, 0] == 0)
                {
                    Turn(2, 2, 0);
                    Result = 1;
                }
            }
            #endregion

            return Result;
        }

        //判断是否有 创造两个一排的良好机会
        private int FindBreach2(int Player)
        {
            int Result = 0, Opponent = 0;

            #region 分配自己和对手的Player值
            if (Player == 1) Opponent = 2;
            else Opponent = 1;
            #endregion
            //判断第一横排
            if (ButtonArray[0, 0] + ButtonArray[0, 1] + ButtonArray[0, 2] == Opponent&&
                ButtonArray[0, 0] != Player && ButtonArray[0, 1] != Player && ButtonArray[0, 2] != Player)
                if(ButtonArray[0, 0] == Opponent)
                {
                    Turn(2, 0, 2);
                    return Result = 1;
                }
                else if(ButtonArray[0, 2] == Opponent)
                {
                    Turn(2, 0, 0);
                    return Result = 1;
                }
            //判断第三横排
            if (ButtonArray[2, 0] + ButtonArray[2, 1] + ButtonArray[2, 2] == Opponent &&
                ButtonArray[2, 0] != Player && ButtonArray[2, 1] != Player && ButtonArray[2, 2] != Player)
                if (ButtonArray[2, 0] == Opponent)
                {
                    Turn(2, 2, 2);
                    return Result = 1;
                }
                else if (ButtonArray[2, 2] == Opponent)
                {
                    Turn(2, 2, 0);
                    return Result = 1;
                }
            //判断第一纵排
            if (ButtonArray[0, 0] + ButtonArray[1, 0] + ButtonArray[2, 0] == Opponent &&
                ButtonArray[0, 0] != Player && ButtonArray[1, 0] != Player && ButtonArray[2, 0] != Player)
                if (ButtonArray[0, 0] == Opponent)
                {
                    Turn(2, 2, 0);
                    return Result = 1;
                }
                else if (ButtonArray[2, 0] == Opponent)
                {
                    Turn(2, 0, 0);
                    return Result = 1;
                }
            //判断第三纵排
            if (ButtonArray[0, 2] + ButtonArray[1, 2] + ButtonArray[2, 2] ==  Opponent &&
                ButtonArray[0, 2] != Player && ButtonArray[1, 2] != Player && ButtonArray[2, 2] != Player)
                if (ButtonArray[0, 2] == Opponent)
                {
                    Turn(2, 2, 2);
                    return Result = 1;
                }
                else if (ButtonArray[2, 2] == Opponent)
                {
                    Turn(2, 0, 2);
                    return Result = 1;
                }
            //判断左上到右下
            if (ButtonArray[0, 0] + ButtonArray[1, 1] + ButtonArray[2, 2] ==  Opponent &&
                ButtonArray[0, 0] != Player && ButtonArray[1, 1] != Player && ButtonArray[2, 2] != Player)
                if (ButtonArray[0, 0] == Opponent)
                {
                    Turn(2, 2, 2);
                    return Result = 1;
                }
                else if (ButtonArray[2, 2] == Opponent)
                {
                    Turn(2, 0, 0);
                    return Result = 1;
                }
            //判断右上到左下
            if (ButtonArray[0, 2] + ButtonArray[1, 1] + ButtonArray[2, 0] ==  Opponent &&
                ButtonArray[0, 2] != Player && ButtonArray[1, 1] != Player && ButtonArray[2, 0] != Player)
                if (ButtonArray[0, 2] == Opponent)
                {
                    Turn(2, 2, 0);
                    return Result = 1;
                }
                else if (ButtonArray[2, 0] == Opponent)
                {
                    Turn(2, 0, 2);
                    return Result = 1;
                }
            return Result;
        }

        /// <summary>
        /// 输入玩家、X和Y坐标进行回合处理
        /// </summary>
        /// <param name="Player">玩家为1,电脑为2</param>
        /// <param name="X">X坐标</param>
        /// <param name="Y">Y坐标</param>
        private void Turn(int Player, int X, int Y)
        {
            string Graph;
            if (Player == 1) Graph = "X";
            else Graph = "O";

            //修改对应按钮数组中对应位置
            ButtonArray[X, Y] = Player;

            //将被点击按钮上的文字改为“X”
            ((Button)Controls.Find("Button" + X + Y, true)[0]).Text = Graph;

            //将被点击按钮禁用
            ((Button)Controls.Find("Button" + X + Y, true)[0]).Enabled = false;

            //判断是否获胜
            if (JudgeWin(Player) == 0)
                if (Player == 1&&(type==3||type==4)) ComputerTurn();//人机模式自动让机器下棋
        }
        //恢复初始情况
        private void Restart()
        {
            #region 将按钮数组还原
            for (int x = 0; x <= 2; x++)
                for (int y = 0; y <= 2; y++)
                    ButtonArray[x, y] = 0;
            #endregion

            #region 将按钮控件还原
            Button00.Text = "";
            Button00.Enabled = true;
            Button01.Text = "";
            Button01.Enabled = true;
            Button02.Text = "";
            Button02.Enabled = true;
            Button10.Text = "";
            Button10.Enabled = true;
            Button11.Text = "";
            Button11.Enabled = true;
            Button12.Text = "";
            Button12.Enabled = true;
            Button20.Text = "";
            Button20.Enabled = true;
            Button21.Text = "";
            Button21.Enabled = true;
            Button22.Text = "";
            Button22.Enabled = true;
            #endregion
            //模式选项还原
            模式ToolStripMenuItem.Enabled = true;
            type = 0;
        }

        //重新开始
        private void ToolStripMenuItem_Restart_Click(object sender, EventArgs e)
        {
            Restart();
        }

        //以下为 模式选择时的初始化
        private void 玩家1ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            type = 1;//1 人VS人且玩家1先攻
            模式ToolStripMenuItem.Enabled = false;
            turn = true;
        }

        private void 玩家2ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            type = 2;//2 人VS人且玩家2先攻
            模式ToolStripMenuItem.Enabled = false;
            turn = false;
        }

        private void 人ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            type = 3;//3 人VS电脑且人先攻
            模式ToolStripMenuItem.Enabled = false;
        }

        private void 电脑ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            type = 4;//4 人VS电脑且电脑先攻
            模式ToolStripMenuItem.Enabled = false;
            //ComputerTurn();//简单固定位置起步

            //电脑随机下第一颗棋子
            Random ro = new Random();
            int x = ro.Next(1, 10);
            switch (x)
            {
                case 1: Turn(2, 0, 0); break;
                case 2: Turn(2, 0, 1); break;
                case 3: Turn(2, 0, 2); break;
                case 4: Turn(2, 1, 0); break;
                case 5: Turn(2, 1, 1); break;
                case 6: Turn(2, 1, 2); break;
                case 7: Turn(2, 2, 0); break;
                case 8: Turn(2, 2, 1); break;
                case 9: Turn(2, 2, 2); break;
                default:MessageBox.Show("Error!", "信息提示!", MessageBoxButtons.OK, MessageBoxIcon.Error);break;
            }
        }
    }
}

【8】源码下载

链接:https://pan.baidu.com/s/1fN9SJZH7ub-UZmYnOQkkmQ 密码:y782