Exemplo n.º 1
0
        /// <summary>
        /// 局面に、評価値を付けます。
        /// </summary>
        public static void DoScoreing_Kyokumen(
            KifuNode node_yomi_mutable,
            EvaluationArgs args
            )
        {
            //----------------------------------------
            // 千日手判定
            //----------------------------------------
            bool isSennitite;

            {
                ulong hash = Conv_Sky.ToKyokumenHash(node_yomi_mutable.Value.KyokumenConst);
                if (args.SennititeConfirmer.IsNextSennitite(hash))
                {
                    // 千日手になる場合。
                    isSennitite = true;
                }
                else
                {
                    isSennitite = false;
                }
            }

            // 局面スコア
            node_yomi_mutable.KyHyokaSheet_Mutable.Clear();

            if (isSennitite)
            {
                // 千日手用の評価をします。
                Hyokakansu hyokakansu = Util_HyokakansuCollection.Hyokakansu_Sennichite;

                float score;
#if DEBUG || LEARN
                KyHyokaMeisai_Koumoku meisai;
#endif
                hyokakansu.Evaluate(
                    out score,
#if DEBUG || LEARN
                    out meisai,
#endif
                    node_yomi_mutable.Value.KyokumenConst,
                    args.FeatureVector
                    );

                node_yomi_mutable.AddScore(score);
#if DEBUG || LEARN
                node_yomi_mutable.KyHyokaSheet_Mutable.Add(
                    hyokakansu.Name.ToString(),
                    meisai
                    );
#endif
            }
            else
            {
                Util_HyokakansuCollection.EvaluateAll_Normal(
                    node_yomi_mutable,
                    args.FeatureVector
                    );
            }
        }
