示例#1
0
        /// <summary>
        ///		Coloca la partida en un movimiento
        /// </summary>
        internal void GoToMovement(MovementFigureViewModel movementViewModel)
        {
            bool end = false;
            List <ActionBaseModel> actions = new List <ActionBaseModel>();

            // Limpia el tablero
            Reset();
            // Realiza los movimientos
            while (!end)
            {
                MovementFigureModel movement = GetNextMovement();

                if (movement == null)
                {
                    end = true;
                }
                else
                {
                    // Acumula las acciones
                    actions.AddRange(MakeMovement(movement));
                    // Si estamos en el movimiento buscado, terminamos
                    if (movementViewModel.Movement == ActualMovement || ActualMovementIndex >= ActualVariationGame.Movements.Count)
                    {
                        // Selecciona el movimiento en la lista
                        MovementsList.SelectMovement(ActualMovement);
                        // Indica que ha terminado
                        end = true;
                    }
                }
            }
            // Ejecuta las acciones
            RaiseEventShowMovements(actions, false);
        }
 public MovementFigureViewModel(MovementListViewModel movementListViewModel, MovementFigureModel movement, int movementIndex, int variationIndex)
 {
     // Inicializa las propiedades
     MovementListViewModel = movementListViewModel;
     VariationIndex        = variationIndex;
     Selected      = false;
     Piece         = movement.OriginPiece;
     Color         = movement.Color;
     MovementIndex = movementIndex;
     Movement      = movement;
     Text          = movement.Content;
     HasVariation  = movement.Variations.Count > 0;
     Time          = "01:07";
     // Añade las variaciones
     VariationsList = new MovementListSelectVariationViewModel(movement);
     // Añade los comentarios
     Remarks = new ObservableCollection <MovementRemarkViewModel>();
     foreach (string comment in movement.Comments)
     {
         Remarks.Add(new MovementRemarkViewModel(comment));
         RemarksText += comment + Environment.NewLine;
     }
     HasRemarks = Remarks.Count > 0;
     // Inicializa la forma en que se debe ver el movimiento en la lista (tamaños de fuente, tamaños de imagen...)
     AssignViewSizes(variationIndex);
     // Inicializa los comandos
     SelectMovementCommand = new Mvvm.BaseCommand(parameter => ExecuteMovement(), parameter => CanExecuteMovement());
 }
示例#3
0
        /// <summary>
        ///		Convierte un movimiento de pieza
        /// </summary>
        private MovementFigureModel ConvertPieceMovement(PieceMovementModel movement)
        {
            MovementFigureModel movementFigure = new MovementFigureModel(ConvertTurn(movement.Turn), movement.Content);

            // Convierte los datos básicos
            ConvertMovementBase(movement, movementFigure);
            // Añade las variaciones (antes de mover real)
            foreach (VariationModel variation in movement.Variations)
            {
                movementFigure.Variations.Add(ConvertVariation(variation, movementFigure));
            }
            // Convierte el color de la figura
            if (movement.Turn.Type == TurnModel.TurnType.White)
            {
                movementFigure.Color = PieceBaseModel.PieceColor.White;
            }
            else
            {
                movementFigure.Color = PieceBaseModel.PieceColor.Black;
            }
            // Convierte los datos de la notación SAN
            ConvertSan(movementFigure, movement.Content);
            // Devuelve el movimiento
            return(movementFigure);
        }
示例#4
0
        /// <summary>
        ///		Crea las acciones necesarias para deshacer un movimiento
        /// </summary>
        private List <ActionBaseModel> CreateUndoMoveActions(MovementFigureModel movement)
        {
            List <ActionBaseModel> actions = new List <ActionBaseModel>();

            // Deshace la promoción
            if (movement.PromotedPiece != null)
            {
                // Elimina la pieza promocionada
                actions.Add(CreateCaptureAction(movement.PromotedPiece ?? PieceBaseModel.PieceType.Queen, movement.Color, movement.To));
                // Crea de nuevo el peón en el mismo lugar que la pieza promocionada
                actions.Add(CreatePromoteAction(PieceBaseModel.PieceType.Pawn, movement.Color, movement.To));
            }
            // Deshace el movimiento
            actions.Add(CreateMoveAction(movement.OriginPiece, movement.Color, movement.To, movement.From));
            // Crea de nuevo la pieza capturada
            if (movement.Type == MovementFigureModel.MovementType.Capture)
            {
                if (movement.CapturedEnPassant != null)
                {
                    actions.Add(CreatePromoteAction(movement.Captured.Type, movement.Captured.Color, movement.CapturedEnPassant));
                }
                else
                {
                    actions.Add(CreatePromoteAction(movement.Captured.Type, movement.Captured.Color, movement.To));
                }
            }
            // Devuelve las accioens
            return(actions);
        }
