Пример #1
0
        /// <summary>
        /// 棋譜ツリーに、ノードを追加していきます。再帰します。
        /// </summary>
        /// <param name="node_yomiCur"></param>
        /// <param name="yomiGenjo"></param>
        /// <param name="isAiteban"></param>
        /// <param name="log"></param>
        private static void WAAA_Yomu_Loop(
            KifuNode node_yomiCur,
            MoveGenGenjo yomiGenjo,
            SsssLogGenjo log
            )
        {
            //
            // まず前提として、
            // 現手番の「被王手の局面」だけがピックアップされます。
            // これはつまり、次の局面がないときは、その枝は投了ということです。
            //

            // このハブ・ノード自身は空っぽで、ハブ・ノードの次ノードが、次局面のリストになっています。
            KifuNode hub_NextNodes = MoveGenRoutine.WAAAA_CreateNextNodes(yomiGenjo, node_yomiCur, log);

            //
            // (2)現在の局面に、読んだ局面を継ぎ足します。
            //
            node_yomiCur.AppdendNextNodes(hub_NextNodes);


            MoveGenRoutine.WAAAA_Read_NextBranch(yomiGenjo, hub_NextNodes, log);
        }
Пример #2
0
        /// <summary>
        /// 次の枝を読みます。
        /// </summary>
        private static void WAAAA_Read_NextBranch(
            MoveGenGenjo yomiGenjo,
            Node <ShootingStarlightable, KyokumenWrapper> hubNode_genTeban,
            SsssLogGenjo log
            )
        {
            // (3)次のノードをシャッフルします。
            List <Node <ShootingStarlightable, KyokumenWrapper> > nextNodes_shuffled = Converter04.NextNodes_ToList(hubNode_genTeban);

            LarabeShuffle <Node <ShootingStarlightable, KyokumenWrapper> > .Shuffle_FisherYates(ref nextNodes_shuffled);

            // (4)次の局面
            int wideCount = 0;

            foreach (KifuNode nextNode in nextNodes_shuffled)
            {
                // (5)読みの深さ2手目以降なら、横幅制限
                if (1 < yomiGenjo.YomuDeep)
                {
                    if (yomiGenjo.Args.YomuLimitter[yomiGenjo.YomuDeep] <= wideCount)
                    {
                        break;// もう次の手の横には読まない。
                    }
                }


                // 《8》カウンターを次局面へ(2手目の読み)

                // 《9》まだ深く読むなら
                if (yomiGenjo.YomuDeep + 1 < yomiGenjo.Args.YomuLimitter.Length)
                {
                    yomiGenjo.YomuDeep++;
                    yomiGenjo.Tesumi_yomiCur++;
                    yomiGenjo.Pside_teban = yomiGenjo.Pside_teban == Playerside.P1 ? Playerside.P2 : Playerside.P1; //先後を反転します。
                    MoveGenRoutine.WAAA_Yomu_Loop(nextNode, yomiGenjo, log);
                    yomiGenjo.YomuDeep--;                                                                           //元に戻します。
                    yomiGenjo.Tesumi_yomiCur--;                                                                     //元に戻します。
                    yomiGenjo.Pside_teban = yomiGenjo.Pside_teban == Playerside.P1 ? Playerside.P2 : Playerside.P1; //元に戻します。
                }
                else
                {
                    // もう深くよまないなら
                }

                wideCount++;
            }


            if (yomiGenjo.Args.YomuLimitter.Length <= yomiGenjo.YomuDeep + 1)//もう深く読まないなら
            {
                //
                // ログの書き出し
                //
                Util_GraphicalLog.Log(
                    true,//enableLog,
                    "指し手生成ログA",
                    "[" + Util_GraphicalLog.BoardFileLog_ToJsonStr(yomiGenjo.Args.LogF_moveKiki) + "]"
                    );

                // 書き出した分はクリアーします。
                yomiGenjo.Args.LogF_moveKiki.boards.Clear();
            }
        }
