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]++; } } } }
/// <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)); } }
/// <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> /// /// </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> /// 盤上の駒を取り除く。 /// /// よくある問題 /// ────── /// /// (1)きりんA の右上に きりんB を打つ。 /// (2)きりんB を取り除く。 /// (3)このとき、きりんB の利きも取り除くが、きりんA と被っている利きもある。 /// これを消してしまうと、利きが欠けた きりんA ができてしまい、整合性が取れない。 /// /// </summary> /// <param name="ms_ibasho">取り除く駒がある升</param> /// <param name="km_remove">取り除く駒</param> /// <param name="ms_mirainihaKomagaAru">(飛び利き更新用)</param> /// <param name="updateKiki">偽にすると、利きを更新しません</param> /// <param name="yomiGky"></param> /// <param name="reigai1"></param> /// <returns></returns> public bool TryFail_TorinozokuKoma( Masu ms_ibasho, Piece km_remove, Masu ms_mirainihaKomagaAru, bool updateKiki #if DEBUG , IDebugMojiretu reigai1 #endif ) { Debug.Assert(Conv_Koma.IsOk(km_remove), "km_remove not ok"); Debug.Assert(Conv_Masu.IsBanjo(ms_ibasho), ""); // 取り除いた駒は、どちらの対局者の物か☆(^~^) Taikyokusya tai_removed = Med_Koma.KomaToTaikyokusya(km_remove); //──────────────────────────────────────── // (1)利き表をいじる前☆(^▽^) //──────────────────────────────────────── //────────── // とりあえず、駒を取り除いた状態にするぜ☆(^~^) //────────── TorinozokuKoma(ms_ibasho, km_remove); //────────── // 駒が取り除かれた現状に更新する //────────── if (updateKiki) { // 駒の利き割りの評価値を減らすならここで☆(^~^) kikiBan.TorinozokuKiki(km_remove, ms_ibasho); //────────── // 駒が減った後の、関連する飛び利きを増やす //────────── // 置いた駒がある 縦列きりん、横列きりん、縦列いのしし、左上がりぞう、左下がりぞう を探す foreach (Taikyokusya tai in Conv_Taikyokusya.itiran) { Komasyurui[] ksAr = new Komasyurui[] { Komasyurui.K, Komasyurui.Z, Komasyurui.S, }; foreach (Komasyurui ks in ksAr) { Piece km_forReverse = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai); BitboardsOmatome.KomanoUgokikataYk00.ToSet_Merge( km_forReverse, // 相手番の駒にして、利きを飛ばしてきている位置を調べるのに使う ms_ibasho, // 升 bbTmp_kiki_forOku // リーガルムーブの盤面を、ここに入れるぜ☆(^~^) ); Masu ms_atk; while (bbTmp_kiki_forOku.Ref_PopNTZ(out ms_atk))// 立っているビットを降ろすぜ☆ { kikiBan.OkuKiki(km_forReverse, ms_atk); } } } } return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 盤上の駒を置くぜ☆(^▽^) /// </summary> /// <param name="ms_t1"></param> /// <param name="km_t1"></param> /// <param name="updateKiki">利きを先に作るか、駒を先に並べるか、という循環が発生するのを防ぐために</param> public bool TryFail_OkuKoma( Masu ms_t1, Piece km_t1, bool updateKiki #if DEBUG , IDebugMojiretu reigai1 #endif ) { Debug.Assert(Conv_Koma.IsOk(km_t1), string.Format("置けない駒 km_t1 を置こうとしました。 km_t1={0}", km_t1)); Debug.Assert(Conv_Masu.IsBanjo(ms_t1), string.Format("ms={0}", ms_t1)); // 取り除いた駒は、どちらの対局者の物か☆(^~^) Taikyokusya tai_put = Med_Koma.KomaToTaikyokusya(km_t1); //────────── // とりあえず、盤に駒を置くんだぜ☆(^~^) //────────── OkuKoma(ms_t1, km_t1); //────────── // TODO: 駒が増えた現状に更新する //────────── if (updateKiki) { // 駒の利き割りの評価値を増やすならここで☆(^~^) //────────── // 駒が増えた後の、関連する飛び利きを消す //────────── // 置いた駒がある 縦列きりん、横列きりん、縦列いのしし、左上がりぞう、左下がりぞう を探す foreach (Taikyokusya tai in Conv_Taikyokusya.itiran) { Komasyurui[] ksAr = new Komasyurui[] { Komasyurui.K, Komasyurui.Z, Komasyurui.S, }; foreach (Komasyurui ks in ksAr) { Piece km_reverse = Med_Koma.KomasyuruiAndTaikyokusyaToKoma(ks, tai); //bbTmp_kiki_forOku.Clear(); BitboardsOmatome.KomanoUgokikataYk00.ToSet_Merge( km_reverse, // 相手番の駒にして、利きを飛ばしてきている位置を調べるのに使う ms_t1, // 升 bbTmp_kiki_forOku // リーガルムーブの盤面を、ここに入れるぜ☆(^~^) ); Masu ms_atk; while (bbTmp_kiki_forOku.Ref_PopNTZ(out ms_atk))// 立っているビットを降ろすぜ☆ { kikiBan.TorinozokuKiki(km_reverse, ms_atk); } } } //* // 利きを増やすぜ☆(^~^) kikiBan.OkuKiki( km_t1, // 駒 ms_t1 // 升 ); //*/ } // TODO: 駒割り評価値を増やすならここだぜ☆(^~^) return(Pure.SUCCESSFUL_FALSE); }
/// <summary> /// 盤上の駒を取り除きます /// /// よくある問題 /// ────── /// /// (1)きりんA の右上に きりんB を打つ。 /// (2)きりんB を取り除く。 /// (3)このとき、きりんB の利きも取り除くが、きりんA と被っている利きもある。 /// これを消してしまうと、利きが欠けた きりんA ができてしまい、整合性が取れない。 /// /// </summary> /// <param name="km"></param> /// <param name="ms"></param> public void N240_TorinozokuKoma(Piece km, Masu ms) { BBItiran_Komazenbu.Sitdown(Med_Koma.KomaToTaikyokusya(km), ms); BBItiran_Komabetu.RefBBKoma(km).Sitdown(ms); }
/// <summary> /// 駒を置きます /// </summary> /// <param name="km"></param> /// <param name="ms"></param> public void N240_OkuKoma(Piece km, Masu ms) { BBItiran_Komazenbu.Standup(Med_Koma.KomaToTaikyokusya(km), ms); BBItiran_Komabetu.RefBBKoma(km).Standup(ms); }