コード例 #1
0
ファイル: ChessBoard.cs プロジェクト: BogdanFi/Licenta
        /// <summary>
        /// Reverts last move applied to the board
        /// </summary>
        public void RevertLastMove()
        {
            MoveInformation lastMove = Moves.Last();

            Moves.RemoveAt(Moves.Count() - 1);

            ChessPiece lastPieceMoved = FindPieceAt(lastMove.End.File, lastMove.End.Rank);

            lastPieceMoved.Move(lastMove.Start.File, lastMove.Start.Rank);
            if (lastMove.FirstMove)
            {
                lastPieceMoved.Deployed = false; // Reset first move
            }

            // Undo captures
            lastMoveWasCapture = false;
            if (lastMove.IsCapture)
            {
                lastMove.CapturedPiece.Captured = false;
                lastMoveWasCapture = true;
            }

            if (lastMove.IsPromotion)
            {
                lastPieceMoved.Demote();
            }

            // Undo a castling move
            if (lastMove.IsCastle)
            {
                // Move the rook back as well
                ChessPiece rook             = lastMove.CastlingRook;
                PieceFile  castleTargetFile = lastMove.End.File;
                int        rookRank         = (rook.Color == PieceColor.White) ? 1 : 8;
                if (castleTargetFile.ToInt() == 7) // g->h
                {
                    rook.Move(new PieceFile('h'), rookRank);
                }
                else if (castleTargetFile.ToInt() == 3) // c->a
                {
                    rook.Move(new PieceFile('a'), rookRank);
                }
                else
                {
                    // It has to be one of the above if logic is correct
                    throw new IndexOutOfRangeException();
                }
                rook.Deployed = false;
            }

            // Reset castling rights
            ActivePlayerCastlingRights = lastMove.CastlingRights;

            // Flip players
            activePlayer = OppositeColor(activePlayer);

            // Set last FEN
            currentFEN = lastMove.PreviousFEN;
        }
コード例 #2
0
ファイル: ChessBoardView.cs プロジェクト: BogdanFi/Licenta
        /// <summary>
        /// Find the rect for a given location on the board
        /// </summary>
        /// <param name="file">File for the piece</param>
        /// <param name="rank">Rank for the piece</param>
        /// <returns>Rectangle for the board location in client coordinates</returns>
        private Rectangle GetRect(PieceFile file, int rank)
        {
            // This simple diagram helps demonstrate the inverted relationship
            // (not pictured is the overall board offset)
            //
            //       Black                White
            //   +-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+
            // 8 | |X| |X| |X| |X|   | |X| |X| |X| |X| 1
            //   +-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+
            // 7 |X| |X| |X| |X| |   |X| |X| |X| |X| | 2
            //   +-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+
            // 6 | |X| |X| |X| |X|   | |X| |X| |X| |X| 3
            //   +-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+
            // 5 |X| |X| |X| |X| |   |X| |X| |X| |X| | 4
            //   +-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+
            // 4 | |X| |X| |X| |X|   | |X| |X| |X| |X| 5
            //   +-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+
            // 3 |X| |X| |X| |X| |   |X| |X| |X| |X| | 6
            //   +-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+
            // 2 | |X| |X| |X| |X|   | |X| |X| |X| |X| 7
            //   +-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+
            // 1 |X| |X| |X| |X| |   |X| |X| |X| |X| | 8
            //   +-+-+-+-+-+-+-+-+   +-+-+-+-+-+-+-+-+
            //    a b c d e f g h     h g f e d c b a
            //       White                Black
            int X;
            int Y;

            // PieceFile is 1-based, same as the physical board
            if (data.Orientation == BoardOrientation.WhiteOnBottom)
            {
                X = (file.ToInt() - 1) * squareSizeInPixels;
                Y = (8 - rank) * squareSizeInPixels;
            }
            else
            {
                X = (8 - file.ToInt()) * squareSizeInPixels;
                Y = (rank - 1) * squareSizeInPixels;
            }

            // Return the calculated rect offset from the overall topLeft location
            return(new Rectangle(X + topLeft.X, Y + topLeft.Y, squareSizeInPixels, squareSizeInPixels));
        }
