コード例 #1
0
        public static String to_chinese_name(String audio_name, ChessColour player)
        {
            String chinese_name = "";

            while (audio_name.Length > 0)
            {
                if (Char.IsDigit(audio_name[0]))
                {
                    chinese_name += audio_name[0].to_chinese_submove(player);
                    try
                    {
                        audio_name = audio_name.Substring(1);
                    }
                    catch (ArgumentOutOfRangeException) { break; }
                    continue;
                }
                chinese_name += audio_name.Substring(0, 2).to_chinese_submove(player);
                try
                {
                    audio_name = audio_name.Substring(2);
                }
                catch (ArgumentOutOfRangeException) { break; }
                continue;
            }
            return(chinese_name);
        }
コード例 #2
0
        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);
            }
        }
コード例 #3
0
        public Boolean has_king(ChessColour lobby_player)
        {
            ChessColour current_player = this.current_player;

            if (lobby_player != current_player)
            {
                return(true);
            }
            for (Int32 y = 9; y >= 0; y--)
            {
                for (Int32 x = 0; x < 9; x++)
                {
                    Coordinate cdn = new Coordinate(x, y);
                    if (!is_inside_castle(cdn, current_player))
                    {
                        continue;
                    }
                    if (this[cdn].colour == current_player &&
                        this[cdn].type == PieceType.KING)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
コード例 #4
0
        private static Boolean is_inside_castle(Coordinate cdn, ChessColour player)
        {
            if (cdn.x.value < 3 || cdn.x.value > 5)
            {
                return(false);
            }
            switch (player)
            {
            default:
                throw new ArgumentOutOfRangeException("选手颜色越界!");

            case ChessColour.BLACK:
                if (cdn.y.value < 7)
                {
                    return(false);
                }
                return(true);

            case ChessColour.RED:
                if (cdn.y.value > 2)
                {
                    return(false);
                }
                return(true);
            }
        }
コード例 #5
0
        public static String to_chinese_submove(this String submove, ChessColour player)
        {
            switch (submove)
            {
            default:
                throw new ArgumentOutOfRangeException("Submove out of range!");

            case "ba":
                return("士");

            case "ra":
                return("仕");

            case "bb":
                return("象");

            case "rb":
                return("相");

            case "bc":
                return("砲");

            case "rc":
                return("炮");

            case "bk":
                return("將");

            case "rk":
                return("帥");

            case "bn":
                return("傌");

            case "rn":
                return("馬");

            case "bp":
                return("卒");

            case "rp":
                return("兵");

            case "br":
                return("俥");

            case "rr":
                return("車");

            case "ad":
                return("进");

            case "tr":
                return("平");

            case "wi":
                return("退");
            }
        }
コード例 #6
0
 public VerticalLine(Int32 col_num, ChessColour player)
     : base(col_num)
 {
     if (player == ChessColour.NONE)
     {
         throw new ArgumentOutOfRangeException("选手颜色越界!");
     }
     this.player = player;
 }
コード例 #7
0
        public void gamestart(ChessColour colour)
        {
            this.initialize_pieces();
            ReflectionType reflection = colour == ChessColour.RED ?
                                        ReflectionType.None : ReflectionType.PointReflection;

            reflect(this.reflection ^ reflection);
            this.lobby_player = colour;
        }
コード例 #8
0
ファイル: Utils.cs プロジェクト: paymog/Chess
 public static ChessColour GetOtherColour(ChessColour currentColour)
 {
     if(currentColour == ChessColour.Black)
     {
         return ChessColour.White;
     }
     else
     {
         return ChessColour.Black;
     }
 }
コード例 #9
0
        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));
        }
コード例 #10
0
        /// <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));
            }
        }