Пример #3
0
        /// <summary>
        /// 読む。
        ///
        /// 棋譜ツリーを作成します。
        /// </summary>
        /// <param name="kifu">この棋譜ツリーの現局面に、次局面をぶら下げて行きます。</param>
        /// <param name="enableLog"></param>
        /// <param name="isHonshogi"></param>
        /// <param name="logTag"></param>
        /// <returns></returns>
        public static void WAA_Yomu_Start(
            KifuTree kifu,
            bool isHonshogi,
            SsssLogGenjo log
            )
        {
            //------------------------------------------------------------
            // (>_<)次の1手の合法手の中からランダムに選ぶぜ☆!
            //------------------------------------------------------------
            //
            // バグ探し:
            //          ①次の1手の合法手のリスト作成
            //          ②ランダムに1手選ぶ
            //
            //          の2つしかやっていないんだが、合法手ではない手を返してくるんだぜ☆

#if DEBUG_STOPPABLE
            MessageBox.Show("ここでブレイク☆!", "デバッグ");
            System.Diagnostics.Debugger.Break();
            //throw new Exception("デバッグだぜ☆! エラーはキャッチできたかな~☆?(^▽^)");
#endif


            KifuNode node_yomiNext = (KifuNode)kifu.CurNode;// このノードに、ツリーをぶら下げていきます。
            int      yomuIndex     = 0;



            // TODO:ここではログを出力せずに、ツリーの先端で出力したい。
            GraphicalLog_File logF_moveKiki = new GraphicalLog_File();

            // TODO:「読む」と、ツリー構造が作成されます。
            //int[] yomuLimitter = new int[]{
            //    600, // 読みの1手目の横幅   // 王手回避漏れのために、合法手全読み(約600)は必要です。
            //    100, // 読みの2手目の横幅
            //    100, // 読みの3手目の横幅
            //    //2, // 読みの4手目の横幅
            //    //1 // 読みの5手目の横幅
            //};

            //// ↓これなら1手1秒で指せる☆
            //int[] yomuLimitter = new int[]{
            //    600, // 読みの1手目の横幅   // 王手回避漏れのために、合法手全読み(約600)は必要です。
            //    150, // 読みの2手目の横幅
            //    150, // 読みの3手目の横幅
            //    //2 // 読みの4手目の横幅
            //    //1 // 読みの5手目の横幅
            //};

            //int[] yomuLimitter = new int[]{
            //    600, // 読みの1手目の横幅   // 王手回避漏れのために、合法手全読み(約600)は必要です。
            //    600, // 読みの2手目の横幅
            //    600, // 読みの3手目の横幅
            //};

            //ok
            //int[] yomuLimitter = new int[]{
            //    0,   // 現局面は無視します。
            //    600, // 読みの1手目の横幅   // 王手回避漏れのために、合法手全読み(約600)は必要です。
            //    600, // 読みの2手目の横幅
            //};

            int[] yomuLimitter = new int[] {
                0,   // 現局面は無視します。
                600, // 読みの1手目の横幅   // 王手回避漏れのために、1手目は、合法手全読み(約600)は必要です。
                600, // 読みの2手目の横幅
                //600, // 読みの3手目の横幅
            };

#if DEBUG
            // ログの出力数を減らすために、読みを弱くします。

            //yomuLimitter = new int[]{
            //    0,  // 現局面は無視します。
            //    600, // 読みの1手目の横幅   // 王手回避漏れのために、合法手全読み(約600)は必要です。
            //    100, // 読みの2手目の横幅
            //    100 // 読みの3手目の横幅
            //};

            yomuLimitter = new int[] {
                0,   // 現局面は無視します。
                600, // 読みの1手目の横幅   // 王手回避漏れのために、1手目は、合法手全読み(約600)は必要です。
                600, // 読みの2手目の横幅
                //600 // 読みの3手目の横幅
            };

            //yomuLimitter = new int[]{
            //    600, // 読みの1手目の横幅   // 王手回避漏れのために、合法手全読み(約600)は必要です。
            //    600, // 読みの2手目の横幅
            //    600, // 読みの3手目の横幅
            //    100,
            //    100
            //};
#endif
            MoveGenArgs  yomiArgs  = new MoveGenArgsImpl(isHonshogi, yomuLimitter, logF_moveKiki);
            MoveGenGenjo yomiGenjo = new MoveGenGenjoImpl(yomiArgs, yomuIndex + 1, kifu.CurrentTesumi(), kifu.CountPside(node_yomiNext));
            MoveGenRoutine.WAAA_Yomu_Loop(node_yomiNext, yomiGenjo, log);

            if (0 < logF_moveKiki.boards.Count)//ログが残っているなら
            {
                //
                // ログの書き出し
                //
                Util_GraphicalLog.Log(
                    true,//enableLog,
                    "MoveRoutine#Yomi_NextNodes(00)新ログ",
                    "[" + Util_GraphicalLog.BoardFileLog_ToJsonStr(logF_moveKiki) + "]"
                    );

                // 書き出した分はクリアーします。
                logF_moveKiki.boards.Clear();
            }
        }
