/// <summary> /// [一手指す]ボタン。 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public static void IttesasuByBtnClick( ref bool isRequestShowGohosyu, ref bool isRequestChangeKyokumenPng, LearningData learningData, Uc_Main ucMain) { #if DEBUG Stopwatch sw1 = new Stopwatch(); sw1.Start(); #endif if (ucMain is null) { throw new ArgumentNullException(nameof(ucMain)); } // if (logTag is null) throw new ArgumentNullException(nameof(logTag)); // // リストの先頭の項目を取得したい。 // if (ucMain.LstMove.Items.Count < 1) { goto gt_EndMethod; } // リストボックスの先頭から指し手をSFEN形式で1つ取得。 HonpuMoveListItemImpl item = (HonpuMoveListItemImpl)ucMain.LstMove.Items[0]; string sfen = item.Sfen; // (2020-12-18 fri)この機能むずかしいからいったん廃止☆(^~^) // logTag.OnAppendLog?.Invoke($"sfen={sfen}\n"); // // 現局面の合法手は、既に読んであるとします。(棋譜ツリーのNextNodesが既に設定されていること) // // // 合法手の一覧は既に作成されているものとします。 // 次の手に進みます。 // IMove nextMove; { if (learningData.Kifu.CurNode.HasChildNode(sfen)) { Node <IMove, KyokumenWrapper> nextNode = learningData.Kifu.CurNode.GetChildNode(sfen); nextMove = nextNode.Key;//次の棋譜ノードのキーが、指し手(きふわらべ式)になっています。 } else { nextMove = null; throw new Exception($@"指し手[{sfen}]はありませんでした。 {learningData.DumpToAllGohosyu(learningData.Kifu.CurNode.Value.KyokumenConst)}"); } } //---------------------------------------- // 一手指したい。 //---------------------------------------- //↓↓一手指し IttesasuResult ittesasuResult; Util_IttesasuRoutine.Before1( new IttesasuArgImpl( learningData.Kifu.CurNode.Value, ((KifuNode)learningData.Kifu.CurNode).Value.KyokumenConst.KaisiPside, nextMove, // FIXME: これがヌルのことがあるのだろうか? learningData.Kifu.CurNode.Value.KyokumenConst.Temezumi + 1 //1手進める ), out ittesasuResult, //this.Kifu,//診断用 "Util_LearningView#Ittesasu_ByBtnClick" ); Debug.Assert(ittesasuResult.Get_SyuryoNode_OrNull != null, "ittesasuResult.Get_SyuryoNode_OrNull がヌル☆?!"); Util_IttesasuRoutine.Before2( ref ittesasuResult ); // //次ノートを追加します。次ノードを、これからのカレントとします。 // //this.Kifu.AssertChildPside(this.Kifu.CurNode.Value.ToKyokumenConst.KaisiPside, ittesasuResult.Get_SyuryoNode_OrNull.Value.ToKyokumenConst.KaisiPside); Util_IttesasuRoutine.After3_ChangeCurrent( learningData.Kifu, ConvMoveStrSfen.ToMoveStrSfen(ittesasuResult.Get_SyuryoNode_OrNull.Key), ittesasuResult.Get_SyuryoNode_OrNull ); // これで、棋譜ツリーに、構造変更があったはず。 //↑↑一手指し //---------------------------------------- // カレント・ノードより古い、以前読んだ手を削除したい。 //---------------------------------------- Logger.Trace($"カレント・ノード={ConvMoveStrSfen.ToMoveStrSfen(learningData.Kifu.CurNode.Key)}"); int result_removedCount = UtilKifuTree282.IzennoHenkaCutter(learningData.Kifu); Logger.Trace($"削除した要素数={result_removedCount}"); ////---------------------------------------- //// 合法手一覧を作成したい。 ////---------------------------------------- learningData.Aa_Yomi(nextMove); // ノード情報の表示 Util_LearningView.Aa_ShowNode2(ucMain.LearningData, ucMain); // 合法手表示の更新を要求します。 isRequestShowGohosyu = true; // 局面PNG画像を更新を要求。 isRequestChangeKyokumenPng = true; // // リストの頭1個を除外します。 // ucMain.LstMove.Items.RemoveAt(0); #if DEBUG sw1.Stop(); Logger.Trace($"一手指すボタン合計 = {sw1.Elapsed}"); Logger.Trace("────────────────────────────────────────"); #endif gt_EndMethod: ; //---------------------------------------- // ボタン表示の回復 //---------------------------------------- if (0 < ucMain.LstMove.Items.Count) { ucMain.BtnUpdateKyokumenHyoka.Enabled = true;//[局面評価更新]ボタン連打防止解除。 } }
/// <summary> /// 駒を動かします(1)。マウスボタンが押下されたとき。 /// /// 成る、成らない関連。 /// /// </summary> public static void Komamove1a_50Srv( out bool torareruKomaAri, out RO_Star koma_Food_after, IMoveHalf dst, Finger fig_btnTumandeiruKoma, RO_Star foodee_koma,//取られる対象の駒 Model_Manual model_Manual ) { Finger btnKoma_Food_Koma; // 取られることになる駒のボタン btnKoma_Food_Koma = Util_Sky_FingersQuery.InMasuNow(model_Manual.GuiSkyConst, foodee_koma.Masu).ToFirst(); if (Fingers.Error_1 == btnKoma_Food_Koma) { koma_Food_after = null; torareruKomaAri = false; btnKoma_Food_Koma = Fingers.Error_1; goto gt_EndBlock1; } else { //>>>>> 取る駒があったとき torareruKomaAri = true; } PieceType koma_Food_pre_Syurui = Util_Starlightable.AsKoma(model_Manual.GuiSkyConst.StarlightIndexOf(btnKoma_Food_Koma).Now).Komasyurui; // その駒は、駒置き場に移動させます。 SyElement akiMasu; switch (foodee_koma.Pside) { case Playerside.P2: akiMasu = Util_IttesasuRoutine.GetKomadaiKomabukuroSpace(Okiba.Gote_Komadai, model_Manual.GuiSkyConst); if (!Masu_Honshogi.IsErrorBasho(akiMasu)) { // 駒台に空きスペースがありました。 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> koma_Food_after = new RO_Star( Playerside.P2, akiMasu, //駒台へ Util_Komasyurui14.NarazuCaseHandle(koma_Food_pre_Syurui) ); } else { // エラー: 駒台に空きスペースがありませんでした。 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> koma_Food_after = new RO_Star( Playerside.P2, Util_Masu10.OkibaSujiDanToMasu( Okiba.Gote_Komadai, Util_Koma.CTRL_NOTHING_PROPERTY_SUJI, Util_Koma.CTRL_NOTHING_PROPERTY_DAN ), Util_Komasyurui14.NarazuCaseHandle(koma_Food_pre_Syurui) ); } break; case Playerside.P1: //thru default: akiMasu = Util_IttesasuRoutine.GetKomadaiKomabukuroSpace(Okiba.Sente_Komadai, model_Manual.GuiSkyConst); if (!Masu_Honshogi.IsErrorBasho(akiMasu)) { // 駒台に空きスペースがありました。 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> koma_Food_after = new RO_Star( Playerside.P1, akiMasu, //駒台へ Util_Komasyurui14.NarazuCaseHandle(koma_Food_pre_Syurui) ); } else { // エラー: 駒台に空きスペースがありませんでした。 //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> koma_Food_after = new RO_Star( Playerside.P1, Util_Masu10.OkibaSujiDanToMasu( Okiba.Sente_Komadai, Util_Koma.CTRL_NOTHING_PROPERTY_SUJI, Util_Koma.CTRL_NOTHING_PROPERTY_DAN ), Util_Komasyurui14.NarazuCaseHandle(koma_Food_pre_Syurui) ); } break; } gt_EndBlock1: SkyConst sky2; if (btnKoma_Food_Koma != Fingers.Error_1) { //------------------------------ // 取られる駒があった場合 //------------------------------ sky2 = SkyConst.NewInstance_OverwriteOrAdd_Light( model_Manual.GuiSkyConst, -1, //そのまま // // 指した駒 // fig_btnTumandeiruKoma, dst, // // 取られた駒 // btnKoma_Food_Koma, new RO_Starlight( koma_Food_after ) ); } else { //------------------------------ // 取られる駒がなかった場合 //------------------------------ RO_Star movedKoma = Util_Starlightable.AsKoma(model_Manual.GuiSkyConst.StarlightIndexOf(fig_btnTumandeiruKoma).Now); sky2 = SkyConst.NewInstance_OverwriteOrAdd_Light( model_Manual.GuiSkyConst, -1, //そのまま // // 指した駒 // fig_btnTumandeiruKoma, dst, // // 手得計算 // movedKoma.Komasyurui, 0, movedKoma.Masu ); } model_Manual.SetGuiSky(sky2); // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // 棋譜は変更された。 // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ }
/// <summary> /// 指し手一覧を、リストボックスに表示します。 /// </summary> /// <param name="uc_Main"></param> public static void ShowMoveList( LearningData learningData, Uc_Main uc_Main ) { // // まず、リストを空っぽにします。 // uc_Main.LstMove.Items.Clear(); Playerside firstPside = Playerside.P1; KifuTree kifu1 = new KifuTreeImpl( new KifuNodeImpl( Util_Sky258A.RootMove, new KyokumenWrapper(SkyConst.NewInstance( Util_SkyWriter.New_Hirate(firstPside), 0 //初期局面は 0手済み。 )) //日本の符号読取時 ) ); //kifu1.AssertPside(kifu1.CurNode, "ShowMoveList",logTag); List <CsaKifuMove> moveList = learningData.CsaKifu.MoveList; foreach (CsaKifuMove csaMove in moveList) { // 開始局面 SkyConst kaisi_Sky = kifu1.CurNode.Value.KyokumenConst; // // csaMove を データ指し手 に変換するには? // IMove nextMove; { Playerside pside = UtilCsaMove.ToPside(csaMove); // 元位置 SyElement srcMasu = UtilCsaMove.ToSrcMasu(csaMove); Finger figSrcKoma; if (Masu_Honshogi.IsErrorBasho(srcMasu))// 駒台の "00" かも。 { //駒台の駒。 PieceType utuKomasyurui = Util_Komasyurui14.NarazuCaseHandle(UtilCsaMove.ToKomasyurui(csaMove));// 打つ駒の種類。 Okiba komadai; switch (pside) { case Playerside.P1: komadai = Okiba.Sente_Komadai; break; case Playerside.P2: komadai = Okiba.Gote_Komadai; break; default: komadai = Okiba.Empty; break; } figSrcKoma = Util_Sky_FingersQuery.InOkibaPsideKomasyuruiNow(kaisi_Sky, komadai, pside, utuKomasyurui).ToFirst(); } else { // 盤上の駒。 figSrcKoma = Util_Sky_FingerQuery.InMasuNow(kaisi_Sky, pside, srcMasu); } RO_Star srcKoma = Util_Starlightable.AsKoma(kaisi_Sky.StarlightIndexOf(figSrcKoma).Now); // 先位置 SyElement dstMasu = UtilCsaMove.ToDstMasu(csaMove); Finger figFoodKoma = Util_Sky_FingerQuery.InShogibanMasuNow(kaisi_Sky, pside, dstMasu); PieceType foodKomasyurui; if (figFoodKoma == Fingers.Error_1) { // 駒のない枡 foodKomasyurui = PieceType.None;//取った駒無し。 } else { // 駒のある枡 foodKomasyurui = Util_Starlightable.AsKoma(kaisi_Sky.StarlightIndexOf(figFoodKoma).Now).Komasyurui;//取った駒有り。 } IMoveSource dstKoma = new RO_Star( pside, dstMasu, UtilCsaMove.ToKomasyurui(csaMove) ); nextMove = new RO_Starbeam( srcKoma, // 移動元 dstKoma, // 移動先 foodKomasyurui ////取った駒 ); } { //---------------------------------------- // 一手指したい。 //---------------------------------------- // //↓↓一手指し IttesasuResult ittesasuResult; Util_IttesasuRoutine.Before1( new IttesasuArgImpl( kifu1.CurNode.Value, ((KifuNode)kifu1.CurNode).Value.KyokumenConst.KaisiPside, nextMove, kifu1.CurNode.Value.KyokumenConst.Temezumi + 1//1手進める ), out ittesasuResult, //kifu1,//診断用 "Utli_LearningViews#ShowMoveList" ); Debug.Assert(ittesasuResult.Get_SyuryoNode_OrNull != null, "ittesasuResult.Get_SyuryoNode_OrNull がヌル☆?!"); Util_IttesasuRoutine.Before2( ref ittesasuResult ); // //次ノートを追加します。次ノードを、これからのカレントとします。 // //kifu1.AssertChildPside(kifu1.CurNode.Value.ToKyokumenConst.KaisiPside, ittesasuResult.Get_SyuryoNode_OrNull.Value.ToKyokumenConst.KaisiPside); Util_IttesasuRoutine.After3_ChangeCurrent( kifu1, ConvMoveStrSfen.ToMoveStrSfen(ittesasuResult.Get_SyuryoNode_OrNull.Key),// nextMoveStr, ittesasuResult.Get_SyuryoNode_OrNull ); // これで、棋譜ツリーに、構造変更があったはず。 //↑↑一手指し } string sfen; if (kifu1.CurNode.IsRoot()) { sfen = UtilCsaMove.ToSfen(csaMove, null); } else { sfen = UtilCsaMove.ToSfen(csaMove, kifu1.CurNode.GetParentNode().Value.KyokumenConst); } HonpuMoveListItemImpl listItem = new HonpuMoveListItemImpl(csaMove, sfen); uc_Main.LstMove.Items.Add(listItem); } //---------------------------------------- // ソート //---------------------------------------- //List<MoveListItemImpl> list = new List<MoveListItemImpl>(); //list.Sort((MoveListItemImpl a, MoveListItemImpl b) => //{ // return a - b; //}); }