コード例 #11
0
 private void chessboard_gamestart(ChessColour colour)
 {
     if (chessboard_container.InvokeRequired)
     {
         ChessColourArgReturningVoidDelegate d =
             new ChessColourArgReturningVoidDelegate(
                 chessboard_gamestart);
         this.Invoke(d, new object[] { colour });
     }
     else
     {
         this.chessboard_container.chessboard.gamestart(colour);
     }
 }
コード例 #12
0
 /// <summary>
 /// 相三进五型
 /// </summary>
 /// <returns></returns>
 public static String to_audio_name
 (
     ChessColour player,
     PieceType piece,
     VerticalLine start,
     MoveDirection direction,
     VerticalLine end
 )
 {
     if (player == ChessColour.NONE || piece == PieceType.NONE)
     {
         throw new ArgumentOutOfRangeException("越界!");
     }
     return(($"{player.ToString()[0]}{(char)piece}{start.value}" +
             $"{direction.to_audio_string()}{end.value}").ToLower());
 }
コード例 #13
0
        public static String to_chinese_submove(this Char submove, ChessColour player)
        {
            String red_nums   = "一二三四五六七八九";
            String black_nums = "123456789";
            Int32  num        = Int32.Parse(submove.ToString()) - 1;

            switch (player)
            {
            default:
                throw new ArgumentOutOfRangeException("Player out of range!");

            case ChessColour.RED:
                return(red_nums.Substring(num, 1));

            case ChessColour.BLACK:
                return(black_nums.Substring(num, 1));
            }
        }
コード例 #14
0
ファイル: ChessBoard.cs プロジェクト: Jheschl17/ConsoleChess
        public (bool success, string errorMessage) Move(ChessColour chessColour, int xFrom, int yFrom, int xTo, int yTo)
        {
            var piece = (
                from pcs in _chessPieces
                where pcs.X == xFrom && pcs.Y == yFrom
                select pcs
                ).FirstOrDefault();

            // If no piece could be found on the given position (xFrom, yFrom), return false.
            if (piece == null)
            {
                return(false, "This position is empty");
            }

            if (piece.Colour != chessColour)
            {
                return(false, "This piece is of the opposite colour");
            }

            var(canMove, errorMessage) = piece.CanMove(xTo, yTo, _chessPieces);
            // If moving the chosen piece to the chosen field is not allowed according to the CanMove method implemented
            // in each ChessPiece subclass, return false.
            if (!canMove)
            {
                return(false, errorMessage);
            }

            // All checks succeeded
            // If on exists, remove the chess piece currently at the position the moving piece moves to
            var take = (
                from pcs in _chessPieces
                where pcs.X == xTo && pcs.Y == yTo
                select pcs
                ).FirstOrDefault();

            _chessPieces.Remove(take);

            // Update position of moving piece
            piece.X = xTo;
            piece.Y = yTo;

            return(true, null);
        }
コード例 #15
0
ファイル: AIEngine.cs プロジェクト: paymog/Chess
        private int AlphaBeta(Chessboard board, int depth, int alpha, int beta, ChessColour player)
        {
            recursiveCount += 1;
            if (depth == 0)
            {
                return Evaluator.Evaluate(board);
            }

            Chessboard originalBoard = new Chessboard(board);
            if(player == ChessColour.White)
            {
                foreach(var move in FindAllMoves(board, player))
                {
                    board.MakeMove(move.FromIndex, move.ToIndex);
                    alpha = Math.Max(alpha, AlphaBeta(board, depth - 1, alpha, beta, ChessColour.Black));
                    board.UndoMove(move);

                    if(beta <= alpha)
                    {
                        break;
                    }
                }
                return alpha;
            }
            else
            {
                foreach (var move in FindAllMoves(board, player))
                {
                    board.MakeMove(move.FromIndex, move.ToIndex);
                    beta = Math.Min(beta, AlphaBeta(board, depth - 1, alpha, beta, ChessColour.White));
                    board.UndoMove(move);

                    if (beta <= alpha)
                    {
                        break;
                    }
                }
                return beta;
            }
        }
