Example #1
0
        /// <summary>
        /// 指したあとの、次の局面を作るだけ☆
        /// </summary>
        /// <param name="src_Sky"></param>
        /// <param name="finger"></param>
        /// <param name="masu"></param>
        /// <param name="pside_genTeban"></param>
        /// <param name="logTag"></param>
        /// <returns></returns>
        public static SkyConst Sasu(
            SkyConst src_Sky, //指定局面
            Finger finger,    //動かす駒
            SyElement masu,   //移動先マス
            bool toNaru       //成るなら真
            )
        {
            SkyBuffer sky_buf = new SkyBuffer(src_Sky);                         // 現局面を元に、新規局面を書き換えます。

            sky_buf.SetKaisiPside(Conv_Playerside.Reverse(src_Sky.KaisiPside)); // 開始先後を逆転させます。
            sky_buf.SetTemezumi(sky_buf.Temezumi + 1);                          // 1手進めます。
            SkyConst src_Sky2 = SkyConst.NewInstance(sky_buf,
                                                     -1                         //sky_bufでもう変えてあるので、そのまま。
                                                     );

            // 移動先に相手の駒がないか、確認します。
            Finger tottaKoma = Util_Sky_FingersQuery.InMasuNow(src_Sky2, masu).ToFirst();

            if (tottaKoma != Fingers.Error_1)
            {
                // なにか駒を取ったら
                SyElement akiMasu;

                if (src_Sky.KaisiPside == Playerside.P1)
                {
                    akiMasu = Util_IttesasuRoutine.GetKomadaiKomabukuroSpace(Okiba.Sente_Komadai, src_Sky2);
                }
                else
                {
                    akiMasu = Util_IttesasuRoutine.GetKomadaiKomabukuroSpace(Okiba.Gote_Komadai, src_Sky2);
                }


                RO_Star koma = Util_Starlightable.AsKoma(sky_buf.StarlightIndexOf(tottaKoma).Now);

                // FIXME:配役あってるか?
                sky_buf.PutOverwriteOrAdd_Starlight(tottaKoma, new RO_Starlight(new RO_Star(src_Sky.KaisiPside, akiMasu, koma.Komasyurui)));//tottaKoma,
            }

            // 駒を1個動かします。
            // FIXME: 取った駒はどうなっている?
            {
                RO_Star   koma       = Util_Starlightable.AsKoma(sky_buf.StarlightIndexOf(finger).Now);
                PieceType komaSyurui = koma.Komasyurui;

                if (toNaru)
                {
                    komaSyurui = Util_Komasyurui14.ToNariCase(komaSyurui);
                }

                sky_buf.PutOverwriteOrAdd_Starlight(finger, new RO_Starlight(new RO_Star(src_Sky.KaisiPside, masu, komaSyurui)));
            }

            return(SkyConst.NewInstance(sky_buf,
                                        -1//sky_bufでもう進めてあるので、そのまま。
                                        ));
        }
Example #2
0
 public static void SplitGroup_Teban(
     out Playerside tebanSeme,  //手番(利きを調べる側)
     out Playerside tebanKurau, //手番(喰らう側)
     bool isAiteban,
     Playerside pside_genTeban3
     )
 {
     if (isAiteban)
     {
         tebanSeme  = Conv_Playerside.Reverse(pside_genTeban3);
         tebanKurau = pside_genTeban3;
     }
     else
     {
         tebanSeme  = pside_genTeban3;
         tebanKurau = Conv_Playerside.Reverse(pside_genTeban3);
     }
 }