Exemplo n.º 2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="node_mutable">この評価シートに明細項目を追加します。</param>
        /// <param name="fv"></param>
        public static void EvaluateAll_Normal(
            KifuNode node_mutable,
            FeatureVector fv
            )
        {
            // 妄想と、指定のノードを比較し、点数付けします。
            foreach (Hyokakansu hyokakansu in Util_HyokakansuCollection.Hyokakansu_Normal)
            {
                float score;
#if DEBUG || LEARN
                KyHyokaMeisai_Koumoku meisai;
#endif
                hyokakansu.Evaluate(
                    out score,
#if DEBUG || LEARN
                    out meisai,
#endif
                    node_mutable.Value.KyokumenConst,
                    fv
                    );

                node_mutable.AddScore(score);
#if DEBUG || LEARN
                node_mutable.KyHyokaSheet_Mutable.Add(
                    hyokakansu.Name.ToString(),
                    meisai
                    );
#endif
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// 盤1個分のログ。
        /// </summary>
        private void Log_Board(
            IEngineConf engineConf,
            string nodePath,
            KifuNode node,
            KifuTree kifu,
            string logDirectory,
            ReportEnvironment reportEnvironment
            )
        {
            // 出力先
            string basename = $"#{((int)node.KyHyoka.Total())}点_{KyHyokaWriterImpl.logFileCounter}_{nodePath}.log.png"; // TODO

            //
            // 画像ログ
            //
            if (true)
            {
                //SFEN文字列と、出力ファイル名を指定することで、局面の画像ログを出力します。
                KyokumenPngWriterImpl.Write1(
                    engineConf,
                    node.ToRO_Kyokumen1(),
                    Path.Combine(logDirectory, basename),
                    reportEnvironment
                    );
                KyHyokaWriterImpl.logFileCounter++;
            }

            //
            // スコア明細
            //
            {
                KyHyokaListWriterImpl.Write(basename, node, logDirectory, reportEnvironment);
            }
        }
Exemplo n.º 4
0
 public KyHandanArgsImpl(
     TenonagareGenjo tenonagareGenjo,
     KifuNode node,
     PlayerInfo playerInfo
     )
 {
     this.tenonagareGenjo = tenonagareGenjo;
     this.node            = node;
     this.playerInfo      = playerInfo;
 }
Exemplo n.º 5
0
 public static void Update_Branch(
     float alphabeta_bestScore,
     KifuNode node_yomi_mutable
     )
 {
     // FIXME: 点数(評価明細)を上書きしているような。
     // 枝はこれでいいのか?
     node_yomi_mutable.SetScore(alphabeta_bestScore);
     node_yomi_mutable.SetBranchKyHyokaSheet(new KyHyokaSheetImpl(alphabeta_bestScore));
 }
Exemplo n.º 6
0
        /// <summary>
        /// ベスト・スコアを更新します。
        /// アルファ・カットの有無も調べます。
        /// </summary>
        /// <param name="node_yomi"></param>
        /// <param name="a_parentsiblingDecidedValue"></param>
        /// <param name="a_myScore"></param>
        /// <param name="ref_a_childBest"></param>
        /// <param name="alpha_cut"></param>
        public static void Update_BestScore_And_Check_AlphaCut(
            int yomiDeep,//1start
            KifuNode node_yomi,
            float a_parentsiblingDecidedValue,
            float a_myScore,
            ref float ref_a_childBest,
            out bool alpha_cut
            )
        {
            // このノードが、どちらの手番か。
            Playerside pside = node_yomi.Value.KyokumenConst.KaisiPside;

            alpha_cut = false;
            switch (pside)
            {
            case Playerside.P1:
                // 1プレイヤーは、大きな数を見つけたい。
                if (ref_a_childBest < a_myScore)
                {
                    ref_a_childBest = a_myScore;
                }
                //----------------------------------------
                // アルファー・カット
                //----------------------------------------
                if (1 < yomiDeep && a_parentsiblingDecidedValue < ref_a_childBest)
                {
                    // 親の兄が既に見つけている数字より 大きな数字を見つけた場合
                    alpha_cut = true;    //探索を打ち切り
                }
                break;

            case Playerside.P2:
                // 2プレイヤーは、小さな数を見つけたい。
                if (a_myScore < ref_a_childBest)
                {
                    ref_a_childBest = a_myScore;
                }
                //----------------------------------------
                // アルファー・カット
                //----------------------------------------
                if (1 < yomiDeep && ref_a_childBest < a_parentsiblingDecidedValue)
                {
                    // 親の兄が既に見つけている数字より 小さな数字を見つけた場合
                    alpha_cut = true;    //探索を打ち切り
                }
                break;

            default: throw new Exception("子要素探索中、プレイヤーサイドのエラー");
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// 評価明細の書き出し。
        /// </summary>
        /// <param name="id"></param>
        /// <param name="node"></param>
        /// <param name="treeFolder"></param>
        /// <param name="env"></param>
        public static void AAAA_Write_HyokaMeisai(
            IEngineConf engineConf,
            string id,
            KifuNode node,
            string treeFolder,
            KyokumenPngEnvironment env
            )
        {
            StringBuilder sb = new StringBuilder();

            // 見出し
            sb.Append(id);
            sb.Append("    ");
            sb.Append(((int)node.Score).ToString());
            sb.Append("    ");
            switch (node.Value.KyokumenConst.KaisiPside)
            {
            case Playerside.P1: sb.Append("P2が指し終えた局面。手番P1"); break;

            case Playerside.P2: sb.Append("P1が指し終えた局面。手番P2"); break;

            case Playerside.Empty: sb.Append("手番Empty"); break;
            }
            sb.AppendLine();

            foreach (KeyValuePair <string, KyHyokaMeisai_Koumoku> entry in node.KyHyokaSheet_Mutable.Items)
            {
                KyHyokaMeisai_Koumoku koumoku = ((KyHyokaMeisai_Koumoku)entry.Value);

                sb.Append("    ");

                sb.Append(entry.Key);            //項目名
                sb.Append("  ");
                sb.Append(koumoku.UtiwakeValue); //評価値
                sb.Append("  ");

                sb.Append(koumoku.Utiwake);//内訳
                sb.AppendLine();
            }
            sb.AppendLine();

            ////------------------------------
            //// TODO: 局面ハッシュ
            ////------------------------------
            //sb.Append("hash:");
            //sb.AppendLine(Conv_Sky.ToKyokumenHash(node.Value.ToKyokumenConst).ToString());
            //sb.AppendLine();

            File.AppendAllText($"{env.OutFolder}{treeFolder}{engineConf.GetResourceBasename("HyokaMeisaiLogTxtBasename")}", sb.ToString());
        }
Exemplo n.º 8
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
        }
Exemplo n.º 9
0
        /// <summary>
        /// 盤1個分のログ。
        /// </summary>
        public static void Build_LogBoard(
            Node <IMove, KyokumenWrapper> node_forLog,
            string nodePath,
            KifuNode niniNode, //任意のノード
                               //KifuTree kifu_forAssert,
            KyokumenPngEnvironment reportEnvironment,
            KaisetuBoards logF_kiki
            )
        {
            //
            // HTMLログ
            //
            if (logF_kiki.boards.Count < 30)//出力件数制限
            {
                KaisetuBoard logBrd_move1 = new KaisetuBoard();

                List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus;
                Playerside pside = niniNode.Value.KyokumenConst.KaisiPside;
                Util_KyokumenMoves.LA_Split_KomaBETUSusumeruMasus(
                    2,
                    //node_forLog,
                    out komaBETUSusumeruMasus,
                    true,                         //本将棋
                    niniNode.Value.KyokumenConst, //現在の局面
                    pside,
                    false
                    //#if DEBUG
                    ,
                    new MmLogGenjoImpl(
                        0, //読み開始手目済み
                        logBrd_move1,
                        0, //現在の手済み
                        niniNode.Key
                        )
                    //#endif
                    );

                logBrd_move1.moveOrNull = niniNode.Key;

                logBrd_move1.YomikaisiTemezumi = niniNode.Value.KyokumenConst.Temezumi;//読み開始手目済み    // int.MinValue;
                logBrd_move1.Temezumi          = int.MinValue;
                logBrd_move1.Score             = (int)niniNode.Score;

                logF_kiki.boards.Add(logBrd_move1);
            }
        }
Exemplo n.º 10
0
        private static void Log2(
            Tansaku_Genjo genjo,
            KifuNode node_yomi,
            KaisetuBoard logBrd_move1
            )
        {
            logBrd_move1.moveOrNull = node_yomi.Key;


            RO_Star srcKoma = Util_Starlightable.AsKoma(logBrd_move1.moveOrNull.LongTimeAgo);
            RO_Star dstKoma = Util_Starlightable.AsKoma(logBrd_move1.moveOrNull.Now);


            // ログ試し
            logBrd_move1.Arrow.Add(new Gkl_Arrow(Conv_SyElement.ToMasuNumber(srcKoma.Masu), Conv_SyElement.ToMasuNumber(dstKoma.Masu)));
            genjo.Args.LogF_moveKiki.boards.Add(logBrd_move1);
        }
Exemplo n.º 11
0
        /// <summary>
        /// 棋譜ツリーの、ノードに格納されている、局面評価明細を、出力していきます。
        /// </summary>
        public static void AA_Write_ForeachLeafs_ForDebug(
            IEngineConf engineConf,
            ref int logFileCounter,
            string nodePath,
            KifuNode node,
            KifuTree kifu,
            string treeFolder,
            KyokumenPngEnvironment reportEnvironment
            )
        {
            // 次ノードの有無
            if (0 < node.Count_ChildNodes)
            {
                // 葉ノードではないなら

                int logFileCounter_temp = logFileCounter;
                // 先に奥の枝から。
                node.Foreach_ChildNodes((string key, Node <IMove, KyokumenWrapper> nextNode, ref bool toBreak) =>
                {
                    float score = ((KifuNode)nextNode).Score;

                    // 再帰
                    Util_KifuTreeLogWriter.AA_Write_ForeachLeafs_ForDebug(
                        engineConf,
                        ref logFileCounter_temp,
                        $"{nodePath} {ConvMoveStrSfen.ToMoveStrSfenForFilename(nextNode.Key)}",
                        (KifuNode)nextNode,
                        kifu,
                        $"{treeFolder}{(int)score}点_{ConvMoveStrSfen.ToMoveStrSfen(nextNode.Key)}/",
                        reportEnvironment
                        );
                });
                logFileCounter = logFileCounter_temp;
            }

            // 盤1個分の png 画像ログ出力
            Util_KifuTreeLogWriter.AAA_Write_Node(
                engineConf,
                ref logFileCounter,
                nodePath,
                node,
                kifu,
                treeFolder,
                reportEnvironment
                );
        }
Exemplo n.º 12
0
        /// <summary>
        /// 棋譜ツリーの、ノードに格納されている、局面評価明細を、出力していきます。
        /// </summary>
        public void Write_ForeachLeafs(
            IEngineConf engine,
            string nodePath,
            KifuNode node,
            KifuTree kifu,
            PlayerInfo playerInfo,
            string relFolder,
            ReportEnvironment reportEnvironment
            )
        {
            // 次ノードの有無
            if (0 < node.Count_NextNodes)
            {
                // 先に奥の枝から。
                node.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) =>
                {
                    double score = ((KifuNode)nextNode).KyHyoka.Total();

                    this.Write_ForeachLeafs(
                        engine,
                        nodePath + " " + Util_Sky.ToSfenMoveTextForFilename(nextNode.Key),
                        (KifuNode)nextNode,
                        kifu,
                        playerInfo,
                        relFolder + ((int)score).ToString() + "点_" + Util_Sky.ToSfenMoveText(nextNode.Key) + "/",
                        //relFolder + ((int)((KifuNode)nextNode).KyHyoka.Total()).ToString() + "点_" + Util_Sky.ToSfenMoveText(nextNode.Key) + "/",
                        reportEnvironment
                        );
                });
            }

            // このノード
            //
            // 盤1個分のログの準備
            //
            this.Log_Board(
                engine,
                nodePath,
                node,
                kifu,
                relFolder,
                reportEnvironment
                );
        }
Exemplo n.º 13
0
        /// <summary>
        /// レッツ☆判断!
        ///
        /// (1)ノードは、局面であるとともに、点数を覚えておくこともできます。
        /// (2)考え方の条件を指定します。
        /// (3)このメソッドは、「指定の駒が、指定のマスより、どれぐらい離れているか」で点数付けします。
        /// (4)ノードに、点数を設定します。
        /// </summary>
        public KyHyokaItem LetHandan(
            Tenonagare tenonagare,
            KifuNode node,
            PlayerInfo playerInfo
            )
        {
            KyHyokaItem scoreExp;

            if (this.KyHyokas.ContainsKey(tenonagare.Name))
            {
                this.KyHyokas[tenonagare.Name].Keisan(out scoreExp, new KyHandanArgsImpl(tenonagare, node, playerInfo));
            }
            else
            {
                scoreExp = new KyHyoka100limitItemImpl(1.0d, 0.0d, "ヌル");
            }

            return(scoreExp);
        }
Exemplo n.º 14
0
        /// <summary>
        /// 盤1個分のログ。
        /// </summary>
        private void Log_Board(
            string nodePath,
            KifuNode node,
            KifuTree kifu,
            ReportEnvironment reportEnvironment,
            GraphicalLog_File logF_kiki
            )
        {
            //
            // HTMLログ
            //
            if (logF_kiki.boards.Count < 30)//出力件数制限
            {
                GraphicalLog_Board logBrd_move1 = new GraphicalLog_Board();

                List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus;
                Util_MovableMove.LA_Get_KomaBETUSusumeruMasus(
                    out komaBETUSusumeruMasus,
                    new MmGenjo_MovableMasuImpl(
                        true,                       //本将棋
                        node.Value.ToKyokumenConst, //現在の局面
                        kifu.CountPside(node),
                        false
                        ),
                    new MmLogGenjoImpl(
                        false, //ログなし
                        logBrd_move1,
                        0,     //読みの深さ
                        0,     //現在の手済み
                        node.Key
                        )
                    );

                logBrd_move1.moveOrNull = ((KifuNode)node).Key;

                logBrd_move1.NounaiYomiDeep = int.MinValue;
                logBrd_move1.Tesumi         = int.MinValue;
                logBrd_move1.Score          = (int)node.KyHyoka.Total();

                logF_kiki.boards.Add(logBrd_move1);
            }
        }
Exemplo n.º 15
0
        /// <summary>
        /// 新しいノードを、次ノードとして追加します。
        /// そして、追加した新しいノードを、カレント・ノードとします。
        /// </summary>
        /// <param name="nextNode_and_nextCurrent"></param>
        public static void AppendChild_And_ChangeCurrentToChild(
            KifuTree kifuRef,
            KifuNode nextNode_and_nextCurrent,
            string hint
            )
        {
            string moveStr = ConvMoveStrSfen.ToMoveStrSfen(nextNode_and_nextCurrent.Key);

            if (!((KifuNode)kifuRef.CurNode).HasTuginoitte(moveStr))
            {
                //----------------------------------------
                // 次ノート追加
                //----------------------------------------
                kifuRef.GetSennititeCounter().CountUp_New(Conv_Sky.ToKyokumenHash(nextNode_and_nextCurrent.Value.KyokumenConst), $"{hint}/AppendChild_And_ChangeCurrentToChild");
                ((KifuNode)kifuRef.CurNode).PutTuginoitte_New(nextNode_and_nextCurrent);
            }

            kifuRef.SetCurNode(nextNode_and_nextCurrent);//次ノードを、これからのカレントとします。
            Debug.Assert(kifuRef.CurNode != null, "カレントノードがヌル。");
        }
Exemplo n.º 16
0
        /// <summary>
        /// 二駒関係の評価値を算出します。
        /// </summary>
        public void DoScoreing_ForLearning(
            KifuNode node
#if DEBUG || LEARN
            ,
            out KyHyokaMeisai_Koumoku out_komawariMeisai,
            out KyHyokaMeisai_Koumoku out_ppMeisai
#endif
            )
        {
            //----------------------------------------
            // Komawari
            //----------------------------------------
            {
                Hyokakansu_Komawari handan = new Hyokakansu_Komawari();
                float score;
                handan.Evaluate(
                    out score,
#if DEBUG || LEARN
                    out out_komawariMeisai,
#endif
                    node.Value.KyokumenConst,
                    this.Fv //参照してもらうだけ。
                    );
            }
            //----------------------------------------
            // PP
            //----------------------------------------
            {
                Hyokakansu_NikomaKankeiPp handan_pp = new Hyokakansu_NikomaKankeiPp();
                float score;
                handan_pp.Evaluate(
                    out score,
#if DEBUG || LEARN
                    out out_ppMeisai,
#endif
                    node.Value.KyokumenConst,
                    this.Fv //参照してもらうだけ。
                    );
            }
        }
Exemplo n.º 17
0
        public static void Write(
            string id,
            KifuNode node,
            string logDirectory,
            ReportEnvironment env
            )
        {
            StringBuilder sb = new StringBuilder();

            // 見出し
            sb.Append(id);
            sb.Append("    ");
            sb.Append(((int)node.KyHyoka.Total()).ToString());
            sb.Append("    ");
            switch (node.Tebanside)
            {
            case Playerside.P1: sb.Append("P2が指し終えた局面。手番P1"); break;

            case Playerside.P2: sb.Append("P1が指し終えた局面。手番P2"); break;

            case Playerside.Empty: sb.Append("手番Empty"); break;
            }
            sb.AppendLine();

            foreach (KeyValuePair <string, KyHyokaItem> entry in node.KyHyoka.Items)
            {
                sb.Append("    ");
                sb.Append(entry.Key);
                sb.Append("  ");
                sb.Append(((KyHyokaItem)entry.Value).Score);
                sb.Append("  ");
                sb.Append(((KyHyokaItem)entry.Value).Text);
                sb.AppendLine();
            }
            sb.AppendLine();

            File.AppendAllText(Path.Combine(logDirectory, "#スコア明細.log"), sb.ToString()); // TODO
        }
Exemplo n.º 18
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);
        }
