/// <summary> /// a - b = c /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="sbGohosyu"></param> public static Maps_OneAndOne <Finger, SySet <SyElement> > MinusMasus( SkyConst src_Sky_forLog, Maps_OneAndOne <Finger, SySet <SyElement> > a1, SySet <SyElement> b ) { //GraphicalLogUtil.Log(enableLog, "Thought_KomaAndMove#MinusMasus", // "["+ // GraphicalLogUtil.JsonKyokumens_MultiKomabetuMasus(enableLog, siteiSky_forLog, a1, "a1") + // "]" // ); Maps_OneAndOne <Finger, SySet <SyElement> > c = new Maps_OneAndOne <Finger, SySet <SyElement> >(a1); List <Finger> list_koma = c.ToKeyList();//調べたい側の全駒 foreach (Finger selfKoma in list_koma) { SySet <SyElement> srcMasus = c.ElementAt(selfKoma); SySet <SyElement> minusedMasus = srcMasus.Minus_Closed(b, Util_SyElement_BinaryOperator.Dlgt_Equals_MasuNumber); // 差替え c.AddReplace(selfKoma, minusedMasus, false);//差分に差替えます。もともと無い駒なら何もしません。 } return(c); }
/// <summary> /// a - b = c /// </summary> /// <param name="a"></param> /// <param name="b"></param> /// <param name="sbGohosyu"></param> public static Maps_OneAndOne <Finger, SySet <SyElement> > Minus_OverThereMasus( SkyConst src_srcSky_forLog, Maps_OneAndOne <Finger, SySet <SyElement> > a, SySet <SyElement> b ) { Maps_OneAndOne <Finger, SySet <SyElement> > c = new Maps_OneAndOne <Finger, SySet <SyElement> >(a); bool enableLog = false; //if (null != errH_orNull) //{ // enableLog = errH_orNull.Logger.Enable; //} foreach (Finger selfKoma in c.ToKeyList())//調べたい側の全駒 { SySet <SyElement> srcMasus = c.ElementAt(selfKoma); // a -overThere b するぜ☆ Util_GraphicalLog.WriteHtml5(enableLog, "Thought_KomaAndMove Minus_OverThereMasus1", $@"[ [ {Util_FormatJson_LogGraphicEx.JsonElements_Masus(enableLog, srcMasus, "(1)引く前")} ], ], " ); SySet <SyElement> minusedMasus = srcMasus.Clone(); minusedMasus.MinusMe_Opened(b, Util_SyElement_BinaryOperator.Dlgt_Equals_MasuNumber); // 差替え c.AddReplace(selfKoma, minusedMasus, false);//差分に差替えます。もともと無い駒なら何もしません。 } Util_GraphicalLog.WriteHtml5(enableLog, "Thought_KomaAndMove Minus_OverThereMasus2", $@"[ [ {Util_FormatJson_LogGraphicEx.JsonKyokumens_MultiKomabetuMasus(enableLog, src_srcSky_forLog, a, "(1)a")}{Util_FormatJson_LogGraphicEx.JsonElements_Masus(enableLog, b, "(2)-overThere_b")}{Util_FormatJson_LogGraphicEx.JsonKyokumens_MultiKomabetuMasus(enableLog, src_srcSky_forLog, c, "(3)=c")} ], ], " ); return(c); }
/// <summary> /// FIXME: 使ってない? /// /// 変換『「駒→手」のコレクション』→『「駒、指し手」のペアのリスト』 /// </summary> public static List <Couple <Finger, SyElement> > ToList( Maps_OneAndOne <Finger, SySet <SyElement> > km ) { List <Couple <Finger, SyElement> > kmList = new List <Couple <Finger, SyElement> >(); foreach (Finger koma in km.ToKeyList()) { SySet <SyElement> masus = km.ElementAt(koma); foreach (SyElement masu in masus.Elements) { // セットとして作っているので、重複エレメントは無いはず……☆ kmList.Add(new Couple <Finger, SyElement>(koma, masu)); } } return(kmList); }
/// <summary> /// 打ち歩詰め処理。 /// /// TODO:打ち歩詰めチェック /// </summary> public static void Utifudume( SkyConst src_Sky, SySet <SyElement> masus_mikata_onBanjo, //打ち歩詰めチェック用 SySet <SyElement> masus_aite_onBanjo, //打ち歩詰めチェック用 SySet <SyElement>[] aMasus //駒種類別、置こうとする升 ) { // 攻め側 Playerside pside_seme = src_Sky.KaisiPside; // 相手の王の位置 RO_Star king_aite; Finger figKing_aite; Playerside pside_aite; switch (src_Sky.KaisiPside) { case Playerside.P1: pside_aite = Playerside.P2; figKing_aite = Finger_Honshogi.GoteOh; king_aite = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(figKing_aite).Now); break; case Playerside.P2: pside_aite = Playerside.P1; figKing_aite = Finger_Honshogi.SenteOh; king_aite = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(figKing_aite).Now); break; default: throw new Exception("エラー:打ち歩詰めチェック中。プレイヤー不明。"); } // 相手の玉頭の升。 SyElement masu_gyokutou = null; { SySet <SyElement> sySet = KomanoKidou.DstIppo_上(pside_aite, king_aite.Masu); foreach (SyElement element2 in sySet.Elements)//最初の1件を取る。 { masu_gyokutou = element2; break; } if (null == masu_gyokutou) { goto gt_EndUtifudume; } } // 相手の玉。 Fingers fingers_aiteKing = new Fingers(); fingers_aiteKing.Add(figKing_aite); // 相手の玉頭に、自分側の利きがあるかどうか。 bool isKiki_mikata = false; { // 利き一覧 Maps_OneAndOne <Finger, SySet <SyElement> > kikiMap = Query_FingersMasusSky.To_KomabetuKiki_OnBanjo( fingers_aiteKing, masus_mikata_onBanjo, masus_aite_onBanjo, src_Sky ); int gyokutouMasuNumber = Conv_SyElement.ToMasuNumber(masu_gyokutou); kikiMap.Foreach_Values((SySet <SyElement> values, ref bool toBreak) => { foreach (SyElement element in values.Elements) { int masuNumber = Conv_SyElement.ToMasuNumber(element); if (masuNumber == gyokutouMasuNumber) { isKiki_mikata = true; toBreak = true; break; } } }); } if (!isKiki_mikata) { goto gt_EndUtifudume; } // 相手の玉頭に、利きのある相手側の駒の種類の一覧。 List <PieceType> ksList = new List <PieceType>(); SySet <SyElement> aitegyokuKiki; { // 相手側の盤上の駒一覧。 Fingers fingers_aiteKoma_Banjo = Util_Sky_FingersQuery.InOkibaPsideNow(src_Sky, Okiba.ShogiBan, pside_aite); // 利き一覧 Maps_OneAndOne <Finger, SySet <SyElement> > kikiMap = Query_FingersMasusSky.To_KomabetuKiki_OnBanjo( fingers_aiteKoma_Banjo, masus_aite_onBanjo, //相手の駒は、味方 masus_mikata_onBanjo, //味方の駒は、障害物。 src_Sky ); aitegyokuKiki = kikiMap.ElementAt(figKing_aite); int gyokutouMasuNumber = Conv_SyElement.ToMasuNumber(masu_gyokutou); kikiMap.Foreach_Entry((Finger figKoma, SySet <SyElement> values, ref bool toBreak) => { foreach (SyElement element in values.Elements) { int masuNumber = Conv_SyElement.ToMasuNumber(element); if (masuNumber == gyokutouMasuNumber) { ksList.Add(Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(figKoma).Now).Komasyurui); break; } } }); } // 「王様でしか取れない状態」ではなければ、スルー。 if (ksList.Count != 1) { goto gt_EndUtifudume; } else if (ksList[0] != PieceType.K) { goto gt_EndUtifudume; } // 「王様に逃げ道がある」なら、スルー。 MasubetuKikisu masubetuKikisu_semeKoma = Util_SkyPside.ToMasubetuKikisu(src_Sky, pside_seme); Dictionary <int, int> nigerarenaiMap = new Dictionary <int, int>(); switch (src_Sky.KaisiPside) { case Playerside.P1: nigerarenaiMap = masubetuKikisu_semeKoma.Kikisu_AtMasu_2P; break; case Playerside.P2: nigerarenaiMap = masubetuKikisu_semeKoma.Kikisu_AtMasu_1P; break; default: throw new Exception("エラー:打ち歩詰めチェック中。プレイヤー不明。"); } foreach (SyElement element in aitegyokuKiki.Elements) { // 攻撃側の利きが利いていない、空きマスがあるかどうか。 int movableMasuNumber_king = Conv_SyElement.ToMasuNumber(element); if (nigerarenaiMap[movableMasuNumber_king] == 0) { // 逃げ切った☆! goto gt_EndUtifudume; } } //---------------------------------------- // 打ち歩詰め確定 //---------------------------------------- // 1升(玉頭升)を、クリアーします。 aMasus[(int)PieceType.P].Minus_Closed( masu_gyokutou, Util_SyElement_BinaryOperator.Dlgt_Equals_MasuNumber); gt_EndUtifudume: ; }