Exemple #1
0
 public void AddRange_New(List_OneAndMulti <T1, T2> om)
 {
     om.Foreach_Entry((T1 key, T2 value, ref bool toBreak) =>
     {
         this.AddNew(key, value);
     });
 }
Exemple #2
0
        public static Dictionary <ShootingStarlightable, KyokumenWrapper> KomabetuMasusToMovebetuSky(
            List_OneAndMulti <Finger, SySet <SyElement> > sMs, SkyConst src_Sky, Playerside pside)
        {
            Dictionary <ShootingStarlightable, KyokumenWrapper> result = new Dictionary <ShootingStarlightable, KyokumenWrapper>();


            sMs.Foreach_Entry((Finger key, SySet <SyElement> value, ref bool toBreak) =>
            {
                RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(key).Now);


                foreach (SyElement dstMasu in value.Elements)
                {
                    ShootingStarlightable move = Util_Sky.New(
                        //key,
                        new RO_Star_Koma(pside, koma.Masu, koma.Haiyaku),
                        new RO_Star_Koma(pside, dstMasu, koma.Haiyaku),//FIXME:配役は適当。
                        PieceType.None
                        );

                    result.Add(move, new KyokumenWrapper(Util_Sasu.Sasu(src_Sky, key, dstMasu, pside)));
                }
            });


            return(result);
        }
Exemple #3
0
        /// <summary>
        /// 指定した持ち駒全てについて、基本的な駒の動きを返します。(金は「前、ななめ前、横、下に進める」のような)
        ///
        /// TODO: 打ち歩詰めチェック
        ///
        /// </summary>
        /// <param name="src_Sky"></param>
        /// <param name="fingers"></param>
        /// <returns></returns>
        public static List_OneAndMulti <Finger, SySet <SyElement> > Get_PotentialMove_Motikoma(
            SkyConst src_Sky,
            Fingers fingers,
            SySet <SyElement> okenaiMasus
            )
        {
            // 「どの持ち駒を」「どこに置いたとき」「どこに利きがある」のコレクション。
            List_OneAndMulti <Finger, SySet <SyElement> > resultOmm = new List_OneAndMulti <Finger, SySet <SyElement> >();

            foreach (Finger donoKoma in fingers.Items)
            {
                // ポテンシャル・ムーブを調べます。

                RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(donoKoma).Now);


                PieceType syurui = Haiyaku184Array.Syurui(koma.Haiyaku);

                // 置ける升
                SySet <SyElement> okeruMasus = Util_Sky.KomaKidou_Potential(donoKoma, src_Sky);

                // 置けない升を引きます。
                okeruMasus = okeruMasus.Minus_Closed(okenaiMasus);

                if (syurui == PieceType.P)
                {
                    // 二歩チェック

                    int suji;
                    Util_MasuNum.MasuToSuji(koma.Masu, out suji);

                    Fingers sujiKomas = Util_Sky.Fingers_InSuji(src_Sky, suji);

                    Starlight fu      = src_Sky.StarlightIndexOf(donoKoma);
                    Fingers   existFu = Util_Sky.Matches(fu, src_Sky, sujiKomas);

                    if (0 < existFu.Count)
                    {
                        // 二歩だ☆!
                        goto gt_Next;
                    }

                    // TODO:打ち歩詰めチェック
                }


                if (!okeruMasus.IsEmptySet())
                {
                    // 空でないなら
                    resultOmm.AddNew(donoKoma, okeruMasus);
                }

gt_Next:
                ;
            }

            return(resultOmm);
        }
Exemple #4
0
        /// <summary>
        /// 変換
        /// </summary>
        /// <returns></returns>
        public static List_OneAndMulti <Finger, SySet <SyElement> > SplitKey1And2(
            Maps_OneAndMultiAndMulti <Finger, Basho, SySet <SyElement> > komabetuMasubetuMasus
            )
        {
            List_OneAndMulti <Finger, SySet <SyElement> > result = new List_OneAndMulti <Finger, SySet <SyElement> >();

            komabetuMasubetuMasus.Foreach_Entry((Finger finger, Basho key2, SySet <SyElement> masus, ref bool toBreak) =>
            {
                result.AddNew(finger, masus);
            });

            return(result);
        }