Exemplo n.º 19
0
        /// <summary>
        /// 同点決勝。
        ///
        /// 評価値が同点のノード(指し手)の中で、ランダムに1つ選びます。
        /// </summary>
        /// <param name="kifu">ツリー構造になっている棋譜</param>
        /// <returns></returns>
        public KifuNode ChoiceNode_DoutenKessyou(
            KifuTree kifu,
            bool isHonshogi)
        {
            KifuNode bestKifuNode = null;

            {
                // 次のノードをリストにします。
                //List<KifuNode> nextNodes = Util_Converter280.NextNodes_ToList(kifu.CurNode);

                // 次のノードをシャッフル済みリストにします。
                List <KifuNode> nextNodes_shuffled = Conv_NextNodes.ToList(kifu.CurNode);
                LarabeShuffle <KifuNode> .Shuffle_FisherYates(ref nextNodes_shuffled);

                // シャッフルした最初のノードを選びます。
                if (0 < nextNodes_shuffled.Count)
                {
                    bestKifuNode = nextNodes_shuffled[0];
                }
            }

            return(bestKifuNode);
        }
Exemplo n.º 20
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値。
            //--------------------------------------------------------------------------------
            // ↑↑↑↑アルファベータ法の準備
            //--------------------------------------------------------------------------------
        }
