Example #1
0
        /// <summary>
        /// 棋譜の選択行が変更になった。
        /// 対局中でなければ、現在局面をその棋譜の局面に変更する。
        ///
        /// このメソッドを直接呼び出さずに、this.KifuListSelectedIndexのsetterか、UpdateKifuSelectedIndex()を用いること。
        /// </summary>
        private void KifuListSelectedIndexChangedCommand(PropertyChangedEventArgs args)
        {
            AddCommand(
                () =>
            {
                if (GameMode.IsConsideration())
                {
                    // 現在の局面と違う行であるかを判定して、同じ行である場合は、
                    // このイベントを処理してはならない。

                    // 無理やりではあるが棋譜のN行目に移動出来るのであった…。
                    int selectedIndex = (int)args.value;
                    kifuManager.Tree.GotoSelectedIndex(selectedIndex);
                    PlayTimers.SetKifuMoveTimes(kifuManager.Tree.GetKifuMoveTimes());

                    // 検討モードのとき)
                    //   思考エンジンでの検討中       → 局面が変わったので思考しなおすためにNotifyTurnChanged()が必要。
                    //   思考エンジンで検討していない → 掴んでいる駒を離す必要があるためにNotifyTurnChanged()が必要。
                    if (GameMode.IsConsideration())
                    {
                        NotifyTurnChanged();
                    }
                }
            });
        }
Example #2
0
        /// <summary>
        /// ユーザーによる対局中の2手戻し
        /// 受理できるかどうかは別
        /// </summary>
        public void UndoCommand()
        {
            AddCommand(
                () =>
            {
                if (InTheGame)
                {
                    var stm       = kifuManager.Position.sideToMove;
                    var stmPlayer = Player(stm);

                    // 人間の手番でなければ受理しない
                    if (stmPlayer.PlayerType == PlayerTypeEnum.Human)
                    {
                        // 棋譜を消すUndo()
                        kifuManager.UndoMoveInTheGame();
                        kifuManager.UndoMoveInTheGame();

                        // 時刻を巻き戻さないといけない
                        PlayTimers.SetKifuMoveTimes(kifuManager.Tree.GetKifuMoveTimes());

                        // これにより、2手目の局面などであれば1手しかundoできずに手番が変わりうるので手番の更新を通知。
                        NotifyTurnChanged();
                    }
                }
            });
        }
        /// <summary>
        /// ユーザーによる対局中の2手戻し
        /// 受理できるかどうかは別
        /// </summary>
        public void UndoCommand()
        {
            AddCommand(
                () =>
            {
                if (InTheGame)
                {
                    var stm       = kifuManager.Position.sideToMove;
                    var stmPlayer = Player(stm);

                    // 人間の手番でなければ受理しない
                    if (stmPlayer.PlayerType == PlayerTypeEnum.Human)
                    {
                        // 棋譜を消すUndo()
                        kifuManager.UndoMoveInTheGame();
                        kifuManager.UndoMoveInTheGame();

                        // 残り持ち時間などを巻き戻さないといけない。
                        // ただし、再開局で開始局面以上に巻き戻すと、いまより持ち時間が減ってしまう可能性がある。
                        // 開始局面以上に巻き戻す場合は、再開時の時間にしてやる必要がある。
                        // しかし、中断局であるなら、遡れなければならない。難しい。

                        var nextTime = kifuManager.Tree.GetKifuMoveTimes();
                        PlayTimers.SetKifuMoveTimes(nextTime);

                        // これにより、2手目の局面などであれば1手しかundoできずに手番が変わりうるので手番の更新を通知。
                        NotifyTurnChanged();
                    }
                }
            });
        }
Example #4
0
        /// <summary>
        /// 棋譜(string型)の読み込みコマンド
        /// ファイルから読み込むには、MainMenu.ReadKifuFile()のようなメソッドを用いること。
        /// </summary>
        /// <param name="kifuText"></param>
        public void KifuReadCommand(string kifuText)
        {
            AddCommand(
                () =>
            {
                if (GameMode.CanUserMove())
                {
                    // 対局中ではないので、EnableKifuList == falseになっているが、
                    // 一時的にこれをtrueにしないと、読み込んだ棋譜に対して、Tree.KifuListが同期しない。
                    // ゆえに、読み込みの瞬間だけtrueにして、そのあとfalseに戻す。
                    kifuManager.EnableKifuList = true;
                    var error = kifuManager.FromString(kifuText);
                    kifuManager.EnableKifuList = false;

                    if (error != null)
                    {
                        TheApp.app.MessageShow("棋譜の読み込みに失敗しました。\n" + error, MessageShowType.Error);

                        kifuManager.Init(); // 不正な局面のままになるとまずいので初期化。
                    }
                    else
                    {
                        // 読み込みが完了すれば自動的に末尾の局面に行っているはずだが、
                        // 棋譜ウィンドウを更新した結果、分岐局面などに戻ってしまうといけない。

                        // 棋譜に書かれていた持ち時間設定・残り時間を画面に反映させる。(GameSettingには反映させない)
                        PlayTimers.SetKifuTimeSettings(kifuManager.Tree.KifuTimeSettings);
                        PlayTimers.SetKifuMoveTimes(kifuManager.Tree.GetKifuMoveTimes());
                        UpdateTimeString();

                        // 末尾の局面に移動するコマンドを叩いておく。
                        UpdateKifuSelectedIndex(int.MaxValue);

                        // -- 棋譜上の名前を表示名に反映させる。

                        foreach (var c in All.Colors())
                        {
                            var name = kifuManager.KifuHeader.GetPlayerName(c);
                            SetPlayerName(c, name);
                        }
                    }

                    // 棋譜が綺麗になった扱いにする。(この棋譜はファイルなどに丸ごと保存されているはずであるから)
                    KifuDirty = false;

                    // 駒を持ち上げていたりしたらそれをリセットする必要があるので。
                    RaisePropertyChanged("TurnChanged");
                }
            });
        }