コード例 #16
0
 /// <summary>
 /// 前炮进一型或炮五进一型
 /// </summary>
 /// <returns></returns>
 public static String to_audio_name
 (
     PieceIdentifier id,
     ChessColour player,
     PieceType piece,
     VerticalLine start,
     MoveDirection direction,
     CoordinateDelta delta
 )
 {
     if (id == PieceIdentifier.NONE)
     {
         return(to_audio_name(
                    player, piece, start, direction, delta));
     }
     if (player == ChessColour.NONE || piece == PieceType.NONE)
     {
         throw new ArgumentOutOfRangeException("越界!");
     }
     return(($"{id.to_audio_string()}{player.ToString()[0]}{(char)piece}" +
             $"{direction.to_audio_string()}{Math.Abs(delta.y)}").ToLower());
 }
コード例 #17
0
ファイル: AIEngine.cs プロジェクト: paymog/Chess
        public ChessMove FindBestAlphaBetaMove(Chessboard board, ChessColour player)
        {
            var moves = new List<Tuple<int, ChessMove>>();

            foreach(var move in FindAllMoves(board, player))
            {
                var newBoard = new Chessboard(board);
                newBoard.MakeMove(move.FromIndex, move.ToIndex);

                var score = AlphaBeta(newBoard, MAX_PLY - 1, int.MinValue, int.MaxValue, Utils.GetOtherColour(player));

                moves.Add(Tuple.Create( score, move));
            }

            if(player == ChessColour.White)
            {
                return FindMax(moves).Item2;
            }
            else
            {
                return FindMin(moves).Item2;
            }
        }
コード例 #18
0
        /// <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);
        }
コード例 #19
0
ファイル: ChessboardTest.cs プロジェクト: paymog/Chess
 private void makeMovePieceAssertions(int fromIndex, int toIndex, Type pieceType, ChessColour pieceColour)
 {
     Assert.IsInstanceOfType(board.Locations[toIndex].Piece, pieceType);
     Assert.AreEqual(board.Locations[toIndex].PieceColour, pieceColour);
     Assert.IsNull(board.Locations[fromIndex].Piece);
 }
コード例 #20
0
 /// <summary>
 /// 返回相反的颜色.
 /// </summary>
 /// <param name="colour"></param>
 /// <returns></returns>
 public static ChessColour flip(this ChessColour colour)
 {
     return(ChessColour.NONE ^ colour);
 }
コード例 #21
0
ファイル: AIEngine.cs プロジェクト: paymog/Chess
        private Tuple<int, ChessMove> FindBestMove(Chessboard board, ChessColour player, int currentPly)
        {
            recursiveCount += 1;
            var movesAndScore = new List<Tuple<int, ChessMove>>();

            foreach(var move in FindAllMoves(board, player))
            {
                var newBoard = new Chessboard(board);
                newBoard.MakeMove(move.FromIndex, move.ToIndex);

                // base case
                if (currentPly == 1)
                {
                    movesAndScore.Add(new Tuple<int, ChessMove>(Evaluator.Evaluate(newBoard), move));
                }
                else //recursive case
                {
                    var bestMove = FindBestMove(newBoard, Utils.GetOtherColour(player), currentPly - 1);
                    movesAndScore.Add(Tuple.Create(bestMove.Item1, move));
                }
            }

            if (player == ChessColour.Black)
            {
                return FindMin(movesAndScore);
            }
            else
            {
                return FindMax(movesAndScore);
            }
        }
コード例 #22
0
ファイル: Knight.cs プロジェクト: paymog/Chess
 public Knight(ChessColour colour)
     : base(colour)
 {
 }
コード例 #23
0
 /// <summary>
 /// 初始化<see cref="Piece"/>类的新实例
 /// </summary>
 /// <param name="colour">棋子颜色</param>
 /// <param name="type">棋子种类</param>
 public Piece(ChessColour colour, PieceType type)
 {
     this._colour = colour;
     this._type   = type;
 }