Exemplo n.º 21
0
        /// <summary>
        /// 指定された手の中から、王手局面を除外します。
        ///
        /// 王手回避漏れを防ぎたいんだぜ☆
        /// </summary>
        /// <param name="km_available">自軍の各駒の移動できる升セット</param>
        /// <param name="sbGohosyu"></param>
        /// <param name="logTag"></param>
        public static KifuNode LA_RemoveMate(
            bool isHonshogi,
            Maps_OneAndMulti <Finger, ShootingStarlightable> genTeban_komabetuAllMove1, // 現手番の、どの駒が、どんな手を指すことができるか
            int yomuDeep,                                                               //脳内読み手数
            int tesumi_yomiGenTeban,
            Playerside pside_yomiGenTeban,
            KifuNode siteiNode_yomiGenTeban,
            bool enableLog,
            GraphicalLog_File logF_kiki,
            string hint)
        {
            Node <ShootingStarlightable, KyokumenWrapper> hubNode = UtilKomabetuMove.ToNextNodes_AsHubNode(
                genTeban_komabetuAllMove1, siteiNode_yomiGenTeban, pside_yomiGenTeban
                );                                                    // ハブ・ノード自身はダミーノードなんだが、子ノードに、次のノードが入っている。

            Converter04.AssertNariMove(hubNode, "#LA_RemoveMate(1)"); //ここはok
            Util_LegalMove.Log1(hubNode, enableLog, tesumi_yomiGenTeban, hint);


            if (isHonshogi)
            {
                // 王手が掛かっている局面を除きます。

                Util_LegalMove.LAA_RemoveNextNode_IfMate(
                    hubNode,
                    enableLog,
                    yomuDeep,
                    tesumi_yomiGenTeban,
                    pside_yomiGenTeban,
                    logF_kiki);
            }
            Converter04.AssertNariMove(hubNode, "#LA_RemoveMate(2)王手局面削除直後");//ここはok


            // 「指し手一覧」を、「駒別の全指し手」に分けます。
            Maps_OneAndMulti <Finger, ShootingStarlightable> komabetuAllMoves2 = siteiNode_yomiGenTeban.SplitMoveByKoma(hubNode);

            Converter04.AssertNariMove(komabetuAllMoves2, "#LA_RemoveMate(3)更に変換後");//ここはok

            //
            // 「駒別の指し手一覧」を、「駒別の進むマス一覧」になるよう、データ構造を変換します。
            //
            Maps_OneAndOne <Finger, SySet <SyElement> > komabetuSusumuMasus = new Maps_OneAndOne <Finger, SySet <SyElement> >();// 「どの駒を、どこに進める」の一覧

            foreach (KeyValuePair <Finger, List <ShootingStarlightable> > entry in komabetuAllMoves2.Items)
            {
                Finger finger = entry.Key;
                List <ShootingStarlightable> teList = entry.Value;

                // ポテンシャル・ムーブを調べます。
                SySet <SyElement> masus_PotentialMove = new SySet_Default <SyElement>("ポテンシャルムーブ");
                foreach (ShootingStarlightable te in teList)
                {
                    RO_Star_Koma koma = Util_Koma.AsKoma(te.Now);

                    masus_PotentialMove.AddElement(koma.Masu);
                }

                if (!masus_PotentialMove.IsEmptySet())
                {
                    // 空でないなら
                    Util_KomabetuMasus.AddOverwrite(komabetuSusumuMasus, finger, masus_PotentialMove);
                }
            }

            // まず、ディクショナリー構造へ変換。
            Dictionary <ShootingStarlightable, KyokumenWrapper> movebetuSky = Converter04.KomabetuMasus_ToMovebetuSky(
                komabetuSusumuMasus, siteiNode_yomiGenTeban.Value.ToKyokumenConst, pside_yomiGenTeban);

            // 棋譜ノード構造へ変換。
            return(Converter04.MovebetuSky_ToHubNode(movebetuSky, KifuNodeImpl.GetReverseTebanside(pside_yomiGenTeban)));
        }
Exemplo n.º 22
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);
        }