Example #3
0
        /// <summary>
        /// 一手戻します。
        /// </summary>
        /// <param name="ittemodosuArg"></param>
        /// <param name="ittesasu_mutable"></param>
        /// <param name="ittemodosuResult"></param>
        /// <param name="logTag"></param>
        /// <param name="memberName"></param>
        /// <param name="sourceFilePath"></param>
        /// <param name="sourceLineNumber"></param>
        public static void Before1(
            IttemodosuArg ittemodosuArg,
            out IttemodosuResult ittemodosuResult
            ,
            [CallerMemberName] string memberName    = "",
            [CallerFilePath] string sourceFilePath  = "",
            [CallerLineNumber] int sourceLineNumber = 0
            )
        {
            bool isMakimodosi = true;

            ittemodosuResult = new IttemodosuResultImpl(Fingers.Error_1, Fingers.Error_1, null, PieceType.None, null);

            //
            // 一手指し開始局面(不変)
            // 一手指し終了局面(null or 可変)
            //
            Playerside kaisi_tebanside = ((KifuNode)ittemodosuArg.KaisiNode).Value.KyokumenConst.KaisiPside;
            SkyConst   kaisi_Sky       = ittemodosuArg.KaisiNode.Value.KyokumenConst;

            //
            // 編集対象ノード(巻き戻し時と、進む時で異なる)
            //
            Node <IMove, KyokumenWrapper> editNodeRef;

            //------------------------------
            // 符号の追加(一手進む)
            //------------------------------
            {
                // 戻る時。
                ittemodosuResult.Susunda_Sky_orNull = null;
                editNodeRef = ittemodosuArg.KaisiNode;
            }


            //
            // 動かす駒を移動先へ。
            //
            Finger figMovedKoma;

            Util_IttemodosuRoutine.Do25_UgokasuKoma_IdoSakiHe(
                out figMovedKoma,
                ittemodosuArg.Move,
                kaisi_tebanside,
                kaisi_Sky
                );
            ittemodosuResult.FigMovedKoma = figMovedKoma; //動かした駒更新


            if (Fingers.Error_1 == ittemodosuResult.FigMovedKoma)
            {
                goto gt_EndMethod;
            }


            //
            // 巻き戻しなら、非成りに戻します。
            //
            PieceType syurui2 = Util_IttemodosuRoutine.Do30_MakimodosiNara_HinariNiModosu(ittemodosuArg.Move, isMakimodosi);


            IMoveHalf dst;
            {
                dst = Util_IttemodosuRoutine.Do37_KomaOnDestinationMasu(syurui2, ittemodosuArg.Move,
                                                                        kaisi_Sky);
            }



            // Sky 局面データは、この関数の途中で何回か変更されます。ローカル変数に退避しておくと、同期が取れなくなります。

            //------------------------------------------------------------
            // あれば、取られていた駒を取得
            //------------------------------------------------------------
            Finger figFoodKoma;//取られていた駒

            Util_IttemodosuRoutine.Do62_TorareteitaKoma_ifExists(
                ittemodosuArg.Move,
                kaisi_Sky,                              //巻き戻しのとき
                ittemodosuResult.Susunda_Sky_orNull,
                out figFoodKoma                         //変更される場合あり。
                );
            ittemodosuResult.FigFoodKoma = figFoodKoma; //取られていた駒更新

            //------------------------------------------------------------
            // 駒の移動
            //------------------------------------------------------------
            if (Fingers.Error_1 != figFoodKoma)
            {
                //------------------------------------------------------------
                // 指されていた駒と、取られていた駒の移動
                //------------------------------------------------------------

                //------------------------------
                // 指し手の、取った駒部分を差替えます。
                //------------------------------
                RO_Star koma = Util_Starlightable.AsKoma(ittemodosuArg.Move.Now);
                kaisi_Sky = SkyConst.NewInstance_OverwriteOrAdd_Light(
                    kaisi_Sky,
                    ittemodosuArg.KorekaranoTemezumi_orMinus1,
                    //
                    // 指されていた駒
                    //
                    figMovedKoma,
                    dst,
                    //
                    // 取られていた駒
                    //
                    figFoodKoma,
                    new RO_Starlight(
                        new RO_Star(
                            Conv_Playerside.Reverse(koma.Pside), //先後を逆にして駒台に置きます。
                            koma.Masu,                           // マス
                            (PieceType)ittemodosuArg.Move.FoodKomaSyurui
                            )
                        ));
            }
            else
            {
                //------------------------------------------------------------
                // 指されていた駒の移動
                //------------------------------------------------------------
                kaisi_Sky = SkyConst.NewInstance_OverwriteOrAdd_Light(
                    kaisi_Sky,
                    ittemodosuArg.KorekaranoTemezumi_orMinus1,
                    //
                    // 指されていた駒
                    //
                    figMovedKoma,
                    dst
                    );
            }
            editNodeRef.Value.SetKyokumen(kaisi_Sky);
            // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
            // この時点で、必ず現局面データに差替えあり
            // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


            // ノード
            ittemodosuResult.SyuryoNode_OrNull = editNodeRef;// この変数を返すのがポイント。棋譜とは別に、現局面。

gt_EndMethod:
            ;
        }
