Exemple #1
0
        /// <summary>
        /// 駒の移動 盤面編集
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        public void move_piece_for_edit(SquareHand from, SquareHand to)
        {
            var pos = gameServer.Position;

            // 何にせよ、移動、もしくは交換をする。
            // → 交換をする実装、不評なので、将棋所・ShogiGUIに倣い、手駒に移動させる。

            var from_pc = pos.PieceOn(from);
            var from_pt = from_pc.PieceType();
            var from_pr = from_pc.RawPieceType();
            var to_pc   = pos.PieceOn(to);
            var to_pr   = to_pc.RawPieceType();

            // 移動元と移動先が同じなら何もする必要はない。
            if (from == to)
            {
                // このケースを除外しておかないと、toの駒を手駒に移動させる処理などで
                // from == toだと手駒が増えることになる。

                // しかし、駒を掴んでいる状態が変化するのでこのときだけ再描画は必要。
                Dirty = true;
            }
            else if (to.IsBoardPiece())
            {
                if (from.IsBoardPiece())
                {
                    // -- 盤上と盤上の駒

#if false // 2駒交換する実装 → 不評なので手駒に移動させることに変更。
                    // fromとtoの升の駒を交換する。
                    // fromに駒があることは確定している。toに駒があろうがなかろうが良い。
                    BoardEditCommand(raw =>
                    {
                        raw.board[(int)from] = to_pc;
                        raw.board[(int)to]   = from_pc;
                    });
#endif

#if true // toのほうが手駒に移動する実装
                    BoardEditCommand(raw =>
                    {
                        raw.board[(int)from] = Piece.NO_PIECE;
                        raw.board[(int)to]   = from_pc;
                        if (to_pr != Piece.NO_PIECE && to_pr != Piece.KING)
                        {
                            // 移動元の駒のcolorの手駒に移動させる。玉は、(欠落するので)勝手に駒箱に移動する。
                            raw.hands[(int)from_pc.PieceColor()].Add(to_pr);
                        }
                    });
#endif
                }
                else if (from.IsHandPiece())
                {
                    // -- 手駒を盤面に

                    BoardEditCommand(raw =>
                    {
#if false // 駒箱に移動する実装 → 不評なので手駒になるように変更
                        raw.hands[(int)from.PieceColor()].Sub(from_pt);
                        raw.board[(int)to] = from_pc;
                        // このtoの位置にもし駒があったとしたら、それは駒箱に移動する。
                        // (その駒が欠落するので..)
#endif

#if true // toのほうが手駒に移動する実装
                        raw.hands[(int)from.PieceColor()].Sub(from_pt);
                        raw.board[(int)to] = from_pc;

                        if (to_pr != Piece.NO_PIECE && to_pr != Piece.KING)
                        {
                            // 移動元の駒のcolorの手駒に移動させる。玉は、(欠落するので)勝手に駒箱に移動する。
                            raw.hands[(int)from.PieceColor()].Add(to_pr);
                        }
#endif
                    });
                }
                else if (from.IsPieceBoxPiece())
                {
                    // -- 駒箱の駒を盤面に
                    // toにあった駒は駒箱に戻ってくるが、これは仕方がない。

                    BoardEditCommand(raw => raw.board[(int)to] = from_pc);
                }
            }
            else if (to.IsHandPiece())
            {
                if (from.IsBoardPiece())
                {
                    // -- 盤上の駒を手駒に移動させる。

                    // 手駒に出来る駒種でなければキャンセル
                    if (from_pt == Piece.KING)
                    {
                        return;
                    }

                    BoardEditCommand(raw =>
                    {
                        raw.board[(int)from] = Piece.NO_PIECE;
                        raw.hands[(int)to.PieceColor()].Add(from_pr);
                    });
                }
                else if (from.IsHandPiece())
                {
                    // -- 手駒を手駒に。手番が違うならこれは合法。

                    if (from.PieceColor() != to.PieceColor())
                    {
                        BoardEditCommand(raw =>
                        {
                            // 同種の駒が駒台から駒台に移動するので、to_prは関係ない。
                            raw.hands[(int)from.PieceColor()].Sub(from_pr);
                            raw.hands[(int)to.PieceColor()].Add(from_pr);
                        });
                    }
                    else
                    {
                        // 手駒を同じ駒台に移動させることは出来ないし、
                        // 選び直しているのでは?

                        if (to_pr != Piece.NO_PIECE)
                        {
                            pick_up_for_edit(to);
                            return;
                        }
                    }
                }
                else if (from.IsPieceBoxPiece())
                {
                    // -- 駒箱の駒を手駒に

                    // 玉は移動手駒に出来ない
                    if (from_pt != Piece.KING)
                    {
                        BoardEditCommand(raw => raw.hands[(int)to.PieceColor()].Add(from_pr));
                    }
                }
            }
            else if (to.IsPieceBoxPiece())
            {
                if (from.IsBoardPiece())
                {
                    // -- 盤上の駒を駒箱に
                    BoardEditCommand(raw => raw.board[(int)from] = Piece.NO_PIECE);
                }
                else if (from.IsHandPiece())
                {
                    // -- 駒台の駒を駒箱に

                    BoardEditCommand(raw => raw.hands[(int)from.PieceColor()].Sub(from_pr));
                }
                else if (from.IsPieceBoxPiece())
                {
                    // 駒箱の駒を移動させることは出来ないし、
                    // 選び直しているのでは?

                    if (to_pr != Piece.NO_PIECE)
                    {
                        pick_up_for_edit(to);
                        return;
                    }
                }
            }
        }
