Пример #1
0
 /// <summary>
 /// グローバル変数に結果を入れるぜ☆(^~^)
 /// </summary>
 /// <param name="out_list"></param>
 /// <param name="hyoji"></param>
 /// <returns></returns>
 public static bool TryFailMoveCmd1(StringBuilder hyoji)
 {
     //グローバル変数に指し手がセットされるぜ☆(^▽^)
     PureMemory.SetTnskFukasa(PureMemory.FUKASA_MANUAL);
     MoveGenAccessor.DoMovePickerBegin(MoveType.N21_All);
     MovePicker01.MovePickerN01(MoveType.N21_All, true);
     return(Pure.SUCCESSFUL_FALSE);
 }
Пример #2
0
        public static bool Try_Rnd(
#if DEBUG
            IDebugMojiretu dbg_reigai
#endif
            )
        {
            //グローバル変数に指し手がセットされるぜ☆(^▽^)
            PureMemory.SetTnskFukasa(PureMemory.FUKASA_MANUAL);
            MoveGenAccessor.DoMovePickerBegin(MoveType.N21_All);
            MovePicker01.MovePickerN01(MoveType.N21_All, true);

            if (PureMemory.ssss_moveList[PureMemory.FUKASA_MANUAL].listCount < 1)
            {
                Move     ss     = Move.Toryo;
                MoveType ssType = MoveType.N00_Karappo;
                if (DoMoveOpe.TryFailDoMoveAll(ss, ssType
#if DEBUG
                                               , PureSettei.fenSyurui
                                               , dbg_reigai
                                               , false
                                               , "Try_Rnd(1)"
#endif
                                               ))
                {
                    return(false);
                }
                // 手番を進めるぜ☆(^~^)
                MoveGenAccessor.AddKifu(ss, ssType, PureMemory.dmv_ks_c);
//#if DEBUG
//                Util_Tansaku.Snapshot("Rndコマンド", dbg_reigai);
//#endif
            }
            else
            {
                Move ss = PureMemory.ssss_moveList[PureMemory.FUKASA_MANUAL].moveList[PureSettei.random.Next(PureMemory.ssss_moveList[PureMemory.FUKASA_MANUAL].listCount)];

                MoveType ssType = MoveType.N00_Karappo;
                if (DoMoveOpe.TryFailDoMoveAll(ss, ssType
#if DEBUG
                                               , PureSettei.fenSyurui
                                               , dbg_reigai
                                               , false
                                               , "Try_Rnd(2)"
#endif
                                               ))
                {
                    return(false);
                }
                // 手番を進めるぜ☆(^~^)
                MoveGenAccessor.AddKifu(ss, ssType, PureMemory.dmv_ks_c);
//#if DEBUG
//                Util_Tansaku.Snapshot("Rnd(2)", dbg_reigai);
//#endif
            }
            return(true);
        }