コード例 #3
0
ファイル: ChessBoard.cs プロジェクト: BogdanFi/Licenta
        /// <summary>
        /// Returns true if the current piece is trying to castle.  It must be
        /// a king that moved in the correct manner (2 squares horizontally)
        /// </summary>
        /// <param name="piece">ChessPiece to check</param>
        /// <param name="targetFile">ChessFile the piece is moving to</param>
        /// <returns>True if the move is a castling move</returns>
        private bool IsCastling(ChessPiece piece, PieceFile targetFile)
        {
            bool result       = false;
            int  deltaSquares = Math.Abs(piece.File.ToInt() - targetFile.ToInt());

            if ((piece.Job == PieceClass.King) && (deltaSquares == 2))
            {
                result = true;
            }
            return(result);
        }
コード例 #4
0
        /// <summary>
        /// Checks if a given piece can target a specified square.  It is not required
        /// that the square be occupied by an enemy piece, just potentially reachable
        /// </summary>
        /// <param name="board">ChessBoard to check against</param>
        /// <param name="piece">ChessPiece to check</param>
        /// <param name="targetFile">file to target</param>
        /// <param name="targetRank">rank to target</param>
        /// <returns>true if the piece can target the given square</returns>
        public static bool CanPieceTargetSquare(ChessBoard board, ChessPiece piece, PieceFile targetFile, int targetRank)
        {
            bool result = false;

            if (piece.Captured == true)
            {
                return(false);
            }

            BoardSquare        targetSquare = new BoardSquare(targetFile, targetRank);
            List <BoardSquare> moves        = new List <BoardSquare>();

            switch (piece.Job)
            {
            case PieceClass.Pawn:
                // Can't reuse the normal helper as it requires the space to be occupied
                // also w/o en-passant and double moves, this can be simpler
                int pawnTargetRank = (piece.Color == PieceColor.White) ? piece.Rank + 1 : piece.Rank - 1;
                if (targetRank == pawnTargetRank)
                {
                    if (((piece.File.ToInt() - 1) == targetFile.ToInt()) ||
                        ((piece.File.ToInt() + 1) == targetFile.ToInt()))
                    {
                        result = true;
                    }
                }
                break;

            case PieceClass.Knight:
                moves = GetLegalMoves_Knight(piece, board);
                break;

            case PieceClass.Bishop:
                moves = GetLegalMoves_Bishop(piece, board);
                break;

            case PieceClass.Rook:
                moves = GetLegalMoves_Rook(piece, board);
                break;

            case PieceClass.Queen:
                moves = GetLegalMoves_Queen(piece, board);
                break;

            case PieceClass.King:
                // don't recurse into the normal call, also alternate method to examine
                // These are pairs of offsets (-1, 0), (-1, 1),...etc so there are twice
                // as many of these as squares to check
                int[] offsets = new int[] { -1, 0, -1, 1, -1, -1, 1, 0, 1, 1, 1, -1, 0, 1, 0, -1 };
                for (int index = 0; index < offsets.Length / 2; index++)
                {
                    int fileOffset = offsets[index * 2];
                    int rankOffset = offsets[(index * 2) + 1];
                    // Test the validity of the square offset
                    if (BoardSquare.IsValid(piece.File.ToInt() + fileOffset, piece.Rank + rankOffset))
                    {
                        BoardSquare testSquare =
                            new BoardSquare(new PieceFile(piece.File.ToInt() + fileOffset), piece.Rank + rankOffset);
                        if (testSquare == targetSquare)
                        {
                            result = true;
                            break;
                        }
                    }
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            // King is special above
            if (piece.Job != PieceClass.King)
            {
                // Check moves for the target square
                foreach (BoardSquare square in moves)
                {
                    if (square == targetSquare)
                    {
                        result = true;
                        break;
                    }
                }
            }
            return(result);
        }