Пример #4
0
        /// <summary>
        /// まず前提として、
        /// 現手番の「被王手の局面」だけがピックアップされます。
        /// これはつまり、次の局面がないときは、その枝は投了ということです。
        /// </summary>
        /// <param name="enableLog"></param>
        /// <param name="isHonshogi"></param>
        /// <param name="yomuDeep"></param>
        /// <param name="tesumi_yomiCur"></param>
        /// <param name="pside_yomiCur"></param>
        /// <param name="node_yomiCur"></param>
        /// <param name="logF_moveKiki"></param>
        /// <param name="logTag"></param>
        /// <returns>複数のノードを持つハブ・ノード</returns>
        private static KifuNode WAAAA_CreateNextNodes(
            MoveGenGenjo genjo,
            KifuNode node_yomiCur,
            SsssLogGenjo log
            )
        {
            // 利きから、被王手の局面を除いたハブノード
            // このハブ・ノード自身は空っぽで、ハブ・ノードの次ノードが、次局面のリストになっています。
            KifuNode hubNode;

            {
                // ①現手番の駒の移動可能場所_被王手含む
                List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus;
                {
                    GraphicalLog_Board logBrd_move1 = new GraphicalLog_Board();// 盤1個分のログの準備

                    Util_MovableMove.LA_Get_KomaBETUSusumeruMasus(
                        out komaBETUSusumeruMasus,              //進めるマス
                        new MmGenjo_MovableMasuImpl(
                            genjo.Args.IsHonshogi,              //本将棋か
                            node_yomiCur.Value.ToKyokumenConst, //現在の局面
                            genjo.Pside_teban,                  //手番
                            false                               //相手番か
                            ),
                        new MmLogGenjoImpl(
                            log.EnableLog,        //ログを出力するかfalse,
                            logBrd_move1,         //ログ?
                            genjo.YomuDeep,       //読みの深さ
                            genjo.Tesumi_yomiCur, //手済み
                            node_yomiCur.Key      //指し手
                            )
                        );

                    MoveGenRoutine.Log1(genjo, node_yomiCur, logBrd_move1);//ログ試し
                }


                // ②利きから、被王手の局面を除いたハブノード
                if (genjo.Args.IsHonshogi)
                {
                    Maps_OneAndMulti <Finger, ShootingStarlightable> komaBETUAllMoves = Converter04.KomaBETUSusumeruMasusToKomaBETUAllMoves(komaBETUSusumeruMasus, node_yomiCur);
                    Converter04.AssertNariMove(komaBETUAllMoves, "#WAAAA_CreateNextNodes(1)");

                    // 本将棋の場合、王手されている局面は削除します。
                    hubNode = Util_LegalMove.LA_RemoveMate(
                        genjo.Args.IsHonshogi,
                        komaBETUAllMoves,
                        genjo.YomuDeep,
                        genjo.Tesumi_yomiCur,
                        genjo.Pside_teban,
                        node_yomiCur,
                        log.EnableLog,
                        genjo.Args.LogF_moveKiki,//利き用
                        "読みNextルーチン");

                    Converter04.AddNariMove(node_yomiCur, hubNode);


                    Converter04.AssertNariMove(hubNode, "#WAAAA_CreateNextNodes(2)");//ここで消えていた☆
                }
                else
                {
                    //そのまま変換
                    Dictionary <ShootingStarlightable, KyokumenWrapper> ss = Converter04.KomabetuMasusToMovebetuSky(
                        komaBETUSusumeruMasus,
                        node_yomiCur.Value.ToKyokumenConst,
                        genjo.Pside_teban);
                    hubNode = Converter04.MovebetuSky_ToHubNode(ss, KifuNodeImpl.GetReverseTebanside(genjo.Pside_teban));
                }
            }

            return(hubNode);
        }