Exemple #5
0
        /// <summary>
        /// 変換「各(自駒が動ける升)」→「各(自駒が動ける手)」
        /// </summary>
        /// <param name="komaBETUSusumeruMasus"></param>
        /// <returns></returns>
        public static Maps_OneAndMulti <Finger, ShootingStarlightable> KomaBETUSusumeruMasusToKomaBETUAllMoves(
            List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus,
            Node <ShootingStarlightable, KyokumenWrapper> siteiNode_genzai
            )
        {
            Maps_OneAndMulti <Finger, ShootingStarlightable> komabetuAllMove = new Maps_OneAndMulti <Finger, ShootingStarlightable>();

            komaBETUSusumeruMasus.Foreach_Entry((Finger figKoma, SySet <SyElement> susumuMasuSet, ref bool toBreak) =>
            {
                RO_Star_Koma srcKoma = Util_Koma.AsKoma(siteiNode_genzai.Value.ToKyokumenConst.StarlightIndexOf(figKoma).Now);

                foreach (SyElement susumuMasu in susumuMasuSet.Elements)
                {
                    // 移動先の駒
                    RO_Star_Koma dstKoma = new RO_Star_Koma(
                        srcKoma.Pside,
                        Masu_Honshogi.Items_All[Util_Masu.AsMasuNumber(susumuMasu)],
                        srcKoma.Haiyaku//TODO:ここで、駒の種類が「成り」に上書きされているバージョンも考えたい
                        );

                    ShootingStarlightable move = new RO_ShootingStarlight(
                        //figKoma,//駒
                        srcKoma,       // 移動元
                        dstKoma,       // 移動先
                        PieceType.None //取った駒不明
                        );
                    komabetuAllMove.AddOverwrite(figKoma, move);

                    // これが通称【水際のいんちきプログラム】なんだぜ☆
                    // 必要により、【成り】の指し手を追加します。
                    Converter04.AddKomaBETUAllNariMoves(
                        komabetuAllMove,
                        figKoma,
                        srcKoma,
                        dstKoma
                        );
                }
            });

            //Converter04.AssertNariMove(komabetuAllMove, "#KomabetuMasus_ToKomabetuAllMove");//ここはOK

            return(komabetuAllMove);
        }
