Example #1
0
        /// <summary>
        /// 一手指します。または、一手戻します。
        /// </summary>
        /// <param name="move"></param>
        /// <param name="kifu"></param>
        /// <param name="isMakimodosi"></param>
        /// <param name="figMovedKoma"></param>
        /// <param name="figFoodKoma">取られた駒</param>
        /// <param name="out_newNode_OrNull"></param>
        /// <param name="memberName"></param>
        /// <param name="sourceFilePath"></param>
        /// <param name="sourceLineNumber"></param>
        public static void Ittesasi(
            ShootingStarlightable move,
            KifuTree kifu,
            bool isMakimodosi,
            out Finger figMovedKoma,
            out Finger figFoodKoma,
            out Node <ShootingStarlightable, KyokumenWrapper> out_newNode_OrNull
            ,
            [CallerMemberName] string memberName    = "",
            [CallerFilePath] string sourceFilePath  = "",
            [CallerLineNumber] int sourceLineNumber = 0
            )
        {
            out_newNode_OrNull = null;
            figFoodKoma        = Fingers.Error_1;


            KifuIO.Kifusasi25(
                out figMovedKoma,
                move,
                kifu,
                isMakimodosi
                );


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


            PieceType syurui2 = KifuIO.Kifusasi30_Naru(move, isMakimodosi);


            Starlight dst = KifuIO.Kifusasi35_NextMasu(syurui2, move, kifu, isMakimodosi);



            KifuIO.Kifusasi52_WhenKifuRead(
                dst,
                syurui2,
                ref figMovedKoma,
                out figFoodKoma,
                move,
                kifu,
                isMakimodosi,
                out out_newNode_OrNull
                );



gt_EndMethod:

            if (isMakimodosi)
            {
                Node <ShootingStarlightable, KyokumenWrapper> removedLeaf = kifu.PopCurrentNode();
            }

            Logger.Trace("一手指しが終わったぜ☆ ノードが追加されているんじゃないか☆? ");
        }
Example #2
0
        public static SkyConst Sasu(
            SkyConst src_Sky,         //現局面
            Finger finger,            //動かす駒
            SyElement masu,           //移動先マス
            Playerside pside_genTeban //動かす駒がどちらのプレイヤーのものか
            )
        {
            SkyBuffer dst_Sky = new SkyBuffer(src_Sky.Clone()); // 現局面をコピーします。

            // 移動先に相手の駒がないか、確認します。
            Finger tottaKoma = Util_Sky.Fingers_AtMasuNow(new SkyConst(dst_Sky), masu).ToFirst();

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

                if (pside_genTeban == Playerside.P1)
                {
                    akiMasu = KifuIO.GetKomadaiKomabukuroSpace(Okiba.Sente_Komadai, new SkyConst(dst_Sky));
                }
                else
                {
                    akiMasu = KifuIO.GetKomadaiKomabukuroSpace(Okiba.Gote_Komadai, new SkyConst(dst_Sky));
                }


                RO_Star_Koma koma = Util_Koma.AsKoma(dst_Sky.StarlightIndexOf(tottaKoma).Now);

                // FIXME:配役あってるか?
                dst_Sky.AddOverwriteStarlight(tottaKoma, new RO_MotionlessStarlight(new RO_Star_Koma(pside_genTeban, akiMasu, koma.Syurui)));//tottaKoma,
            }

            // 駒を1個動かします。
            // FIXME: 取った駒はどうなっている?
            {
                RO_Star_Koma koma = Util_Koma.AsKoma(dst_Sky.StarlightIndexOf(finger).Now);

                dst_Sky.AddOverwriteStarlight(finger, new RO_MotionlessStarlight(new RO_Star_Koma(pside_genTeban, masu, koma.Syurui)));//finger,
            }

            return(new SkyConst(dst_Sky));
        }