Пример #3
0
        /// <summary>
        /// 探索だぜ☆(^▽^)
        /// </summary>
        /// <param name="ky"></param>
        /// <param name="alpha"></param>
        /// <param name="fukasa">カウントダウン式の数字☆(^▽^) 反復深化探索の1週目の初期値は 1、2週目の初期値は 2 だぜ☆(^▽^)
        /// これがどんどんカウントダウンしていくぜ☆(^▽^) 0 で呼び出されたときは葉にしてすぐ処理を終われよ☆(^▽^)www</param>
        /// <param name="out_yomisujiToBack"></param>
        /// <param name="out_bestHyokatiAb1">手番から見た指し手の評価値だぜ☆(^~^)</param>
        /// <param name="out_edaBest_Komawari_JohoNoTame">内訳の目視確認用に使うだけの項目。</param>
        /// <param name="out_edaBest__Okimari_JohoNoTame">内訳の目視確認用に使うだけの項目。</param>
        /// <param name="out_edaBest_____Riyu_JohoNoTame">内訳の目視確認用に使うだけの項目。</param>
        /// <param name="dlgt_CreateJoho"></param>
        /// <returns></returns>
        private static void Tansaku_(
            out Move out_bestMove,
            out Hyokati out_bestHyokasu // 手番側の指し手の評価値だぜ☆(^~^)
            )
        {
            Debug.Assert(0 <= PureMemory.tnsk_fukasa && PureMemory.tnsk_fukasa < PureMemory.ssss_moveList.Length, "");

            out_bestMove    = Move.Toryo;
            out_bestHyokasu = null;

            //────────────────────────────────────────
            // 時間切れ判定
            //────────────────────────────────────────
            if (ComSettei.timeManager.IsTimeOver_TansakuChu())
            {
                out_bestMove    = Move.Toryo;
                out_bestHyokasu = new Hyokati(
                    Conv_Hyokati.Hyokati_Rei,
                    Conv_Tumesu.Stalemate,
                    true // 今回の探索の結果は破棄するぜ☆(^~^)
#if DEBUG
                    , Conv_Hyokati.Hyokati_Rei
                    , Conv_Hyokati.Hyokati_Rei
                    , Conv_Hyokati.Hyokati_Rei
                    , HyokaRiyu.JikanGire
                    , ""
#endif
                    );
#if DEBUG
                Util_Tansaku.Snapshot("時間切れだぜ☆(^~^)", out_bestMove);
#endif
                return;
            }

            //────────────────────────────────────────
            // 葉
            //────────────────────────────────────────
            #region 葉
            if (
                // 深さ0 で呼び出されたときは、葉にしろということだぜ☆(^▽^)www
                PureMemory.tnsk_fukasa == 0
                )
            {
                // 深さ(根っこからの深さ)は 1 以上で始まるから、ループの1週目は、スルーされるはずだぜ☆(^▽^)
                // 1手指して 枝を伸ばしたとき、相手の手番の局面になっているな☆(^▽^)そのとき ここを通る可能性があるぜ☆

                //
                // 末端局面で評価値を作らないぜ☆(^~^)!
                // 指し手を、指したときに作るんだぜ☆(^~^)!
                //

                PureMemory.tnsk_happaTeme = PureMemory.kifu_endTeme;

                // 「手目」カーソルは DoMove で1つ進んでいるはずなので、戻すんだぜ☆(^~^)
                out_bestMove    = PureMemory.kifu_moveArray[PureMemory.kifu_endTeme - 1];
                out_bestHyokasu = new Hyokati(PureMemory.gky_hyokati);


                // 葉で情報表示
                Util_Joho.JohoMatome(
                    PureMemory.tnsk_fukasa + 1,
                    out_bestHyokasu,
                    PureMemory.tnsk_hyoji
#if DEBUG
                    , out_bestHyokasu.dbg_riyu.ToString()
#endif
                    );
#if DEBUG
                Util_Tansaku.Snapshot("葉だぜ☆(^~^)", out_bestMove);
#endif
                return;//枝を戻る(正常終了)
            }
            #endregion

            //────────────────────────────────────────
            // 指し手生成
            //────────────────────────────────────────
            // グローバル変数 Util_MoveSeisei.Sslist に指し手がセットされるぜ☆(^▽^)
            MoveGenAccessor.DoMovePickerBegin(MoveType.N21_All);
            MovePicker01.MovePickerN01(MoveType.N21_All, true);

            #region ステイルメイト
            //────────────────────────────────────────
            // ステイル・メイト
            //────────────────────────────────────────
            if (PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].listCount < 1)
            {
                // 詰んでるぜ☆(^~^)
                out_bestMove    = Move.Toryo;
                out_bestHyokasu = new Hyokati(
                    Conv_Hyokati.Hyokati_Rei,
                    Conv_Tumesu.Stalemate,
                    false
#if DEBUG
                    , Conv_Hyokati.Hyokati_Rei
                    , Conv_Hyokati.Hyokati_Rei
                    , Conv_Hyokati.Hyokati_Rei
                    , HyokaRiyu.Stalemate
                    , ""
#endif
                    );

                // ステイルメイトで情報表示
                Util_Joho.JohoMatome(
                    PureMemory.tnsk_fukasa + 1,// 深さは 0 になっているので、Tansaku していない状態(=+1 して)に戻すぜ☆
                    out_bestHyokasu,
                    PureMemory.tnsk_hyoji
#if DEBUG
                    , "Stalemate"
#endif
                    );
#if DEBUG
                Util_Tansaku.Snapshot("ステイルメイトだぜ☆(^~^)", out_bestMove);
                MoveSeiseiAccessor.DumpMoveSeisei(PureMemory.tnsk_hyoji);
#endif
                return;//枝を戻る(正常終了)
            }
            #endregion


            for (int iSs = 0; iSs < PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].listCount; iSs++)
            {
                // 枝☆ 適当にここらへんでカウントアップするかだぜ☆(^~^)
                PureMemory.tnsk_tyakusyuEdas++;



                //────────────────────────────────────────
                // 指す
                //────────────────────────────────────────

//#if DEBUG
//                Util_Tansaku.Snapshot("ドゥ前", hyoji);
//#endif

                Move     ss_jibun     = PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].moveList[iSs];
                MoveType ssType_jibun = PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].moveTypeList[iSs];

                if (DoMoveOpe.TryFailDoMoveAll(
                        ss_jibun,
                        ssType_jibun
#if DEBUG
                        , PureSettei.fenSyurui
                        , (IDebugMojiretu)PureMemory.tnsk_hyoji
                        , false
                        , "TryFail_Tansaku_(1)"
#endif
                        ))
                {
                    // 探索時にエラーが起こった場合は強制終了☆(^~^)
                    throw new Exception(PureMemory.tnsk_hyoji.ToString());
                }
                // 手番を進めるぜ☆(^~^)
                MoveGenAccessor.AddKifu(
                    ss_jibun,
                    ssType_jibun,
                    PureMemory.dmv_ks_c);
