예제 #1
0
        /// <summary>
        /// 打ち歩詰め処理。
        ///
        /// TODO:打ち歩詰めチェック
        /// </summary>
        public static void Utifudume(
            SkyConst src_Sky,
            SySet <SyElement> masus_mikata_onBanjo, //打ち歩詰めチェック用
            SySet <SyElement> masus_aite_onBanjo,   //打ち歩詰めチェック用
            SySet <SyElement>[] aMasus              //駒種類別、置こうとする升
            )
        {
            // 攻め側
            Playerside pside_seme = src_Sky.KaisiPside;

            // 相手の王の位置
            RO_Star    king_aite;
            Finger     figKing_aite;
            Playerside pside_aite;

            switch (src_Sky.KaisiPside)
            {
            case Playerside.P1:
                pside_aite   = Playerside.P2;
                figKing_aite = Finger_Honshogi.GoteOh;
                king_aite    = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(figKing_aite).Now);
                break;

            case Playerside.P2:
                pside_aite   = Playerside.P1;
                figKing_aite = Finger_Honshogi.SenteOh;
                king_aite    = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(figKing_aite).Now);
                break;

            default: throw new Exception("エラー:打ち歩詰めチェック中。プレイヤー不明。");
            }

            // 相手の玉頭の升。
            SyElement masu_gyokutou = null;
            {
                SySet <SyElement> sySet = KomanoKidou.DstIppo_上(pside_aite, king_aite.Masu);
                foreach (SyElement element2 in sySet.Elements)//最初の1件を取る。
                {
                    masu_gyokutou = element2;
                    break;
                }

                if (null == masu_gyokutou)
                {
                    goto gt_EndUtifudume;
                }
            }

            // 相手の玉。
            Fingers fingers_aiteKing = new Fingers();

            fingers_aiteKing.Add(figKing_aite);

            // 相手の玉頭に、自分側の利きがあるかどうか。
            bool isKiki_mikata = false;

            {
                // 利き一覧
                Maps_OneAndOne <Finger, SySet <SyElement> > kikiMap = Query_FingersMasusSky.To_KomabetuKiki_OnBanjo(
                    fingers_aiteKing,
                    masus_mikata_onBanjo,
                    masus_aite_onBanjo,
                    src_Sky
                    );

                int gyokutouMasuNumber = Conv_SyElement.ToMasuNumber(masu_gyokutou);
                kikiMap.Foreach_Values((SySet <SyElement> values, ref bool toBreak) =>
                {
                    foreach (SyElement element in values.Elements)
                    {
                        int masuNumber = Conv_SyElement.ToMasuNumber(element);
                        if (masuNumber == gyokutouMasuNumber)
                        {
                            isKiki_mikata = true;
                            toBreak       = true;
                            break;
                        }
                    }
                });
            }

            if (!isKiki_mikata)
            {
                goto gt_EndUtifudume;
            }

            // 相手の玉頭に、利きのある相手側の駒の種類の一覧。
            List <PieceType>  ksList = new List <PieceType>();
            SySet <SyElement> aitegyokuKiki;

            {
                // 相手側の盤上の駒一覧。
                Fingers fingers_aiteKoma_Banjo = Util_Sky_FingersQuery.InOkibaPsideNow(src_Sky, Okiba.ShogiBan, pside_aite);

                // 利き一覧
                Maps_OneAndOne <Finger, SySet <SyElement> > kikiMap = Query_FingersMasusSky.To_KomabetuKiki_OnBanjo(
                    fingers_aiteKoma_Banjo,
                    masus_aite_onBanjo,   //相手の駒は、味方
                    masus_mikata_onBanjo, //味方の駒は、障害物。
                    src_Sky
                    );
                aitegyokuKiki = kikiMap.ElementAt(figKing_aite);

                int gyokutouMasuNumber = Conv_SyElement.ToMasuNumber(masu_gyokutou);
                kikiMap.Foreach_Entry((Finger figKoma, SySet <SyElement> values, ref bool toBreak) =>
                {
                    foreach (SyElement element in values.Elements)
                    {
                        int masuNumber = Conv_SyElement.ToMasuNumber(element);
                        if (masuNumber == gyokutouMasuNumber)
                        {
                            ksList.Add(Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(figKoma).Now).Komasyurui);
                            break;
                        }
                    }
                });
            }

            // 「王様でしか取れない状態」ではなければ、スルー。
            if (ksList.Count != 1)
            {
                goto gt_EndUtifudume;
            }
            else if (ksList[0] != PieceType.K)
            {
                goto gt_EndUtifudume;
            }

            // 「王様に逃げ道がある」なら、スルー。
            MasubetuKikisu        masubetuKikisu_semeKoma = Util_SkyPside.ToMasubetuKikisu(src_Sky, pside_seme);
            Dictionary <int, int> nigerarenaiMap          = new Dictionary <int, int>();

            switch (src_Sky.KaisiPside)
            {
            case Playerside.P1: nigerarenaiMap = masubetuKikisu_semeKoma.Kikisu_AtMasu_2P; break;

            case Playerside.P2: nigerarenaiMap = masubetuKikisu_semeKoma.Kikisu_AtMasu_1P; break;

            default: throw new Exception("エラー:打ち歩詰めチェック中。プレイヤー不明。");
            }
            foreach (SyElement element in aitegyokuKiki.Elements)
            {
                // 攻撃側の利きが利いていない、空きマスがあるかどうか。
                int movableMasuNumber_king = Conv_SyElement.ToMasuNumber(element);

                if (nigerarenaiMap[movableMasuNumber_king] == 0)
                {
                    // 逃げ切った☆!
                    goto gt_EndUtifudume;
                }
            }

            //----------------------------------------
            // 打ち歩詰め確定
            //----------------------------------------

            // 1升(玉頭升)を、クリアーします。

            aMasus[(int)PieceType.P].Minus_Closed(
                masu_gyokutou, Util_SyElement_BinaryOperator.Dlgt_Equals_MasuNumber);


