/// <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> 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> /// <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); }