示例#5
0
        /// <summary>
        ///		Obtiene el siguiente movimiento (hacia atrás o hacia delante)
        /// </summary>
        internal MovementFigureModel GetMovement(bool back)
        {
            MovementFigureModel movement = null;

            // Obtiene el movimiento
            if (back)
            {
                if (_actualMovementIndex > 0)
                {
                    movement = FigureMovements[--_actualMovementIndex];
                }
            }
            else
            {
                if (_actualMovementIndex < FigureMovements.Count)
                {
                    movement = FigureMovements[_actualMovementIndex];
                    _actualMovementIndex++;
                }
            }
            // Selecciona el movimiento
            if (movement != null)
            {
                SelectMovement(_actualMovementIndex);
            }
            // Devuelve el movimiento
            return(movement);
        }
示例#6
0
        /// <summary>
        ///		Realiza un movimiento
        /// </summary>
        public bool Move(MovementFigureModel movement)
        {
            bool canMove = false;

            // Dependiendo del tipo de movimiento
            switch (movement.Type)
            {
            case MovementFigureModel.MovementType.CastleKingSide:
                canMove = MoveCastleKingSide(movement.Color);
                break;

            case MovementFigureModel.MovementType.CastleQueenSide:
                canMove = MoveCastleQueenSide(movement.Color);
                break;

            default:
                canMove = Move(movement.From.Row, movement.From.Column, movement.To.Row, movement.To.Column);
                break;
            }
            // Promociona la pieza
            if (canMove && movement.PromotedPiece != null)
            {
                canMove = Promote(movement.To.Row, movement.To.Column, movement.PromotedPiece ?? PieceBaseModel.PieceType.Pawn);
            }
            // Devuelve el valor que indica si se puede hacer un movimiento
            return(canMove);
        }
示例#7
0
        /// <summary>
        ///		Realiza un movimiento
        /// </summary>
        private List <ActionBaseModel> MakeMovement(MovementFigureModel movement)
        {
            List <ActionBaseModel> actions = new ActionFactory().Create(movement);

            // Guarda el movimiento actual
            ActualMovement = movement;
            // Ejecuta el movimiento sobre el tablero
            Board.Move(movement);
            // Devuelve las acciones
            return(actions);
        }
示例#8
0
        /// <summary>
        ///		Realiza el siguiente movimiento
        /// </summary>
        private void GoNextMovement()
        {
            MovementFigureModel movement = GetNextMovement();

            // Realiza el movimiento
            if (movement != null)
            {
                // Ejecuta el movimiento
                RaiseEventShowMovements(MakeMovement(movement), MainViewModel.MustShowAnimation);
                // Lo muestra en la lista
                MovementsList.SelectMovement(movement);
            }
        }
 public MovementSelectVariationViewModel(GameBoardViewModel gameBoardViewModel, MovementVariationModel variation, MovementFigureModel movement)
 {
     // Inicializa los objetos
     GameBoardViewModel = gameBoardViewModel;
     Movement           = movement;
     Variation          = variation;
     // Inicializa las propiedades
     Piece = movement.OriginPiece;
     Color = movement.Color;
     Text  = movement.Content;
     // Inicializa los comandos
     SelectMovementCommand = new Mvvm.BaseCommand(parameter => ExecuteMovement(), parameter => CanExecuteMovement());
 }
示例#10
0
        /// <summary>
        ///		Realiza el movimiento de la figura
        /// </summary>
        private void MakeMove(MovementFigureModel movement)
        {
            //// Debug
            //#if DEBUG
            //	System.Diagnostics.Debug.WriteLine($"Movement: {movement}");
            //#endif
            // Realiza los movimientos
            switch (movement.Type)
            {
            case MovementFigureModel.MovementType.CastleKingSide:
                if (!Board.CanMoveCastleKingSide(movement.Color))
                {
                    throw new LibChessGame.Models.Exceptions.GameReaderException($"Error at movement castle king side {movement.Content}");
                }
                else
                {
                    Board.MoveCastleKingSide(movement.Color);
                }
                break;

            case MovementFigureModel.MovementType.CastleQueenSide:
                if (!Board.CanMoveCastleQueenSide(movement.Color))
                {
                    throw new LibChessGame.Models.Exceptions.GameReaderException($"Error at movement castle queen side {movement.Content}");
                }
                else
                {
                    Board.MoveCastleQueenSide(movement.Color);
                }
                break;

            case MovementFigureModel.MovementType.CaptureEnPassant:
                throw new NotImplementedException("Cant do EnPassant capture");

            default:
                if (!Board.CanMove(movement.From.Row, movement.From.Column, movement.To.Row, movement.To.Column))
                {
                    throw new LibChessGame.Models.Exceptions.GameReaderException($"Error at movement {movement.Content}");
                }
                else
                {
                    Board.Move(movement);
                }
                break;
            }
            //// Debug
            //#if DEBUG
            //	System.Diagnostics.Debug.WriteLine(Board.GetText());
            //	System.Diagnostics.Debug.WriteLine(new string('-', 80));
            //#endif
        }
