public void Setumei(bool isSfen, StringBuilder syuturyoku) { // 初期局面を作成 Kyokumen ky2 = new Kyokumen(); int caret = 0; ky2.ParsePositionvalue(isSfen, SyokiKyokumenFen, ref caret, false, false, out string moves, syuturyoku); // 初期局面を出力 syuturyoku.AppendLine("初期局面"); Util_Information.Setumei_NingenGameYo(ky2, syuturyoku); int temeMade = 1; foreach (Move ss in this.SsList) { syuturyoku.Append("("); syuturyoku.Append(temeMade.ToString()); syuturyoku.Append(")"); ConvMove.AppendFenTo(isSfen, ss, syuturyoku); syuturyoku.Append(" "); temeMade++; } syuturyoku.AppendLine(); }
/// <summary> /// 次の入力を促す表示をしてるだけだぜ☆(^~^) /// </summary> public static void ShowPrompt(IPlaying playing, bool isSfen, Kyokumen ky, StringBuilder syuturyoku) { if (0 < Util_Commandline.CommandBuffer.Count) { // コマンド・バッファーの実行中だぜ☆(^▽^) syuturyoku.Append($"{Util_Commandline.CommandBufferName }> "); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); } else if (GameMode.Game == Util_Application.GameMode) { // 表示(コンソール・ゲーム用) 局面、あれば勝敗☆(^~^) { if (Util_Commandline.IsKyokumenEcho) { Util_Information.Setumei_NingenGameYo(ky, syuturyoku); #if DEBUG //Util_Commands.Ky(isSfen, "ky fen", ky, syuturyoku);// 参考:改造FEN表示 //Util_Commands.MoveCmd(isSfen, "move", ky, syuturyoku);// 参考:指し手表示 //if (false){ // Util_Information.HyojiKomanoIbasho(ky.Shogiban, syuturyoku);// 参考:駒の表示 // Util_Information.HyojiKomanoKikiSu(ky.Shogiban, syuturyoku);// 参考:利きの数 //} //Util_Commands.MoveCmd(isSfen, "move seisei", ky, syuturyoku);// 参考:指し手表示 詳細 //Logger.Flush(syuturyoku); #endif playing.Result(ky, syuturyoku, CommandMode.NingenYoConsoleGame); } Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); } var(exists, phase) = ky.CurrentOptionalPhase.Match; if (exists) { if ((phase == Phase.Black && !Option_Application.Optionlist.P1Com) || (phase == Phase.White && !Option_Application.Optionlist.P2Com) ) { // 人間の手番が始まるところで☆ syuturyoku.Append( @"指し手を入力してください。一例 do B3B2 ※ do b3b2 も同じ > "); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); } } } else { // 表示(コンソール・ゲーム用) syuturyoku.Append("> "); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); } }
public static void Setumei_Kiki(Kyokumen ky, Masu attackerMs, StringBuilder syuturyoku) { var(exists, optionalPhase) = ky.Shogiban.ExistsBBKomaZenbu(attackerMs); if (exists) { ky.Shogiban.ExistsBBKoma(optionalPhase, attackerMs, out Komasyurui ks); Util_Information.Setumei_1Bitboard("利き", Util_Application.Kiki_BB(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalPhase), attackerMs, ky.Shogiban)//利き , syuturyoku); } }
public static void Assert_Sabun_Kiki(string message, Kyokumen.Sindanyo kys) { // 駒の利き☆ bool safe = true; // 再計算 Recalculate Shogiban saikeisan = new Shogiban(kys); saikeisan.Tukurinaosi_1_Clear_KikiKomabetu(); saikeisan.Tukurinaosi_2_Input_KikiKomabetu(kys); foreach (var optionalPhase in Conv_Taikyokusya.AllOptionalPhaseList) // 対局者1、対局者2 { int iKm = 0; //どの駒でエラーがあったか foreach (Koma km in Conv_Koma.ItiranTai[OptionalPhase.IndexOf(optionalPhase)]) { if (!kys.EqualsKiki(km, saikeisan))//現行版と、再計算版の比較 { safe = false; break; } iKm++; } // ダイアログボックスに収まるように分けるぜ☆ if (!safe) { StringBuilder sindan1 = new StringBuilder(); //// 参考:駒の居場所 //{ // sindan1.Append(message); // sindan1.AppendLine("参考:駒の居場所"); // Util_Information.HyojiKomanoIbasho(ky.BB_KomaZenbu, ky.BB_Koma, sindan1); // sindan1.AppendLine($"Util_Tansaku.TansakuTyakusyuEdas=[{Util_Tansaku.TansakuTyakusyuEdas}]"); //} sindan1.Append(message); sindan1.Append("【エラー】"); Conv_Taikyokusya.Setumei_Name(optionalPhase, sindan1); sindan1.AppendLine(); sindan1.AppendLine($"iKm=[{iKm}]"); sindan1.AppendLine("利き:(再計算)"); Util_Information.Setumei_Bitboards(Med_Koma.GetKomasyuruiNamaeItiran(optionalPhase), saikeisan.WhereBBKiki(optionalPhase), sindan1); kys.Setumei_GenkoKiki(optionalPhase, sindan1); // 利き:(現行) var msg = sindan1.ToString(); sindan1.Clear(); Logger.Flush(msg); Debug.Assert(safe, msg); } } }
/// <summary> /// 決着時のメッセージ表示☆ /// </summary> public static void ShowMessage_KettyakuJi(Kyokumen ky, StringBuilder syuturyoku) { if (TaikyokuKekka.Karappo != Util_Application.Result(ky)) { // 表示(コンソール・ゲーム用) 勝敗☆(^~^)””” syuturyoku.AppendLine("決着図"); Util_Information.Setumei_NingenGameYo(ky, syuturyoku); // 表示(コンソール・ゲーム用) 勝敗☆(^~^)””” switch (Util_Application.Result(ky)) { case TaikyokuKekka.Taikyokusya1NoKati: if (Option_Application.Optionlist.P2Com) { syuturyoku.AppendLine("まいったぜ☆(>_<)"); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); } break; case TaikyokuKekka.Taikyokusya2NoKati: if (Option_Application.Optionlist.P2Com) { syuturyoku.AppendLine("やったぜ☆(^▽^)!"); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); } break; case TaikyokuKekka.Hikiwake: { syuturyoku.AppendLine("決着を付けたかったぜ☆(^~^)"); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); } break; case TaikyokuKekka.Sennitite: { syuturyoku.AppendLine("まあ、良しとするかだぜ☆(^_^)"); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); } break; case TaikyokuKekka.Karappo: //thru default: break; } } }
/// <summary> /// 将棋盤をコンソールへ出力するぜ☆(^▽^) /// 見出し無し☆(^~^) /// </summary> /// <returns></returns> public static void Setumei_Bitboards(Bitboard[] bbHairetu, StringBuilder syuturyoku) { Util_Information.AppendLine_Top_Kyokumen(bbHairetu.Length, syuturyoku); for (int dan = 0; dan < Option_Application.Optionlist.BanTateHaba; dan++) { AppendLine_Data(bbHairetu, dan * Option_Application.Optionlist.BanYokoHaba, syuturyoku); if (dan + 1 < Option_Application.Optionlist.BanTateHaba) { AppendLine_Middle(bbHairetu.Length, syuturyoku); } } AppendLine_Bottom(bbHairetu.Length, syuturyoku); }
/// <summary> /// 駒の利き数☆(^~^) /// </summary> /// <returns></returns> public static void HyojiKomanoKikiSu(Shogiban shogiban, StringBuilder syuturyoku) { //, KikisuKomabetuCountboardItiran kikiKomabetuCB // KikisuZenbuCountboardItiran kikiZenbuCB syuturyoku.AppendLine("重ね利き数全部"); // 対局者別 全部 { // 見出し Setumei_Headers(Conv_Taikyokusya.NamaeItiran, syuturyoku); Util_Information.AppendLine_Top_Kyokumen(Conv_Taikyokusya.AllOptionalPhaseList.Length, syuturyoku); // ┌──┬──┬──┐みたいな線☆ for (int dan = 0; dan < Option_Application.Optionlist.BanTateHaba; dan++) { AppendLine_Data_Countboard(shogiban, dan * Option_Application.Optionlist.BanYokoHaba, syuturyoku); if (dan + 1 < Option_Application.Optionlist.BanTateHaba) { Util_Information.AppendLine_Middle(Conv_Taikyokusya.AllOptionalPhaseList.Length, syuturyoku); // ├──┼──┼──┤みたいな線☆ } } Util_Information.AppendLine_Bottom(Conv_Taikyokusya.AllOptionalPhaseList.Length, syuturyoku); // └──┴──┴──┘みたいな線☆ } // 駒別 foreach (var optionalPhase29 in Conv_Taikyokusya.AllOptionalPhaseList) // 対局者1、対局者2 { foreach (Koma km in Conv_Koma.ItiranTai[OptionalPhase.IndexOf(optionalPhase29)]) { syuturyoku.Append(Util_Information.FormatBanWidthZenkaku(Conv_Koma.GetName(km))); } syuturyoku.AppendLine(); Util_Information.AppendLine_Top_Kyokumen(Conv_Komasyurui.Itiran.Length, syuturyoku); for (int dan = 0; dan < Option_Application.Optionlist.BanTateHaba; dan++) { AppendLine_Data_Countboard(optionalPhase29, shogiban, dan * Option_Application.Optionlist.BanYokoHaba, syuturyoku); if (dan + 1 < Option_Application.Optionlist.BanTateHaba) { Util_Information.AppendLine_Middle(Conv_Komasyurui.Itiran.Length, syuturyoku); } } Util_Information.AppendLine_Bottom(Conv_Komasyurui.Itiran.Length, syuturyoku); } }
public static void Assert_Genkou_Bitboard(string message, Kyokumen ky) { bool safe = ky.Shogiban.Assert(); if (!safe) { StringBuilder sindan1 = new StringBuilder(); sindan1.Append(message); sindan1.AppendLine(" ビットボード診断"); Util_Information.HyojiKomanoIbasho(ky.Shogiban, sindan1); sindan1.AppendLine($"Util_Tansaku.TansakuTyakusyuEdas=[{Util_Tansaku.TansakuTyakusyuEdas}]"); var msg = sindan1.ToString(); sindan1.Clear(); Logger.Flush(msg); Debug.Fail(msg); } }
/// <summary> /// 定跡更新(ゲームセクション内) /// </summary> public static void Update2_JosekiToroku(Move bestMove, Hyokati bestHyokati, Kyokumen ky, StringBuilder syuturyoku) { if (Util_Machine.IsEnableBoardSize() && Option_Application.Optionlist.JosekiRec) { if (!IsJosekiTraced)// 定跡を使った指し手ではない場合に限り { #if DEBUG // 指し手の整合性をチェックしておきたいぜ☆(^▽^) { Kyokumen ky_forAssert = new Kyokumen(); int caret_2 = 0; if (!ky_forAssert.ParsePositionvalue(Option_Application.Optionlist.USI, KyFen_before, ref caret_2, true, false, out string moves, syuturyoku)) // ビットボードを更新したいので、適用する { syuturyoku.AppendLine("パースに失敗だぜ☆(^~^)! #鯰"); var msg = syuturyoku.ToString(); syuturyoku.Clear(); Logger.Flush(msg); throw new Exception(msg); } if (!ky_forAssert.CanDoMove(bestMove, out MoveMatigaiRiyu riyu)) { StringBuilder reigai1 = new StringBuilder(); reigai1.AppendLine("指せない指し手を定跡に登録しようとしたぜ☆(^~^)!:"); // reigai1.Append("理由:"); ConvMove.SetumeiLine(riyu, reigai1); reigai1.Append("指し手:"); ConvMove.SetumeiLine(Option_Application.Optionlist.USI, bestMove, reigai1); reigai1.Append("定跡にする1手前の局面 ("); reigai1.Append(KyFen_before); reigai1.AppendLine(")"); Util_Information.Setumei_Lines_Kyokumen(ky_forAssert, reigai1); reigai1.AppendLine(); reigai1.Append("1手後は、現局面"); Util_Information.Setumei_Lines_Kyokumen(ky, reigai1); syuturyoku.AppendLine(reigai1.ToString()); var msg = syuturyoku.ToString(); syuturyoku.Clear(); Logger.Flush(msg); throw new Exception(msg); } } #endif Option_Application.Joseki.AddMove(KyFen_before, KyHash_before, OptionalPhaseBeforeMove, bestMove, bestHyokati, Util_Tansaku.NekkoKaranoFukasa, Util_Application.VERSION, syuturyoku); } } }
/// <summary> /// 駒の動き☆ /// </summary> /// <param name="komanoUgokikata"></param> /// <param name="syuturyoku"></param> public static void HyojiKomanoUgoki(Shogiban shogiban, int masuYososu, StringBuilder syuturyoku) { // KomanoUgokikata komanoUgokikata for (int ms = 0; ms < masuYososu; ms++) { syuturyoku.AppendLine($"ます{ms}"); foreach (var optionalPhase in Conv_Taikyokusya.AllOptionalPhaseList) { // 盤上 Bitboard[] bbHairetu = new Bitboard[Conv_Komasyurui.Itiran.Length]; foreach (Komasyurui ks in Conv_Komasyurui.Itiran) { bbHairetu[(int)ks] = shogiban.GetKomanoUgokikata(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalPhase), (Masu)ms); } Util_Information.Setumei_Bitboards(Med_Koma.GetKomasyuruiNamaeItiran(optionalPhase), bbHairetu, syuturyoku); syuturyoku.AppendLine(); } } }
/// <summary> /// 将棋盤をコンソールへ出力するぜ☆(^▽^) /// 見出し有り /// </summary> /// <returns></returns> public static void Setumei_Bitboards(string[] headers, Bitboard[] bbHairetu, StringBuilder syuturyoku) { Debug.Assert(0 < bbHairetu.Length && null != bbHairetu[0], ""); // 見出し Setumei_Headers(headers, syuturyoku); // 盤上 Util_Information.AppendLine_Top_Kyokumen(bbHairetu.Length, syuturyoku); for (int dan = 0; dan < Option_Application.Optionlist.BanTateHaba; dan++) { AppendLine_Data(bbHairetu, dan * Option_Application.Optionlist.BanYokoHaba, syuturyoku); if (dan + 1 < Option_Application.Optionlist.BanTateHaba) { AppendLine_Middle(bbHairetu.Length, syuturyoku); } } AppendLine_Bottom(bbHairetu.Length, syuturyoku); }
/// <summary> /// 定跡局面の中で、評価値が一番高い指し手を返すぜ☆(^▽^) /// </summary> /// <param name="ky"></param> /// <returns>なければ投了☆</returns> public Move GetMove(bool isSfen, Kyokumen ky, out Hyokati out_bestHyokati, StringBuilder syuturyoku #if DEBUG , out string fen_forTest #endif ) { Move bestMove = Move.Toryo; out_bestHyokati = Hyokati.TumeTesu_GohosyuNasi; int bestFukasa = 0; #if DEBUG fen_forTest = ""; #endif //Util_Machine.Assert_KyokumenSeigosei_SabunKosin("ゲット指し手 #鯨",true); ulong hash = ky.KyokumenHash.Value; if (this.KyItems.ContainsKey(hash)) { JosekiKyokumen josekyKy = this.KyItems[hash]; // 整合性の確認用だぜ☆(^~^) #if DEBUG fen_forTest = josekyKy.Fen; #endif foreach (KeyValuePair <Move, JosekiMove> entry in josekyKy.SsItems) { if (out_bestHyokati < entry.Value.Hyokati)// 評価値が高い指し手を選ぶぜ☆(^▽^) { bestMove = entry.Key; out_bestHyokati = entry.Value.Hyokati; bestFukasa = entry.Value.Fukasa; } else if (out_bestHyokati == entry.Value.Hyokati && //評価値が同じ場合は、 bestFukasa < entry.Value.Fukasa //深く読んでいる指し手を選ぶぜ☆(^▽^) ) { bestMove = entry.Key; out_bestHyokati = entry.Value.Hyokati; bestFukasa = entry.Value.Fukasa; } } } #if DEBUG // 指し手の整合性をチェックしておきたいぜ☆(^▽^) { Kyokumen ky_forAssert = new Kyokumen(); int caret = 0; StringBuilder sindan1 = new StringBuilder(); ky.AppendFenTo(Option_Application.Optionlist.USI, sindan1); //if (!ky2.ParseFen(sindan1.ToString(), ref caret, false, syuturyoku)) if (!ky_forAssert.ParsePositionvalue(isSfen, sindan1.ToString(), ref caret, true, false, out string moves, syuturyoku))// ビットボードを更新したいので、適用する { syuturyoku.AppendLine("取得: パースに失敗だぜ☆(^~^)! #鰯"); var msg = syuturyoku.ToString(); syuturyoku.Clear(); Logger.Flush(msg); throw new Exception(msg); } if (!ky_forAssert.CanDoMove(bestMove, out MoveMatigaiRiyu riyu)) { StringBuilder sindan2 = new StringBuilder(); sindan2.Append("取得: 指せない指し手を定跡から取り出そうとしたぜ☆(^~^)!:"); // sindan2.Append("理由:"); ConvMove.SetumeiLine(riyu,sindan2); sindan2.Append("指し手:"); ConvMove.SetumeiLine(isSfen, bestMove, sindan2); sindan2.Append("定跡局面 ("); ky_forAssert.AppendFenTo(Option_Application.Optionlist.USI, sindan2); sindan2.AppendLine(")"); Util_Information.Setumei_Lines_Kyokumen(ky_forAssert, sindan2); //str2.AppendLine("以下、定跡メモリのダンプ"); //str2.AppendLine("┌──────────┐"); //str2.Append(this.ToString()); //str2.AppendLine("└──────────┘"); syuturyoku.AppendLine(sindan2.ToString()); var msg = syuturyoku.ToString(); syuturyoku.Clear(); Logger.Flush(msg); throw new Exception(sindan2.ToString()); } } #endif return(bestMove); }
public void Setumei(StringBuilder syuturyoku) { syuturyoku.AppendLine($"指し手生成を抜けた場所:{MoveGenBunseki.Instance.MoveGenWoNuketaBasho}"); Util_Information.Setumei_1Bitboard("移動先升", BB_IdosakiBase, syuturyoku); }
/// <summary> /// 一手詰めの局面かどうか調べるぜ☆(^▽^) /// /// 盤上の駒を動かすのか、駒台の駒を打つのかによって、利き の形が異なるぜ☆(^~^) /// /// 自分が一手詰めを掛けられるから、この指し手は作らないでおこう、といった使い方がされるぜ☆(^▽^) /// /// FIXME: 成りを考慮してない /// </summary> /// <param name="ky"></param> /// <param name="jibun"></param> /// <param name="ms_t0">移動元。持ち駒の場合、エラー値</param> /// <param name="ms_t1">移動先</param> /// <param name="jibunHioute"></param> /// <returns></returns> public static bool Ittedume_BanjoKoma(Kyokumen ky, Option <Phase> phase, Masu ms_t0, Masu ms_t1, HiouteJoho jibunHioute, HiouteJoho aiteHioute) { Debug.Assert(ky.Sindan.IsBanjo(ms_t1), "升エラー"); var optionalOpponent = Conv_Taikyokusya.Reverse(phase); // 動かす駒 if (!ky.Shogiban.ExistsBBKoma(phase, ms_t0, out Komasyurui ks_t0)) { StringBuilder reigai1 = new StringBuilder(); reigai1.AppendLine($"盤上の駒じゃないじゃないか☆(^▽^)www phase=[{ phase }] ms_src=[{ ms_t0 }] ks_jibun=[{ ks_t0 }]"); Util_Information.HyojiKomanoIbasho(ky.Shogiban, reigai1); var msg = reigai1.ToString(); Logger.Flush(msg); throw new Exception(msg); } Koma km_t0 = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks_t0, phase); Koma km_t1 = km_t0; // FIXME: 成りを考慮していないぜ☆(>_<) // A B C // ┌──┬──┬──┐ //1│ │▽ら│ │ // ├──┼──┼──┤ //2│▲き│ │▲き│ // ├──┼──┼──┤ //3│ │▲に│▲ら│ // ├──┼──┼──┤ //4│▲ぞ│▲ひ│▲ぞ│ // └──┴──┴──┘ // 動かしたばかりの駒を 取り返されるようでは、一手詰めは成功しないぜ☆(^~^)(ステイルメイト除く) if (1 < ky.Shogiban.CountKikisuZenbu(optionalOpponent, ms_t1)) { // 移動先升は、相手らいおん の利きも 1つ あるはず。 // 移動先升に 相手の利きが2つあれば、駒を取り返される☆ return(false); } if (!ky.Shogiban.GetBBKoma(aiteHioute.KmRaion).IsIntersect( // 相手のらいおん ky.Shogiban.GetKomanoUgokikata(km_t0, ms_t1) // 移動先での駒の利き )) // 相手らいおん が、移動先での駒の利きの中に居ないんだったら、一手詰め にはならないぜ☆(^~^) { // FIXME: ステイルメイトは考えてないぜ☆(>_<) return(false); } Bitboard bb_idogoKikiNew = new Bitboard();// 移動後の、利き { // 盤上の重ね利きの数を差分更新するぜ☆(^▽^) { ky.Shogiban.N100_HerasuKiki(km_t0, ky.Sindan.CloneKomanoUgoki(km_t0, ms_t0), ky.Sindan); // 移動元の駒の利きを消すぜ☆(^▽^) ky.Shogiban.N100_FuyasuKiki(km_t1, ky.Sindan.CloneKomanoUgoki(km_t1, ms_t1), ky.Sindan); // 移動先の駒の利きを増やすぜ☆(^▽^) } // 移動後の利きを作り直し bb_idogoKikiNew = ky.Shogiban.ToBitboard_KikisuZenbuPositiveNumber(phase, ky.Sindan); // 盤上の重ね利きの数の差分更新を元に戻すぜ☆(^▽^) { //ky.BB_KikiZenbu ky.Shogiban.N100_HerasuKiki(km_t1, ky.Sindan.CloneKomanoUgoki(km_t1, ms_t1), ky.Sindan); // 移動先の駒の利きを減らすぜ☆(^▽^) ky.Shogiban.N100_FuyasuKiki(km_t0, ky.Sindan.CloneKomanoUgoki(km_t0, ms_t0), ky.Sindan); // 移動元の駒の利きを増やすぜ☆(^▽^) } } return (aiteHioute.FriendRaion8KinboBB.Clone() // 相手らいおん が逃げれる、相手らいおんの周りの空白 .Sitdown(ky.Shogiban.GetBBKomaZenbu(optionalOpponent)) // 相手の駒がない升 .Sitdown(bb_idogoKikiNew) // こっちの利きがない升 .IsEmpty()); // がない場合、詰み☆ ; }
/// <summary> /// 詰将棋を用意するぜ☆ /// </summary> public static void TumeShogi(bool isSfen, int bango, Kyokumen ky, StringBuilder syuturyoku) { // FIXME: 終わったら元に戻したいが☆(^~^) Option_Application.Optionlist.PNChar[(int)Phase.Black] = MoveCharacter.TansakuNomi; Option_Application.Optionlist.PNChar[(int)Phase.White] = MoveCharacter.TansakuNomi; //Option_Application.Optionlist.BetaCutPer = 0; // ベータ・カットは使わないぜ☆(^▽^)wwww //Option_Application.Optionlist.TranspositionTableTukau = false; // トランスポジション・テーブルは使わないぜ☆(^▽^)wwww Option_Application.Optionlist.JosekiPer = 0; // 定跡は使わないぜ☆(^▽^) Option_Application.Optionlist.NikomaHyokaKeisu = 0; // 二駒関係の評価値も使わないぜ☆(^▽^) Option_Application.Optionlist.SikoJikan = 60000; // とりあえず 60 秒ぐらい☆ Option_Application.Optionlist.SikoJikanRandom = 0; Option_Application.Optionlist.JohoJikan = 0; // 情報全部出すぜ☆ // 詰め手数 + 1 にしないと、詰んでるか判断できないぜ☆(^▽^) //int motonoSaidaiFukasa = Option_Application.Optionlist.SaidaiFukasa; switch (bango) { #region 1手詰め case 0: { syuturyoku.AppendLine("# 1手詰め"); Option_Application.Optionlist.SaidaiFukasa = 1 + 1; ky.SetBanjo(isSfen, " ラ " + "き ひ" + " ら " + " ", false, syuturyoku); ky.MotiKomas.Clear().Set(MotiKoma.H, 1); // = new int[] { 0, 0, 1, 0, 0, 0 }; ky.Tekiyo(true, syuturyoku); Util_Information.Setumei_Lines_Kyokumen(ky, syuturyoku); syuturyoku.AppendLine(); } break; #endregion #region 1手詰め case 1: { syuturyoku.AppendLine("# 1手詰め"); Option_Application.Optionlist.SaidaiFukasa = 3 + 1; ky.SetBanjo(isSfen, " ラ" + "き " + " ら " + " ", false, syuturyoku); ky.MotiKomas.Clear(); // = new int[] { 0, 0, 0, 0, 0, 0 }; ky.Tekiyo(true, syuturyoku); Util_Information.Setumei_Lines_Kyokumen(ky, syuturyoku); syuturyoku.AppendLine(); } break; #endregion #region 3手詰め case 2: { syuturyoku.AppendLine("# 3手詰め"); Option_Application.Optionlist.SaidaiFukasa = 3 + 1; ky.SetBanjo(isSfen, " ゾラ" + " " + "ぞ " + "ら ", false, syuturyoku); ky.MotiKomas.Clear().Set(MotiKoma.Z, 1).Set(MotiKoma.H, 1); // = new int[] { 1, 0, 1, 0, 0, 0 }; ky.Tekiyo(true, syuturyoku); Util_Information.Setumei_Lines_Kyokumen(ky, syuturyoku); syuturyoku.AppendLine(); } break; #endregion #region 1手詰め case 3: { syuturyoku.AppendLine("# 1手詰め"); Option_Application.Optionlist.SaidaiFukasa = 1 + 1; ky.SetBanjo(isSfen, " ゾ " + " ぞラ" + "ぞ " + "ら ", false, syuturyoku); ky.MotiKomas.Clear().Set(MotiKoma.H, 1); // = new int[] { 0, 0, 1, 0, 0, 0 }; ky.Tekiyo(true, syuturyoku); Util_Information.Setumei_Lines_Kyokumen(ky, syuturyoku); syuturyoku.AppendLine(); } break; #endregion #region 1手詰め default: { syuturyoku.AppendLine("# 1手詰め"); Option_Application.Optionlist.SaidaiFukasa = 1 + 1; ky.SetBanjo(isSfen, " ラ " + "き き" + " にら" + "ぞひぞ", false, syuturyoku); ky.MotiKomas.Clear(); // = new int[] { 0, 0, 0, 0, 0, 0 }; ky.Tekiyo(true, syuturyoku); Util_Information.Setumei_Lines_Kyokumen(ky, syuturyoku); syuturyoku.AppendLine(); } break; #endregion } }
/// <summary> /// トライできる先。 /// </summary> /// <param name="ky">局面</param> /// <param name="kikiBB">手番らいおんの利きビットボード</param> /// <param name="tb">手番</param> /// <param name="ms1">手番らいおんがいる升</param> /// <returns></returns> public static Bitboard GetTrySaki(Kyokumen ky, Bitboard kikiBB, Option <Phase> optionalPhase, Masu ms1, StringBuilder syuturyoku) { var phaseIndex = OptionalPhase.IndexOf(optionalPhase); Util_Test.AppendLine("テスト: トライルール", syuturyoku); m_trySakiBB_.Clear(); // 自分はN段目にいる☆ int dan = Conv_Masu.ToDan_JibunSiten(optionalPhase, ms1, ky.Sindan); bool nidanme = 2 == dan; Util_Test.AppendLine("2段目にいるか☆?[{ nidanme }] わたしは[{ dan }]段目にいるぜ☆", syuturyoku); if (!nidanme) { Util_Test.AppendLine("むりだぜ☆", syuturyoku); Util_Test.Flush(syuturyoku); return(m_trySakiBB_); } // 1段目に移動できる升☆ m_trySakiBB_.Set(kikiBB); m_trySakiBB_.Select(ky.BB_Try[phaseIndex]); Util_Test.TestCode((StringBuilder syuturyoku2) => { Util_Information.Setumei_Bitboards(new string[] { "らいおんの利き", "1段目に移動できる升" }, new Bitboard[] { kikiBB, m_trySakiBB_ }, syuturyoku2); }); // 味方の駒がないところ☆ Bitboard spaceBB = new Bitboard(); spaceBB.Set(ky.BB_BoardArea); spaceBB.Sitdown(ky.Shogiban.GetBBKomaZenbu(optionalPhase)); m_trySakiBB_.Select(spaceBB); Util_Test.TestCode((StringBuilder str) => { Util_Information.Setumei_Bitboards(new string[] { "味方駒無い所", "トライ先" }, new Bitboard[] { spaceBB, m_trySakiBB_ }, str); }); if (m_trySakiBB_.IsEmpty()) { Util_Test.AppendLine("むりだぜ☆", syuturyoku); Util_Test.Flush(syuturyoku); return(m_trySakiBB_); } // 相手の利きが届いていないところ☆ var optionalOpponent2 = Conv_Taikyokusya.Reverse(optionalPhase); Bitboard safeBB = new Bitboard(); safeBB.Set(ky.BB_BoardArea); ky.Shogiban.ToSitdown_BBKikiZenbu(optionalOpponent2, safeBB); m_trySakiBB_.Select(safeBB); Util_Test.TestCode((StringBuilder syuturyoku2) => { Util_Information.Setumei_Bitboards(new string[] { "相手利き無い所", "トライ先" }, new Bitboard[] { safeBB, m_trySakiBB_ }, syuturyoku2); }); if (m_trySakiBB_.IsEmpty()) { Util_Test.AppendLine("むりだぜ☆", syuturyoku); Util_Test.Flush(syuturyoku); return(m_trySakiBB_); } Util_Test.AppendLine("トライできるぜ☆", syuturyoku); Util_Test.Flush(syuturyoku); return(m_trySakiBB_); }
//private static Option<T> Option<T>(T white) //{ // throw new NotImplementedException(); //} /// <summary> /// 将棋盤をコンソールへ出力するぜ☆(^▽^) /// コンソールでゲームするのに向いた表示☆ /// </summary> /// <returns></returns> public static void Setumei_NingenGameYo(Kyokumen ky, StringBuilder syuturyoku) { // 1行目 { // 千日手 int sennitite = ky.Konoteme.GetSennititeCount(); if (Const_Game.SENNITITE_COUNT == sennitite) { Conv_Taikyokusya.Setumei_Name(Conv_Taikyokusya.Reverse(ky.CurrentOptionalPhase), syuturyoku); syuturyoku.Append("の着手にて 千日手"); syuturyoku.AppendLine(); } else if (1 < sennitite) { syuturyoku.Append("同一局面反復 "); syuturyoku.Append(sennitite.ToString()); syuturyoku.AppendLine(" 回目"); } else { syuturyoku.AppendLine(); } } // 2行目 { // 何手目 syuturyoku.Append("図は"); syuturyoku.Append(string.Format("{0,3}", ky.Konoteme.ScanNantemadeBango())); syuturyoku.Append("手まで "); // 手番 Conv_Taikyokusya.Setumei_Name(ky.CurrentOptionalPhase, syuturyoku); syuturyoku.Append("の番"); // #仲ルール if (Option_Application.Optionlist.SagareruHiyoko) { syuturyoku.Append(" #仲"); } syuturyoku.AppendLine(); } // 3行目 後手の持ち駒の数 { foreach (MotiKomasyurui mks in Conv_MotiKomasyurui.Itiran) { MotiKoma mk = Med_Koma.MotiKomasyuruiAndPhaseToMotiKoma(mks, OptionalPhase.White); if (ky.MotiKomas.HasMotiKoma(mk)) { syuturyoku.Append(Conv_MotiKomasyurui.GetHyojiName(mks)); syuturyoku.Append(ky.MotiKomas.Get(mk).ToString()); } } syuturyoku.AppendLine(); } // 4行目 { syuturyoku.Append(" "); AppendLine_SujiFugo_Kyokumen(syuturyoku); //syuturyoku.AppendLine(" A B C "); } // 5行目~13行目 // 盤上 { // 5行目 syuturyoku.Append(" "); Util_Information.AppendLine_Top_Kyokumen(1, syuturyoku); // ┌──┬──┬──┐ for (int dan = 0; dan < Option_Application.Optionlist.BanTateHaba; dan++) { // 6,8,10,12行目 syuturyoku.Append(Conv_Kihon.ToZenkakuInteger(dan + 1)); AppendLine_Data_Kyokumen(ky, dan, syuturyoku); if (dan + 1 < Option_Application.Optionlist.BanTateHaba) { // 7,9,11行目 syuturyoku.Append(" "); AppendLine_Middle(1, syuturyoku);//├──┼──┼──┤ } } // 13行目 syuturyoku.Append(" "); AppendLine_Bottom(1, syuturyoku);//└──┴──┴──┘ } // 14行目 { // 先手の持ち駒の数 foreach (MotiKomasyurui mks in Conv_MotiKomasyurui.Itiran) { MotiKoma mk = Med_Koma.MotiKomasyuruiAndPhaseToMotiKoma(mks, OptionalPhase.Black); if (ky.MotiKomas.HasMotiKoma(mk)) { syuturyoku.Append(Conv_MotiKomasyurui.GetHyojiName(mks)); syuturyoku.Append(ky.MotiKomas.Get(mk).ToString()); } } syuturyoku.AppendLine(); } }