Exemple #1
0
        public ChessBoardCell GetRelativeCell(ChessBoardCell baseCell, ChessCellOffset offset)
        {
            int newRowIndex    = baseCell.RowIndex + offset.VerticalOffset;
            int newColumnIndex = baseCell.ColumnIndex + offset.HorizontalOffset;

            return(this[newRowIndex, newColumnIndex]);
        }
Exemple #2
0
        internal void MovePiece(string from, string to)
        {
            ChessBoardCell fromCell = Game.Board[from];
            ChessBoardCell toCell   = Game.Board[to];

            if (fromCell.PieceInCell != null)
            {
                if (this.Equals(fromCell.PieceInCell.Player))
                {
                    ChessMove move = ChessMove.CreateStandardChessMove(fromCell, toCell);
                    RequestMovement(move);
                }
                else
                {
                    throw new ChessExceptionInvalidGameAction(ExceptionCode.AttemptToMoveOtherPlayerPiece, "Piece does not belong to this player: " +
                                                              fromCell.PieceInCell.ToString() +
                                                              fromCell.ToString() +
                                                              "["
                                                              +
                                                              (fromCell.PieceInCell.Color == ChessColor.ChessColor_Black ? "B" : "W")
                                                              +
                                                              "]");
                }
            }
            else
            {
                throw new ChessExceptionInvalidGameAction(ExceptionCode.InvalidMovement, "Cell is empty: " + from);
            }
        }
Exemple #3
0
        private void CalcularMovimientosComoPeon()
        {
            ChessCellOffset[] moves = ChessCellOffset.GetPawnMoveSet(Color);

            for (int i = 0; i < moves.Count(); i++)
            {
                ChessBoardCell nextCell = Board.GetRelativeCell(BoardPosition, moves[i]);
                if (nextCell != null)
                {
                    if (i < 2) //2 first movements cannot capture pieces
                    {
                        if (nextCell.PieceInCell == null)
                        {
                            posibleMovements.Add(nextCell);
                        }
                    }
                    else
                    {
                        if (nextCell.PieceInCell != null && nextCell.PieceInCell.Color != Color)
                        {
                            posibleMovements.Add(nextCell);
                        }
                    }
                }
            }
        }
Exemple #4
0
 private ChessMove(MoveType type, ChessPiece piece, ChessBoardCell toCell, ChessPieceType promoteTo, PGNMarkersFlags pgnMarkers)
 {
     Type       = type;
     PGNMarkers = pgnMarkers;
     if (Type == MoveType.StandardMove)
     {
         Origin    = piece.BoardPosition;
         Destiny   = toCell;
         PromoteTo = promoteTo;
     }
     else
     {
         Origin  = null;
         Destiny = null;
     }
 }
Exemple #5
0
        public void MovePiece(ChessPiece piece, byte rowIndex, byte colIndex)
        {
            try
            {
                //remove the piece from its original position
                ChessBoardCell originalPosition = piece.BoardPosition;
                originalPosition.PieceInCell = null;

                //Obtain the new position
                ChessBoardCell cell = this[rowIndex, colIndex];
                if (cell != null)
                {
                    //Check if the new position capture a piece.
                    if (cell.PieceInCell != null)
                    {
                        if (cell.PieceInCell.Color != piece.Color)
                        {
                            //Capture the other piece
                            ChessPiece capturedPiece = cell.PieceInCell;
                            CapturedPieces.Add(capturedPiece);

                            //Player Expected Action: The player remove the piece of his active piece list.
                            //Piece Expected Action: Update its internal position record.
                            OnNewPieceCaptured?.Invoke(this, new PieceCapturedEventArgs(capturedPiece));

                            //Remove the captured piece from board.
                            cell.PieceInCell = null;
                        }
                        else
                        {
                            throw new ChessExceptionInvalidGameAction(ExceptionCode.InvalidAttemptToCapturePiece, "The piece that you are trying to capture has the same color than the moved piece");
                        }
                    }

                    cell.PieceInCell    = piece;
                    piece.BoardPosition = cell;
                }
            }
            catch (Exception)
            {
                throw new ChessExceptionInvalidGameAction(ExceptionCode.InvalidCellIndexes, "Row Index: " + rowIndex + ", Col Index: " + colIndex);
            }
        }