Example #5
0
        /// <summary>
        /// 棋譜の選択行が変更になった。
        /// 対局中でなければ、現在局面をその棋譜の局面に変更する。
        /// </summary>
        public void KifuSelectedIndexChangedCommand(int selectedIndex)
        {
            AddCommand(
                () =>
            {
                if (GameMode.IsConsideration())
                {
                    // 現在の局面と違う行であるかを判定して、同じ行である場合は、
                    // このイベントを処理してはならない。

                    // 無理やりではあるが棋譜のN行目に移動出来るのであった…。
                    kifuManager.Tree.GotoSelectedIndex(selectedIndex);
                    PlayTimers.SetKifuMoveTimes(kifuManager.Tree.GetKifuMoveTimes());
                }
            });
        }
        /// <summary>
        /// 棋譜の選択行が変更になった。
        /// 対局中でなければ、現在局面をその棋譜の局面に変更する。
        ///
        /// このメソッドを直接呼び出さずに、this.KifuListSelectedIndexのsetterを使うこと。
        /// </summary>
        private void KifuListSelectedIndexChangedCommand(PropertyChangedEventArgs args)
        {
            AddCommand(
                () =>
            {
                if (GameMode.IsConsideration())
                {
                    // 現在の局面と違う行であるかを判定して、同じ行である場合は、
                    // このイベントを処理してはならない。

                    // 無理やりではあるが棋譜のN行目に移動出来るのであった…。
                    int selectedIndex = (int)args.value;
                    kifuManager.Tree.GotoSelectedIndex(selectedIndex);
                    PlayTimers.SetKifuMoveTimes(kifuManager.Tree.GetKifuMoveTimes());

                    // 局面が変わったので思考しなおす。
                    if (GameMode.IsConsiderationWithEngine())
                    {
                        NotifyTurnChanged();
                    }
                }
            });
        }
Example #7
0
        /// <summary>
        /// 棋譜の読み込みコマンド
        /// </summary>
        /// <param name="kifuText"></param>
        public void KifuReadCommand(string kifuText)
        {
            AddCommand(
                () =>
            {
                if (GameMode.CanUserMove())
                {
                    // 対局中ではないので、EnableKifuList == falseになっているが、
                    // 一時的にこれをtrueにしないと、読み込んだ棋譜に対して、Tree.KifuListが同期しない。
                    // ゆえに、読み込みの瞬間だけtrueにして、そのあとfalseに戻す。
                    kifuManager.EnableKifuList = true;
                    var error = kifuManager.FromString(kifuText);
                    kifuManager.EnableKifuList = false;

                    if (error != null)
                    {
                        TheApp.app.MessageShow("棋譜の読み込みに失敗しました。\n" + error, "読み込みエラー");

                        kifuManager.Init(); // 不正な局面のままになるとまずいので初期化。
                    }
                    else
                    {
                        // 読み込みが完了すれば自動的に末尾の局面に行っているはずだが、
                        // 棋譜ウィンドウを更新した結果、分岐局面などに戻ってしまうといけない。

                        // 棋譜に書かれていた持ち時間設定・残り時間を画面に反映させる。(GameSettingには反映させない)
                        PlayTimers.SetKifuTimeSettings(kifuManager.Tree.KifuTimeSettings);
                        PlayTimers.SetKifuMoveTimes(kifuManager.Tree.GetKifuMoveTimes());
                        UpdateTimeString();

                        // 末尾の局面に移動するコマンドを叩いておく。
                        RaisePropertyChanged("SetKifuListIndex", kifuManager.KifuList.Count - 1);
                    }
                }
            });
        }