示例#11
0
        /// <summary>
        ///		Obtiene el icono asociado a un <see cref="MovementFigureModel"/>
        /// </summary>
        private string GetIcon(MovementFigureModel movement)
        {
            string nameColor = "";
            string namePiece = "";

            // Obtiene el nombre del color
            if (movement.Color == PieceBaseModel.PieceColor.White)
            {
                nameColor = "White";
            }
            else
            {
                nameColor = "Black";
            }
            // Obtiene el nombre de la pieza
            switch (movement.OriginPiece)
            {
            case PieceBaseModel.PieceType.Pawn:
                namePiece = "Pawn";
                break;

            case PieceBaseModel.PieceType.Rook:
                namePiece = "Rook";
                break;

            case PieceBaseModel.PieceType.Knight:
                namePiece = "Knight";
                break;

            case PieceBaseModel.PieceType.Bishop:
                namePiece = "Bishop";
                break;

            case PieceBaseModel.PieceType.Queen:
                namePiece = "Queen";
                break;

            case PieceBaseModel.PieceType.King:
                namePiece = "King";
                break;
            }
            // Obtiene el nombre de la imagen
            if (!string.IsNullOrEmpty(nameColor) && !string.IsNullOrEmpty(namePiece))
            {
                return($"/BauChessViewer;component/Resources/Images/{namePiece}{nameColor}.gif");
            }
            else
            {
                return(null);
            }
        }
示例#12
0
        /// <summary>
        ///		Deshace un movimiento
        /// </summary>
        private void UndoMovement(MovementFigureModel movement, bool raiseActions)
        {
            List <ActionBaseModel> actions = new ActionFactory().CreateUndo(movement);

            // Guarda el movimiento actual
            IsMoving = true;
            // Lanza las acciones
            if (raiseActions)
            {
                RaiseEventShowMovements(actions, MainViewModel.MustShowAnimation);
            }
            // Ejecuta el movimiento sobre el tablero
            Board.Undo(movement);
        }
示例#13
0
 /// <summary>
 ///		Deshace el movimiento
 /// </summary>
 private void UndoMove(MovementFigureModel movement)
 {
     // Deshace la promoción
     if (movement.PromotedPiece != null)
     {
         this[movement.To] = new PawnModel(movement.Color);
     }
     // Deshace el movimiento
     MoveWithoutCheck(movement.To.Row, movement.To.Column, movement.From.Row, movement.From.Column, false);
     // Deshace la captura
     if (movement.Captured != null)
     {
         CreatePiece(movement.Captured.Type, movement.Captured.Color);
     }
     //? Debería cambiar los parámetros de movimiento de la figura
 }
示例#14
0
 /// <summary>
 ///		Crea los movimientos hasta una variación
 /// </summary>
 internal void GoToVariation(MovementVariationModel variation, MovementFigureModel movement)
 {
     if (variation != null && movement != null)
     {
         // Cambia la variación actual y guarda el movimiento de la variación
         ActualVariationGame = VariationGame.CloneTo(null, variation, movement);
         VariationMovement   = variation.Parent as MovementFigureModel;
         // y carga la lista
         LoadListViewMovements(ActualVariationGame.Movements);
         // Selecciona el movimiento en la lista y mueve
         MovementsList.SelectMovement(movement);
         GoToMovement(MovementsList.ActualMovement);
         // Indica que está en una variación
         IsAtVariation = true;
     }
 }
        /// <summary>
        ///		Añade un movimiento a la lista
        /// </summary>
        private MovementFigureModel ParseMovement(GameBoardModel board, PieceBaseModel.PieceColor actualColor, Move move)
        {
            MovementFigureModel newMovement   = new MovementFigureModel();
            CellConversor       cellConversor = new CellConversor();

            // Asigna los datos
            newMovement.Color         = actualColor;
            newMovement.Type          = ConvertMovement(move.Type);
            newMovement.Text          = move.ToString();
            newMovement.IsCheck       = move.IsCheck ?? false;
            newMovement.IsDoubleCheck = move.IsDoubleCheck ?? false;
            newMovement.IsCheckMate   = move.IsCheckMate ?? false;
            switch (newMovement.Type)
            {
            case MovementFigureModel.MovementType.CastleKingSide:
            case MovementFigureModel.MovementType.CastleQueenSide:
                // Asigna la pieza de origen
                newMovement.OriginPiece = PieceBaseModel.PieceType.Rook;
                // Crea las acciones de enroque
                newMovement.Actions.CreateCastleKingActions(board, newMovement);
                break;

            default:
                PieceBaseModel.PieceType?targetPiece = null;

                // Asigna los datos
                newMovement.OriginPiece = ConvertPiece(move.Piece);
                targetPiece             = ConvertPiece(move.TargetPiece);
                // Añade la pieza promocionada
                if (move.PromotedPiece != null)
                {
                    newMovement.PromotedPiece = ConvertPiece(move.PromotedPiece);
                }
                // Crea las acciones
                newMovement.Actions.CreateActions(board, newMovement,
                                                  cellConversor.ConvertCell(move.TargetSquare.Rank, move.TargetSquare.File),
                                                  cellConversor.ConvertCell(move.OriginRank, move.OriginFile),
                                                  targetPiece);
                break;
            }
            newMovement.Annotation = ConvertAnnotation(move.Annotation);
            // Ejecuta los movimientos sobre el tablero
            board.Execute(newMovement);
            // Devuelve el movimiento
            return(newMovement);
        }