Example #3
0
        public string Execute(
            ref KifuParserA_Result result,
            IRoomViewModel roomViewModel,
            out KifuParserA_State nextState,
            KifuParserA owner,
            KifuParserA_Genjo genjo
            )
        {
            // 現局面。
            SkyConst src_Sky = roomViewModel.GameViewModel.Kifu.CurNode.Value.ToKyokumenConst;
            //            Debug.Assert(!Util_MasuNum.OnKomabukuro((int)((RO_Star_Koma)src_Sky.StarlightIndexOf((Finger)0).Now).Masu), "カレント、駒が駒袋にあった。");

            bool isHonshogi = true;                                                                                                   //FIXME:暫定
            int  tesumi_yomiGenTeban_forLog = roomViewModel.GameViewModel.Kifu.CountTesumi(roomViewModel.GameViewModel.Kifu.CurNode); // 0;//FIXME:暫定。読み進めている現在の手目

            //            Debug.Assert(!Util_MasuNum.OnKomabukuro((int)((RO_Star_Koma)kifu.NodeAt(tesumi_yomiGenTeban_forLog).Value.ToKyokumenConst.StarlightIndexOf((Finger)0).Now).Masu), "[" + tesumi_yomiGenTeban_forLog + "]手目、駒が駒袋にあった。");

            nextState = this;

            if (0 < genjo.InputLine.Trim().Length)
            {
                ShootingStarlightable nextTe = Util_Sky.NullObjectMove;
                string rest;

                //「6g6f」形式と想定して、1手だけ読込み
                string str1;
                string str2;
                string str3;
                string str4;
                string str5;
                string str6;
                string str7;
                string str8;
                string str9;
                if (KifuIO_MovesParsers.ParseSfen_FromText(
                        genjo.InputLine, out str1, out str2, out str3, out str4, out str5, out rest)
                    &&
                    !(str1 == "" && str2 == "" && str3 == "" && str4 == "" && str5 == "")
                    )
                {
                    KifuIO_MovesExecuter.ExecuteSfenMoves_FromTextSub(
                        isHonshogi,
                        str1,  //123456789 か、 PLNSGKRB
                        str2,  //abcdefghi か、 *
                        str3,  //123456789
                        str4,  //abcdefghi
                        str5,  //+
                        out nextTe,
                        roomViewModel.GameViewModel.Kifu,
                        "_SFENパース1",
                        tesumi_yomiGenTeban_forLog
                        );
                }
                else
                {
                    //>>>>> 「6g6f」形式ではなかった☆

                    //「▲6六歩」形式と想定して、1手だけ読込み
                    if (KifuIO_MovesParsers.ParseJfugo_FromText(
                            genjo.InputLine, out str1, out str2, out str3, out str4, out str5, out str6, out str7, out str8, out str9, out rest))
                    {
                        if (!(str1 == "" && str2 == "" && str3 == "" && str4 == "" && str5 == "" && str6 == "" && str7 == "" && str8 == "" && str9 == ""))
                        {
                            KifuIO_MovesExecuter.ExecuteJfugo_FromTextSub(
                                str1, //▲△
                                str2, //123…9、123…9、一二三…九
                                str3, //123…9、123…9、一二三…九
                                str4, // “同”
                                str5, //(歩|香|桂|…
                                str6, // 右|左…
                                str7, // 上|引
                                str8, //成|不成
                                str9, //打
                                out nextTe,
                                roomViewModel.GameViewModel.Kifu
                                );
                        }
                    }
                    else
                    {
                        //「6g6f」形式でもなかった☆

                        Logger.Trace("(^△^)「" + genjo.InputLine + "」vs【" + this.GetType().Name + "】 : !? 次の一手が読めない☆ inputLine=[" + genjo.InputLine + "]");
                        genjo.ToBreak = true;
                        goto gt_EndMethod;
                    }
                }

                genjo.InputLine = rest;



                if (null != nextTe)
                {
                    Finger figMovedKoma = Fingers.Error_1;
                    Finger figFoodKoma  = Fingers.Error_1;

                    Application.DoEvents(); // 時間のかかる処理の間にはこれを挟みます。

                    //------------------------------
                    // ★棋譜読込専用  駒移動
                    //------------------------------

                    Logger.Trace("一手指し開始 : 残りの符号つ「" + genjo.InputLine + "」");
                    bool isBack = false;
                    Node <ShootingStarlightable, KyokumenWrapper> out_newNode_OrNull;
                    KifuIO.Ittesasi(
                        nextTe,
                        roomViewModel.GameViewModel.Kifu,
                        isBack,
                        out figMovedKoma,
                        out figFoodKoma,
                        out out_newNode_OrNull//変更した現局面が、ここに入る。
                        );
                    result.Out_newNode_OrNull = out_newNode_OrNull;
                    Logger.Trace(Util_Sky.Json_1Sky(
                                     src_Sky, "一手指し終了",
                                     "_SFENパース2",
                                     tesumi_yomiGenTeban_forLog//読み進めている現在の手目
                                     ));
                }
                else
                {
                    genjo.ToBreak = true;
                    throw new Exception($"\(^o^)/teMoveオブジェクトがない☆! inputLine=[{genjo.InputLine}]");
                }
            }
            else
            {
                Logger.Trace("(^△^)現局面まで進んだのかだぜ☆?\n" + Util_Sky.Json_1Sky(
                                 src_Sky, "棋譜パース",
                                 "_SFENパース3",
                                 tesumi_yomiGenTeban_forLog//読み進めている現在の手目
                                 ));
                genjo.ToBreak = true;
            }

gt_EndMethod:
            return(genjo.InputLine);
        }
