/// <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> /// シングルトン。 /// </summary> /// <returns></returns> public static Event_CsharpImpl GetInstance() { if (null == Event_CsharpImpl.instance) { Event_CsharpImpl ins = new Event_CsharpImpl(); Event_CsharpImpl.instance = ins; // // [成る]ボタンのイベント。 // ins.delegate_BtnNaru = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; MainGui_Csharp shogibanGui2 = (MainGui_Csharp)obj_shogiGui2; shogibanGui2.SetNaruFlag(true); ins.After_NaruNaranai_ButtonPushed( shogibanGui2 , btnKoma_Selected ); }; // // [成らない]ボタンのイベント。 // ins.delegate_BtnNaranai = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; MainGui_Csharp shogibanGui2 = (MainGui_Csharp)obj_shogiGui2; shogibanGui2.SetNaruFlag(false); ins.After_NaruNaranai_ButtonPushed( shogibanGui2 , btnKoma_Selected ); }; // // [クリアー]ボタンのイベント。 // ins.delegate_BtnClear = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; MainGui_Csharp shogibanGui2 = (MainGui_Csharp)obj_shogiGui2; Util_Lua_Csharp.ShogiGui = shogibanGui2; Util_Lua_Csharp.Perform("click_clearButton"); }; // // [再生]ボタンのイベント。 // ins.delegate_BtnPlay = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; MainGui_Csharp shogibanGui2 = (MainGui_Csharp)obj_shogiGui2; Util_Lua_Csharp.ShogiGui = shogibanGui2; Util_Lua_Csharp.Perform("click_playButton"); }; // // [コマ送り]ボタンのイベント。 // ins.delegate_BtnForward = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; MainGui_Csharp mainGui3 = (MainGui_Csharp)obj_shogiGui2; string restText = Util_Function_Csharp.ReadLine_FromTextbox(); Util_Functions_Server.Komaokuri_Srv( ref restText, mainGui3.Link_Server.Model_Taikyoku, mainGui3.Model_Manual); Util_Function_Csharp.Komaokuri_Gui(restText, mainGui3); Util_Menace.Menace(mainGui3);// メナス }; // // [巻き戻し]ボタンのイベント。 // ins.delegate_BtnBackward = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; MainGui_Csharp shogibanGui2 = (MainGui_Csharp)obj_shogiGui2; Finger movedKoma; Finger foodKoma;//取られた駒 string fugoJStr; if (!Util_Functions_Server.Makimodosi_Srv(out movedKoma, out foodKoma, out fugoJStr, shogibanGui2.Link_Server.Model_Taikyoku)) { goto gt_EndBlock; } Util_Function_Csharp.Makimodosi_Gui(shogibanGui2, movedKoma, foodKoma, fugoJStr, Util_Function_Csharp.ReadLine_FromTextbox()); Util_Menace.Menace(shogibanGui2);//メナス gt_EndBlock: ; }; // // [ログ出せ]ボタンのイベント。 // ins.delegate_BtnLogdase = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { MainGui_Csharp shogibanGui2 = (MainGui_Csharp)obj_shogiGui2; Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; shogibanGui2.Logdase(); }; // // [壁置く]ボタンのイベント。 // ins.delegate_BtnKabeOku = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { MainGui_Csharp shogibanGui2 = (MainGui_Csharp)obj_shogiGui2; Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; UserWidget widget = shogibanGui2.GetWidget("BtnKabeOku"); // [壁置く]←→[駒動かす]切替 switch (widget.Text) { case "壁置く": widget.Text = "駒動かす"; break; default: widget.Text = "壁置く"; break; } shogibanGui2.RepaintRequest.SetFlag_RefreshRequest(); }; // // [出力切替]ボタンのイベント。 // ins.delegate_BtnSyuturyokuKirikae = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; MainGui_Csharp shogibanGui2 = (MainGui_Csharp)obj_shogiGui2; switch (shogibanGui2.SyuturyokuKirikae) { case SyuturyokuKirikae.Japanese: shogibanGui2.SetSyuturyokuKirikae(SyuturyokuKirikae.Sfen); break; case SyuturyokuKirikae.Sfen: shogibanGui2.SetSyuturyokuKirikae(SyuturyokuKirikae.Html); break; case SyuturyokuKirikae.Html: shogibanGui2.SetSyuturyokuKirikae(SyuturyokuKirikae.Japanese); break; } shogibanGui2.RepaintRequest.SyuturyokuRequest = RepaintRequestGedanTxt.Kifu; }; // // [各種符号]ボタンのイベント。 // ins.delegate_BtnKakusyuFugo = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; UserWidget userWidget = (UserWidget)userWidget2; MainGui_Csharp shogibanGui2 = (MainGui_Csharp)obj_shogiGui2; UserWidget widget = shogibanGui2.GetWidget(userWidget.Name); shogibanGui2.RepaintRequest.SetNyuryokuTextTail(widget.Fugo); }; // // [全消]ボタンのイベント。 // ins.delegate_BtnZenkesi = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; MainGui_Csharp shogibanGui2 = (MainGui_Csharp)obj_shogiGui2; shogibanGui2.RepaintRequest.NyuryokuText = ""; }; // // [ここから採譜]ボタンのイベント。 // ins.delegate_BtnKokokaraSaifu = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; MainGui_Csharp shogibanGui2 = (MainGui_Csharp)obj_shogiGui2; UtilKifuTree282.SetStartpos_KokokaraSaifu(shogibanGui2.Link_Server.Model_Taikyoku.Kifu, shogibanGui2.Link_Server.Model_Taikyoku.Kifu.CurNode.Value.KyokumenConst.KaisiPside); shogibanGui2.RepaintRequest.SyuturyokuRequest = RepaintRequestGedanTxt.Kifu; }; // // [初期配置]ボタンのイベント。 // ins.delegate_BtnSyokihaichi = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; MainGui_Csharp shogibanGui2 = (MainGui_Csharp)obj_shogiGui2; Util_Function_Csharp.Perform_SyokiHaichi(shogibanGui2); }; // // [向き]ボタンのイベント。 // ins.delegate_BtnMuki = ( object obj_shogiGui2 , object userWidget2 // UerWidget , object btnKoma_Selected2 ) => { Shape_BtnKoma btnKoma_Selected = (Shape_BtnKoma)btnKoma_Selected2; MainGui_Csharp mainGui3 = (MainGui_Csharp)obj_shogiGui2; Shape_BtnKoma movedKoma = mainGui3.Shape_PnlTaikyoku.Btn_MovedKoma(); RO_Star koma; Finger figKoma = Fingers.Error_1; if (null != movedKoma) { //>>>>> 移動直後の駒があるとき koma = Util_Starlightable.AsKoma(mainGui3.Model_Manual.GuiSkyConst.StarlightIndexOf(movedKoma.Finger).Now); figKoma = movedKoma.Finger; } else if (null != btnKoma_Selected) { //>>>>> 選択されている駒があるとき koma = Util_Starlightable.AsKoma(mainGui3.Model_Manual.GuiSkyConst.StarlightIndexOf(btnKoma_Selected.Koma).Now); figKoma = btnKoma_Selected.Koma; } else { koma = null; } if (null != koma) { KifuNode modifyNode = new KifuNodeImpl( mainGui3.Link_Server.Model_Taikyoku.Kifu.CurNode.Key,//現在の局面を流用 new KyokumenWrapper( SkyConst.NewInstance_OverwriteOrAdd_Light( mainGui3.Model_Manual.GuiSkyConst, -1,//そのまま figKoma, new RO_Starlight( new RO_Star( Conv_Playerside.Reverse(koma.Pside),//向きを逆さにします。 koma.Masu, koma.Komasyurui ) ) ) ) ); // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // ここで局面データを変更します。 // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ string jsaFugoStr; Util_Functions_Server.SetCurNode_Srv( mainGui3.Link_Server.Model_Taikyoku, mainGui3.Model_Manual, modifyNode, out jsaFugoStr); mainGui3.RepaintRequest.SetFlag_RefreshRequest(); } }; } return(Event_CsharpImpl.instance); }
public void Go(string btime, string wtime, string byoyomi, string binc, string winc) { //------------------------------------------------------------ // あなたの手番です //------------------------------------------------------------ // // 図. // // log.txt // ┌──────────────────────────────────────── // ~ // │2014/08/02 2:36:19> go btime 599000 wtime 600000 byoyomi 60000 // │ // // もう指していいときに、将棋所から送られてくる文字が go です。 // //------------------------------------------------------------ // 先手 3:00 後手 0:00 記録係「50秒ぉ~」 //------------------------------------------------------------ // // 上図のメッセージのままだと使いにくいので、 // あとで使いやすいように Key と Value の表に分けて持ち直します。 // // 図. // // goDictionary // ┌──────┬──────┐ // │Key │Value │ // ┝━━━━━━┿━━━━━━┥ // │btime │599000 │ // ├──────┼──────┤ // │wtime │600000 │ // ├──────┼──────┤ // │byoyomi │60000 │ // └──────┴──────┘ // 単位はミリ秒ですので、599000 は 59.9秒 です。 // //---------------------------------------- // 棋譜ツリー、局面データは、position コマンドで先に与えられているものとします。 //---------------------------------------- // ┏━━━━プログラム━━━━┓ int latestTemezumi = this.Game.Kifu.CurNode.Value.KyokumenConst.Temezumi; //現・手目済 SkyConst src_Sky = this.Game.Kifu.NodeAt(latestTemezumi).Value.KyokumenConst; //現局面 //Logger.Trace($"将棋サーバー「{latestTemezumi}手目、きふわらべ さんの手番ですよ!」 {line}"); //---------------------------------------- // 王の状態を調べます。 //---------------------------------------- Result_KingState result_kingState; { result_kingState = Result_KingState.Empty; RO_Star king1p = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(Finger_Honshogi.SenteOh).Now); RO_Star king2p = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(Finger_Honshogi.GoteOh).Now); //Logger.Trace("将棋サーバー「ではここで、王さまがどこにいるか確認してみましょう」"); //Logger.Trace($"▲王の置き場={Conv_SyElement.Masu_ToOkiba(koma1.Masu)}"); //Logger.Trace($"△王の置き場={Conv_SyElement.Masu_ToOkiba(koma2.Masu)}"); if (Conv_SyElement.ToOkiba(king1p.Masu) != Okiba.ShogiBan) { // 先手の王さまが将棋盤上にいないとき☆ result_kingState = Result_KingState.Lost_SenteOh; } else if (Conv_SyElement.ToOkiba(king2p.Masu) != Okiba.ShogiBan) { // または、後手の王さまが将棋盤上にいないとき☆ result_kingState = Result_KingState.Lost_GoteOh; } else { result_kingState = Result_KingState.Empty; } } //------------------------------------------------------------ // わたしの手番のとき、王様が 将棋盤上からいなくなっていれば、投了します。 //------------------------------------------------------------ // // 将棋GUI『きふならべ』用☆ 将棋盤上に王さまがいないときに、本将棋で go コマンドが送られてくることは無いのでは☆? // switch (result_kingState) { case Result_KingState.Lost_SenteOh: // 先手の王さまが将棋盤上にいないとき☆ case Result_KingState.Lost_GoteOh: // または、後手の王さまが将棋盤上にいないとき☆ { //------------------------------------------------------------ // 投了 //------------------------------------------------------------ // // 図. // // log.txt // ┌──────────────────────────────────────── // ~ // │2014/08/02 2:36:21< bestmove resign // │ // // この将棋エンジンは、後手とします。 // 20手目、投了 を決め打ちで返します。 Playing.Send("bestmove resign"); //投了 } break; default: // どちらの王さまも、まだまだ健在だぜ☆! { List <KifuNode> bestKifuNodeList = new List <KifuNode>(); //------------------------------------------------------------ // 指し手のチョイス //------------------------------------------------------------ bool isHonshogi = true; //------------------------------------------------------------ // MultiPV のテスト中☆ //------------------------------------------------------------ // // 指し手を決めます。 // TODO: その指し手の評価値がいくらだったのか調べたい。 // // FIXME: ログがMultiPV別になっていないので、混ざって、同じ手を2度指しているみたいに見えてしまう☆ // int multiPV_Count = 1; // 2; { // 最善手、次善手、三次善手、四次善手、五次善手 for (int iMultiPV = 0; iMultiPV < multiPV_Count; iMultiPV++) { bestKifuNodeList.Add(this.WA_Bestmove( isHonshogi, this.Game.Kifu) ); } #if DEBUG //// 内容をログ出力 //// 最善手、次善手、三次善手、四次善手、五次善手 //StringBuilder sb = new StringBuilder(); //for (int iMultiPV = 0; iMultiPV < 5; iMultiPV++) //{ // string sfenText = Util_Sky.ToSfenMoveText(bestMoveList[iMultiPV]); // sb.AppendLine($"[{iMultiPV}]{sfenText}"); //} //System.Windows.Forms.MessageBox.Show(sb.ToString()); #endif } KifuNode bestKifuNode = null; // 最善手、次善手、三次善手、四次善手、五次善手 float bestScore = float.MinValue; for (int iMultiPV = 0; iMultiPV < bestKifuNodeList.Count; iMultiPV++) { KifuNode node = bestKifuNodeList[iMultiPV]; if (null != node && null != node.KyHyokaSheet_Mutable && bestScore <= node.Score) { bestScore = node.Score; bestKifuNode = node; } } IMove bestMove2; if (null == bestKifuNode) { // 投了 bestMove2 = Util_Sky258A.NullObjectMove; } else { bestMove2 = bestKifuNode.Key; } if (Util_Sky_BoolQuery.isEnableSfen(bestMove2)) { string sfenText = ConvMoveStrSfen.ToMoveStrSfen(bestMove2); // ログが重過ぎる☆! //Logger.Trace($"(Warabe)指し手のチョイス: bestmove=[{sfenText}] 棋譜={KirokuGakari.ToJsaKifuText(this.Kifu)}"); //---------------------------------------- // スコア 試し //---------------------------------------- { //int hyojiScore = (int)(bestScore / 100.0d);//FIXME:適当に調整した。 int hyojiScore = (int)bestScore; if (this.Game.Kifu.CurNode.Value.KyokumenConst.KaisiPside == Playerside.P2) { // 符号を逆転 hyojiScore = -hyojiScore; } Playing.Send($"info time 1 depth 1 nodes 1 score cp {hyojiScore.ToString()} pv "); //FIXME: //+ " pv 3a3b L*4h 4c4d" } //---------------------------------------- // 指し手を送ります。 //---------------------------------------- Playing.Send($"bestmove {sfenText}"); } else // 指し手がないときは、SFENが書けない☆ 投了だぜ☆ { // ログが重過ぎる☆! //Logger.Trace($"(Warabe)指し手のチョイス: 指し手がないときは、SFENが書けない☆ 投了だぜ☆ww(>_<) 棋譜={KirokuGakari.ToJsaKifuText(this.Kifu)}"); //---------------------------------------- // 投了w! //---------------------------------------- Playing.Send("bestmove resign"); } //------------------------------------------------------------ // 以前の手カッター //------------------------------------------------------------ UtilKifuTree282.IzennoHenkaCutter(this.Game.Kifu); } break; } // ┗━━━━プログラム━━━━┛ // Logger.Trace(); //throw new Exception("デバッグだぜ☆! エラーはキャッチできたかな~☆?(^▽^)"); }