Beispiel #1
0
        /// <summary>
        /// 実際に指し手を進めます。
        /// </summary>
        private void DoMove(BoardMove move)
        {
            if (move == null || !move.Validate())
            {
                return;
            }

            this.RaiseEvent(new BoardPieceRoutedEventArgs(
                                BoardPieceChangingEvent, Board.Clone(), move));
            Board.DoMove(move);
            this.RaiseEvent(new BoardPieceRoutedEventArgs(
                                BoardPieceChangedEvent, Board.Clone(), move));
        }
Beispiel #2
0
        /// <summary>
        /// 実際に指し手を進めます。
        /// </summary>
        private void MakeMove(BoardMove move)
        {
            if (move == null || !move.Validate())
            {
                return;
            }

            BoardPieceChanging.SafeRaiseEvent(this,
                                              new BoardPieceEventArgs(Board.Clone(), move));
            Board.DoMove(move);
            BoardPieceChanged.SafeRaiseEvent(this,
                                             new BoardPieceEventArgs(Board.Clone(), move));
        }
Beispiel #3
0
        /// <summary>
        /// 指し手をSFEN形式の文字列に変換します。
        /// </summary>
        /// <remarks>
        /// 筋に関しては1から9までの数字で表記され、段に関してはaからiまでの
        /// アルファベット(1段目がa、2段目がb、・・・、9段目がi)
        /// というように表記されます。位置の表記はこの2つを組み合わせ、
        /// 5一なら5a、1九なら1iとなります。
        ///
        /// 指し手に関しては、駒の移動元の位置と移動先の位置を並べて書きます。
        /// 7七の駒が7六に移動したのであれば、7g7fと表記します。
        /// (駒の種類を表記する必要はありません。)
        /// 駒が成るときは最後に+を追加します。8八の駒が2二に移動して
        /// 成るなら8h2b+です。
        /// 持ち駒を打つときは "[駒の種類(大文字)]*[打った場所]" となります。
        /// 金を5二に打つ場合はG*5bとなります
        /// </remarks>
        public static string ToSfen(this BoardMove move)
        {
            if (move == null)
            {
                throw new ArgumentNullException("move");
            }

            if (!move.Validate())
            {
                throw new ArgumentException("move");
            }

            if (move.IsSpecialMove)
            {
                // 投了などの特殊な指し手
                throw new SfenException(
                          move + ": sfenに変換することはできません。");
            }

            var dstFile = move.DstSquare.File;
            var dstRank = (char)((int)'a' + (move.DstSquare.Rank - 1));

            if (move.ActionType == ActionType.Drop)
            {
                // 駒打ちの場合
                var piece = SfenUtil.PieceTypeToSfen(move.DropPieceType);

                return(string.Format("{0}*{1}{2}",
                                     piece, dstFile, dstRank));
            }
            else
            {
                // 駒の移動の場合
                var srcFile   = move.SrcSquare.File;
                var srcRank   = (char)((int)'a' + (move.SrcSquare.Rank - 1));
                var isPromote = (move.ActionType == ActionType.Promote);

                return(string.Format("{0}{1}{2}{3}{4}",
                                     srcFile, srcRank, dstFile, dstRank,
                                     (isPromote ? "+" : "")));
            }
        }
        /// <summary>
        /// 実際に指し手を進めます。
        /// </summary>
        private void MakeMove(BoardMove move)
        {
            if (move == null || !move.Validate())
            {
                return;
            }

            BoardPieceChanging.SafeRaiseEvent(this,
                new BoardPieceEventArgs(Board.Clone(), move));
            Board.DoMove(move);
            BoardPieceChanged.SafeRaiseEvent(this,
                new BoardPieceEventArgs(Board.Clone(), move));
        }
Beispiel #5
0
        /// <summary>
        /// <paramref name="move"/>をCSA形式に変換します。
        /// </summary>
        public static string ToCsa(this BoardMove move)
        {
            if (move == null)
            {
                throw new ArgumentNullException("move");
            }

            if (!move.Validate())
            {
                throw new ArgumentException("move");
            }

            if (move.IsSpecialMove)
            {
                return(move.SpecialMoveType.ToCsa());
            }

            var sb = new StringBuilder();

            sb.Append(
                move.BWType == BWType.Black ? "+" :
                move.BWType == BWType.White ? "-" :
                "");

            if (move.SrcSquare != null)
            {
                sb.Append(move.SrcSquare.File);
                sb.Append(move.SrcSquare.Rank);
            }
            else
            {
                // 駒打の場合
                sb.Append("00");
            }

            if (move.DstSquare != null)
            {
                sb.Append(move.DstSquare.File);
                sb.Append(move.DstSquare.Rank);
            }
            else
            {
                // ほんとはエラー
                sb.Append("00");
            }

            var piece = (
                move.ActionType == ActionType.Drop ?
                new Piece(move.DropPieceType) :
                move.MovePiece);

            if (move.IsPromote)
            {
                // 駒を成った場合は、なった後の駒を出力します。
                piece = new Piece(piece.PieceType, true);
            }

            sb.Append(CsaUtil.PieceToStr(piece));

            return(sb.ToString());
        }
