public static bool MatchTaikyokusya(string line, ref int caret, out Taikyokusya out_tai #if DEBUG , IDebugMojiretu hyoji #endif ) { Match m = GetTaikyokusyaPattern(PureSettei.fenSyurui).Match(line, caret); if (m.Success) { string tai_moji = m.Groups[1].Value; if (!Med_Parser.Try_MojiToTaikyokusya(PureSettei.fenSyurui, tai_moji, out out_tai)) { // パースエラーの場合(エラーにはしない) return(false); } // キャレットを進めます Util_String.SkipMatch(line, ref caret, m); return(true); } else { out_tai = Taikyokusya.Yososu; return(false); } }
/// <summary> /// アプリケーション開始時☆ /// アプリケーション設定完了時に呼び出せだぜ☆(^▽^)! /// </summary> public static bool TryFail_Begin2_Application( #if DEBUG IDebugMojiretu reigai1 #endif ) { Face_TimeManager.timeManager.stopwatch_Savefile.Start();// 定跡ファイルの保存間隔の計測 Face_TimeManager.timeManager.stopwatch_RenzokuRandomRule.Start(); // 34将棋の平手初期局面を作るぜ☆(*^~^*)wwww // どうぶつしょうぎの平手初期局面に変更するぜ☆www(^▽^) LisGenkyoku.SetRule( GameRule.DobutuShogi, 3, 4, "キラゾ" + " ヒ " + " ひ " + "ぞらき" , new Dictionary <Motigoma, int>() { { Motigoma.K, 0 }, { Motigoma.Z, 0 }, { Motigoma.H, 0 }, { Motigoma.k, 0 }, { Motigoma.z, 0 }, { Motigoma.h, 0 }, } ); // ゲームモード設定☆ PureAppli.gameMode = GameMode.Karappo; return(Pure.SUCCESSFUL_FALSE); }
public static bool MatchSrcMs(string line, ref int caret, out Masu out_ms #if DEBUG , IDebugMojiretu hyoji #endif ) { Match m = GetSrcMsPattern(PureSettei.fenSyurui).Match(line, caret); if (m.Success) { // キャレットを進めます Util_String.SkipMatch(line, ref caret, m); string ms_moji = m.Groups[1].Value; int caret2 = 0; return(LisMasu.MatchMasu(ms_moji, ref caret2, out out_ms #if DEBUG , hyoji #endif )); } else { out_ms = Conv_Masu.masu_error; return(false); } }
public static bool Try_DoMove_Input(Move ss #if DEBUG , FenSyurui f , IDebugMojiretu dbg_reigai #endif ) { MoveType ssType = MoveType.N00_Karappo; if (DoMoveOpe.TryFailDoMoveAll(ss, ssType #if DEBUG , f , dbg_reigai , false , "Try_DoMove_Input" #endif )) { return(false); } // 手番を進めるぜ☆(^~^) MoveGenAccessor.AddKifu(ss, ssType, PureMemory.dmv_ks_c); //#if DEBUG // Util_Tansaku.Snapshot("Try_DoMove_Input", dbg_reigai); //#endif return(true); }
/// <summary> /// 移動元の盤の升に、手番の駒を戻すぜ☆(^▽^) /// </summary> /// <returns></returns> public static bool TryFail_Tejun2Utu_IdomotoniTebannoKomawoModosu( #if DEBUG FenSyurui dbg_f , IDebugMojiretu dbg_reigai #endif ) { //──────────────────────────────────────── // T0 [1] 移動元に 駒 が無い //──────────────────────────────────────── //──────────────────────────────────────── // T0 [遷移] 移動元に 駒 が現れる☆ //──────────────────────────────────────── { // 今の駒台の駒数は消える ※駒台だけ、このステップが多い PureMemory.gky_ky.motigomaItiran.Fuyasu(PureMemory.umv_mk_t0); // TODO: 駒割り評価値を増やすならここだぜ☆(^~^) } //──────────────────────────────────────── // T0 [2] 移動元に 駒 が在る //──────────────────────────────────────── return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 2017-04-19 作成 /// /// パースに失敗してもエラーではない。 /// </summary> /// <param name="line"></param> /// <param name="caret"></param> /// <param name="out_ms"></param> /// <returns></returns> public static bool MatchMasu (string line, ref int caret, out Masu out_ms #if DEBUG , IDebugMojiretu dbg_reigai #endif ) { Match m = Itiran_FenParser.GetMasuPattern(PureSettei.fenSyurui).Match(line, caret); if (m.Success) { // キャレットを進める Util_String.SkipMatch(line, ref caret, m); int suji = LisInt.FenSuji_Int(PureSettei.fenSyurui, m.Groups[1].Value); int dan = LisInt.FenDan_Int(PureSettei.fenSyurui, m.Groups[2].Value); // 升を返す out_ms = Conv_Masu.ToMasu(suji, dan); return(true); } else { // 該当なし(エラーではない) out_ms = Conv_Masu.masu_error; return(false); } }
/// <summary> /// 移動元の盤の升に、手番の駒を戻すぜ☆(^▽^) /// </summary> /// <returns></returns> public static bool TryFail_Tejun2Sasu_IdomotoniTebannoKomawoModosu( #if DEBUG FenSyurui dbg_f , IDebugMojiretu dbg_reigai #endif ) { //──────────────────────────────────────── // T0 [1] 移動元に 駒 が無い //──────────────────────────────────────── //──────────────────────────────────────── // T0 [遷移] 移動元に 駒 が現れる☆ //──────────────────────────────────────── { // ハッシュを差分更新 if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma(// 手順2 移動元に手番の駒を戻す PureMemory.umv_ms_t0, PureMemory.umv_km_t0, true #if DEBUG , dbg_reigai #endif )) { return(Pure.FailTrue("undo-tj2s gky.ky.shogiban.Try_Oku")); } // TODO: 駒割り評価値を増やすならここだぜ☆(^~^) } //──────────────────────────────────────── // T0 [2] 移動元に 駒 が在る //──────────────────────────────────────── return(Pure.SUCCESSFUL_FALSE); }
public static bool Try_Rnd( #if DEBUG IDebugMojiretu dbg_reigai #endif ) { //グローバル変数に指し手がセットされるぜ☆(^▽^) PureMemory.SetTnskFukasa(PureMemory.FUKASA_MANUAL); MoveGenAccessor.DoMovePickerBegin(MoveType.N21_All); MovePicker01.MovePickerN01(MoveType.N21_All, true); if (PureMemory.ssss_moveList[PureMemory.FUKASA_MANUAL].listCount < 1) { Move ss = Move.Toryo; MoveType ssType = MoveType.N00_Karappo; if (DoMoveOpe.TryFailDoMoveAll(ss, ssType #if DEBUG , PureSettei.fenSyurui , dbg_reigai , false , "Try_Rnd(1)" #endif )) { return(false); } // 手番を進めるぜ☆(^~^) MoveGenAccessor.AddKifu(ss, ssType, PureMemory.dmv_ks_c); //#if DEBUG // Util_Tansaku.Snapshot("Rndコマンド", dbg_reigai); //#endif } else { Move ss = PureMemory.ssss_moveList[PureMemory.FUKASA_MANUAL].moveList[PureSettei.random.Next(PureMemory.ssss_moveList[PureMemory.FUKASA_MANUAL].listCount)]; MoveType ssType = MoveType.N00_Karappo; if (DoMoveOpe.TryFailDoMoveAll(ss, ssType #if DEBUG , PureSettei.fenSyurui , dbg_reigai , false , "Try_Rnd(2)" #endif )) { return(false); } // 手番を進めるぜ☆(^~^) MoveGenAccessor.AddKifu(ss, ssType, PureMemory.dmv_ks_c); //#if DEBUG // Util_Tansaku.Snapshot("Rnd(2)", dbg_reigai); //#endif } return(true); }
/// <summary> /// 移動元の盤の升から、自分の駒を取るぜ☆(^▽^) /// </summary> /// <returns></returns> public static bool TryFail_SrcOff( Move ss, Masu ms_t0, Piece km_t0, Motigoma mk_t0, Masu ms_t1 // 移動先升 #if DEBUG , FenSyurui f , IDebugMojiretu dbg_reigai #endif ) { //──────────────────────────────────────── // T1 [1] 移動元に 手番の駒 が在る //──────────────────────────────────────── //──────────────────────────────────────── // T1 [遷移] 移動元の 手番の駒 を除外する //──────────────────────────────────────── { // TODO: 駒割りを評価値減らすならここだぜ☆(^~^) // FIXME: ここに問題のコードがあった★★★★★★★★★★★★★★★★★★★ } //DoMove1( isSfen, ss, ssType, ref konoTeme, syuturyoku, out gt_EndMethod); // ローカル変数はグローバル変数に移動した。 { // この下の HerasuBanjoKoma で指し手件数が動くようだ。 // 盤上はこのステップが多い Debug.Assert(Conv_Koma.IsOk(km_t0), "km_t0 can not remove"); if (PureMemory.gky_ky.shogiban.TryFail_TorinozokuKoma( ms_t0, km_t0, ms_t1, // (2017-05-02 22:19 Add)移動先の升(将来駒を置く升)を指定しておくぜ☆(^~^) true #if DEBUG , dbg_reigai #endif )) { return(Pure.FailTrue("TryFail_Torinozoku(2)")); } // 駒が無かった、というキャッシュは取らないぜ☆(^▽^) // この上の HerasuBanjoKoma で指し手件数が動くようだ。 } //──────────────────────────────────────── // T1 [2] 移動元に 手番の駒 が無い //──────────────────────────────────────── return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 評価値以外にも、数字のパーサーとしてよく使うぜ☆(^~^) /// </summary> /// <param name="out_restLine"></param> /// <param name="commandline"></param> /// <param name="out_hyokati"></param> /// <returns></returns> public static bool TryParse(string commandline, ref int caret, out int out_hyokati #if DEBUG , IDebugMojiretu reigai1 #endif ) { Match m = Itiran_FenParser.HyokatiPattern.Match(commandline, caret); if (m.Success) { //if(""== m.Groups[1].Value) //{ // //* // // FIXME: // string msg = $"パースに失敗だぜ☆(^~^)! commandline=[{ commandline }]caret({ caret }) .Value=[{ m.Groups[1].Value }] m.Index=[{ m.Index }] m.Length=[{ m.Length }]"; // Util_Machine.AppendLine(msg); // Util_Machine.Flush(); // throw new Exception(msg); // // */ //} // キャレットを進めるぜ☆(^▽^) Util_String.SkipMatch(commandline, ref caret, m); // moji1 = m.Groups[1].Value; if (int.TryParse(m.Groups[1].Value, out out_hyokati)) { return(true); } else { //* // FIXME: #if DEBUG reigai1.AppendLine($"パースに失敗だぜ☆(^~^)! #鱒 commandline=[{ commandline }]caret({ caret }) .Value=[{ m.Groups[1].Value }]"); #endif return(false); // */ } } /* * { * // FIXME: * string msg = $"パースに失敗だぜ☆(^~^)! commandline=[{ commandline }]caret({ caret })"; * Util_Machine.AppendLine(msg); * Util_Machine.Flush(); * throw new Exception(msg); * } * // */ out_hyokati = 0; return(false); }
/// <summary> /// 盤上に駒を置くだけ。 /// /// クリアーしない(もうクリアーしてあるはず)。適用しない。利きを更新しない。 /// </summary> public static bool TryFail_DoHirate_KomaNarabe( FenSyurui f #if DEBUG , IDebugMojiretu reigai1 #endif ) { bool updateKiki = false; // 0 ~ 初期局面升数-1 // FIXME: 本将棋にしても、これが12のままになっている // 初期局面升数 ~ 将棋盤の升数-1 for (int iMs = 0; iMs < PureSettei.banHeimen; iMs++) { if (iMs < HirateShokiKyokumen.banjo.Length) { Piece km = HirateShokiKyokumen.banjo[iMs]; if (Piece.Kuhaku != km) { if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma( (Masu)iMs, km, updateKiki #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Oku")); } } } else { Piece km_remove = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma((Masu)iMs); Debug.Assert(Conv_Koma.IsOk(km_remove), string.Format("km_remove can not remove 初期局面升数={0} 盤上の升数={1}", HirateShokiKyokumen.banjo.Length, PureSettei.banHeimen)); if (PureMemory.gky_ky.shogiban.TryFail_TorinozokuKoma( (Masu)iMs, km_remove, Conv_Masu.masu_error, updateKiki #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Torinozoku(8)")); } } } // ここではまだ、利きチェックは働かない return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 取った駒を、駒台に置くぜ☆(^▽^) /// </summary> /// <returns></returns> public static bool TryFail_DaiOn( Piece km_c,// あれば、移動先の相手の駒(取られる駒; capture) Komasyurui ks_c, Motigoma mk_c #if DEBUG , FenSyurui f , IDebugMojiretu dbg_reigai #endif ) { //──────────────────────────────────────── // 状況: // 移動先に駒があれば……。 //──────────────────────────────────────── #region 駒を取る if (km_c != Piece.Kuhaku) { // 駒取るぜ☆(^▽^)! // ただし、らいおんを除く if (ks_c != Komasyurui.R) // らいおん を取っても、持駒は増えないぜ☆ { //──────────────────────────────────────── // C [1] 取る前の 持ち駒が増える前の 駒台が在る //──────────────────────────────────────── //──────────────────────────────────────── // C [遷移] 取った持ち駒を増やす //──────────────────────────────────────── // 取る前の持ち駒をリカウントする // 増やす PureMemory.gky_ky.motigomaItiran.Fuyasu(mk_c); // TODO: 駒割りを増やすならここだぜ☆(^~^) //──────────────────────────────────────── // C [3] 取った後の 持駒が1つ増えた 駒台が在る //──────────────────────────────────────── } } #endregion return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 駒台から、取った駒を除外するぜ☆(^▽^) /// </summary> /// <returns></returns> public static bool TryFail_Tejun3_KomadaiKaraTottakomawoJogai( #if DEBUG FenSyurui dbg_f , IDebugMojiretu dbg_reigai #endif ) { if (Komasyurui.Yososu != PureMemory.umv_ks_c) { //------------------------------------------------------------ // 取った駒を戻す //------------------------------------------------------------ if (PureMemory.umv_ks_c != Komasyurui.R)// らいおん を盤に戻しても、持駒の数は変わらないぜ☆(^▽^) { //──────────────────────────────────────── // C [1] 取ったあとの 持駒の数 の駒台が在る //──────────────────────────────────────── //──────────────────────────────────────── // C [遷移] 取った 持駒 を除外する //──────────────────────────────────────── // 消して // 増やす MotigomaItiran motiKomaItiranImpl; if (!PureMemory.gky_ky.motigomaItiran.Try_Herasu(out motiKomaItiranImpl, PureMemory.umv_mk_c #if DEBUG , (IDebugMojiretu)dbg_reigai #endif )) { return(Pure.FailTrue("Try_Herasu")); } // TODO: 駒割り評価値を減らすならここだぜ☆(^~^) //──────────────────────────────────────── // C [2] 戻したあとの 持駒の数 の駒台が在る //──────────────────────────────────────── } } return(Pure.SUCCESSFUL_FALSE); }
public bool Try_Herasu(out MotigomaItiran out_ret, Motigoma mk #if DEBUG , IDebugMojiretu reigai1 #endif ) { valueMk[(int)mk]--; #if DEBUG if (valueMk[(int)mk] < 0) { reigai1.AppendLine("error 持駒の数がマイナス"); out_ret = null; return(false); } #endif out_ret = this; return(true); }
/// <summary> /// 移動先の手番の駒を取り除くぜ☆(^▽^) /// </summary> /// <returns></returns> public static bool TryFail_Tejun1_IdosakiNoTebanNoKomaWoTorinozoku( #if DEBUG FenSyurui f , IDebugMojiretu dbg_reigai #endif ) { //──────────────────────────────────────── // T1 [1] 移動先に 手番の駒 が在る //──────────────────────────────────────── //──────────────────────────────────────── // T1 [遷移] 移動先の 手番の駒 を除外する //──────────────────────────────────────── // ハッシュ、駒割、二駒 // TODO:駒割り評価値を減らすならここだぜ☆(^~^) // 駒を取り除く Debug.Assert(Conv_Koma.IsOk(PureMemory.umv_km_t1), "km_t1 can not remove"); if (PureMemory.gky_ky.shogiban.TryFail_TorinozokuKoma( PureMemory.umv_ms_t1, // 移動先の升 PureMemory.umv_km_t1, // 移動先の駒 PureMemory.umv_ms_t0, // 移動元の升 (2017-05-02 22:44 Add) 未来に駒があるのは、元の場所なのでここなんだが☆(^~^)? // 未指定の場合があるが、飛び利きに使ってるだけなんで関係無い☆(^~^) // × ms_t1, // × Sindan.MASU_ERROR, // × ms_t0 true #if DEBUG , dbg_reigai #endif )) { return(Pure.FailTrue("TryFail_Torinozoku(3)")); } //──────────────────────────────────────── // T1 [2] 移動先に 手番の駒 が無い //──────────────────────────────────────── return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 移動元の自分の駒台から、駒を取るぜ☆(^▽^) /// </summary> /// <returns></returns> public static bool TryFail_DaiOff( Masu ms_t0, Piece km_t0, Motigoma mk_t0, Masu ms_t1 // 移動先升 #if DEBUG , FenSyurui f , IDebugMojiretu dbg_reigai #endif ) { //──────────────────────────────────────── // T1 [1] 移動元に 手番の駒 が在る //──────────────────────────────────────── //──────────────────────────────────────── // T1 [遷移] 移動元の 手番の駒 を除外する //──────────────────────────────────────── { MotigomaItiran motiKomaItiranImpl; if (!PureMemory.gky_ky.motigomaItiran.Try_Herasu(out motiKomaItiranImpl, mk_t0 #if DEBUG , (IDebugMojiretu)dbg_reigai #endif )) { return(Pure.FailTrue("do-tj3u gky.ky.motiKomas.Try_Herasu")); } // TODO: 駒割り評価値を減らすならここだぜ☆(^~^) // 駒台はこのステップが1つ多い } //DoMove1( isSfen, ss, ssType, ref konoTeme, syuturyoku, out gt_EndMethod); //──────────────────────────────────────── // T1 [2] 移動元に 手番の駒 が無い //──────────────────────────────────────── return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 盤面の設定☆(^~^) /// /// "キラゾ" /// " ヒ " /// " ひ " /// "ぞらき" /// といった書式で盤上を設定。改行は無視される。 /// /// 駒を取り除く操作はしないぜ☆(^~^) /// </summary> /// <param name="banmen_z1"></param> public static bool TryFail_SetBanjo( string banmen_z1 #if DEBUG , IDebugMojiretu reigai1 #endif ) { banmen_z1 = banmen_z1.Replace("\r", "");//2017-11-07 USI用に追加 banmen_z1 = banmen_z1.Replace("\n", ""); if (banmen_z1.Length != PureSettei.banHeimen) { throw new Exception(string.Format("盤面カナ入力パースエラー 文字数=[{0}] 盤サイズ=[{1}]", banmen_z1.Length, PureSettei.banHeimen)); } for (int iMs = 0; iMs < PureSettei.banHeimen; iMs++) { Piece km; string moji_z1 = banmen_z1.ToCharArray()[iMs].ToString(); if (!LisKoma.TryParse_ZenkakuKanaNyuryoku(moji_z1, out km)) { throw new Exception(string.Format("盤面カナ入力パースエラー ms=[{0}] moji_z1=[{1}]", iMs, moji_z1)); } if (Piece.Kuhaku != km) { if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma( //AddBanjo (Masu)iMs, km, false //利きは更新しないでおく(駒を置くだけ) #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Oku")); } } } return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 移動先の相手番の駒を取るぜ☆(^▽^) /// </summary> /// <returns></returns> public static bool TryFail_DstOff( Masu ms_t1, // 移動先升 Piece km_c, // あれば、移動先の相手の駒(取られる駒; capture) Komasyurui ks_c // 取られた駒の種類 #if DEBUG , FenSyurui f , IDebugMojiretu dbg_reigai #endif ) { // 移動先に駒があるかどうかのチェックは先に終わらせておくこと☆(^~^) //──────────────────────────────────────── // T2C [1] 移動先に 相手の駒 が在る //──────────────────────────────────────── //──────────────────────────────────────── // T2C [遷移] 移動先の 相手の駒 を除外する //──────────────────────────────────────── Debug.Assert(Conv_Koma.IsOk(km_c), "km_c can not remove"); if (PureMemory.gky_ky.shogiban.TryFail_TorinozokuKoma( ms_t1, km_c, Conv_Masu.masu_error, true #if DEBUG , dbg_reigai #endif )) { return(Pure.FailTrue("TryFail_Torinozoku(1)")); } //──────────────────────────────────────── // T2C [2] 移動先に 相手の駒 が無い //──────────────────────────────────────── // ビットボードの駒の数は合っていないからチェックしないぜ☆ return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 移動先に、取った駒を戻すぜ☆(^▽^) /// </summary> /// <returns></returns> public static bool TryFail_Tejun4_IdosakiniTottakomawoModosu( #if DEBUG FenSyurui dbg_f , IDebugMojiretu dbg_reigai #endif ) { if (Komasyurui.Yososu != PureMemory.umv_ks_c) { //──────────────────────────────────────── // T1C [1] 移動先に、取っていた駒が現れる //──────────────────────────────────────── //──────────────────────────────────────── // T1C [遷移] 駒が増える //──────────────────────────────────────── if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma(//手順4 移動先に取った駒を戻す PureMemory.umv_ms_t1, PureMemory.umv_km_c, true #if DEBUG , dbg_reigai #endif )) { return(Pure.FailTrue("gky.ky.shogiban.Try_Oku")); } // TODO: 駒割り評価値を増やすならここだぜ☆(^~^) //──────────────────────────────────────── // T1C [2] //──────────────────────────────────────── } return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 移動先に手番の駒を置くぜ☆(^▽^) /// </summary> /// <returns></returns> public static bool TryFail_DstOn( Masu ms_t0, Piece km_t1, Masu ms_t1 // 移動先升 #if DEBUG , FenSyurui f , IDebugMojiretu dbg_reigai #endif ) { //──────────────────────────────────────── // T2 [1] 移動先に 手番の駒 が無い //──────────────────────────────────────── //──────────────────────────────────────── // T2 [遷移] 移動先に 手番の駒 を増やす //──────────────────────────────────────── // FIXME:(2017-05-02 23:14) if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma(//手順4 移動先に手番の駒を置く ms_t1, km_t1, true #if DEBUG , dbg_reigai #endif )) { return(Pure.FailTrue("gky.ky.shogiban.Try_Oku")); } //──────────────────────────────────────── // T2 [2] 移動先に 手番の駒 が在る //──────────────────────────────────────── return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 盤上の駒を置くぜ☆(^▽^) /// </summary> /// <param name="ms_t1"></param> /// <param name="km_t1"></param> /// <param name="updateKiki">利きを先に作るか、駒を先に並べるか、という循環が発生するのを防ぐために</param> public bool TryFail_OkuKoma( Masu ms_t1, Piece km_t1, bool updateKiki #if DEBUG , IDebugMojiretu reigai1 #endif ) { Debug.Assert(Conv_Koma.IsOk(km_t1), string.Format("置けない駒 km_t1 を置こうとしました。 km_t1={0}", km_t1)); Debug.Assert(Conv_Masu.IsBanjo(ms_t1), string.Format("ms={0}", ms_t1)); // 取り除いた駒は、どちらの対局者の物か☆(^~^) Taikyokusya tai_put = Med_Koma.KomaToTaikyokusya(km_t1); //────────── // とりあえず、盤に駒を置くんだぜ☆(^~^) //────────── OkuKoma(ms_t1, km_t1); //────────── // TODO: 駒が増えた現状に更新する //────────── if (updateKiki) { // 駒の利き割りの評価値を増やすならここで☆(^~^) //────────── // 駒が増えた後の、関連する飛び利きを消す //────────── // 置いた駒がある 縦列きりん、横列きりん、縦列いのしし、左上がりぞう、左下がりぞう を探す foreach (Taikyokusya tai in Conv_Taikyokusya.itiran) { Komasyurui[] ksAr = new Komasyurui[] { Komasyurui.K, Komasyurui.Z, Komasyurui.S, }; foreach (Komasyurui ks in ksAr) { Piece km_reverse = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai); //bbTmp_kiki_forOku.Clear(); BitboardsOmatome.KomanoUgokikataYk00.ToSet_Merge( km_reverse, // 相手番の駒にして、利きを飛ばしてきている位置を調べるのに使う ms_t1, // 升 bbTmp_kiki_forOku // リーガルムーブの盤面を、ここに入れるぜ☆(^~^) ); Masu ms_atk; while (bbTmp_kiki_forOku.Ref_PopNTZ(out ms_atk))// 立っているビットを降ろすぜ☆ { kikiBan.TorinozokuKiki(km_reverse, ms_atk); } } } //* // 利きを増やすぜ☆(^~^) kikiBan.OkuKiki( km_t1, // 駒 ms_t1 // 升 ); //*/ } // TODO: 駒割り評価値を増やすならここだぜ☆(^~^) return(Pure.SUCCESSFUL_FALSE); }
/// <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> /// 指したあとの、次の局面へと更新するぜ☆ /// ハッシュも差分変更するぜ☆ /// /// 手番を進める処理は、分けるぜ☆(^~^) /// </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); }
/// <summary> /// 詰将棋を用意するぜ☆ /// </summary> public static bool Try_TumeShogi(FenSyurui f, int bango, out int out_nantedume #if DEBUG , IDebugMojiretu reigai1 #endif ) { // FIXME: 終わったら元に戻したいが☆(^~^) PureSettei.char_playerN[(int)Taikyokusya.T1] = MoveCharacter.TansakuNomi; PureSettei.char_playerN[(int)Taikyokusya.T2] = MoveCharacter.TansakuNomi; ComSettei.sikoJikan = 60000; // とりあえず 60 秒ぐらい☆ ComSettei.sikoJikanRandom = 0; ComSettei.johoJikan = 0; // 情報全部出すぜ☆ // 詰め手数 + 1 にしないと、詰んでるか判断できないぜ☆(^▽^) //int motonoSaidaiFukasa = Option_Application.Optionlist.SaidaiFukasa; switch (bango) { #region 1手詰め case 0: { out_nantedume = 1; LisGenkyoku.SetRule( GameRule.DobutuShogi, 3, 4, " ラ " + "き ひ" + " ら " + " " , new Dictionary <Motigoma, int>() { { Motigoma.K, 0 }, { Motigoma.Z, 0 }, { Motigoma.H, 1 }, { Motigoma.k, 0 }, { Motigoma.z, 0 }, { Motigoma.h, 0 }, } ); } break; #endregion #region 1手詰め case 1: { out_nantedume = 1; LisGenkyoku.SetRule( GameRule.DobutuShogi, 3, 4, " ラ" + "き " + " ら " + " " , new Dictionary <Motigoma, int>() { { Motigoma.K, 0 }, { Motigoma.Z, 0 }, { Motigoma.H, 0 }, { Motigoma.k, 0 }, { Motigoma.z, 0 }, { Motigoma.h, 0 }, } ); } break; #endregion #region 3手詰め case 2: { out_nantedume = 3; LisGenkyoku.SetRule( GameRule.DobutuShogi, 3, 4, " ゾラ" + " " + "ぞ " + "ら " , new Dictionary <Motigoma, int>() { { Motigoma.K, 0 }, { Motigoma.Z, 1 }, { Motigoma.H, 1 }, { Motigoma.k, 0 }, { Motigoma.z, 0 }, { Motigoma.h, 0 }, } ); } break; #endregion #region 1手詰め case 3: { out_nantedume = 1; LisGenkyoku.SetRule( GameRule.DobutuShogi, 3, 4, " ゾ " + " ぞラ" + "ぞ " + "ら " , new Dictionary <Motigoma, int>() { { Motigoma.K, 0 }, { Motigoma.Z, 0 }, { Motigoma.H, 1 }, { Motigoma.k, 0 }, { Motigoma.z, 0 }, { Motigoma.h, 0 }, } ); } break; #endregion #region 1手詰め default: { out_nantedume = 1; LisGenkyoku.SetRule( GameRule.DobutuShogi, 3, 4, " ラ " + "き き" + " にら" + "ぞひぞ" , new Dictionary <Motigoma, int>() { { Motigoma.K, 0 }, { Motigoma.Z, 0 }, { Motigoma.H, 0 }, { Motigoma.k, 0 }, { Motigoma.z, 0 }, { Motigoma.h, 0 }, } ); } break; #endregion } return(true); }
/// <summary> /// 将棋盤の駒を適当に動かすぜ☆(^▽^)www /// 主にテスト用だぜ☆(^▽^) /// </summary> public static bool TryFail_Mazeru(FenSyurui f #if DEBUG , IDebugMojiretu reigai1 #endif ) { int r; //ランダム値☆ Piece tmpKm; MotigomaItiran motiKomaItiranImpl; //使わない // 盤がでかくなると時間がかかる☆(^~^)最大 1万回で☆(^~^) int nokori = 10000; // 50回もやれば混ざるだろ☆(^▽^) for (int i = 0; i < 50; i++) { int kakuritu = PureSettei.banHeimen + Conv_Motigoma.itiran.Length;//適当☆(^~^) Komasyurui tmpKs; // 盤上にある駒を、別の空き升、あるいは持ち駒に移動するぜ☆(^▽^) for (int iMs1 = 0; iMs1 < PureSettei.banHeimen; iMs1++) { for (int iMs2 = 0; iMs2 < PureSettei.banHeimen; iMs2++) { r = PureSettei.random.Next(kakuritu); if (3 == r || 4 == r || 5 == r || 6 == r)// 確率 { // 位置交換成立☆(^~^)空白同士の交換とか意味ないこともするぜ☆(^▽^) tmpKm = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma((Masu)iMs1); if (3 == r || 5 == r) { if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma(//混ぜる (Masu)iMs1, Conv_Koma.Hanten(PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma((Masu)iMs2)), true #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Oku")); } } else { if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma(//混ぜる (Masu)iMs1, PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma((Masu)iMs2), true #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("Try_Oku")); } } if (4 == r || 5 == r) { if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma(//混ぜる (Masu)iMs2, Conv_Koma.Hanten(tmpKm), true #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("Try_Oku")); } } else { if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma(//混ぜる (Masu)iMs2, tmpKm, true #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("Try_Oku")); } } nokori--; } else if ((1 == r || 2 == r) && PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ExistsKomaZenbu((Masu)iMs1)) { // 持駒交換成立☆(^▽^) Piece km_tmp = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma((Masu)iMs1); tmpKs = Med_Koma.KomaToKomasyurui(km_tmp); //Taikyokusya tai_tmp = Med_Koma.KomaToTaikyokusya(km_tmp); // どちらの持駒にするかはランダムで☆(^~^) Motigoma mk = Med_Koma.KomasyuruiAndTaikyokusyaToMotiKoma(tmpKs, 1 == r ? Taikyokusya.T1 : Taikyokusya.T2); switch (tmpKs) { case Komasyurui.Z: { PureMemory.gky_ky.motigomaItiran.Fuyasu(mk); Piece km_remove = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma((Masu)iMs1); Debug.Assert(Conv_Koma.IsOk(km_remove), "km_remove can not remove"); if (PureMemory.gky_ky.shogiban.TryFail_TorinozokuKoma( (Masu)iMs1, km_remove, Conv_Masu.masu_error, true #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Torinozoku(4)")); } } break; case Komasyurui.K: { PureMemory.gky_ky.motigomaItiran.Fuyasu(mk); Piece km_remove = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma((Masu)iMs1); Debug.Assert(Conv_Koma.IsOk(km_remove), "km_remove can not remove"); if (PureMemory.gky_ky.shogiban.TryFail_TorinozokuKoma( (Masu)iMs1, km_remove, Conv_Masu.masu_error, true #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Torinozoku(5)")); } } break; case Komasyurui.PH: //thru case Komasyurui.H: { PureMemory.gky_ky.motigomaItiran.Fuyasu(mk); Piece km_remove = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma((Masu)iMs1); Debug.Assert(Conv_Koma.IsOk(km_remove), "km_remove can not remove"); if (PureMemory.gky_ky.shogiban.TryFail_TorinozokuKoma( (Masu)iMs1, km_remove, Conv_Masu.masu_error, true #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Torinozoku(6)")); } } break; } nokori--; } } // ひんぱんに、ひよこ/にわとりの入れ替えだぜ☆(^▽^)www { Piece km; r = PureSettei.random.Next(kakuritu); if (r % 5 < 2) { if (PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ExistsKoma(Piece.P1, (Masu)iMs1) || PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ExistsKoma(Piece.P2, (Masu)iMs1)) { if (0 == r) { km = Piece.PP1; } else { km = Piece.PP2; } } else if (PureMemory.gky_ky.shogiban.yomiIbashoBan_yoko.IsOn(Piece.PP1, (Masu)iMs1) || PureMemory.gky_ky.shogiban.yomiIbashoBan_yoko.IsOn(Piece.PP2, (Masu)iMs1)) { if (0 == r) { km = Piece.P1; } else { km = Piece.P2; } } else { km = Piece.Yososu; } if (km != Piece.Yososu) { if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma(// 混ぜる (Masu)iMs1, km, true #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Oku")); } } } } for (int iMk2 = 0; iMk2 < Conv_Motigoma.itiran.Length; iMk2++) { Piece km = Piece.Yososu; r = PureSettei.random.Next(kakuritu); if ((1 == r || 2 == r) && PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ExistsKomaZenbu((Masu)iMs1) && PureMemory.gky_ky.motigomaItiran.yomiMotigomaItiran.HasMotigoma((Motigoma)iMk2)) { // 持駒交換成立☆(^▽^) switch ((Motigoma)iMk2) { case Motigoma.Z: if (!PureMemory.gky_ky.motigomaItiran.Try_Herasu(out motiKomaItiranImpl, Motigoma.Z #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("Try_Herasu")); } if (1 == r) { km = Piece.B1; } else { km = Piece.B2; } break; case Motigoma.K: if (!PureMemory.gky_ky.motigomaItiran.Try_Herasu(out motiKomaItiranImpl, Motigoma.K #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("Try_Herasu")); } if (1 == r) { km = Piece.R1; } else { km = Piece.R2; } break; case Motigoma.H: if (!PureMemory.gky_ky.motigomaItiran.Try_Herasu(out motiKomaItiranImpl, Motigoma.H #if DEBUG , (IDebugMojiretu)reigai1 #endif )) { return(Pure.FailTrue("Try_Herasu")); } if (1 == r) { km = Piece.P1; } else { km = Piece.P2; } break; case Motigoma.z: if (!PureMemory.gky_ky.motigomaItiran.Try_Herasu(out motiKomaItiranImpl, Motigoma.z #if DEBUG , (IDebugMojiretu)reigai1 #endif )) { return(Pure.FailTrue("Try_Herasu")); } if (1 == r) { km = Piece.B2; } else { km = Piece.B1; } break; case Motigoma.k: if (!PureMemory.gky_ky.motigomaItiran.Try_Herasu(out motiKomaItiranImpl, Motigoma.k #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("Try_Herasu")); } if (1 == r) { km = Piece.R2; } else { km = Piece.R1; } break; case Motigoma.h: if (!PureMemory.gky_ky.motigomaItiran.Try_Herasu(out motiKomaItiranImpl, Motigoma.h #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("Try_Herasu")); } if (1 == r) { km = Piece.P2; } else { km = Piece.P1; } break; } if (Piece.Yososu != km) { if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma(//混ぜる (Masu)iMs1, km, true #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Oku")); } } nokori--; } } if (nokori < 0) { break; } } // FIXME: 手番をひっくり返す機能は無いぜ☆(^~^) if (nokori < 0) { break; } } // らいおんの先後を調整するぜ☆(^▽^) { Taikyokusya tb = Taikyokusya.T1; r = PureSettei.random.Next(2); if (0 == r) { tb = Conv_Taikyokusya.Hanten(tb); } for (int iMs1 = 0; iMs1 < PureSettei.banHeimen; iMs1++) { /* * // トライしてたら、位置を変えるぜ☆(^▽^)www * if (Koma.R == this.Komas[iMs1] && Conv_Masu.IsTried(Taikyokusya.T1, (Masu)iMs1)) * { * int iMs2 = iMs1 + 9;//9升足しておくか☆(^▽^)www * tmpKm = this.Komas[iMs1]; * this.Komas[iMs1] = this.Komas[iMs2]; * this.Komas[iMs2] = tmpKm; * } * else if (Koma.r == this.Komas[iMs1] && Conv_Masu.IsTried(Taikyokusya.T2, (Masu)iMs1)) * { * int iMs2 = iMs1 - 9;//9升引いておくか☆(^▽^)www * tmpKm = this.Komas[iMs1]; * this.Komas[iMs1] = this.Komas[iMs2]; * this.Komas[iMs2] = tmpKm; * } */ if (PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ExistsKoma(Piece.K1, (Masu)iMs1) || PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ExistsKoma(Piece.K2, (Masu)iMs1)) { Piece km = Piece.Yososu; if (tb == Taikyokusya.T1) { km = Piece.K1; } else { km = Piece.K2; } if (Piece.Yososu != km) { if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma(//混ぜる (Masu)iMs1, km, true #if DEBUG , reigai1 #endif )) { return(Pure.FailTrue("TryFail_Oku")); } } tb = Conv_Taikyokusya.Hanten(tb); } } } // 駒を配置したあとで使えだぜ☆(^~^) PureMemory.gky_ky.shogiban.Tukurinaosi_RemakeKiki(); return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 例: fen kr1/1h1/1H1/1R1 K2z 1 /// 例: startpos /// /// moves 以降は解析しないが、あれば文字列は返すぜ☆(^~^) /// </summary> /// <param name="line">頭に「fen 」を付けておかないと、パースに失敗する☆</param> /// <returns>解析の成否</returns> public static bool TryFail_MatchPositionvalue( FenSyurui f,//翻訳で切替 string line, ref int caret, out string out_moves #if DEBUG , IDebugMojiretu reigai1 #endif ) { out_moves = ""; Match m = Itiran_FenParser.GetKyokumenPattern(f).Match(line, caret); if (m.Success) { // キャレットを進めるぜ☆(^▽^) Util_String.SkipMatch(line, ref caret, m); // .Value は、該当しないときは空文字列か☆ if (Itiran_FenParser.STARTPOS_LABEL == m.Groups[1].Value) { // 初期局面をセットだぜ☆(^~^) if (TryFail_SetSyokiKyokumen_ByFen( f, Itiran_FenParser.GetStartpos(f).Split('/'), //1~N 段目 Itiran_FenParser.MOTIGOMA_NASI, // 持ち駒 Itiran_FenParser.TAIKYOKUSYA1 #if DEBUG , reigai1 //手番 #endif )) { return(Pure.FailTrue("Try_SetNaiyo(1)")); } } else { // 初期局面をセットだぜ☆(^~^) if (TryFail_SetSyokiKyokumen_ByFen( f, m.Groups[2].Value.Split('/'), //1~N 段目 m.Groups[3].Value, // 持ち駒 m.Groups[4].Value #if DEBUG , reigai1 //手番 #endif )) { return(Pure.FailTrue("Try_SetNaiyo(2)")); } } // TODO: moves if ("" != m.Groups[5].Value) { out_moves = m.Groups[5].Value; } // 初期局面 { tmp_syokikyokumenFen.Clear(); SpkGenkyokuOpe.AppendFenTo(f, tmp_syokikyokumenFen); PureMemory.kifu_syokiKyokumenFen = tmp_syokikyokumenFen.ToString(); } return(Pure.SUCCESSFUL_FALSE); } { // FIXME: #if DEBUG reigai1.AppendLine($"パースに失敗だぜ☆(^~^)! #麒麟 commandline=[{ line }] caret=[{ caret }]"); #endif return(false); } }
/// <summary> /// 初期局面としてセットするぜ☆(^▽^) /// </summary> public static bool TryFail_SetSyokiKyokumen_ByFen( FenSyurui f, string[] danMojiretu, // [0~3]1段目~4段目、[0~2]1筋目~3筋目 string motigoma, string tb_Mojis //手番 #if DEBUG , IDebugMojiretu dbg_reigai #endif ) { PureMemory.gky_ky.Tukurinaosi_ClearKyokumen(); // 持ち駒パース { //PureMemory.gky_ky.motigomaItiran.Clear(); if ("-" != motigoma)// '-' は持ち駒無し { int maisu = 0; for (int caret = 0; caret < motigoma.Length; caret++) { char ch = motigoma[caret]; int numeric; if (int.TryParse(ch.ToString(), out numeric)) { maisu = maisu * 10 + numeric; } else { Motigoma mk; if (!LisMotiKoma.TryParseFen(f, ch, out mk)) { return(Pure.FailTrue("TryParseFen")); } else { // 枚数の指定がなかったとき(=0)は、1。 PureMemory.gky_ky.motigomaItiran.Set(mk, maisu == 0 ? 1 : maisu); maisu = 0; } } } } } // 盤上の升(既にクリアされているものとするぜ☆) int suji; for (int dan = 1; dan <= danMojiretu.Length; dan++) // 1段目~N段目 の順に解析。 { // // "2z" のように、3列を 2桁 で表記しているので、タテ筋のループ・カウントの数え方には注意だぜ☆(^~^) // suji = 1; int ruikeiKuhakuSu = 0; //累計空白数 bool isPowerupKoma = false; //パワーアップ駒(成りゴマ) for (int caret = 0; //caret < 3 && caret < danMojiretu[dan - 1].Length // 可変長配列☆ ; caret++) { char moji = danMojiretu[dan - 1][caret]; int kuhaku; if ('+' == moji) { isPowerupKoma = true; } else if (int.TryParse(moji.ToString(), out kuhaku)) { // 数字は空き升の個数なので、筋を進めるぜ☆(^▽^) // とりあえず 1~9 まで対応できるだろうなんだぜ☆(^~^) //for (int i = 0; i < kuhaku; i++) //{ ruikeiKuhakuSu = ruikeiKuhakuSu * 10 + kuhaku; //} //Mojiretu reigai1 = new StringBuilder(); //reigai1.AppendLine($"未定義の空白の数 moji=[{moji}]"); //reigai1.AppendLine($"dan =[{dan}]"); //reigai1.AppendLine($"caret =[{caret}]"); //reigai1.AppendLine($"danMojiretu[dan-1] =[{danMojiretu[dan - 1]}]"); //throw new Exception(reigai1.ToContents()); } else { // 駒でした。 if (0 < ruikeiKuhakuSu) { // 空白は置かなくていいのでは? //Masu ms = Conv_Masu.ToMasu(suji, dan); //Koma km_actual = GetBanjoKoma(ms); //HerasuBanjoKoma(ms, km_actual, true); suji += ruikeiKuhakuSu; ruikeiKuhakuSu = 0; } Piece tmp; if (!LisKoma.Try_ParseFen(f, (isPowerupKoma ? $"+{moji}" : moji.ToString()), out tmp)) { #if DEBUG Pure.Sc.AddErr(string.Format("SetNaiyoで未定義の駒が指定されました。 fen moji=[{0}]", moji)); #endif return(Pure.FailTrue("Try_ParseFen")); } isPowerupKoma = false; if (PureMemory.gky_ky.shogiban.TryFail_OkuKoma(//SetNaiyo Conv_Masu.ToMasu(suji, dan), tmp, true #if DEBUG , dbg_reigai #endif )) { return(Pure.FailTrue("TryFail_Oku")); } // あとで適用 suji += 1; } } if (0 < ruikeiKuhakuSu) { // 空白は置かなくていいのでは? //Masu ms = Conv_Masu.ToMasu(suji, dan); //HerasuBanjoKoma(ms, GetBanjoKoma(ms), true); suji += ruikeiKuhakuSu; ruikeiKuhakuSu = 0; } } // 手番 { Taikyokusya syokikyokumenTai; if (!Med_Parser.Try_MojiToTaikyokusya(f, tb_Mojis, out syokikyokumenTai)) { #if DEBUG dbg_reigai.AppendLine(string.Format("SetNaiyoで未定義の手番が指定されたんだぜ☆ isSfen={0} 入力={1} 出力={2}", f, tb_Mojis, syokikyokumenTai )); //reigai1.AppendLine($"ky.Teban=[{PureMemory.gky_ky.yomiKy.teban}]"); //reigai1.AppendLine($"BanTateHaba=[{PureSettei.banTateHaba}]"); dbg_reigai.AppendLine(string.Format("持ち駒数一覧({0}件)", danMojiretu.Length)); foreach (Motigoma mk in Conv_Motigoma.itiran) { dbg_reigai.AppendLine(string.Format("{0}={1}", mk, PureMemory.gky_ky.motigomaItiran.yomiMotigomaItiran.Count(mk))); } #endif return(Pure.FailTrue("Try_Taikyokusya")); //throw new Exception($"対局者のパースエラー tb_Mojis=[{tb_Mojis}]{reigai1.ToContents()}"); } // 先手番始まりか、後手番始まりか、に合わせるぜ☆(^~^) PureMemory.ResetTebanArray(syokikyokumenTai); // 手番には 1 が入っていると思うんだが、無視して 0 スタートに固定するぜ☆(^~^) // PureMemory.ClearTeme(); } return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 盤上の駒を取り除く。 /// /// よくある問題 /// ────── /// /// (1)きりんA の右上に きりんB を打つ。 /// (2)きりんB を取り除く。 /// (3)このとき、きりんB の利きも取り除くが、きりんA と被っている利きもある。 /// これを消してしまうと、利きが欠けた きりんA ができてしまい、整合性が取れない。 /// /// </summary> /// <param name="ms_ibasho">取り除く駒がある升</param> /// <param name="km_remove">取り除く駒</param> /// <param name="ms_mirainihaKomagaAru">(飛び利き更新用)</param> /// <param name="updateKiki">偽にすると、利きを更新しません</param> /// <param name="yomiGky"></param> /// <param name="reigai1"></param> /// <returns></returns> public bool TryFail_TorinozokuKoma( Masu ms_ibasho, Piece km_remove, Masu ms_mirainihaKomagaAru, bool updateKiki #if DEBUG , IDebugMojiretu reigai1 #endif ) { Debug.Assert(Conv_Koma.IsOk(km_remove), "km_remove not ok"); Debug.Assert(Conv_Masu.IsBanjo(ms_ibasho), ""); // 取り除いた駒は、どちらの対局者の物か☆(^~^) Taikyokusya tai_removed = Med_Koma.KomaToTaikyokusya(km_remove); //──────────────────────────────────────── // (1)利き表をいじる前☆(^▽^) //──────────────────────────────────────── //────────── // とりあえず、駒を取り除いた状態にするぜ☆(^~^) //────────── TorinozokuKoma(ms_ibasho, km_remove); //────────── // 駒が取り除かれた現状に更新する //────────── if (updateKiki) { // 駒の利き割りの評価値を減らすならここで☆(^~^) kikiBan.TorinozokuKiki(km_remove, ms_ibasho); //────────── // 駒が減った後の、関連する飛び利きを増やす //────────── // 置いた駒がある 縦列きりん、横列きりん、縦列いのしし、左上がりぞう、左下がりぞう を探す foreach (Taikyokusya tai in Conv_Taikyokusya.itiran) { Komasyurui[] ksAr = new Komasyurui[] { Komasyurui.K, Komasyurui.Z, Komasyurui.S, }; foreach (Komasyurui ks in ksAr) { Piece km_forReverse = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai); BitboardsOmatome.KomanoUgokikataYk00.ToSet_Merge( km_forReverse, // 相手番の駒にして、利きを飛ばしてきている位置を調べるのに使う ms_ibasho, // 升 bbTmp_kiki_forOku // リーガルムーブの盤面を、ここに入れるぜ☆(^~^) ); Masu ms_atk; while (bbTmp_kiki_forOku.Ref_PopNTZ(out ms_atk))// 立っているビットを降ろすぜ☆ { kikiBan.OkuKiki(km_forReverse, ms_atk); } } } } return(Pure.SUCCESSFUL_FALSE); }