gt_EndUtifudume:
            ;
        }
예제 #2
0
        /// <summary>
        /// 駒別の進めるマスを返します。
        ///
        /// 指定された局面で、指定された手番の駒の、移動可能マスを算出します。
        /// 利きを調べる目的ではありません。
        ///
        /// 「手目」は判定できません。
        ///
        /// </summary>
        /// <param name="kouho"></param>
        /// <param name="sbGohosyu"></param>
        /// <param name="logger"></param>
        public static void LA_Split_KomaBETUSusumeruMasus(
            int caller_forLog,//デバッグ用。
            out List_OneAndMulti <Finger, SySet <SyElement> > out_komaBETUSusumeruMasus,

            bool isHonshogi,
            SkyConst src_Sky,
            Playerside pside_genTeban3,
            bool isAiteban
#if DEBUG
            ,
            MmLogGenjo mmLog_orNull
#endif
            )
        {
            //if (null != log_orNull)
            //{
            //    log_orNull.Log1(mmGenjo.Pside_genTeban3);
            //}


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


                //
                // 《1.2》 駒を4つのグループに分類します。
                //
                //  ┌─駒──────────┬─────────┐
                //  │                        │                  │
                //  │  利きを調べる側の戦駒  │  喰らう側の戦駒  │
                //  ├────────────┼─────────┤
                //  │                        │                  │
                //  │  利きを調べる側の持駒  │  喰らう側の持駒  │
                //  └────────────┴─────────┘
                //
                Fingers fingers_seme_BANJO;  //盤上駒(利きを調べる側)
                Fingers fingers_kurau_BANJO; //盤上駒(喰らう側)
                Fingers fingers_seme_MOTI;   // 持駒(利きを調べる側)
                Fingers fingers_kurau_MOTI;  // 持駒(喰らう側)
                {
                    Util_Sky_FingersQueryFx.Split_BanjoSeme_BanjoKurau_MotiSeme_MotiKurau(
                        out fingers_seme_BANJO, out fingers_kurau_BANJO, out fingers_seme_MOTI, out fingers_kurau_MOTI, src_Sky, tebanSeme, tebanKurau);
                    //#if DEBUG
                    //                    Logger.Trace($"◇fingers_seme_BANJOの要素数={fingers_seme_BANJO.Count}");
                    //                    Logger.Trace($"◇fingers_kurau_BANJOの要素数={fingers_kurau_BANJO.Count}");
                    //                    Logger.Trace($"◇fingers_seme_MOTIの要素数={fingers_seme_MOTI.Count}");
                    //                    Logger.Trace($"◇fingers_kurau_MOTIの要素数={fingers_kurau_MOTI.Count}");
                    //#endif
                    //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_BANJO;  // 盤上のマス(利きを調べる側の駒)
                SySet <SyElement> masus_kurau_BANJO; // 盤上のマス(喰らう側の駒)
                {
                    Util_KyokumenMoves.SplitGroup_Banjo(out masus_seme_BANJO, out masus_kurau_BANJO, src_Sky, fingers_kurau_BANJO, fingers_seme_BANJO);
                    // 駒のマスの位置は、特にログに取らない。
                }



                // 《1.4》
                Maps_OneAndOne <Finger, SySet <SyElement> > kmSusumeruMasus_seme_BANJO;
                kmSusumeruMasus_seme_BANJO = Query_FingersMasusSky.To_KomabetuKiki_OnBanjo(
                    fingers_seme_BANJO,
                    masus_seme_BANJO,
                    masus_kurau_BANJO,
                    src_Sky
                    );// 盤上の駒の移動できる場所

                //
                // 持ち駒(代表)を置ける場所
                //
                List_OneAndMulti <Finger, SySet <SyElement> > sMsSusumeruMasus_seme_MOTI;
                sMsSusumeruMasus_seme_MOTI = Util_KyokumenMoves.Get_MotiDaihyo_ToMove(
                    caller_forLog,
                    fingers_seme_MOTI,
                    masus_seme_BANJO,
                    masus_kurau_BANJO,
                    src_Sky//これは、どの局面?
                    );
                //#if DEBUG
                //                Logger.Trace($"sMsSusumeruMasus_seme_MOTIの要素数={Util_List_OneAndMultiEx<Finger, SySet<SyElement>>.CountAllElements(sMsSusumeruMasus_seme_MOTI))}";
                //#endif

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


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

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

                // 持ち駒の置ける場所を足します。
                out_komaBETUSusumeruMasus.AddRange_New(sMsSusumeruMasus_seme_MOTI);
            }
        }
