/// <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); }