/// <summary>
        /// 完成棋子的移动以及回合数的更新
        /// </summary>
        /// <param name="start">起始坐标</param>
        /// <param name="end">终止坐标</param>
        /// <returns></returns>
        public ChessPosition move(Coordinate start, Coordinate end)
        {
            ChessPosition new_position = new ChessPosition(this);

            #region ' Update the Stats '

            new_position._current_player = new_position._current_player.flip();
            if (this[end] == null)
            {
                new_position.noncapture_moves += 1;
            }
            else
            {
                new_position.noncapture_moves = 0;
            }
            if (this._current_player == ChessColour.BLACK)
            {
                new_position.total_rounds += 1;
            }

            #endregion

            #region ' Move the Piece '

            new_position[start] = new Piece();
            new_position[end]   = new Piece(this[start].ToString());

            #endregion

            return(new_position);
        }
 /// <summary>
 /// 刷新格点的Tag.
 /// </summary>
 /// <param name="chess_position">当前棋局</param>
 private void refresh_pieces(ChessPosition chess_position)
 {
     foreach (Coordinate cdn in this.Keys)
     {
         Coordinate reflected_cdn = cdn.reflect(this.reflection);
         this[reflected_cdn].tag.piece = chess_position[cdn];
         Boolean masked = this.masked_panels.Contains(cdn);
         this[reflected_cdn].masked = masked;
         this[reflected_cdn].refresh_image();
     }
 }
        /// <summary>
        /// 初始化特定fen值下的棋子.
        /// </summary>
        /// <param name="fen"></param>
        public void initialize_pieces(String fen)
        {
            this.turns        = 0;
            this.lobby_player = ChessColour.NONE;
            this.last_click   = null;
            this.masked_panels.Clear();
            this.chess_positions = new List <ChessPosition>();
            ChessPosition chess_position = new ChessPosition(fen);

            this.chess_positions.Add(chess_position);
            this.refresh_pieces();
        }
        /// <summary>
        /// 获得棋步的音频字符串
        /// </summary>
        /// <param name="start">起始坐标</param>
        /// <param name="end">终止坐标</param>
        /// <returns></returns>
        public String get_audio_string(Coordinate start, Coordinate end)
        {
            ChessColour     player     = this.current_player;
            PieceType       piece      = this[start].type;
            CoordinateDelta delta      = end - start;
            VerticalLine    start_line = ChessPosition.get_vertical_line(
                start, player);
            VerticalLine end_line = ChessPosition.get_vertical_line(
                end, player);
            MoveDirection direction = ChessPosition.get_move_direction(
                delta, player);
            PieceIdentifier id;

            switch (piece)
            {
            default:
                throw new ArgumentOutOfRangeException("棋子种类越界!");

            case PieceType.ADVISOR:
            case PieceType.BISHOP:
                return(ChessMove.to_audio_name(
                           player, piece, start_line, direction, end_line));

            case PieceType.CANNON:
            case PieceType.ROOK:
            case PieceType.PAWN:
                id = this.get_identifier(start);
                if (direction == MoveDirection.SIDEWARD)
                {
                    return(ChessMove.to_audio_name(
                               id, player, piece, start_line, direction, end_line));
                }
                return(ChessMove.to_audio_name(
                           id, player, piece, start_line, direction, delta));

            case PieceType.KING:
                if (direction == MoveDirection.SIDEWARD)
                {
                    return(ChessMove.to_audio_name(
                               player, piece, start_line, direction, end_line));
                }
                return(ChessMove.to_audio_name(
                           player, piece, start_line, direction, delta));

            case PieceType.KNIGHT:
                id = this.get_identifier(start);
                return(ChessMove.to_audio_name(
                           id, player, piece, start_line, direction, end_line));
            }
        }
 /// <summary>
 /// 初始化<see cref="ChessPosition"/>的新实例
 /// </summary>
 /// <param name="chess_position"></param>
 public ChessPosition(ChessPosition chess_position)
     : this(chess_position.ToString())
 {
     ;
 }
        /// <summary>
        /// 判断忽略棋规的情况下棋步是否合法
        /// </summary>
        /// <param name="start">起始坐标</param>
        /// <param name="end">终止坐标</param>
        private Boolean is_raw_move(Coordinate start, Coordinate end)
        {
            ChessColour     player = this.current_player;
            PieceType       piece  = this[start].type;
            CoordinateDelta delta  = end - start;

            switch (piece)
            {
            default:
                throw new ArgumentOutOfRangeException("棋子种类越界!");

            case PieceType.ADVISOR:
            case PieceType.KING:
                if (ChessPosition.is_inside_castle(end, player))
                {
                    return(true);
                }
                return(false);

            case PieceType.BISHOP:
                if (ChessPosition.is_castle_side(end, player))
                {
                    if (this.check_bishop_eye(start, delta))
                    {
                        return(true);
                    }
                }
                return(false);

            case PieceType.CANNON:
                if (this[end].type == PieceType.NONE)
                {
                    if (this.count_piece(start, delta) == 0)
                    {
                        return(true);
                    }
                    return(false);
                }
                if (this.count_piece(start, delta) == 1)
                {
                    return(true);
                }
                return(false);

            case PieceType.KNIGHT:
                if (this.check_knight_leg(start, delta))
                {
                    return(true);
                }
                return(false);

            case PieceType.PAWN:
                if (ChessPosition.get_move_direction(delta, player) ==
                    MoveDirection.BACKWARD)
                {
                    return(false);
                }
                if (ChessPosition.is_castle_side(start, player))
                {
                    if (!delta.abs().Equals(new CoordinateDelta(0, 1)))
                    {
                        return(false);
                    }
                }
                return(true);

            case PieceType.ROOK:
                if (this.count_piece(start, delta) == 0)
                {
                    return(true);
                }
                return(false);
            }
        }