Example #4
0
        /// <summary>
        /// 棋譜[再生]時用(マウス操作のときは関係ない)
        ///
        ///         一手進む、一手[巻戻し]に対応。
        ///
        /// </summary>
        /// <param name="move">棋譜に記録するために「指す前/指した後」を含めた手。</param>
        /// <param name="kifu"></param>
        /// <param name="isMakimodosi"></param>
        private static void Kifusasi52_WhenKifuRead(
            Starlight dst,
            PieceType syurui2,
            ref Finger figMovedKoma,
            out Finger out_figFoodKoma,
            ShootingStarlightable move,
            KifuTree kifu,
            bool isMakimodosi,
            out Node <ShootingStarlightable, KyokumenWrapper> out_newNode_OrNull
            )
        {
            out_figFoodKoma = Fingers.Error_1;

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

            //------------------------------------------------------------
            // 駒を取る
            //------------------------------------------------------------
            if (!isMakimodosi)
            {
                RO_Star_Koma dstKoma = Util_Koma.AsKoma(dst.Now);


                PieceType foodKomaSyurui;//取られた駒の種類

                //----------
                // 将棋盤上のその場所に駒はあるか
                //----------
                foodKomaSyurui  = PieceType.None;                                                                         //ひとまずクリアー
                out_figFoodKoma = Util_Sky.Fingers_AtMasuNow(kifu.CurNode.Value.ToKyokumenConst, dstKoma.Masu).ToFirst(); //盤上

                if (Fingers.Error_1 != out_figFoodKoma)
                {
                    //>>>>> 指した先に駒があったなら

                    //
                    // 取られる駒
                    //
                    foodKomaSyurui = Util_Koma.AsKoma(kifu.CurNode.Value.ToKyokumenConst.StarlightIndexOf(out_figFoodKoma).Now).Syurui;

                    //
                    // 取られる駒は、駒置き場の空きマスに移動させます。
                    //
                    Okiba      okiba;
                    Playerside pside;
                    switch (dstKoma.Pside)
                    {
                    case Playerside.P1:
                    {
                        okiba = Okiba.Sente_Komadai;
                        pside = Playerside.P1;
                    }
                    break;

                    case Playerside.P2:
                    {
                        okiba = Okiba.Gote_Komadai;
                        pside = Playerside.P2;
                    }
                    break;

                    default:
                    {
                        //>>>>> エラー: 先後がおかしいです。

                        throw new Exception($@"エラー: 先後がおかしいです。
dst.Pside={dstKoma.Pside}");
                    }
                    }

                    // 駒台の空きスペース
                    SyElement akiMasu = akiMasu = KifuIO.GetKomadaiKomabukuroSpace(okiba, kifu.CurNode.Value.ToKyokumenConst);

                    if (Masu_Honshogi.Error == akiMasu)
                    {
                        //>>>>> エラー: 駒台に空きスペースがありませんでした。
                        throw new Exception($@"エラー: 駒台に空きスペースがありませんでした。
駒台={Okiba.Gote_Komadai}");
                    }

                    //>>>>> 駒台に空きスペースがありました。

                    //
                    // 取られる動き
                    //
                    {
                        SkyBuffer buffer_Sky = new SkyBuffer(kifu.CurNode.Value.ToKyokumenConst);
                        buffer_Sky.AddOverwriteStarlight(
                            out_figFoodKoma,
                            new RO_MotionlessStarlight(
                                //out_figFoodKoma,
                                new RO_Star_Koma(
                                    pside,
                                    akiMasu,                                                                                          //駒台の空きマスへ
                                    Util_Koma.AsKoma(kifu.CurNode.Value.ToKyokumenConst.StarlightIndexOf(out_figFoodKoma).Now).Syurui //駒の種類
                                    )
                                )
                            );
                        kifu.CurNode.Value.SetKyokumen(new SkyConst(buffer_Sky));
                        // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                        // この時点で局面データに変更あり
                        // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                    }



                    //------------------------------
                    // 成っていれば、「成り」は解除。
                    //------------------------------
                    RO_Star_Koma koma3 = Util_Koma.AsKoma(kifu.CurNode.Value.ToKyokumenConst.StarlightIndexOf(out_figFoodKoma).Now);


                    switch (Util_Masu.GetOkiba(koma3.Masu))
                    {
                    case Okiba.Sente_Komadai:    //thru
                    case Okiba.Gote_Komadai:
                        // 駒台へ移動しました
                        //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>

                        SkyBuffer buffer_Sky = new SkyBuffer(kifu.CurNode.Value.ToKyokumenConst);
                        buffer_Sky.AddOverwriteStarlight(out_figFoodKoma, new RO_MotionlessStarlight(
                                                             //out_figFoodKoma,
                                                             new RO_Star_Koma(koma3.Pside,
                                                                              koma3.Masu,
                                                                              koma3.ToNarazuCase())
                                                             )
                                                         );
                        kifu.CurNode.Value.SetKyokumen(new SkyConst(buffer_Sky));
                        // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                        // この時点で局面データに変更あり
                        // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

                        break;
                    }


                    //------------------------------
                    // 取った駒を棋譜に覚えさせます。(差替え)
                    //------------------------------
                    kifu.AppendChildB_Swap(
                        foodKomaSyurui,
                        kifu.CurNode.Value.ToKyokumenConst,
                        "KifuIO_Kifusasi52"
                        );
                    //}
                }
            }

            //------------------------------------------------------------
            // 駒の移動
            //------------------------------------------------------------
            {
                SkyBuffer buffer_Sky = new SkyBuffer(kifu.CurNode.Value.ToKyokumenConst);
                buffer_Sky.AddOverwriteStarlight(figMovedKoma, dst);
                kifu.CurNode.Value.SetKyokumen(new SkyConst(buffer_Sky));
            }
            // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
            // この時点で局面データに変更あり
            // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■


            //------------------------------------------------------------
            // 取った駒を戻す
            //------------------------------------------------------------
            if (isMakimodosi)
            {
                RO_Star_Koma koma = Util_Koma.AsKoma(move.Now);


                if (PieceType.None != (PieceType)move.FoodKomaSyurui)
                {
                    // 駒台から、駒を検索します。
                    Okiba okiba;
                    if (Playerside.P2 == koma.Pside)
                    {
                        okiba = Okiba.Gote_Komadai;
                    }
                    else
                    {
                        okiba = Okiba.Sente_Komadai;
                    }


                    // 取った駒は、種類が同じなら、駒台のどの駒でも同じです。
                    Finger temp_figFoodKoma = Util_Sky.FingerNow_BySyuruiIgnoreCase(kifu.CurNode.Value.ToKyokumenConst, okiba, (PieceType)move.FoodKomaSyurui);
                    if (Fingers.Error_1 != temp_figFoodKoma)
                    {
                        // 取った駒のデータをセットし直します。
                        SkyBuffer buffer_Sky = new SkyBuffer(kifu.CurNode.Value.ToKyokumenConst);

                        buffer_Sky.AddOverwriteStarlight(
                            temp_figFoodKoma,
                            new RO_MotionlessStarlight(
                                //temp_figFoodKoma,
                                new RO_Star_Koma(
                                    Converter04.AlternatePside(koma.Pside), //先後を逆にして駒台に置きます。
                                    koma.Masu,                              // マス
                                    (PieceType)move.FoodKomaSyurui
                                    )
                                )
                            );

                        kifu.CurNode.Value.SetKyokumen(new SkyConst(buffer_Sky));
                        // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                        // この時点で局面データに変更あり
                        // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■

                        out_figFoodKoma = temp_figFoodKoma;
                    }
                }
            }


            //
            // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
            // 局面データに変更があったものとして進めます。
            // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
            //
            out_newNode_OrNull = kifu.CurNode;// この変数を返すのがポイント。
            {
                out_newNode_OrNull.Value.SetKyokumen(kifu.CurNode.Value.ToKyokumenConst);

                kifu.CurNode.Value.SetKyokumen(kifu.CurNode.Value.ToKyokumenConst);
            }
        }
Example #5
0
        /// <summary>
        /// [巻戻し]時の、駒台にもどる動きを吸収。
        /// </summary>
        /// <param name="syurui2"></param>
        /// <param name="move">棋譜に記録するために「指す前/指した後」を含めた手。</param>
        /// <param name="kifu"></param>
        /// <param name="isMakimodosi"></param>
        /// <returns></returns>
        private static Starlight Kifusasi35_NextMasu(
            PieceType syurui2,
            ShootingStarlightable move,
            KifuTree kifu,
            bool isMakimodosi)
        {
            Starlight dst;

            RO_Star_Koma srcKoma = Util_Koma.AsKoma(move.LongTimeAgo); //移動元
            RO_Star_Koma dstKoma = Util_Koma.AsKoma(move.Now);         //移動先


            if (isMakimodosi)
            {
                SyElement masu;

                if (
                    Okiba.Gote_Komadai == Util_Masu.GetOkiba(srcKoma.Masu) ||
                    Okiba.Sente_Komadai == Util_Masu.GetOkiba(srcKoma.Masu)
                    )
                {
                    //>>>>> 1手前が駒台なら

                    // 駒台の空いている場所

                    Node <ShootingStarlightable, KyokumenWrapper> node6 = kifu.CurNode;

                    masu = KifuIO.GetKomadaiKomabukuroSpace(Util_Masu.GetOkiba(srcKoma.Masu), node6.Value.ToKyokumenConst);
                    // 必ず空いている場所があるものとします。
                }
                else
                {
                    //>>>>> 1手前が将棋盤上なら

                    // その位置
                    masu = srcKoma.Masu;//戻し先
                }



                dst = new RO_MotionlessStarlight(
                    //move.Finger,
                    new RO_Star_Koma(dstKoma.Pside,
                                     masu,//戻し先
                                     syurui2)
                    );
            }
            else
            {
                // 次の位置


                dst = new RO_MotionlessStarlight(
                    //move.Finger,
                    new RO_Star_Koma(dstKoma.Pside,
                                     dstKoma.Masu,
                                     syurui2)
                    );
            }

            return(dst);
        }