/// <summary> /// 指定の場所にある駒を返します。 /// /// 先後は見ますが、将棋盤限定です。 /// /// </summary> /// <param name="okiba">置き場</param> /// <param name="masu">筋、段</param> /// <param name="uc_Main">メインパネル</param> /// <returns>駒。無ければヌル。</returns> public static Finger InShogibanMasuNow(SkyConst src_Sky, Playerside pside, SyElement masu) { Finger foundKoma = Fingers.Error_1; foreach (Finger finger in Finger_Honshogi.Items_KomaOnly) { IMoveHalf sl = src_Sky.StarlightIndexOf(finger); RO_Star koma = Util_Starlightable.AsKoma(sl.Now); int suji1; int suji2; int dan1; int dan2; Util_MasuNum.TryMasuToSuji(koma.Masu, out suji1); Util_MasuNum.TryMasuToSuji(masu, out suji2); Util_MasuNum.TryMasuToDan(koma.Masu, out dan1); Util_MasuNum.TryMasuToDan(masu, out dan2); // 先後は見ますが、将棋盤限定です。 if ( koma.Pside == pside && Conv_SyElement.ToOkiba(koma.Masu) == Okiba.ShogiBan && suji1 == suji2 && dan1 == dan2 ) { foundKoma = finger; break; } } return(foundKoma); }
/// <summary> /// ************************************************************************************************************************ /// 1マス上、のように指定して、マスを取得します。 /// ************************************************************************************************************************ /// </summary> /// <param name="offsetSuji"></param> /// <param name="offsetDan"></param> /// <returns></returns> public static SyElement Offset(Okiba okiba, SyElement masu, int offsetSuji, int offsetDan) { int suji; int dan; Util_MasuNum.TryMasuToSuji(masu, out suji); Util_MasuNum.TryMasuToDan(masu, out dan); return(Util_Masu10.OkibaSujiDanToMasu( okiba, suji + offsetSuji, dan + offsetDan )); }
/// <summary> /// ************************************************************************************************************************ /// 棋譜用の符号テキスト(*1)を作ります。 /// ************************************************************************************************************************ /// /// *1…「▲5五銀上」など。 /// /// “同”表記に「置き換えない」バージョンです。 /// /// </summary> /// <param name="move"></param> /// <param name="previousKomaP"></param> /// <returns></returns> public static string ToString_NoUseDou( JsaFugoImpl jsaFugo, RO_Starbeam move ) { StringBuilder sb = new StringBuilder(); RO_Star koma = Util_Starlightable.AsKoma(move.Now); sb.Append(Conv_Playerside.ToSankaku(koma.Pside)); //------------------------------ // “同”に変換せず、“筋・段”をそのまま出します。 //------------------------------ int suji; int dan; Util_MasuNum.TryMasuToSuji(koma.Masu, out suji); Util_MasuNum.TryMasuToDan(koma.Masu, out dan); sb.Append(Conv_Int.ToArabiaSuji(suji)); sb.Append(Conv_Int.ToKanSuji(dan)); //------------------------------ // “歩”とか。“全”ではなく“成銀” <符号用> //------------------------------ sb.Append(Util_Komasyurui14.Fugo[(int)jsaFugo.Syurui]); //------------------------------ // “右”とか //------------------------------ sb.Append(Conv_MigiHidari.ToStr(jsaFugo.MigiHidari)); //------------------------------ // “寄”とか //------------------------------ sb.Append(Conv_AgaruHiku.ToStr(jsaFugo.AgaruHiku)); //------------------------------ // “成”とか //------------------------------ sb.Append(Conv_NariNarazu.Nari_ToStr(jsaFugo.Nari)); //------------------------------ // “打”とか //------------------------------ sb.Append(Conv_DaHyoji.ToBool(jsaFugo.DaHyoji)); return(sb.ToString()); }
//------------------------------------------------------------ #endregion /// <summary> /// 「2八」といった表記にして返します。 /// /// Conv_SyElement使用。 /// </summary> /// <param name="masu"></param> /// <returns></returns> public static string ToSujiKanji(SyElement masu) { StringBuilder sb = new StringBuilder(); int suji; int dan; Util_MasuNum.TryMasuToSuji(masu, out suji); Util_MasuNum.TryMasuToDan(masu, out dan); sb.Append(Conv_Int.ToArabiaSuji(suji)); sb.Append(Conv_Int.ToKanSuji(dan)); return(sb.ToString()); }
/// <summary> /// ************************************************************************************************************************ /// 1マス上、のように指定して、マスを取得します。 /// ************************************************************************************************************************ /// </summary> /// <param name="offsetSuji"></param> /// <param name="offsetDan"></param> /// <returns></returns> public static SyElement Offset(Okiba okiba, SyElement masu, Playerside pside, Hogaku muki) { int offsetSuji; int offsetDan; Util_Muki.MukiToOffsetSujiDan(muki, pside, out offsetSuji, out offsetDan); int suji; int dan; Util_MasuNum.TryMasuToSuji(masu, out suji); Util_MasuNum.TryMasuToDan(masu, out dan); return(Util_Masu10.OkibaSujiDanToMasu( okiba, suji + offsetSuji, dan + offsetDan)); }
/// <summary> /// ************************************************************************************************************************ /// 指定の筋にあるスプライトを返します。(本将棋用)二歩チェックに利用。 /// ************************************************************************************************************************ /// </summary> /// <param name="src_Sky"></param> /// <param name="okiba">置き場</param> /// <param name="pside">先後</param> /// <param name="pside">駒種類</param> /// <param name="suji">筋番号1~9</param> /// <returns></returns> public static Fingers InOkibaPsideKomasyuruiSujiNow(SkyConst src_Sky, Okiba okiba, Playerside pside, PieceType ks, int suji) { Fingers found = new Fingers(); foreach (Finger finger in Finger_Honshogi.Items_KomaOnly) { RO_Star koma2 = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(finger).Now); int suji2; Util_MasuNum.TryMasuToSuji(koma2.Masu, out suji2); if ( Conv_SyElement.ToOkiba(koma2.Masu) == okiba && koma2.Pside == pside && koma2.Komasyurui == ks && suji2 == suji ) { found.Add(finger); } } return(found); }
/// <summary> /// 指定した持ち駒全てについて、基本的な駒の動きを返します。(金は「前、ななめ前、横、下に進める」のような) /// (ポテンシャル・ムーブ=障害物がなかったときの動き) /// /// 1局面につき、1回実行される。 /// </summary> /// <param name="src_Sky"></param> /// <param name="fingers_sirabetaiMOTIkoma"></param> /// <param name="motiOkenaiMasus">持ち駒を置けないマス(味方駒、敵駒が置いてあるマス)</param> /// <returns></returns> public static List_OneAndMulti <Finger, SySet <SyElement> > Translate_Motikoma_ToMove( SkyConst src_Sky, Fingers fingers_sirabetaiMOTIkoma, SySet <SyElement> masus_mikata_onBanjo, //打ち歩詰めチェック用 SySet <SyElement> masus_aite_onBanjo, //打ち歩詰めチェック用 SySet <SyElement> motiOkenaiMasus ) { // 駒種類別、置こうとする升 SySet <SyElement>[] aMasus = new SySet <SyElement> [Array_Komasyurui.Items_AllElements.Length]; // 駒種類別、置こうとする駒(持駒の代表) RO_Star[] aDaihyo = new RO_Star[Array_Komasyurui.Items_AllElements.Length]; // 駒種類別、置こうとする駒番号 Finger[] aFigKoma = new Finger[Array_Komasyurui.Items_AllElements.Length]; Finger[] daihyoArray;// 持駒。駒の種類代表1個 Util_Fingers_KomasyuruiQuery.Translate_Fingers_ToKomasyuruiBETUFirst( src_Sky, fingers_sirabetaiMOTIkoma, out daihyoArray ); foreach (Finger figDaihyo in daihyoArray) { if (Fingers.Error_1 != figDaihyo) { RO_Star daihyo = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(figDaihyo).Now); #if DEBUG Debug.Assert(daihyo != null, "持ち駒の代表がヌル"); #endif // 駒種類別、置こうとする駒 aDaihyo[(int)daihyo.Komasyurui] = daihyo; // 駒種類別、置こうとする升 aMasus[(int)daihyo.Komasyurui] = Util_Sky_SyugoQuery.KomaKidou_Potential(figDaihyo, src_Sky); // 駒種類別、置こうとする駒番号 aFigKoma[(int)daihyo.Komasyurui] = figDaihyo; } } if (aDaihyo[(int)PieceType.P] != null)// 攻め手が、歩を持っているなら { //---------------------------------------- // 二歩チェック //---------------------------------------- // // 打てない筋の升を除外します。 // #if DEBUG //if (null != errH_orNull) //{ // Logger.Trace("----------------------------------------"); // Logger.Trace($"歩を置きたかった升={Util_SySet.Dump_Elements(aMasus[(int)Komasyurui14.H01_Fu_____])}"); // Logger.Trace("----------------------------------------"); // Logger.Trace("歩の置けない筋チェック(二歩チェック)開始"); //} #endif // 将棋盤上の自歩一覧。 Fingers banjoJiFus = Util_Sky_FingersQuery.InOkibaPsideKomasyuruiNow( src_Sky, //指定局面 Okiba.ShogiBan, //将棋盤上の aDaihyo[(int)PieceType.P].Pside, //持駒を持っているプレイヤー側の PieceType.P //歩 ); #if DEBUG //if (null != errH_orNull) //{ // Logger.Trace($"banjoJiFus.Count=[{banjoJiFus.Count}]"); // foreach (Finger figKoma in banjoJiFus.Items) // { // Logger.Trace($"figKoma=[{(int)figKoma}]"); // } // Logger.Trace("----------------------------------------"); //} #endif // 筋別、歩のあるなしチェック bool[] existsFu_sujibetu = new bool[10]; foreach (Finger figBanjoJiFu in banjoJiFus.Items) { RO_Star banjoJiFu = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(figBanjoJiFu).Now); int suji;//1~9 Util_MasuNum.TryMasuToSuji(banjoJiFu.Masu, out suji); existsFu_sujibetu[suji] = true; } // 9筋 確認します。 for (int suji = 1; suji < 10; suji++) { if (existsFu_sujibetu[suji]) { // 二歩になる筋番号の発見☆ #if DEBUG //Logger.Trace($"二歩チェック: {suji}筋は二歩。"); #endif // 筋一列を、クリアーします。 // 駒種類別、置こうとする升 aMasus[(int)PieceType.P] = aMasus[(int)PieceType.P].Minus_Closed( Masu_Honshogi.BAN_SUJIS[suji], Util_SyElement_BinaryOperator.Dlgt_Equals_MasuNumber); } } #if DEBUG //if (null != errH_orNull) //{ // Logger.Trace("歩の置けない筋チェック(二歩チェック)終了"); // Logger.Trace("----------------------------------------"); // Logger.Trace($"歩の置ける升={Util_SySet.Dump_Elements(aMasus[(int)Komasyurui14.H01_Fu_____])}"); // Logger.Trace("----------------------------------------"); //} #endif //---------------------------------------- // 打ち歩詰めチェック //---------------------------------------- if (false) { Util_Utifudume.Utifudume( src_Sky, masus_mikata_onBanjo, //打ち歩詰めチェック用 masus_aite_onBanjo, //打ち歩詰めチェック用 aMasus //駒種類別、置こうとする升 ); } } //---------------------------------------- // 集計 //---------------------------------------- // 「どの持ち駒を」「どこに置ける」のコレクション。 List_OneAndMulti <Finger, SySet <SyElement> > result = new List_OneAndMulti <Finger, SySet <SyElement> >(); foreach (PieceType ks in Array_Komasyurui.MotiKoma7Syurui) { // 置こうとする駒があれば if (null != aDaihyo[(int)ks]) { // 置けない升を引きます。 aMasus[(int)ks] = aMasus[(int)ks].Minus_Closed( motiOkenaiMasus, Util_SyElement_BinaryOperator.Dlgt_Equals_MasuNumber); if (!aMasus[(int)ks].IsEmptySet()) { // 置ける升があれば登録 result.AddNew( aFigKoma[(int)ks], //置こうとする持駒番号 aMasus[(int)ks] //置ける升 ); } } } return(result); }
/// <summary> /// ************************************************************************************************************************ /// SFEN符号表記。 /// ************************************************************************************************************************ /// </summary> /// <returns></returns> public static string ToMoveStrSfen( IMove move, [CallerMemberName] string memberName = "", [CallerFilePath] string sourceFilePath = "", [CallerLineNumber] int sourceLineNumber = 0 ) { StringBuilder sb = new StringBuilder(); try { if (Util_Sky258A.RootMove == move) { sb.Append(ConvMoveStrSfen.KIFU_TREE_LOG_ROOT_FOLDER); goto gt_EndMethod; } RO_Star srcKoma = Util_Starlightable.AsKoma(move.LongTimeAgo); RO_Star dstKoma = Util_Starlightable.AsKoma(move.Now); //int srcDan; //if (!Util_MasuNum.TryMasuToDan(srcKoma.Masu, out srcDan)) //{ // throw new Exception("指定の元マス[$"{Util_Masu10.AsMasuNumber(srcKoma.Masu)}]は、段に変換できません。 : {memberName}.{sourceFilePath}.{sourceLineNumber}"); //} //int dan; //if (!Util_MasuNum.TryMasuToDan(dstKoma.Masu, out dan)) //{ // throw new Exception($"指定の先マス[{Util_Masu10.AsMasuNumber(dstKoma.Masu)}]は、段に変換できません。 : {memberName}.{sourceFilePath}.{sourceLineNumber}"); //} if (Util_Sky_BoolQuery.IsDaAction(move)) { // 打でした。 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // (自)筋・(自)段は書かずに、「P*」といった表記で埋めます。 sb.Append(Util_Komasyurui14.SfenDa[(int)Util_Komahaiyaku184.Syurui(srcKoma.Haiyaku)]); sb.Append("*"); } else { //------------------------------------------------------------ // (自)筋 //------------------------------------------------------------ string strSrcSuji; int srcSuji; if (Util_MasuNum.TryMasuToSuji(srcKoma.Masu, out srcSuji)) { strSrcSuji = srcSuji.ToString(); } else { strSrcSuji = "N筋";//エラー表現 } sb.Append(strSrcSuji); //------------------------------------------------------------ // (自)段 //------------------------------------------------------------ string strSrcDan2; int srcDan2; if (Util_MasuNum.TryMasuToDan(srcKoma.Masu, out srcDan2)) { strSrcDan2 = Conv_Int.ToAlphabet(srcDan2); } else { strSrcDan2 = "N段";//エラー表現 } sb.Append(strSrcDan2); } //------------------------------------------------------------ // (至)筋 //------------------------------------------------------------ string strSuji; int suji2; if (Util_MasuNum.TryMasuToSuji(dstKoma.Masu, out suji2)) { strSuji = suji2.ToString(); } else { strSuji = "N筋";//エラー表現 } sb.Append(strSuji); //------------------------------------------------------------ // (至)段 //------------------------------------------------------------ string strDan; int dan2; if (Util_MasuNum.TryMasuToDan(dstKoma.Masu, out dan2)) { strDan = Conv_Int.ToAlphabet(dan2); } else { strDan = "N段";//エラー表現 } sb.Append(strDan); //------------------------------------------------------------ // 成 //------------------------------------------------------------ if (Util_Sky_BoolQuery.IsNattaMove(move)) { sb.Append("+"); } } catch (Exception e) { sb.Append(e.Message);//FIXME: } gt_EndMethod: ; return(sb.ToString()); }
/// <summary> /// ************************************************************************************************************************ /// 棋譜用の符号テキスト(*1)を作ります。 /// ************************************************************************************************************************ /// /// *1…「▲5五銀上」など。 /// /// </summary> /// <param name="douExpr">“同”表記に置き換えるなら真。</param> /// <param name="previousKomaP"></param> /// <returns></returns> public static string ToString_UseDou( JsaFugoImpl jsaFugo, Node <IMove, KyokumenWrapper> siteiNode ) { StringBuilder sb = new StringBuilder(); IMove curMove = siteiNode.Key; RO_Star curSrcKoma = Util_Starlightable.AsKoma(curMove.LongTimeAgo); RO_Star curDstKoma = Util_Starlightable.AsKoma(curMove.Now); sb.Append(Conv_Playerside.ToSankaku(curDstKoma.Pside)); //------------------------------ // “同”で表記できるところは、“同”で表記します。それ以外は“筋・段”で表記します。 //------------------------------ if (!siteiNode.IsRoot()) { IMove preMove = siteiNode.GetParentNode().Key; if (null != preMove) { //RO_Star_Koma preSrcKoma = Util_Starlightable.AsKoma(preMove.LongTimeAgo); RO_Star preDstKoma = Util_Starlightable.AsKoma(preMove.Now); if (Conv_SyElement.ToMasuNumber(preDstKoma.Masu) == Conv_SyElement.ToMasuNumber(curDstKoma.Masu)) { // “同” sb.Append("同"); goto gt_Next1; } } } { // “筋・段” int suji; int dan; Util_MasuNum.TryMasuToSuji(curDstKoma.Masu, out suji); Util_MasuNum.TryMasuToDan(curDstKoma.Masu, out dan); sb.Append(Conv_Int.ToArabiaSuji(suji)); sb.Append(Conv_Int.ToKanSuji(dan)); } gt_Next1: ; //------------------------------ // “歩”とか。“全”ではなく“成銀” <符号用> //------------------------------ sb.Append(Util_Komasyurui14.Fugo[(int)jsaFugo.Syurui]); //------------------------------ // “右”とか //------------------------------ sb.Append(Conv_MigiHidari.ToStr(jsaFugo.MigiHidari)); //------------------------------ // “寄”とか //------------------------------ sb.Append(Conv_AgaruHiku.ToStr(jsaFugo.AgaruHiku)); //------------------------------ // “成”とか //------------------------------ sb.Append(Conv_NariNarazu.Nari_ToStr(jsaFugo.Nari)); //------------------------------ // “打”とか //------------------------------ sb.Append(Conv_DaHyoji.ToBool(jsaFugo.DaHyoji)); return(sb.ToString()); }
/// <summary> /// 重複をなくした表現 /// </summary> /// <returns></returns> public static string LogString_Set( SySet <SyElement> masus ) { StringBuilder sb = new StringBuilder(); if (masus is SySet_Default <SyElement> ) { HashSet <T1> set = new HashSet <T1>(); // まず自分の要素 foreach (T1 hMasu1 in ((SySet_Default <SyElement>)masus).Elements_) { set.Add(hMasu1); } // 次に親集合 foreach (SySet <T1> superset in ((SySet_Default <SyElement>)masus).Supersets) { foreach (T1 hMasu2 in superset.Elements) { set.Add(hMasu2); } } T1[] array = set.ToArray(); Array.Sort(array); int fieldCount = 0; foreach (T1 masuHandle in array) { sb.Append("["); sb.Append(masuHandle); sb.Append("]"); fieldCount++; if (fieldCount % 20 == 19) { sb.AppendLine(); } } } else if (masus is SySet_Ordered <SyElement> ) { // まず自分の要素 foreach (T1 hMasu1 in ((SySet_Ordered <SyElement>)masus).Elements_) { int suji; int dan; Util_MasuNum.TryMasuToSuji(hMasu1, out suji); Util_MasuNum.TryMasuToDan(hMasu1, out dan); sb.Append($"[{suji}{dan}]"); } // 次に親集合 foreach (SySet <SyElement> superset in ((SySet_Ordered <SyElement>)masus).Supersets) { sb.Append(Util_Masus <New_Basho> .LogString_Concrete(superset)); } } else if (masus is SySet_DirectedSegment <SyElement> ) { sb.Append("["); foreach (T1 hMasu1 in ((SySet_DirectedSegment <SyElement>)masus).Elements) { int suji; int dan; Util_MasuNum.TryMasuToSuji(hMasu1, out suji); Util_MasuNum.TryMasuToDan(hMasu1, out dan); sb.Append($"{suji}{dan}→"); } // 最後の矢印は削除します。 if ("[".Length < sb.Length) { sb.Remove(sb.Length - 1, 1); } sb.Append("]"); } else { } return(sb.ToString()); }
/// <summary> /// 筋も残し、全件網羅 /// </summary> /// <returns></returns> public static string LogString_Concrete( SySet <SyElement> masus ) { StringBuilder sb = new StringBuilder(); if (masus is SySet_Default <SyElement> ) { // まず自分の要素 foreach (SyElement hMasu1 in ((SySet_Default <SyElement>)masus).Elements_) { int suji; int dan; Util_MasuNum.TryMasuToSuji(hMasu1, out suji); Util_MasuNum.TryMasuToDan(hMasu1, out dan); sb.Append($"[{suji}{dan}]"); } // 次に親集合 foreach (SySet <SyElement> superset in ((SySet_Default <SyElement>)masus).Supersets) { sb.Append(Util_Masus <SyElement> .LogString_Concrete(superset)); } } else if (masus is SySet_Ordered <SyElement> ) { // まず自分の要素 foreach (SyElement hMasu1 in ((SySet_Ordered <SyElement>)masus).Elements_) { int suji; int dan; Util_MasuNum.TryMasuToSuji(hMasu1, out suji); Util_MasuNum.TryMasuToDan(hMasu1, out dan); sb.Append($"[{suji}{dan}]"); } // 次に親集合 foreach (SySet <SyElement> superset in ((SySet_Ordered <SyElement>)masus).Supersets) { sb.Append(Util_Masus <SyElement> .LogString_Concrete(superset)); } } else if (masus is SySet_DirectedSegment <SyElement> ) { sb.Append("["); foreach (T1 hMasu1 in ((SySet_DirectedSegment <SyElement>)masus).Elements) { int suji; int dan; Util_MasuNum.TryMasuToSuji(hMasu1, out suji); Util_MasuNum.TryMasuToDan(hMasu1, out dan); sb.Append($"{suji}{dan}→"); } // 最後の矢印は削除します。 if ("[".Length < sb.Length) { sb.Remove(sb.Length - 1, 1); } sb.Append("]"); } else { } return(sb.ToString()); }