/// <summary> /// 駒の利き /// </summary> /// <param name="bbItiran_kikiZenbu"></param> /// <param name="bbItiran_kikiKomabetu"></param> /// <param name="syuturyoku"></param> public static void HyojiKomanoKiki(Shogiban shogiban, StringBuilder syuturyoku) { Debug.Assert(shogiban.IsActiveBBKiki(), ""); // 利き全部 { syuturyoku.AppendLine("利き(全部)"); Bitboard[] bbHairetu = new Bitboard[Conv_Taikyokusya.AllOptionalPhaseList.Length]; foreach (var optionalPhase65 in Conv_Taikyokusya.AllOptionalPhaseList) { bbHairetu[OptionalPhase.IndexOf(optionalPhase65)] = shogiban.GetBBKikiZenbu(optionalPhase65); } Setumei_Bitboards(Conv_Taikyokusya.NamaeItiran, bbHairetu, syuturyoku); } // 駒別 { syuturyoku.AppendLine("利き(駒別)"); foreach (var optionalPhase74 in Conv_Taikyokusya.AllOptionalPhaseList)// 対局者1、対局者2 { // 盤上 Bitboard[] bbHairetu = new Bitboard[Conv_Komasyurui.Itiran.Length]; foreach (Komasyurui ks in Conv_Komasyurui.Itiran) { bbHairetu[(int)ks] = shogiban.GetBBKiki(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalPhase74)); } Setumei_Bitboards(Med_Koma.GetKomasyuruiNamaeItiran(optionalPhase74), bbHairetu, syuturyoku); } } }
public static bool IsLegalMove(Koma km, Masu dstMs, Masu attackerMs, Shogiban shogiban) { // KomanoUgokikata komanoUgokikata return(shogiban.GetKomanoUgokikata(km, attackerMs).IsIntersect( // 相手の利き dstMs // 調べる升 )); }
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); } } }
public static void AppendLine_Data_Countboard(Option <Phase> optionalPhase, Shogiban sg, int ms_hidariHasi, StringBuilder syuturyoku) { for (int iKs = 0; iKs < Conv_Komasyurui.Itiran.Length; iKs++) { syuturyoku.Append("│"); for (int iMs_offset = 0; iMs_offset < Option_Application.Optionlist.BanYokoHaba; iMs_offset++) { int kikisuKomabetu = sg.CountKikisuKomabetu(Med_Koma.KomasyuruiAndTaikyokusyaToKoma((Komasyurui)iKs, optionalPhase), (Masu)(ms_hidariHasi + iMs_offset)); syuturyoku.Append(0 < kikisuKomabetu ? string.Format(" {0,2} ", kikisuKomabetu) : " "); syuturyoku.Append("│"); } } syuturyoku.AppendLine(); }
public static void AppendLine_Data_Countboard(Shogiban sg, int ms_hidariHasi, StringBuilder syuturyoku) { for (int iTai = 0; iTai < Conv_Taikyokusya.AllOptionalPhaseList.Length; iTai++) { syuturyoku.Append("│"); for (int iMs_offset = 0; iMs_offset < Option_Application.Optionlist.BanYokoHaba; iMs_offset++) { int kikisuZenbu = sg.CountKikisuZenbu(OptionalPhase.From(iTai), (Masu)(ms_hidariHasi + iMs_offset)); syuturyoku.Append(0 < kikisuZenbu ? string.Format(" {0,2} ", kikisuZenbu) : " "); syuturyoku.Append("│"); } } syuturyoku.AppendLine(); }
/// <summary> /// 手番と、 /// 駒の種類と、その升、 /// この3つを指定すると、利きを表にして返すぜ☆(^▽^) /// </summary> /// <param name="tai"></param> /// <param name="targetMs"></param> /// <param name="ks"></param> /// <param name="attackerMs"></param> /// <returns></returns> public static bool[] Kiki(Koma km, Masu attackerMs, Kyokumen.Sindanyo kys, Shogiban shogiban)//KomanoUgokikata komanoUgokikata { bool[] kiki = new bool[kys.MASU_YOSOSU]; // 盤上 for (int iDan = 0; iDan < Option_Application.Optionlist.BanTateHaba; iDan++) { for (int iSuji = 0; iSuji < Option_Application.Optionlist.BanYokoHaba; iSuji++) { kiki[iDan * Option_Application.Optionlist.BanYokoHaba + iSuji] = Util_HiouteCase.IsLegalMove(km, (Masu)(iDan * Option_Application.Optionlist.BanYokoHaba + iSuji), attackerMs, shogiban); } } return(kiki); }
/// <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 Bitboard Kiki_BB(Koma km, Masu attackerMs, Shogiban shogiban) { Bitboard kiki = new Bitboard(); // 盤上 for (int iDan = 0; iDan < Option_Application.Optionlist.BanTateHaba; iDan++) { for (int iSuji = 0; iSuji < Option_Application.Optionlist.BanYokoHaba; iSuji++) { if (Util_HiouteCase.IsLegalMove(km, (Masu)(iDan * Option_Application.Optionlist.BanYokoHaba + iSuji), attackerMs, shogiban)) { kiki.Standup((Masu)(iDan * Option_Application.Optionlist.BanYokoHaba + iSuji)); } } } return(kiki); }
/// <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> /// <param name="motiKomas1"></param> /// <returns></returns> public static bool Equals_ForDevelop(Shogiban shogiban_hikaku, int[] motiKomas1) { Debug.Assert(PureMemory.gky_ky.yomiKy.yomiMotigomaItiran.GetArrayLength() == motiKomas1.Length, "局面の一致判定"); // 盤上の一致判定 for (int iTai = 0; iTai < Conv_Taikyokusya.itiran.Length; iTai++) { Taikyokusya tai = (Taikyokusya)iTai; if (!PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.Equals_KomaZenbu_ForDevelop(tai, shogiban_hikaku.ibashoBan_yk00.yomiIbashoBan)) { return(false); } for (int iKs = 0; iKs < Conv_Komasyurui.itiran.Length; iKs++) { Komasyurui ks = Conv_Komasyurui.itiran[iKs]; Piece km = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai); if (!PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.Equals_Koma_ForDevelop(km, shogiban_hikaku.ibashoBan_yk00.yomiIbashoBan)) { return(false); } } } // 持ち駒の一致判定 for (int iMk = 0; iMk < Conv_Motigoma.itiran.Length; iMk++) { if (PureMemory.gky_ky.yomiKy.yomiMotigomaItiran.Count((Motigoma)iMk) != motiKomas1[iMk]) { return(false); } } return(true); }
/// <summary> /// 駒の居場所 /// </summary> /// <param name="syuturyoku"></param> public static void HyojiKomanoIbasho(Shogiban shogiban, StringBuilder syuturyoku) { //IbasyoKomabetuBitboardItiran bb_koma, // KomaZenbuIbasyoBitboardItiran bb_komaZenbu syuturyoku.AppendLine("駒の居場所"); // 駒全部☆ { Setumei_Bitboards(new string[] { "対局者1", "対局者2" }, new Bitboard[] { shogiban.GetBBKomaZenbu(OptionalPhase.Black), shogiban.GetBBKomaZenbu(OptionalPhase.White) }, syuturyoku); syuturyoku.AppendLine(); } foreach (var optionalPhase81 in Conv_Taikyokusya.AllOptionalPhaseList)// 対局者1、対局者2 { // 見出し foreach (Koma km in Conv_Koma.ItiranTai[OptionalPhase.IndexOf(optionalPhase81)]) { syuturyoku.Append(FormatBanWidthZenkaku(Conv_Koma.GetName(km))); } syuturyoku.AppendLine(); // 盤 Bitboard[] bbHairetu = new Bitboard[Conv_Komasyurui.Itiran.Length]; int i = 0; foreach (Komasyurui ks in Conv_Komasyurui.Itiran) { bbHairetu[i] = shogiban.GetBBKoma(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalPhase81)); i++; } Setumei_Bitboards(bbHairetu, syuturyoku); } }
/// <summary> /// ここからコンソール・アプリケーションが始まるぜ☆(^▽^) /// /// PCのコンソール画面のプログラムなんだぜ☆(^▽^) /// Unityでは中身は要らないぜ☆(^~^) /// </summary> /// <param name="args"></param> static void Main(string[] args) { try { var engineConf = new EngineConf(); EntitiesLayer.Implement(engineConf); var playing = new Playing(engineConf); /* #if DEBUG * // いろいろテスト☆ * System.Console.WriteLine("# デバッグ"); * System.Console.WriteLine($"# (1L<<31)=[{(1L << 31)}]"); * System.Console.WriteLine($"# (1L<<32)=[{(1L << 32)}]"); * System.Console.WriteLine($"# (1L<<33)=[{(1L << 33)}]"); * System.Console.WriteLine($"# (1L<<62)=[{(1L << 62)}]"); * System.Console.WriteLine($"# (1L<<63)=[{(1L << 63)}]"); * System.Console.WriteLine($"# (1L<<64)=[{(1L << 64)}]"); * System.Console.WriteLine($"# (1L<<65)=[{(1L << 65)}]"); * System.Console.WriteLine($"# (long.MinValue << 1)=[{(long.MinValue << 1)}]"); * System.Console.WriteLine($"# (~0UL)=[{(~0UL)}]"); * System.Console.WriteLine($"# (~0UL << 1)=[{(~0UL << 1)}]"); #endif */ //──────────────────────────────────────── // (手順1)アプリケーション開始前に設定しろだぜ☆(^▽^)! //──────────────────────────────────────── { // アプリケーション開始後は Face_Kifuwarabe.Execute("set 名前 値") を使って設定してくれだぜ☆(^▽^) // ↓コメントアウトしているところは、デフォルト値を使っている☆(^~^) //Option_Application.Optionlist.AspirationFukasa = 7; //Option_Application.Optionlist.AspirationWindow = Hyokati.Hyokati_SeiNoSu_Hiyoko; //Option_Application.Optionlist.BetaCutPer = 100; //Option_Application.Optionlist.HanpukuSinkaTansakuTukau = true; //Option_Application.Optionlist.JohoJikan = 3000; //────────── // 定跡 //────────── Option_Application.Optionlist.JosekiPer = 0; // 定跡を利用する確率。0~100。 Option_Application.Optionlist.JosekiRec = false; // 定跡は記録しない //Option_Application.Optionlist.JosekiRec = true;// 定跡を記録する☆ //Option_Application.Optionlist.Learn = false; //Option_Application.Optionlist.NikomaHyokaKeisu = 1.0d; //Option_Application.Optionlist.NikomaGakusyuKeisu = 0.001d;// HYOKA_SCALEが 1.0d のとき、GAKUSYU_SCALE 0.00001d なら、小数点部を広く使って じっくりしている☆(^~^) //Option_Application.Optionlist.P1Com = false; Option_Application.Optionlist.P2Com = true; //対局者2はコンピューター☆ //Option_Application.Optionlist.PNChar = new SasiteCharacter[] { SasiteCharacter.HyokatiYusen, SasiteCharacter.HyokatiYusen }; //Option_Application.Optionlist.PNName = new string[] { "対局者1", "対局者2" }; //Option_Application.Optionlist.RandomCharacter = false; //Option_Application.Optionlist.RandomNikoma = false; //Option_Application.Optionlist.RandomStart = false; //Option_Application.Optionlist.RenzokuTaikyoku = false; Option_Application.Optionlist.SagareruHiyoko = false; // さがれるひよこモード☆ アプリケーション開始後は Face_Kifuwarabe.Execute("set SagareruHiyoko true") コマンドを使って設定すること☆ #仲ルール Option_Application.Optionlist.SaidaiFukasa = 13; // コンピューターの読みの最大深さ //────────── // 成績 //────────── Option_Application.Optionlist.SeisekiRec = false; // 成績は記録しない //Option_Application.Optionlist.SeisekiRec = true;// 成績を記録する☆ //Option_Application.Optionlist.SennititeKaihi = false; //────────── // 思考時間 //────────── Option_Application.Optionlist.SikoJikan = 5000; // 500; // 最低でも用意されているコンピューターが思考する時間(ミリ秒) Option_Application.Optionlist.SikoJikanRandom = 5000; // 1501;// 追加で増えるランダム時間の最大(この値未満)。 期待値を考えて設定しろだぜ☆(^~^)例: ( 500 + 1500 ) / 2 = 1000 //Option_Application.Optionlist.TranspositionTableTukau = true; //Option_Application.Optionlist.UseTimeOver = true; } StringBuilder syuturyoku = Util_Machine.Syuturyoku; // (手順3)アプリケーション開始時設定 を終えた後に これを呼び出すこと☆(^~^)! Option_Application.TimeManager.Stopwatch_Savefile.Start();// 定跡ファイルの保存間隔の計測 Option_Application.TimeManager.Stopwatch_RenzokuRandomRule.Start(); // 平手初期局面を作るぜ☆(*^~^*) Option_Application.Kyokumen.DoHirate(Option_Application.Optionlist.USI, syuturyoku); Util_Machine.Assert_Sabun_Kiki("アプリケーション始30", Option_Application.Kyokumen.Sindan); /* * Util_Application.LoadJoseki(syuturyoku);// 定跡ファイルの読込み * Util_Application.LoadSeiseki(syuturyoku);// 成績ファイルの読込み * Util_Application.LoadNikoma(syuturyoku);// 二駒関係ファイルの読込み */ // ゲームモード設定☆ Util_Application.GameMode = GameMode.Karappo; // まず最初に「USI\n」が届くかどうかを判定☆(^~^) Util_ConsoleGame.ReadCommandline(syuturyoku); //string firstInput = Util_Machine.ReadLine(); if (Util_Commandline.Commandline == "usi") { Option_Application.Optionlist.USI = true; var engineName = engineConf.GetEngine("Name"); Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; var engineAuthor = engineConf.GetEngine("Author"); playing.UsiOk($"{engineName} {version.Major}.{version.Minor}.{version.Build}", engineAuthor, syuturyoku); } else { Util_ConsoleGame.WriteMessage_TitleGamen(syuturyoku);// とりあえず、タイトル画面表示☆(^~^) } // 空打ちで、ゲームモードに入るぜ☆(^▽^) var ky = Option_Application.Kyokumen; // このプログラムでは(A)コマンド・モード、(B)ゲーム・モード の2種類があるぜ☆ // 最初は コマンド・モードになっている☆(^~^) // // ゲームモード // (1)手番 // 人間、コンピューターの設定が有効になり、 // 人間の手番のときにしかコマンドが打てなくなるぜ☆ // (2)合法手 // 指し手の合法手チェックを行うぜ☆ // (3)自動着手 // コンピューターは自分の手番で 指すぜ☆ // (4)決着 // 決着すると ゲームモード を抜けるぜ☆ 連続対局設定の場合は抜けない☆(^▽^) // // コマンドモード // (1)手番 // MAN vs MAN扱い // (2)合法手 // チェックしない☆ ひよこをナナメに進めるのも、ワープするのも可能☆ // (3)自動着手 // しない☆ // (4)決着 // しない☆ [Enter]キーを空打ちすると、ゲームモードに変わるぜ☆(^▽^) for (; ;) //メインループ(無限ループ) { //──────────────────────────────────────── // (手順2)ユーザー入力 //──────────────────────────────────────── Util_Commandline.InitCommandline(); // コマンド・ライン初期化☆ Util_Commandline.ReadCommandBuffer(syuturyoku); // コマンド・バッファー読取り☆ if (Util_Commandline.Commandline != null) { // コマンド・バッファーにコマンドラインが残っていたようなら、そのまま使うぜ☆(^▽^) } else if ( GameMode.Game == Util_Application.GameMode // ゲームモードの場合☆ && Util_Application.IsComputerNoBan(ky) // コンピューターの番の場合☆ ) { Util_Commandline.ClearCommandline(); // コマンドラインは消しておくぜ☆(^▽^) } else { Util_ConsoleGame.ReadCommandline(syuturyoku);// コンソールからのキー入力を受け取るぜ☆(^▽^)(コンソール・ゲーム用) } if (GameMode.Game == Util_Application.GameMode) { // 指す前の局面☆(定跡 登録用) Util_ConsoleGame.Init_JosekiToroku(ky); //──────────────────────────────────────── // (手順3)人間の手番 //──────────────────────────────────────── if (Util_Application.IsNingenNoBan(ky)) // 人間の手番 { // ゲームモードでの人間の手番では、さらにコマンド解析 // ここで do コマンド(do b3b2 等)を先行して解析するぜ☆(^▽^) if (Util_Commandline.Caret != Util_Commandline.Commandline.IndexOf("do ", Util_Commandline.Caret)) { // do以外のコマンドであれば、コマンドラインを保持したまま、そのまま続行 } // 以下、do コマンドの場合☆ else if (!Util_Application.ParseDoMove(ky, out Move inputSasite)) { // do コマンドのパースエラー表示(コンソール・ゲーム用)☆(^~^) syuturyoku.AppendLine(ConvMove.Setumei(MoveMatigaiRiyu.ParameterSyosikiMatigai)); var msg = syuturyoku.ToString(); syuturyoku.Clear(); Logger.Flush(msg); Util_Commandline.CommentCommandline(); // コマンドの誤発動防止 } else if (!ky.CanDoMove(inputSasite, out MoveMatigaiRiyu reason)) // 指し手の合否チェック { // イリーガル・ムーブなどの、エラー理由表示☆(^~^) syuturyoku.AppendLine(ConvMove.Setumei(reason)); var msg = syuturyoku.ToString(); syuturyoku.Clear(); Logger.Flush(msg); } else { // do コマンドを実行するぜ☆(^▽^) // 1手指す☆!(^▽^) Nanteme konoTeme = new Nanteme();// 使いまわさないだろう☆(^~^)ここで作ってしまおう☆ ky.DoMove(Option_Application.Optionlist.USI, inputSasite, MoveType.N00_Karappo, ref konoTeme, ky.CurrentOptionalPhase, syuturyoku); Util_Application.JudgeKettyaku(inputSasite, ky);// 勝敗判定☆(^▽^) // 局面出力 Util_Information.Setumei_NingenGameYo(ky, syuturyoku); Util_ConsoleGame.Update1_JosekiToroku(inputSasite, ky, syuturyoku);// やるなら、定跡更新☆(^▽^) } }// 人間おわり☆(^▽^) //──────────────────────────────────────── // (手順4)コンピューターの手番 //──────────────────────────────────────── else if (Util_Application.IsComputerNoBan(ky)) //コンピューターの番☆ { Util_ConsoleGame.AppendMessage_ComputerSikochu(ky, syuturyoku); // 表示(コンピューター思考中☆) Move bestSasite = Util_Application.Go(playing, ky, out HyokatiUtiwake best_hyokatiUTiwake, Face_YomisujiJoho.Dlgt_WriteYomisujiJoho, syuturyoku); // コンピューターに1手指させるぜ☆ Util_Application.JudgeKettyaku(bestSasite, ky); // 勝敗判定☆(^▽^) Util_ConsoleGame.Update2_JosekiToroku(bestSasite, best_hyokatiUTiwake.EdaBest, ky, syuturyoku); // やるなら、定跡更新☆(^▽^) Util_ConsoleGame.ShowMessage_KettyakuJi(ky, syuturyoku); // 決着していた場合はメッセージ表示☆(^~^) }// コンピューターの手番おわり☆(^~^) //──────────────────────────────────────── // (手順5)決着時 //──────────────────────────────────────── if (Util_Application.IsKettyaku(ky)) // 決着が付いているなら☆ { Util_Application.DoTejun5_SyuryoTaikyoku1(playing, ky, syuturyoku); // 対局終了時 } } //──────────────────────────────────────── // (手順6)ゲーム用の指し手以外のコマンドライン実行 //──────────────────────────────────────── string commandline = Util_Commandline.Commandline; int caret = Util_Commandline.Caret; Util_Commandline.IsQuit = false; Util_Commandline.IsKyokumenEcho = true; // ゲーム・モードの場合、特に指示がなければ コマンド終了後、局面表示を返すぜ☆ if (null == commandline) { // 未設定 } else if (commandline == "") { // 空打ちは無視するか、からっぽモードでは、ゲームモードに切り替えるぜ☆(^▽^) if (GameMode.Karappo == Util_Application.GameMode)// 感想戦での発動防止☆ { // ゲームモード(対局開始) Util_Application.GameMode = GameMode.Game; } } // なるべく、アルファベット順☆(^▽^)同じつづりで始まる単語の場合、語句の長い単語を優先にしないと if 文が通らないぜ☆www else if (caret == commandline.IndexOf("@", caret)) { playing.Atmark(commandline); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("#", caret)) { // 受け付けるが、何もしないぜ☆(^▽^)www Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("bitboard", caret)) { // テスト用だぜ☆(^~^) if (commandline == "bitboard") { // ビットボード表示☆ // 筋 { for (int iSuji = 0; iSuji < Option_Application.Optionlist.BanYokoHaba; iSuji++) { Util_Information.Setumei_1Bitboard($"筋{iSuji}", ky.BB_SujiArray[iSuji], syuturyoku); } syuturyoku.AppendLine(); } // 段 { for (int iDan = 0; iDan < Option_Application.Optionlist.BanTateHaba; iDan++) { Util_Information.Setumei_1Bitboard($"段{iDan}", ky.BB_DanArray[iDan], syuturyoku); } syuturyoku.AppendLine(); } // トライ { Util_Information.Setumei_Bitboards(new string[] { "対局者1", "対局者2(トライ)" }, new Bitboard[] { ky.BB_Try[(int)Phase.Black], ky.BB_Try[(int)Phase.White] }, syuturyoku); syuturyoku.AppendLine(); } Util_Information.HyojiKomanoIbasho(ky.Shogiban, syuturyoku); // 駒の居場所☆ Util_Information.HyojiKomanoKikiSu(ky.Shogiban, syuturyoku); // 駒の重ね利き数☆ Util_Information.HyojiKomanoKiki(ky.Shogiban, syuturyoku); // 駒の利き☆ Util_Information.HyojiKomanoUgoki(ky.Shogiban, ky.Sindan.MASU_YOSOSU, syuturyoku); // 駒の動き☆ return; } // うしろに続く文字は☆(^▽^) int caret2 = 0; Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret2, "bitboard "); if (caret2 == commandline.IndexOf("kiki", caret2)) { // 重ね利きビットボード表示☆ // 駒別 { // 再計算 Shogiban saikeisan = new Shogiban(ky.Sindan); saikeisan.Tukurinaosi_1_Clear_KikiKomabetu(); saikeisan.Tukurinaosi_2_Input_KikiKomabetu(ky.Sindan); saikeisan.TukurinaosiBBKikiZenbu(); syuturyoku.AppendLine("利き:(再計算)全部、駒別"); Util_Information.HyojiKomanoKiki(saikeisan, syuturyoku); // 現行 syuturyoku.AppendLine("利き:(現行)全部、駒別"); Util_Information.HyojiKomanoKiki(ky.Shogiban, syuturyoku); } // 全部 { // 再計算 Shogiban saikeisan = new Shogiban(ky.Sindan); saikeisan.TukurinaosiKikisuZenbu(ky.Shogiban, ky.Sindan); saikeisan.TukurinaosiKikisuKomabetu(ky.Shogiban, ky.Sindan); syuturyoku.AppendLine("利き数:(再計算)全部、駒別"); Util_Information.HyojiKomanoKikiSu(saikeisan, syuturyoku); // 現行 syuturyoku.AppendLine("利き数:全部(現行)全部、駒別"); Util_Information.HyojiKomanoKikiSu(ky.Shogiban, syuturyoku); } return; } else if (caret2 == commandline.IndexOf("remake", caret2)) { // 駒の動き方を作り直し ky.Shogiban.Tukurinaosi_1_Clear_KomanoUgokikata(ky.Sindan.MASU_YOSOSU); ky.Shogiban.Tukurinaosi_2_Input_KomanoUgokikata(ky.Sindan); } Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("cando", caret)) { // GameMode.Game == Util_Application.GameMode ? CommandMode.NingenYoConsoleGame : CommandMode.NigenYoConsoleKaihatu, // うしろに続く文字は☆(^▽^) int caret2 = 0; Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret2, "cando "); if (!Med_Parser.TryFenMove(Option_Application.Optionlist.USI, commandline, ref caret2, ky.Sindan, out Move ss)) { throw new Exception($"パースエラー [{commandline}]"); } if (ky.CanDoMove(ss, out MoveMatigaiRiyu riyu)) { syuturyoku.AppendLine("cando, true"); } else { syuturyoku.Append("cando, false, "); syuturyoku.AppendLine(riyu.ToString()); } } else if (caret == commandline.IndexOf("clear", caret)) { Util_Machine.Clear(); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("do", caret)) { playing.Do( Option_Application.Optionlist.USI, commandline, ky, GameMode.Game == Util_Application.GameMode ? CommandMode.NingenYoConsoleGame : CommandMode.NigenYoConsoleKaihatu, syuturyoku); } else if (caret == commandline.IndexOf("gameover", caret)) { playing.Gameover(commandline, ky, syuturyoku); } else if (caret == commandline.IndexOf("go", caret)) { var isSfen = Option_Application.Optionlist.USI; var mode = CommandMode.NigenYoConsoleKaihatu; playing.Go(isSfen, mode, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("hash", caret)) { playing.Hash(ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("hirate", caret)) { playing.Hirate(Option_Application.Optionlist.USI, ky, syuturyoku); } else if (caret == commandline.IndexOf("honyaku", caret)) { playing.Honyaku(commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("hyoka", caret)) { playing.Hyoka(commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("isready", caret)) { playing.ReadyOk(syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("jam", caret)) { playing.Jam(Option_Application.Optionlist.USI, ky, syuturyoku); } else if (caret == commandline.IndexOf("jokyo", caret)) { playing.Jokyo(commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("joseki", caret)) { playing.Joseki(Option_Application.Optionlist.USI, commandline, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("kansosen", caret)) { // 駒の場所を表示するぜ☆(^▽^) playing.Kansosen(Option_Application.Optionlist.USI, commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("kifu", caret)) { // 駒の場所を表示するぜ☆(^▽^) playing.Kifu(Option_Application.Optionlist.USI, commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("kikikazu", caret)) { // 利きの数を調べるぜ☆(^▽^) playing.KikiKazu(commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("kiki", caret)) { // 利きを調べるぜ☆(^▽^) playing.Kiki(Option_Application.Optionlist.USI, commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("koma", caret)) { // 駒の場所を表示するぜ☆(^▽^) playing.Koma_cmd(Option_Application.Optionlist.USI, commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("ky", caret)) { // 局面を表示するぜ☆(^▽^) Util_Machine.Assert_Sabun_Kiki("飛び利き増やす1", ky.Sindan); playing.Ky(Option_Application.Optionlist.USI, commandline, ky, syuturyoku); Util_Machine.Assert_Sabun_Kiki("飛び利き増やす2", ky.Sindan); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("manual", caret)) { // "man" と同じ☆(^▽^) playing.Man(syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("man", caret)) { // "manual" と同じ☆(^▽^) playing.Man(syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("masu", caret)) { playing.Masu_cmd(commandline, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("nikoma", caret)) { playing.Nikoma(Option_Application.Optionlist.USI, commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("position", caret)) { playing.Position(); // うしろに続く文字は☆(^▽^) int caret2 = 0; Util_String.YomuTangoTobasuMatubiKuhaku(commandline, ref caret2, out string token); if ("position" == token) { // パース☆!(^▽^) if (!ky.ParsePositionvalue(Option_Application.Optionlist.USI, commandline, ref caret2, true, false, out string moves, syuturyoku)) { string msg = "パースに失敗だぜ☆(^~^)! #黒牛"; syuturyoku.AppendLine(msg); var msg2 = syuturyoku.ToString(); syuturyoku.Clear(); Logger.Flush(msg2); throw new Exception(msg); } // 棋譜を作成するぜ☆(^▽^) Kifu kifu = new Kifu(); // 初期局面 { StringBuilder mojiretu = new StringBuilder(); ky.AppendFenTo(Option_Application.Optionlist.USI, mojiretu); kifu.SyokiKyokumenFen = mojiretu.ToString(); } // うしろに続く文字は☆(^▽^) Util_String.YomuTangoTobasuMatubiKuhaku(commandline, ref caret2, out token); if ("" != moves) { // moves が続いていたら☆(^~^) // 頭の moves を取り除くぜ☆(*^~^*) moves = moves.Substring("moves ".Length); kifu.AddMoves(Option_Application.Optionlist.USI, moves, ky.Sindan); // positionで渡された最終局面まで進めようぜ☆(^▽^)www kifu.GoToFinish(Option_Application.Optionlist.USI, ky, syuturyoku); } // 初回は「position startpos」しか送られてこない☆(^~^) } Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("quit", caret)) { playing.Quit(); Util_Commandline.IsQuit = true; } else if (caret == commandline.IndexOf("result", caret)) { playing.Result(ky, syuturyoku, CommandMode.NigenYoConsoleKaihatu); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("rnd", caret)) { playing.Rnd(ky, syuturyoku); } else if (caret == commandline.IndexOf("move", caret)) { playing.MoveCmd(Option_Application.Optionlist.USI, commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("see", caret)) { playing.See(Option_Application.Optionlist.USI, commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("seiseki", caret)) { playing.Seiseki(Option_Application.Optionlist.USI, commandline, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("setoption", caret)) { // // とりあえず無視☆(*^~^*) // 「setoption name 名前 value 値」といった書式なので、 // 「set 名前 値」に変えたい。 // うしろに続く文字は☆(^▽^) int caret2 = 0; Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret2, "setoption "); Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret2, "name "); int end = commandline.IndexOf("value ", caret2); if (-1 != end) { StringBuilder sb = new StringBuilder(); sb.Append("set "); sb.Append(commandline.Substring(caret2, end - caret2)); //名前 caret2 = end + "value ".Length; sb.Append(commandline.Substring(caret2)); //値 playing.Set(sb.ToString(), ky, syuturyoku); } Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("set", caret)) { playing.Set(commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("taikyokusya", caret)) { playing.Taikyokusya_cmd(commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("test", caret)) { playing.Test(Option_Application.Optionlist.USI, commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("tantaitest", caret)) { playing.TantaiTest(playing, Option_Application.Optionlist.USI, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("tumeshogi", caret)) { // "tu" と同じ☆(^▽^) playing.TumeShogi(Option_Application.Optionlist.USI, commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("tu", caret)) { // "tumeshogi" と同じ☆(^▽^) playing.TumeShogi(Option_Application.Optionlist.USI, commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("undo", caret)) { playing.Undo(commandline, ky, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("usinewgame", caret)) { playing.UsiNewGame(); Util_Commandline.IsKyokumenEcho = false; } else if (caret == commandline.IndexOf("usi", caret)) { //ここは普通、来ない☆(^~^) var engineName = engineConf.GetEngine("Name"); Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; var engineAuthor = engineConf.GetEngine("Author"); playing.UsiOk($"{engineName} {version.Major}.{version.Minor}.{version.Build}", engineAuthor, syuturyoku); Util_Commandline.IsKyokumenEcho = false; } else { // 表示(コンソール・ゲーム用) syuturyoku.Append("「"); syuturyoku.Append(commandline); syuturyoku.AppendLine("」☆?(^▽^)"); syuturyoku.AppendLine("そんなコマンドは無いぜ☆(>_<) man で調べろだぜ☆(^▽^)"); var msg = syuturyoku.ToString(); syuturyoku.Clear(); Logger.Flush(msg); } if (Util_Commandline.IsQuit) { break;//goto gt_EndLoop1; } // 次の入力を促す表示をしてるだけだぜ☆(^~^) Util_Commandline.ShowPrompt(playing, Option_Application.Optionlist.USI, ky, syuturyoku); }//無限ループ //gt_EndLoop1: //; // 開発モードでは、ユーザー入力を待機するぜ☆(^▽^) // (手順5)アプリケーション終了時に呼び出せだぜ☆(^▽^)! Face_Kifuwarabe.OnApplicationFinished(syuturyoku); } catch (Exception ex) { // エラーが起こりました。 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> // どうにもできないので ログだけ取って無視します。 Logger.Fatal($"(^ー^)「大外枠でキャッチ」:{ex}"); Console.Out.WriteLine("bestmove resign"); //throw;//追加 } }