/// <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; } } }
public void Tukurinaosi_Remake() { valueKmMs = new int[Conv_Koma.itiran.Length][]; Bitboard bb_ibashoCopy = new Bitboard(); Bitboard bb_ugokikataCopy = new Bitboard(); // 盤上 foreach (Piece km_all in Conv_Koma.itiran) { Taikyokusya tai = Med_Koma.KomaToTaikyokusya(km_all); Komasyurui ks = Med_Koma.KomaToKomasyurui(km_all); valueKmMs[(int)km_all] = new int[PureSettei.banHeimen]; PureMemory.gky_ky.yomiKy.yomiShogiban.yomiIbashoBan.ToSet_Koma(km_all, bb_ibashoCopy); Masu ms_ibasho; while (bb_ibashoCopy.Ref_PopNTZ(out ms_ibasho)) { BitboardsOmatome.KomanoUgokikataYk00.ToSet_Merge( km_all, ms_ibasho, bb_ugokikataCopy); Masu ms_kiki; while (bb_ugokikataCopy.Ref_PopNTZ(out ms_kiki)) { valueKmMs[(int)km_all][(int)ms_kiki]++; } } } }
public static void Update(Hyokati hyokaSu, Taikyokusya taikyokusya) { if (Conv_Tumesu.None != hyokaSu.tumeSu) { // 詰め手数が表示されているぜ☆ if (Util_Taikyoku.nantedumeTeme_playerN[(int)taikyokusya] == int.MaxValue) { // 詰め手数が新たに表示されたようだぜ☆ Util_Taikyoku.nantedumeTeme_playerN[(int)taikyokusya] = PureMemory.kifu_endTeme; } // 前から表示されていたのなら、そのままだぜ☆(^▽^) } else { // 詰め手数は、表示されていないぜ☆ if (Util_Taikyoku.nantedumeTeme_playerN[(int)taikyokusya] != int.MaxValue) { // 詰め手数が消えたようだぜ☆ Util_Taikyoku.nantedumeTeme_playerN[(int)taikyokusya] = int.MaxValue; } // もともと表示されていなかったのなら、そのままだぜ☆(^▽^) } }
/// <summary> /// "1" を 対局者1、 "2" を 対局者2 にするぜ☆(^~^) /// </summary> /// <param name="moji1"></param> /// <returns></returns> public static bool Try_MojiToTaikyokusya(FenSyurui f, string moji1, out Taikyokusya out_tai) { switch (f) { case FenSyurui.sfe_n: { switch (moji1) { case "b": out_tai = Taikyokusya.T1; return(true); case "w": out_tai = Taikyokusya.T2; return(true); default: out_tai = Taikyokusya.Yososu; return(false); } } case FenSyurui.dfe_n: { switch (moji1) { case "1": out_tai = Taikyokusya.T1; return(true); case "2": out_tai = Taikyokusya.T2; return(true); default: out_tai = Taikyokusya.Yososu; return(false); } } default: throw new Exception(string.Format("未定義 {0}", f)); } }
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> /// 下側に自分の陣地がある視点の筋番号だぜ☆(^▽^) /// 左端筋が1☆(^~^) /// </summary> /// <param name="ms"></param> /// <returns></returns> public static int ToSujiO1_JibunSiten_BySujiO1(Taikyokusya tb, int sujiO1) { if (tb == Taikyokusya.T1) { return(sujiO1); } return(PureSettei.banYokoHaba - (sujiO1 - 1)); }
/// <summary> /// 下側に自分の陣地がある視点の段番号だぜ☆(^▽^) /// 例:対局者1でも2でも、トライルールは らいおん が1段目に入ったときだぜ☆(^▽^) /// </summary> /// <param name="ms"></param> /// <returns></returns> public static int ToDanO1_JibunSiten(Taikyokusya tb, Masu ms) { if (tb == Taikyokusya.T1) { return(ToDanO1_WithoutErrorCheck((int)ms)); } return(ToDanO1_WithoutErrorCheck(PureSettei.banHeimen - 1 - (int)ms)); }
/// <summary> /// 下側に自分の陣地がある視点の段番号だぜ☆(^▽^) /// </summary> /// <param name="ms"></param> /// <returns></returns> public static int ToDanO1_JibunSiten_ByDanO1(Taikyokusya tb, int danO1) { if (tb == Taikyokusya.T1) { return(danO1); } return(PureSettei.banTateHaba - (danO1 - 1)); }
public YomiBitboard[] GetBB_Where(Taikyokusya tai) { YomiBitboard[] bbItiran = new YomiBitboard[Conv_Komasyurui.itiran.Length]; foreach (Komasyurui ks in Conv_Komasyurui.itiran) { bbItiran[(int)ks] = new YomiBitboard(valuesKm[(int)Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai)]); } return(bbItiran); }
public Piece GetBanjoKoma(Taikyokusya tai, Masu ms) { Komasyurui ks; if (ExistsKoma(tai, ms, out ks)) { return(Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai)); } return(Piece.Kuhaku); }
/// <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 bool Exists(Taikyokusya tai, Masu ms) { for (int iKm = 0; iKm < Conv_Koma.itiranTai[(int)tai].Length; iKm++) { if (valueKm[(int)Conv_Koma.itiranTai[(int)tai][iKm]].IsOn(ms)) { return(true); } } return(false); }
public void ScanKomaZenbu(DLGT_scanKomaZenbu dlgt_scanKomaZenbu, Taikyokusya tai) { // 駒全部 Bitboard bbVar_komaZenbu = CloneKomaZenbu(tai); Masu ms_ibasho; while (bbVar_komaZenbu.Ref_PopNTZ(out ms_ibasho)) { dlgt_scanKomaZenbu(ms_ibasho); } }
/// <summary> /// 対局者反転 /// </summary> /// <param name="ts"></param> /// <returns></returns> public static Taikyokusya Hanten(Taikyokusya ts) { switch (ts) { case Taikyokusya.T1: return(Taikyokusya.T2); case Taikyokusya.T2: return(Taikyokusya.T1); default: return(ts); } }
/// <summary> /// 先後。 /// </summary> /// <param name="tai"></param> /// <returns></returns> public static string ToSetumeiName(Taikyokusya tai) { switch (tai) { case Taikyokusya.T1: return(PureSettei.name_playerN[(int)Taikyokusya.T1]); case Taikyokusya.T2: return(PureSettei.name_playerN[(int)Taikyokusya.T2]); default: return("×"); } }
public static void ResetTebanArray(Taikyokusya kaisiTai) { if (kifu_syokikyokumenTeban != kaisiTai) { kifu_syokikyokumenTeban = kaisiTai; switch (kaisiTai) { case Taikyokusya.T1: { // 先手始まりケース for (int iTeme_even = 0; iTeme_even < KIFU_SIZE; iTeme_even += 2) { kifu_tebanAr_[iTeme_even] = Taikyokusya.T1; kifu_aitebanAr_[iTeme_even] = Taikyokusya.T2; kifu_nTebanAr_[iTeme_even] = (int)Taikyokusya.T1; kifu_nAitebanAr_[iTeme_even] = (int)Taikyokusya.T2; } for (int iTeme_odd = 1; iTeme_odd < KIFU_SIZE; iTeme_odd += 2) { // 1つ飛ばしで、相手番☆(^~^) kifu_tebanAr_[iTeme_odd] = Taikyokusya.T2; kifu_aitebanAr_[iTeme_odd] = Taikyokusya.T1; kifu_nTebanAr_[iTeme_odd] = (int)Taikyokusya.T2; kifu_nAitebanAr_[iTeme_odd] = (int)Taikyokusya.T1; } } break; case Taikyokusya.T2: { // 後手始まりケース for (int iTeme_even = 0; iTeme_even < KIFU_SIZE; iTeme_even += 2) { kifu_tebanAr_[iTeme_even] = Taikyokusya.T2; kifu_aitebanAr_[iTeme_even] = Taikyokusya.T1; kifu_nTebanAr_[iTeme_even] = (int)Taikyokusya.T2; kifu_nAitebanAr_[iTeme_even] = (int)Taikyokusya.T1; } for (int iTeme_odd = 1; iTeme_odd < KIFU_SIZE; iTeme_odd += 2) { // 1つ飛ばしで、相手番☆(^~^) kifu_tebanAr_[iTeme_odd] = Taikyokusya.T1; kifu_aitebanAr_[iTeme_odd] = Taikyokusya.T2; kifu_nTebanAr_[iTeme_odd] = (int)Taikyokusya.T1; kifu_nAitebanAr_[iTeme_odd] = (int)Taikyokusya.T2; } } break; default: throw new Exception(string.Format("未定義 tai={0}", kaisiTai)); } } }
/// <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("未定義の手番"); } }
/// <summary> /// 引き算 /// </summary> /// <param name="km"></param> /// <param name="cbKomabetu_clear">こっちはクリアーされる</param> public void Substruct(Piece km, KikisuKomabetuCountboardItiran cbKomabetu_clear) { Taikyokusya tai = Med_Koma.KomaToTaikyokusya(km); for (int iMs = 0; iMs < valueTaiMs[(int)tai].Length; iMs++) { int num = cbKomabetu_clear.Get(km, (Masu)iMs); valueTaiMs[(int)tai][iMs] -= num; valueTai[(int)tai] -= num; } cbKomabetu_clear.Tukurinaosi_Clear(km); }
/// <summary> /// 駒別の利き を先に作っておいて、それをまとめるだけだぜ☆(^~^) /// </summary> /// <param name="bb_sourceKomabetuKiki"></param> public void Tukurinaosi_Remake(KikiKomabetuBitboardItiran bb_sourceKomabetuKiki) { Util_Bitboard.ClearBitboards(valueTai); foreach (Piece km_all in Conv_Koma.itiran) { Taikyokusya tai = Med_Koma.KomaToTaikyokusya(km_all); //Komasyurui ks = Med_Koma.KomaToKomasyurui(km); bb_sourceKomabetuKiki.ToStandup(km_all, valueTai[(int)tai]); //valueTai[(int)tai].Standup(bb_sourceKomabetuKiki.RefBB_Kiki(km)); } }
public bool Exists(Masu ms, out Taikyokusya out_tai) { for (int iTai = 0; iTai < Conv_Taikyokusya.itiran.Length; iTai++) { out_tai = (Taikyokusya)iTai; if (valueTai[iTai].IsOn(ms)) { return(true); } } out_tai = Taikyokusya.Yososu; return(false); }
/// <summary> /// [手番,升] 型のカウントボードを、ビットボードに変換するぜ☆(^▽^) /// </summary> /// <param name="tai"></param> /// <param name="kikiZenbuCB"></param> /// <returns></returns> public Bitboard CreateBitboard_PositiveNumber(Taikyokusya tai) { Bitboard bb = new Bitboard(); for (int iMs = 0; iMs < PureSettei.banHeimen; iMs++) { if (0 < Get(tai, (Masu)iMs)) { bb.Standup((Masu)iMs); } } return(bb); }
public bool Exists(Taikyokusya tai, Masu ms, out Komasyurui out_ks) { for (int iKm = 0; iKm < Conv_Koma.itiranTai[(int)tai].Length; iKm++) { Piece km = Conv_Koma.itiranTai[(int)tai][iKm]; if (valueKm[(int)km].IsOn(ms)) { out_ks = Med_Koma.KomaToKomasyurui(km); return(true); } } out_ks = Komasyurui.Yososu; return(false); }
/// <summary> /// 駒種類、対局者 /// </summary> /// <param name="dlgt_GetCellData"></param> /// <param name="tai"></param> /// <param name="ms_hidariHasi"></param> /// <param name="hyoji"></param> public static void AppendLine_Record_Cell4Hankakus3( DLGT_GetCellData3 dlgt_GetCellData, Taikyokusya tai, int dan, StringBuilder hyoji) { for (int iKs = 0; iKs < Conv_Komasyurui.itiran.Length; iKs++) { hyoji.Append("│"); for (int iMs_offset = 0; iMs_offset < PureSettei.banYokoHaba; iMs_offset++) { hyoji.Append(dlgt_GetCellData(tai, (Komasyurui)iKs, (Masu)(dan * PureSettei.banYokoHaba + iMs_offset))); hyoji.Append("│"); } } hyoji.AppendLine(); }
public static Option <Phase> From(Taikyokusya tai) { switch (tai) { case Taikyokusya.T1: return(OptionalPhase.Black); case Taikyokusya.T2: return(OptionalPhase.White); case Taikyokusya.Yososu: return(Option <Phase> .None); default: throw new Exception($"tai={tai} is fail."); } }
/// <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="km_target"></param> /// <param name="bbVar_add">注意、このメソッド実行後に0になるぜ☆(^~^)</param> /// <param name="yomiKy"></param> /// <param name="reigai1"></param> /// <returns></returns> public void OkuKiki(Piece km_target, Bitboard bbVar_add) { Taikyokusya tai = Med_Koma.KomaToTaikyokusya(km_target); // ビットボードは、一気に更新するぜ☆(^~^) Standup_Kiki(km_target, bbVar_add); Standup_KikiZenbu(tai, bbVar_add); // カウントボードは、1升ずつ、足していくぜ☆(^~^) Masu ms_hit; while (bbVar_add.Ref_PopNTZ(out ms_hit)) { int result_zenbu; CB_kikisuZenbu.Increase1(tai, ms_hit, out result_zenbu); int result_komabetu; CB_kikisuKomabetu.Increase1(km_target, ms_hit, out result_komabetu); } }
/// <summary> /// 将棋盤を180度ひっくり返すぜ☆(^▽^) /// 主にテスト用だぜ☆(^▽^) /// /// 参考:「ビットの並びを反転する」http://blog.livedoor.jp/techblog1/archives/5365383.html /// </summary> public static void Hanten() { // 盤上 { // 左右反転して、先後も入替 Bitboard tmp_T1 = PureMemory.gky_ky.shogiban.ibashoBan_yk00.CloneBB_KomaZenbu(Taikyokusya.T1); Bitboard tmp_T2 = PureMemory.gky_ky.shogiban.ibashoBan_yk00.CloneBB_KomaZenbu(Taikyokusya.T2); tmp_T1.Bitflip128(); tmp_T2.Bitflip128(); PureMemory.gky_ky.shogiban.ibashoBan_yk00.Set_KomaZenbu(Taikyokusya.T1, tmp_T1); PureMemory.gky_ky.shogiban.ibashoBan_yk00.Set_KomaZenbu(Taikyokusya.T2, tmp_T2); for (int iKs = 0; iKs < Conv_Komasyurui.itiran.Length; iKs++) { Komasyurui ks = Conv_Komasyurui.itiran[iKs]; Piece km1 = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, Taikyokusya.T1); tmp_T1 = PureMemory.gky_ky.shogiban.ibashoBan_yk00.CloneBb_Koma(km1); tmp_T1.Bitflip128(); PureMemory.gky_ky.shogiban.ibashoBan_yk00.Set_Koma(km1, tmp_T1); Piece km2 = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, Taikyokusya.T2); tmp_T2 = PureMemory.gky_ky.shogiban.ibashoBan_yk00.CloneBb_Koma(km2); tmp_T2.Bitflip128(); PureMemory.gky_ky.shogiban.ibashoBan_yk00.Set_Koma(km2, tmp_T2); } // 盤面反転、駒の先後も反転だぜ☆(^▽^) } // 持ち駒 { MotigomaItiran tmp = new MotigomaItiran(); foreach (Motigoma mk in Conv_Motigoma.itiran) { MotigomaSyurui mks = Med_Koma.MotiKomaToMotiKomasyrui(mk); Taikyokusya tai = Med_Koma.MotiKomaToTaikyokusya(mk); Motigoma hantenMotikoma = Med_Koma.MotiKomasyuruiAndTaikyokusyaToMotiKoma(mks, Conv_Taikyokusya.Hanten(tai)); tmp.Set(mk, PureMemory.gky_ky.motigomaItiran.yomiMotigomaItiran.Count(hantenMotikoma)); } PureMemory.gky_ky.motigomaItiran.Set(tmp); } }
/// <summary> /// /// </summary> /// <param name="km_removed"></param> /// <param name="bbVer_remove">注意、このメソッド実行後に0になるぜ☆(^~^)</param> /// <param name="yomiKy"></param> /// <param name="dbg_reigai"></param> /// <param name="hint"></param> /// <param name="changing"></param> /// <returns></returns> public void TorinozokuKiki(Piece km_removed, Bitboard bbVer_remove) { Taikyokusya teban = Med_Koma.KomaToTaikyokusya(km_removed); // 1マスずつ、利きを減らしていくぜ☆(^~^) Masu ms_cur; while (bbVer_remove.Ref_PopNTZ(out ms_cur)) { //──────────────────── // まず 駒別を 減らす //──────────────────── // (1)カウントボードの数字を減らす int result_komabetu; CB_kikisuKomabetu.Decrease1(km_removed, ms_cur, out result_komabetu); // (2)「カウントが無くなったら」ビットをOFFにするんだぜ☆(^~^)まるごとOFFにしてはいけないぜ☆(^~^) if (result_komabetu < 1) { Sitdown_Kiki(km_removed, ms_cur); } //──────────────────── // 次に 対局者別を 減らす //──────────────────── // (1)カウントボードの数字を減らす int result_zenbu; CB_kikisuZenbu.Decrease1(teban, ms_cur, out result_zenbu); // (2)「カウントが無くなったら」ビットをOFFにするんだぜ☆(^~^)まるごとOFFにしてはいけないぜ☆(^~^) if (result_zenbu < 1) { Sitdown_KikiZenbu(teban, ms_cur); } } // 現局面より、利きの数が減っているのが正解 }
/// <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> /// 詰んでるか☆(^▽^) /// </summary> /// <returns></returns> public static bool IsTunderu(Taikyokusya tai) { // どうぶつしょうぎ用の詰み判定 switch (PureSettei.gameRule) { case GameRule.DobutuShogi: { return(1 < PureMemory.hot_outeKomasCountAr[(int)tai] && // 両王手で、 PureMemory.hot_bb_nigeroAr[(int)tai].IsEmpty()); // 逃げ道がない場合は、回避不能だぜ☆(^▽^) } case GameRule.HonShogi: { return(1 < PureMemory.hot_outeKomasCountAr[(int)tai] && // 両王手で、 PureMemory.hot_bb_nigeroAr[(int)tai].IsEmpty()); // 逃げ道がない場合は、回避不能だぜ☆(^▽^) } default: { // ルールが分からないので、とりあえず詰んではいないことにするぜ☆(^~^) return(false); } } }