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> /// <returns></returns> public void Tukurinaosi(Kyokumen ky) { ulong hash = 0; // 盤上 Bitboard komaBB = new Bitboard(); for (int iTai = 0; iTai < Conv_Taikyokusya.AllOptionalPhaseList.Length; iTai++) { var optionalPhase = Conv_Taikyokusya.AllOptionalPhaseList[iTai]; for (int iKs = 0; iKs < Conv_Komasyurui.Itiran.Length; iKs++) { Komasyurui ks = Conv_Komasyurui.Itiran[iKs]; Koma km = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalPhase); ky.Shogiban.ToSet_BBKoma(km, komaBB); while (komaBB.Ref_PopNTZ(out Masu ms)) { hash ^= Util_ZobristHashing.GetBanjoKey(ms, km, ky.Sindan); } } } // 持ち駒 foreach (MotiKoma mk in Conv_MotiKoma.Itiran) { hash ^= Util_ZobristHashing.GetMotiKey(ky.Sindan, mk); } // 手番 hash ^= Util_ZobristHashing.GetTaikyokusyaKey(ky.CurrentOptionalPhase, ky.Sindan); Value = hash; }
public static bool ParseDoMove(Kyokumen ky, out Move out_sasite) { // コンソールからのキー入力を解析するぜ☆(^▽^) int caret = Util_Commandline.Caret; int oldCaret = Util_Commandline.Caret; Util_String.TobasuTangoToMatubiKuhaku(Util_Commandline.Commandline, ref caret, "do "); // うしろに続く文字は☆(^▽^) if (!Med_Parser.TryFenMove(Option_Application.Optionlist.USI, Util_Commandline.Commandline, ref caret, ky.Sindan, out out_sasite)) { Util_Commandline.Caret = oldCaret; //String2 str = new String2Impl(); //str.Append("指し手のパースに失敗だぜ☆(^~^)! #鷺 commandline=["); //str.Append(commandline); //str.Append("] caret=["); //str.Append(caret); //str.Append("]"); //syuturyoku.AppendLine(str.ToString()); //Logger.Flush(); //throw new Exception(str.ToString()); return(false); } // do コマンドだった場合☆ Util_Commandline.Caret = caret; Util_Commandline.CommentCommandline();// コマンドの誤発動防止 return(true); }
/// <summary> /// 定跡局面の中で、勝率が一番高い指し手を返すぜ☆(^▽^) /// </summary> /// <param name="ky"></param> /// <returns>なければ投了☆</returns> public Move GetSasite_Winest(Kyokumen ky, out float out_bestSyoritu) { Move bestSasite = Move.Toryo; out_bestSyoritu = float.MinValue; int minMake = int.MaxValue; //Util_Machine.Assert_KyokumenSeigosei_SabunKosin("ゲット指し手 #鯨",true); ulong hash = ky.KyokumenHash.Value; if (this.KyItems.ContainsKey(hash)) { SeisekiKyokumen josekyKy = this.KyItems[hash]; foreach (KeyValuePair <Move, SeisekiMove> entry in josekyKy.SsItems) { if (out_bestSyoritu < entry.Value.GetSyoritu())// 勝率が高い指し手を選ぶぜ☆(^▽^) { bestSasite = entry.Key; out_bestSyoritu = entry.Value.GetSyoritu(); minMake = entry.Value.Make; } else if (out_bestSyoritu == entry.Value.GetSyoritu() && //勝率が同じ場合は、 entry.Value.Make < minMake //負けが少ない指し手を選ぶぜ☆(^▽^) ) { bestSasite = entry.Key; out_bestSyoritu = entry.Value.GetSyoritu(); minMake = entry.Value.Make; } } } return(bestSasite); }
/// <summary> /// 項目番号 K を返すぜ☆(^~^) /// </summary> /// <returns>該当なければ -1</returns> public static int GetKoumokuBango_Banjo(Kyokumen ky, Koma km_jissai, Masu ms_jissai) { return(-1); //// 盤上の駒1 //int iMs_jissai = (int)ms_jissai; //if (Conv_Koma.IsOk(km_jissai)) //{ // // 盤上のパラメーター // // まず、大きく10区画「RZKHNrzkhn」に分かれているので、 // // komaArea = ( 0 ~ 10 ) に分けるぜ☆ // int komaArea; // switch (km_jissai) // { // case Koma.King1: komaArea = 0; break; // area = 0 の場合、 0 以上 1 未満だぜ☆(^~^) // case Koma.Bishop1: komaArea = 1; break; // case Koma.Rook1: komaArea = 2; break; // case Koma.Pawn1: komaArea = 3; break; // case Koma.ProPawn1: komaArea = 4; break; // case Koma.King2: komaArea = 5; break; // case Koma.Bishop2: komaArea = 6; break; // case Koma.Rook2: komaArea = 7; break; // case Koma.Pawn2: komaArea = 8; break; // case Koma.ProPawn2: komaArea = 9; break; // default: throw new Exception("未定義の駒"); // } // // K2 の方も、 K1 と同じように分かれているぜ☆(^▽^) // return komaArea * KyokumenImpl.MASUS + iMs_jissai; //} //return -1; }
public static Move Go(IPlaying playing, Kyokumen ky, out HyokatiUtiwake out_hyokatiUtiwake, Util_Tansaku.Dlgt_CreateJoho dlgt_CreateJoho, StringBuilder syuturyoku) { Move move = Util_Tansaku.Go(playing, Option_Application.Optionlist.USI, ky, out out_hyokatiUtiwake, out bool isJosekiTraced, dlgt_CreateJoho, syuturyoku); Util_ConsoleGame.IsJosekiTraced = isJosekiTraced; return(move); }
/// <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(); } }
/// <summary> /// /// </summary> /// <param name="bestSasite">投了かどうか調べるだけ☆</param> public static void JudgeKettyaku(Move bestSasite, Kyokumen ky) { var optionalOpponent2 = Conv_Taikyokusya.Reverse(ky.CurrentOptionalPhase); if (Move.Toryo == bestSasite) { switch (ky.CurrentOptionalPhase.Unwrap())// 投了した時点で、次の手番に移っているぜ☆ { case Phase.White: // 対局者1が投了して、対局者2の手番になったということだぜ☆ // だから対局者2の勝ちだぜ☆ ky.Kekka = TaikyokuKekka.Taikyokusya2NoKati; break; case Phase.Black: ky.Kekka = TaikyokuKekka.Taikyokusya1NoKati; break; default: throw new Exception("未定義の手番"); } } else if (ky.Konoteme.IsSennitite()) { ky.Kekka = TaikyokuKekka.Sennitite; } // トライルール else if (Util_TryRule.IsTried(ky, optionalOpponent2//手番が進んでいるので、相手番のトライを判定☆ ) ) { switch (optionalOpponent2.Unwrap()) { case Phase.Black: ky.Kekka = TaikyokuKekka.Taikyokusya1NoKati; break; case Phase.White: ky.Kekka = TaikyokuKekka.Taikyokusya2NoKati; break; default: throw new Exception("未定義の手番"); } } else { // らいおんがいるか☆ bool raion1Vanished = ky.Shogiban.IsEmptyBBKoma(Koma.King1); bool raion2Vanished = ky.Shogiban.IsEmptyBBKoma(Koma.King2); if (raion1Vanished && raion2Vanished) { // らいおんが2匹ともいない場合(エラー) ky.Kekka = TaikyokuKekka.Hikiwake; } else if (raion2Vanished) { ky.Kekka = TaikyokuKekka.Taikyokusya1NoKati; } else if (raion1Vanished) { ky.Kekka = TaikyokuKekka.Taikyokusya2NoKati; } } }
public static Masu GetDstMasu(Move ss, Kyokumen ky) { // エラーチェック付き if (Move.Toryo == ss) { return(ky.MASU_ERROR); } return(GetDstMasu_WithoutErrorCheck((int)ss)); }
/// <summary> /// トライしていれば真☆ /// </summary> /// <returns></returns> public static bool IsTried(Kyokumen ky, Option <Phase> phase) { switch (phase.Unwrap()) { case Phase.Black: return(ky.BB_DanArray[0].IsIntersect(ky.Shogiban.GetBBKoma(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Komasyurui.R, phase)))); case Phase.White: return(ky.BB_DanArray[Option_Application.Optionlist.BanTateHaba - 1].IsIntersect(ky.Shogiban.GetBBKoma(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Komasyurui.R, phase)))); default: throw new Exception("未定義の手番"); } }
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 AppendLine_Data_Kyokumen(Kyokumen ky, int dan, StringBuilder syuturyoku) { syuturyoku.Append("│"); for (int iMs_offset = 0; iMs_offset < Option_Application.Optionlist.BanYokoHaba; iMs_offset++) { Masu ms = (Masu)(dan * Option_Application.Optionlist.BanYokoHaba + iMs_offset); Koma km = ky.GetBanjoKoma(ms); Conv_Koma.Setumei(km, syuturyoku); syuturyoku.Append("│"); } syuturyoku.AppendLine(); }
/// <summary> /// コンピューター思考中表示☆(^~^) /// </summary> public static void AppendMessage_ComputerSikochu(Kyokumen ky, StringBuilder syuturyoku) { #if DEBUG syuturyoku.Append("**デバッグ・モード** ");//注意喚起☆(^▽^) #endif Conv_Taikyokusya.Setumei_Name(ky.CurrentOptionalPhase, syuturyoku); syuturyoku.Append("("); syuturyoku.Append(Option_Application.Optionlist.PNChar[OptionalPhase.IndexOf(ky.CurrentOptionalPhase)].ToString()); syuturyoku.Append(")の思考中(^~^)"); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); }
/// <summary> /// 一手詰めの局面かどうか調べるぜ☆(^▽^) /// /// 自分が一手詰めを掛けられるから、この指し手は作らないでおこう、といった使い方がされるぜ☆(^▽^) /// /// FIXME: 持ち駒の打ちにも使えないか☆(^~^)? /// </summary> /// <param name="fukasa"></param> /// <param name="ky"></param> /// <param name="jibun"></param> /// <param name="ms_src">持ち駒の場合、エラー値</param> /// <param name="mks">持ち駒の場合、持駒の種類</param> /// <param name="ms_t1"></param> /// <param name="jibunHioute"></param> /// <returns></returns> public static bool Ittedume_MotiKoma(int fukasa, Kyokumen ky, MotiKoma mk, Masu ms_t1, HiouteJoho jibunHioute, HiouteJoho aiteHioute) { if (!Conv_MotiKoma.IsOk(mk)) { throw new Exception("持ち駒じゃないじゃないか☆(^▽^)www"); } // A B C // ┌──┬──┬──┐ //1│ │▽ら│ │ // ├──┼──┼──┤ //2│▲き│ │▲き│ // ├──┼──┼──┤ //3│ │▲に│▲ら│ // ├──┼──┼──┤ //4│▲ぞ│▲ひ│▲ぞ│ // └──┴──┴──┘ // 盤上の駒を動かすのか、駒台の駒を打つのかによって、利き の形が異なるぜ☆(^~^) Bitboard bb_kiki_t1 = ky.Shogiban.GetKomanoUgokikata(Med_Koma.MotiKomaToKoma(mk), ms_t1); if (!ky.Shogiban.GetBBKoma(aiteHioute.KmRaion).IsIntersect( // 相手らいおんの場所☆ bb_kiki_t1)) // 相手らいおん が、動かした駒の、利きの中に居ないんだったら、一手詰め にはならないぜ☆(^~^) { // FIXME: ステイルメイトは考えてないぜ☆(>_<) return(false); } Koma km_t1 = Med_Koma.MotiKomaToKoma(mk);//t0も同じ // FIXME: ↓駒移動後の、利きを取る必要がある Bitboard bb_jibunKikiNew = new Bitboard(); { // 打による、重ね利きの数を差分更新するぜ☆(^▽^) //, ky.BB_KikiZenbu ky.Shogiban.N100_FuyasuKiki(km_t1, ky.Sindan.CloneKomanoUgoki(km_t1, ms_t1), ky.Sindan);// 移動先の駒の利きを増やすぜ☆(^▽^) // こっちの利きを作り直し bb_jibunKikiNew = ky.Shogiban.ToBitboard_KikisuZenbuPositiveNumber(Med_Koma.MotiKomaToPhase(mk), ky.Sindan); // 打による、重ね利きの数の差分更新を元に戻すぜ☆(^▽^) // , ky.BB_KikiZenbu ky.Shogiban.N100_HerasuKiki(km_t1, ky.Sindan.CloneKomanoUgoki(km_t1, ms_t1), ky.Sindan);// 移動先の駒の利きを減らすぜ☆(^▽^) } // 相手らいおんが逃げようとしていて。 return(aiteHioute.FriendRaion8KinboBB.Clone() // 相手らいおんの8近傍 .Sitdown(ky.Shogiban.GetBBKomaZenbu(aiteHioute.CurrentOptionalPhase)) // 相手の駒がない升 .Sitdown(bb_jibunKikiNew) // こっちの利きがない升 .IsEmpty()); // 相手らいおん が逃げれる升がない場合、詰み☆ }
public static void Undo(string commandline, Kyokumen ky, StringBuilder syuturyoku) { // うしろに続く文字は☆(^▽^) int caret = 0; Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret, "undo "); if (!Med_Parser.TryFenMove(Option_Application.Optionlist.USI, commandline, ref caret, ky.Sindan, out Move ss)) { throw new Exception($"パースエラー [{ commandline }]"); } ky.UndoMove(Option_Application.Optionlist.USI, ss, syuturyoku); // このムーブには取った駒は含まれないのでは。 }
/// <summary> /// 評価値の計算し直し。 /// /// 多対多の項目の組み合わせを全部加算。 /// </summary> /// <param name="ky"></param> /// <returns>手番の視点で返す</returns> public void KeisanSinaosi(Kyokumen ky) { // 駒の位置(評価関数の項目番号)をリストに入れておくぜ☆ Util_NikomaKankei.MakeKoumokuBangoHairetu_Subete(ky, Util_NikomaKankei.KoumokuBangoHairetu1); // 評価値 int hyokati = 0; for (int iGyoIndex = 0; iGyoIndex < Util_NikomaKankei.KoumokuBangoHairetu1.Nagasa; iGyoIndex++) { for (int iRetuIndex = 0; iRetuIndex < Util_NikomaKankei.KoumokuBangoHairetu1.Nagasa; iRetuIndex++) { if (Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iGyoIndex] <= Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iRetuIndex])// 組み合わせを反対から見ただけの同じものを弾くぜ☆(^~^) { continue; } // 差分更新と比較するので、差分更新用☆(^~^) //hyokati += Util_NikomaKankei.GetHyokaNumber_SabunKosinYou(Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iRetuIndex], Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iGyoIndex]); // (^▽^)関数(小さい数字,大きい数字)だぜ☆ そうでなければ逆立ちさせるぜ☆(^▽^)www if (Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iRetuIndex] < Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iGyoIndex]) { hyokati += Util_NikomaKankei.GetHyokaNumber_SabunKosinYou(Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iRetuIndex], Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iGyoIndex]); } else if (Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iGyoIndex] < Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iRetuIndex]) { // 逆立ち☆(^▽^)www hyokati += Util_NikomaKankei.GetHyokaNumber_SabunKosinYou(Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iGyoIndex], Util_NikomaKankei.KoumokuBangoHairetu1.Hairetu[iRetuIndex]); } } } if (hyokati < Util_NikomaKankei.SAISYO_HYOKATI_SABUNKOSINYOU) { hyokati = Util_NikomaKankei.SAISYO_HYOKATI_SABUNKOSINYOU; } else if (Util_NikomaKankei.SAIDAI_HYOKATI_SABUNKOSINYOU < hyokati) { hyokati = Util_NikomaKankei.SAIDAI_HYOKATI_SABUNKOSINYOU; } var(exists, phase) = ky.CurrentOptionalPhase.Match; if (exists) { if (phase == Phase.White) { hyokati = -hyokati; // 対局者2視点に変えるぜ☆(^▽^) } } Hyokati = (Hyokati)hyokati; }
/// <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; } } }
public static void Kiki(bool isSfen, string commandline, Kyokumen ky, out Masu out_ms, out Bitboard out_kikiBB) { //KomanoUgokikata komanoUgokikata, // うしろに続く文字は☆(^▽^) int caret = 0; Util_String.TobasuTangoToMatubiKuhaku(commandline, ref caret, "kiki "); string line = commandline.Substring(caret).TrimEnd(); if (line.Length == 2)// kiki b3 { out_kikiBB = null; // 升を返すぜ☆ if (!Med_Parser.TryParseMs(isSfen, commandline, ky, ref caret, out out_ms)) { throw new Exception("パースエラー102"); } } else// kiki b3 R 1 { out_ms = ky.MASU_ERROR; // 盤面表示を返すぜ☆ string moji1 = ""; string moji2 = ""; string moji3 = ""; string moji4 = ""; Match m = Itiran_FenParser.GetKikiCommandPattern(Option_Application.Optionlist.USI).Match(commandline, caret); if (m.Success) { Util_String.SkipMatch(commandline, ref caret, m); moji1 = m.Groups[1].Value; moji2 = m.Groups[2].Value; moji3 = m.Groups[3].Value; moji4 = m.Groups[4].Value; if (!Med_Parser.TryTaikyokusya(Option_Application.Optionlist.USI, moji4, out Option <Phase> phase)) { throw new Exception($"対局者のパースエラー moji4=[{ moji4 }]"); } out_kikiBB = Util_Application.Kiki_BB(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Med_Parser.Moji_Komasyurui(Option_Application.Optionlist.USI, moji3), phase), Med_Parser.FenSujiDan_Masu(Option_Application.Optionlist.USI, moji1, moji2), ky.Shogiban);// komanoUgokikata } else { out_kikiBB = null; } } }
public static List <MoveKakucho> MoveCmd(Kyokumen ky, StringBuilder syuturyoku) { List <MoveKakucho> sslist = new List <MoveKakucho>(); int fukasa = 0; AbstractUtilMoveGen.GenerateMove01(fukasa, ky, MoveType.N21_All, true, syuturyoku);//グローバル変数に指し手がセットされるぜ☆(^▽^) for (int iSs = 0; iSs < AbstractUtilMoveGen.MoveList[fukasa].SslistCount; iSs++) { sslist.Add(new MoveKakuchoImpl(AbstractUtilMoveGen.MoveList[fukasa].ListMove[iSs], AbstractUtilMoveGen.MoveList[fukasa].List_Reason[iSs])); } return(sslist); }
public void Parse(bool isSfen, string[] lines, StringBuilder syuturyoku) { this.Clear(); Kyokumen ky2 = new Kyokumen(); int caret; SeisekiKyokumen josekiKy = null; int gyoBango = 1; foreach (string commandline in lines) { caret = 0; if (caret == commandline.IndexOf("fen ", caret))// fen で始まれば局面データ☆(^▽^) { // キャレットは進めずに続行だぜ☆(^▽^) if (!ky2.ParsePositionvalue(isSfen, commandline, ref caret, false, false, out string moves, syuturyoku)) { string msg = $"パースに失敗だぜ☆(^~^)! #寒鰤 定跡ファイル解析失敗 {gyoBango}]行目"; syuturyoku.AppendLine(msg); Logger.Flush(syuturyoku.ToString()); syuturyoku.Clear(); throw new Exception(msg); } { ky2.Tekiyo(false, syuturyoku); // とりあえず全部作り直し☆(^~^)ルールは変わらないものとするぜ☆(^~^) //ky2.KyokumenHash = ky2.CreateKyokumenHash();//必要最低限、ハッシュだけ適用しておくぜ☆(^▽^) } josekiKy = this.Parse_AddKyLine(commandline, ky2.KyokumenHash.Value, ky2.CurrentOptionalPhase); } else if (commandline.Trim().Length < 1) { // 空行は無視☆ // 半角空白とか、全角空白とか、タブとか 入れてるやつは考慮しないぜ☆(^~^)! } else { // それ以外は手筋☆(^▽^) if (null == josekiKy) { throw new Exception("定跡ファイル解析失敗 定跡局面の指定なし☆"); } josekiKy.AddSasite(ky2, commandline, syuturyoku); } gyoBango++; } }
/// <summary> /// 定跡登録 初期化(ゲームセクション内) /// </summary> public static void Init_JosekiToroku(Kyokumen ky) { IsJosekiTraced = false;//毎回リセット☆(^▽^) KyFen_before = null; KyHash_before = 0; OptionalPhaseBeforeMove = Option <Phase> .None; if (Util_Machine.IsEnableBoardSize() && Option_Application.Optionlist.JosekiRec) { StringBuilder fenMojiretu = new StringBuilder(); ky.AppendFenTo(Option_Application.Optionlist.USI, fenMojiretu); KyFen_before = fenMojiretu.ToString(); KyHash_before = ky.KyokumenHash.Value; OptionalPhaseBeforeMove = ky.CurrentOptionalPhase; } }
/// <summary> /// 人間の番☆ /// </summary> /// <returns></returns> public static bool IsNingenNoBan(Kyokumen ky) { var(exists, phase) = ky.CurrentOptionalPhase.Match; if (exists) { return((phase == Phase.Black && !Option_Application.Optionlist.P1Com) // コンピューターでない場合 || (phase == Phase.White && !Option_Application.Optionlist.P2Com) // コンピューターでない場合 ); } else { return(false); } }
/// <summary> /// コンピューターの番☆ /// </summary> /// <returns></returns> public static bool IsComputerNoBan(Kyokumen ky) { var(exists, phase) = ky.CurrentOptionalPhase.Match; if (exists) { return((phase == Phase.Black && Option_Application.Optionlist.P1Com) // 対局者1でコンピューター☆ || (phase == Phase.White && Option_Application.Optionlist.P2Com) // 対局者2でコンピューター☆ ); } else { return(false); } }
/// <summary> /// 手番の駒 の8近傍を調べて、利きに飛び込んでいたら真顔で真だぜ☆(^▽^) /// </summary> /// <param name="ky"></param> /// <param name="attackerMs">相手の攻撃駒の居場所</param> /// <param name="targetMs">狙っている升</param> /// <returns></returns> public static bool InKiki(Kyokumen ky, Masu attackerMs, Masu targetMs) { var optionalOpponent = Conv_Taikyokusya.Reverse(ky.CurrentOptionalPhase); if (ky.Shogiban.ExistsBBKomaZenbu(optionalOpponent, attackerMs)) // 指定の場所に相手の駒があることを確認 { if (ky.Shogiban.ExistsBBKoma(optionalOpponent, attackerMs, out Komasyurui ks)) // 攻撃側の駒の種類 { return(ky.Shogiban.GetKomanoUgokikata(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, optionalOpponent), attackerMs).IsIntersect( //相手の攻撃駒の利き targetMs //調べる升 )); } } return(false); }
/// <summary> /// 反映するぜ☆(^▽^) /// </summary> /// <param name="ky"></param> /// <param name="mk"></param> /// <param name="ninsyo"></param> public void HaneiMotiKoma(Kyokumen ky, MotiKoma mk) { if (DebugOptions.EvaluationHand) { // 駒の位置(評価関数の項目番号)☆ 持ち駒が 0 枚で、-1 の場合もあり☆ int koumokuNo = Util_NikomaKankei.GetKoumokuBango_MotiKoma(ky, mk); if (-1 != koumokuNo) { Util_NikomaKankei.MakeKoumokuBangoHairetu_Subete(ky, Util_NikomaKankei.KoumokuBangoHairetu1); Increase( Util_NikomaKankei.Kazoeru_NikomaKankeiHyokati_ItiTaiTa_SabunKosinYou(ky, koumokuNo, Util_NikomaKankei.KoumokuBangoHairetu1 ) ); } } }
/// <summary> /// 定跡更新(ゲームセクション内) /// </summary> public static void Update1_JosekiToroku(Move inputMove, Kyokumen ky, StringBuilder syuturyoku) { if (Util_Machine.IsEnableBoardSize() && Option_Application.Optionlist.JosekiRec) { Util_Application.Hyoka(ky, out HyokatiUtiwake hyokatiUtiwake, HyokaRiyu.Yososu, true//ランダムな局面の可能性もあるぜ☆(^~^) ); // 定跡更新☆(^▽^) Option_Application.Joseki.AddMove(KyFen_before, KyHash_before, OptionalPhaseBeforeMove, inputMove, hyokatiUtiwake.EdaBest, // 指した直後の局面の点数 1, //人間は1手読み扱いで☆ Util_Application.VERSION, 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 TukuruKifu(bool isSfen, Kyokumen ky, StringBuilder syuturyoku) { // 指した後の手☆(成績 登録用) Move ss_after = Move.Toryo; // 未使用時の初期値 // 決着から初期局面まで、逆順で戻しながら棋譜を記録するぜ☆(^▽^) int fukasa = 0; while (null != ky.Konoteme.Ittemae) //アンドゥできなくなるまで戻すぜ☆(^▽^) { ss_after = ky.Konoteme.Move; // アンドゥする前に指し手を残しておくぜ☆(^▽^) Option_Application.Kifu.AddFirst(ss_after); ky.UndoMove(isSfen, ss_after, syuturyoku); // 指し手を頼りにアンドゥするぜ☆(^▽^) Util_Application.InLoop_SeisekiKosin(ss_after, ky, syuturyoku); // 成績更新☆(^▽^) fukasa++; } }
/// <summary> /// 差分更新は、対局者1 の視点の盤で行えなんだぜ☆(^▽^) /// </summary> /// <param name="ky"></param> /// <param name="km"></param> /// <param name="ms"></param> /// <param name="fueta"></param> public void FuyasuBanjoKoma(Kyokumen ky, Koma km, Masu ms) { if (DebugOptions.AddPiecesOnBoard) { var optionalPiece = OptionalPiece.From(km); Debug.Assert(Conv_Koma.IsOk(optionalPiece), "");//空白とか禁止☆(^~^)! Util_NikomaKankei.MakeKoumokuBangoHairetu_Subete(ky, Util_NikomaKankei.KoumokuBangoHairetu1); Increase( Util_NikomaKankei.Kazoeru_NikomaKankeiHyokati_ItiTaiTa_SabunKosinYou(ky, Util_NikomaKankei.GetKoumokuBango_Banjo(ky, km, ms),// 駒の位置(評価関数の項目番号)をリストに入れておくぜ☆ Util_NikomaKankei.KoumokuBangoHairetu1 )); } }
public static void Rnd(Kyokumen ky, StringBuilder syuturyoku) { int fukasa = 0; AbstractUtilMoveGen.GenerateMove01(fukasa, ky, MoveType.N21_All, true, syuturyoku);//グローバル変数に指し手がセットされるぜ☆(^▽^) if (AbstractUtilMoveGen.MoveList[fukasa].SslistCount < 1) { Nanteme nanteme = new Nanteme(); ky.DoMove(Option_Application.Optionlist.USI, Move.Toryo, MoveType.N00_Karappo, ref nanteme, ky.CurrentOptionalPhase, syuturyoku); } else { Move ss = AbstractUtilMoveGen.MoveList[fukasa].ListMove[Option_Application.Random.Next(AbstractUtilMoveGen.MoveList[fukasa].SslistCount)]; Nanteme nanteme = new Nanteme(); ky.DoMove(Option_Application.Optionlist.USI, ss, MoveType.N00_Karappo, ref nanteme, ky.CurrentOptionalPhase, syuturyoku); } }