Exemple #6
0
        /// <summary>
        /// 指定された局面で、指定された手番の駒の、利きマスを算出します。
        /// 持ち駒は盤上にないので、利きを調べる必要はありません。
        ///
        /// 「手目」は判定できません。
        ///
        /// </summary>
        /// <param name="kouho"></param>
        /// <param name="sbGohosyu"></param>
        /// <param name="logger"></param>
        public static List_OneAndMulti <Finger, SySet <SyElement> > LAAAA_GetEffect(
            bool enableLog,
            bool isHonshogi,
            SkyConst src_Sky,
            Playerside pside_genTeban3,
            bool isAiteban,
            GraphicalLog_File logF_kiki,
            string logBrd_caption,
            int yomuDeep_forLog,//脳内読み手数
            int tesumi_yomiCur_forLog,
            ShootingStarlightable move_forLog
            )
        {
            GraphicalLog_Board logBrd_kiki = new GraphicalLog_Board();

            logBrd_kiki.Caption        = logBrd_caption;// "利き_"
            logBrd_kiki.Tesumi         = tesumi_yomiCur_forLog;
            logBrd_kiki.NounaiYomiDeep = yomuDeep_forLog;
            //logBrd_kiki.Score = 0.0d;
            logBrd_kiki.GenTeban = pside_genTeban3;// 現手番
            logF_kiki.boards.Add(logBrd_kiki);

            // 《1》
            List_OneAndMulti <Finger, SySet <SyElement> > sMs_effect = new List_OneAndMulti <Finger, SySet <SyElement> >();//盤上の駒の利き

            {
                // 《1.1》
                Playerside tebanSeme;  //手番(利きを調べる側)
                Playerside tebanKurau; //手番(喰らう側)
                {
                    if (isAiteban)
                    {
                        tebanSeme  = Converter04.AlternatePside(pside_genTeban3);
                        tebanKurau = pside_genTeban3;
                    }
                    else
                    {
                        tebanSeme  = pside_genTeban3;
                        tebanKurau = Converter04.AlternatePside(pside_genTeban3);
                    }

                    if (Playerside.P1 == tebanSeme)
                    {
                        logBrd_kiki.NounaiSeme = Gkl_NounaiSeme.Sente;
                    }
                    else if (Playerside.P2 == tebanSeme)
                    {
                        logBrd_kiki.NounaiSeme = Gkl_NounaiSeme.Gote;
                    }
                }


                // 《1.2》
                Fingers fingers_seme_IKUSA;  //戦駒(利きを調べる側)
                Fingers fingers_kurau_IKUSA; //戦駒(喰らう側)
                Fingers dust1;
                Fingers dust2;

                Util_Things.AAABAAAA_SplitGroup(
                    out fingers_seme_IKUSA,
                    out fingers_kurau_IKUSA,
                    out dust1,
                    out dust2,
                    src_Sky,
                    tebanSeme,
                    tebanKurau
                    );


                // 攻め手の駒の位置
                GraphicalLog_Board boardLog_clone = new GraphicalLog_Board(logBrd_kiki);
                foreach (Finger finger in fingers_seme_IKUSA.Items)
                {
                    RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(finger).Now);


                    Gkl_KomaMasu km = new Gkl_KomaMasu(
                        Util_GraphicalLog.PsideKs14_ToString(tebanSeme, Haiyaku184Array.Syurui(koma.Haiyaku), ""),
                        Util_Masu.AsMasuNumber(koma.Masu)
                        );
                    boardLog_clone.KomaMasu1.Add(km);
                }

                foreach (Finger finger in fingers_kurau_IKUSA.Items)
                {
                    RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(finger).Now);


                    logBrd_kiki.KomaMasu2.Add(new Gkl_KomaMasu(
                                                  Util_GraphicalLog.PsideKs14_ToString(tebanKurau, Haiyaku184Array.Syurui(koma.Haiyaku), ""),
                                                  Util_Masu.AsMasuNumber(koma.Masu)
                                                  ));
                }

                logBrd_kiki = boardLog_clone;



                // 《1.3》
                SySet <SyElement> masus_seme_IKUSA  = Converter04.Fingers_ToMasus(fingers_seme_IKUSA, src_Sky);  // 盤上のマス(利きを調べる側の駒)
                SySet <SyElement> masus_kurau_IKUSA = Converter04.Fingers_ToMasus(fingers_kurau_IKUSA, src_Sky); // 盤上のマス(喰らう側の駒)

                // 駒のマスの位置は、特にログに取らない。

                // 《1.4》
                Maps_OneAndOne <Finger, SySet <SyElement> > kmEffect_seme_IKUSA = Util_Things.Get_KmEffect_seme_IKUSA(
                    fingers_seme_IKUSA,//この中身がおかしい。
                    masus_seme_IKUSA,
                    masus_kurau_IKUSA,
                    src_Sky,
                    enableLog,
                    Converter04.MoveToStringForLog(move_forLog, pside_genTeban3)
                    );// 利きを調べる側の利き(戦駒)

                // 戦駒の利き
                logBrd_kiki = new GraphicalLog_Board(logBrd_kiki);
                kmEffect_seme_IKUSA.Foreach_Entry((Finger key, SySet <SyElement> value, ref bool toBreak) =>
                {
                    RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(key).Now);


                    string komaImg = Util_GraphicalLog.PsideKs14_ToString(tebanSeme, Haiyaku184Array.Syurui(koma.Haiyaku), "");

                    foreach (Basho masu in value.Elements)
                    {
                        boardLog_clone.Masu_theEffect.Add((int)masu.MasuNumber);
                    }
                });

                logBrd_kiki = boardLog_clone;


                // 《1》 = 《1.4》の戦駒+持駒
                sMs_effect.AddRange_New(kmEffect_seme_IKUSA);
            }

            return(sMs_effect);
        }