Exemplo n.º 23
0
        /// <summary>
        /// これが通称【水際のいんちきプログラム】なんだぜ☆
        /// 必要により、【成り】の指し手を追加します。
        /// </summary>
        public static void AddNariMove(
            KifuNode node_yomiCur,
            KifuNode hubNode
            )
        {
            Dictionary <string, ShootingStarlightable> newMoveList = new Dictionary <string, ShootingStarlightable>();

            hubNode.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) =>
            {
                RO_Star_Koma srcKoma = Util_Koma.AsKoma(nextNode.Key.LongTimeAgo);
                RO_Star_Koma dstKoma = Util_Koma.AsKoma(nextNode.Key.Now);

                bool isPromotionable;
                if (!Converter04.IsPromotionable(out isPromotionable, srcKoma, dstKoma))
                {
                    // エラー
                    goto gt_Next1;
                }

                if (isPromotionable)
                {
                    ShootingStarlightable move = new RO_ShootingStarlight(
                        //figKoma,//駒
                        srcKoma,// 移動元
                        new RO_Star_Koma(
                            dstKoma.Pside,
                            dstKoma.Masu,
                            KomaSyurui14Array.ToNariCase(dstKoma.Syurui) //強制的に【成り】に駒の種類を変更
                            ),                                           // 移動先
                        PieceType.None                                   //取った駒不明
                        );

                    // TODO: 一段目の香車のように、既に駒は成っている場合があります。無い指し手だけ追加するようにします。
                    string moveStr = Util_Sky.ToSfenMoveText(move);//重複防止用のキー
                    if (!newMoveList.ContainsKey(moveStr))
                    {
                        newMoveList.Add(moveStr, move);
                    }
                }

                gt_Next1:
                ;
            });


            // 新しく作った【成り】の指し手を追加します。
            foreach (ShootingStarlightable newMove in newMoveList.Values)
            {
                // 指す前の駒
                RO_Star_Koma sasumaenoKoma = Util_Koma.AsKoma(newMove.LongTimeAgo);

                // 指した駒
                RO_Star_Koma sasitaKoma = Util_Koma.AsKoma(newMove.Now);

                // 現局面
                SkyConst src_Sky = node_yomiCur.Value.ToKyokumenConst;

                // 指す前の駒を、盤上のマス目で指定
                Finger figSasumaenoKoma = Util_Sky.Fingers_AtMasuNow(src_Sky, sasumaenoKoma.Masu).ToFirst();

                // 新たな局面
                KyokumenWrapper kyokumenWrapper = new KyokumenWrapper(Util_Sasu.Sasu(src_Sky, figSasumaenoKoma, sasitaKoma.Masu, KifuNodeImpl.GetReverseTebanside(node_yomiCur.Tebanside)));



                try
                {
                    string moveStr = Util_Sky.ToSfenMoveText(newMove);

                    if (!hubNode.ContainsKey_NextNodes(moveStr))
                    {
                        // 指し手が既存でない局面だけを追加します。

                        hubNode.Add_NextNode(
                            moveStr,
                            new KifuNodeImpl(
                                newMove,
                                kyokumenWrapper,//node_yomiCur.Value,//FIXME: 成りの手を指した局面を作りたい。
                                KifuNodeImpl.GetReverseTebanside(node_yomiCur.Tebanside)
                                )
                            );
                    }
                }
                catch (Exception ex)
                {
                    // 既存の指し手
                    StringBuilder sb = new StringBuilder();
                    {
                        hubNode.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) =>
                        {
                            sb.Append("「");
                            sb.Append(Util_Sky.ToSfenMoveText(nextNode.Key));
                            sb.Append("」");
                        });
                    }

                    //>>>>> エラーが起こりました。
                    // どうにもできないので  ログだけ取って、上に投げます。
                    Logger.Error(ex.GetType().Name + " " + ex.Message + ":新しく作った「成りの指し手」を既存ノードに追加していた時です。:追加したい指し手=「" + Util_Sky.ToSfenMoveText(newMove) + "」既存の手=" + sb.ToString());
                    throw;
                }
            }

            // gt_EndMethod:
            // ;
        }
Exemplo n.º 24
0
        /// <summary>
        /// 棋譜ツリーの、ノードのネクストノードに、点数を付けていきます。
        /// </summary>
        public void Tensuduke_ForeachLeafs(
            string nodePath,
            KifuNode node,
            KifuTree kifu,
            Kokoro kokoro,
            PlayerInfo playerInfo,
            ReportEnvironment reportEnvironment,//MinimaxEngineImpl.REPORT_ENVIRONMENT
            GraphicalLog_File logF_kiki
            )
        {
            // 次ノードの有無
            if (node.Count_NextNodes < 1)
            {
                // 次ノードが無ければ、このノードが、葉です。
                // 点数を付けます。

                // 局面スコア
                node.KyHyoka.Clear();

                // 妄想と、指定のノードを比較し、点数付けします。
                foreach (Tenonagare nagare in kokoro.TenonagareItems)
                {
                    node.KyHyoka.Add(
                        nagare.Name.ToString(),
                        this.hyokaEngineImpl.LetHandan(nagare, node, playerInfo)
                        );
                }

#if DEBUG
                //
                // 盤1個分のログの準備
                //
                this.Log_Board(
                    nodePath,
                    node,
                    kifu,
                    reportEnvironment,
                    logF_kiki
                    );
#endif
            }
            else
            {
                node.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) =>
                {
                    this.Tensuduke_ForeachLeafs(
                        nodePath + " " + Util_Sky.ToSfenMoveText(nextNode.Key),
                        (KifuNode)nextNode,
                        kifu,
                        kokoro,
                        playerInfo,
                        reportEnvironment,
                        logF_kiki
                        );
                });

                // このノードが、自分の手番かどうか。
                bool jibun = playerInfo.Playerside == kifu.CountPside(node);
                if (jibun)
                {
                    // 自分のノードの場合、次ノードの中で一番点数の高いもの。
                    double maxScore = double.MinValue;
                    node.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) =>
                    {
                        double score = ((KifuNode)nextNode).KyHyoka.Total();
                        if (maxScore < score)
                        {
                            maxScore = score;
                        }
                    });
                    node.SetBranchKyHyoka(new KyHyokaImpl(maxScore));
                }
                else
                {
                    // 相手のノードの場合、次ノードの中で一番点数の低いもの。
                    double minScore = double.MaxValue;
                    node.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) =>
                    {
                        double score = ((KifuNode)nextNode).KyHyoka.Total();
                        if (score < minScore)
                        {
                            minScore = score;
                        }
                    });
                    node.SetBranchKyHyoka(new KyHyokaImpl(minScore));
                }
            }
        }
Exemplo n.º 25
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();
            }
        }
