Beispiel #1
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
                );
        }
Beispiel #2
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));
                }
            }
        }
Beispiel #3
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:
            // ;
        }