Exemple #6
0
        public ChessPiece InsertPieceInBoard(ChessPiece piece, string algebraicPosition)
        {
            ChessBoardCell cell = this[algebraicPosition];

            if (cell != null)
            {
                //Add the piece to the board
                cell.PieceInCell = piece;
                piece.Board      = this;
                //Piece Expected Action: Update its internal fields.
                //                       Initial Position, CurrentPosition
                OnNewPieceInserted?.Invoke(this, new PieceInsertedEventArgs(piece, cell));
                return(piece);
            }
            else
            {
                throw new ChessExceptionInvalidGameAction(ExceptionCode.InvalidInitialPiecePosition, algebraicPosition);
            }
        }
Exemple #7
0
        public ChessBoard()
        {
            boardCells = new ChessBoardCell[8, 8];

            Parallel.For(0, 8, (row) =>
            {
                for (byte column = 0; column < 8; column++)
                {
                    ChessBoardCell cell     = new ChessBoardCell();
                    cell.Board              = this;
                    cell.RowIndex           = (byte)(row);
                    cell.ColumnIndex        = (byte)(column);
                    boardCells[row, column] = cell;
                }
            });


            CapturedPieces = new List <ChessPiece>();
        }
Exemple #8
0
        public void MovePiece(ChessPiece piece, ChessBoardCell toCell)
        {
            ChessMove move = ChessMove.CreateStandardChessMove(piece, toCell);

            RequestMovement(move);
        }
Exemple #9
0
 public static ChessMove CreateStandardChessMove(ChessPiece piece, ChessBoardCell toCell, ChessPieceType promoteTo, PGNMarkersFlags pgnMarkers)
 {
     return(new ChessMove(MoveType.StandardMove, piece, toCell, ChessPieceType.ChessPieceType_Unknown, pgnMarkers));
 }
Exemple #10
0
 public static ChessMove CreateStandardChessMove(ChessBoardCell fromCell, ChessBoardCell toCell)
 {
     return(new ChessMove(MoveType.StandardMove, fromCell.PieceInCell, toCell, ChessPieceType.ChessPieceType_Unknown, PGNMarkersFlags.NoMarkers));
 }
