コード例 #1
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)]);
        }
    }
コード例 #2
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);
    }