Unity3D/C#で簡単なリバーシ(オセロ)を作る！！~Part2~ 


#はじめに
本記事は前回の「Unity3D/C#で簡単なリバーシ(オセロ)を作る！！~Part1~」 (https://qiita.com/t-o2mt/items/40e4bca24011dd88d8a7) の続きとなります。

前回は盤と石を作成し、ゲームスタート時に石を初期配置するところまで説明しました。
今回はタップして石を置く処理と、引っくり返す処理を説明します。


#タップして石を置く
```C#
    private int x;
    private int z;//タップした座標
    private eStoneState turn = eStoneState.BLACK;//ターン。最初は黒

    void Update()
    {
        PutStone();
        
        for (int i = 0; i < squareZ; i++)
        {
            for (int j = 0; j < squareX; j++)
            {
                // 石の状態を確認
                stoneManagers[i, j].SetState(stoneState[i, j]);
            }
        }
    }
    //タップで石を置く処理
    public void PutStone(){
        if (Input.GetMouseButtonDown(0))
        {
            //マウスのポジションを取得してRayに代入
            Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);

            //マウスのポジションからRayを投げて何かに当たったらhitに入れる
            if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out RaycastHit hit, 100))
            {
                //x,zの値を取得
                x = (int)hit.collider.gameObject.transform.position.x;
                z = (int)hit.collider.gameObject.transform.position.z;

                if (0 <= x && x < squareX && 0 <= z && z < squareZ &&
                    stoneState[z, x] == eStoneState.EMPTY && Turn(false) > 0)
                {
                    stoneState[z, x] = turn;
                    Turn(true);
                    turn = ((turn == eStoneState.BLACK) ? eStoneState.WHITE : eStoneState.BLACK);
                }
            }
        }
    }
```
"StageManager"に上記のコードを追加します。
Raycastの関数で得た座標をhitに入れ、xとz分け、stoneState[z, x]がeStoneState.EMPTYならturnでWHITEかBLACKに変え、Part1で記述したSetState()で石を表示させます。
これで、タップしたマスに石を置くことができます。
#石を引っくり返す
```C#
    class TurnableStone {
        public int turnZ;
        public int turnX;
        public TurnableStone(int z, int x)
        {
            turnZ = z;
            turnX = x;
        }
    }//ひっくり返すことができる駒の位置

    int[] TURN_CHECK_X = new int[] { -1, -1, 0, 1, 1, 1, 0, -1 };
    int[] TURN_CHECK_Z = new int[] { 0, 1, 1, 1, 0, -1, -1, -1 };//石の隣8方向

    //ひっくり返す石を取得する処理
        int Turn(bool isTurn)
    {
        // 相手の石の色
        eStoneState enemyColor = ((turn == eStoneState.BLACK) ? eStoneState.WHITE : eStoneState.BLACK);

        bool isTurnable = false;// ひっくり返すことができるかどうか
        List<TurnableStone> turnableStoneList = new List<TurnableStone>();//ひっくり返す石のリスト
        int count = 0;
        int turnCount = 0;

        int plusX = 0, plusZ = 0;
        for (int i = 0; i < TURN_CHECK_X.Length; i++)
        {
            int _x = x;
            int _z = z;

            plusX = TURN_CHECK_X[i];
            plusZ = TURN_CHECK_Z[i];
            isTurnable = false;
            turnableStoneList.Clear();
            while (true)
            {
                _x += plusX;
                _z += plusZ;
                if (!(0 <= _x && _x < squareX && 0 <= _z && _z < squareZ))
                {
                    break;
                }
                if (stoneState[_z, _x] == enemyColor)
                {
                    // ひっくり返す対象
                    turnableStoneList.Add(new TurnableStone(_z, _x));
                }
                else if (stoneState[_z, _x] == turn)
                {
                    // ひっくり返すことができる
                    isTurnable = true;
                    break;
                }
                else
                {
                    break;
                }
            }

            //ひっくり返す処理
            if (isTurnable)
            {
                count += turnableStoneList.Count;
                if (isTurn)
                {
                    for (int j = 0; j < turnableStoneList.Count; j++)
                    {
                        TurnableStone ts = turnableStoneList[j];
                        stoneState[ts.turnZ, ts.turnX] = turn;
                        turnCount++;
                    }
                }
            }
        }
        return count;
    }
```
"StageManager"に上記のコードを追加します。Turnはint型でreturnさせています。
TURN_CHECKで隣接する全方位の石を確認し、引っくり返すことができるものだけをturnableStoneListに格納していき、for文でturnを繰り返し行えば引っくり返しが行えます。

駆け足ですが、これでようやくオセロの超最低限の機能をつけ終わることができました！！8888888888
#最後に
<img width="576" alt="bc3930ec879f30243e4f692fa5679611.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570839/a222c06e-c9f8-402e-d09b-c0448a869eda.png">

Part1,2で説明した機能に【ランダムに石を置く敵AI】【枚数チェック】【制限時間】【勝利判定】を加えたものが上の画像です。やっぱり2Dよりきれい！！人は3Dより2D派だけど、ゲームはやっぱり3Dに限るね〜。

これにしっかりした敵AIさえつけることができればできれば、老若男女が白熱して楽しむことができる国民的ボードゲームアプリの完成です！！

ご拝読いただき、ありがとうございました。