コード例 #24
0
ファイル: ChessBoard.cs プロジェクト: paymog/Chess
        private BitArray GetAttackVectors(ChessColour chessColour)
        {
            BitArray result = new BitArray(Chessboard.NumLocations, false);
            for (int i = 0; i < this.Locations.Count; i++)
            {
                var piece = this.Locations[i].Piece;
                if (piece != null && piece.Colour == chessColour)
                {
                    result.Or(piece.GetCorrectedRay(i, WhiteLocations, BlackLocations));
                }
            }

            return result;
        }
コード例 #25
0
ファイル: ChessBoard.cs プロジェクト: paymog/Chess
        /// <summary>
        /// Gets all of the board location objects with a piece of a specified colour
        /// </summary>
        /// <param name="pieceColour">The piece color to filter by</param>
        /// <returns></returns>
        public IEnumerable<BoardLocation> GetLocations(ChessColour pieceColour)
        {
            // TODO method needs to be renamed, I think

            return from location in Locations
                   where location.HasPiece && location.PieceColour == pieceColour
                   select location;
        }
コード例 #26
0
ファイル: ChessBoard.cs プロジェクト: paymog/Chess
 public bool IsPlayerInCheck(ChessColour playerToCheck)
 {
     int kingIndex = FindKingIndex(playerToCheck);
     BitArray otherPlayerAttackVectors = GetAttackVectors(playerToCheck == ChessColour.Black ? ChessColour.White : ChessColour.Black);
     return otherPlayerAttackVectors[kingIndex];
 }
コード例 #27
0
ファイル: Bishop.cs プロジェクト: paymog/Chess
 public Bishop(ChessColour colour)
     : base(colour)
 {
 }
コード例 #28
0
 /// <summary>
 /// 判断<see cref="ChessColour"/>是否正在被将军.
 /// </summary>
 /// <param name="player">玩家</param>
 /// <returns></returns>
 private Boolean is_check(ChessColour player)
 {
     return(false);
 }
コード例 #29
0
 /// <summary>
 /// 判断棋步之后该<see cref="ChessColour"/>是否被将军
 /// </summary>
 /// <param name="start">起始坐标</param>
 /// <param name="end">终止坐标</param>
 /// <returns></returns>
 private Boolean is_check(
     Coordinate start, Coordinate end, ChessColour player)
 {
     return(this.move(start, end).is_check(player));
 }
コード例 #30
0
        /// <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);
            }
        }
コード例 #31
0
ファイル: ChessPiece.cs プロジェクト: paymog/Chess
 protected ChessPiece(ChessColour colour)
 {
     this._colour = colour;
 }
コード例 #32
0
ファイル: ChessBoard.cs プロジェクト: paymog/Chess
        /// <summary>
        /// Given a ray of potential moves (assuming the player isn't in check), this method will generate a ray
        /// a new ray which eliminates any of the potential moves which result in check.
        /// </summary>
        /// <param name="potentialMoves">The potential moves of a piece</param>
        /// <param name="index">The location of the piece</param>
        /// <param name="pieceColour">The colour of the piece</param>
        /// <returns>A bit array of moves which will NOT result in check for <paramref name="pieceColour"/></returns>
        private BitArray GetCheckPreventionRay(BitArray potentialMoves, int index, ChessColour pieceColour)
        {
            var ray = new BitArray(potentialMoves.Count, false);

            var board = new Chessboard(this);
            for (int i = 0; i < potentialMoves.Count; i++)
            {
                var bit = potentialMoves[i];
                if (bit)
                {
                    var move = Utils.BuildMove(Locations, index, i);
                    board.MakeMove(move);
                    if (!board.IsPlayerInCheck(pieceColour))
                    {
                        ray[i] = true;
                    }
                    board.UndoMove(move);
                }
            }

            return ray;
        }
