public GameViewModel() { // // 駒なし // this.guiSky = Util_Sky.New_Komabukuro();// 描画モデル作成時 this.GuiTesumi = 0; this.GuiPside = Playerside.P1; // // // this.kifu = new KifuTreeImpl( new KifuNodeImpl( Util_Sky.NullObjectMove, new KyokumenWrapper(new SkyConst(this.guiSky)), Playerside.P2 ) ); this.Init(); }
/// <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 = 0.0d; SkyConst src_Sky = args.Node.Value.ToKyokumenConst; // // どの駒(のある場所)が // 指定のマスより、どれぐらい離れているか(距離) // int kyori = Util_KomanoKyori.GetKyori(args.TenonagareGenjo.Masu, args.TenonagareGenjo.Koma1.Masu); score = 100.0d - 3.0d * kyori;//てきとーな数字です。 //// ログ //{ // string move = Converter04.Move_ToString_ForLog(args.Input_node.Key);// どの指し手の局面で // ((ShogiEngine)args.Owner).Log_Engine.WriteLine_AddMemo("駒[" + Haiyaku184Array.Name[(int)koma.Haiyaku].Trim() + "(No." + (int)((Atamanosumi)args.atamanosumi).Finger + ")]が、マス[" + Converter04.Masu_ToKanji(((Atamanosumi)args.Input_atamanosumi).Masu) + "]を目指したいんだぜ~☆。指し手が[" + move + "]なら、距離は[" + kyori + "]、スコアは[" + score + "]だぜ☆"); //} string meisai = ""; #if DEBUG // 明細 { StringBuilder sb = new StringBuilder(); sb.Append("100.0d - 3.0d * (距離 " + kyori + ")"); meisai = sb.ToString(); } #endif kyokumenScore = new KyHyoka100limitItemImpl(args.TenonagareGenjo.ScoreKeisu, score, meisai); }
/// <summary> /// 全合法手をダンプ。 /// </summary> /// <returns></returns> public string DumpToAllGohosyu(SkyConst src_Sky) { StringBuilder sb = new StringBuilder(); //sb.AppendLine("--------------------"); //sb.AppendLine("カレントノード内部データ"); //sb.AppendLine("--------------------"); src_Sky.Foreach_Starlights((Finger finger, IMoveHalf light, ref bool toBreak) => { // 番号 sb.Append("Fig."); sb.Append(finger); sb.Append(" "); RO_Star koma = Util_Starlightable.AsKoma(light.Now); // P1,P2 sb.Append(koma.Pside); sb.Append(" "); // 升00 sb.Append(Conv_Sy.Query_Word(koma.Masu.Bitfield)); sb.Append(" "); // 歩、香… sb.Append(Util_Komasyurui14.ToIchimoji(koma.Komasyurui)); sb.AppendLine(); }); return(sb.ToString()); }
public Result_Ajimi Ajimi(SkyConst src_Sky) { Result_Ajimi result_Ajimi = Result_Ajimi.Empty; RO_Star_Koma koma1 = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(Finger_Honshogi.SenteOh).Now); RO_Star_Koma koma2 = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(Finger_Honshogi.GoteOh).Now); Logger.Trace("将棋サーバー「ではここで、王さまがどこにいるか確認してみましょう」"); Logger.Trace("▲王の置き場=" + Util_Masu.GetOkiba(koma1.Masu)); Logger.Trace("△王の置き場=" + Util_Masu.GetOkiba(koma2.Masu)); if (Util_Masu.GetOkiba(koma1.Masu) != Okiba.ShogiBan) { // 先手の王さまが将棋盤上にいないとき☆ result_Ajimi = Result_Ajimi.Lost_SenteOh; } else if (Util_Masu.GetOkiba(koma2.Masu) != Okiba.ShogiBan) { // または、後手の王さまが将棋盤上にいないとき☆ result_Ajimi = Result_Ajimi.Lost_GoteOh; } else { result_Ajimi = Result_Ajimi.Empty; } return(result_Ajimi); }
public AimsServerImpl(SkyConst src_Sky, int temezumi) : base(src_Sky, temezumi, new Receiver_ForAimsImpl()) { // AIMSサーバー用の特別処理。 ((Receiver_ForAimsImpl)this.EngineClient.Receiver).SetOwner_AimsServer(this); // 最初の状態。 this.phase_AimsServer = Phase_AimsServer._01_Server_Booted; }
/// <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 = 0.0d; SkyConst src_Sky = args.Node.Value.ToKyokumenConst; // // 指定された駒。 // RO_Star_Koma koma1 = args.TenonagareGenjo.Koma1; if (Okiba.ShogiBan != Util_Masu.Masu_ToOkiba(koma1.Masu)) { // 指定された駒が将棋盤の上になければ、無視。 goto gt_EndMethod; } // // 初期位置にいると、点数が低いものとします。 // if (koma1.Masu == args.TenonagareGenjo.Masu) { score = 0.0d; } else { score = 100.0d; } //// //// 先手から見た盤に回転。 //// //SyElement komaMasu = Util_Masu.BothSenteView(koma1.Masu, koma1.Pside); //int dan; //Util_MasuNum.MasuToDan(komaMasu, out dan); gt_EndMethod: string meisai = ""; #if DEBUG // 明細 { StringBuilder sb = new StringBuilder(); // 初期位置にいると、点数が低いものとします。 if (koma1.Masu == args.TenonagareGenjo.Masu) { sb.Append("(初期位置 0.0d)"); } else { sb.Append("(初期位置から離れている 100.0d)"); } meisai = sb.ToString(); } #endif kyokumenScore = new KyHyoka100limitItemImpl(args.TenonagareGenjo.ScoreKeisu, score, meisai); }
public Model_ManualImpl() { // // 駒なし // this.GuiTemezumi = 0; Playerside firstPside = Playerside.P1; this.GuiPside = firstPside; this.guiSkyConst = Util_SkyWriter.New_Komabukuro(firstPside);// 描画モデル作成時 }
public MmGenjo_MovableMasuImpl( bool isHonshogi, SkyConst src_Sky, Playerside pside_genTeban3, bool isAiteban ) { this.isHonshogi = isHonshogi; this.src_Sky = src_Sky; this.pside_genTeban3 = pside_genTeban3; this.isAiteban = isAiteban; }
/// <summary> /// SasuEntry→KifuNode /// </summary> /// <param name="sasuEntry"></param> /// <param name="src_Sky"></param> /// <returns></returns> public static KifuNode ToKifuNode( SasuEntry sasuEntry, SkyConst src_Sky ) { return(new KifuNodeImpl(sasuEntry.NewMove, new KyokumenWrapper( Util_Sasu341.Sasu( src_Sky, //指定局面 sasuEntry.Finger, //指す駒 sasuEntry.Masu, //移動先升 sasuEntry.Naru //成ります。 )))); }
public Game() { this.FirstPside = Playerside.P1; // FIXME:平手とは限らないが、平手という前提で作っておく。 this.Kifu = new KifuTreeImpl( new KifuNodeImpl( Util_Sky258A.RootMove, new KyokumenWrapper(SkyConst.NewInstance( Util_SkyWriter.New_Hirate(this.FirstPside), 0 // 初期局面は 0手目済み )) // きふわらべ起動時 ) ); this.Kifu.SetProperty(Word_KifuTree.PropName_Startpos, "startpos");// 平手 // FIXME:平手とは限らないが。 }
private static void Log1( Tansaku_Genjo genjo, IMove src_Sky_move, SkyConst src_Sky, out MmLogGenjoImpl out_mm_log, out KaisetuBoard out_logBrd_move1 ) { out_logBrd_move1 = new KaisetuBoard();// 盤1個分のログの準備 out_mm_log = new MmLogGenjoImpl( genjo.YomikaisiTemezumi, out_logBrd_move1, //ログ? src_Sky.Temezumi, //手済み src_Sky_move //指し手 ); }
static void Main(string[] args) { MessageBox.Show("AIMSサーバー"); var engineConf = new EngineConf(); EntitiesLayer.Implement(engineConf); string filepath = engineConf.GetResourceFullPath("AimsDataSetteiXml"); MessageBox.Show($"設定ファイルパス=[{filepath}]"); // // 設定XMLファイル // SetteiXmlFile setteiXmlFile; { setteiXmlFile = new SetteiXmlFile(filepath); //if (!setteiXmlFile.Exists()) //{ // // ファイルが存在しませんでした。 // // 作ります。 // setteiXmlFile.Write(); //} setteiXmlFile.Read(); // デバッグ //setteiXmlFile.DebugWrite(); } MessageBox.Show($"AIMSサーバー\n将棋エンジン・ファイルパス=[{setteiXmlFile.ShogiEngineFilePath}]"); SkyConst src_Sky = Util_SkyWriter.New_Hirate(Playerside.P1); AimsServerImpl aimsServer = new AimsServerImpl(src_Sky, 0); aimsServer.ShogiEngineFilePath = setteiXmlFile.ShogiEngineFilePath; aimsServer.AtBegin(); aimsServer.AtBody(); }
/// <summary> /// v(^▽^)v超能力『メナス』だぜ☆ 未来の脅威を予測し、可視化するぜ☆www /// </summary> public static void Menace(MainGui_Csharp mainGui) { if (0 < mainGui.Model_Manual.GuiTemezumi) { // 処理の順序が悪く、初回はうまく判定できない。 SkyConst src_Sky = mainGui.Model_Manual.GuiSkyConst; //---------- // 将棋盤上の駒 //---------- mainGui.RepaintRequest.SetFlag_RefreshRequest(); // [クリアー] mainGui.Shape_PnlTaikyoku.Shogiban.ClearHMasu_KikiKomaList(); // 全駒 foreach (Finger figKoma in Finger_Honshogi.Items_KomaOnly) { RO_Star koma = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(figKoma).Now); if ( Okiba.ShogiBan == Conv_SyElement.ToOkiba(koma.Masu) && mainGui.Model_Manual.GuiPside != koma.Pside ) { // 駒の利き SySet <SyElement> kikiZukei = Util_Sky_SyugoQuery.KomaKidou_Potential(figKoma, src_Sky); IEnumerable <SyElement> kikiMasuList = kikiZukei.Elements; foreach (SyElement masu in kikiMasuList) { // その枡に利いている駒のハンドルを追加 if (!Masu_Honshogi.IsErrorBasho(masu)) { mainGui.Shape_PnlTaikyoku.Shogiban.HMasu_KikiKomaList[Conv_SyElement.ToMasuNumber(masu)].Add((int)figKoma); } } } } } }
/// <summary> /// v(^▽^)v超能力『メナス』だぜ☆ 未来の脅威を予測し、可視化するぜ☆www /// </summary> public static void Menace(NarabeRoomViewModel shogiGui) { if (0 < shogiGui.GameViewModel.GuiTesumi) { // 処理の順序が悪く、初回はうまく判定できない。 SkyConst src_Sky = shogiGui.GameViewModel.GuiSkyConst; //---------- // 将棋盤上の駒 //---------- shogiGui.ResponseData.ToRedraw(); // [クリアー] shogiGui.Shape_PnlTaikyoku.Shogiban.ClearHMasu_KikiKomaList(); // 全駒 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) && shogiGui.GameViewModel.GuiPside != koma.Pside ) { // 駒の利き SySet <SyElement> kikiZukei = Util_Sky.KomaKidou_Potential(figKoma, src_Sky); IEnumerable <SyElement> kikiMasuList = kikiZukei.Elements; foreach (SyElement masu in kikiMasuList) { // その枡に利いている駒のハンドルを追加 if (Masu_Honshogi.Error != masu) { shogiGui.Shape_PnlTaikyoku.Shogiban.HMasu_KikiKomaList[Util_Masu.AsMasuNumber(masu)].Add((int)figKoma); } } } } } }
/// <summary> /// /// </summary> /// <param name="kifu"></param> /// <param name="restText"></param> /// <param name="startposImporter"></param> /// <param name="logTag"></param> public static void OnChangeSky_Im_Client( Model_Taikyoku model_Taikyoku, KifuParserA_Genjo genjo ) { Logger.Trace($"(^△^)「{genjo.InputLine}」Util_InClient : クライアントの委譲メソッドキター☆"); string old_inputLine = genjo.InputLine;//退避 string rest; ISfenPosition2 ro_Kyokumen2_ForTokenize; Sfenstring146Conv.ToKyokumen2( genjo.InputLine, out rest, out ro_Kyokumen2_ForTokenize ); Logger.Trace($"(^△^)old_inputLine=「{old_inputLine}」 rest=「{rest}」 Util_InClient : ハハッ☆"); //string old_inputLine = genjo.InputLine; //genjo.InputLine = ""; //---------------------------------------- // 棋譜を空っぽにし、指定の局面を与えます。 //---------------------------------------- { model_Taikyoku.Kifu.Clear();// 棋譜を空っぽにします。 // 文字列から、指定局面を作成します。 Playerside pside = Playerside.P1; int temezumi = 0; model_Taikyoku.Kifu.GetRoot().Value.SetKyokumen( SkyConst.NewInstance( Conv_Sfenstring307.ToSkyConst(new SfenStringImpl(old_inputLine), pside, temezumi), temezumi //初期配置は 0手目済み。 ) ); //SFENのstartpos解析時 model_Taikyoku.Kifu.SetProperty(Word_KifuTree.PropName_Startpos, old_inputLine); //指定の初期局面 } }
/// <summary> /// Pの持ち駒項目の、配列の添え字番号。 /// /// 王は判定できない。 /// </summary> /// <param name="src_Sky"></param> /// <param name="pside"></param> /// <param name="syurui"></param> /// <returns>エラー時は-1</returns> public static int ParamIndex_Moti(SkyConst src_Sky, Playerside pside, PieceType syurui) { Fingers fingers = Util_Sky_FingersQuery.InOkibaPsideKomasyuruiNow(src_Sky, Conv_Playerside.ToKomadai(pside), pside, syurui); int index_playerside = Util_FvParamIndex.paramIndex_Playerside[(int)pside]; int index_komasyurui = Util_FvParamIndex.paramIndex_KomaSyrui_Moti[(int)syurui]; if (index_playerside == -1) { throw new Exception("二駒関係の持ち駒_先後不明の駒"); } else if (index_komasyurui == -1) { throw new Exception("二駒関係の持ち駒_駒種類が対象外の駒"); } int koumokuP = index_playerside + index_komasyurui + fingers.Count; Debug.Assert(0 <= koumokuP && koumokuP < FeatureVectorImpl.CHOSA_KOMOKU_P, $"koumokuP=[{koumokuP}]"); return(koumokuP); }
public Server_Impl(SkyConst src_Sky, int temezumi, Receiver receiver) { this.engineClient = new EngineClient_Impl(receiver); this.engineClient.SetOwner_Server(this); //---------- // モデル //---------- this.model_Taikyoku = new Model_TaikyokuImpl(new KifuTreeImpl( new KifuNodeImpl( Util_Sky258A.RootMove, new KyokumenWrapper(SkyConst.NewInstance( src_Sky, //model_Manual.GuiSkyConst, temezumi //model_Manual.GuiTemezumi )) ) )); this.Model_Taikyoku.Kifu.SetProperty(Word_KifuTree.PropName_Startpos, "9/9/9/9/9/9/9/9/9"); this.inputString99 = ""; }
/// <summary> /// 棋譜ツリーを、平手初期局面 で準備します。 /// </summary> public static void CreateKifuTree(out KifuTree kifu) { // 初期局面では、Player 1 の手番とします。 Playerside firstPside = Playerside.P1; // 棋譜 kifu = new KifuTreeImpl( new KifuNodeImpl( Util_Sky258A.RootMove, new KyokumenWrapper(SkyConst.NewInstance( Util_SkyWriter.New_Hirate(firstPside), 0//初期局面なので、0手目済み。 )) ) ); kifu.SetProperty(Word_KifuTree.PropName_Startpos, "startpos");// 平手 Debug.Assert(!Conv_MasuHandle.OnKomabukuro( Conv_SyElement.ToMasuNumber(((RO_Star)kifu.CurNode.Value.KyokumenConst.StarlightIndexOf((Finger)0).Now).Masu) ), "駒が駒袋にあった。"); }
/// <summary> /// 2駒関係[KK]用。 /// フィーチャーベクターの調査項目インデックス。該当なければ-1。 /// </summary> /// <param name="pside">プレイヤーサイド</param> /// <param name="komasyurui">盤上の種類</param> /// <param name="masu">盤上の駒の升</param> /// <returns></returns> public static int ToKIndex_From_PsideBanjoKomasyuruiMasu(SkyConst src_Sky, Playerside pside) { // 調査項目番号(K1、K2等) int result; SyElement masu; { Finger figK1 = Util_Sky_FingersQuery.InOkibaPsideKomasyuruiNow(src_Sky, Okiba.ShogiBan, pside, PieceType.K).ToFirst(); RO_Star komaK1 = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(figK1).Now); masu = komaK1.Masu; } if (Okiba.ShogiBan != Conv_SyElement.ToOkiba(masu)) { // 盤上でなければ。 result = -1; goto gt_EndMethod; } int kSuji; Util_MasuNum.TryMasuToSuji(masu, out kSuji); int kDan; Util_MasuNum.TryMasuToDan(masu, out kDan); int p1; Conv_FvKoumoku522.Converter_K1_to_P(Playerside.P1, kDan, kSuji, out p1); result = p1; gt_EndMethod: ; return(result); }
/// <summary> /// 評価値を返します。先手が有利ならプラス、後手が有利ならマイナス、互角は 0.0 です。 /// </summary> /// <param name="input_node"></param> /// <param name="playerInfo"></param> /// <returns></returns> public override void Evaluate( out float out_score, #if DEBUG || LEARN out KyHyokaMeisai_Koumoku out_meisaiKoumoku_orNull, #endif SkyConst src_Sky, FeatureVector featureVector ) { out_score = 0.0f;//互角 switch (src_Sky.KaisiPside) { case Playerside.P1: out_score = float.MinValue; break; case Playerside.P2: out_score = float.MaxValue; break; default: throw new Exception("千日手判定をしようとしましたが、先後の分からない局面データがありました。"); } //gt_EndMethod: // ; //---------------------------------------- // 明細項目 //---------------------------------------- #if DEBUG || LEARN string utiwake = ""; // 明細 { StringBuilder sb = new StringBuilder(); sb.Append($"千日手。 score=[{out_score}]"); utiwake = sb.ToString(); } out_meisaiKoumoku_orNull = new KyHyokaMeisai_KoumokuImpl(utiwake, out_score); #endif }
/// <summary> /// 指定した局面の評価を、加点(減点)します。 /// </summary> public static void UpdateKyokumenHyoka( N54List n54List, SkyConst src_Sky, FeatureVector fv_mutable, float tyoseiryo, out float out_real_tyoseiryo//実際に調整した量。 ) { // // 盤上の駒数と、持駒の先後の種類数 // //int banjoKomaKazu_motiSyuruiKazu = 0; // 増 or 減 { // 調整量を刻みます。 float kizami_up = Util_Tyoseiryo.Average_54x54Parameters(tyoseiryo, n54List); int changedCells; Util_FvScoreing.Fill54x54_Add(out changedCells, kizami_up, src_Sky, fv_mutable, n54List); out_real_tyoseiryo = changedCells * kizami_up; } // 持ち駒の BAD値を矯正 FIXME: 持ち駒を打つのが悪手なのは、だいたい合っているのでは? //if(false) //{ // float sum_bad = Util_FvScoreing.Spoil_MotiBad(src_Sky.KaisiPside, fv_mutable, n54List); // // 盤上の三駒関係に、均等に BAD値 を配分。 // Util_FvScoreing.Fill54x54_Add_ToBanjo( // sum_bad / (float)n54List.P40Next,//平均にする // src_Sky, // fv_mutable, // n54List, // logTag // ); //} }
public static float Initial_BestScore(SkyConst src_Sky) { // このノードが、どちらの手番か。 Playerside pside = src_Sky.KaisiPside; float alphabeta_bestScore;// プレイヤー1ならmax値、プレイヤー2ならmin値。 switch (pside) { case Playerside.P1: // 1プレイヤーはまだ、大きな数を見つけていないという設定。 alphabeta_bestScore = float.MinValue; break; case Playerside.P2: // 2プレイヤーはまだ、小さな数を見つけていないという設定。 alphabeta_bestScore = float.MaxValue; break; default: throw new Exception("探索中、プレイヤーサイドのエラー"); } return(alphabeta_bestScore); }
/// <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> /// 将棋エンジンから、データを非同期受信(*1)します。 /// /// *1…こっちの都合に合わせず、データが飛んできます。 /// /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public override void OnListenUpload_Async(object sender, DataReceivedEventArgs e) { string line = e.Data; if (null == line) { // 無視 } else { switch (this.Owner_AimsServer.Phase_AimsServer) { case Phase_AimsServer._01_Server_Booted: break; //thru case Phase_AimsServer._02_WaitAimsUsiok: break; //thru case Phase_AimsServer._03_WaitEngineLive: break; //thru case Phase_AimsServer._04_WaitEngineUsiok: { if (line.StartsWith("option ")) { //ok MessageBox.Show($"将棋サーバー「Firstフェーズで、将棋エンジンから、オプション[{line}]が返ってきたぜ☆!」"); } else if (line.StartsWith("id ")) { //ok MessageBox.Show($"将棋サーバー「Firstフェーズで、将棋エンジンから、アイディー[{line}]が返ってきたぜ☆!」"); } else if ("usiok" == line) { //------------------------------------------------------------ // AIMS GUIへ: 「isready」を転送します。 //------------------------------------------------------------ //MessageBox.Show($"将棋サーバー「将棋エンジンから、usiokが返ってきたぜ☆!\nサーバーは WaitAimsIsready フェーズに移るぜ☆\nAIMS GUIには isready を送るぜ☆!」"); this.Owner_AimsServer.SetPhase_AimsServer(Phase_AimsServer._05_WaitAimsReadyok); Console.Out.WriteLine("isready"); } else { MessageBox.Show($"将棋サーバー「WaitEngineUsiokフェーズで、将棋エンジンから、[{line}]が返ってきたぜ☆!」"); } } break; case Phase_AimsServer._05_WaitEngineReadyok: { //------------------------------------------------------------ // 将棋エンジンからの「readyok」コマンドを待っています。 //------------------------------------------------------------ if ("readyok" == line) { //MessageBox.Show("将棋サーバー「将棋エンジンから、readyokが返ってきたぜ☆!\n" + // "AIMS GUI が先手と仮定し、\n" + // "サーバーは WaitAimsBestmove フェーズに移るぜ☆\n" + // "AIMS GUI、将棋エンジンの双方に usinewgame コマンドを送るぜ☆!」"); //------------------------------------------------------------ // 対局開始! //------------------------------------------------------------ Console.Out.WriteLine("usinewgame"); ((EngineClient)this.Owner_EngineClient).ShogiEngineProcessWrapper.Send_Usinewgame(); // FIXME:平手とは限らないが、平手という前提で、毎回一から作りなおします。 Playerside firstPside = Playerside.P1; this.Owner_AimsServer.Model_Taikyoku.SetKifu(new KifuTreeImpl( new KifuNodeImpl( Util_Sky258A.RootMove, new KyokumenWrapper(SkyConst.NewInstance( Util_SkyWriter.New_Hirate(firstPside), 0 // 初期局面は 0手目済み )) ) )); this.Owner_AimsServer.Model_Taikyoku.Kifu.SetProperty(Word_KifuTree.PropName_Startpos, "startpos"); //// //// どちらが先手かにもよるが。 //// AIMS GUI が先手と仮定します。 //// MessageBox.Show("将棋サーバー「AIMS GUI が先手と仮定し、\n" + "サーバーは WaitAimsBestmove フェーズに移るぜ☆\n" + "将棋エンジンには position コマンド、\n" + "AIMS GUI には position,go コマンドを送るぜ☆!」"); this.Owner_AimsServer.SetPhase_AimsServer(Phase_AimsServer._101_WaitAimsBestmove); // 将棋エンジンに対して // 例:「position startpos moves 7g7f」 ((EngineClient)this.Owner_EngineClient).ShogiEngineProcessWrapper.Send_Position( Util_KirokuGakari.ToSfen_PositionCommand(this.Owner_AimsServer.Model_Taikyoku.Kifu) ); // AIMS GUIに対して // 例:「position startpos moves 7g7f」 Console.Out.WriteLine(Util_KirokuGakari.ToSfen_PositionCommand(this.Owner_AimsServer.Model_Taikyoku.Kifu)); Console.Out.WriteLine("go"); } } break; default: { MessageBox.Show($"将棋サーバー「該当なしフェーズで、将棋エンジンから、[{line}]が返ってきたぜ☆!」"); } break; } /* * else if (line.StartsWith("info")) * { * } * else if (line.StartsWith("bestmove resign")) * { * // 将棋エンジンが、投了されました。 * //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> * * //------------------------------------------------------------ * // あなたの負けです☆ * //------------------------------------------------------------ * ((EngineClient)this.Owner_EngineClient).ShogiEngineProcessWrapper.Send_Gameover_lose(); * * //------------------------------------------------------------ * // 将棋エンジンを終了してください☆ * //------------------------------------------------------------ * ((EngineClient)this.Owner_EngineClient).ShogiEngineProcessWrapper.Send_Quit(); * } * else if (line.StartsWith("bestmove")) * { * // 将棋エンジンが、手を指されました。 * //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> * * ((Server)((EngineClient)this.Owner_EngineClient).Owner_Server).SetInputString99( * ((Server)((EngineClient)this.Owner_EngineClient).Owner_Server).InputString99 + line.Substring("bestmove".Length + "".Length) * ); * * OwataMinister.BY_GUI.Logger.WriteLineAddMemo($"USI受信:bestmove input99=[{((Server)((EngineClient)this.Owner_EngineClient).Owner_Server).InputString99}"); * } */ } }
public void SetGuiSky(SkyConst sky) { this.guiSkyConst = sky; }
public override void Step() { // 入っているマウス操作イベントのうち、マウスムーブは 1つに 集約 します。 bool bMouseMove_SceneB_1TumamitaiKoma = false; // 入っているマウス操作イベントは、全部捨てていきます。 MouseEventState[] queue = this.MouseEventQueue.ToArray(); this.MouseEventQueue.Clear(); foreach (MouseEventState eventState in queue) { switch (this.shogiGui.Scene) { case SceneName.SceneB_1TumamitaiKoma: { #region つまみたい駒 switch (eventState.Name2) { case MouseEventStateName.Arive: { #region アライブ //------------------------------ // メナス //------------------------------ Util_Menace.Menace(this.shogiGui); #endregion } break; case MouseEventStateName.MouseMove: { #region マウスムーブ if (bMouseMove_SceneB_1TumamitaiKoma) { continue; } bMouseMove_SceneB_1TumamitaiKoma = true; SkyConst src_Sky = shogiGui.GameViewModel.GuiSkyConst; Point mouse = eventState.MouseLocation; //---------- // 将棋盤:升目 //---------- foreach (UserWidget widget in shogiGui.Shape_PnlTaikyoku.Widgets.Values) { if ("Masu" == widget.Type && Okiba.ShogiBan == widget.Okiba) { Shape_BtnMasuImpl cell = (Shape_BtnMasuImpl)widget.Object; cell.LightByMouse(mouse.X, mouse.Y); if (cell.Light) { shogiGui.ResponseData.ToRedraw(); } break; } } //---------- // 駒置き、駒袋:升目 //---------- foreach (UserWidget widget in shogiGui.Shape_PnlTaikyoku.Widgets.Values) { if ("Masu" == widget.Type && widget.Okiba.HasFlag(Okiba.Sente_Komadai | Okiba.Gote_Komadai | Okiba.KomaBukuro)) { Shape_BtnMasuImpl cell = (Shape_BtnMasuImpl)widget.Object; cell.LightByMouse(mouse.X, mouse.Y); if (cell.Light) { shogiGui.ResponseData.ToRedraw(); } } } //---------- // 駒 //---------- foreach (Shape_BtnKomaImpl btnKoma in shogiGui.Shape_PnlTaikyoku.BtnKomaDoors) { btnKoma.LightByMouse(mouse.X, mouse.Y); if (btnKoma.Light) { shogiGui.ResponseData.ToRedraw(); RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(btnKoma.Koma).Now); if (Okiba.ShogiBan == Util_Masu.Masu_ToOkiba(koma.Masu)) { // マウスオーバーした駒の利き TimedB.Check_MouseoverKomaKiki(shogiGui, btnKoma.Koma); break; } } } foreach (UserWidget widget in shogiGui.Shape_PnlTaikyoku.Widgets.Values) { if (widget.IsLight_OnFlowB_1TumamitaiKoma) { widget.LightByMouse(mouse.X, mouse.Y); if (widget.Light) { shogiGui.ResponseData.ToRedraw(); } } } #endregion } break; case MouseEventStateName.MouseLeftButtonDown: { #region マウス左ボタンダウン SceneName nextPhaseB = SceneName.Ignore; SkyConst src_Sky = shogiGui.GameViewModel.GuiSkyConst; //---------- // 駒 //---------- foreach (Shape_BtnKomaImpl btnKoma in shogiGui.Shape_PnlTaikyoku.BtnKomaDoors) { if (btnKoma.HitByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y)) { //>>>>>>>>>> 駒にヒットしました。 if (null != shogiGui.Shape_PnlTaikyoku.Btn_TumandeiruKoma(shogiGui)) { //>>>>>>>>>> 既に選択されている駒があります。→★成ろうとしたときの、取られる相手の駒かも。 goto gt_Next1; } // 既に選択されている駒には無効 if (shogiGui.Shape_PnlTaikyoku.FigTumandeiruKoma == (int)btnKoma.Koma) { goto gt_Next1; } if (btnKoma.HitByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y)) //>>>>> 駒をつまみました。 { // 駒をつまみます。 shogiGui.Shape_PnlTaikyoku.SetFigTumandeiruKoma((int)btnKoma.Koma); shogiGui.Shape_PnlTaikyoku.SelectFirstTouch = true; nextPhaseB = SceneName.SceneB_2OkuKoma; shogiGui.Shape_PnlTaikyoku.SetMouseStarlightOrNull2( src_Sky.StarlightIndexOf(btnKoma.Koma) //TODO:改造 ); shogiGui.Shape_PnlTaikyoku.SetHMovedKoma(Fingers.Error_1); shogiGui.ResponseData.ToRedraw(); } } gt_Next1: ; } //---------- // 既に選択されている駒 //---------- Shape_BtnKoma btnKoma_Selected = shogiGui.Shape_PnlTaikyoku.Btn_TumandeiruKoma(shogiGui); //---------- // 各種ボタン //---------- { foreach (UserWidget widget in shogiGui.Shape_PnlTaikyoku.Widgets.Values) { if (widget.HitByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y)) { if (null != widget.Delegate_MouseHitEvent) { widget.Delegate_MouseHitEvent( shogiGui , btnKoma_Selected ); } } } } shogiGui.SetScene(nextPhaseB); //------------------------------ // このメインパネルの反応 //------------------------------ shogiGui.Response("MouseOperation"); #endregion } break; case MouseEventStateName.MouseLeftButtonUp: { #region マウス左ボタンアップ SkyConst src_Sky = shogiGui.GameViewModel.GuiSkyConst; //---------- // 将棋盤:升目 //---------- foreach (UserWidget widget in shogiGui.Shape_PnlTaikyoku.Widgets.Values) { if ("Masu" == widget.Type && Okiba.ShogiBan == widget.Okiba) { Shape_BtnMasuImpl cell = (Shape_BtnMasuImpl)widget.Object; if (cell.DeselectByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y)) { shogiGui.ResponseData.ToRedraw(); } } } //---------- // 駒置き、駒袋:升目 //---------- foreach (UserWidget widget in shogiGui.Shape_PnlTaikyoku.Widgets.Values) { if ("Masu" == widget.Type && widget.Okiba.HasFlag(Okiba.Sente_Komadai | Okiba.Gote_Komadai | Okiba.KomaBukuro)) { Shape_BtnMasuImpl cell = (Shape_BtnMasuImpl)widget.Object; if (cell.DeselectByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y)) { shogiGui.ResponseData.ToRedraw(); } } } //---------- // 駒 //---------- foreach (Shape_BtnKomaImpl btnKoma in shogiGui.Shape_PnlTaikyoku.BtnKomaDoors) { if (btnKoma.HitByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y)) { //>>>>> つまんでいる駒から、指を放しました shogiGui.Shape_PnlTaikyoku.SetFigTumandeiruKoma(-1); RO_Star_Koma koma1 = Util_Koma.AsKoma(src_Sky.StarlightIndexOf((int)btnKoma.Koma).Now); if (Okiba.ShogiBan == Util_Masu.GetOkiba(koma1.Masu)) { //---------- // 移動済表示 //---------- shogiGui.Shape_PnlTaikyoku.SetHMovedKoma(btnKoma.Koma); //------------------------------ // 棋譜に符号を追加(マウスボタンが放されたとき)TODO:まだ早い。駒が成るかもしれない。 //------------------------------ // 棋譜 Starlight dstStarlight = shogiGui.Shape_PnlTaikyoku.MouseStarlightOrNull2; System.Diagnostics.Debug.Assert(null != dstStarlight, "mouseStarlightがヌル"); Starlight srcStarlight = src_Sky.StarlightIndexOf(btnKoma.Koma); System.Diagnostics.Debug.Assert(null != srcStarlight, "komaStarlightがヌル"); ShootingStarlightable move = new RO_ShootingStarlight( //btnKoma.Koma, dstStarlight.Now, srcStarlight.Now, shogiGui.Shape_PnlTaikyoku.MousePos_FoodKoma != null ? shogiGui.Shape_PnlTaikyoku.MousePos_FoodKoma.Syurui : PieceType.None ); // 選択している駒の元の場所と、移動先 // TODO: 一手[巻戻し]のときは追加したくない Node <ShootingStarlightable, KyokumenWrapper> newNode = new KifuNodeImpl(move, new KyokumenWrapper(new SkyConst(src_Sky)), KifuNodeImpl.GetReverseTebanside(((KifuNode)shogiGui.GameViewModel.Kifu.CurNode).Tebanside) ); //マウスの左ボタンを放したときです。 ((KifuNode)KifuNarabe_KifuWrapper.CurNode(shogiGui.GameViewModel.Kifu)).AppendChildA_New(newNode); Util_InServer.SetCurNode_Srv(shogiGui, newNode); shogiGui.ResponseData.ToRedraw(); //------------------------------ // 符号表示 //------------------------------ FugoJ fugoJ; RO_Star_Koma koma2 = Util_Koma.AsKoma(move.LongTimeAgo); fugoJ = JFugoCreator15Array.ItemMethods[(int)Haiyaku184Array.Syurui(koma2.Haiyaku)](move, new KyokumenWrapper(src_Sky)); //「▲2二角成」なら、馬(dst)ではなくて角(src)。 shogiGui.Shape_PnlTaikyoku.SetFugo(fugoJ.ToText_UseDou( KifuNarabe_KifuWrapper.CurNode(shogiGui.GameViewModel.Kifu) )); //------------------------------ // チェンジターン //------------------------------ if (!shogiGui.Shape_PnlTaikyoku.Requested_NaruDialogToShow) { shogiGui.ChangeTurn(); //マウス左ボタンを放したのでチェンジターンします。 } shogiGui.ResponseData.OutputTxt = ResponseGedanTxt.Kifu; shogiGui.ResponseData.ToRedraw(); } } } //------------------------------------------------------------ // 選択解除か否か //------------------------------------------------------------ { foreach (UserWidget widget in shogiGui.Shape_PnlTaikyoku.Widgets.Values) { if (widget.DeselectByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y, shogiGui)) { shogiGui.ResponseData.ToRedraw(); } } } //------------------------------ // このメインパネルの反応 //------------------------------ shogiGui.Response("MouseOperation"); #endregion } break; } #endregion } break; case SceneName.SceneB_2OkuKoma: { #region 置く駒 switch (eventState.Name2) { case MouseEventStateName.MouseLeftButtonUp: { #region マウス左ボタンアップ Node <ShootingStarlightable, KyokumenWrapper> siteiNode = KifuNarabe_KifuWrapper.CurNode(shogiGui.GameViewModel.Kifu); SkyConst src_Sky = shogiGui.GameViewModel.GuiSkyConst; //---------- // 駒 //---------- foreach (Shape_BtnKomaImpl btnKoma in shogiGui.Shape_PnlTaikyoku.BtnKomaDoors) { if (btnKoma.HitByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y)) { //>>>>> マウスが重なっていました if (shogiGui.Shape_PnlTaikyoku.SelectFirstTouch) { // クリックのマウスアップ shogiGui.Shape_PnlTaikyoku.SelectFirstTouch = false; } else { RO_Star_Koma koma = Util_Koma.AsKoma(src_Sky.StarlightIndexOf(btnKoma.Koma).Now); if (Okiba.ShogiBan == Util_Masu.GetOkiba(koma.Masu)) { //>>>>> 将棋盤の上に置いてあった駒から、指を放しました //System.C onsole.WriteLine("つまんでいる駒を放します。(4)"); shogiGui.Shape_PnlTaikyoku.SetFigTumandeiruKoma(-1); //---------- // 移動済表示 //---------- shogiGui.Shape_PnlTaikyoku.SetHMovedKoma(btnKoma.Koma); //------------------------------ // 棋譜に符号を追加(マウスボタンが放されたとき)TODO:まだ早い。駒が成るかもしれない。 //------------------------------ ShootingStarlightable move = new RO_ShootingStarlight( //btnKoma.Koma, shogiGui.Shape_PnlTaikyoku.MouseStarlightOrNull2.Now, src_Sky.StarlightIndexOf(btnKoma.Koma).Now, shogiGui.Shape_PnlTaikyoku.MousePos_FoodKoma != null ? shogiGui.Shape_PnlTaikyoku.MousePos_FoodKoma.Syurui : PieceType.None ); // 選択している駒の元の場所と、移動先 ShootingStarlightable last; { last = siteiNode.Key; } //ShootingStarlightable previousMove = last; //符号の追加が行われる前に退避 Node <ShootingStarlightable, KyokumenWrapper> newNode = new KifuNodeImpl( move, new KyokumenWrapper(new SkyConst(src_Sky)), KifuNodeImpl.GetReverseTebanside(((KifuNode)shogiGui.GameViewModel.Kifu.CurNode).Tebanside) ); //マウスの左ボタンを放したときです。 ((KifuNode)KifuNarabe_KifuWrapper.CurNode(shogiGui.GameViewModel.Kifu)).AppendChildA_New(newNode); Util_InServer.SetCurNode_Srv(shogiGui, newNode); shogiGui.ResponseData.ToRedraw(); // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ // ここでツリーの内容は変わっている。 // ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ //------------------------------ // 符号表示 //------------------------------ RO_Star_Koma koma2 = Util_Koma.AsKoma(move.LongTimeAgo); FugoJ fugoJ; fugoJ = JFugoCreator15Array.ItemMethods[(int)Haiyaku184Array.Syurui(koma2.Haiyaku)](move, new KyokumenWrapper(src_Sky)); //「▲2二角成」なら、馬(dst)ではなくて角(src)。 shogiGui.Shape_PnlTaikyoku.SetFugo(fugoJ.ToText_UseDou( KifuNarabe_KifuWrapper.CurNode(shogiGui.GameViewModel.Kifu) )); //------------------------------ // チェンジターン //------------------------------ if (!shogiGui.Shape_PnlTaikyoku.Requested_NaruDialogToShow) { //System.C onsole.WriteLine("マウス左ボタンを放したのでチェンジターンします。"); shogiGui.ChangeTurn(); //マウス左ボタンを放したのでチェンジターンします。 } shogiGui.ResponseData.OutputTxt = ResponseGedanTxt.Kifu; shogiGui.ResponseData.ToRedraw(); } } } } //------------------------------ // このメインパネルの反応 //------------------------------ shogiGui.Response("MouseOperation"); #endregion } break; case MouseEventStateName.MouseLeftButtonDown: { #region マウス左ボタンダウン SceneName nextPhaseB = SceneName.Ignore; //System.C onsole.WriteLine("B2マウスダウン"); //---------- // つまんでいる駒 //---------- Shape_BtnKoma btnTumandeiruKoma = shogiGui.Shape_PnlTaikyoku.Btn_TumandeiruKoma(shogiGui); if (null == btnTumandeiruKoma) { //System.C onsole.WriteLine("つまんでいる駒なし"); goto gt_nextBlock; } //>>>>> 選択されている駒があるとき Starlight tumandeiruLight = shogiGui.GameViewModel.GuiSkyConst.StarlightIndexOf((int)btnTumandeiruKoma.Finger); //---------- // 指したい先 //---------- Shape_BtnMasuImpl btnSasitaiMasu = null; //---------- // 将棋盤:升目 <移動先など> //---------- foreach (UserWidget widget in shogiGui.Shape_PnlTaikyoku.Widgets.Values) { if ("Masu" == widget.Type && Okiba.ShogiBan == widget.Okiba) { if (widget.HitByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y)) //>>>>> 指したいマスはここです。 { btnSasitaiMasu = (Shape_BtnMasuImpl)widget.Object; break; } } } //---------- // 駒置き、駒袋:升目 //---------- foreach (UserWidget widget in shogiGui.Shape_PnlTaikyoku.Widgets.Values) { if ("Masu" == widget.Type && widget.Okiba.HasFlag(Okiba.Sente_Komadai | Okiba.Gote_Komadai | Okiba.KomaBukuro)) { Shape_BtnMasuImpl btnSasitaiMasu2 = (Shape_BtnMasuImpl)widget.Object; if (btnSasitaiMasu2.HitByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y)) //>>>>> 升目をクリックしたとき { bool match = false; shogiGui.GameViewModel.GuiSkyConst.Foreach_Starlights((Finger finger, Starlight ml, ref bool toBreak) => { RO_Star_Koma koma = Util_Koma.AsKoma(ml.Now); if (koma.Masu == btnSasitaiMasu2.Zahyo) { //>>>>> そこに駒が置いてあった。 #if DEBUG // MessageBox.Show("駒が置いてあった","デバッグ中"); #endif match = true; toBreak = true; } }); if (!match) { btnSasitaiMasu = btnSasitaiMasu2; goto gt_EndKomaoki; } } } } gt_EndKomaoki: ; if (null == btnSasitaiMasu) { // 指したいマスなし goto gt_nextBlock; } //指したいマスが選択されたとき // TODO:合法手かどうか判定したい。 if (Okiba.ShogiBan == Util_Masu.Masu_ToOkiba(btnSasitaiMasu.Zahyo)) //>>>>> 将棋盤:升目 <移動先など> { //------------------------------ // 成る/成らない //------------------------------ // // 盤上の、不成の駒で、 / 相手陣に入るものか、相手陣から出てくる駒 ※先手・後手区別なし // RO_Star_Koma koma = Util_Koma.AsKoma(tumandeiruLight.Now); if ( Okiba.ShogiBan == Util_Masu.Masu_ToOkiba(koma.Masu) && Util_Sky.IsNareruKoma(tumandeiruLight) && ( Util_Masu.InAitejin(btnSasitaiMasu.Zahyo, Util_InServer.CurPside(shogiGui)) || Util_Sky.InAitejin(tumandeiruLight) ) ) { // 成るか/成らないか ダイアログボックスを表示します。 shogiGui.Shape_PnlTaikyoku.Request_NaruDialogToShow(true); } if (shogiGui.Shape_PnlTaikyoku.Requested_NaruDialogToShow) { // 成る/成らないボタン表示 shogiGui.Shape_PnlTaikyoku.GetWidget("BtnNaru").Visible = true; shogiGui.Shape_PnlTaikyoku.GetWidget("BtnNaranai").Visible = true; shogiGui.Shape_PnlTaikyoku.SetNaruMasu(btnSasitaiMasu); nextPhaseB = SceneName.SceneB_3ErabuNaruNaranai; } else { shogiGui.Shape_PnlTaikyoku.GetWidget("BtnNaru").Visible = false; shogiGui.Shape_PnlTaikyoku.GetWidget("BtnNaranai").Visible = false; // 駒を動かします。 { // GuiからServerへ渡す情報 PieceType syurui; Starlight dst; Util_InGui.Komamove1a_49Gui(out syurui, out dst, btnTumandeiruKoma, btnSasitaiMasu, shogiGui); // ServerからGuiへ渡す情報 bool torareruKomaAri; RO_Star_Koma koma_Food_after; Util_InServer.Komamove1a_50Srv(out torareruKomaAri, out koma_Food_after, dst, btnTumandeiruKoma.Koma, Util_Koma.AsKoma(dst.Now), shogiGui); Util_InGui.Komamove1a_51Gui(torareruKomaAri, koma_Food_after, shogiGui); } nextPhaseB = SceneName.SceneB_1TumamitaiKoma; } shogiGui.ResponseData.ToRedraw(); } else if ((Okiba.Sente_Komadai | Okiba.Gote_Komadai).HasFlag( Util_Masu.GetOkiba(btnSasitaiMasu.Zahyo))) //>>>>> 駒置き:升目 { //System.C onsole.WriteLine("駒台上"); RO_Star_Koma koma = Util_Koma.AsKoma(shogiGui.GameViewModel.GuiSkyConst.StarlightIndexOf(btnTumandeiruKoma.Koma).Now); SkyBuffer buffer_Sky = new SkyBuffer(shogiGui.GameViewModel.GuiSkyConst); buffer_Sky.AddOverwriteStarlight(btnTumandeiruKoma.Koma, new RO_MotionlessStarlight( //btnTumandeiruKoma.Koma, new RO_Star_Koma(Converter04.Okiba_ToPside(Util_Masu.GetOkiba(btnSasitaiMasu.Zahyo)),// 先手の駒置きに駒を置けば、先手の向きに揃えます。 btnSasitaiMasu.Zahyo, KomaSyurui14Array.NarazuCaseHandle(Haiyaku184Array.Syurui(koma.Haiyaku))) )); shogiGui.GameViewModel.SetGuiSky(new SkyConst(buffer_Sky)); nextPhaseB = SceneName.SceneB_1TumamitaiKoma; shogiGui.ResponseData.RedrawStarlights(); // 駒の再描画要求 shogiGui.ResponseData.ToRedraw(); } gt_nextBlock: //---------- // 既に選択されている駒 //---------- Shape_BtnKoma btnKoma_Selected = shogiGui.Shape_PnlTaikyoku.Btn_TumandeiruKoma(shogiGui); //---------- // 初期配置ボタン //---------- { foreach (UserWidget widget in shogiGui.Shape_PnlTaikyoku.Widgets.Values) { if (widget.HitByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y)) { if (null != widget.Delegate_MouseHitEvent) { widget.Delegate_MouseHitEvent( shogiGui , btnKoma_Selected ); } } } } shogiGui.SetScene(nextPhaseB); //------------------------------ // このメインパネルの反応 //------------------------------ shogiGui.Response("MouseOperation"); #endregion } break; case MouseEventStateName.MouseRightButtonDown: { #region マウス右ボタンダウン // 各駒の、移動済フラグを解除 //System.C onsole.WriteLine("つまんでいる駒を放します。(5)"); shogiGui.Shape_PnlTaikyoku.SetFigTumandeiruKoma(-1); shogiGui.Shape_PnlTaikyoku.SelectFirstTouch = false; //------------------------------ // 状態を戻します。 //------------------------------ shogiGui.SetScene(SceneName.SceneB_1TumamitaiKoma); //------------------------------ // このメインパネルの反応 //------------------------------ shogiGui.Response("MouseOperation"); #endregion } break; } #endregion } break; case SceneName.SceneB_3ErabuNaruNaranai: { #region 成る成らない switch (eventState.Name2) { case MouseEventStateName.MouseLeftButtonDown: { #region マウス左ボタンダウン SceneName nextPhaseB = SceneName.Ignore; //GuiSky この関数の途中で変更される。ローカル変数に入れているものは古くなる。 //---------- // 既に選択されている駒 //---------- Shape_BtnKoma btnKoma_Selected = shogiGui.Shape_PnlTaikyoku.Btn_TumandeiruKoma(shogiGui); string[] buttonNames = new string[] { "BtnNaru", // [成る]ボタン "BtnNaranai" // [成らない]ボタン }; foreach (string buttonName in buttonNames) { UserWidget widget = shogiGui.Shape_PnlTaikyoku.GetWidget(buttonName); if (widget.HitByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y)) { if (null != widget.Delegate_MouseHitEvent) { widget.Delegate_MouseHitEvent( shogiGui , btnKoma_Selected ); } } } // //---------- // 既に選択されている駒 //---------- //Shape_BtnKomaImpl btnKoma_Selected = shogiGui.Shape_PnlTaikyoku.Btn_TumandeiruKoma(shogiGui); //---------- // 初期配置ボタン //---------- { foreach (UserWidget widget in shogiGui.Shape_PnlTaikyoku.Widgets.Values) { if (widget.HitByMouse(eventState.MouseLocation.X, eventState.MouseLocation.Y)) { if (null != widget.Delegate_MouseHitEvent) { widget.Delegate_MouseHitEvent( shogiGui , btnKoma_Selected ); } } } } shogiGui.SetScene(nextPhaseB); //------------------------------ // このメインパネルの反応 //------------------------------ shogiGui.Response("MouseOperation"); #endregion } break; } #endregion } break; } } //gt_EndMethod1: // ; }
/// <summary> /// 平手初期局面が -100点~+100点 に収まるように調整します。 /// /// 7回だけ調整します。 /// /// [0]回目: 順位を 64 ずらす。 /// [1]回目: 順位を 32 ずらす。 /// [2]回目: 順位を 16 ずらす。 /// [3]回目: 順位を 8 ずらす。 /// [4]回目: 順位を 4 ずらす。 /// [5]回目: 順位を 2 ずらす。 /// [6]回目: 順位を 1 ずらす。 /// /// これで、1方向に最長で(順位換算で) 130 ほどずれます。 /// /// </summary> public static void Adjust_HirateSyokiKyokumen_0ten_AndFvParamRange( ref bool ref_isRequestDoEvents, FeatureVector fv) { if (null == Util_StartZero.src_Sky_hirateSyokikyokumen) { // 平手初期局面 Util_StartZero.src_Sky_hirateSyokikyokumen = SkyConst.NewInstance( Util_SkyWriter.New_Hirate(Playerside.P1), 0 // 初期局面は 0手目済み ); } if (null == Util_StartZero.n54List_hirateSyokikyokumen) { //---------------------------------------- // 40枚の駒、または14種類の持駒。多くても54要素。 //---------------------------------------- Util_StartZero.n54List_hirateSyokikyokumen = Util_54List.Calc_54List(Util_StartZero.src_Sky_hirateSyokikyokumen); } Hyokakansu_NikomaKankeiPp kansu = new Hyokakansu_NikomaKankeiPp(); //-------------------------------------------------------------------------------- // Check //-------------------------------------------------------------------------------- // // 平手初期局面の点数を調べます。 // float score; #if DEBUG || LEARN KyHyokaMeisai_Koumoku meisaiKoumoku_orNull; #endif kansu.Evaluate( out score, #if DEBUG || LEARN out meisaiKoumoku_orNull, #endif Util_StartZero.src_Sky_hirateSyokikyokumen, fv ); if (-100 <= score && score <= 100) { // 目標達成。 goto gt_Goal; } for (int iCount = 0; iCount < 7; iCount++)//最大で7回調整します。 { // 初期局面の評価値が、-100~100 よりも振れていれば、0 になるように調整します。 //-------------------------------------------------------------------------------- // 点数を、順位に変換します。 //-------------------------------------------------------------------------------- Util_Ranking.Perform_Ranking(fv); // // 調整量 // int chosei_offset = Util_StartZero.tyoseiryo[iCount];// 調整量を、調整します。どんどん幅が広くなっていきます。 if (-100 <= score && score <= 100) { // 目標達成。 goto gt_Goal; } else if (100 < score)// ±0か、マイナスに転じさせたい。 { chosei_offset *= -1; } int changedCells; Util_FvScoreing.Fill54x54_Add(out changedCells, chosei_offset, src_Sky_hirateSyokikyokumen, fv, Util_StartZero.n54List_hirateSyokikyokumen); // 順位を、点数に変換します。 Util_Zooming.ZoomTo_FvParamRange(fv); // フォームの更新を要求します。 ref_isRequestDoEvents = true; //-------------------------------------------------------------------------------- // Check //-------------------------------------------------------------------------------- // // 平手初期局面の点数を調べます。 // kansu.Evaluate( out score, #if DEBUG || LEARN out meisaiKoumoku_orNull, #endif Util_StartZero.src_Sky_hirateSyokikyokumen, fv ); if (-100 <= score && score <= 100) { // 目標達成。 goto gt_Goal; } // 目標を達成していないなら、ループを繰り返します。 } gt_Goal: ; }
/// <summary> /// ************************************************************************************************************************ /// HTML出力。(これは作者のホームページ用に書かれています) /// ************************************************************************************************************************ /// </summary> public static string CreateHtml(MainGui_Csharp mainGui) { StringBuilder sb = new StringBuilder(); sb.AppendLine("<div style=\"position:relative; left:0px; top:0px; border:solid 1px black; width:250px; height:180px;\">"); // 後手の持ち駒 sb.AppendLine(" <div style=\"position:absolute; left:0px; top:2px; width:30px;\">"); sb.AppendLine(" △後手"); sb.AppendLine(" <div style=\"margin-top:10px; width:30px;\">"); sb.Append(" "); SkyConst siteiSky = mainGui.Model_Manual.GuiSkyConst; siteiSky.Foreach_Starlights((Finger finger, IMoveHalf ml, ref bool toBreak) => { RO_Star koma = Util_Starlightable.AsKoma(ml.Now); if (Conv_SyElement.ToOkiba(koma.Masu) == Okiba.Gote_Komadai) { sb.Append(Util_Komasyurui14.Fugo[(int)Util_Komahaiyaku184.Syurui(koma.Haiyaku)]); } }); sb.AppendLine(" </div>"); sb.AppendLine(" </div>"); // 将棋盤 sb.AppendLine(" <div style=\"position:absolute; left:30px; top:2px; width:182px;\">"); sb.AppendLine(" <table>"); for (int dan = 1; dan <= 9; dan++) { sb.Append(" <tr>"); for (int suji = 9; 1 <= suji; suji--) { bool isSpace = true; siteiSky.Foreach_Starlights((Finger finger, IMoveHalf ml, ref bool toBreak) => { RO_Star koma2 = Util_Starlightable.AsKoma(ml.Now); int suji2; Util_MasuNum.TryMasuToSuji(koma2.Masu, out suji2); int dan2; Util_MasuNum.TryMasuToDan(koma2.Masu, out dan2); if ( Conv_SyElement.ToOkiba(koma2.Masu) == Okiba.ShogiBan && //盤上 suji2 == suji && dan2 == dan ) { if (Playerside.P2 == koma2.Pside) { sb.Append("<td><span class=\"koma2x\">"); sb.Append(Util_Komasyurui14.Fugo[(int)Util_Komahaiyaku184.Syurui(koma2.Haiyaku)]); sb.Append("</span></td>"); isSpace = false; } else { sb.Append("<td><span class=\"koma1x\">"); sb.Append(Util_Komasyurui14.Fugo[(int)Util_Komahaiyaku184.Syurui(koma2.Haiyaku)]); sb.Append("</span></td>"); isSpace = false; } } }); if (isSpace) { sb.Append("<td> </td>"); } } sb.AppendLine("</tr>"); } sb.AppendLine(" </table>"); sb.AppendLine(" </div>"); // 先手の持ち駒 sb.AppendLine(" <div style=\"position:absolute; left:215px; top:2px; width:30px;\">"); sb.AppendLine(" ▲先手"); sb.AppendLine(" <div style=\"margin-top:10px; width:30px;\">"); sb.Append(" "); siteiSky.Foreach_Starlights((Finger finger, IMoveHalf ml, ref bool toBreak) => { RO_Star koma = Util_Starlightable.AsKoma(ml.Now); if (Conv_SyElement.ToOkiba(koma.Masu) == Okiba.Sente_Komadai) { sb.Append(Util_Komasyurui14.Fugo[(int)Util_Komahaiyaku184.Syurui(koma.Haiyaku)]); } }); sb.AppendLine(" </div>"); sb.AppendLine(" </div>"); // sb.AppendLine("</div>"); return(sb.ToString()); }
/// <summary> /// 評価値を返します。先手が有利ならプラス、後手が有利ならマイナス、互角は 0.0 です。 /// </summary> /// <param name="input_node"></param> /// <returns></returns> public override void Evaluate( out float out_score, #if DEBUG || LEARN out KyHyokaMeisai_Koumoku out_meisaiKoumoku_orNull, #endif SkyConst src_Sky, FeatureVector fv ) { out_score = 0.0f; // -999~999(*bairitu) が 40×40個ほど足し合わせた数になるはず。 #if DEBUG float[] komabetuMeisai = new float[Finger_Honshogi.Items_KomaOnly.Length]; #endif // // 盤上にある駒だけ、項目番号を調べます。 // //---------------------------------------- // 項目番号リスト //---------------------------------------- // // 40個の駒と、14種類の持ち駒があるだけなので、 // 54個サイズの長さがあれば足りるんだぜ☆ 固定長にしておこう☆ // int nextIndex = 0; int[] komokuArray_unsorted = new int[54]; //昇順でなくても構わないアルゴリズムにすること。 for (int i = 0; i < Finger_Honshogi.Items_KomaOnly.Length; i++) // 全駒 { RO_Star koma = Util_Starlightable.AsKoma(src_Sky.StarlightIndexOf(Finger_Honshogi.Items_KomaOnly[i]).Now); if (Okiba.ShogiBan == Conv_SyElement.ToOkiba(koma.Masu)) { // 盤上 komokuArray_unsorted[nextIndex] = Util_FvParamIndex.ParamIndex_Banjo(koma); nextIndex++; } else { // 持ち駒は、ここでは無視します。 } } // 持ち駒:先後×7種類 for (int iPside = 0; iPside < Array_Playerside.Items_PlayerOnly.Length; iPside++) { for (int iKomasyurui = 0; iKomasyurui < Array_Komasyurui.MotiKoma7Syurui.Length; iKomasyurui++) { komokuArray_unsorted[nextIndex] = Util_FvParamIndex.ParamIndex_Moti(src_Sky, Array_Playerside.Items_PlayerOnly[iPside], Array_Komasyurui.MotiKoma7Syurui[iKomasyurui]); nextIndex++; } } //Array.Sort(komokuArray_unsorted); // // // 例えば、[1P1三歩、2P2一桂]という組み合わせと、[2P2一桂、1P1三歩]という組み合わせは、同じだが欄が2つある。 // そこで、表の半分を省きたい。 // しかし、表を三角形にするためには、要素は昇順にソートされている必要がある。 // 合法手1つごとにソートしていては、本末転倒。 // そこで、表は正方形に読み、内容は三角形の部分にだけ入っているということにする。 // // // 例えば、[1P1三歩、1P1三歩]という組み合わせもある。これは、自分自身の絶対位置の評価として試しに、残しておいてみる☆ // // for (int iA = 0; iA < nextIndex; iA++) { int p1 = komokuArray_unsorted[iA]; for (int iB = 0; iB < nextIndex; iB++) { int p2 = komokuArray_unsorted[iB]; if (p1 <= p2) // 「p2 < p1」という組み合わせは同じ意味なので省く。「p1==p2」は省かない。 { //---------------------------------------- // よし、組み合わせだぜ☆! //---------------------------------------- out_score += fv.NikomaKankeiPp_ForMemory[p1, p2]; } else { //---------------------------------------- // 使っていない方の三角形だぜ☆! //---------------------------------------- // スルー。 } } } //---------------------------------------- // 明細項目 //---------------------------------------- #if DEBUG || LEARN string utiwake = ""; // 内訳 { StringBuilder sb = new StringBuilder(); sb.Append(" PP "); sb.Append(out_score); sb.Append("点"); utiwake = sb.ToString(); } out_meisaiKoumoku_orNull = new KyHyokaMeisai_KoumokuImpl(utiwake, out_score); #endif }
/// <summary> /// 54駒のリスト。 /// /// 盤上の40駒リスト。 /// 駒台の14駒リスト。 /// </summary> public static N54List Calc_54List(SkyConst src_Sky) { N54List result_n54List = new N54ListImpl(); //---------------------------------------- // インナー・メソッド用 集計変数 //---------------------------------------- int p54Next = 0; int[] p54List = new int[54]; src_Sky.Foreach_Starlights((Finger finger, IMoveHalf light, ref bool toBreak) => { RO_Star koma = Util_Starlightable.AsKoma(light.Now); //---------------------------------------- // まず、p を調べます。 //---------------------------------------- if (Conv_SyElement.ToOkiba(koma.Masu) == Okiba.ShogiBan) { int pIndex = FeatureVectorImpl.CHOSA_KOMOKU_ERROR;// 調査項目P1 //---------------------------------------- // 盤上の駒 //---------------------------------------- Conv_FvKoumoku525.ToPIndex_FromBanjo_PsideKomasyuruiMasu(koma.Pside, koma.Komasyurui, koma.Masu, out pIndex); if (FeatureVectorImpl.CHOSA_KOMOKU_ERROR == pIndex) { // p1 がエラーでは、処理は続けられない。 Util_54List.Panic1(koma); goto gt_NextLoop_player1; } //---------------------------------------- // 盤上の駒だぜ☆! //---------------------------------------- p54List[p54Next] = pIndex; p54Next++; } else if ( Conv_SyElement.ToOkiba(koma.Masu) == Okiba.Sente_Komadai || Conv_SyElement.ToOkiba(koma.Masu) == Okiba.Gote_Komadai) { int pIndex = FeatureVectorImpl.CHOSA_KOMOKU_ERROR;// 調査項目P1 //---------------------------------------- // 持ち駒 //---------------------------------------- PieceType motiKomasyurui = koma.ToNarazuCase();//例:駒台に馬はない。角の数を数える。 // 駒の枚数 int maisu = Util_Sky_FingersQuery.InOkibaKomasyuruiNow(src_Sky, Conv_Playerside.ToKomadai(koma.Pside), motiKomasyurui).Items.Count; Conv_FvKoumoku525.ToPIndex_FromMoti_PsideKomasyuruiMaisu(koma.Pside, motiKomasyurui, maisu, out pIndex); if (FeatureVectorImpl.CHOSA_KOMOKU_ERROR == pIndex) { // p1 がエラーでは、処理は続けられない。 Util_54List.Panic1(koma); goto gt_NextLoop_player1; } //---------------------------------------- // 駒台の駒だぜ☆! //---------------------------------------- p54List[p54Next] = pIndex; p54Next++; } gt_NextLoop_player1: ; }); result_n54List.SetP54List_Unsorted(p54List); result_n54List.SetP54Next(p54Next); return(result_n54List); }