Exemple #2
0
        /// <summary>
        /// [UI thread] : 盤面のsqの升(手駒も含む)がクリックされた
        /// </summary>
        /// <param name="sq"></param>
        public void OnBoardClick(SquareHand sq)
        {
            var pos   = gameServer.Position;
            var state = viewState;
            var pc    = pos.PieceOn(sq);

            //Console.WriteLine(sq.Pretty());

            if (gameServer.InTheBoardEdit)
            {
                // -- 盤面編集中

                switch (state.state)
                {
                case GameScreenControlViewStateEnum.Normal:
                {
                    // 盤面編集中はどの駒でも掴める
                    if (pc != Piece.NO_PIECE)
                    {
                        pick_up_for_edit(sq);
                    }
                    break;
                }

                case GameScreenControlViewStateEnum.PiecePickedUp:
                {
                    // 盤面編集中はどの駒でも掴める
                    state.picked_to = sq;
                    move_piece_for_edit(state.picked_from, state.picked_to);
                    break;
                }
                }
            }
            else
            {
                // -- 対局中、もしくは、対局終了後である。

                switch (state.state)
                {
                case GameScreenControlViewStateEnum.Normal:
                {
                    // 掴んだのが自分の駒であるか
                    if (pc != Piece.NO_PIECE && pc.PieceColor() == pos.sideToMove && !sq.IsPieceBoxPiece())
                    {
                        pick_up(sq);         // sqの駒を掴んで行き先の候補の升情報を更新する
                    }
                    break;
                }

                case GameScreenControlViewStateEnum.PiecePickedUp:
                {
                    // 次の4つのケースが考えられる
                    // 1.駒を掴んでいる状態なので移動先のクリック
                    // 2.自駒を再度掴んだ(掴んでいたのをキャンセルする)
                    // 3.別の自分の駒を掴んだ(掴み直し)
                    // 4.無縁の升をクリックした(掴んでいたのをキャンセルする)

                    // 1. 駒の移動

                    // いま掴んでいる駒の移動できる先であるのか。
                    var bb = state.picked_piece_legalmovesto;
                    if (sq.IsBoardPiece() && bb.IsSet((Square)sq))
                    {
                        state.picked_to = sq;
                        move_piece(state.picked_from, state.picked_to);
                    }
                    // 2. 掴んでいた駒の再クリック
                    else if (sq == state.picked_from)
                    {
                        StateReset();
                    }

                    // 3. 別の駒のクリック
                    else if (pc != Piece.NO_PIECE && pc.PieceColor() == pos.sideToMove && !sq.IsPieceBoxPiece())
                    {
                        pick_up(sq);
                    }

                    // 4. 掴む動作のキャンセル
                    else
                    {
                        StateReset();
                    }

                    break;
                }

                case GameScreenControlViewStateEnum.PromoteDialog:
                {
                    // PromoteDialogを出していたのであれば、
                    switch (state.promote_dialog_selection)
                    {
                    case PromoteDialogSelectionEnum.NO_SELECT:
                        break;             // 無視

                    case PromoteDialogSelectionEnum.CANCEL:
                        // キャンセルするので移動の駒の選択可能状態に戻してやる。
                        StateReset();
                        break;

                    // 成り・不成を選んでクリックしたのでそれに応じた移動を行う。
                    case PromoteDialogSelectionEnum.UNPROMOTE:
                    case PromoteDialogSelectionEnum.PROMOTE:
                        var m = Util.MakeMove(state.picked_from, state.picked_to,
                                              state.promote_dialog_selection == PromoteDialogSelectionEnum.PROMOTE);
                        DoMoveCommand(m);
                        break;
                    }

                    break;
                }
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// 駒の移動 盤面編集
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        public void move_piece_for_edit(SquareHand from, SquareHand to)
        {
            var pos = gameServer.Position;

            // 何にせよ、移動、もしくは交換をする。
            var from_pc = pos.PieceOn(from);
            var from_pt = from_pc.PieceType();
            var from_pr = from_pc.RawPieceType();
            var to_pc   = pos.PieceOn(to);
            var to_pr   = to_pc.RawPieceType();

            if (to.IsBoardPiece())
            {
                if (from.IsBoardPiece())
                {
                    // -- 盤上と盤上の駒

                    // fromとtoの升の駒を交換する。
                    // fromに駒があることは確定している。toに駒があろうがなかろうが良い。
                    BoardEditCommand(raw =>
                    {
                        raw.board[(int)from] = to_pc;
                        raw.board[(int)to]   = from_pc;
                    });
                }
                else if (from.IsHandPiece())
                {
                    // -- 手駒を盤面に

                    BoardEditCommand(raw =>
                    {
                        raw.hands[(int)from.PieceColor()].Sub(from_pt);
                        raw.board[(int)to] = from_pc;
                        // このtoの位置にもし駒があったとしたら、それは駒箱に移動する。
                        // (その駒が欠落するので..)
                    });
                }
                else if (from.IsPieceBoxPiece())
                {
                    // -- 駒箱の駒を盤面に

                    BoardEditCommand(raw => raw.board[(int)to] = from_pc);
                }
            }
            else if (to.IsHandPiece())
            {
                if (from.IsBoardPiece())
                {
                    // -- 盤上の駒を手駒に移動させる。

                    // 手駒に出来る駒種でなければキャンセル
                    if (from_pt == Piece.KING)
                    {
                        return;
                    }

                    BoardEditCommand(raw =>
                    {
                        raw.board[(int)from] = Piece.NO_PIECE;
                        raw.hands[(int)to.PieceColor()].Add(from_pr);
                    });
                }
                else if (from.IsHandPiece())
                {
                    // -- 手駒を手駒に。手番が違うならこれは合法。

                    if (from.PieceColor() != to.PieceColor())
                    {
                        BoardEditCommand(raw =>
                        {
                            // 同種の駒が駒台から駒台に移動するので、to_prは関係ない。
                            raw.hands[(int)from.PieceColor()].Sub(from_pr);
                            raw.hands[(int)to.PieceColor()].Add(from_pr);
                        });
                    }
                    else
                    {
                        // 手駒を同じ駒台に移動させることは出来ないし、
                        // 選び直しているのでは?

                        if (to_pr != Piece.NO_PIECE)
                        {
                            pick_up_for_edit(to);
                            return;
                        }
                    }
                }
                else if (from.IsPieceBoxPiece())
                {
                    // -- 駒箱の駒を手駒に

                    // 玉は移動手駒に出来ない
                    if (from_pt != Piece.KING)
                    {
                        BoardEditCommand(raw => raw.hands[(int)to.PieceColor()].Add(from_pr));
                    }
                }
            }
            else if (to.IsPieceBoxPiece())
            {
                if (from.IsBoardPiece())
                {
                    // -- 盤上の駒を駒箱に
                    BoardEditCommand(raw => raw.board[(int)from] = Piece.NO_PIECE);
                }
                else if (from.IsHandPiece())
                {
                    // -- 駒台の駒を駒箱に

                    BoardEditCommand(raw => raw.hands[(int)from.PieceColor()].Sub(from_pr));
                }
                else if (from.IsPieceBoxPiece())
                {
                    // 駒箱の駒を移動させることは出来ないし、
                    // 選び直しているのでは?

                    if (to_pr != Piece.NO_PIECE)
                    {
                        pick_up_for_edit(to);
                        return;
                    }
                }
            }

            StateReset();
        }