#if DEBUG
                Util_Tansaku.Snapshot("ドゥ後・探索前", out_bestMove);
#endif

                Move ss_aite;
                //MoveType eda_moveType;
                // goto文で飛ぶと未割当になるので、ヌルでも入れておくぜ☆(^~^)
                Hyokati hyokasu_aiteToJibun = null;

                // この指し手が、駒を取った手かどうか☆

                PureMemory.SetTnskHyoji(PureMemory.tnsk_hyoji);
                // 探索者がプラスでスタートして、
                // 探索者の反対側はマイナスになり、
                // 探索者の反対側の反対側はプラスに戻るぜ☆(^▽^)
                PureMemory.DecreaseTnskFukasa();
                Tansaku_(
                    out ss_aite,
                    out hyokasu_aiteToJibun
                    // 相手番の指し手の評価値が入ってくるぜ☆(^~^)
                    );
                PureMemory.IncreaseTnskFukasa();
//#if DEBUG
//                Util_Tansaku.Snapshot("探索後・アンドゥ前", hyoji);
//#endif

                //────────────────────────────────────────
                // 詰みを発見していれば、打ち切りフラグを立てるぜ☆(*^~^*)
                //────────────────────────────────────────
                bool undoAndBreak = false;
                if (hyokasu_aiteToJibun.tumeSu == Conv_Tumesu.CatchRaion)
                {
                    out_bestMove    = ss_jibun;
                    out_bestHyokasu = new Hyokati(
                        Conv_Hyokati.Hyokati_Rei,
                        Conv_Tumesu.CatchRaion,// この枝にこれるようなら、勝ち宣言だぜ☆(^▽^)
                        false
                #if DEBUG
                        , Conv_Hyokati.Hyokati_Rei
                        , Conv_Hyokati.Hyokati_Rei
                        , Conv_Hyokati.Hyokati_Rei
                        , HyokaRiyu.TansakuRaionCatch
                        , ""
                #endif
                        );
                    // 打ち切りで情報表示
                    Util_Joho.JohoMatome(
                        PureMemory.tnsk_fukasa,
                        out_bestHyokasu,
                        PureMemory.tnsk_hyoji
#if DEBUG
                        , "TansakuRaionCatch"
#endif
                        );

                    // 詰みではなく、らいおんきゃっち または トライかを 調べるぜ☆(^~^)
                    // この手番は、
                    // この指し手を選べば、勝てるという理屈だが……☆
                    undoAndBreak = true;
#if DEBUG
                    Util_Tansaku.Snapshot("らいおんキャッチだぜ☆(^~^)", out_bestMove);
#endif
                }

                // 探索で先の枝から戻ってきたときは、評価の符号を反転し、詰め手数のカウントもアップするぜ☆(^~^)
                hyokasu_aiteToJibun.CountUpTume();
                hyokasu_aiteToJibun.ToHanten();



                if (UndoMoveOpe.TryFailUndoMove(
#if DEBUG
                        PureSettei.fenSyurui
                        , (IDebugMojiretu)PureMemory.tnsk_hyoji
#endif
                        ))
                {
                    // 探索時にエラーが起こった場合は強制終了☆(^~^)
                    throw new Exception(PureMemory.tnsk_hyoji.ToString());
                }