示例#16
0
        /// <summary>
        ///		Deshace un movimiento
        /// </summary>
        public void Undo(MovementFigureModel movement)
        {
            switch (movement.Type)
            {
            case MovementFigureModel.MovementType.CastleKingSide:
                UndoCastleKingSide(movement.Color);
                break;

            case MovementFigureModel.MovementType.CastleQueenSide:
                UndoCastleQueenSide(movement.Color);
                break;

            default:
                UndoMove(movement);
                break;
            }
        }
示例#17
0
        /// <summary>
        ///		Muestra el movimiento siguiente / anterior
        /// </summary>
        private void ShowMovement(bool back, bool showAnimation)
        {
            if (ChessGameViewModel.ChessGame != null)
            {
                MovementFigureModel movement = ChessGameViewModel.GetMovement(back);

                // Limpia el panel
                ClearMovementPanel();
                // Obtiene el siguiente movimiento
                if (ChessGameViewModel.MovementsList.ActualMovement != null)
                {
                    lblMovement.Text   = ChessGameViewModel.MovementsList.ActualMovement.Text;
                    imgMovement.Source = udtBoard.LoadImage(ChessGameViewModel.MovementsList.ActualMovement.Color,
                                                            ChessGameViewModel.MovementsList.ActualMovement.Piece);
                    udtBoard.ShowMovement(movement, back, showAnimation);
                }
            }
        }
示例#18
0
 public MovementFigureViewModel(PgnGameViewModel pgnGameViewModel, MovementFigureModel movement, int movementIndex, int variationIndex)
 {
     // Inicializa las propiedades
     PgnGameViewModel = pgnGameViewModel;
     VariationIndex   = variationIndex;
     Selected         = false;
     Piece            = movement.OriginPiece;
     Color            = movement.Color;
     MovementIndex    = movementIndex;
     Movement         = movement;
     Text             = movement.Text;
     HasVariation     = movement.Variation != null;
     Time             = "01:07";
     // Inicializa la forma en que se debe ver el movimiento en la lista (tamaños de fuente, tamaños de imagen...)
     AssignViewSizes(variationIndex, Selected);
     // Inicializa los comandos
     SelectMovementCommand = new BaseCommand(parameter => ExecuteMovement(), parameter => CanExecuteMovement());
 }
示例#19
0
        /// <summary>
        ///		Crea las acciones de enroque
        /// </summary>
        private List <ActionBaseModel> CreateCastleKingActions(MovementFigureModel movement)
        {
            List <ActionBaseModel> actions = new List <ActionBaseModel>();
            int row = movement.Color == PieceBaseModel.PieceColor.White ? 7 : 0;

            // Enroque
            if (movement.Type == MovementFigureModel.MovementType.CastleKingSide)                     // enroque corto
            {
                actions.Add(CreateMoveAction(PieceBaseModel.PieceType.Rook, movement.Color, new CellModel(row, 7), new CellModel(row, 5)));
                actions.Add(CreateMoveAction(PieceBaseModel.PieceType.King, movement.Color, new CellModel(row, 4), new CellModel(row, 6)));
            }
            else                     // enroque largo
            {
                actions.Add(CreateMoveAction(PieceBaseModel.PieceType.Rook, movement.Color, new CellModel(row, 0), new CellModel(row, 3)));
                actions.Add(CreateMoveAction(PieceBaseModel.PieceType.King, movement.Color, new CellModel(row, 4), new CellModel(row, 2)));
            }
            // Devuelve las acciones
            return(actions);
        }
