/// <summary> /// 駒別の居場所 /// </summary> /// <param name="hyoji"></param> static void AppendKomaBetuIbashoTo(IbashoBan.YomiIbashoBan yomiIbashoBan, StringBuilder hyoji) { hyoji.AppendLine("駒別の居場所"); foreach (Taikyokusya tai in Conv_Taikyokusya.itiran)// 対局者1、対局者2 { // 駒別 foreach (Piece km_tai in Conv_Koma.itiranTai[(int)tai]) { hyoji.Append(SpkBanWaku.CutHeaderBanWidthZenkaku(Conv_Koma.GetName(km_tai))); } hyoji.AppendLine(); // 盤 YomiBitboard[] bbHairetu = new YomiBitboard[Conv_Komasyurui.itiran.Length]; int i = 0; foreach (Komasyurui ks in Conv_Komasyurui.itiran) { bbHairetu[i] = yomiIbashoBan.GetKoma(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai)); i++; } SpkBan_MultiColumn.Setumei_Bitboard(null, bbHairetu, " 〇 ", " ", hyoji); } }
/// <summary> /// 桂馬跳び左 /// </summary> /// <param name="ms"></param> /// <param name="tb"></param> /// <returns></returns> static void TasuKeimatobiHidari(Piece km, Masu ms) { Taikyokusya tai = Med_Koma.KomaToTaikyokusya(km); if (!BitboardsOmatome.YomiBitboardsOmatome.IsIntersect_UsagigaHidariniToberu(tai, ms)) { switch (tai) { case Taikyokusya.T1: { Masu ms_tmp = ms - 2 * PureSettei.banYokoHaba - 1; if (Conv_Masu.IsBanjo(ms_tmp)) { BitboardsOmatome.KomanoUgokikataYk00.StandupElement(km, ms, ms_tmp); } } break; case Taikyokusya.T2: { Masu ms_tmp = ms + 2 * PureSettei.banYokoHaba + 1; if (Conv_Masu.IsBanjo(ms_tmp)) { BitboardsOmatome.KomanoUgokikataYk00.StandupElement(km, ms, ms_tmp); } } break; default: break; } } }
/// <summary> /// 駒の利き /// </summary> /// <param name="bbItiran_kikiZenbu"></param> /// <param name="bbItiran_kikiKomabetu"></param> /// <param name="hyoji"></param> public static void HyojiKomanoKiki(KikiBan.YomiKikiBan yomiKikiBan, StringBuilder hyoji) { Debug.Assert(yomiKikiBan.IsActiveBBKiki(), ""); // 対局者別 { hyoji.AppendLine("利き(対局者別)"); YomiBitboard[] bbHairetu = new YomiBitboard[Conv_Taikyokusya.itiran.Length]; foreach (Taikyokusya tai in Conv_Taikyokusya.itiran) { bbHairetu[(int)tai] = new YomiBitboard(yomiKikiBan.CloneBBKikiZenbu(tai)); } SpkBan_MultiColumn.Setumei_Bitboard(Conv_Taikyokusya.namaeItiran, bbHairetu, " + ", " ", hyoji); } // 駒別 { hyoji.AppendLine("利き(駒別)"); foreach (Taikyokusya tai in Conv_Taikyokusya.itiran)// 対局者1、対局者2 { // 盤上 YomiBitboard[] bbHairetu = new YomiBitboard[Conv_Komasyurui.itiran.Length]; foreach (Komasyurui ks in Conv_Komasyurui.itiran) { bbHairetu[(int)ks] = new YomiBitboard(yomiKikiBan.CloneBBKiki(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai))); } SpkBan_MultiColumn.Setumei_Bitboard(Med_Koma.GetKomasyuruiNamaeItiran(tai), bbHairetu, " + ", " ", hyoji); } } }
/// <summary> /// 指し手生成の開始時に呼び出されるぜ☆(^~^) /// </summary> /// <param name="gky"></param> public static void Tukurinaosi() { // らいおんの場所(らいおんは0~1匹という前提) foreach (Taikyokusya tai in Conv_Taikyokusya.itiran) { Masu ms_tmp; if (PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetNTZ(Med_Koma.ToRaion(tai), out ms_tmp)) { PureMemory.hot_ms_raionAr[(int)tai] = ms_tmp;// ここに、らいおんのマスを覚えておくぜ☆(^~^) // <編集> // ライオンの利き=8近傍 BitboardsOmatome.KomanoUgokikataYk00.ToSet_Merge( Med_Koma.ToRaion(tai), PureMemory.hot_ms_raionAr[(int)tai], PureMemory.hot_bb_raion8KinboAr[(int)tai]// ここに、らいおんの8近傍を覚えておくぜ☆(^~^) ); } else { // らいおんがいない場合 PureMemory.hot_ms_raionAr[(int)tai] = Conv_Masu.masu_error; PureMemory.hot_bb_raion8KinboAr[(int)tai].Clear(); } } // 手番側が、王手回避が必要かどうか調べたいぜ☆(^~^) Tukurinaosi_1(PureMemory.kifu_teban, PureMemory.kifu_aiteban, false); // 相手番側が、王手回避が必要かどうか調べたいぜ☆(^~^) Tukurinaosi_1(PureMemory.kifu_aiteban, PureMemory.kifu_teban, true);//手番を ひっくり返す }
/// <summary> /// この左上 /// </summary> /// <param name="ms"></param> /// <param name="tb"></param> /// <returns></returns> static void TasuKonoHidariue(Piece km, Masu ms) { switch (Med_Koma.KomaToTaikyokusya(km)) { case Taikyokusya.T1: if (!BitboardsOmatome.YomiBitboardsOmatome.IsIntersect_UeHajiDan(ms) && !BitboardsOmatome.YomiBitboardsOmatome.IsIntersect_HidariHajiSuji(ms)) { Masu ms_tmp = ms - PureSettei.banYokoHaba - 1; if (Conv_Masu.IsBanjo(ms_tmp)) { BitboardsOmatome.KomanoUgokikataYk00.StandupElement(km, ms, ms_tmp); } } break; case Taikyokusya.T2: if (!BitboardsOmatome.YomiBitboardsOmatome.IsIntersect_SitaHajiDan(ms) && !BitboardsOmatome.YomiBitboardsOmatome.IsIntersect_MigiHajiSuji(ms)) { Masu ms_tmp = ms + PureSettei.banYokoHaba + 1; if (Conv_Masu.IsBanjo(ms_tmp)) { BitboardsOmatome.KomanoUgokikataYk00.StandupElement(km, ms, ms_tmp); } } break; default: break; } }
/// <summary> /// 一手詰めの局面かどうか調べるぜ☆(^▽^) /// /// 自分が一手詰めを掛けられるから、この指し手は作らないでおこう、といった使い方がされるぜ☆(^▽^) /// /// FIXME: 持ち駒の打ちにも使えないか☆(^~^)? /// </summary> /// <param name="fukasa"></param> /// <param name="ky2"></param> /// <param name="ms_src">持ち駒の場合、エラー値</param> /// <param name="mks">持ち駒の場合、持駒の種類</param> /// <param name="ms_t1"></param> /// <param name="tebanHioute"></param> /// <returns></returns> public static bool CheckBegin_Ittedume_MotiKoma() { if (!PureSettei.ittedumeTukau) { return(false); } if (!Conv_Motigoma.IsOk(PureMemory.ssss_mot_mg)) { throw new Exception("持ち駒じゃないじゃないか☆(^▽^)www"); } // A B C // ┌──┬──┬──┐ //1│ │▽ら│ │ // ├──┼──┼──┤ //2│▲き│ │▲き│ // ├──┼──┼──┤ //3│ │▲に│▲ら│ // ├──┼──┼──┤ //4│▲ぞ│▲ひ│▲ぞ│ // └──┴──┴──┘ // 盤上の駒を動かすのか、駒台の駒を打つのかによって、利き の形が異なるぜ☆(^~^) Bitboard bb_kiki_t1 = BitboardsOmatome.KomanoUgokikataYk00.Clone_Merge(Med_Koma.MotiKomaToKoma(PureMemory.ssss_mot_mg), PureMemory.ssss_ugoki_ms_dst); if (!PureMemory.gky_ky.shogiban.yomiIbashoBan_yoko.IsIntersect(Med_Koma.ToRaion(PureMemory.kifu_aiteban), // 相手らいおんの場所☆ bb_kiki_t1)) // 相手らいおん が、動かした駒の、利きの中に居ないんだったら、一手詰め にはならないぜ☆(^~^) { // FIXME: ステイルメイトは考えてないぜ☆(>_<) return(false); } Piece km_t1 = Med_Koma.MotiKomaToKoma(PureMemory.ssss_mot_mg);//t0も同じ // FIXME: ↓駒移動後の、利きを取る必要がある Bitboard bb_kikiNewJibun = new Bitboard(); { // 打による、重ね利きの数を差分更新するぜ☆(^▽^) //, ky.BB_KikiZenbu // 移動先の駒の利きを増やすぜ☆(^▽^) PureMemory.gky_ky.shogiban.kikiBan.OkuKiki(km_t1, PureMemory.ssss_ugoki_ms_dst); // こっちの利きを作り直し bb_kikiNewJibun = PureMemory.gky_ky.shogiban.kikiBan.RefBB_FromKikisuZenbuPositiveNumber(Med_Koma.MotiKomaToTaikyokusya(PureMemory.ssss_mot_mg)); // 打による、重ね利きの数の差分更新を元に戻すぜ☆(^▽^) // 移動先の駒の利きを減らすぜ☆(^▽^) PureMemory.gky_ky.shogiban.kikiBan.TorinozokuKiki(km_t1, PureMemory.ssss_ugoki_ms_dst); } // 相手らいおんが逃げようとしていて。 Bitboard bb1 = PureMemory.hot_bb_raion8KinboAr[PureMemory.kifu_nAiteban].Clone(); // 相手らいおんの8近傍 PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_aiteban, bb1); // 相手の駒がない升 return (bb1.Sitdown(bb_kikiNewJibun) // こっちの利きがない升 .IsEmpty()); // 相手らいおん が逃げれる升がない場合、詰み☆ }
/// <summary> /// 駒の利き数☆(^~^) /// 対局者別と、駒別 /// </summary> /// <returns></returns> public static void HyojiKomanoKikiSu(KikiBan.YomiKikiBan yomiKikiBan, StringBuilder hyoji) { hyoji.AppendLine("重ね利き数全部"); hyoji.AppendLine(string.Format("差分更新トータル ▲{0} △{1}", yomiKikiBan.CountKikisuTotalZenbu(Taikyokusya.T1), yomiKikiBan.CountKikisuTotalZenbu(Taikyokusya.T2))); // 対局者別 全部 { // 見出し SpkBanWaku.Setumei_Headers(Conv_Taikyokusya.namaeItiran, hyoji); SpkBanWaku.AppendLine_TopBar(Conv_Taikyokusya.itiran.Length, PureSettei.banYokoHaba, hyoji); // ┌──┬──┬──┐みたいな線☆ for (int dan = 0; dan < PureSettei.banTateHaba; dan++) { // データ表示 SpkBanWaku.AppendLine_Record_Cell4Hankakus1( (Taikyokusya tai, Masu ms) => { int kikisuZenbu = yomiKikiBan.CountKikisuZenbu(tai, ms); return(0 < kikisuZenbu ? string.Format(" {0,2} ", kikisuZenbu) : " "); }, dan, hyoji ); if (dan + 1 < PureSettei.banTateHaba) { SpkBanWaku.AppendLine_MiddleBar(Conv_Taikyokusya.itiran.Length, PureSettei.banYokoHaba, hyoji); // ├──┼──┼──┤みたいな線☆ } } SpkBanWaku.AppendLine_BottomBar(Conv_Taikyokusya.itiran.Length, PureSettei.banYokoHaba, hyoji); // └──┴──┴──┘みたいな線☆ } // 駒別 foreach (Taikyokusya tai in Conv_Taikyokusya.itiran) // 対局者1、対局者2 { foreach (Piece km_tai in Conv_Koma.itiranTai[(int)tai]) { hyoji.Append(SpkBanWaku.CutHeaderBanWidthZenkaku(Conv_Koma.GetName(km_tai))); } hyoji.AppendLine(); SpkBanWaku.AppendLine_TopBar(Conv_Komasyurui.itiran.Length, PureSettei.banYokoHaba, hyoji); for (int dan = 0; dan < PureSettei.banTateHaba; dan++) { SpkBanWaku.AppendLine_Record_Cell4Hankakus3( (Taikyokusya tai1, Komasyurui ks, Masu ms) => { int kikisuKomabetu = yomiKikiBan.CountKikisuKomabetu(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai1), ms); return(0 < kikisuKomabetu ? string.Format(" {0,2} ", kikisuKomabetu) : " "); }, tai, dan, hyoji); if (dan + 1 < PureSettei.banTateHaba) { SpkBanWaku.AppendLine_MiddleBar(Conv_Komasyurui.itiran.Length, PureSettei.banYokoHaba, hyoji); } } SpkBanWaku.AppendLine_BottomBar(Conv_Komasyurui.itiran.Length, PureSettei.banYokoHaba, hyoji); } }
/// <summary> /// 利き /// </summary> /// <param name="yomiKy"></param> /// <param name="tai"></param> /// <param name="hyoji"></param> public static void Setumei_GenkoKiki(Taikyokusya tai, StringBuilder hyoji) { hyoji.AppendLine("利き:(現行)"); SpkBan_MultiColumn.Setumei_Bitboard( Med_Koma.GetKomasyuruiNamaeItiran(tai), PureMemory.gky_ky.yomiKy.yomiShogiban.yomiKikiBan.GetBB_WhereKiki(tai), " + ", " ", hyoji ); }
public static void BunkaiMoveUmv() { PureMemory.umv_ss = PureMemory.kifu_moveArray[PureMemory.kifu_endTeme]; // 駒がないところを指していることがないか? PureMemory.umv_ms_t1 = AbstractConvMove.GetDstMasu_WithoutErrorCheck((int)PureMemory.umv_ss); PureMemory.umv_km_t1 = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma(PureMemory.umv_ms_t1); PureMemory.umv_ks_t1 = Med_Koma.KomaToKomasyurui(PureMemory.umv_km_t1);// 成っているかもしれない☆ Debug.Assert(Conv_Masu.IsBanjoOrError(PureMemory.umv_ms_t1), "error Undo-Begin-6"); Debug.Assert(Conv_Koma.IsOk(PureMemory.umv_km_t1), "error Undo-Begin-7"); if (!AbstractConvMove.IsUtta(PureMemory.umv_ss)) // 指す { PureMemory.umv_ms_t0 = AbstractConvMove.GetSrcMasu_WithoutErrorCheck((int)PureMemory.umv_ss); // 戻し先。 Debug.Assert(Conv_Masu.IsBanjo(PureMemory.umv_ms_t0), "error Undo-Begin-21 #金魚 戻し先が盤上でない?"); PureMemory.umv_mk_t0 = Motigoma.Yososu; if (AbstractConvMove.IsNatta(PureMemory.umv_ss)) // 成っていたとき { PureMemory.umv_ks_t0 = Conv_Komasyurui.ToNarazuCase(PureMemory.umv_ks_t1); // 成る前 } else { PureMemory.umv_ks_t0 = PureMemory.umv_ks_t1;// 成る前、あるいは、成っていない、あるいは もともと にわとり☆ } PureMemory.umv_km_t0 = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(PureMemory.umv_ks_t0, PureMemory.kifu_teban); Debug.Assert(Conv_Koma.IsOk(PureMemory.umv_km_t0), "error Undo-Begin-9 #羊"); Debug.Assert(Conv_Masu.IsBanjoOrError(PureMemory.umv_ms_t0), "error Undo-Begin-8 #颪"); } else// 打つ { PureMemory.umv_ms_t0 = Conv_Masu.masu_error; PureMemory.umv_km_t0 = Piece.Yososu; PureMemory.umv_ks_t0 = Komasyurui.Yososu; PureMemory.umv_mk_t0 = Med_Koma.KomasyuruiAndTaikyokusyaToMotiKoma(PureMemory.umv_ks_t1, PureMemory.kifu_teban); } PureMemory.umv_ks_c = PureMemory.kifu_toraretaKsAr[PureMemory.kifu_endTeme]; if (Komasyurui.Yososu != PureMemory.umv_ks_c) { PureMemory.umv_km_c = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(PureMemory.umv_ks_c, PureMemory.kifu_aiteban); PureMemory.umv_mk_c = Med_Koma.BanjoKomaToMotiKoma(PureMemory.umv_km_c); Debug.Assert(Conv_Koma.IsOk(PureMemory.umv_km_c), "error Undo-Begin-10 #竜巻"); } else { PureMemory.umv_km_c = Piece.Yososu; PureMemory.umv_mk_c = Motigoma.Yososu; } }
/// <summary> /// トライしていれば真☆ /// </summary> /// <returns></returns> public static bool IsTried(Taikyokusya ts) { Piece km = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Komasyurui.R, ts); switch (ts) { case Taikyokusya.T1: return(PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.ToIsIntersect_Koma(km, BitboardsOmatome.bb_danArray[0])); case Taikyokusya.T2: return(PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.ToIsIntersect_Koma(km, BitboardsOmatome.bb_danArray[PureSettei.banTateHaba - 1])); default: throw new Exception("未定義の手番"); } }
public static bool SetSsssMotMks_AndHasMotigoma(MotigomaSyurui val) { ssss_mot_mks_ = val; ssss_mot_mg_ = Med_Koma.MotiKomasyuruiAndTaikyokusyaToMotiKoma(val, kifu_teban); if (gky_ky.motigomaItiran.yomiMotigomaItiran.HasMotigoma(ssss_mot_mg_)) { // 持ち駒を持っているときだけセットするぜ☆(^~^) ssss_mot_km_ = Med_Koma.MotiKomasyuruiAndTaikyokusyaToKoma(ssss_mot_mks_, kifu_teban); ssss_mot_ks_ = Med_Koma.MotiKomasyuruiToKomasyrui(ssss_mot_mks_); return(true); } return(false); }
/// <summary> /// 二歩防止 /// </summary> public static void SiborikomiByNifu() { bbTmp_nifu.Clear(); Piece hiyoko = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Komasyurui.H, PureMemory.kifu_teban); for (int iSuji = 0; iSuji < PureSettei.banYokoHaba; iSuji++) { PureMemory.gky_ky.shogiban.yomiIbashoBan_yoko.ToSet_Koma(hiyoko, bbTmp_nifu); //自分の歩 bbTmp_nifu.Siborikomi(BitboardsOmatome.bb_sujiArray[iSuji]); //調べる筋だけ残す if (!bbTmp_nifu.IsEmpty()) { PureMemory.ssss_bbVar_idosaki_narazu.Sitdown(BitboardsOmatome.bb_sujiArray[iSuji]); } } }
/// <summary> /// タダ捨ての動き /// </summary> /// <param name="ky2"></param> /// <param name="tai1"></param> /// <param name="ms_src"></param> /// <param name="ms_dst"></param> /// <param name="da">打の場合</param> /// <returns></returns> public static bool TadasuteNoUgoki() { // 主なケース // ・移動先の升には、味方の利き(動かす駒の利き除く)がない。 // ・敵の利きに指す、打ち込む // タダ捨ての特殊なケース // // ・移動先の升は 空白☆ // ・移動先の升には、手番らいおん の利きがある☆(味方の利きはあるが、それが らいおん だった場合☆) // ・移動先の升には、相手番の駒の 重ね利きが 2つ以上ある☆ // // これはタダ捨てになる☆ らいおんでは取り返せないので☆ // 「らいおんの利きを除いた利きビットボード」とかあれば便利だろうか☆(>_<)? // if (PureMemory.gky_ky.shogiban.kikiBan.yomiKikiBan.ExistsKikiZenbu(PureMemory.kifu_aiteban, PureMemory.ssss_ugoki_ms_dst)) // 相手の利きがあるところに放り込む { // 移動先の升の、味方の重ね利き の数(これから動かす駒を除く) int kiki_ts1 = PureMemory.gky_ky.shogiban.kikiBan.yomiKikiBan.CountKikisuZenbu(PureMemory.kifu_teban, PureMemory.ssss_ugoki_ms_dst); if (!PureMemory.ssss_ugoki_kakuteiDa) { // 「指」だと、自分の利きの数はカウントしないぜ☆(^▽^)wwwこれから動くからな☆(^▽^)wwww // 「打」だと、数字を-1してはいけないぜ☆ kiki_ts1--; } int kiki_ts2 = PureMemory.gky_ky.shogiban.kikiBan.yomiKikiBan.CountKikisuZenbu(PureMemory.kifu_aiteban, PureMemory.ssss_ugoki_ms_dst); if (0 == kiki_ts1 && 0 < kiki_ts2)//味方の利きがなくて、敵の利きがあれば、タダ捨てだぜ☆(^▽^)www { return(true); } if (1 == kiki_ts1 && 1 < kiki_ts2//味方の利きがあり、敵の利きが2以上あり、 && //その味方はらいおんだった場合、タダ捨てだぜ☆(^▽^)www PureMemory.gky_ky.shogiban.kikiBan.yomiKikiBan.ExistsBBKiki(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Komasyurui.R, PureMemory.kifu_teban), PureMemory.ssss_ugoki_ms_dst) ) { return(true); } } return(false); }
/// <summary> /// 手番の駒 の8近傍を調べて、利きに飛び込んでいたら真顔で真だぜ☆(^▽^) /// </summary> /// <param name="gky"></param> /// <param name="ms_attacker">相手の攻撃駒の居場所</param> /// <param name="ms_target">狙っている升</param> /// <returns></returns> public static bool IsTobikondaKiki(Taikyokusya irekaeAiteban, Masu ms_attacker, Masu ms_target) { if (PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.ExistsKomaZenbu(irekaeAiteban, ms_attacker)) // 攻撃を仕掛けてくるだろう場所(attackerMs)に相手の駒があることを確認 { Komasyurui ks; if (PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.ExistsKoma(irekaeAiteban, ms_attacker, out ks))// 駒があれば、その駒の種類を確認 { Piece km_attacker = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, irekaeAiteban); // 相手の攻撃駒の利き // ここで飛び利きを判定できるか? return(BitboardsOmatome.KomanoUgokikataYk00.IsIntersect( km_attacker, // 王手してくる駒 ms_attacker, // その駒がいる升 ms_target // 調べている升(王手されている升) )); } } return(false); }
/// <summary> /// 駒の動き☆ /// </summary> /// <param name="komanoUgokikata"></param> /// <param name="hyoji"></param> public static void HyojiKomanoUgoki(KikiBan.YomiKikiBan yomiKikiBan, int masuYososu, StringBuilder hyoji) { for (int ms = 0; ms < masuYososu; ms++) { hyoji.AppendLine($"ます{ ms}"); foreach (Taikyokusya tai in Conv_Taikyokusya.itiran) { // 盤上 YomiBitboard[] bbHairetu = new YomiBitboard[Conv_Komasyurui.itiran.Length]; foreach (Komasyurui ks in Conv_Komasyurui.itiran) { bbHairetu[(int)ks] = new YomiBitboard(BitboardsOmatome.KomanoUgokikataYk00.Clone_Merge( Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai), (Masu)ms)); } SpkBan_MultiColumn.Setumei_Bitboard(Med_Koma.GetKomasyuruiNamaeItiran(tai), bbHairetu, " + ", " ", hyoji); hyoji.AppendLine(); } } }
/// <summary> /// 指定の升にいる駒を除く、味方全部の利き☆ /// /// 盤上の駒を指す場合、自分自身が動いてしまうので利きが変わってしまうので、 /// 全部の利きを合成したBBが使えないので、代わりにこの関数を使うんだぜ☆(^~^) /// </summary> /// <param name="ky"></param> /// <param name="ms_nozoku">除きたい駒がいる升</param> /// <returns></returns> public static Bitboard CreateBBTebanKikiZenbu_1KomaNozoku(Masu ms_nozoku) { Bitboard kikiZenbuBB = new Bitboard(); // 味方の駒(変数使いまわし) Bitboard mikataBB = new Bitboard(); foreach (Komasyurui ks in Conv_Komasyurui.itiran) { Piece km_teban = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, PureMemory.kifu_teban); PureMemory.gky_ky.shogiban.yomiIbashoBan_yoko.ToSet_Koma(km_teban, mikataBB); Masu ms; while (mikataBB.Ref_PopNTZ(out ms)) { if (ms_nozoku != ms)//この駒を除く { BitboardsOmatome.KomanoUgokikataYk00.ToStandup_Merge(km_teban, ms, kikiZenbuBB); } } } return(kikiZenbuBB); }
/// <summary> /// 局面(駒の配置)の一致判定だぜ☆(^▽^) /// /// 重い処理がある☆ 探索で使うような内容じゃないぜ☆(^~^)開発中用だぜ☆(^▽^) /// </summary> /// <param name="motiKomas1"></param> /// <returns></returns> public static bool Equals_ForDevelop(Shogiban shogiban_hikaku, int[] motiKomas1) { Debug.Assert(PureMemory.gky_ky.yomiKy.yomiMotigomaItiran.GetArrayLength() == motiKomas1.Length, "局面の一致判定"); // 盤上の一致判定 for (int iTai = 0; iTai < Conv_Taikyokusya.itiran.Length; iTai++) { Taikyokusya tai = (Taikyokusya)iTai; if (!PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.Equals_KomaZenbu_ForDevelop(tai, shogiban_hikaku.ibashoBan_yk00.yomiIbashoBan)) { return(false); } for (int iKs = 0; iKs < Conv_Komasyurui.itiran.Length; iKs++) { Komasyurui ks = Conv_Komasyurui.itiran[iKs]; Piece km = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai); if (!PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.Equals_Koma_ForDevelop(km, shogiban_hikaku.ibashoBan_yk00.yomiIbashoBan)) { return(false); } } } // 持ち駒の一致判定 for (int iMk = 0; iMk < Conv_Motigoma.itiran.Length; iMk++) { if (PureMemory.gky_ky.yomiKy.yomiMotigomaItiran.Count((Motigoma)iMk) != motiKomas1[iMk]) { return(false); } } return(true); }
/// <summary> /// 勝負なし調査☆ /// 指し次いではいけない局面なら真だぜ☆(^~^) /// (A)自分のらいおんがいない☆ /// (B)相手のらいおんがいない☆ /// (C)自分のらいおんがトライしている☆ /// (D)相手のらいおんがトライしている☆ /// </summary> /// <returns></returns> public static bool IsSyobuNasi() { Piece raionJibun = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Komasyurui.R, PureMemory.kifu_teban); Piece raionAite = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(Komasyurui.R, PureMemory.kifu_aiteban); // (A)自分のらいおんがいない☆ if (PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.IsEmptyKoma(raionJibun)) { return(true); } // (B)相手のらいおんがいない☆ if (PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.IsEmptyKoma(raionAite)) { return(true); } // (C)自分のらいおんがトライしている☆ Bitboard bbTmp = new Bitboard(); bbTmp.Set(BitboardsOmatome.bb_try[PureMemory.kifu_nTeban]); PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.ToSelect_Koma(raionJibun, bbTmp); if (!bbTmp.IsEmpty()) { return(true); } // (D)相手のらいおんがトライしている☆ bbTmp.Set(BitboardsOmatome.bb_try[PureMemory.kifu_nAiteban]); PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.ToSelect_Koma(raionAite, bbTmp); if (!bbTmp.IsEmpty()) { return(true); } return(false); }
/// <summary> /// /// </summary> public static void DoMovePickerBegin(MoveType flag) { MoveGenAccessor.Clear_SsssUtikiri(); // 空っぽにしておくぜ☆ 何か入れないと投了だぜ☆(^▽^)www MoveGenAccessor.ClearMoveList(); PureMemory.ssss_isSyobuNasi = GenkyokuOpe.IsSyobuNasi(); PureMemory.ssss_bbBase_idosaki01_checker.Clear(); PureMemory.ssss_bbBase_idosaki02_raionCatch.Clear(); PureMemory.ssss_bbBase_idosaki03_nigeroTe.Clear(); PureMemory.ssss_bbBase_idosaki04_try.Clear(); PureMemory.ssss_bbBase_idosaki05_komaWoToruTe.Clear(); PureMemory.ssss_bbBase_idosaki06_himodukiOteZasi.Clear(); PureMemory.ssss_bbBase_idosaki07_suteOteZasi.Clear(); PureMemory.ssss_bbBase_idosaki08_suteOteDa.Clear(); PureMemory.ssss_bbBase_idosaki09_himodukiOteDa.Clear(); PureMemory.ssss_bbBase_idosaki10_himodukiKanmanDa.Clear(); PureMemory.ssss_bbBase_idosaki11_himodukiKanmanZasi.Clear(); PureMemory.ssss_bbBase_idosaki12_bottiKanmanZasi.Clear(); PureMemory.ssss_bbBase_idosaki13_bottiKanmanDa.Clear(); PureMemory.ssss_bbBase_idosaki14_suteKanmanZasi.Clear(); PureMemory.ssss_bbBase_idosaki15_suteKanmanDa.Clear(); PureMemory.ssss_bbVar_idosaki_narazu.Clear(); PureMemory.ssss_bbVar_idosaki_nari.Clear(); PureMemory.ssssTmp_bbVar_ibasho.Clear(); // 変数名短縮 Kyokumen.YomiKy yomiKy = PureMemory.gky_ky.yomiKy; IbashoBan.YomiIbashoBan yomiIbashoBan = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan; KikiBan.YomiKikiBan yomiKikiBan = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiKikiBan; //──────────────────────────────────────── // 被王手 //──────────────────────────────────────── Util_Hioute.Tukurinaosi(); //──────────────────────────────────────── // 移動先 //──────────────────────────────────────── if ( flag.HasFlag(MoveType.N13_HippakuKaeriutiTe) || flag.HasFlag(MoveType.N14_YoyuKaeriutiTe) ) { // 移動先は、王手をかけてきている駒☆(^~^) PureMemory.ssss_bbBase_idosaki01_checker.Set(PureMemory.hot_bb_checkerAr[PureMemory.kifu_nTeban]); } if (flag.HasFlag(MoveType.N12_RaionCatch) || flag.HasFlag(MoveType.N17_RaionCatchChosa)) { // 相手らいおん を取る手のみ生成するぜ☆(^▽^) yomiIbashoBan.ToSet_Koma(Med_Koma.ToRaion(PureMemory.kifu_aiteban), PureMemory.ssss_bbBase_idosaki02_raionCatch); } if (flag.HasFlag(MoveType.N15_NigeroTe)) { // 移動先 PureMemory.ssss_bbBase_idosaki03_nigeroTe.Set(BitboardsOmatome.bb_boardArea); PureMemory.ssss_bbBase_idosaki03_nigeroTe.Siborikomi(PureMemory.hot_bb_nigeroAr[PureMemory.kifu_nTeban]); PureMemory.ssss_bbBase_idosaki03_nigeroTe.Sitdown(PureMemory.hot_bb_checkerAr[PureMemory.kifu_nTeban]); // (逼迫/余裕)返討手は除外するぜ☆(^▽^) yomiIbashoBan.ToSitdown_Koma(Med_Koma.ToRaion(PureMemory.kifu_aiteban), PureMemory.ssss_bbBase_idosaki03_nigeroTe); // 利きのうち、らいおんを取る手 は、除外するぜ☆(^▽^) PureMemory.ssss_bbBase_idosaki03_nigeroTe.Sitdown(PureMemory.hot_bb_checkerAr[PureMemory.kifu_nTeban]); // 返討手 は除外するぜ☆(^▽^) } if (flag.HasFlag(MoveType.N16_Try)) { // トライは どうぶつしょうぎ用 だぜ☆(^~^) if (PureSettei.gameRule == GameRule.DobutuShogi) { PureMemory.ssss_bbBase_idosaki04_try.Set(BitboardsOmatome.bb_boardArea); yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_teban, PureMemory.ssss_bbBase_idosaki04_try); // 味方の駒があるところには移動できないぜ☆(^▽^) yomiIbashoBan.ToSitdown_Koma(Med_Koma.ToRaion(PureMemory.kifu_aiteban), PureMemory.ssss_bbBase_idosaki04_try); // 利きのうち、らいおん を取る手は、除外するぜ☆(^▽^) PureMemory.ssss_bbBase_idosaki04_try.Sitdown(PureMemory.hot_bb_checkerAr[PureMemory.kifu_nTeban]); // 返討手 は除外するぜ☆(^▽^) } } if (flag.HasFlag(MoveType.N01_KomaWoToruTe)) { // 移動先 yomiIbashoBan.ToSet_KomaZenbu(PureMemory.kifu_aiteban, PureMemory.ssss_bbBase_idosaki05_komaWoToruTe); // 相手の駒があるところだけ☆(^▽^) yomiIbashoBan.ToSitdown_Koma(Med_Koma.ToRaion(PureMemory.kifu_aiteban), PureMemory.ssss_bbBase_idosaki05_komaWoToruTe); // らいおんキャッチ は除外するぜ☆(^▽^) PureMemory.ssss_bbBase_idosaki05_komaWoToruTe.Sitdown(PureMemory.hot_bb_checkerAr[PureMemory.kifu_nTeban]); // 返討手 は除外するぜ☆(^▽^) } if (flag.HasFlag(MoveType.N10_HimozukiOteZasi)) { // 移動先 PureMemory.ssss_bbBase_idosaki06_himodukiOteZasi.Set(BitboardsOmatome.bb_boardArea); yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_teban, PureMemory.ssss_bbBase_idosaki06_himodukiOteZasi); // 味方の駒があるところには移動できないぜ☆(^▽^) yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_aiteban, PureMemory.ssss_bbBase_idosaki06_himodukiOteZasi); // 相手の駒がある升 は除外するぜ☆(^▽^) PureMemory.ssss_bbBase_idosaki06_himodukiOteZasi.Sitdown(PureMemory.hot_bb_checkerAr[PureMemory.kifu_nTeban]); // 返討手 は除外するぜ☆(^▽^) } if (flag.HasFlag(MoveType.N06_SuteOteZasi)) { // 移動先 PureMemory.ssss_bbBase_idosaki07_suteOteZasi.Set(BitboardsOmatome.bb_boardArea); yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_teban, PureMemory.ssss_bbBase_idosaki07_suteOteZasi); // 味方の駒がある升 は除外☆(^▽^) yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_aiteban, PureMemory.ssss_bbBase_idosaki07_suteOteZasi); // 相手の駒がある升 は除外☆(^▽^) PureMemory.ssss_bbBase_idosaki07_suteOteZasi.Sitdown(PureMemory.hot_bb_checkerAr[PureMemory.kifu_nTeban]); // 返討手 は除外☆(^▽^) } if (flag.HasFlag(MoveType.N07_SuteOteDa)) { // 持ち駒 PureMemory.ssss_bbBase_idosaki08_suteOteDa.Set(BitboardsOmatome.bb_boardArea); yomiIbashoBan.ToSitdown_KomaZenbu(Taikyokusya.T1, PureMemory.ssss_bbBase_idosaki08_suteOteDa);// 持ち駒の打てる場所 = 駒が無いところ☆ yomiIbashoBan.ToSitdown_KomaZenbu(Taikyokusya.T2, PureMemory.ssss_bbBase_idosaki08_suteOteDa); } if (flag.HasFlag(MoveType.N11_HimodukiOteDa)) { // 持ち駒 PureMemory.ssss_bbBase_idosaki09_himodukiOteDa.Set(BitboardsOmatome.bb_boardArea); yomiIbashoBan.ToSitdown_KomaZenbu(Taikyokusya.T1, PureMemory.ssss_bbBase_idosaki09_himodukiOteDa); // 持ち駒の打てる場所 = 駒が無いところ☆ yomiIbashoBan.ToSitdown_KomaZenbu(Taikyokusya.T2, PureMemory.ssss_bbBase_idosaki09_himodukiOteDa); PureMemory.gky_ky.yomiKy.yomiShogiban.yomiKikiBan.ToSelect_BBKikiZenbu(PureMemory.kifu_teban, PureMemory.ssss_bbBase_idosaki09_himodukiOteDa); // 紐を付ける☆ } if (flag.HasFlag(MoveType.N08_HimotukiKanmanSasi)) { // 盤面全体 PureMemory.ssss_bbBase_idosaki11_himodukiKanmanZasi.Set(BitboardsOmatome.bb_boardArea); // - 味方の駒がある升 ※味方の駒があるところには移動できないぜ☆(^▽^) yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_teban, PureMemory.ssss_bbBase_idosaki11_himodukiKanmanZasi); // - 相手の駒がある升 ※除外するぜ☆(^▽^) yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_aiteban, PureMemory.ssss_bbBase_idosaki11_himodukiKanmanZasi); // - 利きのうち、らいおんを取る手 ※除外するぜ☆(^▽^) yomiIbashoBan.ToSitdown_Koma(Med_Koma.ToRaion(PureMemory.kifu_aiteban), PureMemory.ssss_bbBase_idosaki11_himodukiKanmanZasi); } if (flag.HasFlag(MoveType.N02_BottiKanmanSasi)) { // 移動先 PureMemory.ssss_bbBase_idosaki12_bottiKanmanZasi.Set(BitboardsOmatome.bb_boardArea); yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_teban, PureMemory.ssss_bbBase_idosaki12_bottiKanmanZasi); // 味方の駒があるところには移動できないぜ☆(^▽^) yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_aiteban, PureMemory.ssss_bbBase_idosaki12_bottiKanmanZasi); // 相手の駒がある升 は除外するぜ☆(^▽^) yomiIbashoBan.ToSitdown_Koma(Med_Koma.ToRaion(PureMemory.kifu_aiteban), PureMemory.ssss_bbBase_idosaki12_bottiKanmanZasi); // 利きのうち、らいおんを取る手 は、除外するぜ☆(^▽^) PureMemory.ssss_bbBase_idosaki12_bottiKanmanZasi.Sitdown(PureMemory.hot_bb_checkerAr[PureMemory.kifu_nTeban]); // 返討手 は除外するぜ☆(^▽^) } if (flag.HasFlag(MoveType.N03_BottiKanmanDa)) { // 持ち駒 PureMemory.ssss_bbBase_idosaki13_bottiKanmanDa.Set(BitboardsOmatome.bb_boardArea); yomiIbashoBan.ToSitdown_KomaZenbu(Taikyokusya.T1, PureMemory.ssss_bbBase_idosaki13_bottiKanmanDa); // 自駒が無いところ☆ yomiIbashoBan.ToSitdown_KomaZenbu(Taikyokusya.T2, PureMemory.ssss_bbBase_idosaki13_bottiKanmanDa); // 相手駒が無いところ☆ yomiKikiBan.ToSitdown_BBKikiZenbu(PureMemory.kifu_teban, PureMemory.ssss_bbBase_idosaki13_bottiKanmanDa); // 味方の利きが利いていない場所☆(^▽^) yomiKikiBan.ToSitdown_BBKikiZenbu(PureMemory.kifu_aiteban, PureMemory.ssss_bbBase_idosaki13_bottiKanmanDa); // 敵の利きが利いていない場所☆(^▽^) } if (flag.HasFlag(MoveType.N04_SuteKanmanSasi)) { PureMemory.ssss_bbBase_idosaki14_suteKanmanZasi.Set(BitboardsOmatome.bb_boardArea); yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_teban, PureMemory.ssss_bbBase_idosaki14_suteKanmanZasi); // 味方の駒があるところには移動できないぜ☆(^▽^) yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_aiteban, PureMemory.ssss_bbBase_idosaki14_suteKanmanZasi); // 相手の駒がある升 は除外するぜ☆(^▽^) yomiIbashoBan.ToSitdown_Koma(Med_Koma.ToRaion(PureMemory.kifu_aiteban), PureMemory.ssss_bbBase_idosaki14_suteKanmanZasi); // 利きのうち、らいおん を取る手は、除外するぜ☆(^▽^) PureMemory.ssss_bbBase_idosaki14_suteKanmanZasi.Sitdown(PureMemory.hot_bb_checkerAr[PureMemory.kifu_nTeban]); // 返討手 は除外するぜ☆(^▽^) } if (flag.HasFlag(MoveType.N05_SuteKanmanDa)) { PureMemory.ssss_bbBase_idosaki15_suteKanmanDa.Set(BitboardsOmatome.bb_boardArea); yomiIbashoBan.ToSitdown_KomaZenbu(Taikyokusya.T1, PureMemory.ssss_bbBase_idosaki15_suteKanmanDa); // 味方の駒がない升 yomiIbashoBan.ToSitdown_KomaZenbu(Taikyokusya.T2, PureMemory.ssss_bbBase_idosaki15_suteKanmanDa); // 相手の駒がない升// 2016-12-22 捨てだからと言って、紐を付けないとは限らない☆ yomiKikiBan.ToSelect_BBKikiZenbu(PureMemory.kifu_aiteban, PureMemory.ssss_bbBase_idosaki15_suteKanmanDa); // 敵の利きが利いている場所に打つぜ☆(^▽^) } }
public static void SetSsssUgokiKm(Piece km) { ssss_ugoki_km_ = km; ssss_ugoki_ks_ = Med_Koma.KomaToKomasyurui(km); ssss_ugoki_sakasaKm_ = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ssss_ugoki_ks_, kifu_aiteban); }
/// <summary> /// 指し手情報を分解するぜ☆(^~^) /// 駒を動かす方を手番、相手を相手番と考えるぜ☆(^~^) /// </summary> public static void BunkaiMoveDmv(Move ss) { // // 動かす駒を t0 と呼ぶとする。 // 移動元を t0、移動先を t1 と呼ぶとする。 // 取られる駒を c と呼ぶとする。 // 取られる駒の元位置は t1 、駒台は 3 と呼ぶとする。 // // 変数をグローバルに一時退避 // 移動先升 PureMemory.dmv_ms_t1 = AbstractConvMove.GetDstMasu_WithoutErrorCheck((int)ss); // あれば、移動先の相手の駒(取られる駒; capture) PureMemory.dmv_km_c = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma(PureMemory.kifu_aiteban, PureMemory.dmv_ms_t1); PureMemory.dmv_ks_c = Med_Koma.KomaToKomasyurui(PureMemory.dmv_km_c); PureMemory.dmv_mk_c = Med_Koma.BanjoKomaToMotiKoma(PureMemory.dmv_km_c); if (AbstractConvMove.IsUtta(ss)) { // 打 PureMemory.dmv_ms_t0 = Conv_Masu.masu_error; // 指し手から「持駒」を判別 PureMemory.dmv_mks_t0 = AbstractConvMove.GetUttaKomasyurui(ss); PureMemory.dmv_mk_t0 = Med_Koma.MotiKomasyuruiAndTaikyokusyaToMotiKoma(PureMemory.dmv_mks_t0, PureMemory.kifu_teban); // 「持駒」から「駒」へ変換 PureMemory.dmv_km_t0 = Med_Koma.MotiKomasyuruiAndTaikyokusyaToKoma(PureMemory.dmv_mks_t0, PureMemory.kifu_teban); // 持ち駒は t0 も t1 も同じ。 PureMemory.dmv_km_t1 = PureMemory.dmv_km_t0; PureMemory.dmv_ks_t0 = Med_Koma.MotiKomasyuruiToKomasyrui(PureMemory.dmv_mks_t0); //おまとめ☆(^~^) PureMemory.dmv_ks_t1 = PureMemory.dmv_ks_t0; //追加 //#if DEBUG // if (!gky.ky.motiKomas.sindanMK.HasMotiKoma(mk_t0)) // { // CommandK.Ky(isSfen, "ky", gky, syuturyoku); // Util_Machine.Flush(syuturyoku); // } //#endif Debug.Assert(PureMemory.gky_ky.motigomaItiran.yomiMotigomaItiran.HasMotigoma(PureMemory.dmv_mk_t0), $"持っていない駒を打つのか☆(^~^)!? mks_src=[{ PureMemory.dmv_mks_t0 }] mk_utu=[{ PureMemory.dmv_mk_t0 }]"); } else { // 指し PureMemory.dmv_ms_t0 = AbstractConvMove.GetSrcMasu_WithoutErrorCheck((int)ss); PureMemory.dmv_km_t0 = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma(PureMemory.dmv_ms_t0); PureMemory.dmv_ks_t0 = Med_Koma.KomaToKomasyurui(PureMemory.dmv_km_t0);//移動元の駒の種類 PureMemory.dmv_mks_t0 = MotigomaSyurui.Yososu; PureMemory.dmv_mk_t0 = Motigoma.Yososu; if (AbstractConvMove.IsNatta(ss)) // 駒が成るケース { PureMemory.dmv_ks_t1 = Conv_Komasyurui.ToNariCase(PureMemory.dmv_ks_t0); PureMemory.dmv_km_t1 = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(PureMemory.dmv_ks_t1, PureMemory.kifu_teban); } else // 駒が成らないケース { PureMemory.dmv_km_t1 = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma(PureMemory.dmv_ms_t0); PureMemory.dmv_ks_t1 = PureMemory.dmv_ks_t0; } } }
/// <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); }
public static bool CanDoMove(Move ss, out MoveMatigaiRiyu reason) { if (Move.Toryo == ss) { reason = MoveMatigaiRiyu.Karappo; return(true); } // 投了はOKだぜ☆(^~^) // 打つ駒調べ MotigomaSyurui mksUtta = AbstractConvMove.GetUttaKomasyurui(ss);// 打った駒の種類 bool utta = MotigomaSyurui.Yososu != mksUtta; if (utta) { // 「打」の場合、持ち駒チェック☆ if (!PureMemory.gky_ky.yomiKy.yomiMotigomaItiran.HasMotigoma(Med_Koma.MotiKomasyuruiAndTaikyokusyaToMotiKoma(mksUtta, PureMemory.kifu_teban))) { // 持駒が無いのに打とうとしたぜ☆(>_<) reason = MoveMatigaiRiyu.NaiMotiKomaUti; return(false); } } // 移動先、打つ先 調べ☆ Masu ms_dst = AbstractConvMove.GetDstMasu_WithoutErrorCheck((int)ss); // 移動先升 if (!Conv_Masu.IsBanjo(ms_dst)) { // 盤外に移動しようとしたぜ☆(^~^) reason = MoveMatigaiRiyu.BangaiIdo; return(false); } Piece km_dst = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma(ms_dst); Taikyokusya tai_dstKm = Med_Koma.KomaToTaikyokusya(km_dst); if (km_dst != Piece.Kuhaku && PureMemory.kifu_teban == tai_dstKm) { // 自分の駒を取ろうとするのは、イリーガル・ムーブだぜ☆(^▽^) reason = MoveMatigaiRiyu.TebanKomaNoTokoroheIdo; return(false); } else if (utta && km_dst != Piece.Kuhaku) { // 駒があるところに打ち込んではいけないぜ☆(^▽^) reason = MoveMatigaiRiyu.KomaGaAruTokoroheUti; return(false); } // 移動元調べ☆ Piece km_src; if (utta) { // 「打」のときは ここ。 km_src = Med_Koma.MotiKomasyuruiAndTaikyokusyaToKoma(mksUtta, PureMemory.kifu_teban); } else { Masu ms_src = AbstractConvMove.GetSrcMasu_WithoutErrorCheck((int)ss); // 移動先升 km_src = PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.GetBanjoKoma(ms_src); Taikyokusya tai_srcKm = Med_Koma.KomaToTaikyokusya(km_src); if (km_src == Piece.Kuhaku) { // 空き升に駒があると思って動かそうとするのは、イリーガル・ムーブだぜ☆(^▽^) reason = MoveMatigaiRiyu.KuhakuWoIdo; return(false); } else if (tai_srcKm != PureMemory.kifu_teban) { // 相手の駒を動かそうとするのは、イリーガル・ムーブだぜ☆(^▽^) reason = MoveMatigaiRiyu.AiteNoKomaIdo; return(false); } // 移動方向調べ if (!BitboardsOmatome.KomanoUgokikataYk00.IsIntersect( km_src, ms_src, //この2つのマスが交わっているか ms_dst //この2つのマスが交わっているか )) { // その駒の種類からは、ありえない動きをしたぜ☆(^▽^) //#if DEBUG // throw new Exception($"その駒の種類からは、ありえない動きをしたぜ☆(^▽^) ms1=[{ ms_src }] ms2=[{ ms_dst }]"); //#else reason = MoveMatigaiRiyu.SonoKomasyuruiKarahaArienaiUgoki; return(false); //#endif } } // 成り調べ if (AbstractConvMove.IsNatta(ss))//成りを指示した場合 { switch (PureSettei.gameRule) { case GameRule.DobutuShogi: { if (Med_Koma.KomaToKomasyurui(km_src) != Komasyurui.H) { // ひよこ以外が、にわとりになろうとしました☆ reason = MoveMatigaiRiyu.NarenaiNari; return(false); } } break; case GameRule.HonShogi: { switch (Med_Koma.KomaToKomasyurui(km_src)) { case Komasyurui.H: case Komasyurui.K: case Komasyurui.N: case Komasyurui.S: case Komasyurui.U: case Komasyurui.Z: // セーフ break; case Komasyurui.I: case Komasyurui.PH: case Komasyurui.PK: case Komasyurui.PN: case Komasyurui.PS: case Komasyurui.PU: case Komasyurui.PZ: case Komasyurui.R: case Komasyurui.Yososu: //FIXME: default: { // 成れる駒以外が、成ろうとしました☆ reason = MoveMatigaiRiyu.NarenaiNari; return(false); } } } break; } } reason = MoveMatigaiRiyu.Karappo; return(true); }
/// <summary> /// 改造Fen /// 例: fen kr1/1h1/1H1/1R1 K2z 1 /// 盤上の駒配置、持ち駒の数、手番の対局者 /// </summary> public static void AppendFenTo( FenSyurui f, StringBuilder syuturyoku) { syuturyoku.Append(f == FenSyurui.sfe_n ? "sfen " : "fen "); // 盤上 { int space = 0; for (int iDan = 0; iDan < PureSettei.banTateHaba; iDan++) { for (int iSuji = 0; iSuji < PureSettei.banYokoHaba; iSuji++) { Masu ms = (Masu)(iDan * PureSettei.banYokoHaba + iSuji); Taikyokusya tai; if (PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.ExistsKomaZenbu(ms, out tai)) { if (0 < space) { syuturyoku.Append(space.ToString()); space = 0; } Komasyurui ks; PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.ExistsKoma(tai, ms, out ks); SpkKoma.AppendFenTo(f, Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai), syuturyoku); } else { space++; } } if (0 < space) { syuturyoku.Append(space.ToString()); space = 0; } if (iDan + 1 < PureSettei.banTateHaba) { syuturyoku.Append("/"); } } } syuturyoku.Append(" "); // 持駒 if (PureMemory.gky_ky.yomiKy.yomiMotigomaItiran.IsEmpty()) { syuturyoku.Append("-"); } else { for (int iMk = 0; iMk < Conv_Motigoma.itiran.Length; iMk++) { int cnt = PureMemory.gky_ky.yomiKy.yomiMotigomaItiran.Count((Motigoma)iMk); if (0 < cnt) { syuturyoku.Append( cnt == 1 ? SpkMotiKoma.GetFen(f, (Motigoma)iMk)// 1個の時は数字は付かないぜ☆(^~^) : cnt.ToString() + SpkMotiKoma.GetFen(f, (Motigoma)iMk) ); } } } // 手番 syuturyoku.Append(" "); syuturyoku.Append(SpkTaikyokusya.ToFen(f, PureMemory.kifu_teban)); //// moves //if (syuturyokuMoves) //{ //} }
/// <summary> /// 被王手されている情報を調べるぜ☆(^~^) /// 手番側を設定するんだぜ☆(^~^) /// </summary> /// <param name="gky"></param> /// <param name="isHouimouCheck">包囲網チェック</param> /// <returns></returns> public static void Tukurinaosi_1( Taikyokusya irekaeTeban, // 入れ替える Taikyokusya irekaeAiteban, // 入れ替える bool isHouimouCheck ) { bbVar_nigemiti.Clear(); PureMemory.hot_bb_checkerAr[(int)irekaeTeban].Clear(); PureMemory.hot_bb_nigereruAr[(int)irekaeTeban].Clear(); PureMemory.hot_outeKomasCountAr[(int)irekaeTeban] = 0; PureMemory.hot_isNigerarenaiCheckerAr[(int)irekaeTeban] = false; PureMemory.hot_bb_nigemitiWoFusaideiruAiteNoKomaAr[(int)irekaeTeban].Clear(); //らいおんが盤上にいないこともあるぜ☆(^▽^) if (Conv_Masu.masu_error != PureMemory.hot_ms_raionAr[(int)irekaeTeban]) { // 手番らいおんの8近傍の升☆(^▽^) Debug.Assert((int)Komasyurui.R < Conv_Komasyurui.itiran.Length, ""); Debug.Assert((int)irekaeTeban < Conv_Taikyokusya.itiran.Length, ""); Debug.Assert((int)irekaeAiteban < Conv_Taikyokusya.itiran.Length, ""); Debug.Assert((int)PureMemory.hot_ms_raionAr[(int)irekaeTeban] < PureSettei.banHeimen, ""); // らいおんが逃げれる8近傍の升☆(^▽^) // <編集> PureMemory.hot_bb_nigereruAr[(int)irekaeTeban].Set(PureMemory.hot_bb_raion8KinboAr[(int)irekaeTeban]); // <影響> PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.ToSitdown_KomaZenbu(irekaeTeban, PureMemory.hot_bb_nigereruAr[(int)irekaeTeban]); PureMemory.gky_ky.yomiKy.yomiShogiban.yomiKikiBan.ToSitdown_BBKikiZenbu(irekaeAiteban, PureMemory.hot_bb_nigereruAr[(int)irekaeTeban]); // 手番の らいおん の // - 8近傍 // - タテ筋 // - ヨコ筋 // - 左上がり筋 // - 左下がり筋 // を調べて、王手をかけている駒を一覧するぜ☆(^▽^) Masu ms_checker; bbVar_checker.Set(PureMemory.hot_bb_raion8KinboAr[(int)irekaeTeban]); // きりんとぞうは、先後同形☆(^~^) BitboardsOmatome.KomanoUgokikataYk00.ToStandup_Merge(Piece.R1, PureMemory.hot_ms_raionAr[(int)irekaeTeban], bbVar_checker); BitboardsOmatome.KomanoUgokikataYk00.ToStandup_Merge(Piece.B1, PureMemory.hot_ms_raionAr[(int)irekaeTeban], bbVar_checker); // いのししは先後別☆(^~^) switch (irekaeAiteban) { case Taikyokusya.T1: BitboardsOmatome.KomanoUgokikataYk00.ToStandup_Merge(Piece.L1, PureMemory.hot_ms_raionAr[(int)irekaeTeban], bbVar_checker); break; case Taikyokusya.T2: BitboardsOmatome.KomanoUgokikataYk00.ToStandup_Merge(Piece.L2, PureMemory.hot_ms_raionAr[(int)irekaeTeban], bbVar_checker); break; } while (bbVar_checker.Ref_PopNTZ(out ms_checker))// 立っているビットを降ろすぜ☆ { if (IsTobikondaKiki(irekaeAiteban, ms_checker, PureMemory.hot_ms_raionAr[(int)irekaeTeban])) { // <編集> PureMemory.hot_bb_checkerAr[(int)irekaeTeban].Standup(ms_checker); PureMemory.hot_outeKomasCountAr[(int)irekaeTeban]++; } } // 8方向に逃げ場がない場合は、王手を掛けてきている駒(チェッカー)を、 // ~~~~~~~~~~~~~~~~~~~~~~~~ // 必ず取り返して、その場にいようぜ☆ PureMemory.hot_isNigerarenaiCheckerAr[(int)irekaeTeban] = (0 < PureMemory.hot_outeKomasCountAr[(int)irekaeTeban] && PureMemory.hot_bb_nigereruAr[(int)irekaeTeban].IsEmpty()); if (isHouimouCheck) { // 編集 // らいおんが逃げようとする8マス☆(^~^) bbVar_nigemiti.Set(PureMemory.hot_bb_raion8KinboAr[(int)irekaeTeban]); // 影響 // 相手の利きで塞がれているところを消す☆(^~^) PureMemory.gky_ky.yomiKy.yomiShogiban.yomiKikiBan.ToSelect_BBKikiZenbu(irekaeAiteban, bbVar_nigemiti); // 自分の駒があるところを消す☆(^~^) PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ToSitdown_KomaZenbu(irekaeTeban, bbVar_nigemiti); Masu ms_fusagiMiti; while (bbVar_nigemiti.Ref_PopNTZ(out ms_fusagiMiti)) { // 塞がれている升の8近傍に、塞いでいる駒がいるだろう☆ foreach (Komasyurui ks_fusagi8Kinbo in Conv_Komasyurui.itiran) { // <編集> // 8近傍のそれぞれのマスについて、 // 相手の駒がそこに利きを利かしているかどうかを調べるには、 // 8近傍に自分の駒を置いて利きを調べれば、 // そこに利かしている相手の駒の場所が分かるぜ☆(^▽^) BitboardsOmatome.KomanoUgokikataYk00.ToSet_Merge( Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks_fusagi8Kinbo, irekaeTeban), ms_fusagiMiti, bbVar_kikasiteiruKoma ); // <影響> PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ToSelect_Koma(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks_fusagi8Kinbo, irekaeAiteban), bbVar_kikasiteiruKoma); Masu ms_fusagi8KinboKoma; while (bbVar_kikasiteiruKoma.Ref_PopNTZ(out ms_fusagi8KinboKoma)) { PureMemory.hot_bb_nigemitiWoFusaideiruAiteNoKomaAr[(int)irekaeTeban].Standup(ms_fusagi8KinboKoma); } } } } } // 王手を掛けている駒を数えるぜ☆(^~^) if (PureMemory.hot_outeKomasCountAr[(int)irekaeTeban] < 1) { // 王手を掛けられていないか、 // 王手は掛けられているが逃げれる場合は、 // クリアー PureMemory.hot_bb_nigeroAr[(int)irekaeTeban].Clear(); } }
/// <summary> /// 相手番らいおん の逃げ道を開けてしまう、手番側の悪手かどうか調べるぜ☆(^▽^) /// </summary> /// <returns></returns> public static bool IsNigemitiWoAkeru() { if (PureMemory.hot_bb_nigemitiWoFusaideiruAiteNoKomaAr[PureMemory.kifu_nAiteban].IsOff(PureMemory.ssss_ugoki_ms_src)) { // 逃げ道を塞いでいる駒ではないのなら、スルーするぜ☆(^▽^) return(false);//正常 } // 手番らいおん の8近傍 のどこかに、重ね利きの数 0 が出来ていれば、 // 逃げ道を開けると判定するぜ☆(^▽^) bool akeru = false; Piece km0_teban = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(PureMemory.ssss_ugoki_ks, PureMemory.kifu_teban); Piece km1_teban = km0_teban;// FIXME: 成りを考慮していない //──────────────────────────────────────── // (1)利き表をいじる前☆(^▽^) //──────────────────────────────────────── // 2回以上使う Bitboard bbConst_kiki0 = BitboardsOmatome.KomanoUgokikataYk00.Clone_Merge(km0_teban, PureMemory.ssss_ugoki_ms_src); Bitboard bbVar_kiki = bbConst_kiki0.Clone(); if (!bbVar_kiki.IsEmpty()) { //──────────────────────────────────────── // (2)動く前の、駒の利きを、利き表から減らすぜ☆(^▽^) //──────────────────────────────────────── //ビットボード使い回し PureMemory.gky_ky.shogiban.kikiBan.TorinozokuKiki(km0_teban, bbVar_kiki); // FIXME: ここで 利きの数が減っている必要がある } Bitboard kikiBB1_const = BitboardsOmatome.KomanoUgokikataYk00.Clone_Merge(km1_teban, PureMemory.ssss_ugoki_ms_dst); if (!kikiBB1_const.IsEmpty()) { bbVar_kiki.Set(kikiBB1_const); //──────────────────────────────────────── // (3)動いた後の、駒の動きを、利き表へ足すぜ☆(^▽^) //──────────────────────────────────────── //ビットボード使い回し PureMemory.gky_ky.shogiban.kikiBan.OkuKiki(km1_teban, bbVar_kiki); } // 動いたことで、らいおんの逃げ道を塞いでいた駒が、らいおんの逃げ道を空けてしまうか☆(^~^) Bitboard nigemitiBB = new Bitboard(); nigemitiBB.Set(PureMemory.hot_bb_raion8KinboAr[PureMemory.kifu_nAiteban]); PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_aiteban, nigemitiBB); Masu ms_nigemiti; while (nigemitiBB.Ref_PopNTZ(out ms_nigemiti)) { // 手番の利きが無くなったか☆(^▽^) if (0 == PureMemory.gky_ky.yomiKy.yomiShogiban.yomiKikiBan.CountKikisuZenbu(PureMemory.kifu_teban, ms_nigemiti)) { akeru = true; // (^▽^)相手らいおんの逃げ道が開いたぜ☆! goto gt_EndLoop; } } gt_EndLoop: ; bbVar_kiki.Set(kikiBB1_const); if (!bbVar_kiki.IsEmpty()) { //──────────────────────────────────────── // (4)増やした重ね利きの数を減らして、元に戻すぜ☆(^▽^) //──────────────────────────────────────── //ビットボード使い回し PureMemory.gky_ky.shogiban.kikiBan.TorinozokuKiki(km1_teban, bbVar_kiki); } // 利き数は、まだ戻している途中 bbVar_kiki.Set(bbConst_kiki0); if (!bbVar_kiki.IsEmpty()) { //──────────────────────────────────────── // (5)減らした重ね利きの数を増やして、元に戻すぜ☆(^▽^) //──────────────────────────────────────── //ビットボード使い回し PureMemory.gky_ky.shogiban.kikiBan.OkuKiki(km0_teban, bbVar_kiki); } //──────────────────────────────────────── // ここで、利きの数は現局面と合ってるはずだぜ☆(^~^) //──────────────────────────────────────── return(akeru); }
public static void Tukurinaosi() { foreach (Piece km_all in Conv_Koma.itiran) { // 居場所マス for (int iMs = 0; iMs < PureSettei.banHeimen; iMs++) { Masu ms = (Masu)iMs; switch (Med_Koma.KomaToKomasyurui(km_all)) { #region らいおん case Komasyurui.R: { TasuKonoUe(km_all, ms); // 上 TasuKonoMigiue(km_all, ms); // 右上 TasuKonoMigi(km_all, ms); // 右 TasuKonoMigisita(km_all, ms); // 右下 TasuKonoSita(km_all, ms); // 下 TasuKonoHidarisita(km_all, ms); // 左下 TasuKonoHidari(km_all, ms); // 左 TasuKonoHidariue(km_all, ms); // 左上 } break; #endregion #region ぞう case Komasyurui.Z: { if (!PureSettei.tobikikiTukau) { // 飛び利きを使わない場合 TasuKonoMigiue(km_all, ms); // 右上 TasuKonoMigisita(km_all, ms); // 右下 TasuKonoHidarisita(km_all, ms); // 左下 TasuKonoHidariue(km_all, ms); // 左上 } } break; #endregion #region パワーアップぞう case Komasyurui.PZ: { if (!PureSettei.tobikikiTukau) { // 飛び利きを使わない場合 TasuKonoMigiue(km_all, ms); // 右上 TasuKonoMigisita(km_all, ms); // 右下 TasuKonoHidarisita(km_all, ms); // 左下 TasuKonoHidariue(km_all, ms); // 左上 } TasuKonoUe(km_all, ms); // 上 TasuKonoMigi(km_all, ms); // 右 TasuKonoSita(km_all, ms); // 下 TasuKonoHidari(km_all, ms); // 左 } break; #endregion #region きりん case Komasyurui.K: { if (!PureSettei.tobikikiTukau) { // 飛び利きを使わない場合 TasuKonoUe(km_all, ms); // 上 TasuKonoMigi(km_all, ms); // 右 TasuKonoSita(km_all, ms); // 下 TasuKonoHidari(km_all, ms); // 左 } } break; #endregion #region パワーアップきりん case Komasyurui.PK: { if (!PureSettei.tobikikiTukau) { // 飛び利きを使わない場合 TasuKonoMigiue(km_all, ms); // 右上 TasuKonoMigisita(km_all, ms); // 右下 TasuKonoHidarisita(km_all, ms); // 左下 TasuKonoHidariue(km_all, ms); // 左上 } TasuKonoUe(km_all, ms); // 上 TasuKonoMigi(km_all, ms); // 右 TasuKonoSita(km_all, ms); // 下 TasuKonoHidari(km_all, ms); // 左 } break; #endregion #region ひよこ case Komasyurui.H: { TasuKonoUe(km_all, ms); // 上 } break; #endregion #region にわとり case Komasyurui.PH: { TasuKonoUe(km_all, ms); // 上 TasuKonoMigiue(km_all, ms); // 右上 TasuKonoMigi(km_all, ms); // 右 TasuKonoSita(km_all, ms); // 下 TasuKonoHidari(km_all, ms); // 左 TasuKonoHidariue(km_all, ms); // 左上 } break; #endregion #region いぬ case Komasyurui.I: { TasuKonoUe(km_all, ms); // 上 TasuKonoMigiue(km_all, ms); // 右上 TasuKonoMigi(km_all, ms); // 右 TasuKonoSita(km_all, ms); // 下 TasuKonoHidari(km_all, ms); // 左 TasuKonoHidariue(km_all, ms); // 左上 } break; #endregion #region ねこ case Komasyurui.N: { TasuKonoUe(km_all, ms); // 上 TasuKonoMigiue(km_all, ms); // 右上 TasuKonoMigisita(km_all, ms); // 右下 TasuKonoHidarisita(km_all, ms); // 左下 TasuKonoHidariue(km_all, ms); // 左上 } break; #endregion #region パワーアップねこ case Komasyurui.PN: { TasuKonoUe(km_all, ms); // 上 TasuKonoMigiue(km_all, ms); // 右上 TasuKonoMigi(km_all, ms); // 右 TasuKonoSita(km_all, ms); // 下 TasuKonoHidari(km_all, ms); // 左 TasuKonoHidariue(km_all, ms); // 左上 } break; #endregion #region うさぎ case Komasyurui.U: { TasuKeimatobiMigi(km_all, ms); // 桂馬跳び右 TasuKeimatobiHidari(km_all, ms); // 桂馬跳び左 } break; #endregion #region パワーアップうさぎ case Komasyurui.PU: { TasuKonoUe(km_all, ms); // 上 TasuKonoMigiue(km_all, ms); // 右上 TasuKonoMigi(km_all, ms); // 右 TasuKonoSita(km_all, ms); // 下 TasuKonoHidari(km_all, ms); // 左 TasuKonoHidariue(km_all, ms); // 左上 } break; #endregion #region いのしし case Komasyurui.S: { if (!PureSettei.tobikikiTukau) { // 飛び利きを使わない場合 TasuKonoUe(km_all, ms); // 上 } } break; #endregion #region パワーアップいのしし case Komasyurui.PS: { TasuKonoUe(km_all, ms); // 上 TasuKonoMigiue(km_all, ms); // 右上 TasuKonoMigi(km_all, ms); // 右 TasuKonoSita(km_all, ms); // 下 TasuKonoHidari(km_all, ms); // 左 TasuKonoHidariue(km_all, ms); // 左上 } break; #endregion default: break; } } } }
/// <summary> /// 一手詰めの局面かどうか調べるぜ☆(^▽^) /// /// 盤上の駒を動かすのか、駒台の駒を打つのかによって、利き の形が異なるぜ☆(^~^) /// /// 自分が一手詰めを掛けられるから、この指し手は作らないでおこう、といった使い方がされるぜ☆(^▽^) /// /// FIXME: 成りを考慮してない /// </summary> /// <param name="ky2"></param> /// <param name="ms_t0">移動元。持ち駒の場合、エラー値</param> /// <param name="ms_t1">移動先</param> /// <param name="tebanHioute"></param> /// <returns></returns> public static bool CheckBegin_Tume1_BanjoKoma() { Debug.Assert(Conv_Masu.IsBanjo(PureMemory.ssss_ugoki_ms_dst), "升エラー"); if (!PureSettei.ittedumeTukau) { return(false); } // 動かす駒 Komasyurui ks_t0; if (!PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.ExistsKoma(PureMemory.kifu_teban, PureMemory.ssss_ugoki_ms_src, out ks_t0)) { // エラー。盤上の駒ではないのかも☆(^~^) throw new Exception(Interproject.project.Owata("TryFail_Ittedume_BanjoKoma gky.ky.shogiban.ibashoBan.ExistsBBKoma(1)", PureMemory.tnsk_hyoji)); } Piece km_t0 = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks_t0, PureMemory.kifu_teban); Piece km_t1 = km_t0; // FIXME: 成りを考慮していないぜ☆(>_<) // A B C // ┌──┬──┬──┐ //1│ │▽ら│ │ // ├──┼──┼──┤ //2│▲き│ │▲き│ // ├──┼──┼──┤ //3│ │▲に│▲ら│ // ├──┼──┼──┤ //4│▲ぞ│▲ひ│▲ぞ│ // └──┴──┴──┘ // 動かしたばかりの駒を 取り返されるようでは、一手詰めは成功しないぜ☆(^~^)(ステイルメイト除く) if (1 < PureMemory.gky_ky.shogiban.kikiBan.yomiKikiBan.CountKikisuZenbu(PureMemory.kifu_aiteban, PureMemory.ssss_ugoki_ms_dst)) { // 移動先升は、相手らいおん の利きも 1つ あるはず。 // 移動先升に 相手の利きが2つあれば、駒を取り返される☆ return(false); } if (!PureMemory.gky_ky.shogiban.yomiIbashoBan_yoko.IsIntersect(Med_Koma.ToRaion(PureMemory.kifu_aiteban), // 相手のらいおん BitboardsOmatome.KomanoUgokikataYk00.Clone_Merge(km_t0, PureMemory.ssss_ugoki_ms_dst) // 移動先での駒の利き )) // 相手らいおん が、移動先での駒の利きの中に居ないんだったら、一手詰め にはならないぜ☆(^~^) { // FIXME: ステイルメイトは考えてないぜ☆(>_<) return(false); } Bitboard bb_idogoKikiNew = new Bitboard();// 移動後の、利き { // 盤上の重ね利きの数を差分更新するぜ☆(^▽^) // 移動元の駒の利きを消すぜ☆(^▽^) PureMemory.gky_ky.shogiban.kikiBan.TorinozokuKiki(km_t0, PureMemory.ssss_ugoki_ms_src); // 現局面より 利き が減っているのが正しい // 移動先の駒の利きを増やすぜ☆(^▽^) PureMemory.gky_ky.shogiban.kikiBan.OkuKiki(km_t1, PureMemory.ssss_ugoki_ms_dst); // ここで、現行の利きは変更されているぜ☆(^~^)駒は移動していないので、再計算の駒配置は 現行の利きと異なるぜ☆(^~^) // 移動後の利きを作り直し bb_idogoKikiNew = PureMemory.gky_ky.shogiban.kikiBan.RefBB_FromKikisuZenbuPositiveNumber(PureMemory.kifu_teban); // 盤上の重ね利きの数の差分更新を元に戻すぜ☆(^▽^) { // 移動先の駒の利きを減らすぜ☆(^▽^) PureMemory.gky_ky.shogiban.kikiBan.TorinozokuKiki(km_t1, PureMemory.ssss_ugoki_ms_dst); // 駒の利きを減らしているぜ☆(^~^) 駒は減っていないので、再計算すると結果が異なるぜ☆(^~^) // 移動元の駒の利きを増やすぜ☆(^▽^) PureMemory.gky_ky.shogiban.kikiBan.OkuKiki(km_t0, PureMemory.ssss_ugoki_ms_src); } } Bitboard bb1 = PureMemory.hot_bb_raion8KinboAr[PureMemory.kifu_nAiteban].Clone(); // 相手らいおん が逃げれる、相手らいおんの周りの空白 PureMemory.gky_ky.shogiban.ibashoBan_yk00.yomiIbashoBan.ToSitdown_KomaZenbu(PureMemory.kifu_aiteban, bb1); // 相手の駒がない升 return (bb1.Sitdown(bb_idogoKikiNew) // こっちの利きがない升 .IsEmpty()); // がない場合、詰み☆ ; }
/// <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> /// <returns></returns> static void Setumei_Hanyo( DLGT_dataBu dlgt_dataBu, int banYokoHaba_tmp, int banTateHaba_tmp, int teme, StringBuilder hyoji ) { #region 盤の上の方 // 2行目 { // 何手目 hyoji.Append(string.Format("図は{0,3}手まで ", teme)); // 手番 SpkTaikyokusya.AppendSetumeiName(PureMemory.GetTebanByTeme(teme), hyoji); hyoji.Append("の番"); hyoji.AppendLine(); } // 3行目 後手の持ち駒 { // 後手の持ち駒の数 foreach (MotigomaSyurui mks in Conv_MotigomaSyurui.itiran) { Motigoma mk = Med_Koma.MotiKomasyuruiAndTaikyokusyaToMotiKoma(mks, Taikyokusya.T2); if (PureMemory.gky_ky.yomiKy.yomiMotigomaItiran.HasMotigoma(mk)) { hyoji.Append(Conv_MotigomaSyurui.GetHyojiName(mks)); hyoji.Append(PureMemory.gky_ky.yomiKy.yomiMotigomaItiran.Count(mk).ToString()); } } hyoji.AppendLine(); } // 4行目 { // A B C D とか hyoji.Append(" "); SpkBanWaku.AppendLine_SujiFugo(banYokoHaba_tmp, hyoji); } // 5行目 { hyoji.Append(" "); SpkBanWaku.AppendLine_TopBar(1, PureSettei.banYokoHaba, hyoji); // ┌──┬──┬──┐ } #endregion // 5行目~13行目 // 盤上 for (int dan = 0; dan < PureSettei.banTateHaba; dan++) { // 6,8,10,12行目 hyoji.Append(Conv_Kihon.ToZenkakuInteger(dan + 1)); SpkBanWaku.AppendLine_Record_Cell4Hankakus2( (Masu ms) => { return(dlgt_dataBu(dan, ms)); }, dan, banYokoHaba_tmp, hyoji); if (dan + 1 < PureSettei.banTateHaba) { // 7,9,11行目 hyoji.Append(" "); SpkBanWaku.AppendLine_MiddleBar(1, PureSettei.banYokoHaba, hyoji);//├──┼──┼──┤ } } #region 盤の下の方 // 13行目 { hyoji.Append(" "); SpkBanWaku.AppendLine_BottomBar(1, PureSettei.banYokoHaba, hyoji);//└──┴──┴──┘ } // 先手の持ち駒の数 { foreach (MotigomaSyurui mks in Conv_MotigomaSyurui.itiran) { Motigoma mk = Med_Koma.MotiKomasyuruiAndTaikyokusyaToMotiKoma(mks, Taikyokusya.T1); if (PureMemory.gky_ky.yomiKy.yomiMotigomaItiran.HasMotigoma(mk)) { hyoji.Append(Conv_MotigomaSyurui.GetHyojiName(mks)); hyoji.Append(PureMemory.gky_ky.yomiKy.yomiMotigomaItiran.Count(mk).ToString()); } } hyoji.AppendLine(); } #endregion }