Beispiel #6
0
        /// <summary>
        /// 指し手をXX->YYの形式から、ZZ銀上などの形に変換します。
        /// </summary>
        /// <remarks>
        /// <paramref name="useSrcSquare"/>を真にすると、差し手の後に
        /// 古い位置の情報が付加されるようになります。(例: 32金(22))
        /// </remarks>
        public static Move ConvertMove(this Board board, BoardMove move,
                                       bool useSrcSquare)
        {
            if (board == null)
            {
                throw new ArgumentNullException("board");
            }

            if (move == null || !move.Validate())
            {
                throw new ArgumentNullException("move");
            }

            var fromPiece = (
                move.ActionType == ActionType.Drop ?
                new Piece(move.DropPieceType) :
                move.MovePiece);
            if (fromPiece == null)
            {
                return null;
            }

            // 駒の種類と最終位置から、あり得る指し手をすべて検索します。
            var boardMoveList = board.ListupMoves(
                fromPiece, move.BWType, move.DstSquare)
                .ToList();

            return FilterMove(
                board, boardMoveList, move, fromPiece, useSrcSquare);
        }
Beispiel #7
0
        /// <summary>
        /// 駒を動かすか、または駒が動かせるか調べます。
        /// </summary>
        private bool CheckAndDoMove(BoardMove move, MoveFlags flags)
        {
            if (move == null || !move.Validate())
            {
                throw new ArgumentNullException("move");
            }

            using (LazyLock())
            {
                // 手番があわなければ失敗とします。
                if (EnumEx.HasFlag(flags, MoveFlags.CheckTurn))
                {
                    if (this.turn == BWType.None ||
                        this.turn != move.BWType)
                    {
                        return false;
                    }
                }

                if (move.ActionType == ActionType.Drop)
                {
                    return CheckAndDoDrop(move, flags);
                }
                else
                {
                    return CheckAndDoMoveOnly(move, flags);
                }
            }
        }
        /// <summary>
        /// 実際に指し手を進めます。
        /// </summary>
        private void DoMove(BoardMove move)
        {
            if (move == null || !move.Validate())
            {
                return;
            }

            this.RaiseEvent(new BoardPieceRoutedEventArgs(
                BoardPieceChangingEvent, Board.Clone(), move));
            Board.DoMove(move);
            this.RaiseEvent(new BoardPieceRoutedEventArgs(
                BoardPieceChangedEvent, Board.Clone(), move));
        }
Beispiel #9
0
        /// <summary>
        /// 駒を動かすか、または駒が動かせるか調べます。
        /// </summary>
        private bool CheckAndMakeMove(BoardMove move, MoveFlags flags)
        {
            if (move == null || !move.Validate())
            {
                throw new ArgumentNullException("move");
            }

            // 投了などの特殊な指し手がある場合はゲームが既に終了しているので
            // 指し手を進めることはできません。
            if (HasSpecialMove)
            {
                if (flags.HasFlag(MoveFlags.CheckOnly))
                {
                    // CheckOnlyの場合は、ここで失敗させません。
                }
                else if (flags.HasFlag(MoveFlags.AutoRemoveSpecialMove))
                {
                    // 特殊な指し手を取り除きます。
                    RemoveSpecialMove();
                }
                else
                {
                    return false;
                }
            }

            using (LazyLock())
            {
                // 手番があわなければ失敗とします。
                if (EnumEx.HasFlag(flags, MoveFlags.CheckTurn))
                {
                    if (this.turn == BWType.None || this.turn != move.BWType)
                    {
                        return false;
                    }
                }

                if (move.IsSpecialMove)
                {
                    return CheckAndMakeSpecialMove(move, flags);
                }
                else if (move.ActionType == ActionType.Drop)
                {
                    return CheckAndMakeDrop(move, flags);
                }
                else
                {
                    return CheckAndMakeMoveOnly(move, flags);
                }
            }
        }