示例#20
0
        /// <summary>
        ///		Crea una lista de acciones para deshacer un movimiento
        /// </summary>
        public List <ActionBaseModel> CreateUndo(MovementFigureModel movement)
        {
            List <ActionBaseModel> actions = new List <ActionBaseModel>();

            // Añade las acciones
            switch (movement.Type)
            {
            case MovementFigureModel.MovementType.CastleKingSide:
            case MovementFigureModel.MovementType.CastleQueenSide:
                actions.AddRange(CreateUndoCastleKingActions(movement));
                break;

            default:
                actions.AddRange(CreateUndoMoveActions(movement));
                break;
            }
            // Devuelve las acciones
            return(actions);
        }
示例#21
0
        /// <summary>
        ///		Realiza los movimientos asociados a una serie de acciones
        /// </summary>
        internal void Execute(MovementFigureModel movement)
        {
            foreach (ActionBaseModel action in movement.Actions)
            {
                switch (action)
                {
                case ActionMoveModel child:
                    Move(child);
                    break;

                case ActionCaptureModel child:
                    Capture(child);
                    break;

                case ActionPromoteModel child:
                    Promote(child);
                    break;
                }
            }
        }
示例#22
0
        /// <summary>
        ///		Crea una lista de acciones basada en un movimiento
        /// </summary>
        public List <ActionBaseModel> Create(MovementFigureModel movement)
        {
            List <ActionBaseModel> actions = new List <ActionBaseModel>();

            // Añade las acciones
            switch (movement.Type)
            {
            case MovementFigureModel.MovementType.CastleKingSide:
            case MovementFigureModel.MovementType.CastleQueenSide:
                actions.AddRange(CreateCastleKingActions(movement));
                break;

            default:
                // Crea el movimiento
                actions.Add(CreateMoveAction(movement.OriginPiece, movement.Color, movement.From, movement.To));
                // Añade la captura
                if (movement.Type == MovementFigureModel.MovementType.Capture)
                {
                    if (movement.CapturedEnPassant != null)
                    {
                        actions.Add(CreateCaptureAction(movement.Captured.Type, movement.Captured.Color, movement.CapturedEnPassant));
                    }
                    else
                    {
                        actions.Add(CreateCaptureAction(movement.Captured.Type, movement.Captured.Color, movement.To));
                    }
                }
                // Crea la promoción
                if (movement.PromotedPiece != null)
                {
                    // Elimina el peón
                    actions.Add(CreateCaptureAction(PieceBaseModel.PieceType.Pawn, movement.Color, movement.To));
                    // Crea la promoción
                    actions.Add(CreatePromoteAction(movement.PromotedPiece ?? PieceBaseModel.PieceType.Queen, movement.Color, movement.To));
                }
                break;
            }
            // Devuelve las acciones
            return(actions);
        }