Exemplo n.º 26
0
        /// <summary>
        /// 頭の隅(手の流れ)を作成します☆w
        /// </summary>
        /// <param name="input_myPside"></param>
        /// <param name="save_node">狙い作成時の局面を状況として記録するために読取します。</param>
        /// <param name="input_seikaku"></param>
        public void Omoituki(
            Playerside input_myPside,
            KifuNode save_node,
            Seikaku input_seikaku
            )
        {
            SkyConst src_Sky = save_node.Value.ToKyokumenConst;

            // FIXME: どの狙いか どんぶり勘定になっている☆
            {
                List <Tenonagare> removee = new List <Tenonagare>();

                foreach (Tenonagare atamanosumi in this.TenonagareItems)
                {
                    // 失敗回数が、粘り強さを超えたとき
                    if (input_seikaku.NebariDuyosa < atamanosumi.ResultKioku.Sippai)
                    {
                        // 今いだいている妄想を捨てます。
                        removee.Add(atamanosumi);
                    }
                }

                foreach (Tenonagare atamanosumi in removee)
                {
                    this.TenonagareItems.Remove(atamanosumi);
                }
            }

            //
            // とりあえずサンプルとして1つ作ってみます。
            //

            {
                //MessageBox.Show( "とりあえずサンプルとして1つ作ってみます。","デバッグ");
                Tenonagare atamanosumi;

                // 2Pの飛車先の歩の付き捨て
                {
                    if (input_myPside == Playerside.P2)
                    {
                        //MessageBox.Show("プレイヤー2です。", "デバッグ");

                        // 8二に飛車がいる前提です。
                        RO_Star_Koma koma82 = Util_Sky.Koma_AtMasuNow(src_Sky, Masu_Honshogi.ban82_8二, Playerside.P2, PieceType.R);

                        if (null != koma82)
                        {
                            //MessageBox.Show("8二に飛車がいました。", "デバッグ");
                            // 8二に飛車がいた。

                            // 飛車先の駒は?
                            RO_Star_Koma koma83 = Util_Sky.Koma_AtMasuNow(src_Sky, Masu_Honshogi.ban83_8三, Playerside.P2, PieceType.P);

                            RO_Star_Koma koma84 = Util_Sky.Koma_AtMasuNow(src_Sky, Masu_Honshogi.ban84_8四, Playerside.P2);
                            RO_Star_Koma koma85 = Util_Sky.Koma_AtMasuNow(src_Sky, Masu_Honshogi.ban85_8五, Playerside.P2);
                            RO_Star_Koma koma86 = Util_Sky.Koma_AtMasuNow(src_Sky, Masu_Honshogi.ban86_8六, Playerside.P2);
                            RO_Star_Koma koma87 = Util_Sky.Koma_AtMasuNow(src_Sky, Masu_Honshogi.ban87_8七, Playerside.P2);
                            RO_Star_Koma koma88 = Util_Sky.Koma_AtMasuNow(src_Sky, Masu_Honshogi.ban88_8八, Playerside.P2);

                            if (koma83 != null && koma84 == null && koma85 == null && koma86 == null && koma87 == null && koma88 == null)
                            {
                                //MessageBox.Show("8三に自歩があり、8四~8八に自駒はありませんでした。", "デバッグ");

                                // 8三に自歩があり、8四~8八に自駒が無ければ。

                                // 8三の駒を、8九に向かって前進させます。

                                atamanosumi = new TenonagareImpl(save_node.ToRO_Kyokumen1(),
                                                                 TenonagareName.Tukisute,
                                                                 1000.0d,
                                                                 koma83,                //どの駒を
                                                                 null,
                                                                 Masu_Honshogi.ban83_8三 //初期位置
                                                                 );
                                goto gt_Next1;
                            }
                        }
                    }
                }

                int random = LarabeRandom.Random.Next(-9, 10);
                if (0 < random)
                {
                    //
                    // 自駒をランダムに1つ指定し、目指すマスをランダムに1つ指定し、進ませます。
                    // 係数は下げます。
                    //

                    // どの駒が
                    RO_Star_Koma koma1;
                    switch (input_myPside)
                    {
                    case Playerside.P1: koma1 = Util_Koma.FromFinger(src_Sky, LarabeRandom.Random.Next(0, 19)); break;

                    case Playerside.P2: koma1 = Util_Koma.FromFinger(src_Sky, LarabeRandom.Random.Next(20, 39)); break;

                    default: koma1 = Util_Koma.FromFinger(src_Sky, -1); break;
                    }

                    atamanosumi = new TenonagareImpl(save_node.ToRO_Kyokumen1(),
                                                     TenonagareName.Ido, // 「移動」タイプの狙い
                                                     0.05d,              //1.0d,
                                                     koma1,
                                                     null,
                                                     new Basho(LarabeRandom.Random.Next(0, 80))// 目指すマス
                                                     );
                }
                else
                {
                    //
                    // 自駒をランダムに1つ指定し、相手の駒をランダムに1つ指定し、
                    // 取るように目指させます。
                    // 係数は下げます。
                    //
                    RO_Star_Koma koma1;
                    switch (input_myPside)
                    {
                    // FIXME: 持ち駒を考えられていない。
                    case Playerside.P1: koma1 = Util_Koma.FromFinger(src_Sky, LarabeRandom.Random.Next(0, 19)); break;

                    case Playerside.P2: koma1 = Util_Koma.FromFinger(src_Sky, LarabeRandom.Random.Next(20, 39)); break;

                    default: koma1 = Util_Koma.FromFinger(src_Sky, -1); break;
                    }

                    // どの駒を
                    RO_Star_Koma koma2;
                    switch (input_myPside)
                    {
                    // FIXME: 持ち駒を考えられていない。
                    case Playerside.P1:
                        koma2 = Util_Koma.FromFinger(src_Sky, LarabeRandom.Random.Next(20, 39));
                        break;

                    case Playerside.P2:
                        koma2 = Util_Koma.FromFinger(src_Sky, LarabeRandom.Random.Next(0, 19));
                        break;

                    default:
                        koma2 = Util_Koma.FromFinger(src_Sky, -1);
                        break;
                    }

                    // 「取る」タイプの狙い
                    atamanosumi = new TenonagareImpl(save_node.ToRO_Kyokumen1(),
                                                     TenonagareName.Toru,
                                                     0.1d,//1.0d,
                                                     koma1, koma2, new Basho(0));

                    // 目指す
                }
gt_Next1:



                // 作った妄想は履歴に追加。
                //MessageBox.Show("作った妄想は履歴に追加。", "デバッグ");
                this.AddTenonagare(atamanosumi);
            }

            // FIXME: 「手の流れ」が?個を超えてたら、5個消していく☆秒読みで10超えてしまうので。
            {
                int tenonagareMax = 15;//25
                int kesuKazu      = 5;

                if (tenonagareMax < this.TenonagareItems.Count)
                {
                    int iKesu = kesuKazu;// tenonagareMax - this.TenonagareItems.Count + 5;

                    List <Tenonagare> removee = new List <Tenonagare>();

                    foreach (Tenonagare nagare in this.TenonagareItems)
                    {
                        if (iKesu < 1)
                        {
                            break;
                        }

                        // 失敗回数が、粘り強さを超えたとき
                        if (input_seikaku.NebariDuyosa < nagare.ResultKioku.Sippai)
                        {
                            // 今いだいている妄想を捨てます。
                            removee.Add(nagare);
                        }

                        iKesu--;
                    }

                    foreach (Tenonagare nagare in removee)
                    {
                        this.TenonagareItems.Remove(nagare);
                    }
                }
            }
        }