Exemple #7
0
        /// <summary>
        /// 利きに飛び込んでいないか(王手されていないか)、調べます。
        ///
        /// GetAvailableMove()の中では使わないでください。循環してしまいます。
        /// </summary>
        public static bool LAAA_KingSuicide(
            bool enableLog,
            SkyConst src_Sky,          //調べたい局面
            int yomuDeep,              //脳内読み手数
            int tesumi_yomiCur_forLog, //読み進めている現在の手目
            Playerside pside_genTeban, //現手番側
            GraphicalLog_File logF_kiki,
            ShootingStarlightable move_forLog
            )
        {
            bool isHonshogi = true;

            System.Diagnostics.Debug.Assert(src_Sky.Count == Masu_Honshogi.HONSHOGI_KOMAS);

            // 「相手の駒を動かしたときの利き」リスト
            // 持ち駒はどう考える?「駒を置けば、思い出王手だってある」
            List_OneAndMulti <Finger, SySet <SyElement> > sMs_effect_aiTeban = Util_LegalMove.LAAAA_GetEffect(
                enableLog,
                isHonshogi,
                src_Sky,
                pside_genTeban,
                true,// 相手盤の利きを調べます。
                logF_kiki,
                "玉自殺チェック",
                yomuDeep,
                tesumi_yomiCur_forLog,
                move_forLog);


            // 現手番側が受け手に回ったとします。現手番の、王の座標
            SyElement genTeban_kingMasu;

            if (Playerside.P2 == pside_genTeban)
            {
                // 現手番は、後手

                RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(Finger_Honshogi.GoteOh).Now);

                genTeban_kingMasu = koma.Masu;
            }
            else
            {
                // 現手番は、先手
                RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(Finger_Honshogi.SenteOh).Now);

                genTeban_kingMasu = koma.Masu;
            }


            // 相手の利きに、自分の王がいるかどうか確認します。
            bool mate = false;

            sMs_effect_aiTeban.Foreach_Entry((Finger koma, SySet <SyElement> kikis, ref bool toBreak) =>
            {
                foreach (Basho kiki in kikis.Elements)
                {
                    if (Util_Masu.AsMasuNumber(genTeban_kingMasu) == (int)kiki.MasuNumber)
                    {
                        mate    = true;
                        toBreak = true;
                    }
                }
            });

            return(mate);
        }
