Unity3d井字棋实现

整体框架:

首先我们要明确我们要做什么,需要什么函数实现。我只是设计了简单的双人游戏模式,在这个模式中,我们需要下列几个函数:

  • 重置函数Reset();
  • 棋盘界面,我们用OnGUI();函数创建棋盘,该函数用于渲染和处理GUI事件,这意味着每次落子都会调用此函数渲染棋盘。
  • 判断函数Check();用于判断输赢。

一开始我们用一个3*3二维数组创建棋盘,并将数组的初始值设定为0,如果O方在此位置下了,将此位置的值设为1,如果X方在此位置下了,将值设为2。创建一个变量指定是谁的回合,在OnGUI()函数中,对应值为1的地方创建O的button,而对应值为2的地方创建X的button,每次落子后改变回合数。
接下来我们实现Reset()函数:

void reset()
    {
        turn = 1;//回合计数器,初始设为O的回合。
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                state [i, j] = 0;
            }
        }
    }

将这个函数放到start()中,让程序在一开始运行时初始化棋盘。
接下来我们实现判断函数check():

int check()
    {
        for (int i = 0; i < 3; i++) {
            if (state [i, 0] != 0 && state [i, 0] == state [i, 1] && state [i, 1] == state [i, 2])
                return state [i, 0];
        }
        for (int i = 0; i < 3; i++) {
            if (state [0, i] != 0 && state [0, i] == state [1, i] && state [1, i] == state [2, i])
                return state [0, i];
        }
        int flag = state [0, 0];
        int flag2 = state [0, 2];
        for (int i = 0; i < 3; i++) {
            if (state [i, i] != flag && state [i, 2 - i] != flag2)
                return 0;
        }
        if (flag == state [2, 2])
            return flag;
        else
            return flag2;
    }

采用枚举的方法判断每行,每列,每条对角线是否为3个相同的值。
最后,我们实现OnGUI函数,在实现这一函数前,我们需要具备几个与GUI有关的知识:

GUI.Box(new Rect(596, 100, 160, 350), "");//用于在GUI层上创建框架容纳包括文本,图片等元素。
GUIStyle style = new GUIStyle ();//用于改变默认GUIStyle的字体颜色,大小等属性。
GUI.Button (new Rect (x, y, width, height), String string, GUIStyle)//创建一个按钮,包括位置,大小,内容等属性,返回Boolean值表示当点击时返回true,否则返回false。
GUI.Label (new Rect (x, y, width, height), String string, GUIStyle);//Label控件(标签控件)以文本的形式来显示一串字符串信息,该控件不仅可以输入字符串信息,还可以输入贴图。

现在我们可以设计GUI了:
先建立变量result=check(),然后判断当result=1时为O赢,=2时为X赢,而平局的判定我是用遍历数组看看是否所有的棋格都已落子,若都已落子则判断为平局。
落子阶段使用循环查找空的棋格落子并且判断回合数。
具体代码如下:

void OnGUI()
    {
        GUI.Box(new Rect(596, 100, 160, 350), "");
        GUIStyle style = new GUIStyle ();
        style.normal.textColor = new Color (46f / 256f, 163f / 256f, 256f / 256f);
        style.fontSize = 24;
        if (GUI.Button (new Rect (625, 380, 100, 50), "reset")) {
            reset ();
        }
        int result = check ();
        if (result == 1) {
            GUI.Label (new Rect (630, 300, 100, 50), "O win!!!", style);
        } else if (result == 2) {
            GUI.Label (new Rect (630, 300, 100, 50), "X win!!!", style);
        }
        int flag = 0;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (state [i, j] == 0)
                    flag = 1;
            }
        }
        if (flag == 0) {
            GUI.Label (new Rect (650, 300, 100, 50), "平局", style);
        }
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (state [i, j] == 1) {
                    GUI.Button (new Rect (i * 50+600, j * 50+100, 50, 50), "O");
                }
                if (state [i, j] == 2) {
                    GUI.Button (new Rect (i * 50+600, j * 50+100, 50, 50), "X");
                }
                if (GUI.Button (new Rect (i * 50+600, j * 50+100, 50, 50), "")) {
                    if (result == 0) {
                        if (turn == 1)
                            state [i, j] = 1;
                        else
                            state [i, j] = 2;
                        turn = -turn;
                    }
                }
            }
        }
    }

到这一步基本完成了井字棋的设计了,再把脚本挂到一个空对象上就可以了。之后我添加了小小的背景音乐,具体操作就是在main camera的Audio source属性的Audio clip中添加音乐即可,当然,前提是音乐要传到asset文件夹中。
成果图:
这里写图片描述
以上是本人的初代版本。
接下来是单人模式,我设置了先手和后手模式,整体框架不变,只是添加了三个函数分别为:

void robotWin();//检测电脑怎么走才能赢
void playerWin();//检测电脑怎么走才能防止玩家赢
void randomStep();//在无法预测下一步输赢时候的走法

在两个检测函数中我都是通过枚举与循环交替使用进行检测,具体顺序是检测两条对角线,每行,每列。
之后是先后手模式下的设置,我通过设置一个按钮改变回合数以检测先后手。

if (GUI.Button (new Rect (500, 100, 80, 50), "后手")) {
            if (turn_flag == 0)
                turn = -1;
            turn_flag = 1;
        }

效果图:
这里写图片描述
由于代码过长就不列出来了,具体请上本人的github井字棋人机版

猜你喜欢

转载自blog.csdn.net/hellowangld/article/details/79713618