Exemplo n.º 1
0
        /// <summary>
        ///		Clona el tablero
        /// </summary>
        public SquareModel Clone()
        {
            SquareModel target = new SquareModel();

            // Clona los datos
            for (int row = 0; row < 8; row++)
            {
                for (int column = 0; column < 8; column++)
                {
                    PieceBaseModel piece = this[row, column];

                    if (this[row, column] == null)
                    {
                        target[row, column] = null;
                    }
                    else
                    {
                        target.Create(piece.Type, piece.Color, row, column);
                        target[row, column].IsMoved = piece.IsMoved;
                    }
                }
            }
            // Clona los parámetros
            target.Parameters = Parameters.Clone();
            // Devuelve el tablero
            return(target);
        }
        /// <summary>
        ///		Crea las acciones asociadas a un movimiento
        /// </summary>
        internal void CreateActions(GameBoardModel board, MovementFigureModel movement,
                                    CellModel target, CellModel origin, PieceBaseModel.PieceType?targetPiece)
        {
            PieceBaseModel piece = board.SearchMoveTo(movement, target, origin);

            // Comprueba que se haya localizado la pieza que hizo el movimiento
            if (piece == null)
            {
                throw new Exceptions.GameReaderException($"No se encuentra ninguna pieza que pueda realizar el movimiento {movement.Text}");
            }
            // Crea el movimiento
            CreateMoveAction(piece.Type, piece.Color, piece.Cell, target);
            // Crea la captura
            if (movement.Type == MovementFigureModel.MovementType.Capture || movement.Type == MovementFigureModel.MovementType.CaptureEnPassant)
            {
                CreateCaptureAction(board, targetPiece, GetNextColor(movement.Color), target);
            }
            // Crea la promoción
            if (movement.PromotedPiece != null)
            {
                // Crea un movimiento para eliminar el peón que se ha promocionado
                //? No llama a CreateCaptureAction porque si ha habido una captura en este mismo movimiento
                //? la pieza aún no se habrá eliminado del destino y por tanto nos creará una captura
                //? sobre la pieza que se ha eliminado ya
                Add(new ActionCaptureModel(piece.Type, movement.Color, target));
                // Crea una promoción
                CreatePromoteAction(movement.PromotedPiece, movement.Color, target);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        ///		Mueve la pieza a una fila / columna
        /// </summary>
        private void Move(ActionMoveModel action)
        {
            PieceBaseModel piece = GetPiece(action.Type, action.Color, action.From);

            // Mueve la pieza
            piece.Cell    = action.To;
            piece.IsMoved = true;
        }
        /// <summary>
        ///		Crea una captura
        /// </summary>
        private void CreateCaptureAction(GameBoardModel board, PieceBaseModel.PieceType?piece, PieceBaseModel.PieceColor color, CellModel from)
        {
            PieceBaseModel targetPiece = board.Pieces.GetPiece(from);

            //? En ocasiones la pieza leída no es la real del tablero, por eso buscamos la pieza adecuada
            // Añade la pieza
            Add(new ActionCaptureModel(targetPiece?.Type ?? piece ?? PieceBaseModel.PieceType.Unknown, color, from));
        }
Exemplo n.º 5
0
        /// <summary>
        ///		Obtiene el texto del tablero
        /// </summary>
        public string GetText()
        {
            string board = "  0 1 2 3 4 5 6 7" + Environment.NewLine +
                           "  A B C D E F G H" + Environment.NewLine;

            // Obtiene el texto
            for (int row = 0; row < 8; row++)
            {
                // Añade el carácter con la fila
                board += $"{8 - row} ";
                for (int column = 0; column < 8; column++)
                {
                    PieceBaseModel piece = this[row, column];

                    if (piece == null)
                    {
                        board += ".";
                    }
                    else
                    {
                        switch (piece.Type)
                        {
                        case PieceBaseModel.PieceType.Pawn:
                            board += piece.Color == PieceBaseModel.PieceColor.White ? "P" : "p";
                            break;

                        case PieceBaseModel.PieceType.Bishop:
                            board += piece.Color == PieceBaseModel.PieceColor.White ? "B" : "b";
                            break;

                        case PieceBaseModel.PieceType.Knight:
                            board += piece.Color == PieceBaseModel.PieceColor.White ? "N" : "n";
                            break;

                        case PieceBaseModel.PieceType.Rook:
                            board += piece.Color == PieceBaseModel.PieceColor.White ? "R" : "r";
                            break;

                        case PieceBaseModel.PieceType.King:
                            board += piece.Color == PieceBaseModel.PieceColor.White ? "K" : "k";
                            break;

                        case PieceBaseModel.PieceType.Queen:
                            board += piece.Color == PieceBaseModel.PieceColor.White ? "Q" : "q";
                            break;
                        }
                    }
                    board += " ";
                }
                // Añade el número de fila y un salto de línea
                board += $" {8 - row} {row}" + Environment.NewLine;
            }
            // Añade el número de columna
            board += "  A B C D E F G H" + Environment.NewLine +
                     "  0 1 2 3 4 5 6 7";
            // Devuelve el texto
            return(board);
        }
Exemplo n.º 6
0
        /// <summary>
        ///		Inicializa las piezas
        /// </summary>
        private void InitPieces()
        {
            for (int row = 0; row < 8; row++)
            {
                for (int column = 0; column < 8; column++)
                {
                    PieceBaseModel piece = ViewModel.Board[row, column];

                    if (piece != null)
                    {
                        Scapes.Add(new FigureViewModel(row, column, piece.Type, piece.Color));
                    }
                }
            }
        }
Exemplo n.º 7
0
        /// <summary>
        ///		Comprueba si se puede realizar un enroque (las piezas no se han movido y no hay nada entre medias)
        /// </summary>
        private bool CanMoveCastle(PieceBaseModel.PieceColor color, int column)
        {
            bool           canMove = false;
            int            row     = GetRowKing(color);
            PieceBaseModel king    = this[row, 4];
            PieceBaseModel rook    = this[row, column];

            //TODO --> Debería comprobar además si las celdas intermedias no está en jaque
            // Comprueba el movimiento
            if (king != null && rook != null && !king.IsMoved && !rook.IsMoved)
            {
                canMove = IsPathEmpty(row, 4, row, column);
            }
            // Devuelve el valor que indica si se puede mover
            return(canMove);
        }
Exemplo n.º 8
0
        /// <summary>
        ///		Promociona una pieza
        /// </summary>
        public bool Promote(int row, int column, PieceBaseModel.PieceType type)
        {
            bool           canPromote = false;
            PieceBaseModel piece      = this[row, column];

            if (piece != null && piece.Type == PieceBaseModel.PieceType.Pawn && piece.Color == Parameters.GetTurnColor() &&
                type != PieceBaseModel.PieceType.Pawn && type != PieceBaseModel.PieceType.King &&
                ((piece.Color == PieceBaseModel.PieceColor.White && row == 0) ||
                 (piece.Color == PieceBaseModel.PieceColor.Black && row == 7)))
            {
                // Promociona la pieza
                this[row, column] = CreatePiece(type, piece.Color);
                // Indica que se ha promocionado
                canPromote = true;
            }
            // Devuelve el valor que indica si ha podido promocionar
            return(canPromote);
        }
Exemplo n.º 9
0
        /// <summary>
        ///		Comprueba si se puede mover de un lugar a otro
        /// </summary>
        public bool CanMove(int fromRow, int fromColumn, int toRow, int toColumn)
        {
            bool canMove = false;

            // Si realmente hay un movimiento
            if (fromRow != toRow || fromColumn != toColumn)
            {
                PieceBaseModel pieceSource = this[fromRow, fromColumn];

                // Si hay una pieza en el origen del color que toca jugar y no hay nada en el destino o en el destino hay una pieza de otro color
                if (pieceSource != null && pieceSource.Color == Parameters.GetTurnColor() &&
                    (this[toRow, toColumn] == null || this[toRow, toColumn].Color != pieceSource.Color))
                {
                    canMove = pieceSource.CanMoveTo(this, fromRow, fromColumn, toRow, toColumn);
                }
            }
            // Devuelve el valor que indica si se puede mover
            return(canMove);
        }
Exemplo n.º 10
0
        /// <summary>
        ///		Realiza un movimiento (sin comprobaciones por los enroques)
        /// </summary>
        private void MoveWithoutCheck(int fromRow, int fromColumn, int toRow, int toColumn, bool adjustParameters = true)
        {
            PieceBaseModel piece = this[fromRow, fromColumn];

            if (piece != null)
            {
                // Mueve la pieza
                this[toRow, toColumn]     = piece;
                this[fromRow, fromColumn] = null;
                // Asigna los datos para la captura al paso
                CheckEnPassantMove(piece, fromRow, toRow, toColumn);
                // Indica que se ha movido
                piece.IsMoved = true;
                // Ajusta los parámetros (en el caso del enroque, se hacen dos movimientos pero sólo se debe contabilizar uno)
                if (adjustParameters)
                {
                    // Añade el movimiento
                    Parameters.HalfMoveClock++;
                    if (Parameters.HalfMoveClock % 2 == 0)
                    {
                        Parameters.FullMoveCount++;
                    }
                    // Cambia el turno
                    Parameters.IsWhiteMove = !Parameters.IsWhiteMove;
                    // Si es un rey o una torre, invalida los movimientos de enroque
                    if (piece.Type == PieceBaseModel.PieceType.King)
                    {
                        Parameters.DisableCastle(piece.Color);
                    }
                    else if (piece.Type == PieceBaseModel.PieceType.Rook)
                    {
                        if (fromColumn == 0)
                        {
                            Parameters.DisableCastleQueenSide(piece.Color);
                        }
                        else if (fromColumn == 7)
                        {
                            Parameters.DisableCastleKingSide(piece.Color);
                        }
                    }
                }
            }
        }
Exemplo n.º 11
0
        /// <summary>
        ///		Busca la pieza de un color que se puede mover a una celda
        /// </summary>
        public (int row, int column, PieceBaseModel piece) SearchMoveTo(PieceBaseModel.PieceType type, PieceBaseModel.PieceColor color,
                                                                        int fromRow, int fromColumn, int toRow, int toColumn)
        {
            List <(int row, int column, PieceBaseModel piece)> pieces = new List <(int row, int column, PieceBaseModel piece)>();

            // Busca las piezas
            for (int row = 0; row < 8; row++)
            {
                for (int column = 0; column < 8; column++)
                {
                    PieceBaseModel piece = this[row, column];

                    if (piece != null && piece.Type == type && piece.Color == color &&
                        piece.CanMoveTo(this, row, column, toRow, toColumn))
                    {
                        pieces.Add((row, column, piece));
                    }
                }
            }
            // Si se le ha pasado una fila / columna para ajustarlo, obtiene la pieza que estaba inicialmente en esa posición
            if (pieces.Count > 1 && (fromRow != -1 || fromColumn != -1))
            {
                foreach ((int row, int column, PieceBaseModel piece)piece in pieces)
                {
                    if ((fromColumn == -1 && piece.row == fromRow) ||
                        (fromRow == -1 && piece.column == fromColumn) ||
                        (piece.row == fromRow && piece.column == fromColumn))
                    {
                        return(piece);
                    }
                }
            }
            // Devuelve la primera pieza localizada
            if (pieces.Count > 0)
            {
                return(pieces[0]);
            }
            else
            {
                return(-1, -1, null);
            }
        }
Exemplo n.º 12
0
 /// <summary>
 ///		Comprueba un movimiento al paso
 /// </summary>
 private void CheckEnPassantMove(PieceBaseModel piece, int fromRow, int toRow, int toColumn)
 {
     if (piece is PawnModel && Math.Abs(fromRow - toRow) == 2)
     {
         // Asigna la celda donde se coloca el peón que se puede capturar
         Parameters.EnPassantCell = new CellModel(toRow, toColumn);
         // Asigna la celda que se puede capturar al paso
         if (piece.Color == PieceBaseModel.PieceColor.White)
         {
             Parameters.EnPassantCellTarget = new CellModel(toRow + 1, toColumn);
         }
         else
         {
             Parameters.EnPassantCellTarget = new CellModel(toRow - 1, toColumn);
         }
         // Asigna el color que se puede capturar al paso
         Parameters.EnPassantColor = piece.Color;
     }
     else
     {
         Parameters.EnPassantCellTarget = null;
     }
 }
Exemplo n.º 13
0
 public PieceWithCellModel(PieceBaseModel piece, CellModel cell)
 {
     Piece = piece;
     Cell  = cell;
 }
Exemplo n.º 14
0
        /// <summary>
        ///		Comprueba si puede capturar una pieza
        /// </summary>
        internal bool CanCapture(PieceBaseModel piece, CellModel cell)
        {
            PieceBaseModel target = Pieces.GetPiece(cell);

            return(target != null && target.Color != piece.Color);
        }
Exemplo n.º 15
0
 /// <summary>
 ///		Comprueba si es una captura al paso
 /// </summary>
 public bool IsCaptureEnPassant(PieceBaseModel piece, int row, int column, PieceBaseModel target)
 {
     return(piece is PawnModel && target == null && Parameters.EnPassantCellTarget != null &&
            Parameters.EnPassantCellTarget.Row == row && Parameters.EnPassantCellTarget.Column == column &&
            Parameters.EnPassantColor != piece.Color);
 }
Exemplo n.º 16
0
        /// <summary>
        ///		Comprueba si puede capturar una pieza
        /// </summary>
        internal bool CanCapture(PieceBaseModel piece, int row, int column)
        {
            PieceBaseModel target = this[row, column];

            return(IsCaptureEnPassant(piece, row, column, target) || target != null && target.Color != piece.Color);
        }
Exemplo n.º 17
0
        /// <summary>
        ///		Comprueba si es legal colocar una pieza en una posición
        /// </summary>
        internal bool IsLegalMoveTo(PieceBaseModel piece, int row, int column)
        {
            PieceBaseModel target = this[row, column];

            return(target == null || target.Color != piece.Color);
        }