/// <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でもう進めてあるので、そのまま。 )); }
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); } }
/// <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: ; }
/// <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]; } } } }
/// <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); }