Exemplo n.º 27
0
        /// <summary>
        /// 表形式の局面データを出力します。SFENとの親和性高め。
        /// </summary>
        /// <returns></returns>
        public static ISfenPosition1 ToRO_Kyokumen1(KifuNode kifuNode)
        {
            ISfenPosition1 ro_Kyokumen1 = new SfenPosition1Impl();

            SkyConst src_Sky = kifuNode.Value.KyokumenConst;

            // 将棋盤
            for (int suji = 1; suji < 10; suji++)
            {
                for (int dan = 1; dan < 10; dan++)
                {
                    Finger koma0 = Util_Sky_FingersQuery.InMasuNow(
                        src_Sky, Util_Masu10.OkibaSujiDanToMasu(Okiba.ShogiBan, suji, dan)
                        ).ToFirst();

                    if (Fingers.Error_1 != koma0)
                    {
                        RO_Star koma1 = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(koma0).Now);

                        ro_Kyokumen1.Ban[suji, dan] = Util_Komasyurui14.SfenText(
                            Util_Komahaiyaku184.Syurui(koma1.Haiyaku),
                            koma1.Pside
                            );
                    }
                }
            }

            // 持ち駒
            int mK = 0;
            int mR = 0;
            int mB = 0;
            int mG = 0;
            int mS = 0;
            int mN = 0;
            int mL = 0;
            int mP = 0;

            int mk = 0;
            int mr = 0;
            int mb = 0;
            int mg = 0;
            int ms = 0;
            int mn = 0;
            int ml = 0;
            int mp = 0;

            Util_Sky_CountQuery.CountMoti(
                src_Sky,
                out mK,
                out mR,
                out mB,
                out mG,
                out mS,
                out mN,
                out mL,
                out mP,

                out mk,
                out mr,
                out mb,
                out mg,
                out ms,
                out mn,
                out ml,
                out mp
                );

            int player;

            player = 1;
            ro_Kyokumen1.Moti[player, 0] = mR;
            ro_Kyokumen1.Moti[player, 1] = mB;
            ro_Kyokumen1.Moti[player, 2] = mG;
            ro_Kyokumen1.Moti[player, 3] = mS;
            ro_Kyokumen1.Moti[player, 4] = mN;
            ro_Kyokumen1.Moti[player, 5] = mL;
            ro_Kyokumen1.Moti[player, 6] = mP;

            player = 2;
            ro_Kyokumen1.Moti[player, 0] = mr;
            ro_Kyokumen1.Moti[player, 1] = mb;
            ro_Kyokumen1.Moti[player, 2] = mg;
            ro_Kyokumen1.Moti[player, 3] = ms;
            ro_Kyokumen1.Moti[player, 4] = mn;
            ro_Kyokumen1.Moti[player, 5] = ml;
            ro_Kyokumen1.Moti[player, 6] = mp;

            // 手目済み
            ro_Kyokumen1.Temezumi = src_Sky.Temezumi;

            return(ro_Kyokumen1);
        }
Exemplo n.º 28
0
        /// <summary>
        /// 局面データから、SFEN文字列を作ります。
        /// </summary>
        /// <param name="pside"></param>
        /// <returns></returns>
        public static string ToSfenstring(KifuNode kifuNode, Playerside pside)
        {
            SkyConst src_Sky = kifuNode.Value.KyokumenConst;

            StringBuilder sb = new StringBuilder();

            sb.Append("sfen ");

            for (int dan = 1; dan <= 9; dan++)
            {
                int spaceCount = 0;

                for (int suji = 9; suji >= 1; suji--)
                {
                    // 将棋盤上のどこかにある駒?
                    Finger koma0 = Util_Sky_FingersQuery.InMasuNow(
                        src_Sky, Util_Masu10.OkibaSujiDanToMasu(Okiba.ShogiBan, suji, dan)
                        ).ToFirst();

                    if (Fingers.Error_1 != koma0)
                    {
                        if (0 < spaceCount)
                        {
                            sb.Append(spaceCount);
                            spaceCount = 0;
                        }


                        RO_Star koma1 = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(koma0).Now);



                        sb.Append(Util_Komasyurui14.SfenText(
                                      Util_Komahaiyaku184.Syurui(koma1.Haiyaku),
                                      koma1.Pside
                                      ));
                    }
                    else
                    {
                        spaceCount++;
                    }
                }

                if (0 < spaceCount)
                {
                    sb.Append(spaceCount);
                    spaceCount = 0;
                }

                if (dan != 9)
                {
                    sb.Append("/");
                }
            }

            sb.Append(" ");

            //------------------------------------------------------------
            // 先後
            //------------------------------------------------------------
            switch (pside)
            {
            case Playerside.P2:
                sb.Append("w");
                break;

            default:
                sb.Append("b");
                break;
            }

            sb.Append(" ");

            //------------------------------------------------------------
            // 持ち駒
            //------------------------------------------------------------
            {
                int mK = 0;
                int mR = 0;
                int mB = 0;
                int mG = 0;
                int mS = 0;
                int mN = 0;
                int mL = 0;
                int mP = 0;

                int mk = 0;
                int mr = 0;
                int mb = 0;
                int mg = 0;
                int ms = 0;
                int mn = 0;
                int ml = 0;
                int mp = 0;
                Util_Sky_CountQuery.CountMoti(
                    src_Sky,
                    out mK,
                    out mR,
                    out mB,
                    out mG,
                    out mS,
                    out mN,
                    out mL,
                    out mP,

                    out mk,
                    out mr,
                    out mb,
                    out mg,
                    out ms,
                    out mn,
                    out ml,
                    out mp
                    );



                if (0 == mK + mR + mB + mG + mS + mN + mL + mP + mk + mr + mb + mg + ms + mn + ml + mp)
                {
                    sb.Append("-");
                }
                else
                {
                    if (0 < mK)
                    {
                        if (1 < mK)
                        {
                            sb.Append(mK);
                        }
                        sb.Append("K");
                    }

                    if (0 < mR)
                    {
                        if (1 < mR)
                        {
                            sb.Append(mR);
                        }
                        sb.Append("R");
                    }

                    if (0 < mB)
                    {
                        if (1 < mB)
                        {
                            sb.Append(mB);
                        }
                        sb.Append("B");
                    }

                    if (0 < mG)
                    {
                        if (1 < mG)
                        {
                            sb.Append(mG);
                        }
                        sb.Append("G");
                    }

                    if (0 < mS)
                    {
                        if (1 < mS)
                        {
                            sb.Append(mS);
                        }
                        sb.Append("S");
                    }

                    if (0 < mN)
                    {
                        if (1 < mN)
                        {
                            sb.Append(mN);
                        }
                        sb.Append("N");
                    }

                    if (0 < mL)
                    {
                        if (1 < mL)
                        {
                            sb.Append(mL);
                        }
                        sb.Append("L");
                    }

                    if (0 < mP)
                    {
                        if (1 < mP)
                        {
                            sb.Append(mP);
                        }
                        sb.Append("P");
                    }

                    if (0 < mk)
                    {
                        if (1 < mk)
                        {
                            sb.Append(mk);
                        }
                        sb.Append("k");
                    }

                    if (0 < mr)
                    {
                        if (1 < mr)
                        {
                            sb.Append(mr);
                        }
                        sb.Append("r");
                    }

                    if (0 < mb)
                    {
                        if (1 < mb)
                        {
                            sb.Append(mb);
                        }
                        sb.Append("b");
                    }

                    if (0 < mg)
                    {
                        if (1 < mg)
                        {
                            sb.Append(mg);
                        }
                        sb.Append("g");
                    }

                    if (0 < ms)
                    {
                        if (1 < ms)
                        {
                            sb.Append(ms);
                        }
                        sb.Append("s");
                    }

                    if (0 < mn)
                    {
                        if (1 < mn)
                        {
                            sb.Append(mn);
                        }
                        sb.Append("n");
                    }

                    if (0 < ml)
                    {
                        if (1 < ml)
                        {
                            sb.Append(ml);
                        }
                        sb.Append("l");
                    }

                    if (0 < mp)
                    {
                        if (1 < mp)
                        {
                            sb.Append(mp);
                        }
                        sb.Append("p");
                    }
                }
            }

            // 手目
            sb.Append(" 1");

            return(sb.ToString());
        }