示例#23
0
        /// <summary>
        ///		Busca la pieza de un color que se pueden mover a una celda
        /// </summary>
        internal PieceBaseModel SearchMoveTo(MovementFigureModel movement, CellModel target, CellModel origin)
        {
            List <PieceBaseModel> pieces = new List <PieceBaseModel>();

            // Busca las piezas
            foreach (PieceBaseModel piece in Pieces)
            {
                if (piece.Type == movement.OriginPiece && piece.Color == movement.Color &&
                    piece.CanMoveTo(this, target, movement.Type))
                {
                    pieces.Add(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)
            {
                if (origin != null && (origin.Row != -1 || origin.Column != -1))
                {
                    foreach (PieceBaseModel piece in pieces)
                    {
                        if ((origin.Column == -1 && piece.Cell.Row == origin.Row) ||
                            (origin.Row == -1 && piece.Cell.Column == origin.Column) ||
                            (piece.Cell.Row == origin.Row && piece.Cell.Column == origin.Column))
                        {
                            return(piece);
                        }
                    }
                }
            }
            // Devuelve la primera pieza localizada
            if (pieces.Count > 0)
            {
                return(pieces[0]);
            }
            else
            {
                return(null);
            }
        }
示例#24
0
 /// <summary>
 ///		Selecciona un movimiento en la lista
 /// </summary>
 internal void SelectMovement(MovementFigureModel movement)
 {
     if (movement == null)
     {
         SelectedMovement = null;
         ActualMovement   = null;
     }
     else
     {
         foreach (BaseMovementViewModel baseMovement in Movements)
         {
             if (baseMovement is MovementFigureDoubleViewModel movementDouble)
             {
                 // Selecciona el movimiento blanco
                 if (movementDouble.WhiteMovement != null)
                 {
                     movementDouble.WhiteMovement.Selected = movementDouble.WhiteMovement.Movement.Id == movement.Id;
                     if (movementDouble.WhiteMovement.Selected)
                     {
                         SelectedMovement = movementDouble;
                         ActualMovement   = movementDouble.WhiteMovement;
                     }
                 }
                 // Selecciona el movimiento negro
                 if (movementDouble.BlackMovement != null)
                 {
                     movementDouble.BlackMovement.Selected = movementDouble.BlackMovement.Movement.Id == movement.Id;
                     if (movementDouble.BlackMovement.Selected)
                     {
                         SelectedMovement = movementDouble;
                         ActualMovement   = movementDouble.BlackMovement;
                     }
                 }
             }
         }
     }
 }
示例#25
0
 /// <summary>
 ///		Crea un movimiento de una variación
 /// </summary>
 private MovementFigureVariationDoubleViewModel CreateRecursiveMovement(MovementFigureVariationDoubleViewModel lastMovement,
                                                                        MovementFigureModel move, int movementIndex, int movementLineIndex,
                                                                        int variationIndex)
 {
     // Si es necesario, crea un nuevo movimiento
     if (lastMovement == null)
     {
         lastMovement = new MovementFigureVariationDoubleViewModel(movementIndex, movementLineIndex, variationIndex);
         Movements.Add(lastMovement);
     }
     // Asigna el movimiento de blancas / negras
     if (move.Color == Bau.Libraries.LibChessGame.Board.Pieces.PieceBaseModel.PieceColor.White)
     {
         // Asigna el movimiento de blancas
         lastMovement.WhiteMovement = new MovementFigureViewModel(PgnGameViewModel, move, movementIndex, variationIndex);
         // Carga la variación
         if (MustShowVariations(move))
         {
             LoadVariationMovements(move.Variation, movementIndex, movementLineIndex, variationIndex + 1);
             lastMovement = null;
         }
     }
     else             // Asigna el movimiento de negras
     {
         // Asigna el movimiento de negras
         lastMovement.BlackMovement = new MovementFigureViewModel(PgnGameViewModel, move, movementIndex, variationIndex);
         // Carga la variación
         if (MustShowVariations(move))
         {
             LoadVariationMovements(move.Variation, movementIndex, movementLineIndex, variationIndex + 1);
         }
         lastMovement = null;
     }
     // Devuelve el último movimiento añadido a la lista
     return(lastMovement);
 }
        public MovementListSelectVariationViewModel(GameBoardViewModel gameBoardViewModel, MovementFigureModel movement)
        {
            // Crea la colección
            Variations = new ObservableCollection <MovementSelectVariationViewModel>();
            // Añade las variaciones que se pueden seleccionar
            foreach (MovementVariationModel variation in movement.Variations)
            {
                bool isAdded = false;

                // Añade el primer movimiento de figura de la variación
                foreach (MovementBaseModel movementVariation in variation.Movements)
                {
                    if (!isAdded && movementVariation is MovementFigureModel movementFigure)
                    {
                        // Añade la variación
                        Variations.Add(new MovementSelectVariationViewModel(gameBoardViewModel, variation, movementFigure));
                        // Indica que se ha añadido
                        isAdded = true;
                    }
                }
            }
        }
示例#27
0
        /// <summary>
        ///		Extrae la celda origen del movimiento
        /// </summary>
        /// <remarks>
        /// Disambiguation
        /// In the case of ambiguities (multiple pieces of the same type moving to the same square), the first appropriate
        /// disambiguating step of the three following steps is taken:
        /// First, if the moving pieces can be distinguished by their originating files, the originating file letter of the
        /// moving piece is inserted immediately after the moving piece letter.
        /// Second (when the first step fails), if the moving pieces can be distinguished by their originating ranks, the
        /// originating rank digit of the moving piece is inserted immediately after the moving piece letter.
        /// Third (when both the first and the second steps fail), the two character square coordinate of the originating
        /// square of the moving piece is inserted immediately after the moving piece letter.
        /// </remarks>
        /// <example>
        /// cxb5 axb5 dxe5 Bxe7 Qxe7 Nxc4 Bxc4 Nb6 Rxe1+
        /// </example>
        private void ExtractCellsInfo(MovementFigureModel movement, ref string content)
        {
            string cellStart = string.Empty, cellEnd = string.Empty;

            // Captura
            if (content.StartsWith("x", StringComparison.CurrentCultureIgnoreCase))
            {
                movement.Type = MovementFigureModel.MovementType.Capture;
                content       = content.Substring(1);
            }
            // Obtiene los datos de la celda de inicio
            cellStart = ExtractCell(ref content);
            // Captura
            if (content.StartsWith("x", StringComparison.CurrentCultureIgnoreCase))
            {
                // Indica que es una captura (y ya ha habido información de celda)
                movement.Type = MovementFigureModel.MovementType.Capture;
                content       = content.Substring(1);
                // Obtiene los datos de la celda de fin
                if (!string.IsNullOrWhiteSpace(content))
                {
                    cellEnd = ExtractCell(ref content);
                }
            }
            // Interpreta el movimiento
            if (string.IsNullOrWhiteSpace(cellStart) && string.IsNullOrWhiteSpace(cellEnd))
            {
                throw new LibChessGame.Models.Exceptions.GameReaderException($"Cant get movement from {movement.Content}");
            }
            else
            {
                (CellModel from, CellModel to) = GetChoords(cellStart, cellEnd);
                (int row, int column, PieceBaseModel piece)pieceCell = Board.SearchMoveTo(movement.OriginPiece, movement.Color, from.Row,
                                                                                          from.Column, to.Row, to.Column);

                // Asigna los datos del movimiento
                if (pieceCell.piece == null)
                {
                    throw new LibChessGame.Models.Exceptions.GameReaderException($"Cant find who moves to {movement.Content}");
                }
                else
                {
                    // Asigna el movimiento de inicio y fin
                    movement.From = new CellModel(pieceCell.row, pieceCell.column);
                    movement.To   = to;
                    // Asigna la pieza capturada
                    if (movement.Type == MovementFigureModel.MovementType.Capture)
                    {
                        if (Board.IsCaptureEnPassant(Board[movement.From], movement.To.Row, movement.To.Column, Board[movement.To]))
                        {
                            movement.Captured          = new PawnModel(Board.Parameters.EnPassantColor);
                            movement.CapturedEnPassant = new CellModel(Board.Parameters.EnPassantCell);
                        }
                        else
                        {
                            movement.Captured = Board[movement.To];
                        }
                    }
                }
            }
        }
示例#28
0
 /// <summary>
 ///		Obtiene los datos de la notación SAN
 /// </summary>
 private void ConvertSan(MovementFigureModel movement, string content)
 {
     //// Debug
     //#if DEBUG
     //	System.Diagnostics.Debug.WriteLine($"Start convert SAN: {content}");
     //#endif
     // Tipo de movimiento
     movement.Type = MovementFigureModel.MovementType.Normal;
     // Obtiene la información básica del movimiento
     if (content == "0-0" || content == "O-O")
     {
         // Datos de la pieza
         movement.OriginPiece = PieceBaseModel.PieceType.King;
         movement.Type        = MovementFigureModel.MovementType.CastleKingSide;
         // Quita los datos del contenido
         if (content.Length == 3)
         {
             content = string.Empty;
         }
         else
         {
             content = content.Substring(3);
         }
     }
     else if (content == "0-0-0" || content == "O-O-O")
     {
         // Datos de la pieza
         movement.OriginPiece = PieceBaseModel.PieceType.King;
         movement.Type        = MovementFigureModel.MovementType.CastleQueenSide;
         // Quita los datos del contenido
         if (content.Length == 5)
         {
             content = string.Empty;
         }
         else
         {
             content = content.Substring(5);
         }
     }
     else
     {
         // Obtiene la pieza
         movement.OriginPiece = ExtractPiece(ref content);
         // Obtiene la información de las celdas origen y destino
         ExtractCellsInfo(movement, ref content);
     }
     // Obtiene la información adicional
     if (!string.IsNullOrWhiteSpace(content))
     {
         // Promociones, jaque, jaque mate
         if (content.StartsWith("="))                 // promoción
         {
             content = content.Substring(1);
             movement.PromotedPiece = ExtractPiece(ref content);
         }
         else if (content.StartsWith("(=)"))                 // el jugador ofrece tablas (algunos archivos)
         {
             content = content.Substring(3);
             movement.IsDrawOffered = true;
         }
         else if (content.StartsWith("++"))                 // jaque mate en algunos archivos
         {
             content = content.Substring(2);
             movement.IsCheckMate = true;
         }
         else if (content.StartsWith("+"))                 // jaque
         {
             content          = content.Substring(1);
             movement.IsCheck = true;
         }
         else if (content.StartsWith("#"))                 // jaque mate
         {
             content = content.Substring(1);
             movement.IsCheckMate = true;
         }
         // Anotaciones
         if (!string.IsNullOrWhiteSpace(content))
         {
             movement.Info.Add(new MovementInfoModel(content));
         }
     }
     // Y por último realiza el movimiento
     MakeMove(movement);
 }
        /// <summary>
        ///		Muestra un movimiento
        /// </summary>
        internal void ShowMovement(MovementFigureModel movement, bool backMovement, bool showAnimation)
        {
            if (movement != null)
            {
                List <ActionViewMovement> actions = new List <ActionViewMovement>();

                // Recorre las acciones del movimiento hacia delante o hacia atrás
                if (!backMovement)
                {
                    foreach (ActionBaseModel action in movement.Actions)
                    {
                        switch (action)
                        {
                        case ActionMoveModel move:
                            actions.Add(GetActionMovePiece(move));
                            break;

                        case ActionCaptureModel move:
                            actions.Add(GetActionCapturePiece(move));
                            break;

                        case ActionPromoteModel move:
                            actions.Add(GetActionPromotePiece(move));
                            break;
                        }
                    }
                }
                else
                {
                    for (int index = movement.Actions.Count - 1; index >= 0; index--)
                    {
                        switch (movement.Actions[index])
                        {
                        case ActionMoveModel move:
                            actions.Add(GetActionUndoMovePiece(move));
                            break;

                        case ActionCaptureModel move:
                            actions.Add(GetActionUndoCapturePiece(move));
                            break;

                        case ActionPromoteModel move:
                            actions.Add(GetActionUndoPromotePiece(move));
                            break;
                        }
                    }
                }
                // Muestra las animaciones o ejecuta las acciones
                if (showAnimation && ViewModel.MustShowAnimation)
                {
                    Storyboard storyBoard = CreateAnimations(actions);

                    // ... y las muestra
                    if (storyBoard.Children.Count > 0)
                    {
                        // Indica que se está realizando un movimiento
                        CanMove = false;
                        // Asigna el evento de fin de animación
                        storyBoard.Completed += (sender, evntArgs) =>
                        {
                            // Ejecuta las acciones
                            ExecuteActions(actions);
                            // Indica que se ha finalizado el movimiento
                            CanMove = true;
                        };
                        // Comienza la animación
                        storyBoard.Begin();
                    }
                    else
                    {
                        ExecuteActions(actions);
                    }
                }
                else                         // Ejecuta directamente las acciones sobre el tablero
                {
                    ExecuteActions(actions);
                }
            }
        }
        /// <summary>
        ///		Interpreta los movimientos
        /// </summary>
        private MovementModelCollection ParseMovements(VariationModel variation, MoveTextEntryList moveEntryList)
        {
            MovementModelCollection movements = new MovementModelCollection();

            PieceBaseModel.PieceColor actualColor    = PieceBaseModel.PieceColor.White;
            PieceBaseModelCollection  previousPieces = new PieceBaseModelCollection();

            // Inicializa el tablero
            variation.GameBoard.Reset();
            // Cambia el color inicial
            if (variation.Setup.HasSetup && !variation.Setup.IsWhiteMove)
            {
                actualColor = PieceBaseModel.PieceColor.Black;
            }
            // Interpreta la lista de movimientos
            try
            {
                foreach (MoveTextEntry moveEntry in moveEntryList)
                {
                    switch (moveEntry)
                    {
                    case RAVEntry rav:
                        MovementFigureModel lastMovement = movements.SearchLastPieceMovement();

                        if (lastMovement != null)
                        {
                            lastMovement.Variation = CreateVariation(actualColor, previousPieces, rav);
                        }
                        break;

                    case NAGEntry nag:
                        System.Diagnostics.Debug.WriteLine(moveEntry.GetType().ToString());
                        break;

                    case CommentEntry comment:
                        movements.Add(new MovementRemarksModel(comment.Comment));
                        break;

                    case MovePairEntry movement:
                        // Añade el movimiento de blancas
                        movements.Add(ParseMovement(variation.GameBoard, actualColor, (moveEntry as MovePairEntry).White));
                        actualColor = GetNextColor(actualColor);
                        // Clona la lista de piezas hasta el movimiento anterior
                        previousPieces = variation.GameBoard.Pieces.Clone();
                        // Añade el movimiento de negras
                        movements.Add(ParseMovement(variation.GameBoard, actualColor, (moveEntry as MovePairEntry).Black));
                        actualColor = GetNextColor(actualColor);
                        break;

                    case HalfMoveEntry movement:
                        // Clona la lista de piezas hasta el movimiento anterior
                        previousPieces = variation.GameBoard.Pieces.Clone();
                        // Añade el movimiento actual
                        movements.Add(ParseMovement(variation.GameBoard, actualColor, (moveEntry as HalfMoveEntry).Move));
                        actualColor = GetNextColor(actualColor);
                        break;

                    case GameEndEntry movement:
                        movements.Add(new MovementGameEndModel(ConvertResult(movement.Result)));
                        break;

                    default:
                        System.Diagnostics.Debug.WriteLine(moveEntry.GetType().ToString());
                        break;
                    }
                }
            }
            catch (Exception exception)
            {
                variation.ParseError = exception.Message;
            }
            // Devuelve la colección de movimientos
            return(movements);
        }