/// <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("一手指しが終わったぜ☆ ノードが追加されているんじゃないか☆? "); }
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)); }
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); }
/// <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); } }
/// <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); }