#if DEBUG
                Util_Tansaku.Snapshot("アンドゥ後", out_bestMove);
#endif

                //────────────────────────────────────────
                // これ以上 弟要素を探索するのを止め、枝を戻るかどうか☆(^~^)
                //────────────────────────────────────────
                #region 打ち切り各種
                if (undoAndBreak)
                {
                    // (1)千日手の権利を相手に渡すために低点数付け<それ以降の手は読まない>
                    // (2)らいおん を捕獲した
                    // (3)トライ した
#if DEBUG
                    Util_Tansaku.Snapshot("アンドゥ後ブレイクだぜ☆(^~^)", out_bestMove);
#endif
                    break;//枝を戻る(正常終了)
                }
                #endregion

                //────────────────────────────────────────
                // アップデート・枝ベスト
                //────────────────────────────────────────
                #region アップデート・枝ベスト

                // 点数が付かないことがあって、その場合 ベスト指し手 を1度も選ばない
                // 「<=」にすると同点だったら、指し手のオーダリングの低いのを選ぶが☆(^~^)
                if (null == out_bestHyokasu)
                {
                    out_bestMove    = ss_jibun;
                    out_bestHyokasu = hyokasu_aiteToJibun;// new HyokaSu(eda_hyokasu);//ここで新規作成
#if DEBUG
                    Util_Tansaku.Snapshot("アップデート枝ベスト1回目だぜ☆(^~^)", out_bestMove);
#endif
                }
                else if (out_bestHyokasu.hyokaTen < hyokasu_aiteToJibun.hyokaTen)
                {
                    out_bestMove = ss_jibun;
                    out_bestHyokasu.ToSet(hyokasu_aiteToJibun);

                    // 兄弟の中で一番の読み筋だぜ☆(^▽^)
                    // ↓
                    // TODO: ここで情報を表示したいが……☆(^~^)
#if DEBUG
                    Util_Tansaku.Snapshot("アップデート枝ベストだぜ☆(^~^)", out_bestMove);
#endif
                }
                #endregion
            }//指し手ループ
             //;

            // このノードでの最大評価を返すんだぜ☆(^▽^)
            // ここでアルファを返してしまうと、アルファが1回も更新されなかったときに、このノードの最大評価ではないものを返してしまうので不具合になるぜ☆(^~^)

            if (null == out_bestHyokasu)
            {
                out_bestMove    = Move.Toryo;
                out_bestHyokasu = new Hyokati(
                    Conv_Hyokati.Hyokati_Rei,
                    Conv_Tumesu.None,
                    false
#if DEBUG
                    , Conv_Hyokati.Hyokati_Rei
                    , Conv_Hyokati.Hyokati_Rei
                    , Conv_Hyokati.Hyokati_Rei
                    , HyokaRiyu.Fumei
                    , "ループ抜け"
#endif
                    );

                // ステイルメイトで情報表示
                Util_Joho.JohoMatome(
                    PureMemory.tnsk_fukasa,
                    out_bestHyokasu,
                    PureMemory.tnsk_hyoji
#if DEBUG
                    , "LoopOut"
#endif
                    );

#if DEBUG
                Util_Tansaku.Snapshot("評価の決まらない、ループ抜けだぜ☆(^~^)", out_bestMove);
#endif
                return;//枝を戻る(正常終了)
            }
        }