public void Log1(Playerside pside_genTeban3) { this.BrdMove.Caption = "移動可能_" + Converter04.MoveToStringForLog(this.Move, pside_genTeban3); this.BrdMove.Tesumi = this.Tesumi_yomiCur; this.BrdMove.NounaiYomiDeep = this.YomuDeep; this.BrdMove.GenTeban = pside_genTeban3;// 現手番 }
public static void SplitGroup_Ikusa( out SySet <SyElement> masus_seme_IKUSA, out SySet <SyElement> masus_kurau_IKUSA, SkyConst src_Sky, Fingers fingers_kurau_IKUSA, //戦駒(喰らう側) Fingers fingers_seme_IKUSA //戦駒(利きを調べる側) ) { masus_seme_IKUSA = Converter04.Fingers_ToMasus(fingers_seme_IKUSA, src_Sky); // 盤上のマス(利きを調べる側の駒) masus_kurau_IKUSA = Converter04.Fingers_ToMasus(fingers_kurau_IKUSA, src_Sky); // 盤上のマス(喰らう側の駒) }
/// <summary> /// ************************************************************************************************************************ /// 棋譜用の符号テキスト(*1)を作ります。 /// ************************************************************************************************************************ /// /// *1…「▲5五銀上」など。 /// /// “同”表記に「置き換えない」バージョンです。 /// /// </summary> /// <param name="move"></param> /// <param name="previousKomaP"></param> /// <returns></returns> public string ToText_NoUseDou( RO_ShootingStarlight move ) { StringBuilder sb = new StringBuilder(); RO_Star_Koma koma = Util_Koma.AsKoma(move.Now); sb.Append(Converter04.Pside_ToStr(koma.Pside)); //------------------------------ // “同”に変換せず、“筋・段”をそのまま出します。 //------------------------------ int suji; int dan; Util_MasuNum.MasuToSuji(koma.Masu, out suji); Util_MasuNum.MasuToDan(koma.Masu, out dan); sb.Append(ConverterKnSh.Int_ToArabiaSuji(suji)); sb.Append(ConverterKnSh.Int_ToKanSuji(dan)); //------------------------------ // “歩”とか。“全”ではなく“成銀” <符号用> //------------------------------ sb.Append(KomaSyurui14Array.Fugo[(int)this.Syurui]); //------------------------------ // “右”とか //------------------------------ sb.Append(Converter04.MigiHidari_ToStr(this.MigiHidari)); //------------------------------ // “寄”とか //------------------------------ sb.Append(Converter04.AgaruHiku_ToStr(this.AgaruHiku)); //------------------------------ // “成”とか //------------------------------ sb.Append(Converter04.Nari_ToStr(this.Nari)); //------------------------------ // “打”とか //------------------------------ sb.Append(Converter04.Bool_ToDa(this.DaHyoji)); return(sb.ToString()); }
public static string BoardFileLog_ToJsonStr(GraphicalLog_File boardFileLog1) { StringBuilder sb_json_boardsLog = new StringBuilder(); foreach (GraphicalLog_Board boardLog1 in boardFileLog1.boards) { // 指し手。分かれば。 string moveStr = Converter04.MoveToStringForLog(boardLog1.moveOrNull, boardLog1.GenTeban); //string oldCaption = boardLog1.Caption; //boardLog1.Caption += "_" + moveStr; sb_json_boardsLog.Append(boardLog1.ToJsonStr()); //boardLog1.Caption = oldCaption; } return(sb_json_boardsLog.ToString()); }
public static void SplitGroup_Teban( out Playerside tebanSeme, //手番(利きを調べる側) out Playerside tebanKurau, //手番(喰らう側) bool isAiteban, Playerside pside_genTeban3 ) { if (isAiteban) { tebanSeme = Converter04.AlternatePside(pside_genTeban3); tebanKurau = pside_genTeban3; } else { tebanSeme = pside_genTeban3; tebanKurau = Converter04.AlternatePside(pside_genTeban3); } }
/// <summary> /// 変換「各(自駒が動ける升)」→「各(自駒が動ける手)」 /// </summary> /// <param name="komaBETUSusumeruMasus"></param> /// <returns></returns> public static Maps_OneAndMulti <Finger, ShootingStarlightable> KomaBETUSusumeruMasusToKomaBETUAllMoves( List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus, Node <ShootingStarlightable, KyokumenWrapper> siteiNode_genzai ) { Maps_OneAndMulti <Finger, ShootingStarlightable> komabetuAllMove = new Maps_OneAndMulti <Finger, ShootingStarlightable>(); komaBETUSusumeruMasus.Foreach_Entry((Finger figKoma, SySet <SyElement> susumuMasuSet, ref bool toBreak) => { RO_Star_Koma srcKoma = Util_Koma.AsKoma(siteiNode_genzai.Value.ToKyokumenConst.StarlightIndexOf(figKoma).Now); foreach (SyElement susumuMasu in susumuMasuSet.Elements) { // 移動先の駒 RO_Star_Koma dstKoma = new RO_Star_Koma( srcKoma.Pside, Masu_Honshogi.Items_All[Util_Masu.AsMasuNumber(susumuMasu)], srcKoma.Haiyaku//TODO:ここで、駒の種類が「成り」に上書きされているバージョンも考えたい ); ShootingStarlightable move = new RO_ShootingStarlight( //figKoma,//駒 srcKoma, // 移動元 dstKoma, // 移動先 PieceType.None //取った駒不明 ); komabetuAllMove.AddOverwrite(figKoma, move); // これが通称【水際のいんちきプログラム】なんだぜ☆ // 必要により、【成り】の指し手を追加します。 Converter04.AddKomaBETUAllNariMoves( komabetuAllMove, figKoma, srcKoma, dstKoma ); } }); //Converter04.AssertNariMove(komabetuAllMove, "#KomabetuMasus_ToKomabetuAllMove");//ここはOK return(komabetuAllMove); }
/// <summary> /// これが通称【水際のいんちきプログラム】なんだぜ☆ /// 必要により、【成り】の指し手を追加します。 /// </summary> private static void AddKomaBETUAllNariMoves( Maps_OneAndMulti <Finger, ShootingStarlightable> komaBETUAllMoves, Finger figKoma, RO_Star_Koma srcKoma, RO_Star_Koma dstKoma ) { bool isPromotionable; if (!Converter04.IsPromotionable(out isPromotionable, srcKoma, dstKoma)) { goto gt_EndMethod; } // 成りの資格があれば、成りの指し手を作ります。 if (isPromotionable) { //MessageBox.Show("成りの資格がある駒がありました。 src=["+srcKoma.Masu.Word+"]["+srcKoma.Syurui+"]"); ShootingStarlightable move = new RO_ShootingStarlight( //figKoma,//駒 srcKoma,// 移動元 new RO_Star_Koma( dstKoma.Pside, dstKoma.Masu, KomaSyurui14Array.ToNariCase(dstKoma.Syurui) //強制的に【成り】に駒の種類を変更 ), // 移動先 PieceType.None //取った駒不明 ); // TODO: 一段目の香車のように、既に駒は成っている場合があります。無い指し手だけ追加するようにします。 komaBETUAllMoves.AddNotOverwrite(figKoma, move); } gt_EndMethod: ; }
/// <summary> /// ロードした内容を確認するときに使います。 /// </summary> /// <returns></returns> public static string LogString() { StringBuilder sb = new StringBuilder(); foreach (KeyValuePair <Kh185, Dictionary <int, Kh185> > entry1 in ForcePromotionArray.HaiyakuMap) { sb.Append(entry1.Key); sb.Append(": "); foreach (KeyValuePair <int, Kh185> entry2 in entry1.Value) { sb.Append( Converter04.Masu_ToKanji(new Basho(entry2.Key)) ); sb.Append("."); sb.Append(entry2.Value); sb.Append(" "); } sb.AppendLine(); } return(sb.ToString()); }
/// <summary> /// 駒別の進めるマスを返します。 /// /// 指定された局面で、指定された手番の駒の、移動可能マスを算出します。 /// 利きを調べる目的ではありません。 /// /// 「手目」は判定できません。 /// /// </summary> /// <param name="kouho"></param> /// <param name="sbGohosyu"></param> /// <param name="logger"></param> public static void LA_Get_KomaBETUSusumeruMasus( out List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus, MmGenjo_MovableMasu mmGenjo, MmLogGenjo log_orNull ) { if (null != log_orNull) { log_orNull.Log1(mmGenjo.Pside_genTeban3); } // 《1》 移動可能場所 komaBETUSusumeruMasus = new List_OneAndMulti <Finger, SySet <SyElement> >(); { // // 《1.1》 手番を2つのグループに分類します。 // // ┌─手番──────┬──────┐ // │ │ │ // │ 利きを調べる側 │ 喰らう側 │ // └─────────┴──────┘ Playerside tebanSeme; //手番(利きを調べる側) Playerside tebanKurau; //手番(喰らう側) { Util_MovableMove.SplitGroup_Teban(out tebanSeme, out tebanKurau, mmGenjo.IsAiteban, mmGenjo.Pside_genTeban3); if (null != log_orNull) { log_orNull.Log2(tebanSeme, tebanKurau); } } // // 《1.2》 駒を4つのグループに分類します。 // // ┌─駒──────────┬─────────┐ // │ │ │ // │ 利きを調べる側の戦駒 │ 喰らう側の戦駒 │ // ├────────────┼─────────┤ // │ │ │ // │ 利きを調べる側の持駒 │ 喰らう側の持駒 │ // └────────────┴─────────┘ // Fingers fingers_seme_IKUSA; //戦駒(利きを調べる側) Fingers fingers_kurau_IKUSA; //戦駒(喰らう側) Fingers fingers_seme_MOTI; // 持駒(利きを調べる側) Fingers fingers_kurau_MOTI; // 持駒(喰らう側) { Util_Things.AAABAAAA_SplitGroup(out fingers_seme_IKUSA, out fingers_kurau_IKUSA, out fingers_seme_MOTI, out fingers_kurau_MOTI, mmGenjo.Src_Sky, tebanSeme, tebanKurau); if (null != log_orNull) { log_orNull.Log3(mmGenjo.Src_Sky, tebanKurau, tebanSeme, fingers_kurau_IKUSA, fingers_kurau_MOTI, fingers_seme_IKUSA, fingers_seme_MOTI); } } // // 《1.3》 駒を2つのグループに分類します。 // // ┌─盤上のマス───┬──────┐ // │ │ │ // │ 利きを調べる側 │ 喰らう側 │ // └─────────┴──────┘ // SySet <SyElement> masus_seme_IKUSA; // 盤上のマス(利きを調べる側の駒) SySet <SyElement> masus_kurau_IKUSA; // 盤上のマス(喰らう側の駒) { Util_MovableMove.SplitGroup_Ikusa(out masus_seme_IKUSA, out masus_kurau_IKUSA, mmGenjo.Src_Sky, fingers_kurau_IKUSA, fingers_seme_IKUSA); // 駒のマスの位置は、特にログに取らない。 } // 《1.4》 Maps_OneAndOne <Finger, SySet <SyElement> > kmSusumeruMasus_seme_IKUSA; if (null != log_orNull) { kmSusumeruMasus_seme_IKUSA = Util_Things.Get_KmEffect_seme_IKUSA( fingers_seme_IKUSA, masus_seme_IKUSA, masus_kurau_IKUSA, mmGenjo.Src_Sky, log_orNull.Enable, Converter04.MoveToStringForLog(log_orNull.Move, mmGenjo.Pside_genTeban3) );// 盤上の駒の移動できる場所 } else { kmSusumeruMasus_seme_IKUSA = Util_Things.Get_KmEffect_seme_IKUSA( fingers_seme_IKUSA, masus_seme_IKUSA, masus_kurau_IKUSA, mmGenjo.Src_Sky, false, //log.Enable, "" ); // 盤上の駒の移動できる場所 } // 持ち駒を置ける場所 List_OneAndMulti <Finger, SySet <SyElement> > sMsSusumeruMasus_seme_MOTI; if (null != log_orNull) { sMsSusumeruMasus_seme_MOTI = Util_Things.Get_Move_Moti( fingers_seme_MOTI, masus_seme_IKUSA, masus_kurau_IKUSA, mmGenjo.Src_Sky, Converter04.MoveToStringForLog(log_orNull.Move, mmGenjo.Pside_genTeban3) ); } else { sMsSusumeruMasus_seme_MOTI = Util_Things.Get_Move_Moti( fingers_seme_MOTI, masus_seme_IKUSA, masus_kurau_IKUSA, mmGenjo.Src_Sky, "" ); } if (null != log_orNull) { log_orNull.Log4(mmGenjo.Src_Sky, tebanSeme, kmSusumeruMasus_seme_IKUSA); } try { // 《1》 = 《1.4》の戦駒+持駒 // 盤上の駒の移動できる場所を足します。 komaBETUSusumeruMasus.AddRange_New(kmSusumeruMasus_seme_IKUSA); // 持ち駒の置ける場所を足します。 komaBETUSusumeruMasus.AddRange_New(sMsSusumeruMasus_seme_MOTI); } catch (Exception ex) { //>>>>> エラーが起こりました。 throw new Exception($"{ex.GetType().Name} {ex.Message}:ランダムチョイス(50):"); } } }
/// <summary> /// 0.0d ~100.0d の範囲で、評価値を返します。数字が大きい方がグッドです。 /// </summary> /// <param name="input_node"></param> /// <param name="playerInfo"></param> /// <returns></returns> public override void Keisan(out KyHyokaItem kyokumenScore, KyHandanArgs args) { double score; SkyConst src_Sky = args.Node.Value.ToKyokumenConst; // // 「紐が付いていない駒の少なさ」による加点。 // int mikataHimoduki = 0; // 味方の駒に、味方の駒の利きが1つ被っていれば+1。 int mikataNeraware = 0; // 味方の駒に、相手の駒の利きが1つ被っていれば+1。 int aiteHimoduki = 0; // 相手の駒に、相手の駒の利きが1つ被っていれば+1。 int aiteNeraware = 0; // 相手の駒に、味方の駒の利きが1つ被っていれば+1。 List <string> mikataYaburareMasu = new List <string>(); int aiteWin = 0; // 利きの枚数で相手が勝っていた件数。 List <string> aiteYaburareMasu = new List <string>(); int mikataWin = 0; // 利きの枚数で味方が勝っていた件数。 // // 駒の利きの計算。 // KomanoKiki komanoKiki = KomanoKikiImpl.MasuBETUKikisu(src_Sky, args.Node.Tebanside); // // 味方の駒があるマスの得点は、マイナスなら集計。(減点法) // 敵の駒があるマスの得点は、プラスなら集計。(減点法) // // 駒は40枚あり、貫通して加点するのもある。 // foreach (Finger figKoma in Finger_Honshogi.Items_KomaOnly)// 全駒 { RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(figKoma).Now); if (Okiba.ShogiBan != Util_Masu.Masu_ToOkiba(koma.Masu)) { goto gt_Next2; } if (args.PlayerInfo.Playerside == koma.Pside) { // 味方の駒 // その升に利いている味方の利きの数。 int mikataKiki = komanoKiki.Kikisu_AtMasu_Mikata[Util_Masu.AsMasuNumber(koma.Masu)]; // その升に利いている相手の利きの数。 int aiteKiki = komanoKiki.Kikisu_AtMasu_Teki[Util_Masu.AsMasuNumber(koma.Masu)]; mikataHimoduki += mikataKiki; mikataNeraware += aiteKiki; // 破られる場合 if (mikataKiki < aiteKiki) { aiteWin++; mikataYaburareMasu.Add(Converter04.Masu_ToKanji(koma.Masu)); } } else { // 相手の駒 // その升に利いている相手の利きの数。 int aiteKiki = komanoKiki.Kikisu_AtMasu_Mikata[Util_Masu.AsMasuNumber(koma.Masu)]; // その升に利いている味方の利きの数。 int mikataKiki = komanoKiki.Kikisu_AtMasu_Teki[Util_Masu.AsMasuNumber(koma.Masu)]; aiteHimoduki = aiteKiki; aiteNeraware = mikataKiki; // 破られる場合 if (aiteKiki < mikataKiki) { mikataWin++; aiteYaburareMasu.Add(Converter04.Masu_ToKanji(koma.Masu)); } } gt_Next2: ; } // 集計。 score = (double)(mikataWin - aiteWin) * 1.0 + 50.0d; string meisai = ""; #if DEBUG // 明細 { StringBuilder sb = new StringBuilder(); sb.Append(" " + score); sb.Append("点 "); sb.Append(" 衝突箇所勝ち数=" + (mikataWin - aiteWin)); sb.Append(" 味方が破られる" + aiteWin + "箇所"); foreach (string s in mikataYaburareMasu) { sb.Append("["); sb.Append(s); sb.Append("]"); } sb.Append(" 相手が破られる" + mikataWin + "箇所"); foreach (string s in aiteYaburareMasu) { sb.Append("["); sb.Append(s); sb.Append("]"); } meisai = sb.ToString(); } #endif kyokumenScore = new KyHyoka100limitItemImpl(args.TenonagareGenjo.ScoreKeisu, score, meisai); }
/// <summary> /// まず前提として、 /// 現手番の「被王手の局面」だけがピックアップされます。 /// これはつまり、次の局面がないときは、その枝は投了ということです。 /// </summary> /// <param name="enableLog"></param> /// <param name="isHonshogi"></param> /// <param name="yomuDeep"></param> /// <param name="tesumi_yomiCur"></param> /// <param name="pside_yomiCur"></param> /// <param name="node_yomiCur"></param> /// <param name="logF_moveKiki"></param> /// <param name="logTag"></param> /// <returns>複数のノードを持つハブ・ノード</returns> private static KifuNode WAAAA_CreateNextNodes( MoveGenGenjo genjo, KifuNode node_yomiCur, SsssLogGenjo log ) { // 利きから、被王手の局面を除いたハブノード // このハブ・ノード自身は空っぽで、ハブ・ノードの次ノードが、次局面のリストになっています。 KifuNode hubNode; { // ①現手番の駒の移動可能場所_被王手含む List_OneAndMulti <Finger, SySet <SyElement> > komaBETUSusumeruMasus; { GraphicalLog_Board logBrd_move1 = new GraphicalLog_Board();// 盤1個分のログの準備 Util_MovableMove.LA_Get_KomaBETUSusumeruMasus( out komaBETUSusumeruMasus, //進めるマス new MmGenjo_MovableMasuImpl( genjo.Args.IsHonshogi, //本将棋か node_yomiCur.Value.ToKyokumenConst, //現在の局面 genjo.Pside_teban, //手番 false //相手番か ), new MmLogGenjoImpl( log.EnableLog, //ログを出力するかfalse, logBrd_move1, //ログ? genjo.YomuDeep, //読みの深さ genjo.Tesumi_yomiCur, //手済み node_yomiCur.Key //指し手 ) ); MoveGenRoutine.Log1(genjo, node_yomiCur, logBrd_move1);//ログ試し } // ②利きから、被王手の局面を除いたハブノード if (genjo.Args.IsHonshogi) { Maps_OneAndMulti <Finger, ShootingStarlightable> komaBETUAllMoves = Converter04.KomaBETUSusumeruMasusToKomaBETUAllMoves(komaBETUSusumeruMasus, node_yomiCur); Converter04.AssertNariMove(komaBETUAllMoves, "#WAAAA_CreateNextNodes(1)"); // 本将棋の場合、王手されている局面は削除します。 hubNode = Util_LegalMove.LA_RemoveMate( genjo.Args.IsHonshogi, komaBETUAllMoves, genjo.YomuDeep, genjo.Tesumi_yomiCur, genjo.Pside_teban, node_yomiCur, log.EnableLog, genjo.Args.LogF_moveKiki,//利き用 "読みNextルーチン"); Converter04.AddNariMove(node_yomiCur, hubNode); Converter04.AssertNariMove(hubNode, "#WAAAA_CreateNextNodes(2)");//ここで消えていた☆ } else { //そのまま変換 Dictionary <ShootingStarlightable, KyokumenWrapper> ss = Converter04.KomabetuMasusToMovebetuSky( komaBETUSusumeruMasus, node_yomiCur.Value.ToKyokumenConst, genjo.Pside_teban); hubNode = Converter04.MovebetuSky_ToHubNode(ss, KifuNodeImpl.GetReverseTebanside(genjo.Pside_teban)); } } return(hubNode); }
/// <summary> /// これが通称【水際のいんちきプログラム】なんだぜ☆ /// 必要により、【成り】の指し手を追加します。 /// </summary> public static void AddNariMove( KifuNode node_yomiCur, KifuNode hubNode ) { Dictionary <string, ShootingStarlightable> newMoveList = new Dictionary <string, ShootingStarlightable>(); hubNode.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) => { RO_Star_Koma srcKoma = Util_Koma.AsKoma(nextNode.Key.LongTimeAgo); RO_Star_Koma dstKoma = Util_Koma.AsKoma(nextNode.Key.Now); bool isPromotionable; if (!Converter04.IsPromotionable(out isPromotionable, srcKoma, dstKoma)) { // エラー goto gt_Next1; } if (isPromotionable) { ShootingStarlightable move = new RO_ShootingStarlight( //figKoma,//駒 srcKoma,// 移動元 new RO_Star_Koma( dstKoma.Pside, dstKoma.Masu, KomaSyurui14Array.ToNariCase(dstKoma.Syurui) //強制的に【成り】に駒の種類を変更 ), // 移動先 PieceType.None //取った駒不明 ); // TODO: 一段目の香車のように、既に駒は成っている場合があります。無い指し手だけ追加するようにします。 string moveStr = Util_Sky.ToSfenMoveText(move);//重複防止用のキー if (!newMoveList.ContainsKey(moveStr)) { newMoveList.Add(moveStr, move); } } gt_Next1: ; }); // 新しく作った【成り】の指し手を追加します。 foreach (ShootingStarlightable newMove in newMoveList.Values) { // 指す前の駒 RO_Star_Koma sasumaenoKoma = Util_Koma.AsKoma(newMove.LongTimeAgo); // 指した駒 RO_Star_Koma sasitaKoma = Util_Koma.AsKoma(newMove.Now); // 現局面 SkyConst src_Sky = node_yomiCur.Value.ToKyokumenConst; // 指す前の駒を、盤上のマス目で指定 Finger figSasumaenoKoma = Util_Sky.Fingers_AtMasuNow(src_Sky, sasumaenoKoma.Masu).ToFirst(); // 新たな局面 KyokumenWrapper kyokumenWrapper = new KyokumenWrapper(Util_Sasu.Sasu(src_Sky, figSasumaenoKoma, sasitaKoma.Masu, KifuNodeImpl.GetReverseTebanside(node_yomiCur.Tebanside))); try { string moveStr = Util_Sky.ToSfenMoveText(newMove); if (!hubNode.ContainsKey_NextNodes(moveStr)) { // 指し手が既存でない局面だけを追加します。 hubNode.Add_NextNode( moveStr, new KifuNodeImpl( newMove, kyokumenWrapper,//node_yomiCur.Value,//FIXME: 成りの手を指した局面を作りたい。 KifuNodeImpl.GetReverseTebanside(node_yomiCur.Tebanside) ) ); } } catch (Exception ex) { // 既存の指し手 StringBuilder sb = new StringBuilder(); { hubNode.Foreach_NextNodes((string key, Node <ShootingStarlightable, KyokumenWrapper> nextNode, ref bool toBreak) => { sb.Append("「"); sb.Append(Util_Sky.ToSfenMoveText(nextNode.Key)); sb.Append("」"); }); } //>>>>> エラーが起こりました。 // どうにもできないので ログだけ取って、上に投げます。 Logger.Error(ex.GetType().Name + " " + ex.Message + ":新しく作った「成りの指し手」を既存ノードに追加していた時です。:追加したい指し手=「" + Util_Sky.ToSfenMoveText(newMove) + "」既存の手=" + sb.ToString()); throw; } } // gt_EndMethod: // ; }
/// <summary> /// 次の1手データを作ります(*1) /// /// *1…符号1「▲68銀上」を元に、「7968」を作ります。 /// /// <[再生]、[コマ送り]で呼び出されます> /// </summary> /// <returns></returns> public static void ExecuteJfugo_FromTextSub( string strPside, //▲△ string strSuji, //123…9、123…9、一二三…九 string strDan, //123…9、123…9、一二三…九 string strDou, // “同” string strSrcSyurui, //(歩|香|桂|… string strMigiHidari, // 右|左… string strAgaruHiku, // 上|引 string strNariNarazu, //成|不成 string strDaHyoji, //打 out ShootingStarlightable move, KifuTree kifu ) { Node <ShootingStarlightable, KyokumenWrapper> siteiNode = kifu.CurNode; SkyConst src_Sky = siteiNode.Value.ToKyokumenConst; //------------------------------ // 符号確定 //------------------------------ MigiHidari migiHidari = Converter04.Str_ToMigiHidari(strMigiHidari); AgaruHiku agaruHiku = Converter04.Str_ToAgaruHiku(strAgaruHiku); // 上|引 NariNarazu nariNarazu = Converter04.Nari_ToBool(strNariNarazu); //成 DaHyoji daHyoji = Converter04.Str_ToDaHyoji(strDaHyoji); //打 PieceType srcSyurui = Converter04.Str_ToSyurui(strSrcSyurui); //------------------------------ // //------------------------------ Playerside pside = Converter04.Pside_ToEnum(strPside); SyElement dstMasu; if ("同" == strDou) { // 1手前の筋、段を求めるのに使います。 RO_Star_Koma koma = Util_Koma.AsKoma(siteiNode.Key.Now); dstMasu = koma.Masu; } else { dstMasu = Util_Masu.OkibaSujiDanToMasu( Okiba.ShogiBan, ConverterKnSh.Suji_ToInt(strSuji), ConverterKnSh.Suji_ToInt(strDan) ); } // TODO: 駒台にあるかもしれない。 Okiba srcOkiba1 = Okiba.ShogiBan; //Okiba.FUMEI_FUGO_YOMI_CHOKUGO;// Okiba.SHOGIBAN; if (DaHyoji.Visible == daHyoji) { if (Playerside.P2 == pside) { srcOkiba1 = Okiba.Gote_Komadai; } else { srcOkiba1 = Okiba.Sente_Komadai; } } // SyElement dst1 = dstMasu; Finger foundKoma = Fingers.Error_1; //---------- // 駒台の駒を(明示的に)打つなら //---------- bool utsu = false;//駒台の駒を打つなら真 if (DaHyoji.Visible == daHyoji) { utsu = true; goto gt_EndShogiban; } if (PieceType.P == srcSyurui) { //************************************************************ // 歩 //************************************************************ //---------- // 候補マス //---------- //┌─┬─┬─┐ //│ │ │ │ //├─┼─┼─┤ //│ │至│ │ //├─┼─┼─┤ //│ │E│ │ //└─┴─┴─┘ bool isE = true; SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isE) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻引(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } } else if (PieceType.R == srcSyurui) { #region 飛 //************************************************************ // 飛 //************************************************************ //---------- // 候補マス //---------- // ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ // │ │ │ │ │ │ │ │ │A7│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A6│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A5│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A4│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A3│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A2│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A1│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A0│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │G7│G6│G5│G4│G3│G2│G1│G0│至│C0│C1│C2│C3│C4│C5│C6│C7│ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E0│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E1│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E2│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E3│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E4│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E5│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E6│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E7│ │ │ │ │ │ │ │ │ // └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ bool isA = true; bool isC = true; bool isE = true; bool isG = true; switch (agaruHiku) { case AgaruHiku.Yoru: isA = false; isE = false; break; case AgaruHiku.Agaru: isA = false; isC = false; isG = false; break; case AgaruHiku.Hiku: isC = false; isE = false; isG = false; break; } switch (migiHidari) { case MigiHidari.Migi: isA = false; isE = false; isG = false; break; case MigiHidari.Hidari: isA = false; isC = false; isE = false; break; case MigiHidari.Sugu: isA = false; isC = false; isG = false; break; } SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isA) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻上(pside, dst1)); } if (isC) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻射(pside, dst1)); } if (isE) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻引(pside, dst1)); } if (isG) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻滑(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.B == srcSyurui) { #region 角 //************************************************************ // 角 //************************************************************ //---------- // 候補マス //---------- // ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ // │H7│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │B7│ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │H6│ │ │ │ │ │ │ │ │ │ │ │ │ │B6│ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │H5│ │ │ │ │ │ │ │ │ │ │ │B5│ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │H4│ │ │ │ │ │ │ │ │ │B4│ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │H3│ │ │ │ │ │ │ │B3│ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │H2│ │ │ │ │ │B2│ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │H1│ │ │ │B1│ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │H0│ │B0│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │至│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │F0│ │D0│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │F1│ │ │ │D1│ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │F2│ │ │ │ │ │D2│ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │F3│ │ │ │ │ │ │ │D3│ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │F4│ │ │ │ │ │ │ │ │ │D4│ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │F5│ │ │ │ │ │ │ │ │ │ │ │D5│ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │F6│ │ │ │ │ │ │ │ │ │ │ │ │ │D6│ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │F7│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │D7│ // └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ bool isB = true; bool isD = true; bool isF = true; bool isH = true; switch (agaruHiku) { case AgaruHiku.Yoru: isB = false; isD = false; isF = false; isH = false; break; case AgaruHiku.Agaru: isB = false; isH = false; break; case AgaruHiku.Hiku: isB = false; isH = false; break; } switch (migiHidari) { case MigiHidari.Migi: isF = false; isH = false; break; case MigiHidari.Hidari: isB = false; isD = false; break; case MigiHidari.Sugu: isD = false; isF = false; break; } SySet_Default <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isB) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻昇(pside, dst1)); } if (isD) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻沈(pside, dst1)); } if (isF) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻降(pside, dst1)); } if (isH) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻浮(pside, dst1)); } //---------- // 候補マスB //---------- if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.L == srcSyurui) { #region 香 //************************************************************ // 香 //************************************************************ //---------- // 候補マス //---------- // ┌─┬─┬─┐ // │ │至│ │ // ├─┼─┼─┤ // │ │E0│ │ // ├─┼─┼─┤ // │ │E1│ │ // ├─┼─┼─┤ // │ │E2│ │ // ├─┼─┼─┤ // │ │E3│ │ // ├─┼─┼─┤ // │ │E4│ │ // ├─┼─┼─┤ // │ │E5│ │ // ├─┼─┼─┤ // │ │E6│ │ // ├─┼─┼─┤ // │ │E7│ │ // └─┴─┴─┘ bool isE = true; SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isE) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻引(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.N == srcSyurui) { #region 桂 //************************************************************ // 桂 //************************************************************ //---------- // 候補マス //---------- //┌─┐ ┌─┐ //│ │ │ │ //├─┼─┼─┤ //│ │ │ │ //├─┼─┼─┤ //│ │至│ │先手から見た図 //├─┼─┼─┤ //│ │ │ │ //├─┼─┼─┤ //│J│ │I│ //└─┘ └─┘ bool isI = true; bool isJ = true; switch (agaruHiku) { case AgaruHiku.Yoru: isI = false; isJ = false; break; case AgaruHiku.Agaru: break; case AgaruHiku.Hiku: isI = false; isJ = false; break; } switch (migiHidari) { case MigiHidari.Migi: isJ = false; break; case MigiHidari.Hidari: isI = false; break; case MigiHidari.Sugu: isI = false; isJ = false; break; } SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isI) { srcAll.AddSupersets(KomanoKidou.SrcKeimatobi_戻跳(pside, dst1)); } if (isJ) { srcAll.AddSupersets(KomanoKidou.SrcKeimatobi_戻駆(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.S == srcSyurui) { #region 銀 //************************************************************ // 銀 //************************************************************ //---------- // 候補マス //---------- //┌─┬─┬─┐ //│H│ │B│ //├─┼─┼─┤ //│ │至│ │先手から見た図 //├─┼─┼─┤ //│F│E│D│ //└─┴─┴─┘ bool isB = true; bool isD = true; bool isE = true; bool isF = true; bool isH = true; switch (agaruHiku) { case AgaruHiku.Yoru: isB = false; isD = false; isE = false; isF = false; isH = false; break; case AgaruHiku.Agaru: isB = false; isH = false; break; case AgaruHiku.Hiku: isD = false; isE = false; isF = false; break; } switch (migiHidari) { case MigiHidari.Migi: isE = false; isF = false; isH = false; break; case MigiHidari.Hidari: isB = false; isD = false; isE = false; break; case MigiHidari.Sugu: isB = false; isD = false; isF = false; isH = false; break; } SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isB) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻昇(pside, dst1)); } if (isD) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻沈(pside, dst1)); } if (isE) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻引(pside, dst1)); } if (isF) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻降(pside, dst1)); } if (isH) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻浮(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if ( PieceType.G == srcSyurui || PieceType.PP == srcSyurui || PieceType.PL == srcSyurui || PieceType.PN == srcSyurui || PieceType.PS == srcSyurui ) { #region △金、△と金、△成香、△成桂、△成銀 //************************************************************ // △金、△と金、△成香、△成桂、△成銀 //************************************************************ //---------- // 候補マス //---------- //┌─┬─┬─┐ //│ │A│ │ //├─┼─┼─┤ //│G│至│C│先手から見た図 //├─┼─┼─┤ //│F│E│D│ //└─┴─┴─┘ bool isA = true; bool isC = true; bool isD = true; bool isE = true; bool isF = true; bool isG = true; switch (agaruHiku) { case AgaruHiku.Yoru: isA = false; isD = false; isE = false; isF = false; break; case AgaruHiku.Agaru: isA = false; isC = false; isG = false; break; case AgaruHiku.Hiku: isC = false; isD = false; isE = false; isF = false; isG = false; break; } switch (migiHidari) { case MigiHidari.Migi: isA = false; isE = false; isF = false; isG = false; break; case MigiHidari.Hidari: isA = false; isC = false; isD = false; isE = false; break; case MigiHidari.Sugu: isA = false; isC = false; isD = false; isF = false; isG = false; break; } SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isA) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻上(pside, dst1)); } if (isC) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻射(pside, dst1)); } if (isD) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻沈(pside, dst1)); } if (isE) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻引(pside, dst1)); } if (isF) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻降(pside, dst1)); } if (isG) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻滑(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.K == srcSyurui) { #region 王 //************************************************************ // 王 //************************************************************ //---------- // 候補マス //---------- //┌─┬─┬─┐ //│H│A│B│ //├─┼─┼─┤ //│G│至│C│先手から見た図 //├─┼─┼─┤ //│F│E│D│ //└─┴─┴─┘ bool isA = true; bool isB = true; bool isC = true; bool isD = true; bool isE = true; bool isF = true; bool isG = true; bool isH = true; SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isA) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻上(pside, dst1)); } if (isB) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻昇(pside, dst1)); } if (isC) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻射(pside, dst1)); } if (isD) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻沈(pside, dst1)); } if (isE) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻引(pside, dst1)); } if (isF) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻降(pside, dst1)); } if (isG) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻滑(pside, dst1)); } if (isH) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻浮(pside, dst1)); } // 王は1つです。 if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.PR == srcSyurui) { #region 竜 //************************************************************ // 竜 //************************************************************ //---------- // 候補マス //---------- // ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ // │ │ │ │ │ │ │ │ │A7│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A6│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A5│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A4│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A3│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A2│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │A1│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │H│A0│B│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │G7│G6│G5│G4│G3│G2│G1│G0│至│C0│C1│C2│C3│C4│C5│C6│C7│ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │F│E0│D│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E1│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E2│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E3│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E4│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E5│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E6│ │ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │ │E7│ │ │ │ │ │ │ │ │ // └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ bool isA = true; bool isB = true; bool isC = true; bool isD = true; bool isE = true; bool isF = true; bool isG = true; bool isH = true; switch (agaruHiku) { case AgaruHiku.Yoru: isA = false; isB = false; isD = false; isE = false; isF = false; isH = false; break; case AgaruHiku.Agaru: isA = false; isB = false; isC = false; isG = false; isH = false; break; case AgaruHiku.Hiku: isC = false; isD = false; isE = false; isF = false; isG = false; break; } switch (migiHidari) { case MigiHidari.Migi: isA = false; isE = false; isF = false; isG = false; isH = false; break; case MigiHidari.Hidari: isA = false; isB = false; isC = false; isD = false; isE = false; break; case MigiHidari.Sugu: isA = false; isB = false; isC = false; isD = false; isF = false; isG = false; isH = false; break; } SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isA) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻上(pside, dst1)); } if (isB) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻昇(pside, dst1)); } if (isC) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻射(pside, dst1)); } if (isD) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻沈(pside, dst1)); } if (isE) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻引(pside, dst1)); } if (isF) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻降(pside, dst1)); } if (isG) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻滑(pside, dst1)); } if (isH) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻浮(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else if (PieceType.PB == srcSyurui) { #region 馬 //************************************************************ // 馬 //************************************************************ //---------- // 候補マス //---------- // ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐ // │H7│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │B7│ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │H6│ │ │ │ │ │ │ │ │ │ │ │ │ │B6│ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │H5│ │ │ │ │ │ │ │ │ │ │ │B5│ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │H4│ │ │ │ │ │ │ │ │ │B4│ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │H3│ │ │ │ │ │ │ │B3│ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │H2│ │ │ │ │ │B2│ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │H1│ │ │ │B1│ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │H0│A│B0│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │G│至│C│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │ │F0│E│D0│ │ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │ │F1│ │ │ │D1│ │ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │ │F2│ │ │ │ │ │D2│ │ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │ │F3│ │ │ │ │ │ │ │D3│ │ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │ │F4│ │ │ │ │ │ │ │ │ │D4│ │ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │ │F5│ │ │ │ │ │ │ │ │ │ │ │D5│ │ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │ │F6│ │ │ │ │ │ │ │ │ │ │ │ │ │D6│ │ // ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤ // │F7│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │D7│ // └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘ bool isA = true; bool isB = true; bool isC = true; bool isD = true; bool isE = true; bool isF = true; bool isG = true; bool isH = true; switch (agaruHiku) { case AgaruHiku.Yoru: isA = false; isB = false; isD = false; isE = false; isF = false; isH = false; break; case AgaruHiku.Agaru: isA = false; isB = false; isC = false; isG = false; isH = false; break; case AgaruHiku.Hiku: isC = false; isD = false; isE = false; isF = false; isG = false; break; } switch (migiHidari) { case MigiHidari.Migi: isA = false; isE = false; isF = false; isG = false; isH = false; break; case MigiHidari.Hidari: isA = false; isB = false; isC = false; isD = false; isE = false; break; case MigiHidari.Sugu: isA = false; isB = false; isC = false; isD = false; isF = false; isG = false; isH = false; break; } SySet <SyElement> srcAll = new SySet_Default <SyElement>("J符号"); if (isA) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻上(pside, dst1)); } if (isB) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻昇(pside, dst1)); } if (isC) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻射(pside, dst1)); } if (isD) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻沈(pside, dst1)); } if (isE) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻引(pside, dst1)); } if (isF) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻降(pside, dst1)); } if (isG) { srcAll.AddSupersets(KomanoKidou.SrcIppo_戻滑(pside, dst1)); } if (isH) { srcAll.AddSupersets(KomanoKidou.SrcKantu_戻浮(pside, dst1)); } if (KifuIO_MovesParsers.Hit_JfugoParser(pside, srcSyurui, srcAll, kifu, out foundKoma)) { srcOkiba1 = Okiba.ShogiBan; goto gt_EndSyurui; } #endregion } else { #region エラー //************************************************************ // エラー //************************************************************ #endregion } gt_EndShogiban: if (Fingers.Error_1 == foundKoma && utsu) { // 駒台の駒を(明示的に)打ちます。 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Fingers komas = Util_Sky.Fingers_ByOkibaPsideSyuruiNow( siteiNode.Value.ToKyokumenConst, srcOkiba1, pside, srcSyurui); if (0 < komas.Count) { switch (pside) { case Playerside.P2: srcOkiba1 = Okiba.Gote_Komadai; break; case Playerside.P1: srcOkiba1 = Okiba.Sente_Komadai; break; default: srcOkiba1 = Okiba.Empty; break; } foundKoma = komas[0]; goto gt_EndSyurui; } } gt_EndSyurui: int srcMasuHandle1; if (Fingers.Error_1 != foundKoma) { // 将棋盤の上に駒がありました。 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(foundKoma).Now); srcMasuHandle1 = Util_Masu.AsMasuNumber(koma.Masu); } else { // (符号に書かれていませんが)「打」のとき。 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> switch (pside) { case Playerside.P2: srcOkiba1 = Okiba.Gote_Komadai; break; case Playerside.P1: srcOkiba1 = Okiba.Sente_Komadai; break; default: srcOkiba1 = Okiba.Empty; break; } Debug.Assert(0 < siteiNode.Value.ToKyokumenConst.Count, "星の光が 1個未満。"); // 駒台から、該当する駒を探します。 Fingers daiKomaFgs = Util_Sky.Fingers_ByOkibaPsideSyuruiNow( siteiNode.Value.ToKyokumenConst, srcOkiba1, pside, srcSyurui);//(2014-10-04 12:46)変更 Debug.Assert(0 < daiKomaFgs.Count, "フィンガーズが 1個未満。 srcOkiba1=[" + srcOkiba1 + "] pside=[" + pside + "] srcSyurui=[" + srcSyurui + "]"); // 1個はヒットするはず Finger hitKoma = daiKomaFgs[0];//▲![コマ送り]ボタンを連打すると、エラーになります。 RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(hitKoma).Now); srcMasuHandle1 = Util_Masu.AsMasuNumber(koma.Masu); } PieceType dstSyurui; if (NariNarazu.Nari == nariNarazu) { // 成ります dstSyurui = KomaSyurui14Array.NariCaseHandle[(int)srcSyurui]; } else { // そのままです。 dstSyurui = srcSyurui; } // 1手を、データにします。 move = new RO_ShootingStarlight( //foundKoma,//TODO: new RO_Star_Koma( pside, Util_Masu.HandleToMasu(srcMasuHandle1), srcSyurui ), new RO_Star_Koma( pside, dstMasu,//符号は将棋盤の升目です。 dstSyurui ), PieceType.None // 符号からは、取った駒の種類は分からないんだぜ☆ だがバグではない☆ あとで調べる☆ ); }
/// <summary> /// 符号1「7g7f」を元に、move を作ります。 /// /// <[再生]、[コマ送り]で呼び出されます> /// </summary> /// <returns></returns> public static void ExecuteSfenMoves_FromTextSub( bool isHonshogi, string str1, //123456789 か、 PLNSGKRB string str2, //abcdefghi か、 * string str3, //123456789 string str4, //abcdefghi string strNari, //+ out ShootingStarlightable move, KifuTree kifu, string hint, int tesumi_yomiGenTeban//読み進めている現在の手目済 ) { move = Util_Sky.NullObjectMove; SkyConst src_Sky = kifu.NodeAt(tesumi_yomiGenTeban).Value.ToKyokumenConst; Debug.Assert(!Util_MasuNum.OnKomabukuro(Util_Masu.AsMasuNumber(((RO_Star_Koma)src_Sky.StarlightIndexOf((Finger)0).Now).Masu)), "[" + tesumi_yomiGenTeban + "]手目、駒が駒袋にあった。"); try { PieceType uttaSyurui; // 打った駒の種類 int srcSuji = Util_Koma.CTRL_NOTHING_PROPERTY_SUJI; int srcDan = Util_Koma.CTRL_NOTHING_PROPERTY_DAN; if ("*" == str2) { //>>>>>>>>>> 「打」でした。 Converter04.SfenUttaSyurui(str1, out uttaSyurui); } else { //>>>>>>>>>> 指しました。 uttaSyurui = PieceType.None;//打った駒はない☆ //------------------------------ // 1 //------------------------------ if (!int.TryParse(str1, out srcSuji)) { } //------------------------------ // 2 //------------------------------ srcDan = Converter04.Alphabet_ToInt(str2); } //------------------------------ // 3 //------------------------------ int suji; if (!int.TryParse(str3, out suji)) { } //------------------------------ // 4 //------------------------------ int dan; dan = Converter04.Alphabet_ToInt(str4); Finger koma; if ("*" == str2) { //>>>>> 「打」でした。 Node <ShootingStarlightable, KyokumenWrapper> siteiNode = kifu.CurNode; // 駒台から、打った種類の駒を取得 koma = Util_Sky.FingerNow_BySyuruiIgnoreCase( siteiNode.Value.ToKyokumenConst, Converter04.Pside_ToKomadai(kifu.CountPside(kifu.CurNode)),//Okiba.Sente_Komadai,//FIXME: uttaSyurui); if (Fingers.Error_1 == koma) { throw new Exception($"TuginoItte_Sfen#GetData_FromTextSub:駒台から種類[{uttaSyurui}]の駒を掴もうとしましたが、エラーでした。"); } //// FIXME: 打のとき、srcSuji、srcDan が Int.Min } else { //>>>>> 打ではないとき koma = Util_Sky.Fingers_AtMasuNow( src_Sky, Util_Masu.OkibaSujiDanToMasu(Okiba.ShogiBan, srcSuji, srcDan) ).ToFirst(); if (Fingers.Error_1 == koma) { // // エラーの理由: // 0手目、平手局面を想定していたが、駒がすべて駒袋に入っているときなど // var sky2 = Util_Sky.Json_1Sky(src_Sky, "エラー駒になったとき", $"{hint}_SF解3", tesumi_yomiGenTeban); throw new Exception($@"TuginoItte_Sfen#GetData_FromTextSub:SFEN解析中の失敗: 将棋盤から [{srcSuji}]筋、[{srcDan}]段 にある駒を掴もうとしましたが、駒がありませんでした。 isHonshogi=[{isHonshogi}] str1=[{str1}] str2=[{str2}] str3=[{str3}] str4=[{str4}] strNari=[{strNari}] hint=[{hint}] tesumi_yomiGenTeban=[{tesumi_yomiGenTeban}] 局面=sfen {Util_SfenStartposWriter.CreateSfenstring(new StartposExporter(src_Sky), true)} {sky2}"); } } PieceType dstSyurui; PieceType srcSyurui; Okiba srcOkiba; SyElement srcMasu; if ("*" == str2) { //>>>>> 打った駒の場合 dstSyurui = uttaSyurui; srcSyurui = uttaSyurui; switch (kifu.CountPside(kifu.CurNode)) { case Playerside.P2: srcOkiba = Okiba.Gote_Komadai; break; case Playerside.P1: srcOkiba = Okiba.Sente_Komadai; break; default: srcOkiba = Okiba.Empty; break; } int lastTesumi = kifu.CountTesumi(kifu.CurNode); Node <ShootingStarlightable, KyokumenWrapper> siteiNode = kifu.NodeAt(lastTesumi); Finger srcKoma = Util_Sky.FingerNow_BySyuruiIgnoreCase(siteiNode.Value.ToKyokumenConst, srcOkiba, srcSyurui); RO_Star_Koma dstKoma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(srcKoma).Now); srcMasu = dstKoma.Masu; } else { //>>>>> 盤上の駒を指した場合 RO_Star_Koma dstKoma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(koma).Now); dstSyurui = Haiyaku184Array.Syurui(dstKoma.Haiyaku); srcSyurui = dstSyurui; //駒は「元・種類」を記憶していませんので、「現・種類」を指定します。 srcOkiba = Okiba.ShogiBan; srcMasu = Util_Masu.OkibaSujiDanToMasu(srcOkiba, srcSuji, srcDan); } //------------------------------ // 5 //------------------------------ if ("+" == strNari) { // 成りました dstSyurui = KomaSyurui14Array.NariCaseHandle[(int)dstSyurui]; } //------------------------------ // 結果 //------------------------------ // 棋譜 move = new RO_ShootingStarlight( //koma,//TODO: new RO_Star_Koma( kifu.CountPside(kifu.CurNode), srcMasu,//FIXME:升ハンドルにしたい srcSyurui ), new RO_Star_Koma( kifu.CountPside(kifu.CurNode), Util_Masu.OkibaSujiDanToMasu(Okiba.ShogiBan, suji, dan),//符号は将棋盤の升目です。 FIXME:升ハンドルにしたい dstSyurui ), PieceType.None//符号からは、取った駒は分からない ); } catch (Exception ex) { //>>>>> エラーが起こりました。 // どうにもできないので 経路と情報を付け足して 更に外側に投げます。 throw new Exception($"{ex.GetType().Name}:{ex.Message} in TuginoItte_Sfen.GetData_FromTextSub(A) str1=「{str1}」 str2=「{str2}」 str3=「{str3}」 str4=「{str4}」 strNari=「{strNari}」 "); } }
/// <summary> /// 次の枝を読みます。 /// </summary> private static void WAAAA_Read_NextBranch( MoveGenGenjo yomiGenjo, Node <ShootingStarlightable, KyokumenWrapper> hubNode_genTeban, SsssLogGenjo log ) { // (3)次のノードをシャッフルします。 List <Node <ShootingStarlightable, KyokumenWrapper> > nextNodes_shuffled = Converter04.NextNodes_ToList(hubNode_genTeban); LarabeShuffle <Node <ShootingStarlightable, KyokumenWrapper> > .Shuffle_FisherYates(ref nextNodes_shuffled); // (4)次の局面 int wideCount = 0; foreach (KifuNode nextNode in nextNodes_shuffled) { // (5)読みの深さ2手目以降なら、横幅制限 if (1 < yomiGenjo.YomuDeep) { if (yomiGenjo.Args.YomuLimitter[yomiGenjo.YomuDeep] <= wideCount) { break;// もう次の手の横には読まない。 } } // 《8》カウンターを次局面へ(2手目の読み) // 《9》まだ深く読むなら if (yomiGenjo.YomuDeep + 1 < yomiGenjo.Args.YomuLimitter.Length) { yomiGenjo.YomuDeep++; yomiGenjo.Tesumi_yomiCur++; yomiGenjo.Pside_teban = yomiGenjo.Pside_teban == Playerside.P1 ? Playerside.P2 : Playerside.P1; //先後を反転します。 MoveGenRoutine.WAAA_Yomu_Loop(nextNode, yomiGenjo, log); yomiGenjo.YomuDeep--; //元に戻します。 yomiGenjo.Tesumi_yomiCur--; //元に戻します。 yomiGenjo.Pside_teban = yomiGenjo.Pside_teban == Playerside.P1 ? Playerside.P2 : Playerside.P1; //元に戻します。 } else { // もう深くよまないなら } wideCount++; } if (yomiGenjo.Args.YomuLimitter.Length <= yomiGenjo.YomuDeep + 1)//もう深く読まないなら { // // ログの書き出し // Util_GraphicalLog.Log( true,//enableLog, "指し手生成ログA", "[" + Util_GraphicalLog.BoardFileLog_ToJsonStr(yomiGenjo.Args.LogF_moveKiki) + "]" ); // 書き出した分はクリアーします。 yomiGenjo.Args.LogF_moveKiki.boards.Clear(); } }
/// <summary> /// ************************************************************************************************************************ /// 棋譜用の符号テキスト(*1)を作ります。 /// ************************************************************************************************************************ /// /// *1…「▲5五銀上」など。 /// /// </summary> /// <param name="douExpr">“同”表記に置き換えるなら真。</param> /// <param name="previousKomaP"></param> /// <returns></returns> public string ToText_UseDou( Node <ShootingStarlightable, KyokumenWrapper> siteiNode ) { StringBuilder sb = new StringBuilder(); ShootingStarlightable curMove = siteiNode.Key; ShootingStarlightable preMove = siteiNode.PreviousNode.Key; RO_Star_Koma curSrcKoma = Util_Koma.AsKoma(curMove.LongTimeAgo); RO_Star_Koma curDstKoma = Util_Koma.AsKoma(curMove.Now); RO_Star_Koma preSrcKoma = Util_Koma.AsKoma(preMove.LongTimeAgo); RO_Star_Koma preDstKoma = Util_Koma.AsKoma(preMove.Now); sb.Append(Converter04.Pside_ToStr(curDstKoma.Pside)); //------------------------------ // “同”で表記できるところは、“同”で表記します。それ以外は“筋・段”で表記します。 //------------------------------ if ( null != preMove && Util_Masu.MatchSujiDan(Util_Masu.AsMasuNumber(preDstKoma.Masu), Util_Masu.AsMasuNumber(curDstKoma.Masu)) ) { // “同” sb.Append("同"); } else { // “筋・段” int suji; int dan; Util_MasuNum.MasuToSuji(curDstKoma.Masu, out suji); Util_MasuNum.MasuToDan(curDstKoma.Masu, out dan); sb.Append(ConverterKnSh.Int_ToArabiaSuji(suji)); sb.Append(ConverterKnSh.Int_ToKanSuji(dan)); } //------------------------------ // “歩”とか。“全”ではなく“成銀” <符号用> //------------------------------ sb.Append(KomaSyurui14Array.Fugo[(int)this.Syurui]); //------------------------------ // “右”とか //------------------------------ sb.Append(Converter04.MigiHidari_ToStr(this.MigiHidari)); //------------------------------ // “寄”とか //------------------------------ sb.Append(Converter04.AgaruHiku_ToStr(this.AgaruHiku)); //------------------------------ // “成”とか //------------------------------ sb.Append(Converter04.Nari_ToStr(this.Nari)); //------------------------------ // “打”とか //------------------------------ sb.Append(Converter04.Bool_ToDa(this.DaHyoji)); return(sb.ToString()); }
/// <summary> /// 指定された手の中から、王手局面を除外します。 /// /// 王手回避漏れを防ぎたいんだぜ☆ /// </summary> /// <param name="km_available">自軍の各駒の移動できる升セット</param> /// <param name="sbGohosyu"></param> /// <param name="logTag"></param> public static KifuNode LA_RemoveMate( bool isHonshogi, Maps_OneAndMulti <Finger, ShootingStarlightable> genTeban_komabetuAllMove1, // 現手番の、どの駒が、どんな手を指すことができるか int yomuDeep, //脳内読み手数 int tesumi_yomiGenTeban, Playerside pside_yomiGenTeban, KifuNode siteiNode_yomiGenTeban, bool enableLog, GraphicalLog_File logF_kiki, string hint) { Node <ShootingStarlightable, KyokumenWrapper> hubNode = UtilKomabetuMove.ToNextNodes_AsHubNode( genTeban_komabetuAllMove1, siteiNode_yomiGenTeban, pside_yomiGenTeban ); // ハブ・ノード自身はダミーノードなんだが、子ノードに、次のノードが入っている。 Converter04.AssertNariMove(hubNode, "#LA_RemoveMate(1)"); //ここはok Util_LegalMove.Log1(hubNode, enableLog, tesumi_yomiGenTeban, hint); if (isHonshogi) { // 王手が掛かっている局面を除きます。 Util_LegalMove.LAA_RemoveNextNode_IfMate( hubNode, enableLog, yomuDeep, tesumi_yomiGenTeban, pside_yomiGenTeban, logF_kiki); } Converter04.AssertNariMove(hubNode, "#LA_RemoveMate(2)王手局面削除直後");//ここはok // 「指し手一覧」を、「駒別の全指し手」に分けます。 Maps_OneAndMulti <Finger, ShootingStarlightable> komabetuAllMoves2 = siteiNode_yomiGenTeban.SplitMoveByKoma(hubNode); Converter04.AssertNariMove(komabetuAllMoves2, "#LA_RemoveMate(3)更に変換後");//ここはok // // 「駒別の指し手一覧」を、「駒別の進むマス一覧」になるよう、データ構造を変換します。 // Maps_OneAndOne <Finger, SySet <SyElement> > komabetuSusumuMasus = new Maps_OneAndOne <Finger, SySet <SyElement> >();// 「どの駒を、どこに進める」の一覧 foreach (KeyValuePair <Finger, List <ShootingStarlightable> > entry in komabetuAllMoves2.Items) { Finger finger = entry.Key; List <ShootingStarlightable> teList = entry.Value; // ポテンシャル・ムーブを調べます。 SySet <SyElement> masus_PotentialMove = new SySet_Default <SyElement>("ポテンシャルムーブ"); foreach (ShootingStarlightable te in teList) { RO_Star_Koma koma = Util_Koma.AsKoma(te.Now); masus_PotentialMove.AddElement(koma.Masu); } if (!masus_PotentialMove.IsEmptySet()) { // 空でないなら Util_KomabetuMasus.AddOverwrite(komabetuSusumuMasus, finger, masus_PotentialMove); } } // まず、ディクショナリー構造へ変換。 Dictionary <ShootingStarlightable, KyokumenWrapper> movebetuSky = Converter04.KomabetuMasus_ToMovebetuSky( komabetuSusumuMasus, siteiNode_yomiGenTeban.Value.ToKyokumenConst, pside_yomiGenTeban); // 棋譜ノード構造へ変換。 return(Converter04.MovebetuSky_ToHubNode(movebetuSky, KifuNodeImpl.GetReverseTebanside(pside_yomiGenTeban))); }
/// <summary> /// 指定された局面で、指定された手番の駒の、利きマスを算出します。 /// 持ち駒は盤上にないので、利きを調べる必要はありません。 /// /// 「手目」は判定できません。 /// /// </summary> /// <param name="kouho"></param> /// <param name="sbGohosyu"></param> /// <param name="logger"></param> public static List_OneAndMulti <Finger, SySet <SyElement> > LAAAA_GetEffect( bool enableLog, bool isHonshogi, SkyConst src_Sky, Playerside pside_genTeban3, bool isAiteban, GraphicalLog_File logF_kiki, string logBrd_caption, int yomuDeep_forLog,//脳内読み手数 int tesumi_yomiCur_forLog, ShootingStarlightable move_forLog ) { GraphicalLog_Board logBrd_kiki = new GraphicalLog_Board(); logBrd_kiki.Caption = logBrd_caption;// "利き_" logBrd_kiki.Tesumi = tesumi_yomiCur_forLog; logBrd_kiki.NounaiYomiDeep = yomuDeep_forLog; //logBrd_kiki.Score = 0.0d; logBrd_kiki.GenTeban = pside_genTeban3;// 現手番 logF_kiki.boards.Add(logBrd_kiki); // 《1》 List_OneAndMulti <Finger, SySet <SyElement> > sMs_effect = new List_OneAndMulti <Finger, SySet <SyElement> >();//盤上の駒の利き { // 《1.1》 Playerside tebanSeme; //手番(利きを調べる側) Playerside tebanKurau; //手番(喰らう側) { if (isAiteban) { tebanSeme = Converter04.AlternatePside(pside_genTeban3); tebanKurau = pside_genTeban3; } else { tebanSeme = pside_genTeban3; tebanKurau = Converter04.AlternatePside(pside_genTeban3); } if (Playerside.P1 == tebanSeme) { logBrd_kiki.NounaiSeme = Gkl_NounaiSeme.Sente; } else if (Playerside.P2 == tebanSeme) { logBrd_kiki.NounaiSeme = Gkl_NounaiSeme.Gote; } } // 《1.2》 Fingers fingers_seme_IKUSA; //戦駒(利きを調べる側) Fingers fingers_kurau_IKUSA; //戦駒(喰らう側) Fingers dust1; Fingers dust2; Util_Things.AAABAAAA_SplitGroup( out fingers_seme_IKUSA, out fingers_kurau_IKUSA, out dust1, out dust2, src_Sky, tebanSeme, tebanKurau ); // 攻め手の駒の位置 GraphicalLog_Board boardLog_clone = new GraphicalLog_Board(logBrd_kiki); foreach (Finger finger in fingers_seme_IKUSA.Items) { RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(finger).Now); Gkl_KomaMasu km = new Gkl_KomaMasu( Util_GraphicalLog.PsideKs14_ToString(tebanSeme, Haiyaku184Array.Syurui(koma.Haiyaku), ""), Util_Masu.AsMasuNumber(koma.Masu) ); boardLog_clone.KomaMasu1.Add(km); } foreach (Finger finger in fingers_kurau_IKUSA.Items) { RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(finger).Now); logBrd_kiki.KomaMasu2.Add(new Gkl_KomaMasu( Util_GraphicalLog.PsideKs14_ToString(tebanKurau, Haiyaku184Array.Syurui(koma.Haiyaku), ""), Util_Masu.AsMasuNumber(koma.Masu) )); } logBrd_kiki = boardLog_clone; // 《1.3》 SySet <SyElement> masus_seme_IKUSA = Converter04.Fingers_ToMasus(fingers_seme_IKUSA, src_Sky); // 盤上のマス(利きを調べる側の駒) SySet <SyElement> masus_kurau_IKUSA = Converter04.Fingers_ToMasus(fingers_kurau_IKUSA, src_Sky); // 盤上のマス(喰らう側の駒) // 駒のマスの位置は、特にログに取らない。 // 《1.4》 Maps_OneAndOne <Finger, SySet <SyElement> > kmEffect_seme_IKUSA = Util_Things.Get_KmEffect_seme_IKUSA( fingers_seme_IKUSA,//この中身がおかしい。 masus_seme_IKUSA, masus_kurau_IKUSA, src_Sky, enableLog, Converter04.MoveToStringForLog(move_forLog, pside_genTeban3) );// 利きを調べる側の利き(戦駒) // 戦駒の利き logBrd_kiki = new GraphicalLog_Board(logBrd_kiki); kmEffect_seme_IKUSA.Foreach_Entry((Finger key, SySet <SyElement> value, ref bool toBreak) => { RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(key).Now); string komaImg = Util_GraphicalLog.PsideKs14_ToString(tebanSeme, Haiyaku184Array.Syurui(koma.Haiyaku), ""); foreach (Basho masu in value.Elements) { boardLog_clone.Masu_theEffect.Add((int)masu.MasuNumber); } }); logBrd_kiki = boardLog_clone; // 《1》 = 《1.4》の戦駒+持駒 sMs_effect.AddRange_New(kmEffect_seme_IKUSA); } return(sMs_effect); }
/// <summary> /// 棋譜[再生]時用(マウス操作のときは関係ない) /// /// 一手進む、一手[巻戻し]に対応。 /// /// </summary> /// <param name="move">棋譜に記録するために「指す前/指した後」を含めた手。</param> /// <param name="kifu"></param> /// <param name="isMakimodosi"></param> private static void Kifusasi52_WhenKifuRead( Starlight dst, PieceType syurui2, ref Finger figMovedKoma, out Finger out_figFoodKoma, ShootingStarlightable move, KifuTree kifu, bool isMakimodosi, out Node <ShootingStarlightable, KyokumenWrapper> out_newNode_OrNull ) { out_figFoodKoma = Fingers.Error_1; // Sky 局面データは、この関数の途中で何回か変更されます。ローカル変数に退避しておくと、同期が取れなくなります。 //------------------------------------------------------------ // 駒を取る //------------------------------------------------------------ if (!isMakimodosi) { RO_Star_Koma dstKoma = Util_Koma.AsKoma(dst.Now); PieceType foodKomaSyurui;//取られた駒の種類 //---------- // 将棋盤上のその場所に駒はあるか //---------- foodKomaSyurui = PieceType.None; //ひとまずクリアー out_figFoodKoma = Util_Sky.Fingers_AtMasuNow(kifu.CurNode.Value.ToKyokumenConst, dstKoma.Masu).ToFirst(); //盤上 if (Fingers.Error_1 != out_figFoodKoma) { //>>>>> 指した先に駒があったなら // // 取られる駒 // foodKomaSyurui = Util_Koma.AsKoma(kifu.CurNode.Value.ToKyokumenConst.StarlightIndexOf(out_figFoodKoma).Now).Syurui; // // 取られる駒は、駒置き場の空きマスに移動させます。 // Okiba okiba; Playerside pside; switch (dstKoma.Pside) { case Playerside.P1: { okiba = Okiba.Sente_Komadai; pside = Playerside.P1; } break; case Playerside.P2: { okiba = Okiba.Gote_Komadai; pside = Playerside.P2; } break; default: { //>>>>> エラー: 先後がおかしいです。 throw new Exception($@"エラー: 先後がおかしいです。 dst.Pside={dstKoma.Pside}"); } } // 駒台の空きスペース SyElement akiMasu = akiMasu = KifuIO.GetKomadaiKomabukuroSpace(okiba, kifu.CurNode.Value.ToKyokumenConst); if (Masu_Honshogi.Error == akiMasu) { //>>>>> エラー: 駒台に空きスペースがありませんでした。 throw new Exception($@"エラー: 駒台に空きスペースがありませんでした。 駒台={Okiba.Gote_Komadai}"); } //>>>>> 駒台に空きスペースがありました。 // // 取られる動き // { SkyBuffer buffer_Sky = new SkyBuffer(kifu.CurNode.Value.ToKyokumenConst); buffer_Sky.AddOverwriteStarlight( out_figFoodKoma, new RO_MotionlessStarlight( //out_figFoodKoma, new RO_Star_Koma( pside, akiMasu, //駒台の空きマスへ Util_Koma.AsKoma(kifu.CurNode.Value.ToKyokumenConst.StarlightIndexOf(out_figFoodKoma).Now).Syurui //駒の種類 ) ) ); kifu.CurNode.Value.SetKyokumen(new SkyConst(buffer_Sky)); // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // この時点で局面データに変更あり // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ } //------------------------------ // 成っていれば、「成り」は解除。 //------------------------------ RO_Star_Koma koma3 = Util_Koma.AsKoma(kifu.CurNode.Value.ToKyokumenConst.StarlightIndexOf(out_figFoodKoma).Now); switch (Util_Masu.GetOkiba(koma3.Masu)) { case Okiba.Sente_Komadai: //thru case Okiba.Gote_Komadai: // 駒台へ移動しました //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> SkyBuffer buffer_Sky = new SkyBuffer(kifu.CurNode.Value.ToKyokumenConst); buffer_Sky.AddOverwriteStarlight(out_figFoodKoma, new RO_MotionlessStarlight( //out_figFoodKoma, new RO_Star_Koma(koma3.Pside, koma3.Masu, koma3.ToNarazuCase()) ) ); kifu.CurNode.Value.SetKyokumen(new SkyConst(buffer_Sky)); // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // この時点で局面データに変更あり // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ break; } //------------------------------ // 取った駒を棋譜に覚えさせます。(差替え) //------------------------------ kifu.AppendChildB_Swap( foodKomaSyurui, kifu.CurNode.Value.ToKyokumenConst, "KifuIO_Kifusasi52" ); //} } } //------------------------------------------------------------ // 駒の移動 //------------------------------------------------------------ { SkyBuffer buffer_Sky = new SkyBuffer(kifu.CurNode.Value.ToKyokumenConst); buffer_Sky.AddOverwriteStarlight(figMovedKoma, dst); kifu.CurNode.Value.SetKyokumen(new SkyConst(buffer_Sky)); } // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // この時点で局面データに変更あり // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ //------------------------------------------------------------ // 取った駒を戻す //------------------------------------------------------------ if (isMakimodosi) { RO_Star_Koma koma = Util_Koma.AsKoma(move.Now); if (PieceType.None != (PieceType)move.FoodKomaSyurui) { // 駒台から、駒を検索します。 Okiba okiba; if (Playerside.P2 == koma.Pside) { okiba = Okiba.Gote_Komadai; } else { okiba = Okiba.Sente_Komadai; } // 取った駒は、種類が同じなら、駒台のどの駒でも同じです。 Finger temp_figFoodKoma = Util_Sky.FingerNow_BySyuruiIgnoreCase(kifu.CurNode.Value.ToKyokumenConst, okiba, (PieceType)move.FoodKomaSyurui); if (Fingers.Error_1 != temp_figFoodKoma) { // 取った駒のデータをセットし直します。 SkyBuffer buffer_Sky = new SkyBuffer(kifu.CurNode.Value.ToKyokumenConst); buffer_Sky.AddOverwriteStarlight( temp_figFoodKoma, new RO_MotionlessStarlight( //temp_figFoodKoma, new RO_Star_Koma( Converter04.AlternatePside(koma.Pside), //先後を逆にして駒台に置きます。 koma.Masu, // マス (PieceType)move.FoodKomaSyurui ) ) ); kifu.CurNode.Value.SetKyokumen(new SkyConst(buffer_Sky)); // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // この時点で局面データに変更あり // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ out_figFoodKoma = temp_figFoodKoma; } } } // // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // 局面データに変更があったものとして進めます。 // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // out_newNode_OrNull = kifu.CurNode;// この変数を返すのがポイント。 { out_newNode_OrNull.Value.SetKyokumen(kifu.CurNode.Value.ToKyokumenConst); kifu.CurNode.Value.SetKyokumen(kifu.CurNode.Value.ToKyokumenConst); } }