Example #8
0
        /// <summary>
        /// ユーザーによる対局中の2手戻し
        /// 受理できるかどうかは別
        /// </summary>
        public void UndoCommand()
        {
            AddCommand(
                () =>
            {
                if (InTheGame)
                {
                    var stm       = kifuManager.Position.sideToMove;
                    var stmPlayer = Player(stm);

                    // 人間の手番でなければ受理しない
                    if (stmPlayer.PlayerType == PlayerTypeEnum.Human)
                    {
                        // 棋譜を消すUndo()
                        kifuManager.UndoMoveAndRemoveKifu();
                        kifuManager.UndoMoveAndRemoveKifu();

                        // 残り持ち時間などを巻き戻さないといけない。
                        // ただし、再開局で開始局面以上に巻き戻すと、いまより持ち時間が減ってしまう可能性がある。
                        // 開始局面以上に巻き戻す場合は、再開時の時間にしてやる必要がある。
                        // しかし、中断局であるなら、遡れなければならない。難しい。

                        var nextTime = kifuManager.Tree.GetKifuMoveTimes();
                        PlayTimers.SetKifuMoveTimes(nextTime);

                        // これにより、2手目の局面などであれば1手しかundoできずに手番が変わりうるので手番の更新を通知。
                        NotifyTurnChanged();

                        // TreeのUndoにより、KifuListの更新がかかり、選択行が変化して、
                        // 更新通知が来て、そのハンドラのなかでSetKifuMoveTimes()とNotifyTurnChanged()を
                        // 行っているので、本来、上の文は不要なのだが、そのハンドラでは、Consideration中しか
                        // その処理を行わない(ユーザーの棋譜選択でそこが変更されると困る)ので上記処理は必要。
                    }
                }
            });
        }
Example #9
0
        /// <summary>
        /// 棋譜(string型)の読み込みコマンド
        /// ファイルから読み込むには、MainMenu.ReadKifuFile()のようなメソッドを用いること。
        ///
        /// merge == trueなら、棋譜を分岐棋譜としてマージする。
        /// dirtyは、このあと、KifuDirty(棋譜が汚れているかのフラグ)に設定される値。
        /// </summary>
        /// <param name="kifuText"></param>
        public void KifuReadCommand(string kifuText, bool merge = false, bool dirty = false)
        {
            AddCommand(
                () =>
            {
                if (GameMode.CanUserMove())
                {
                    // 対局中ではないので、EnableKifuList == falseになっているが、
                    // 一時的にこれをtrueにしないと、読み込んだ棋譜に対して、Tree.KifuListが同期しない。
                    // ゆえに、読み込みの瞬間だけtrueにして、そのあとfalseに戻す。
                    kifuManager.EnableKifuList = true;

                    var oldSelectedIndex = kifuManager.Tree.pliesFromRoot;

                    var error = merge ? kifuManager.MergeFromString(kifuText) : kifuManager.FromString(kifuText);
                    // マージした場合、その棋譜の末尾に行って欲しい気もするが…。

                    kifuManager.EnableKifuList = false;

                    if (error != null)
                    {
                        TheApp.app.MessageShow((merge ? "棋譜のマージに失敗しました。\n" : "棋譜の読み込みに失敗しました。\n") + error, MessageShowType.Error);

                        kifuManager.Init(); // 不正な局面のままになるとまずいので初期化。
                    }
                    else
                    {
                        // 読み込みが完了すれば自動的に末尾の局面に行っているはずだが、
                        // 棋譜ウィンドウを更新した結果、分岐局面などに戻ってしまうといけない。

                        // 棋譜に書かれていた持ち時間設定・残り時間を画面に反映させる。(GameSettingには反映させない)
                        PlayTimers.SetKifuTimeSettings(kifuManager.Tree.KifuTimeSettings);
                        PlayTimers.SetKifuMoveTimes(kifuManager.Tree.GetKifuMoveTimes());
                        UpdateTimeString();

                        // 末尾の局面に移動するコマンドを叩いておく。
                        // マージ時は、マージ起点に移動してやる。たぶん現在の選択していた行がそれ。
                        if (!merge)
                        {
                            UpdateKifuSelectedIndex(int.MaxValue);
                        }
                        else
                        {
                            UpdateKifuSelectedIndex(oldSelectedIndex + 1);
                        }

                        // -- 棋譜上の名前を表示名に反映させる。

                        foreach (var c in All.Colors())
                        {
                            var name = kifuManager.KifuHeader.GetPlayerName(c);
                            SetPlayerName(c, name);
                        }
                    }

                    // 棋譜が綺麗になった扱いにする。(この棋譜はファイルなどに丸ごと保存されているはずであるから)
                    // ただし、mergeのときは汚れたという扱いにする。(ファイルに残っていないので)
                    KifuDirty = dirty;

                    // 駒を持ち上げていたりしたらそれをリセットする必要があるので。
                    RaisePropertyChanged("TurnChanged");
                }
            });
        }