Ejemplo n.º 1
0
        /// <summary>
        /// もう深く読まない場合の処理。
        /// </summary>
        private static void Do_Leaf(
            Tansaku_Genjo genjo,
            KifuNode node_yomi,
            EvaluationArgs args,
            out float out_a_childrenBest
            )
        {
            // 局面に評価値を付けます。
            Util_Scoreing.DoScoreing_Kyokumen(
                node_yomi,//mutable
                args
                );
            // 局面の評価値。
            out_a_childrenBest = node_yomi.Score;

#if DEBUG_ALPHA_METHOD
            Logger.Trace($"1. 手({node_yomi.Value.ToKyokumenConst.Temezumi})読({yomiDeep}) 兄弟最善=[{a_siblingDecidedValue}] 子ベスト=[{a_childrenBest}]");
#endif

#if DEBUG
            bool enableLog = false;
            //
            // ログの書き出し
            //
            Util_GraphicalLog.WriteHtml5(
                enableLog,
                "指し手生成ログA",
                $"[{Conv_KaisetuBoards.ToJsonStr(genjo.Args.LogF_moveKiki)}]"
                );
            // 書き出した分はクリアーします。
            genjo.Args.LogF_moveKiki.boards.Clear();
#endif

            //#if DEBUG
            //                    //
            //                    // 盤1個分のログの準備
            //                    //
            //                    Util_LogBuilder510.Build_LogBoard(
            //                        nodePath,
            //                        niniNode,
            //                        kifu_forAssert,
            //                        reportEnvironment,
            //                        logF_kiki,
            //                        logTag
            //                    );
            //#endif
        }
Ejemplo n.º 2
0
        /// <summary>
        /// ループに入る前に。
        /// </summary>
        /// <param name="genjo"></param>
        /// <param name="node_yomi"></param>
        /// <param name="out_moveBetuEntry"></param>
        /// <param name="out_yomiDeep"></param>
        /// <param name="out_a_childrenBest"></param>
        private static void CreateEntries_BeforeLoop(
            Tansaku_Genjo genjo,
            KifuNode node_yomi,
            out Dictionary <string, SasuEntry> out_moveBetuEntry,
            out int out_yomiDeep,
            out float out_a_childrenBest
            )
        {
            out_moveBetuEntry = Tansaku_FukasaYusen_Routine.WAAAA_Create_ChildNodes(
                genjo,
                node_yomi.Key,
                node_yomi.Value.KyokumenConst);

            out_yomiDeep = node_yomi.Value.KyokumenConst.Temezumi - genjo.YomikaisiTemezumi + 1;


            //--------------------------------------------------------------------------------
            // ↓↓↓↓アルファベータ法の準備
            //--------------------------------------------------------------------------------
            out_a_childrenBest = Util_Scoreing.Initial_BestScore(node_yomi.Value.KyokumenConst);// プレイヤー1ならmax値、プレイヤー2ならmin値。
            //--------------------------------------------------------------------------------
            // ↑↑↑↑アルファベータ法の準備
            //--------------------------------------------------------------------------------
        }
Ejemplo n.º 3
0
        /// <summary>
        /// 棋譜ツリーに、ノードを追加していきます。再帰します。
        /// </summary>
        /// <param name="genjo"></param>
        /// <param name="alphabeta_otherBranchDecidedValue"></param>
        /// <param name="args"></param>
        /// <returns>子の中で最善の点</returns>
        private static float WAAA_Yomu_Loop(
            Tansaku_Genjo genjo,
            float a_parentsiblingDecidedValue,
            KifuNode node_yomi,
            int moveBetuEntry_count,
            EvaluationArgs args
            )
        {
            float a_childrenBest;

            //
            // まず前提として、
            // 現手番の「被王手の局面」だけがピックアップされます。
            // これはつまり、次の局面がないときは、その枝は投了ということです。
            //

            //
            // (1)合法手に一対一対応した子ノードを作成し、ハブ・ノードにぶら下げます。
            //
            Dictionary <string, SasuEntry> moveBetuEntry2;
            int yomiDeep2;

            Tansaku_FukasaYusen_Routine.CreateEntries_BeforeLoop(
                genjo,
                node_yomi,
                out moveBetuEntry2,
                out yomiDeep2,
                out a_childrenBest
                );

            int wideCount1 = 0;

            foreach (KeyValuePair <string, SasuEntry> entry in moveBetuEntry2)
            {
                if (Tansaku_FukasaYusen_Routine.CanNotNextLoop(
                        yomiDeep2,
                        wideCount1,
                        moveBetuEntry2.Count,
                        genjo
                        ))
                {
                    //----------------------------------------
                    // もう深くよまないなら
                    //----------------------------------------
                    Tansaku_FukasaYusen_Routine.Do_Leaf(
                        genjo,
                        node_yomi,
                        args,
                        out a_childrenBest
                        );

                    wideCount1++;
                    break;
                }
                else
                {
                    //----------------------------------------
                    // 《9》まだ深く読むなら
                    //----------------------------------------
                    // 《8》カウンターを次局面へ


                    // このノードは、途中節か葉か未確定。

                    //
                    // (2)指し手を、ノードに変換し、現在の局面に継ぎ足します。
                    //
                    KifuNode childNode1;

                    if (node_yomi.ContainsKey_ChildNodes(entry.Key))
                    {
                        childNode1 = (KifuNode)node_yomi.GetChildNode(entry.Key);
                    }
                    else
                    {
                        // 既存でなければ、作成・追加
                        childNode1 = Conv_SasuEntry.ToKifuNode(entry.Value, node_yomi.Value.KyokumenConst);
                        node_yomi.PutAdd_ChildNode(entry.Key, childNode1);
                    }

                    // これを呼び出す回数を減らすのが、アルファ法。
                    // 枝か、葉か、確定させにいきます。
                    float a_myScore = Tansaku_FukasaYusen_Routine.WAAA_Yomu_Loop(
                        genjo,
                        a_childrenBest,
                        childNode1,
                        moveBetuEntry2.Count,
                        args);
                    Util_Scoreing.Update_Branch(
                        a_myScore, //a_childrenBest,
                        node_yomi  //mutable
                        );

                    //----------------------------------------
                    // 子要素の検索が終わった時点
                    //----------------------------------------
                    bool alpha_cut;
                    Util_Scoreing.Update_BestScore_And_Check_AlphaCut(
                        yomiDeep2,// yomiDeep0,
                        node_yomi,
                        a_parentsiblingDecidedValue,
                        a_myScore,
                        ref a_childrenBest,
                        out alpha_cut
                        );

                    wideCount1++;

#if DEBUG_ALPHA_METHOD
                    Logger.Trace($"3. 手({node_yomi.Value.ToKyokumenConst.Temezumi})読({yomiDeep}) 兄弟最善=[{a_siblingDecidedValue}] 子ベスト=[{a_childrenBest}] 自点=[{a_myScore}]");
#endif
                    if (alpha_cut)
                    {
#if DEBUG_ALPHA_METHOD
                        Logger.Trace("アルファ・カット☆!");
#endif
                        //----------------------------------------
                        // 次の「子の弟」要素はもう読みません。
                        //----------------------------------------

                        //*TODO:
                        break;
                        //toBreak1 = true;
                        // */
                    }
                }


                // gt_NextLoop:
                //    ;
            }

            return(a_childrenBest);
        }