Exemple #8
0
        /// <summary>
        /// 駒別の進めるマスを返します。
        ///
        /// 指定された局面で、指定された手番の駒の、移動可能マスを算出します。
        /// 利きを調べる目的ではありません。
        ///
        /// 「手目」は判定できません。
        ///
        /// </summary>
        /// <param name="kouho"></param>
        /// <param name="sbGohosyu"></param>
        /// <param name="logger"></param>
        public static void LA_Get_KomaBETUSusumeruMasus(
            out List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus,
            MmGenjo_MovableMasu mmGenjo,
            MmLogGenjo log_orNull
            )
        {
            if (null != log_orNull)
            {
                log_orNull.Log1(mmGenjo.Pside_genTeban3);
            }


            // 《1》 移動可能場所
            komaBETUSusumeruMasus = new List_OneAndMulti <Finger, SySet <SyElement> >();
            {
                //
                // 《1.1》 手番を2つのグループに分類します。
                //
                //  ┌─手番──────┬──────┐
                //  │                  │            │
                //  │  利きを調べる側  │  喰らう側  │
                //  └─────────┴──────┘
                Playerside tebanSeme;   //手番(利きを調べる側)
                Playerside tebanKurau;  //手番(喰らう側)
                {
                    Util_MovableMove.SplitGroup_Teban(out tebanSeme, out tebanKurau, mmGenjo.IsAiteban, mmGenjo.Pside_genTeban3);
                    if (null != log_orNull)
                    {
                        log_orNull.Log2(tebanSeme, tebanKurau);
                    }
                }


                //
                // 《1.2》 駒を4つのグループに分類します。
                //
                //  ┌─駒──────────┬─────────┐
                //  │                        │                  │
                //  │  利きを調べる側の戦駒  │  喰らう側の戦駒  │
                //  ├────────────┼─────────┤
                //  │                        │                  │
                //  │  利きを調べる側の持駒  │  喰らう側の持駒  │
                //  └────────────┴─────────┘
                //
                Fingers fingers_seme_IKUSA;  //戦駒(利きを調べる側)
                Fingers fingers_kurau_IKUSA; //戦駒(喰らう側)
                Fingers fingers_seme_MOTI;   // 持駒(利きを調べる側)
                Fingers fingers_kurau_MOTI;  // 持駒(喰らう側)
                {
                    Util_Things.AAABAAAA_SplitGroup(out fingers_seme_IKUSA, out fingers_kurau_IKUSA, out fingers_seme_MOTI, out fingers_kurau_MOTI, mmGenjo.Src_Sky, tebanSeme, tebanKurau);
                    if (null != log_orNull)
                    {
                        log_orNull.Log3(mmGenjo.Src_Sky, tebanKurau, tebanSeme, fingers_kurau_IKUSA, fingers_kurau_MOTI, fingers_seme_IKUSA, fingers_seme_MOTI);
                    }
                }



                //
                // 《1.3》 駒を2つのグループに分類します。
                //
                //  ┌─盤上のマス───┬──────┐
                //  │                  │            │
                //  │  利きを調べる側  │  喰らう側  │
                //  └─────────┴──────┘
                //
                SySet <SyElement> masus_seme_IKUSA;  // 盤上のマス(利きを調べる側の駒)
                SySet <SyElement> masus_kurau_IKUSA; // 盤上のマス(喰らう側の駒)
                {
                    Util_MovableMove.SplitGroup_Ikusa(out masus_seme_IKUSA, out masus_kurau_IKUSA, mmGenjo.Src_Sky, fingers_kurau_IKUSA, fingers_seme_IKUSA);
                    // 駒のマスの位置は、特にログに取らない。
                }



                // 《1.4》
                Maps_OneAndOne <Finger, SySet <SyElement> > kmSusumeruMasus_seme_IKUSA;
                if (null != log_orNull)
                {
                    kmSusumeruMasus_seme_IKUSA = Util_Things.Get_KmEffect_seme_IKUSA(
                        fingers_seme_IKUSA,
                        masus_seme_IKUSA,
                        masus_kurau_IKUSA,
                        mmGenjo.Src_Sky,
                        log_orNull.Enable,
                        Converter04.MoveToStringForLog(log_orNull.Move, mmGenjo.Pside_genTeban3)
                        );// 盤上の駒の移動できる場所
                }
                else
                {
                    kmSusumeruMasus_seme_IKUSA = Util_Things.Get_KmEffect_seme_IKUSA(
                        fingers_seme_IKUSA,
                        masus_seme_IKUSA,
                        masus_kurau_IKUSA,
                        mmGenjo.Src_Sky,
                        false, //log.Enable,
                        ""
                        );     // 盤上の駒の移動できる場所
                }

                // 持ち駒を置ける場所
                List_OneAndMulti <Finger, SySet <SyElement> > sMsSusumeruMasus_seme_MOTI;
                if (null != log_orNull)
                {
                    sMsSusumeruMasus_seme_MOTI = Util_Things.Get_Move_Moti(
                        fingers_seme_MOTI,
                        masus_seme_IKUSA,
                        masus_kurau_IKUSA,
                        mmGenjo.Src_Sky,
                        Converter04.MoveToStringForLog(log_orNull.Move, mmGenjo.Pside_genTeban3)
                        );
                }
                else
                {
                    sMsSusumeruMasus_seme_MOTI = Util_Things.Get_Move_Moti(
                        fingers_seme_MOTI,
                        masus_seme_IKUSA,
                        masus_kurau_IKUSA,
                        mmGenjo.Src_Sky,
                        ""
                        );
                }

                if (null != log_orNull)
                {
                    log_orNull.Log4(mmGenjo.Src_Sky, tebanSeme, kmSusumeruMasus_seme_IKUSA);
                }



                try
                {
                    // 《1》 = 《1.4》の戦駒+持駒

                    // 盤上の駒の移動できる場所を足します。
                    komaBETUSusumeruMasus.AddRange_New(kmSusumeruMasus_seme_IKUSA);

                    // 持ち駒の置ける場所を足します。
                    komaBETUSusumeruMasus.AddRange_New(sMsSusumeruMasus_seme_MOTI);
                }
                catch (Exception ex)
                {
                    //>>>>> エラーが起こりました。
                    throw new Exception($"{ex.GetType().Name} {ex.Message}:ランダムチョイス(50):");
                }
            }
        }