コード例 #1
0
    //局面が同一かどうか
    public bool equals(Kyokumenn k)
    {
        //手番の比較
        if (this.turn % 2 != k.turn % 2)
        {
            return(false);
        }

        //盤面の比較
        for (int i = 1; i <= 81; i++)
        {
            if (this.banKoma[i] != k.banKoma[i])
            {
                return(false);
            }
        }
        //持ち駒の比較
        for (int koma = 0; koma < 32; koma++)
        {
            if (this.hand [0] [koma] != k.hand [0] [koma] || this.hand [1] [koma] != k.hand [1] [koma])
            {
                return(false);
            }
        }

        return(true);
    }
コード例 #2
0
    public Te getNextTe(Kyokumenn k, int tesu)
    {
        Te te;

        if ((te = joseki.fromjoseki(k, tesu)) != null)
        {
            return(te);
        }

        leaf = 0;
        node = 0;
        List <Te> teList = k.GenerateLegalMoves();

        te = teList[Random.Range(0, teList.Count)];


        if (k.turn % 2 == 1)
        {
            //評価値最大の手をえる
            this.NegaMax(ref te, k, -1000000, 1000000, 0, DEPTH_MAX);
        }
        else
        {
            //評価値最小の手をえる
            this.NegaMax(ref te, k, -100000, 1000000, 0, DEPTH_MAX);
        }

        return(te);
    }
コード例 #3
0
    public Te fromjoseki(Kyokumenn k, int tesu)
    {
        //tesuには実際の手数が渡されるが、定跡データは0手目から始まるので1ずらしておく
        tesu = tesu - 1;
        //定跡にあった候補手を入れる
        List <Te> teList = new List <Te>();
        //定跡で進めた局面を作り、渡された局面と比較する
        Kyokumenn josekiKyokumenn = new Kyokumenn();

        for (int i = 0; i < numJoseki; i++)
        {
            //平手で初期化
            josekiKyokumenn.BanShokika();

            for (int j = 0; j < tesu; j++)
            {
                if (josekiData [i][j * 2] == (byte)0 || josekiData [i][j * 2] == (byte)0xff)
                {
                    break;
                }
                Te te = josekiByteToTe(josekiData [i][j * 2], josekiData [i][j * 2 + 1], josekiKyokumenn);
                josekiKyokumenn.Move(te);
                josekiKyokumenn.turn += 1;
            }
            //局面が一致するか
            if (josekiKyokumenn.equals(k))
            {
                if (josekiData [i][tesu * 2] == (byte)0 || josekiData [i][tesu * 2] == (byte)0xff)
                {
                    continue;
                }
                //候補手を生成
                Te te = josekiByteToTe(josekiData[i][tesu * 2], josekiData[i][tesu * 2 + 1], k);
                teList.Add(te);
            }
        }


        if (teList.Count == 0)
        {
            //候補手がない場合

            /*
             * if(child != null){
             *      //子定跡がある時は、その結果を返す
             *      return child.fromjoseki(k,tesu);
             * }
             */
            //候補手がなかったのでnullを返す
            return(null);
        }
        else
        {
            //候補手の中からランダム
            //候補手がない場合
            return(teList[UnityEngine.Random.Range(0, teList.Count)]);
        }
    }
コード例 #4
0
    public Te josekiByteToTe(byte toByte, byte fromByte, Kyokumenn k)
    {
        int  f = ((int)fromByte) & 0xff;
        int  t = ((int)toByte) & 0xff;
        int  koma = 0;
        int  fs, fd, ts, td;
        bool promote = false;


        if (f > 100)
        {
            //fが100以上なら、持ち駒を打つ手
            if (k.turn % 2 == 1)
            {
                koma = (f - 100);
            }
            else
            {
                koma = (f - 100) + 16;
            }
            fs = 0;
            fd = 1;
        }
        else
        {
            //fをこのプログラムの中で使う座標の方式へ変換
            fs = 10 - ((f - 1) % 9 + 1);                           //筋
            fd = (f + 8) / 9;                                      //段

            koma = k.banKoma [(fd - 1) * 9 + fs];
        }

        //tが100以上なら成り手
        if (t > 100)
        {
            promote = true;
            t      -= 100;
        }
        ts = 10 - ((t - 1) % 9 + 1);                       //筋
        td = (t + 8) / 9;                                  //段
        Te te = new Te();

        te.koma = koma;

        te.from    = (fd - 1) * 9 + fs;
        te.to      = (td - 1) * 9 + ts;
        te.promote = promote;
        te.capture = k.banKoma [te.to];
        return(te);
    }
