/// <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> /// 改造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("+"); } }
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); }