예제 #3
0
        /// <summary>
        /// 指定された局面で、指定された手番の駒の、利きマスを算出します。
        /// 持ち駒は盤上にないので、利きを調べる必要はありません。
        ///
        /// 「手目」は判定できません。
        ///
        /// </summary>
        /// <param name="kouho"></param>
        /// <param name="sbGohosyu"></param>
        /// <param name="logger"></param>
        public static List_OneAndMulti <Finger, SySet <SyElement> > LAAAA_GetEffect(
            int yomikaisiTemezumi,
            bool isHonshogi,
            SkyConst src_Sky,
            Playerside pside_genTeban3,
            bool isAiteban,
#if DEBUG
            KaisetuBoards logF_kiki,
#endif
            string logBrd_caption,
            int temezumi_yomiCur_forLog,
            IMove move_forLog
            )
        {
#if DEBUG
            KaisetuBoard logBrd_kiki = new KaisetuBoard();
            logBrd_kiki.Caption           = logBrd_caption;// "利き_"
            logBrd_kiki.Temezumi          = temezumi_yomiCur_forLog;
            logBrd_kiki.YomikaisiTemezumi = yomikaisiTemezumi;
            //logBrd_kiki.Score = 0.0d;
            logBrd_kiki.GenTeban = pside_genTeban3;// 現手番
            logF_kiki.boards.Add(logBrd_kiki);
#endif

            // 《1》
            List_OneAndMulti <Finger, SySet <SyElement> > sMs_effect = new List_OneAndMulti <Finger, SySet <SyElement> >();//盤上の駒の利き
            {
                // 《1.1》
                Playerside tebanSeme;  //手番(利きを調べる側)
                Playerside tebanKurau; //手番(喰らう側)
                {
                    if (isAiteban)
                    {
                        tebanSeme  = Conv_Playerside.Reverse(pside_genTeban3);
                        tebanKurau = pside_genTeban3;
                    }
                    else
                    {
                        tebanSeme  = pside_genTeban3;
                        tebanKurau = Conv_Playerside.Reverse(pside_genTeban3);
                    }

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


                // 《1.2》
                Fingers fingers_seme_BANJO;  //盤上駒(利きを調べる側)
                Fingers fingers_kurau_BANJO; //盤上駒(喰らう側)
                Fingers dust1;
                Fingers dust2;

                Util_Sky_FingersQueryFx.Split_BanjoSeme_BanjoKurau_MotiSeme_MotiKurau(
                    out fingers_seme_BANJO,
                    out fingers_kurau_BANJO,
                    out dust1,
                    out dust2,
                    src_Sky,
                    tebanSeme,
                    tebanKurau
                    );


                // 攻め手の駒の位置
#if DEBUG
                KaisetuBoard boardLog_clone = new KaisetuBoard(logBrd_kiki);
                foreach (Finger finger in fingers_seme_BANJO.Items)
                {
                    RO_Star koma = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(finger).Now);


                    Gkl_KomaMasu km = new Gkl_KomaMasu(
                        Util_Converter_LogGraphicEx.PsideKs14_ToString(tebanSeme, Util_Komahaiyaku184.Syurui(koma.Haiyaku), ""),
                        Conv_SyElement.ToMasuNumber(koma.Masu)
                        );
                    boardLog_clone.KomaMasu1.Add(km);
                }
                foreach (Finger finger in fingers_kurau_BANJO.Items)
                {
                    RO_Star koma = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(finger).Now);


                    logBrd_kiki.KomaMasu2.Add(new Gkl_KomaMasu(
                                                  Util_Converter_LogGraphicEx.PsideKs14_ToString(tebanKurau, Util_Komahaiyaku184.Syurui(koma.Haiyaku), ""),
                                                  Conv_SyElement.ToMasuNumber(koma.Masu)
                                                  ));
                }
                logBrd_kiki = boardLog_clone;
#endif



                // 《1.3》
                SySet <SyElement> masus_seme_BANJO  = Conv_Fingers.ToMasus(fingers_seme_BANJO, src_Sky);  // 盤上のマス(利きを調べる側の駒)
                SySet <SyElement> masus_kurau_BANJO = Conv_Fingers.ToMasus(fingers_kurau_BANJO, src_Sky); // 盤上のマス(喰らう側の駒)

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

                // 《1.4》
                Maps_OneAndOne <Finger, SySet <SyElement> > kmEffect_seme_BANJO = Query_FingersMasusSky.To_KomabetuKiki_OnBanjo(
                    fingers_seme_BANJO,//この中身がおかしい。
                    masus_seme_BANJO,
                    masus_kurau_BANJO,
                    src_Sky
                    //Conv_Move.Move_To_KsString_ForLog(move_forLog, pside_genTeban3),
                    );// 利きを調べる側の利き(戦駒)

                // 盤上駒の利き
#if DEBUG
                logBrd_kiki = new KaisetuBoard(logBrd_kiki);
                kmEffect_seme_BANJO.Foreach_Entry((Finger key, SySet <SyElement> value, ref bool toBreak) =>
                {
                    RO_Star koma = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(key).Now);


                    string komaImg = Util_Converter_LogGraphicEx.PsideKs14_ToString(tebanSeme, Util_Komahaiyaku184.Syurui(koma.Haiyaku), "");

                    foreach (New_Basho masu in value.Elements)
                    {
                        boardLog_clone.Masu_theEffect.Add(masu.MasuNumber);
                    }
                });
                logBrd_kiki = boardLog_clone;
#endif


                // 《1》 = 《1.4》の盤上駒+持駒
                sMs_effect.AddRange_New(kmEffect_seme_BANJO);
            }

            return(sMs_effect);
        }