Example #4
0
        /// <summary>
        /// クローンを作ります。
        /// </summary>
        /// <param name="src"></param>
        private SkyConst(Sky src, bool toReversePlayerside, int update_temezumi_orMinus1, Finger[] finger1, IMoveHalf[] light1,
                         //
                         // 手得計算
                         //
                         PieceType tedokuKeisan_komasyurui, int tedokukeisan_index, SyElement tedokukeisan_sasitamasu)
        {
            Debug.Assert(src.Count == 40, $"本将棋とみなしてテスト中。sky.Starlights.Count=[{src.Count}]");//将棋の駒の数

            if (tedokuKeisan_komasyurui == PieceType.None)
            {
                //----------------------------------------
                // 手得計算のヒストリーを作らない場合
                //----------------------------------------

                // 手得ヒストリーのクローン
                this.tedokuHistory = TedokuHistoryConst.New_Clone(src.TedokuHistory);
            }
            else
            {
                //----------------------------------------
                // 手得計算のヒストリーを作る場合
                //----------------------------------------

                // 手駒ヒストリーへの追加
                this.tedokuHistory = TedokuHistoryConst.NewInstance_AppendSasitamasu(
                    src.TedokuHistory,
                    tedokuKeisan_komasyurui,
                    tedokukeisan_index,
                    tedokukeisan_sasitamasu
                    );
            }


            // 手番のクローン
            if (toReversePlayerside)
            {
                this.kaisiPside = Conv_Playerside.Reverse(src.KaisiPside);
            }
            else
            {
                this.kaisiPside = src.KaisiPside;
            }

            // 手目済み
            if (-1 == update_temezumi_orMinus1)
            {
                // そのまま
                this.temezumi = src.Temezumi;
            }
            else
            {
                // 上書き更新
                this.temezumi = update_temezumi_orMinus1;
            }

            // 星々のクローン
            this.starlights = new List <IMoveHalf>();
            src.Foreach_Starlights((Finger finger2, IMoveHalf light2, ref bool toBreak2) =>
            {
                this.starlights.Add(light2);
            });

            //
            // 追加分があれば。
            //
            for (int i = 0; i < finger1.Length; i++)
            {
                if (finger1[i] != Fingers.Error_1)
                {
                    if (this.starlights.Count == (int)finger1[i])
                    {
                        // オブジェクトを追加します。
                        this.starlights.Add(light1[i]);
                    }
                    else if (this.starlights.Count + 1 <= (int)finger1[i])
                    {
                        // エラー
                        Debug.Assert((int)finger1[i] < this.starlights.Count, $"要素の個数より2大きいインデックスを指定しました。 インデックス[{(int)finger1[i]}] 要素の個数[{this.starlights.Count}]");

                        throw new Exception($"{this.GetType().Name}#SetStarPos: リストの要素より2多いインデックスを指定されましたので、追加しません。starIndex=[{finger1[i]}] / this.stars.Count=[{this.starlights.Count}]");
                    }
                    else
                    {
                        this.starlights[(int)finger1[i]] = light1[i];
                    }
                }
            }
        }
Example #5
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);
        }