public static void SplitGroup_Teban( out Playerside tebanSeme, //手番(利きを調べる側) out Playerside tebanKurau, //手番(喰らう側) bool isAiteban, Playerside pside_genTeban3 ) { if (isAiteban) { tebanSeme = Converter04.AlternatePside(pside_genTeban3); tebanKurau = pside_genTeban3; } else { tebanSeme = pside_genTeban3; tebanKurau = Converter04.AlternatePside(pside_genTeban3); } }
/// <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); }
/// <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); } }