public static void Setumei(FenSyurui f, StringBuilder hyoji) { bool isBelow = false; MoveGenAccessor.ScanBestYomisuji((int iKifu, ref bool toBreak) => { if (isBelow) { // 2週目以降は空白を挟むぜ☆(^~^) hyoji.Append(" "); } else { isBelow = true; } SpkMove.AppendFenTo(f, PureMemory.kifu_moveArray[iKifu], hyoji); }); }
// 成れる駒(Nareru Koma) 逼迫返討手 public static void GenerateNk_HippakuKaeriutiTe() { if (PureMemory.hot_isNigerarenaiCheckerAr[PureMemory.kifu_nTeban]) { // 逃げられない状況で、王手が掛かけられていれば☆(^~^) // 成れる場合 while (PureMemory.ssss_bbVar_idosaki_nari.Ref_PopNTZ(out PureMemory.ssss_ugoki_ms_dst)) { PureMemory.SetSsssGenk( Tume1Hantei.CheckBegin_Tume1_BanjoKoma(),// 一手詰めルーチン☆ false, false ); // チェッカーを取るような全ての手は、選択肢に入れるぜ☆(^~^) MoveGenAccessor.AddMoveNariGood(); if (Tume1Hantei.CheckEnd_Tume1()) { break; } //終了☆ } while (PureMemory.ssss_bbVar_idosaki_narazu.Ref_PopNTZ(out PureMemory.ssss_ugoki_ms_dst)) { PureMemory.SetSsssGenk( Tume1Hantei.CheckBegin_Tume1_BanjoKoma(),// 一手詰めルーチン☆ false, false ); // チェッカーを取るような全ての手は、選択肢に入れるぜ☆(^~^) MoveGenAccessor.AddMoveNarazuGood(); if (Tume1Hantei.CheckEnd_Tume1()) { break; } //終了☆ } } }
/// <summary> /// 1手指すぜ☆(^▽^) /// </summary> public static void DoMove(Move ss) { MoveType ssType = MoveType.N00_Karappo; if (DoMoveOpe.TryFailDoMoveAll(ss, ssType #if DEBUG , PureSettei.fenSyurui , PureAppli.syuturyoku1 , false , "Shogi34#DoMove" #endif )) { throw new Exception(PureAppli.syuturyoku1.ToString()); } MoveGenAccessor.AddKifu(ss, ssType, PureMemory.dmv_ks_c); //#if DEBUG // Util_Tansaku.Snapshot("Shogi34", dbg_reigai); //#endif }
// らいおん、成れない駒(X Koma) 駒を取る手 public static void GenerateXk_KomaWoToruTe() { while (PureMemory.ssss_bbVar_idosaki_narazu.Ref_PopNTZ(out PureMemory.ssss_ugoki_ms_dst)) { // 駒を取るような全ての手は、選択肢に入れるぜ☆(^~^) PureMemory.SetSsssGenk( Tume1Hantei.CheckBegin_Tume1_BanjoKoma(),// 一手詰めルーチン☆ false, NigemitiWatasuKansyu.IsNigemitiWoAkeru() ); MoveGenAccessor.AddMoveNarazuGoodXorBad(); if (Tume1Hantei.CheckEnd_Tume1()) { break; } //終了☆ } }
// 成れない駒(X Koma) 捨て緩慢指し(タダ捨て指し) public static void GenerateXk_SuteKanmanZasi() { Debug.Assert(Conv_Koma.IsOk(PureMemory.ssss_ugoki_km), ""); // 王手も除外するぜ☆(^▽^) GenerateMove03.KesuOte(); while (PureMemory.ssss_bbVar_idosaki_narazu.Ref_PopNTZ(out PureMemory.ssss_ugoki_ms_dst)) // 立っているビットを降ろすぜ☆ { if (GenerateMove03.TadasuteNoUgoki()) // 相手の利きがあって、自分を除いた味方の利きがない升 に限るぜ☆(^▽^)www { PureMemory.SetSsssGenk( false, // タダ捨てに、一手詰めは無いだろう☆(*^~^*) GenerateMove03.IsMisuteruUgoki(), false //逃げ道を開けて逃がすかどうかは判定しないぜ☆(^~^) ); MoveGenAccessor.AddMoveNarazuGoodXorBad(); } } }
// 成れる駒(Nareru Koma) らいおんキャッチ調査 | らいおんキャッチ public static void GenerateNk_RaionCatch() { // 成れる場合 if (PureMemory.ssss_bbVar_idosaki_nari.GetNTZ(out PureMemory.ssss_ugoki_ms_dst)) { // らいおんをキャッチする手は、1つ見つければOKだぜ☆(^~^) if (MoveType.N17_RaionCatchChosa == PureMemory.ssss_ugoki_kakuteiSsType) { // 調査するだけ☆ らいおんキャッチできることが分かったので終了☆(^~^) PureMemory.hot_raionCatchChosaAr[PureMemory.kifu_nTeban] = true; return; } MoveGenAccessor.AddMoveNariGood(); PureMemory.SetTansakuUtikiri(TansakuUtikiri.RaionTukamaeta); } if (PureMemory.ssss_bbVar_idosaki_narazu.GetNTZ(out PureMemory.ssss_ugoki_ms_dst)) { // らいおんをキャッチする手は、1つ見つければOKだぜ☆(^~^) if (MoveType.N17_RaionCatchChosa == PureMemory.ssss_ugoki_kakuteiSsType) { // 調査するだけ☆ らいおんキャッチできることが分かったので終了☆(^~^) PureMemory.hot_raionCatchChosaAr[PureMemory.kifu_nTeban] = true; return; } PureMemory.SetSsssGenk( false, false, NigemitiWatasuKansyu.IsNigemitiWoAkeru() ); MoveGenAccessor.AddMoveNarazuGoodXorBad(); PureMemory.SetTansakuUtikiri(TansakuUtikiri.RaionTukamaeta); } }
// 仲間を見捨てる動きは Badへ☆(^~^) // らいおん ぼっち緩慢指 | 紐付き緩慢指 (らいおんは 捨て緩慢指し をやらないぜ☆) public static void GenerateRaion_BottiKanmanZasi_HimodukiKanmanZasi() { // トライ は除外するぜ☆(^▽^) GenerateMove03.KesuTry(); // らいおん が自分から 相手の利きに飛び込むのを防ぐぜ☆(^▽^)www GenerateMove03.KesuRaionJisatusyu(); while (PureMemory.ssss_bbVar_idosaki_narazu.Ref_PopNTZ(out PureMemory.ssss_ugoki_ms_dst))// 立っているビットを降ろすぜ☆ { PureMemory.SetSsssGenk( Tume1Hantei.CheckBegin_Tume1_BanjoKoma(), // 一手詰めルーチン☆ GenerateMove03.IsMisuteruUgoki(), false //逃げ道を開けて逃がすかどうかは判定しないぜ☆(^~^) ); MoveGenAccessor.AddMoveNarazuGoodXorBad(); if (Tume1Hantei.CheckEnd_Tume1()) { break; } //終了☆ } }
/// <summary> /// 指定した指し手をやりなおす動きをするぜ☆(^▽^) /// </summary> /// <param name="ss"></param> public static bool TryFailUndoMove( #if DEBUG FenSyurui dbg_f , IDebugMojiretu dbg_reigai #endif ) { //──────────────────────────────────────── // 手番 //──────────────────────────────────────── // 事前に戻すぜ☆(^▽^) PureMemory.RemoveTeme(); //──────────────────────────────────────── // まず最初に整合性を確認だぜ☆(^~^) //──────────────────────────────────────── //──────────────────────────────────────── // グローバル変数に、結果を入れておくぜ☆(^~^) //──────────────────────────────────────── MoveGenAccessor.BunkaiMoveUmv(); if (Move.Toryo == PureMemory.umv_ss) { goto gt_EndMethod; } // なにも更新せず終了☆(^▽^) if (TryFail_Tejun1_IdosakiNoTebanNoKomaWoTorinozoku( #if DEBUG dbg_f , dbg_reigai #endif )) { return(Pure.FailTrue("TryFail_Tejun1_IdosakiNoTebanNoKomaWoTorinozoku")); } if (AbstractConvMove.IsUtta(PureMemory.umv_ss)) { // 打つ if (TryFail_Tejun2Utu_IdomotoniTebannoKomawoModosu( #if DEBUG dbg_f , dbg_reigai #endif )) { return(Pure.FailTrue("TryFail_Tejun2_IdomotoniTebannoKomawoModosu")); } } else { // 指す if (TryFail_Tejun2Sasu_IdomotoniTebannoKomawoModosu( #if DEBUG dbg_f , dbg_reigai #endif )) { return(Pure.FailTrue("TryFail_Tejun2_IdomotoniTebannoKomawoModosu")); } } if (TryFail_Tejun3_KomadaiKaraTottakomawoJogai( #if DEBUG dbg_f , dbg_reigai #endif )) { return(Pure.FailTrue("TryFail_Tejun3_KomadaiKaraTottakomawoJogai")); } if (TryFail_Tejun4_IdosakiniTottakomawoModosu( #if DEBUG dbg_f , dbg_reigai #endif )) { return(Pure.FailTrue("TryFail_Tejun4_IdosakiniTottakomawoModosu")); } //──────────────────────────────────────── // 最後に一括更新 //──────────────────────────────────────── gt_EndMethod: //──────────────────────────────────────── // 最後に整合性を確認だぜ☆(^~^) //──────────────────────────────────────── return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// ここからコンソール・アプリケーションが始まるぜ☆(^▽^) /// /// PCのコンソール画面のプログラムなんだぜ☆(^▽^) /// Unityでは中身は要らないぜ☆(^~^) /// </summary> /// <param name="args"></param> static void Main(string[] args) { var playing = new Playing(); var programSupport = new ProgramSupport(); // (手順2)きふわらべの応答は、文字列になって ここに入るぜ☆(^▽^) // syuturyoku.ToContents() メソッドで中身を取り出せるぜ☆(^~^) StringBuilder hyoji = PureAppli.syuturyoku1; Interproject.project = new WinconsoleProject(); if (PureAppli.TryFail_Init()) { Logger.Flush(hyoji); throw new Exception(hyoji.ToString()); } // コンソールゲーム用の設定上書き ConsolegameSettei.Init_PureAppliOverride(); // まず最初に「USI\n」が届くかどうかを判定☆(^~^) Util_ConsoleGame.ReadCommandline(programSupport, hyoji); if (programSupport.commandline == "usi") { // 「将棋所」で本将棋を指す想定☆(^~^) // CommandA.Atmark("@USI9x9", hyoji); PureSettei.usi = true; PureSettei.fenSyurui = FenSyurui.sfe_n; PureSettei.p1Com = false; PureSettei.p2Com = false; PureSettei.tobikikiTukau = true; // FIXME: 飛び利きはまだ不具合修正されていないぜ☆(^~^) ComSettei.himodukiHyokaTukau = true; // FIXME: 紐付き評価は、使うとしておこう☆(^~^) // ルールを確定してから 局面を作れだぜ☆(^~^) LisGenkyoku.SetRule( GameRule.HonShogi, 9, 9, @"シウネイライネウシ キ ゾ ヒヒヒヒヒヒヒヒヒ ひひひひひひひひひ ぞ き しうねいらいねうし" , new Dictionary <Motigoma, int>() { { Motigoma.K, 0 }, { Motigoma.Z, 0 }, { Motigoma.H, 0 }, { Motigoma.k, 0 }, { Motigoma.z, 0 }, { Motigoma.h, 0 }, } ); var profilePath = System.Configuration.ConfigurationManager.AppSettings["Profile"]; var toml = Toml.ReadFile(Path.Combine(profilePath, "Engine.toml")); var engineName = toml.Get <TomlTable>("Engine").Get <string>("Name"); Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; var engineAuthor = toml.Get <TomlTable>("Engine").Get <string>("Author"); playing.UsiOk(programSupport.commandline, $"{engineName} {version.Major}.{version.Minor}.{version.Build}", engineAuthor, hyoji); } else { SpkNaration.Speak_TitleGamen(hyoji);// とりあえず、タイトル画面表示☆(^~^) Logger.Flush(hyoji); } //Face_Kifuwarabe.Execute("", Option_Application.Kyokumen, syuturyoku); // 空打ちで、ゲームモードに入るぜ☆(^▽^) // 空打ちで、ゲームモードに入るぜ☆(^▽^) // このプログラムでは(A)コマンド・モード、(B)ゲーム・モード の2種類があるぜ☆ // 最初は コマンド・モードになっている☆(^~^) // // ゲームモード // (1)手番 // 人間、コンピューターの設定が有効になり、 // 人間の手番のときにしかコマンドが打てなくなるぜ☆ // (2)合法手 // 指し手の合法手チェックを行うぜ☆ // (3)自動着手 // コンピューターは自分の手番で 指すぜ☆ // (4)決着 // 決着すると ゲームモード を抜けるぜ☆ 連続対局設定の場合は抜けない☆(^▽^) // // コマンドモード // (1)手番 // MAN vs MAN扱い // (2)合法手 // チェックしない☆ ひよこをナナメに進めるのも、ワープするのも可能☆ // (3)自動着手 // しない☆ // (4)決着 // しない☆ [Enter]キーを空打ちすると、ゲームモードに変わるぜ☆(^▽^) bool result1 = Pure.SUCCESSFUL_FALSE; for (; ;) //メインループ(無限ループ) { #region (手順2)ユーザー入力 //──────────────────────────────────────── // (手順2)ユーザー入力 //──────────────────────────────────────── Util_ConsoleGame.Begin_Mainloop(playing, programSupport, hyoji); if (programSupport.commandline != null) { // コマンド・バッファーにコマンドラインが残っていたようなら、そのまま使うぜ☆(^▽^) } else if ( GameMode.Game == PureAppli.gameMode // ゲームモードの場合☆ && Console02.IsComputerNoBan() // コンピューターの番の場合☆ ) { programSupport.ClearCommandline(); // コマンドラインは消しておくぜ☆(^▽^) } else { Util_ConsoleGame.ReadCommandline(programSupport, hyoji);// コンソールからのキー入力を受け取るぜ☆(^▽^)(コンソール・ゲーム用) } #endregion #region ゲームセクション if (GameMode.Game == PureAppli.gameMode) { #region 手番の開始時 //──────────────────────────────────────── // 手番の開始時 //──────────────────────────────────────── // 手番の開始時に 何かやることがあれば ここに書けだぜ☆(^~^) #endregion #region (手順3)人間の手番 //──────────────────────────────────────── // (手順3)人間の手番 //──────────────────────────────────────── if (Console02.IsNingenNoBan()) // 人間の手番 { // ゲームモードでの人間の手番では、さらにコマンド解析 // ここで do コマンド(do b3b2 等)を先行して解析するぜ☆(^▽^) if (programSupport.caret != programSupport.commandline.IndexOf("do ", programSupport.caret)) { // do以外のコマンドであれば、コマンドラインを保持したまま、そのまま続行 } // 以下、do コマンドの場合☆ else if (!programSupport.ParseDoMove(out Move inputMove)) { // do コマンドのパースエラー表示(コンソール・ゲーム用)☆(^~^) SpkMove.AppendSetumei(MoveMatigaiRiyu.ParameterSyosikiMatigai, hyoji); hyoji.AppendLine(); Logger.Flush(hyoji); programSupport.CommentCommandline(); // コマンドの誤発動防止 } else if (!GenkyokuOpe.CanDoMove(inputMove, out MoveMatigaiRiyu reason)) // 指し手の合否チェック { // イリーガル・ムーブなどの、エラー理由表示☆(^~^) SpkMove.AppendSetumei(reason, hyoji); hyoji.AppendLine(); Logger.Flush(hyoji); } else { // do コマンドを実行するぜ☆(^▽^) // 1手指す☆!(^▽^) if (!Util_Control.Try_DoMove_Input(inputMove #if DEBUG , PureSettei.fenSyurui , (IDebugMojiretu)hyoji #endif )) { result1 = Pure.FailTrue("Try_DoMove_Input"); goto gt_EndLoop1; } // 勝敗判定☆(^▽^) if (!Util_Kettyaku.Try_JudgeKettyaku(inputMove #if DEBUG , hyoji #endif )) { result1 = Pure.FailTrue("Try_JudgeKettyaku"); goto gt_EndLoop1; } // 局面出力 SpkBan_1Column.Setumei_NingenGameYo(PureMemory.kifu_endTeme, hyoji); } }// 人間おわり☆(^▽^) #endregion #region (手順4)コンピューターの手番 //──────────────────────────────────────── // (手順4)コンピューターの手番 //──────────────────────────────────────── else if (Console02.IsComputerNoBan()) //コンピューターの番☆ { SpkNaration.Speak_ComputerSikochu(hyoji); // 表示(コンピューター思考中☆) Logger.Flush(hyoji); // コンピューターに1手指させるぜ☆ Util_Tansaku.PreGo(); if (Util_Tansaku.TryFail_Go(hyoji)) { result1 = Pure.FailTrue("Try_Go"); goto gt_EndLoop1; } // 勝敗判定☆(^▽^) if (!Util_Kettyaku.Try_JudgeKettyaku(PureMemory.tnsk_kohoMove #if DEBUG , hyoji #endif )) { result1 = Pure.FailTrue("Try_JudgeKettyaku"); goto gt_EndLoop1; } SpkNaration.Speak_KettyakuJi(hyoji);// 決着していた場合はメッセージ表示☆(^~^) Logger.Flush(hyoji); }// コンピューターの手番おわり☆(^~^) #endregion #region (手順5)決着時 //──────────────────────────────────────── // (手順5)決着時 //──────────────────────────────────────── if (Genkyoku.IsKettyaku())// 決着が付いているなら☆ { // 対局終了時 // 表示(コンソール・ゲーム用) { playing.Result(hyoji, CommandMode.NingenYoConsoleGame); hyoji.AppendLine("終わったぜ☆(^▽^)"); Logger.Flush(hyoji); } // 棋譜の初期局面を更新☆ { StringBuilder kyFen_temp = new StringBuilder(); SpkGenkyokuOpe.AppendFenTo(PureSettei.fenSyurui, kyFen_temp); PureMemory.kifu_syokiKyokumenFen = kyFen_temp.ToString(); } // TODO: 成績は保存しないにしても、棋譜は欲しいときもあるぜ☆(^~^) // 棋譜を作ろうぜ☆ hyoji.AppendLine("感想戦を行う場合は kansosen と打てだぜ☆(^▽^) そのあと kifu 1 とか打て☆(^▽^)"); hyoji.AppendLine("終わるときは hirate な☆(^▽^)"); Logger.Flush(hyoji); // 初期局面に戻すぜ☆(^▽^) Util_Taikyoku.Clear(); // 棋譜カーソルを0にすれば、初期局面に戻るだろ☆www(^▽^) MoveGenAccessor.BackTemeToFirst_AndClearTeme(); if (Util_Machine.IsRenzokuTaikyokuStop()) { // 連続対局を止めるぜ☆(^▽^) ConsolegameSettei.renzokuTaikyoku = false; hyoji.AppendLine($"{Util_Machine.RENZOKU_TAIKYOKU_STOP_FILE }> done"); } if (!ConsolegameSettei.renzokuTaikyoku) { // ゲームモードを解除するぜ☆(^~^) if (GameMode.Game == PureAppli.gameMode)// 感想戦での発動防止☆ { PureAppli.gameMode = GameMode.Karappo; } } else { // 連続対局中☆(^~^) } // コマンドの誤発動防止 programSupport.CommentCommandline(); } #endregion } #endregion #region (手順6)ゲーム用の指し手以外のコマンドライン実行 //──────────────────────────────────────── // (手順6)ゲーム用の指し手以外のコマンドライン実行 //──────────────────────────────────────── bool result2 = Pure.SUCCESSFUL_FALSE; string cmdline = programSupport.commandline; int caret = programSupport.caret; programSupport.isQuit = false; programSupport.isKyokumenEcho1 = false; // ゲーム・モードの場合、特に指示がなければ コマンド終了後、局面表示を返すぜ☆ if (playing.isMultipleLineCommand) { // TODO: 複数行コマンド中☆(^~^) //syuturyoku.AppendLine($"TODO: ky set 複数行コマンド中☆(^~^)(2) commandline={ commandline}"); //isKyokumenEcho1 = false; if (cmdline == ".") { // 「.」だけの行が来たら終了だぜ☆(^~^) playing.isMultipleLineCommand = false; // 実行☆(^~^) playing.dlgt_multipleLineCommand(playing.multipleLineCommand); playing.multipleLineCommand.Clear(); //syuturyoku.AppendLine($"TODO: 複数行コマンドは={ sbMultipleLineCommand}"); } else { playing.multipleLineCommand.Add(cmdline); } goto gt_EndCommand; } if (null == cmdline) { // 未設定 programSupport.isKyokumenEcho1 = true; } else if (cmdline == "") { programSupport.isKyokumenEcho1 = true; // 空打ちは無視するか、からっぽモードでは、ゲームモードに切り替えるぜ☆(^▽^) if (GameMode.Karappo == PureAppli.gameMode)// 感想戦での発動防止☆ { // ゲームモード(対局開始) PureAppli.gameMode = GameMode.Game; } } // なるべく、アルファベット順☆(^▽^)同じつづりで始まる単語の場合、語句の長い単語を優先にしないと if 文が通らないぜ☆www else if (caret == cmdline.IndexOf("@", caret)) { playing.Atmark(cmdline, hyoji); } else if (caret == cmdline.IndexOf("#", caret)) { } // 受け付けるが、何もしないぜ☆(^▽^)www else if (caret == cmdline.IndexOf("bitboard", caret)) { // ビットボードの表示テスト用だぜ☆(^~^) if (playing.TryFail_Bitboard(cmdline, hyoji)) { result2 = Pure.FailTrue("TryFail_Bitboard"); goto gt_EndCommand; } } else if (caret == cmdline.IndexOf("cando", caret)) { playing.CanDo(PureSettei.fenSyurui, cmdline, GameMode.Game == PureAppli.gameMode ? CommandMode.NingenYoConsoleGame : CommandMode.NigenYoConsoleKaihatu, hyoji); programSupport.isKyokumenEcho1 = true; } else if (caret == cmdline.IndexOf("chikanhyo", caret)) { if (playing.TryFail_ChikanHyo(cmdline, hyoji )) { result2 = Pure.FailTrue("TryFail_ChikanHyo"); goto gt_EndCommand; } } else if (caret == cmdline.IndexOf("clear", caret)) { playing.Clear(); } else if (caret == cmdline.IndexOf("dosub", caret)) { if (playing.TryFail_DoSub(cmdline, hyoji)) { result2 = Pure.FailTrue("TryFail_Do"); goto gt_EndCommand; } programSupport.isKyokumenEcho1 = true; } else if (caret == cmdline.IndexOf("do", caret)) { if (playing.TryFail_Do( PureSettei.fenSyurui, cmdline, GameMode.Game == PureAppli.gameMode ? CommandMode.NingenYoConsoleGame : CommandMode.NigenYoConsoleKaihatu, hyoji )) { result2 = Pure.FailTrue("TryFail_Do"); goto gt_EndCommand; } programSupport.isKyokumenEcho1 = true; } #if DEBUG else if (caret == cmdline.IndexOf("dump", caret)) { if (CommandD.TryFail_Dump(cmdline, hyoji )) { return(Pure.FailTrue("TryFail_Dump")); } } #endif else if (caret == cmdline.IndexOf("fugo", caret)) { if (playing.TryFail_Fugo(cmdline, hyoji )) { result2 = Pure.FailTrue("TryFail_Fugo"); goto gt_EndCommand; } } else if (caret == cmdline.IndexOf("gameover", caret)) { playing.Gameover(cmdline, hyoji); programSupport.isKyokumenEcho1 = true; } else if (caret == cmdline.IndexOf("go", caret)) { var result3 = playing.TryFail_Go( PureSettei.usi, PureSettei.fenSyurui, CommandMode.NigenYoConsoleKaihatu , hyoji ); if (result3) { result2 = Pure.FailTrue("Try_Go"); goto gt_EndCommand; } } else if (caret == cmdline.IndexOf("hirate", caret)) { playing.Hirate(cmdline, hyoji); programSupport.isKyokumenEcho1 = true; } else if (caret == cmdline.IndexOf("honyaku", caret)) { playing.Honyaku(cmdline, hyoji); } else if (caret == cmdline.IndexOf("hyoka", caret)) { playing.Hyoka(cmdline, hyoji); } else if (caret == cmdline.IndexOf("ojama", caret)) { if (playing.TryFail_Ojama(cmdline, hyoji )) { result2 = Pure.FailTrue("TryFail_Ojama"); goto gt_EndCommand; } } else if (caret == cmdline.IndexOf("isready", caret)) { playing.ReadOk(cmdline, hyoji); } else if (caret == cmdline.IndexOf("jokyo", caret)) { playing.Jokyo(cmdline, hyoji); } else if (caret == cmdline.IndexOf("kansosen", caret)) { playing.Kansosen(PureSettei.fenSyurui, cmdline, hyoji); } // 駒の場所を表示するぜ☆(^▽^) else if (caret == cmdline.IndexOf("kifu", caret)) { playing.Kifu(PureSettei.fenSyurui, cmdline, hyoji); } // 駒の場所を表示するぜ☆(^▽^) else if (caret == cmdline.IndexOf("kikisu", caret)) { // 利きの数を調べるぜ☆(^▽^) // 旧名「kikikazu」→「kikisu」 playing.Kikisu(cmdline, hyoji); } else if (caret == cmdline.IndexOf("kiki", caret)) { // 利きを調べるぜ☆(^▽^) var result3 = playing.TryFail_Kiki(cmdline, hyoji); if (result3) { result2 = Pure.FailTrue("TryFail_Kiki"); goto gt_EndCommand; } } else if (caret == cmdline.IndexOf("koma", caret)) { Pure.Sc.Push("komaコマンド"); playing.Koma_cmd(PureSettei.fenSyurui, cmdline, hyoji); Pure.Sc.Pop(); }// 駒の場所を表示するぜ☆(^▽^) else if (caret == cmdline.IndexOf("ky", caret)) { // 局面をクリアーしてやり直すときもここを通るので、ここで局面アサートを入れてはいけないぜ☆(^~^) if (playing.TryFail_Ky(cmdline, hyoji)) { result2 = Pure.FailTrue("Try_Ky"); goto gt_EndCommand; } }// 局面を表示するぜ☆(^▽^) else if (caret == cmdline.IndexOf("manual", caret)) { playing.Man(hyoji); } // "man" と同じ☆(^▽^) else if (caret == cmdline.IndexOf("man", caret)) { playing.Man(hyoji); } // "manual" と同じ☆(^▽^) else if (caret == cmdline.IndexOf("masu", caret)) { playing.Masu_cmd(cmdline, hyoji); } else if (caret == cmdline.IndexOf("nanamedan", caret)) { if (playing.TryFail_Nanamedan(cmdline, hyoji )) { result2 = Pure.FailTrue("TryFail_Nanamedan"); goto gt_EndCommand; } } else if (caret == cmdline.IndexOf("nisinsu", caret)) { if (playing.TryFail_Nisinsu(cmdline, hyoji )) { result2 = Pure.FailTrue("TryFail_Nisinsu"); goto gt_EndCommand; } } else if (caret == cmdline.IndexOf("position", caret)) { playing.Position(PureSettei.fenSyurui, cmdline, hyoji); } else if (caret == cmdline.IndexOf("prego", caret)) { playing.PreGo(cmdline, hyoji); } else if (caret == cmdline.IndexOf("quit", caret)) { programSupport.isQuit = true; programSupport.isKyokumenEcho1 = true; } else if (caret == cmdline.IndexOf("result", caret)) { playing.Result(hyoji, CommandMode.NigenYoConsoleKaihatu); } else if (caret == cmdline.IndexOf("rnd", caret)) { if (!playing.Try_Rnd( #if DEBUG (IDebugMojiretu)hyoji #endif )) { result2 = Pure.FailTrue("commandline"); goto gt_EndCommand; } programSupport.isKyokumenEcho1 = true; } else if (caret == cmdline.IndexOf("move", caret)) { if (playing.TryFail_Move_cmd(cmdline, hyoji)) { result2 = Pure.FailTrue("TryFail_Move_cmd"); goto gt_EndCommand; } } else if (caret == cmdline.IndexOf("setoption", caret)) { playing.Setoption(cmdline, hyoji); } else if (caret == cmdline.IndexOf("set", caret)) { playing.Set(cmdline, hyoji); } else if (caret == cmdline.IndexOf("taikyokusya", caret)) { playing.Taikyokusya_cmd(cmdline, hyoji); } else if (caret == cmdline.IndexOf("tansaku", caret)) { playing.Tansaku(cmdline, hyoji); } else if (caret == cmdline.IndexOf("test", caret)) { if (playing.TryFail_Test(cmdline, hyoji)) { result2 = Pure.FailTrue("TryFail_Test"); goto gt_EndCommand; } } else if (caret == cmdline.IndexOf("tonarikiki", caret)) { if (playing.TryFail_Tonarikiki(cmdline, hyoji)) { result2 = Pure.FailTrue("TryFail_Tonarikiki"); goto gt_EndCommand; } } else if (caret == cmdline.IndexOf("tumeshogi", caret)) { playing.TumeShogi(PureSettei.fenSyurui, cmdline, hyoji); } // "tu" と同じ☆(^▽^) else if (caret == cmdline.IndexOf("tu", caret)) { playing.TumeShogi(PureSettei.fenSyurui, cmdline, hyoji); } // "tumeshogi" と同じ☆(^▽^) else if (caret == cmdline.IndexOf("ugokikata", caret)) { if (playing.TryFail_Ugokikata(cmdline, hyoji)) { result2 = Pure.FailTrue("TryFail_Ugokikata"); goto gt_EndCommand; } } else if (caret == cmdline.IndexOf("undo", caret)) { playing.Undo(cmdline, hyoji); } else if (caret == cmdline.IndexOf("updaterule", caret)) { playing.UpdateRule(cmdline, hyoji); } else if (caret == cmdline.IndexOf("usinewgame", caret)) { playing.UsiNewGame(cmdline, hyoji); } else if (caret == cmdline.IndexOf("usi", caret)) { //ここは普通、来ない☆(^~^) var profilePath = System.Configuration.ConfigurationManager.AppSettings["Profile"]; var toml = Toml.ReadFile(Path.Combine(profilePath, "Engine.toml")); var engineName = toml.Get <TomlTable>("Engine").Get <string>("Name"); Version version = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version; var engineAuthor = toml.Get <TomlTable>("Engine").Get <string>("Author"); playing.UsiOk(cmdline, $"{engineName} {version.Major}.{version.Minor}.{version.Build}", engineAuthor, hyoji); } else { // 表示(コンソール・ゲーム用) hyoji.Append("「"); hyoji.Append(cmdline); hyoji.AppendLine("」☆?(^▽^)"); hyoji.AppendLine("そんなコマンドは無いぜ☆(>_<) man で調べろだぜ☆(^▽^)"); Logger.Flush(hyoji); programSupport.isKyokumenEcho1 = true; } gt_EndCommand: if (result2) { result1 = Pure.FailTrue("Try_DoCommandline"); goto gt_EndLoop1; } if (programSupport.isQuit) { break;//goto gt_EndLoop1; } // 次の入力を促す表示をしてるだけだぜ☆(^~^) programSupport.ShowPrompt(playing, PureSettei.fenSyurui, hyoji); #endregion }//無限ループ gt_EndLoop1: ; if (result1) { Logger.Flush(hyoji); Console.WriteLine("おわり☆(^▽^)"); Console.ReadKey(); //throw new Exception(syuturyoku.ToContents()); } // 開発モードでは、ユーザー入力を待機するぜ☆(^▽^) //──────────────────────────────────────── // (手順7)保存して終了 //──────────────────────────────────────── // 保存していないものを保存するぜ☆(^▽^) // ファイルに書き出していないログが溜まっていれば、これで全部書き出します。 Logger.Flush(PureAppli.syuturyoku1); }
/// <summary> /// コンピューターの思考の開始だぜ☆(^▽^) /// ここが入り口だぜ☆(^~^) /// /// 最善手は yomisuji[0] に入っているぜ☆(^▽^) /// </summary> /// <returns></returns> public static bool TryFail_Go(StringBuilder hyoji) { tmp_bestHyokaSu.Clear(); if (PureMemory.gky_ky.shogiban.yomiIbashoBan_yoko.IsEmpty(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Komasyurui.R, PureMemory.kifu_teban))) { // 自分のらいおんがいない局面の場合、投了☆ #if DEBUG PureMemory.tnsk_syuryoRiyu = TansakuSyuryoRiyu.JibunRaionInai; PureMemory.tnsk_kohoMove = Move.Toryo; tmp_bestHyokaSu.tumeSu = Conv_Tumesu.Stalemate; #endif } else { //──────────────────────────────────────── // 反復深化ループ☆(^~^) //──────────────────────────────────────── Move currMove = Move.Toryo; tmp_currHyokaSu.Clear(); for (HanpukuSinka.happaenoFukasa = 1; // まだ思考に時間を使っていい !ComSettei.timeManager.IsTimeOver_IterationDeeping() ; HanpukuSinka.happaenoFukasa++) { Debug.Assert(0 <= HanpukuSinka.happaenoFukasa && HanpukuSinka.happaenoFukasa < PureMemory.ssss_moveList.Length, ""); if (ComSettei.saidaiFukasa < HanpukuSinka.happaenoFukasa) { // 最大深さを超えた場合 Util_Joho.JohoMatome( HanpukuSinka.happaenoFukasa, tmp_bestHyokaSu, hyoji #if DEBUG , "SaidaiFukasaGoe" #endif ); break; } // ここでは現在の局面に盤面を戻してあると思えだぜ☆(^~^) Debug.Assert(1 <= HanpukuSinka.happaenoFukasa && HanpukuSinka.happaenoFukasa < PureMemory.ssss_moveList.Length, ""); ComSettei.SetSikoJikan_KonkaiNoTansaku();//思考時間(ランダム込み)を確定させるぜ☆(^~^) PureMemory.SetTnskHyoji(hyoji); //カウントダウン式の数字☆(^▽^) 反復深化探索の1週目は 1、2週目は 2 だぜ☆(^▽^) PureMemory.SetTnskFukasa(HanpukuSinka.happaenoFukasa); Tansaku_( out currMove, out tmp_currHyokaSu// 相手番の指し手の評価値が入ってくるぜ☆(^~^) ); // TODO: 1手も読めていなければ、さっさと投了したいぜ☆(^~^) if (tmp_currHyokaSu.isHaki) { // 時間切れ等の中途半端探索のとき☆ // この計算結果は、無視するぜ☆(^~^) // ここに来るときは探索終了だぜ☆(^~^) break;// 読みを終了しようなんだぜ☆ } else { // 更新☆(^▽^) PureMemory.tnsk_itibanFukaiNekkoKaranoFukasa_JohoNoTameni = HanpukuSinka.happaenoFukasa; PureMemory.tnsk_kohoMove = currMove; tmp_bestHyokaSu.ToSet(tmp_currHyokaSu); if (Conv_Tumesu.CatchRaion == tmp_bestHyokaSu.tumeSu) { // 「0手詰められ」が返ってきているなら、負けました、をいう場面だぜ☆ #if DEBUG PureMemory.tnsk_syuryoRiyu = TansakuSyuryoRiyu.Minus2TeTumerare; #endif break;// 読みを終了しようなんだぜ☆ } } }//ループ // ストップウォッチ ComSettei.timeManager.stopwatch_Tansaku.Stop(); } //──────────────────────────────────────── // 詰め、詰められ //──────────────────────────────────────── { Util_Taikyoku.Update( tmp_bestHyokaSu, PureMemory.kifu_teban ); } //──────────────────────────────────────── // 指し手は決まった☆(^~^) // 指して、局面を進めておくぜ☆(^~^) //──────────────────────────────────────── // 何これ if (DoMoveOpe.TryFailDoMoveAll( PureMemory.tnsk_kohoMove, MoveType.N00_Karappo #if DEBUG , PureSettei.fenSyurui , (IDebugMojiretu)hyoji , true//アサート抑制 , "TryFail_Go(1)" #endif )) { return(Pure.FailTrue("GenkyokuOpe.Try_DoMove(1)")); } // 手番を進めるぜ☆(^~^) MoveGenAccessor.AddKifu(PureMemory.tnsk_kohoMove, MoveType.N00_Karappo, PureMemory.dmv_ks_c); #if DEBUG Util_Tansaku.Snapshot("Go(1)確定指し", PureMemory.tnsk_kohoMove); #endif // 指し手が決まったときにも、強制情報表示 { if (0 == PureMemory.tnsk_itibanFukaiNekkoKaranoFukasa_JohoNoTameni) { #if DEBUG hyoji.AppendLine($@"0手投了してないかだぜ☆?(^~^) tansakuSyuryoRiyu=[{PureMemory.tnsk_syuryoRiyu}] Option_Application.Optionlist.SaidaiFukasa=[{ComSettei.saidaiFukasa}] Option_Application.Optionlist.SikoJikan_KonkaiNoTansaku=[{ComSettei.sikoJikan_KonkaiNoTansaku}] Option_Application.Optionlist.SikoJikan=[{ComSettei.sikoJikan}] Option_Application.Optionlist.SikoJikanRandom=[{ComSettei.sikoJikanRandom}] "); return(Pure.FailTrue("0手投了")); #endif } } #if DEBUG hyoji.AppendLine(string.Format("bestMove: [{0}] ss={1}", PureMemory.tnsk_kaisiTeme, SpkMove.ToString_Fen(PureSettei.fenSyurui, PureMemory.tnsk_kohoMove) )); #endif return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 探索だぜ☆(^▽^) /// </summary> /// <param name="ky"></param> /// <param name="alpha"></param> /// <param name="fukasa">カウントダウン式の数字☆(^▽^) 反復深化探索の1週目の初期値は 1、2週目の初期値は 2 だぜ☆(^▽^) /// これがどんどんカウントダウンしていくぜ☆(^▽^) 0 で呼び出されたときは葉にしてすぐ処理を終われよ☆(^▽^)www</param> /// <param name="out_yomisujiToBack"></param> /// <param name="out_bestHyokatiAb1">手番から見た指し手の評価値だぜ☆(^~^)</param> /// <param name="out_edaBest_Komawari_JohoNoTame">内訳の目視確認用に使うだけの項目。</param> /// <param name="out_edaBest__Okimari_JohoNoTame">内訳の目視確認用に使うだけの項目。</param> /// <param name="out_edaBest_____Riyu_JohoNoTame">内訳の目視確認用に使うだけの項目。</param> /// <param name="dlgt_CreateJoho"></param> /// <returns></returns> private static void Tansaku_( out Move out_bestMove, out Hyokati out_bestHyokasu // 手番側の指し手の評価値だぜ☆(^~^) ) { Debug.Assert(0 <= PureMemory.tnsk_fukasa && PureMemory.tnsk_fukasa < PureMemory.ssss_moveList.Length, ""); out_bestMove = Move.Toryo; out_bestHyokasu = null; //──────────────────────────────────────── // 時間切れ判定 //──────────────────────────────────────── if (ComSettei.timeManager.IsTimeOver_TansakuChu()) { out_bestMove = Move.Toryo; out_bestHyokasu = new Hyokati( Conv_Hyokati.Hyokati_Rei, Conv_Tumesu.Stalemate, true // 今回の探索の結果は破棄するぜ☆(^~^) #if DEBUG , Conv_Hyokati.Hyokati_Rei , Conv_Hyokati.Hyokati_Rei , Conv_Hyokati.Hyokati_Rei , HyokaRiyu.JikanGire , "" #endif ); #if DEBUG Util_Tansaku.Snapshot("時間切れだぜ☆(^~^)", out_bestMove); #endif return; } //──────────────────────────────────────── // 葉 //──────────────────────────────────────── #region 葉 if ( // 深さ0 で呼び出されたときは、葉にしろということだぜ☆(^▽^)www PureMemory.tnsk_fukasa == 0 ) { // 深さ(根っこからの深さ)は 1 以上で始まるから、ループの1週目は、スルーされるはずだぜ☆(^▽^) // 1手指して 枝を伸ばしたとき、相手の手番の局面になっているな☆(^▽^)そのとき ここを通る可能性があるぜ☆ // // 末端局面で評価値を作らないぜ☆(^~^)! // 指し手を、指したときに作るんだぜ☆(^~^)! // PureMemory.tnsk_happaTeme = PureMemory.kifu_endTeme; // 「手目」カーソルは DoMove で1つ進んでいるはずなので、戻すんだぜ☆(^~^) out_bestMove = PureMemory.kifu_moveArray[PureMemory.kifu_endTeme - 1]; out_bestHyokasu = new Hyokati(PureMemory.gky_hyokati); // 葉で情報表示 Util_Joho.JohoMatome( PureMemory.tnsk_fukasa + 1, out_bestHyokasu, PureMemory.tnsk_hyoji #if DEBUG , out_bestHyokasu.dbg_riyu.ToString() #endif ); #if DEBUG Util_Tansaku.Snapshot("葉だぜ☆(^~^)", out_bestMove); #endif return;//枝を戻る(正常終了) } #endregion //──────────────────────────────────────── // 指し手生成 //──────────────────────────────────────── // グローバル変数 Util_MoveSeisei.Sslist に指し手がセットされるぜ☆(^▽^) MoveGenAccessor.DoMovePickerBegin(MoveType.N21_All); MovePicker01.MovePickerN01(MoveType.N21_All, true); #region ステイルメイト //──────────────────────────────────────── // ステイル・メイト //──────────────────────────────────────── if (PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].listCount < 1) { // 詰んでるぜ☆(^~^) out_bestMove = Move.Toryo; out_bestHyokasu = new Hyokati( Conv_Hyokati.Hyokati_Rei, Conv_Tumesu.Stalemate, false #if DEBUG , Conv_Hyokati.Hyokati_Rei , Conv_Hyokati.Hyokati_Rei , Conv_Hyokati.Hyokati_Rei , HyokaRiyu.Stalemate , "" #endif ); // ステイルメイトで情報表示 Util_Joho.JohoMatome( PureMemory.tnsk_fukasa + 1,// 深さは 0 になっているので、Tansaku していない状態(=+1 して)に戻すぜ☆ out_bestHyokasu, PureMemory.tnsk_hyoji #if DEBUG , "Stalemate" #endif ); #if DEBUG Util_Tansaku.Snapshot("ステイルメイトだぜ☆(^~^)", out_bestMove); MoveSeiseiAccessor.DumpMoveSeisei(PureMemory.tnsk_hyoji); #endif return;//枝を戻る(正常終了) } #endregion for (int iSs = 0; iSs < PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].listCount; iSs++) { // 枝☆ 適当にここらへんでカウントアップするかだぜ☆(^~^) PureMemory.tnsk_tyakusyuEdas++; //──────────────────────────────────────── // 指す //──────────────────────────────────────── //#if DEBUG // Util_Tansaku.Snapshot("ドゥ前", hyoji); //#endif Move ss_jibun = PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].moveList[iSs]; MoveType ssType_jibun = PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].moveTypeList[iSs]; if (DoMoveOpe.TryFailDoMoveAll( ss_jibun, ssType_jibun #if DEBUG , PureSettei.fenSyurui , (IDebugMojiretu)PureMemory.tnsk_hyoji , false , "TryFail_Tansaku_(1)" #endif )) { // 探索時にエラーが起こった場合は強制終了☆(^~^) throw new Exception(PureMemory.tnsk_hyoji.ToString()); } // 手番を進めるぜ☆(^~^) MoveGenAccessor.AddKifu( ss_jibun, ssType_jibun, PureMemory.dmv_ks_c); #if DEBUG Util_Tansaku.Snapshot("ドゥ後・探索前", out_bestMove); #endif Move ss_aite; //MoveType eda_moveType; // goto文で飛ぶと未割当になるので、ヌルでも入れておくぜ☆(^~^) Hyokati hyokasu_aiteToJibun = null; // この指し手が、駒を取った手かどうか☆ PureMemory.SetTnskHyoji(PureMemory.tnsk_hyoji); // 探索者がプラスでスタートして、 // 探索者の反対側はマイナスになり、 // 探索者の反対側の反対側はプラスに戻るぜ☆(^▽^) PureMemory.DecreaseTnskFukasa(); Tansaku_( out ss_aite, out hyokasu_aiteToJibun // 相手番の指し手の評価値が入ってくるぜ☆(^~^) ); PureMemory.IncreaseTnskFukasa(); //#if DEBUG // Util_Tansaku.Snapshot("探索後・アンドゥ前", hyoji); //#endif //──────────────────────────────────────── // 詰みを発見していれば、打ち切りフラグを立てるぜ☆(*^~^*) //──────────────────────────────────────── bool undoAndBreak = false; if (hyokasu_aiteToJibun.tumeSu == Conv_Tumesu.CatchRaion) { out_bestMove = ss_jibun; out_bestHyokasu = new Hyokati( Conv_Hyokati.Hyokati_Rei, Conv_Tumesu.CatchRaion,// この枝にこれるようなら、勝ち宣言だぜ☆(^▽^) false #if DEBUG , Conv_Hyokati.Hyokati_Rei , Conv_Hyokati.Hyokati_Rei , Conv_Hyokati.Hyokati_Rei , HyokaRiyu.TansakuRaionCatch , "" #endif ); // 打ち切りで情報表示 Util_Joho.JohoMatome( PureMemory.tnsk_fukasa, out_bestHyokasu, PureMemory.tnsk_hyoji #if DEBUG , "TansakuRaionCatch" #endif ); // 詰みではなく、らいおんきゃっち または トライかを 調べるぜ☆(^~^) // この手番は、 // この指し手を選べば、勝てるという理屈だが……☆ undoAndBreak = true; #if DEBUG Util_Tansaku.Snapshot("らいおんキャッチだぜ☆(^~^)", out_bestMove); #endif } // 探索で先の枝から戻ってきたときは、評価の符号を反転し、詰め手数のカウントもアップするぜ☆(^~^) hyokasu_aiteToJibun.CountUpTume(); hyokasu_aiteToJibun.ToHanten(); if (UndoMoveOpe.TryFailUndoMove( #if DEBUG PureSettei.fenSyurui , (IDebugMojiretu)PureMemory.tnsk_hyoji #endif )) { // 探索時にエラーが起こった場合は強制終了☆(^~^) throw new Exception(PureMemory.tnsk_hyoji.ToString()); } #if DEBUG Util_Tansaku.Snapshot("アンドゥ後", out_bestMove); #endif //──────────────────────────────────────── // これ以上 弟要素を探索するのを止め、枝を戻るかどうか☆(^~^) //──────────────────────────────────────── #region 打ち切り各種 if (undoAndBreak) { // (1)千日手の権利を相手に渡すために低点数付け<それ以降の手は読まない> // (2)らいおん を捕獲した // (3)トライ した #if DEBUG Util_Tansaku.Snapshot("アンドゥ後ブレイクだぜ☆(^~^)", out_bestMove); #endif break;//枝を戻る(正常終了) } #endregion //──────────────────────────────────────── // アップデート・枝ベスト //──────────────────────────────────────── #region アップデート・枝ベスト // 点数が付かないことがあって、その場合 ベスト指し手 を1度も選ばない // 「<=」にすると同点だったら、指し手のオーダリングの低いのを選ぶが☆(^~^) if (null == out_bestHyokasu) { out_bestMove = ss_jibun; out_bestHyokasu = hyokasu_aiteToJibun;// new HyokaSu(eda_hyokasu);//ここで新規作成 #if DEBUG Util_Tansaku.Snapshot("アップデート枝ベスト1回目だぜ☆(^~^)", out_bestMove); #endif } else if (out_bestHyokasu.hyokaTen < hyokasu_aiteToJibun.hyokaTen) { out_bestMove = ss_jibun; out_bestHyokasu.ToSet(hyokasu_aiteToJibun); // 兄弟の中で一番の読み筋だぜ☆(^▽^) // ↓ // TODO: ここで情報を表示したいが……☆(^~^) #if DEBUG Util_Tansaku.Snapshot("アップデート枝ベストだぜ☆(^~^)", out_bestMove); #endif } #endregion }//指し手ループ //; // このノードでの最大評価を返すんだぜ☆(^▽^) // ここでアルファを返してしまうと、アルファが1回も更新されなかったときに、このノードの最大評価ではないものを返してしまうので不具合になるぜ☆(^~^) if (null == out_bestHyokasu) { out_bestMove = Move.Toryo; out_bestHyokasu = new Hyokati( Conv_Hyokati.Hyokati_Rei, Conv_Tumesu.None, false #if DEBUG , Conv_Hyokati.Hyokati_Rei , Conv_Hyokati.Hyokati_Rei , Conv_Hyokati.Hyokati_Rei , HyokaRiyu.Fumei , "ループ抜け" #endif ); // ステイルメイトで情報表示 Util_Joho.JohoMatome( PureMemory.tnsk_fukasa, out_bestHyokasu, PureMemory.tnsk_hyoji #if DEBUG , "LoopOut" #endif ); #if DEBUG Util_Tansaku.Snapshot("評価の決まらない、ループ抜けだぜ☆(^~^)", out_bestMove); #endif return;//枝を戻る(正常終了) } }
/// <summary> /// 指したあとの、次の局面へと更新するぜ☆ /// ハッシュも差分変更するぜ☆ /// /// 手番を進める処理は、分けるぜ☆(^~^) /// </summary> /// <param name="ss">指し手☆</param> public static bool TryFailDoMoveAll( Move ss, MoveType ssType #if DEBUG , FenSyurui f , IDebugMojiretu reigai1 , bool isAssertYokusei // 駒の取り合いは呼び出し回数が多いので、アサートを抑制したいときに真 , string hint #endif ) { #if DEBUG isAssertYokusei = false;//FIXME: #endif // 投了なら、なにも更新せず終了☆(^▽^) if (Move.Toryo == ss) { PureMemory.dmv_ks_c = Komasyurui.Yososu; goto gt_EndMethod; } MoveGenAccessor.BunkaiMoveDmv(ss); Debug.Assert(Conv_Koma.IsOk(PureMemory.dmv_km_t0), string.Format("Do km_t0={0}", PureMemory.dmv_km_t0)); Debug.Assert(Conv_Koma.IsOk(PureMemory.dmv_km_t1), "Do"); Debug.Assert(Conv_Masu.IsBanjoOrError(PureMemory.dmv_ms_t1), ""); Debug.Assert(Conv_Koma.IsOkOrKuhaku(PureMemory.dmv_km_c), "Do"); if (AbstractConvMove.IsUtta(ss)) { // 打った場合☆(^~^) // 駒台から駒を減らすんだぜ☆(^~^) if (TryFail_DaiOff( PureMemory.dmv_ms_t0, // 打ち、の場合は使わないので、エラー値を入れておく PureMemory.dmv_km_t0, // 打つ駒 PureMemory.dmv_mk_t0, // 持駒 PureMemory.dmv_ms_t1 // 移動先升 #if DEBUG , f , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Tejun3_IdomotoJibunnoKomaTorinozoku")); } } else { // 盤上の駒を動かした場合☆(^~^) // 移動先に駒があれば取る if (CanDstOff(PureMemory.dmv_km_c)) { if (TryFail_DstOff( PureMemory.dmv_ms_t1, // 移動先升 PureMemory.dmv_km_c, // あれば、移動先の相手の駒(取られる駒; capture) PureMemory.dmv_ks_c #if DEBUG , f , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Tejun1_IdosakiNoKomaWoToru")); } // 取った駒が有れば駒台に増やすぜ☆(^~^) if (TryFail_DaiOn( PureMemory.dmv_km_c,// あれば、移動先の相手の駒(取られる駒; capture) PureMemory.dmv_ks_c, PureMemory.dmv_mk_c #if DEBUG , f , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Tejun2_TottaKomaWoKomadainiOku")); } } // 移動元から自分の駒を取り除くぜ☆(^~^) if (TryFail_SrcOff( ss, PureMemory.dmv_ms_t0, PureMemory.dmv_km_t0, PureMemory.dmv_mk_t0, PureMemory.dmv_ms_t1 // 移動先升 #if DEBUG , f , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Tejun3_IdomotoJibunnoKomaTorinozoku")); } } // 移動先に手番の駒を置くぜ☆(^~^) if (TryFail_DstOn( PureMemory.dmv_ms_t0, PureMemory.dmv_km_t1, PureMemory.dmv_ms_t1 // 移動先升 #if DEBUG , f , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Tejun4_IdosakiNiTebanonKomawoOku")); } //──────────────────────────────────────── // 最後に診断 //──────────────────────────────────────── gt_EndMethod: return(Pure.SUCCESSFUL_FALSE); }