コード例 #33
0
ファイル: ChessBoard.cs プロジェクト: paymog/Chess
 public bool IsPlayerInCheckmate(ChessColour player)
 {
     if (IsPlayerInCheck(player))
     {
         return !GetAllPossibleMoves(player).HasTrue();
     }
     else
     {
         return false;
     }
 }
コード例 #34
0
ファイル: King.cs プロジェクト: paymog/Chess
 public King(ChessColour colour)
     : base(colour)
 {
 }
コード例 #35
0
ファイル: AIEngine.cs プロジェクト: paymog/Chess
 /// <summary>
 /// Performs minimax search for best move. No pruning
 /// </summary>
 /// <param name="board"></param>
 /// <param name="player"></param>
 /// <returns></returns>
 public ChessMove FindBestMove(Chessboard board, ChessColour player)
 {
     return FindBestMove(board, player, MAX_PLY).Item2;
 }
コード例 #36
0
ファイル: BoardLocation.cs プロジェクト: paymog/Chess
 public BoardLocation(ChessColour color, ChessPiece piece = null)
 {
     this._colour = color;
     this.Piece = piece;
 }
コード例 #37
0
ファイル: ChessBoard.cs プロジェクト: paymog/Chess
 private BitArray GetAllPossibleMoves(ChessColour colour)
 {
     var possibleMoves = new BitArray(Chessboard.NumLocations, false);
     foreach (var location in Locations)
     {
         if (location.HasPiece && location.PieceColour == colour)
         {
             possibleMoves.Or(GetRay(location));
         }
     }
     return possibleMoves;
 }
コード例 #38
0
ファイル: AIEngine.cs プロジェクト: paymog/Chess
        private IEnumerable<ChessMove> FindAllMoves(Chessboard board, ChessColour player)
        {
            var pieceLocations = board.GetLocations(player);

            foreach (var location in pieceLocations)
            {
                var locationIndex = board.Locations.IndexOf(location);
                var ray = board.GetRay(location);
                for (int i = 0; i < ray.Count; i++)
                {
                    if (ray[i])
                    {
                        yield return new ChessMove(locationIndex, i, location.Piece, board.Locations[i].Piece);
                    }
                }
            }
        }
コード例 #39
0
ファイル: ChessBoard.cs プロジェクト: paymog/Chess
 public bool IsPlayerInStalemate(ChessColour player)
 {
     if (!IsPlayerInCheck(player))
     {
         return !GetAllPossibleMoves(player).HasTrue();
     }
     else
     {
         // if the player is in check he can't possibly be in a stalemate
         return false;
     }
 }
コード例 #40
0
ファイル: Queen.cs プロジェクト: paymog/Chess
 public Queen(ChessColour colour)
     : base(colour)
 {
 }
コード例 #41
0
 private static VerticalLine get_vertical_line(
     Coordinate cdn, ChessColour player)
 {
     return(new VerticalLine(cdn.x.value, player));
 }
コード例 #42
0
ファイル: Pawn.cs プロジェクト: paymog/Chess
 public Pawn(ChessColour color)
     : base(color)
 {
 }
コード例 #43
0
ファイル: ChessBoard.cs プロジェクト: paymog/Chess
        private int FindKingIndex(ChessColour chessColour)
        {
            for (int i = 0; i < this.Locations.Count; i++)
            {
                var piece = this.Locations[i].Piece;
                if (piece is King && piece.Colour == chessColour)
                {
                    return i;
                }
            }

            throw new System.InvalidOperationException("No king was found. A king should always be present.");
        }
コード例 #44
0
        public String get_chinese_string(Coordinate start, Coordinate end)
        {
            ChessColour player = this.current_player;

            return(ChessMove.to_chinese_name(get_audio_string(start, end), player));
        }
コード例 #45
0
ファイル: Rook.cs プロジェクト: paymog/Chess
 public Rook(ChessColour colour)
     : base(colour)
 {
 }