Exemple #11
0
        public static ChessMove GetMoveFromPGN(string PGNMove, ChessPlayer player, ChessBoard board)
        {
            #region INITIALIZATION
            string OriginalPGNMove = PGNMove;
            //string destinationAddress = "";
            bool           isCheck        = false;
            bool           isMate         = false;
            bool           isCapture      = false;
            bool           isPromotion    = false;
            byte           destinationRow = UNKNOWN_INDEX;
            char           destinationCol = UNKNOWN_COL_NAME;
            byte           originRow      = UNKNOWN_INDEX;
            char           originCol      = UNKNOWN_COL_NAME;
            ChessBoardCell fromCell       = null;
            ChessBoardCell toCell         = null;

            ChessPieceType pieceToMove    = ChessPieceType.ChessPieceType_Unknown;
            ChessPieceType pieceToPromote = ChessPieceType.ChessPieceType_Unknown;

            // EXAMPLES, POSSIBLE CODES
            //      '0-0'   Kingside Casteling
            //      '0-0-0' Queen Side Casteling
            //      'h4'    Pawn to h4                   <-- (implicit piece name for pawn)
            //      'Kh4'   King to h4
            //      'Bah4'  Bishop in column a to h4     <-- Column Name provided Desambiguation Level 1
            //      'N3h4'  Knight in Row 3 to h4        <-- Row Number provided Desambiguation Level 2
            //      'Nb1c3' Knight in b1 to c3           <-- Column Name and Row Number provided Desambiguation Level 3
            //      'dd4'   Pawn in Column d to d4       <-- Pawn (Implicit Reference) Desambiguation Level 1
            //      '3d4'   Pawn in Row 3 to d4 (??)     <-- Pawn (Implicit Reference) Desambiguation Level 2
            //      'd3d4'  Pawn in d3 to d4 (??)        <-- Pawn (Implicit Reference) Desambiguation Level 3
            //      '[PGN]=Q'    Pawn Promoted to Quen
            //      'x[PGN]=Q'   Pawn Capture and Promoted to Quen
            //       []x[]       Movement With Capture
            //       '[]+'       Movement and Check
            //       '[]#'       Movement and Check Mate
            //      'x[PGN]=Q#'   Pawn Capture and Promoted to Quen and Check

            if (PGNMove.Length < 2)
            {
                throw new ChessExceptionInvalidPGNNotation("Invalid Notation: " + OriginalPGNMove);
            }
            #endregion
            #region SPECIAL MOVES
            if (PGN_SPECIAL_MOVES.Contains(PGNMove))
            {
                if (PGNMove.Equals(PGN_NOTATION_MOVE_KINKGSIDE_CASTLING))
                {
                    return(ChessMove.CreateKingSideCastlingMove());
                }
                if (PGNMove.Equals(PGN_NOTATION_MOVE_QUEENGSIDE_CASTLING))
                {
                    return(ChessMove.CreateQueenSideCastlingMove());
                }
                throw new ChessExceptionInvalidPGNNotation("Unkwnon Special Notation [" + OriginalPGNMove + "]");
            }
            #endregion
            #region SPECIAL MARKERS

            if (PGNMove.IndexOfAny(PGN_MARKERS) != -1)
            {
                foreach (char marker in PGN_MARKERS)
                {
                    switch (marker)
                    {
                    case PGN_MARKER_CAPTURE:
                        isCapture = true;
                        break;

                    case PGN_MARKER_CHECK:
                        isCheck = true;
                        break;

                    case PGN_MARKER_CHECKMATE:
                        isMate = true;
                        break;

                    case PGN_MARKER_PROMOTION:
                        isPromotion = true;
                        break;
                    }
                }

                PGNMove = PGNMove.Replace(new string(PGN_MARKER_CAPTURE, 1), "")
                          .Replace(new string(PGN_MARKER_CHECK, 1), "")
                          .Replace(new string(PGN_MARKER_CHECKMATE, 1), "")
                          .Replace(new string(PGN_MARKER_PROMOTION, 1), "");
            }

            #endregion
            #region PROCESS PROMOTION
            if (isPromotion)
            {
                char promotedPieceCode = PGNMove[PGNMove.Length - 1];
                pieceToPromote = GetPieceTypeFromPGNName(promotedPieceCode);
                PGNMove        = PGNMove.Substring(0, PGNMove.Length - 1);
            }
            #endregion
            #region REMOVE IMPLICIT PIECE NAME

            if (PGNMove.IndexOfAny(PGN_PIECES_NAMES) == -1)
            {
                //IMPLICIT PAWN
                //       EXAMPLE
                //      'h4' pawn to h4
                PGNMove = PGN_PIECE_PAWN_EXPLICIT + PGNMove;
                //NO MORE IMPLICIT REFERENCES!!!!
            }
            #endregion
            #region OBTAIN DESTINY BOARD CELL
            {
                char row = PGNMove[PGNMove.Length - 1];
                char col = PGNMove[PGNMove.Length - 2];
                if (!(PGN_COLUMN_NAMES.Contains(col) && PGN_ROW_NAMES.Contains(row)))
                {
                    throw new ChessExceptionInvalidPGNNotation("Invalid Notation: " + OriginalPGNMove);
                }
                else
                {
                    destinationRow = byte.Parse(new string(row, 1));
                    destinationCol = col;
                }
                string algebraicCoordinates = string.Format("{0}{1}", col, row);
                toCell  = board[algebraicCoordinates];
                PGNMove = PGNMove.Substring(0, PGNMove.Length - 2);
            }

            #endregion
            #region OBTAIN PIECE TYPE TO MOVE
            {
                char firstChar = PGNMove[0];
                if (PGN_PIECES_NAMES.Contains(firstChar))
                {
                    pieceToMove = GetPieceTypeFromPGNName(firstChar);
                    PGNMove     = PGNMove.Substring(1, PGNMove.Length - 1);
                }
                else
                {
                    throw new ChessExceptionInvalidPGNNotation("Invalid Notation: " + OriginalPGNMove);
                }
            }
            #endregion
            //At this point:
            //   - Special Markers Processed and Codes were Removed
            //   - Promotion Solved and Codes Removed
            //   - Piece To Move Identified and Code was Removed
            //   - PNG String has as least 1 positions.

            #region DESAMBIGUATION ANALISYS
            if (PGNMove.Length > 0)
            {
                //Desambiguation Required
                if (PGNMove.Length == 1)
                {
                    //Desambiguation Level 1 or 2 Required
                    //Disambiguation Level 1 or 2 Required
                    if (PGN_COLUMN_NAMES.Contains(PGNMove[0]))
                    {
                        // Disambiguation LEVEL 1
                        originCol = PGNMove[0];
                    }
                    else if (PGN_ROW_NAMES.Contains(PGNMove[0]))
                    {
                        // Disambiguation LEVEL 2
                        originRow = (byte)char.GetNumericValue(PGNMove[0]);
                    }
                    else
                    {
                        throw new ChessExceptionInvalidPGNNotation("Invalid Notation: " + OriginalPGNMove);
                    }
                }
                else if (PGNMove.Length == 2)
                {
                    //Desambiguation Level 3 Required
                    if (PGN_COLUMN_NAMES.Contains(PGNMove[0]) && PGN_ROW_NAMES.Contains(PGNMove[1]))
                    {
                        // Disambiguation LEVEL 3
                        originCol = PGNMove[0];
                        originRow = (byte)char.GetNumericValue(PGNMove[1]);
                    }
                    else
                    {
                        throw new ChessExceptionInvalidPGNNotation("Invalid Notation: " + OriginalPGNMove);
                    }
                }
                else
                {
                    throw new ChessExceptionInvalidPGNNotation("Invalid Notation: " + OriginalPGNMove);
                }
            }


            #endregion

            #region OBTAIN ORIGIN BOARD CELL
            if (originCol != UNKNOWN_COL_NAME && originRow != UNKNOWN_INDEX)
            {
                string algebraicCoordinates = string.Format("{0}{1}", originCol, originRow);
                fromCell = board[algebraicCoordinates];
            }
            else
            {
                ChessBoardCell[] cells = null;
                if (originCol != UNKNOWN_COL_NAME)
                {
                    byte colIndex = ColumnIndexFromPGNColumnName(originCol);
                    cells = board.GetCol(colIndex);
                }
                else if (originRow != UNKNOWN_INDEX)
                {
                    cells = board.GetRow(originRow);
                }
                else
                {
                    //Row and Column are implicit I need to search piece of the provided type that can move to
                    //the ToCell
                    throw new NotImplementedException();
                }

                if (cells != null)
                {
                    var query = from cell in cells
                                where cell.PieceInCell.Color == player.pieceColor && cell.PieceInCell.PieceType == pieceToMove
                                select cell;
                    ChessBoardCell[] ResultCell = query.ToArray();
                    if (ResultCell.Count() == 1)
                    {
                        fromCell = ResultCell[0];
                    }
                    else
                    {
                        throw new ChessExceptionInvalidPGNNotation("PGN Notation cannot determine the piece to move: " + OriginalPGNMove);
                    }
                }
                else
                {
                    throw new ChessExceptionInvalidPGNNotation("Invalid Notation: " + OriginalPGNMove);
                }
            }
            #endregion

            #region PGN FLAGS
            PGNMarkersFlags flags = PGNMarkersFlags.NoMarkers;
            if (isCheck)
            {
                flags = flags | PGNMarkersFlags.Check;
            }
            if (isMate)
            {
                flags = flags | PGNMarkersFlags.Mate;
            }
            if (isPromotion)
            {
                flags = flags | PGNMarkersFlags.Promote;
            }
            if (isCapture)
            {
                flags = flags | PGNMarkersFlags.Capture;
            }
            #endregion

            return(ChessMove.CreateStandardChessMove(fromCell.PieceInCell, toCell, pieceToPromote, flags));
        }
Exemple #12
0
        public override bool Equals(object obj)
        {
            ChessBoardCell other = (ChessBoardCell)obj;

            return(this.CellAlgebraicName == other.CellAlgebraicName);
        }
Exemple #13
0
 public PieceInsertedEventArgs(ChessPiece piece, ChessBoardCell destinationCell)
 {
     this.PieceInserted   = piece;
     this.DestinationCell = destinationCell;
 }