Exemplo n.º 29
0
        /// <summary>
        /// 盤1個分のログ。
        /// </summary>
        private static void AAA_Write_Node(
            IEngineConf engineConf,
            ref int logFileCounter,
            string nodePath,
            KifuNode node,
            KifuTree kifu,
            string relFolder,
            KyokumenPngEnvironment reportEnvironment
            )
        {
            string fileName = "";


            // 出力先
            fileName  = Conv_Filepath.ToEscape($"_log_{((int)node.Score)}点_{logFileCounter}_{nodePath}.png");
            relFolder = Conv_Filepath.ToEscape(relFolder);
            //
            // 画像ログ
            //
            if (true)
            {
                int srcMasu_orMinusOne = -1;
                int dstMasu_orMinusOne = -1;
                if (null != node.Key)
                {
                    srcMasu_orMinusOne = Conv_SyElement.ToMasuNumber(((RO_Star)node.Key.LongTimeAgo).Masu);
                    dstMasu_orMinusOne = Conv_SyElement.ToMasuNumber(((RO_Star)node.Key.Now).Masu);
                }

                KyokumenPngArgs_FoodOrDropKoma foodKoma;
                if (null != node.Key.FoodKomaSyurui)
                {
                    switch (Util_Komasyurui14.NarazuCaseHandle((PieceType)node.Key.FoodKomaSyurui))
                    {
                    case PieceType.None: foodKoma = KyokumenPngArgs_FoodOrDropKoma.NONE; break;

                    case PieceType.P: foodKoma = KyokumenPngArgs_FoodOrDropKoma.FU__; break;

                    case PieceType.L: foodKoma = KyokumenPngArgs_FoodOrDropKoma.KYO_; break;

                    case PieceType.N: foodKoma = KyokumenPngArgs_FoodOrDropKoma.KEI_; break;

                    case PieceType.S: foodKoma = KyokumenPngArgs_FoodOrDropKoma.GIN_; break;

                    case PieceType.G: foodKoma = KyokumenPngArgs_FoodOrDropKoma.KIN_; break;

                    case PieceType.R: foodKoma = KyokumenPngArgs_FoodOrDropKoma.HI__; break;

                    case PieceType.B: foodKoma = KyokumenPngArgs_FoodOrDropKoma.KAKU; break;

                    default: foodKoma = KyokumenPngArgs_FoodOrDropKoma.UNKNOWN; break;
                    }
                }
                else
                {
                    foodKoma = KyokumenPngArgs_FoodOrDropKoma.NONE;
                }


                // 評価明細に添付
                Util_KyokumenPng_Writer.Write1(
                    Conv_KifuNode.ToRO_Kyokumen1(node),
                    srcMasu_orMinusOne,
                    dstMasu_orMinusOne,
                    foodKoma,
                    ConvMoveStrSfen.ToMoveStrSfen(node.Key),
                    relFolder,
                    fileName,
                    reportEnvironment
                    );
                logFileCounter++;
            }

            //
            // 評価明細
            //
            {
                Util_KifuTreeLogWriter.AAAA_Write_HyokaMeisai(engineConf, fileName, node, relFolder, reportEnvironment);
            }
        }
Exemplo n.º 30
0
        /// <summary>
        /// 棋譜ツリー・ログの書出し
        ///
        /// TODO: フォルダーパスが長く成りすぎるのを、なんとかしたい。折り返すとか、~中略~にするとか、rootから始めないとか。
        /// </summary>
        public static void A_Write_KifuTreeLog(
            KaisetuBoards logF_kiki,
            KifuTree kifu
            )
        {
#if DEBUG
            int logFileCounter = 0;

            //----------------------------------------
            // 既存の棋譜ツリー・ログを空に。
            //----------------------------------------
            {
                string rootFolder = Path.Combine(Util_KifuTreeLogWriter.REPORT_ENVIRONMENT.OutFolder, ConvMoveStrSfen.KIFU_TREE_LOG_ROOT_FOLDER);
                if (Directory.Exists(rootFolder))
                {
                    try
                    {
                        Directory.Delete(rootFolder, true);
                    }
                    catch (IOException)
                    {
                        // ディレクトリーが空でなくて、ディレクトリーを削除できなかったときに
                        // ここにくるが、
                        // ディレクトリーの中は空っぽにできていたりする。
                        //
                        // とりあえず続行。
                    }
                }
            }

            //----------------------------------------
            // カレントノードまでの符号を使って、フォルダーパスを作成。
            //----------------------------------------
            StringBuilder tree_folder = new StringBuilder();
            kifu.ForeachHonpu(kifu.CurNode, (int temezumi2, KyokumenWrapper kWrap, Node <IMove, KyokumenWrapper> node, ref bool toBreak) =>
            {
                tree_folder.Append($"{ConvMoveStrSfen.ToMoveStrSfenForFilename(node.Key)}/");
            });
            //sb_folder.Append( $"{Conv_MoveStr_Sfen.ToMoveStr_Sfen_ForFilename(kifu.CurNode.Key)}/");

            string   moveText1 = ConvMoveStrSfen.ToMoveStrSfen(kifu.CurNode.Key);
            KifuNode kifuNode1 = (KifuNode)kifu.CurNode;

            // 評価明細のログ出力。
            Util_KifuTreeLogWriter.AA_Write_ForeachLeafs_ForDebug(
                ref logFileCounter,
                moveText1,
                kifuNode1,
                kifu,
                tree_folder.ToString(),
                Util_KifuTreeLogWriter.REPORT_ENVIRONMENT
                );

            if (0 < logF_kiki.boards.Count) //ログが残っているなら
            {
                bool enableLog = true;      // false;
                                            //
                                            // ログの書き出し
                                            //
                Util_GraphicalLog.WriteHtml5(
                    enableLog,
                    "#評価ログ",
                    $"[{Conv_KaisetuBoards.ToJsonStr(logF_kiki)}]"
                    );

                // 書き出した分はクリアーします。
                logF_kiki.boards.Clear();
            }
#endif
        }