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> public static void AddMoveUttaGood() { if (PureMemory.ssss_genk_tume1) { MoveGenAccessor.ClearMoveList(); } //他の指し手を消し飛ばすぜ☆(^▽^) Move ss = AbstractConvMove.ToMove01cUtta(PureMemory.ssss_ugoki_ms_dst, PureMemory.ssss_mot_mks); Debug.Assert(Move.Toryo != ss, ""); PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].AddList(ss, PureMemory.ssss_ugoki_kakuteiSsType); }
public static Move TryFenMove2( FenSyurui f, string str1, string str2, string str3, string str4, string str5 ) { int dstSuji = LisInt.FenSuji_Int(f, str3); // 至筋 int dstDan = LisInt.FenDan_Int(f, str4); // 至段 // 取った駒を調べるぜ☆(^▽^) Masu dstMs = Conv_Masu.ToMasu(dstSuji, dstDan); //------------------------------ // 5 //------------------------------ bool natta = false; if ("+" == str5) { // 成りました natta = true; } //------------------------------ // 結果 //------------------------------ if ("*" == str2) { // 駒台から打ったぜ☆ return(AbstractConvMove.ToMove01cUtta( dstMs, Med_Parser.MojiToMotikomaSyurui(f, str1)//打った駒 )); } else { // 盤上の駒を動かしたぜ☆ if (natta) { return(AbstractConvMove.ToMove01bNariSasi(Med_Parser.FenSujiDan_Masu(f, str1, str2), dstMs)); } else { return(AbstractConvMove.ToMove01aNarazuSasi(Med_Parser.FenSujiDan_Masu(f, str1, str2), dstMs)); } } }
public static void AddMoveNariGoodXorBad() { Move ss = AbstractConvMove.ToMove01bNariSasi(PureMemory.ssss_ugoki_ms_src, PureMemory.ssss_ugoki_ms_dst); if (PureMemory.ssss_genk_tume1) { MoveGenAccessor.ClearMoveList(); } //他の指し手を消し飛ばすぜ☆(^▽^) Debug.Assert(Move.Toryo != ss, ""); if (PureMemory.IsAkusyu_Ssss) { PureMemory.ssss_moveListBad[PureMemory.tnsk_fukasa].AddList(ss, PureMemory.ssss_ugoki_kakuteiSsType | PureMemory.GetAkusyuType_Ssss()); } else { PureMemory.ssss_moveList[PureMemory.tnsk_fukasa].AddList(ss, PureMemory.ssss_ugoki_kakuteiSsType); } }
/// <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> /// 改造FEN符号表記 /// </summary> /// <returns></returns> public static void AppendFenTo(FenSyurui f, Move ss, StringBuilder syuturyoku) { if (Move.Toryo == ss) { syuturyoku.Append(Itiran_FenParser.GetToryo(f)); return; } int v = (int)ss;//バリュー(ビットフィールド) // 打った駒の種類(取り出すのは難しいので関数を使う☆) MotigomaSyurui mksUtta = AbstractConvMove.GetUttaKomasyurui(ss); if (MotigomaSyurui.Yososu != mksUtta)//指定があれば { // 打でした。 // (自)筋・(自)段は書かずに、「P*」といった表記で埋めます。 SpkMotiKomasyurui.AppendFenTo(f, mksUtta, syuturyoku); syuturyoku.Append("*"); } else { //------------------------------------------------------------ // (自)筋 //------------------------------------------------------------ //Option_Application.Optionlist.USI switch (f) { case FenSyurui.sfe_n: { syuturyoku.Append(PureSettei.banYokoHaba + 1 - AbstractConvMove.GetSrcSuji_WithoutErrorCheck(v)); } break; case FenSyurui.dfe_n: { syuturyoku.Append(Conv_Kihon.ToAlphabetLarge(AbstractConvMove.GetSrcSuji_WithoutErrorCheck(v))); } break; default: throw new Exception(string.Format("未定義 {0}", f)); } //------------------------------------------------------------ // (自)段 //------------------------------------------------------------ //Option_Application.Optionlist.USI switch (f) { case FenSyurui.sfe_n: { syuturyoku.Append(Conv_Kihon.ToAlphabetSmall(AbstractConvMove.GetSrcDan_WithoutErrorCheck(v))); } break; case FenSyurui.dfe_n: { syuturyoku.Append(AbstractConvMove.GetSrcDan_WithoutErrorCheck(v).ToString()); } break; default: throw new Exception(string.Format("未定義 {0}", f)); } } //------------------------------------------------------------ // (至)筋 //------------------------------------------------------------ //Option_Application.Optionlist.USI switch (f) { case FenSyurui.sfe_n: { syuturyoku.Append(PureSettei.banYokoHaba + 1 - AbstractConvMove.GetDstSuji_WithoutErrorCheck(v)); } break; case FenSyurui.dfe_n: { syuturyoku.Append(Conv_Kihon.ToAlphabetLarge(AbstractConvMove.GetDstSuji_WithoutErrorCheck(v))); } break; default: throw new Exception(string.Format("未定義 {0}", f)); } //------------------------------------------------------------ // (至)段 //------------------------------------------------------------ //Option_Application.Optionlist.USI switch (f) { case FenSyurui.sfe_n: { syuturyoku.Append(Conv_Kihon.ToAlphabetSmall(AbstractConvMove.GetDstDan_WithoutErrorCheck(v))); } break; case FenSyurui.dfe_n: { syuturyoku.Append(AbstractConvMove.GetDstDan_WithoutErrorCheck(v).ToString()); } break; default: throw new Exception(string.Format("未定義 {0}", f)); } //------------------------------------------------------------ // 成 //------------------------------------------------------------ int natta; { // (v & m) >> s + 1。 v:バリュー、m:マスク、s:シフト natta = (v & (int)MoveMask.NATTA) >> (int)MoveShift.NATTA; } if (1 == natta) { syuturyoku.Append("+"); } }
/// <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; } } }
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> /// 指したあとの、次の局面へと更新するぜ☆ /// ハッシュも差分変更するぜ☆ /// /// 手番を進める処理は、分けるぜ☆(^~^) /// </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); }