private static MoveDirection get_move_direction(
            CoordinateDelta delta, ChessColour player)
        {
            switch (player)
            {
            default:
                throw new ArgumentOutOfRangeException("选手颜色越界!");

            case ChessColour.BLACK:
                if (delta.y < 0)
                {
                    return(MoveDirection.FORWARD);
                }
                if (delta.y == 0)
                {
                    return(MoveDirection.SIDEWARD);
                }
                return(MoveDirection.BACKWARD);

            case ChessColour.RED:
                if (delta.y > 0)
                {
                    return(MoveDirection.FORWARD);
                }
                if (delta.y == 0)
                {
                    return(MoveDirection.SIDEWARD);
                }
                return(MoveDirection.BACKWARD);
            }
        }
        private Boolean check_knight_leg(Coordinate start, CoordinateDelta delta)
        {
            Coordinate leg = start + delta / 2;

            if (this[leg].type == PieceType.NONE)
            {
                return(true);
            }
            return(false);
        }
        private Boolean check_bishop_eye(Coordinate start, CoordinateDelta delta)
        {
            Coordinate eye = start + delta / 2;

            if (this[eye].type == PieceType.NONE)
            {
                return(true);
            }
            return(false);
        }
        public static String to_chinese_format(
            this CoordinateDelta delta, ChessColour player)
        {
            Int32 value = Math.Abs(delta.y);

            if (player == ChessColour.RED)
            {
                return("一二三四五六七八九".Substring(value - 1, 1));
            }
            return("123456789".Substring(value - 1, 1));
        }
        /// <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));
            }
        }
Esempio n. 6
0
        /// <summary>
        /// Returns a value that indicates whether the current
        /// <see cref="CoordinateDelta"/> object is equal to a specified object
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public override Boolean Equals(Object obj)
        {
            if (obj == null || this.GetType() != obj.GetType())
            {
                return(false);
            }
            CoordinateDelta delta = obj as CoordinateDelta;

            if (this.x == delta.x && this.y == delta.y)
            {
                return(true);
            }
            return(false);
        }
Esempio n. 7
0
        /// <summary>
        /// 仅从偏移量角度来筛选出不合法走子,
        /// 不考虑子所在的位置, 不考虑兵的前进后退.
        /// </summary>
        /// <param name="delta">偏移量</param>
        /// <param name="piece">棋子种类</param>
        /// <returns></returns>
        public static Boolean is_valid(CoordinateDelta delta, PieceType piece)
        {
            switch (piece)
            {
            default:
                throw new ArgumentOutOfRangeException("棋子种类越界!");

            case PieceType.ADVISOR:
                if (delta.abs().Equals(new CoordinateDelta(1, 1)))
                {
                    return(true);
                }
                return(false);

            case PieceType.BISHOP:
                if (delta.abs().Equals(new CoordinateDelta(2, 2)))
                {
                    return(true);
                }
                return(false);

            case PieceType.CANNON:
            case PieceType.ROOK:
                if (delta.x == 0 || delta.y == 0)
                {
                    return(true);
                }
                return(false);

            case PieceType.KING:
            case PieceType.PAWN:
                if (delta.abs().Equals(new CoordinateDelta(1, 0)) ||
                    delta.abs().Equals(new CoordinateDelta(0, 1)))
                {
                    return(true);
                }
                return(false);

            case PieceType.KNIGHT:
                if (delta.abs().Equals(new CoordinateDelta(2, 1)) ||
                    delta.abs().Equals(new CoordinateDelta(1, 2)))
                {
                    return(true);
                }
                return(false);
            }
        }
 /// <summary>
 /// 帅五进一型
 /// </summary>
 /// <returns></returns>
 public static String to_audio_name
 (
     ChessColour player,
     PieceType piece,
     VerticalLine start,
     MoveDirection direction,
     CoordinateDelta delta
 )
 {
     if (player == ChessColour.NONE || piece == PieceType.NONE)
     {
         throw new ArgumentOutOfRangeException("越界!");
     }
     return(($"{player.ToString()[0]}{(char)piece}{start.value}" +
             $"{direction.to_audio_string()}{Math.Abs(delta.y)}")
            .ToLower());
 }
        private Int32 count_piece(Coordinate start, CoordinateDelta delta)
        {
            Int32 x     = 0;
            Int32 y     = 0;
            Int32 count = 0;

            if (delta.x == 0)
            {
                for
                (
                    y = Math.Sign(delta.y);
                    Math.Abs(y) < Math.Abs(delta.y);
                    y += Math.Sign(delta.y)
                )
                {
                    if (this[start + new CoordinateDelta(x, y)].type != PieceType.NONE)
                    {
                        count += 1;
                    }
                }
                return(count);
            }
            if (delta.y == 0)
            {
                for
                (
                    x = Math.Sign(delta.x);
                    Math.Abs(x) < Math.Abs(delta.x);
                    x += Math.Sign(delta.x)
                )
                {
                    if (this[start + new CoordinateDelta(x, y)].type != PieceType.NONE)
                    {
                        count += 1;
                    }
                }
                return(count);
            }
            throw new ArgumentOutOfRangeException("不是直线移动!");
        }
        /// <summary>
        /// 判断棋步是否合法
        /// </summary>
        /// <param name="start">起始坐标</param>
        /// <param name="end">终止坐标</param>
        /// <returns></returns>
        private Boolean is_valid_move(Coordinate start, Coordinate end)
        {
            ChessColour     player = this.current_player;
            PieceType       piece  = this[start].type;
            CoordinateDelta delta  = end - start;

            // 筛选偏移量是否合法
            if (!CoordinateDelta.is_valid(delta, piece))
            {
                return(false);
            }
            // 筛选忽略棋规情况下是否合法
            if (!this.is_raw_move(start, end))
            {
                return(false);
            }
            // 棋规
            if (!this.check_rules(start, end))
            {
                return(false);
            }
            return(true);
        }
        /// <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);
            }
        }