コード例 #5
0
    //ゲームを初めから
    public void Restart()
    {
        popupCanvas.GetComponent <Canvas>().enabled  = false;
        resultCanvas.GetComponent <Canvas>().enabled = false;
        sente.GetComponent <Text> ().text            = "P";
        gote.GetComponent <Text> ().text             = "P";
        turn.GetComponent <Text>().text = "先手";

        vsCom             = false;
        vsComGote         = false;
        kk                = new Kyokumenn();
        kk.josekiBool     = true;
        kihu              = new List <Te> ();
        historykyokumenn  = new List <Kyokumenn> ();
        this.isSelectKoma = 0;                                         //スタート時は駒を選択していない
        sikou.DEPTH_MAX   = 4;

        if (kihu.Count != 0)
        {
            kihu.Clear();
        }

        kk.turn = 1;
        kk.BanShokika();

        //初期盤面を入れる
        for (int masu = 0; masu <= 81; masu++)
        {
            kk.banKoma[masu] = Kyokumenn.SHOKI_BAN[masu];
        }

        //ボタンを有効にし、駒を正しく
        for (int i = 1; i <= 81; i++)
        {
            Masu [i - 1].GetComponent <Button> ().interactable = true;
            Masu [i - 1].GetComponent <Image>().sprite         = komaPicture[kk.banKoma[i]];
        }


        for (int koma = 1; koma < 8; koma++)
        {
            hand[koma].GetComponent <Text>().text     = kk.hand [1] [koma].ToString();
            hand[koma + 8].GetComponent <Text>().text = kk.hand [0] [koma + 16].ToString();
        }
    }
コード例 #6
0
    public Kyokumenn DeepCopyKyokumenn()                                 //ディープコピー
    {
        Kyokumenn obj = new Kyokumenn();

        //参照型は全てインスタンスをコピーする
        obj.turn = (int)this.turn;

        for (int i = 0; i < 32; i++)
        {
            obj.hand [0][i]  = this.hand [0] [i];
            obj.hand [1] [i] = (int)this.hand [1] [i];
        }


        for (int i = 0; i < 82; i++)
        {
            obj.banKoma [i] = (int)this.banKoma[i];
        }

        return(obj);
    }
コード例 #7
0
//	float countTime;

    /*
     * public void Update () {
     *      countTime += Time.deltaTime;
     *      Debug.Log ("(●・▽・●)");
     * }
     */

    private int NegaMax(ref Te t, Kyokumenn k, int alpha, int beta, int depth, int depthMax)
    {
        int value = new int();

        //深さが最大に達していたら評価値を返して終了
        if (depth >= depthMax)
        {
            leaf++;
            value = k.evaluate();

            //先手ならプラス、後手でマイナスの値を返す
            if (k.turn % 2 == 1)
            {
                return(value);
            }
            else
            {
                return(-value);
            }
        }

        node++;

        //現在の局面での合法手を生成
        var teList = new List <Te>();

        teList = k.GenerateLegalMoves();

        value = -100000000;

        for (int i = 0; i < teList.Count; i++)
        {
            Te te = teList [i];

            //その手で一手進めた局面を作る
            //		KyokumennArray nextKyokumenn = k.DeepCopyKyokumenn ();
            k.Move(te.DeepCopy());
            k.turn += 1;

            Te tempTe = new Te();

            int eval = -NegaMax(ref tempTe, k, -beta, -alpha, depth + 1, depthMax);
            k.Back(te.DeepCopy());
            k.turn -= 1;

            //大きかったら
            if (eval > value)
            {
                value = eval;

                //αの値も更新
                if (eval > alpha)
                {
                    alpha = eval;
                }
                //最善手を更新
                best [depth, depth] = te;
                t.koma    = te.koma;
                t.from    = te.from;
                t.to      = te.to;
                t.promote = te.promote;
                t.capture = k.banKoma [te.to];

                for (int j = depth + 1; j < depthMax; j++)
                {
                    best [depth, j] = best [depth + 1, j];
                }
                //βカットの条件を満たしていたらループ終了
                if (eval >= beta)
                {
                    break;
                }
            }
        }
        return(value);
    }