/// <summary> /// 差分更新で使う☆(^▽^)駒取り☆ /// </summary> public void Hetta(Option <Phase> optionalPhase, MotiKoma mk) { Hyokati henkaRyo = Conv_MotiKoma.MotikomaHyokati[(int)mk]; this.Increase(optionalPhase, (Hyokati)(-(int)henkaRyo)); this.Increase(Conv_Taikyokusya.Reverse(optionalPhase), henkaRyo); }
/// <summary> /// /// </summary> /// <returns></returns> public static ulong GetMotiKey(Kyokumen.Sindanyo kys, MotiKoma mk) { if (Util_ZobristHashing.Dirty) { Util_ZobristHashing.Tukurinaosi(kys); } return(Util_ZobristHashing.m_motiKeys_[(int)mk][kys.CountMotikoma(mk)]); }
/// <summary> /// 一手詰めの局面かどうか調べるぜ☆(^▽^) /// /// 自分が一手詰めを掛けられるから、この指し手は作らないでおこう、といった使い方がされるぜ☆(^▽^) /// /// FIXME: 持ち駒の打ちにも使えないか☆(^~^)? /// </summary> /// <param name="fukasa"></param> /// <param name="ky"></param> /// <param name="jibun"></param> /// <param name="ms_src">持ち駒の場合、エラー値</param> /// <param name="mks">持ち駒の場合、持駒の種類</param> /// <param name="ms_t1"></param> /// <param name="jibunHioute"></param> /// <returns></returns> public static bool Ittedume_MotiKoma(int fukasa, Kyokumen ky, MotiKoma mk, Masu ms_t1, HiouteJoho jibunHioute, HiouteJoho aiteHioute) { if (!Conv_MotiKoma.IsOk(mk)) { throw new Exception("持ち駒じゃないじゃないか☆(^▽^)www"); } // A B C // ┌──┬──┬──┐ //1│ │▽ら│ │ // ├──┼──┼──┤ //2│▲き│ │▲き│ // ├──┼──┼──┤ //3│ │▲に│▲ら│ // ├──┼──┼──┤ //4│▲ぞ│▲ひ│▲ぞ│ // └──┴──┴──┘ // 盤上の駒を動かすのか、駒台の駒を打つのかによって、利き の形が異なるぜ☆(^~^) Bitboard bb_kiki_t1 = ky.Shogiban.GetKomanoUgokikata(Med_Koma.MotiKomaToKoma(mk), ms_t1); if (!ky.Shogiban.GetBBKoma(aiteHioute.KmRaion).IsIntersect( // 相手らいおんの場所☆ bb_kiki_t1)) // 相手らいおん が、動かした駒の、利きの中に居ないんだったら、一手詰め にはならないぜ☆(^~^) { // FIXME: ステイルメイトは考えてないぜ☆(>_<) return(false); } Koma km_t1 = Med_Koma.MotiKomaToKoma(mk);//t0も同じ // FIXME: ↓駒移動後の、利きを取る必要がある Bitboard bb_jibunKikiNew = new Bitboard(); { // 打による、重ね利きの数を差分更新するぜ☆(^▽^) //, ky.BB_KikiZenbu ky.Shogiban.N100_FuyasuKiki(km_t1, ky.Sindan.CloneKomanoUgoki(km_t1, ms_t1), ky.Sindan);// 移動先の駒の利きを増やすぜ☆(^▽^) // こっちの利きを作り直し bb_jibunKikiNew = ky.Shogiban.ToBitboard_KikisuZenbuPositiveNumber(Med_Koma.MotiKomaToPhase(mk), ky.Sindan); // 打による、重ね利きの数の差分更新を元に戻すぜ☆(^▽^) // , ky.BB_KikiZenbu ky.Shogiban.N100_HerasuKiki(km_t1, ky.Sindan.CloneKomanoUgoki(km_t1, ms_t1), ky.Sindan);// 移動先の駒の利きを減らすぜ☆(^▽^) } // 相手らいおんが逃げようとしていて。 return(aiteHioute.FriendRaion8KinboBB.Clone() // 相手らいおんの8近傍 .Sitdown(ky.Shogiban.GetBBKomaZenbu(aiteHioute.CurrentOptionalPhase)) // 相手の駒がない升 .Sitdown(bb_jibunKikiNew) // こっちの利きがない升 .IsEmpty()); // 相手らいおん が逃げれる升がない場合、詰み☆ }
public MotiKomaItiranImpl Herasu(MotiKoma mk) { ValueMk[(int)mk]--; #if DEBUG if (ValueMk[(int)mk] < 0) { var msg = "error 持駒の数がマイナス"; Logger.Flush(msg); throw new Exception(msg); } #endif return(this); }
public MotiKomaItiranImpl Set(MotiKoma mk, int count) { ValueMk[(int)mk] = count; #if DEBUG if (ValueMk[(int)mk] < 0) { var msg = "error 持駒の数にマイナスをセットした☆"; Logger.Flush(msg); throw new Exception(msg); } #endif return(this); }
/// <summary> /// 反映するぜ☆(^▽^) /// </summary> /// <param name="ky"></param> /// <param name="mk"></param> /// <param name="ninsyo"></param> public void HaneiMotiKoma(Kyokumen ky, MotiKoma mk) { if (DebugOptions.EvaluationHand) { // 駒の位置(評価関数の項目番号)☆ 持ち駒が 0 枚で、-1 の場合もあり☆ int koumokuNo = Util_NikomaKankei.GetKoumokuBango_MotiKoma(ky, mk); if (-1 != koumokuNo) { Util_NikomaKankei.MakeKoumokuBangoHairetu_Subete(ky, Util_NikomaKankei.KoumokuBangoHairetu1); Increase( Util_NikomaKankei.Kazoeru_NikomaKankeiHyokati_ItiTaiTa_SabunKosinYou(ky, koumokuNo, Util_NikomaKankei.KoumokuBangoHairetu1 ) ); } } }
/// <summary> /// 項目番号 K を返すぜ☆(^~^) /// </summary> /// <returns></returns> public static int GetKoumokuBango_MotiKoma(Kyokumen ky, MotiKoma mk) { return(-1); //// 持駒の数 //int mkCount = ky.MotiKomas.Get(mk); //if (0<mkCount) //{ // // 持駒エリア // int mkArea = Conv_MotiKoma.NikomaKankei_MotiKomaArea[(int)mk]; // if (-1 == mkArea) // { // throw new Exception("未定義の持駒指定☆"); // } // return Util_NikomaKankei.MOTIKOMA_PART + mkArea + (1 < mkCount ? 1 : 0); //} //return -1;//該当無し☆ }
public void KesuMotiKoma(Kyokumen ky, MotiKoma mk) { if (DebugOptions.ReduceHand) { // 駒の位置(評価関数の項目番号)☆ 持ち駒が 0 枚で、-1 の場合もあり☆ int koumokuNo = Util_NikomaKankei.GetKoumokuBango_MotiKoma(ky, mk); // Debug.Assert(koumokuNo != -1, $"mk=[{mk}]"); // 減点するぜ☆(^▽^) if (-1 != koumokuNo) { Util_NikomaKankei.MakeKoumokuBangoHairetu_Subete(ky, Util_NikomaKankei.KoumokuBangoHairetu1); Increase((Hyokati)( -(int)Util_NikomaKankei.Kazoeru_NikomaKankeiHyokati_ItiTaiTa_SabunKosinYou(ky, koumokuNo, Util_NikomaKankei.KoumokuBangoHairetu1)//評価値 )); } } }
public static Koma MotiKomaToKoma(MotiKoma mk) { return(MotiKomasyuruiAndPhaseToKoma(MotiKomaToMotiKomasyrui(mk), MotiKomaToPhase(mk))); }
public static bool IsOk(MotiKoma mk) { return(MotiKoma.Z <= mk && mk < MotiKoma.Yososu); }
public static Option <Phase> MotiKomaToPhase(MotiKoma mk) { return(Med_Koma.m_OptionalPhaseOfHand_[(int)mk]); }
public MotiKomaItiranImpl Fuyasu(MotiKoma mk) { ValueMk[(int)mk]++; return(this); }
public static string GetFen(bool isSfen, MotiKoma mk) { return(isSfen ? m_sfen_[(int)mk] : m_dfen_[(int)mk]); }
/// <summary> /// 目視確認用の文字列を返すぜ☆(^▽^) /// </summary> /// <param name="mk"></param> /// <returns></returns> public static void Setumei(MotiKoma mk, StringBuilder syuturyoku) { syuturyoku.Append(Conv_MotiKoma.m_setumeiMojiretu_[(int)mk]); }
public MotiKomaItiranImpl Add(MotiKoma mk, int count) { ValueMk[(int)mk] += count; return(this); }
public int Get(MotiKoma mk) { return(ValueMk[(int)mk]); }
/// <summary> /// 持駒を持っているなら真☆ /// </summary> /// <param name="mk"></param> /// <returns></returns> public bool HasMotiKoma(MotiKoma mk) { return(0 < ValueMk[(int)mk]); }
public static MotiKomasyurui MotiKomaToMotiKomasyrui(MotiKoma mk) { return(Med_Koma.m_MotiKomaToMotiKomasyurui_[(int)mk]); }
//private static Option<T> Option<T>(T white) //{ // throw new NotImplementedException(); //} /// <summary> /// 将棋盤をコンソールへ出力するぜ☆(^▽^) /// コンソールでゲームするのに向いた表示☆ /// </summary> /// <returns></returns> public static void Setumei_NingenGameYo(Kyokumen ky, StringBuilder syuturyoku) { // 1行目 { // 千日手 int sennitite = ky.Konoteme.GetSennititeCount(); if (Const_Game.SENNITITE_COUNT == sennitite) { Conv_Taikyokusya.Setumei_Name(Conv_Taikyokusya.Reverse(ky.CurrentOptionalPhase), syuturyoku); syuturyoku.Append("の着手にて 千日手"); syuturyoku.AppendLine(); } else if (1 < sennitite) { syuturyoku.Append("同一局面反復 "); syuturyoku.Append(sennitite.ToString()); syuturyoku.AppendLine(" 回目"); } else { syuturyoku.AppendLine(); } } // 2行目 { // 何手目 syuturyoku.Append("図は"); syuturyoku.Append(string.Format("{0,3}", ky.Konoteme.ScanNantemadeBango())); syuturyoku.Append("手まで "); // 手番 Conv_Taikyokusya.Setumei_Name(ky.CurrentOptionalPhase, syuturyoku); syuturyoku.Append("の番"); // #仲ルール if (Option_Application.Optionlist.SagareruHiyoko) { syuturyoku.Append(" #仲"); } syuturyoku.AppendLine(); } // 3行目 後手の持ち駒の数 { foreach (MotiKomasyurui mks in Conv_MotiKomasyurui.Itiran) { MotiKoma mk = Med_Koma.MotiKomasyuruiAndPhaseToMotiKoma(mks, OptionalPhase.White); if (ky.MotiKomas.HasMotiKoma(mk)) { syuturyoku.Append(Conv_MotiKomasyurui.GetHyojiName(mks)); syuturyoku.Append(ky.MotiKomas.Get(mk).ToString()); } } syuturyoku.AppendLine(); } // 4行目 { syuturyoku.Append(" "); AppendLine_SujiFugo_Kyokumen(syuturyoku); //syuturyoku.AppendLine(" A B C "); } // 5行目~13行目 // 盤上 { // 5行目 syuturyoku.Append(" "); Util_Information.AppendLine_Top_Kyokumen(1, syuturyoku); // ┌──┬──┬──┐ for (int dan = 0; dan < Option_Application.Optionlist.BanTateHaba; dan++) { // 6,8,10,12行目 syuturyoku.Append(Conv_Kihon.ToZenkakuInteger(dan + 1)); AppendLine_Data_Kyokumen(ky, dan, syuturyoku); if (dan + 1 < Option_Application.Optionlist.BanTateHaba) { // 7,9,11行目 syuturyoku.Append(" "); AppendLine_Middle(1, syuturyoku);//├──┼──┼──┤ } } // 13行目 syuturyoku.Append(" "); AppendLine_Bottom(1, syuturyoku);//└──┴──┴──┘ } // 14行目 { // 先手の持ち駒の数 foreach (MotiKomasyurui mks in Conv_MotiKomasyurui.Itiran) { MotiKoma mk = Med_Koma.MotiKomasyuruiAndPhaseToMotiKoma(mks, OptionalPhase.Black); if (ky.MotiKomas.HasMotiKoma(mk)) { syuturyoku.Append(Conv_MotiKomasyurui.GetHyojiName(mks)); syuturyoku.Append(ky.MotiKomas.Get(mk).ToString()); } } syuturyoku.AppendLine(); } }
public static bool TryParseFen(bool isSfen, char moji, out MotiKoma out_koma) { if (isSfen) { switch (moji) { // 角(対局者1、対局者2) case 'B': out_koma = MotiKoma.Z; return(true); case 'b': out_koma = MotiKoma.z; return(true); case 'R': out_koma = MotiKoma.K; return(true); case 'r': out_koma = MotiKoma.k; return(true); case 'P': out_koma = MotiKoma.H; return(true); case 'p': out_koma = MotiKoma.h; return(true); case 'G': out_koma = MotiKoma.I; return(true); case 'g': out_koma = MotiKoma.i; return(true); case 'S': out_koma = MotiKoma.Neko; return(true); case 's': out_koma = MotiKoma.neko; return(true); case 'N': out_koma = MotiKoma.U; return(true); case 'n': out_koma = MotiKoma.u; return(true); case 'L': out_koma = MotiKoma.S; return(true); case 'l': out_koma = MotiKoma.s; return(true); default: out_koma = MotiKoma.Yososu; return(false); } } else { switch (moji) { // ぞう(対局者1、対局者2) case 'Z': out_koma = MotiKoma.Z; return(true); case 'z': out_koma = MotiKoma.z; return(true); case 'K': out_koma = MotiKoma.K; return(true); case 'k': out_koma = MotiKoma.k; return(true); case 'H': out_koma = MotiKoma.H; return(true); case 'h': out_koma = MotiKoma.h; return(true); case 'I': out_koma = MotiKoma.I; return(true); case 'i': out_koma = MotiKoma.i; return(true); case 'N': out_koma = MotiKoma.Neko; return(true); case 'n': out_koma = MotiKoma.neko; return(true); case 'U': out_koma = MotiKoma.U; return(true); case 'u': out_koma = MotiKoma.u; return(true); case 'S': out_koma = MotiKoma.S; return(true); case 's': out_koma = MotiKoma.s; return(true); default: out_koma = MotiKoma.Yososu; return(false); } } }