コード例 #1
0
ファイル: ChessGame.cs プロジェクト: DoubleKnight/ChessOne
 protected void RaisePieceMovedEvent(ChessMove move, ChessMoveInfo moveInfo)
 {
     if (PieceMoved != null)
     {
         PieceMoved(null, new PieceMovedEventArgs(move, moveInfo));
     }
 }
コード例 #2
0
 // Constructor
 public PieceMovedEventArgs(ChessMove move, ChessMoveInfo moveInfo)
 {
     this.move     = move;
     this.moveInfo = moveInfo;
 }
コード例 #3
0
ファイル: ChessGame.cs プロジェクト: DoubleKnight/ChessOne
        public bool MakeMove(ChessMove move, bool validateOnly)
        {
            bool       res   = false;
            ChessPiece piece = new ChessPiece();

            if (move.FromIndex < ChessPositionIndex.A1 || move.FromIndex > ChessPositionIndex.H8 ||
                move.ToIndex < ChessPositionIndex.A1 || move.ToIndex > ChessPositionIndex.H8 ||
                move.FromIndex == move.ToIndex)
            {
                throw new Exception("Invalid index");
            }

            if (Board.GetPiece(move.FromIndex, ref piece) && piece.PieceColor == Turn)
            {
                move.PieceType = piece.PieceType;

                if (!Board.IsColor(move.ToIndex, piece.PieceColor))
                {
                    List <ChessMove> possibleMoves = GetPossibleMoves(Board, Turn);
                    bool             validMove     = false;
                    foreach (ChessMove possibleMove in possibleMoves)
                    {
                        if (possibleMove.FromIndex == move.FromIndex &&
                            possibleMove.ToIndex == move.ToIndex)
                        {
                            move.IsKingsideCastling  = possibleMove.IsKingsideCastling;
                            move.IsQueensideCastling = possibleMove.IsQueensideCastling;
                            validMove = true;
                            break;
                        }
                    }

                    if (validMove)
                    {
                        // Make a copy so we can "undo" the moves if in check after a move.
                        ChessBoard boardCopy = new ChessBoard(Board, true);

                        ChessMoveInfo moveInfo = new ChessMoveInfo();

                        boardCopy.ApplyMove(Turn, move, moveInfo);

                        if (!IsInCheck(boardCopy, Turn))
                        {
                            if (validateOnly)
                            {
                                res = true;
                            }
                            else
                            {
                                if (move.IsCapture)
                                {
                                    ChessPiece capturedPiece = new ChessPiece();
                                    if (Board.GetPiece(moveInfo.CapturedPiecePos, ref capturedPiece))
                                    {
                                        boardCopy.CapturedPieces.Add(capturedPiece);
                                    }
                                }

                                Board = boardCopy;

                                ChessMove moveCopy = new ChessMove(move);
                                moveCopy.ResultingBoard = Board;
                                chessMoves.Add(moveCopy);

                                Turn = InvertColor(Turn);

                                GameState = LookForCheckMateOrDraw(Board, Turn, chessMoves);
                                if (GameState != ChessGameState.Active)
                                {
                                    Turn = ChessPieceColor.None;
                                }

                                RaisePieceMovedEvent(moveCopy, moveInfo);

                                res = true;
                            }
                        }
                    }
                }
            }

            return(res);
        }
コード例 #4
0
ファイル: ChessBoard.cs プロジェクト: DoubleKnight/ChessOne
        private void MoveRookWhenCastling(ChessPieceColor color, ChessPositionIndex fromIndex, ChessPositionIndex toIndex, ChessMoveInfo moveInfo)
        {
            ulong rookFromPos = Precomputed.IndexToBitBoard[(int)fromIndex];
            ulong rookToPos   = Precomputed.IndexToBitBoard[(int)toIndex];

            ChessBoardColorState boardState = GetBoardState(color);

            boardState.Pieces &= ~rookFromPos;
            boardState.Pieces |= rookToPos;

            boardState.Rooks &= ~rookFromPos;
            boardState.Rooks |= rookToPos;

            if (moveInfo != null)
            {
                moveInfo.SecondaryFromIndex = fromIndex;
                moveInfo.SecondaryToIndex   = toIndex;
            }
        }
コード例 #5
0
ファイル: ChessBoard.cs プロジェクト: DoubleKnight/ChessOne
        public void ApplyMove(ChessPieceColor color, ChessMove move, ChessMoveInfo moveInfo)
        {
            // Make the move...
            ulong fromPos = Precomputed.IndexToBitBoard[(int)move.FromIndex];
            ulong toPos   = Precomputed.IndexToBitBoard[(int)move.ToIndex];

            ulong capturePos = toPos;

            if (moveInfo != null)
            {
                moveInfo.MovedBy = color;
            }

            count50MoveRule++;

            ChessBoardColorState boardState = GetBoardState(color);

            boardState.Pieces &= ~fromPos;  // Move the piece.
            boardState.Pieces |= toPos;     // Move the piece.
            switch (move.PieceType)
            {
            case ChessPieceType.Pawn:
                count50MoveRule = 0;

                boardState.Pawns &= ~fromPos;
                switch (move.PromotionPieceType)
                {
                case ChessPieceType.Knight:
                    boardState.Knights |= toPos;
                    break;

                case ChessPieceType.Bishop:
                    boardState.Bishops |= toPos;
                    break;

                case ChessPieceType.Rook:
                    boardState.Rooks |= toPos;
                    break;

                case ChessPieceType.Queen:
                    boardState.Queens |= toPos;
                    break;

                default:
                    boardState.Pawns |= toPos;
                    break;
                }

                if (color == ChessPieceColor.White)
                {
                    if ((Precomputed.WhitePawnCaptureMoves[(int)move.FromIndex] & toPos & (enPassantTarget << 8)) != 0)
                    {
                        capturePos      = enPassantTarget;
                        enPassantTarget = 0;
                    }
                    else if ((Precomputed.WhitePawnDoubleMoves[(int)move.FromIndex] & toPos) != 0)
                    {
                        enPassantTarget = toPos;
                    }
                    else
                    {
                        enPassantTarget = 0;
                    }
                }
                else
                {
                    if ((Precomputed.BlackPawnCaptureMoves[(int)move.FromIndex] & toPos & (enPassantTarget >> 8)) != 0)
                    {
                        capturePos      = enPassantTarget;
                        enPassantTarget = 0;
                    }
                    else if ((Precomputed.BlackPawnDoubleMoves[(int)move.FromIndex] & toPos) != 0)
                    {
                        enPassantTarget = toPos;
                    }
                    else
                    {
                        enPassantTarget = 0;
                    }
                }

                break;

            case ChessPieceType.Knight:
                enPassantTarget     = 0;
                boardState.Knights &= ~fromPos;
                boardState.Knights |= toPos;
                break;

            case ChessPieceType.Bishop:
                enPassantTarget     = 0;
                boardState.Bishops &= ~fromPos;
                boardState.Bishops |= toPos;
                break;

            case ChessPieceType.Rook:
                enPassantTarget   = 0;
                boardState.Rooks &= ~fromPos;
                boardState.Rooks |= toPos;

                if ((fromPos & Precomputed.IndexToBitBoard[(int)ChessPositionIndex.A1]) != 0)
                {
                    whiteBoardState.QueensideCastlingPossible = false;
                }
                else if ((fromPos & Precomputed.IndexToBitBoard[(int)ChessPositionIndex.H1]) != 0)
                {
                    whiteBoardState.KingsideCastlingPossible = false;
                }
                else if ((fromPos & Precomputed.IndexToBitBoard[(int)ChessPositionIndex.A8]) != 0)
                {
                    blackBoardState.QueensideCastlingPossible = false;
                }
                else if ((fromPos & Precomputed.IndexToBitBoard[(int)ChessPositionIndex.H8]) != 0)
                {
                    blackBoardState.KingsideCastlingPossible = false;
                }

                break;

            case ChessPieceType.Queen:
                enPassantTarget    = 0;
                boardState.Queens &= ~fromPos;
                boardState.Queens |= toPos;
                break;

            case ChessPieceType.King:
                enPassantTarget  = 0;
                boardState.King &= ~fromPos;
                boardState.King |= toPos;

                boardState.KingsideCastlingPossible  = false;
                boardState.QueensideCastlingPossible = false;

                if (move.IsKingsideCastling)
                {
                    if (color == ChessPieceColor.White)
                    {
                        MoveRookWhenCastling(color, ChessPositionIndex.H1, ChessPositionIndex.F1, moveInfo);
                    }
                    else
                    {
                        MoveRookWhenCastling(color, ChessPositionIndex.H8, ChessPositionIndex.F8, moveInfo);
                    }
                }
                else if (move.IsQueensideCastling)
                {
                    if (color == ChessPieceColor.White)
                    {
                        MoveRookWhenCastling(color, ChessPositionIndex.A1, ChessPositionIndex.D1, moveInfo);
                    }
                    else
                    {
                        MoveRookWhenCastling(color, ChessPositionIndex.A8, ChessPositionIndex.D8, moveInfo);
                    }
                }

                break;
            }

            ChessPieceColor      invertedColor      = ChessGame.InvertColor(color);
            ChessBoardColorState invertedBoardState = GetBoardState(invertedColor);

            if ((invertedBoardState.Pieces & capturePos) != 0)   // Check if there is a capture.
            {
                invertedBoardState.Pieces  &= ~capturePos;       // Remove the piece from all black pieces.
                invertedBoardState.Pawns   &= ~capturePos;
                invertedBoardState.Knights &= ~capturePos;
                invertedBoardState.Bishops &= ~capturePos;
                invertedBoardState.Rooks   &= ~capturePos;
                invertedBoardState.Queens  &= ~capturePos;

                move.IsCapture  = true;
                count50MoveRule = 0;
                if (moveInfo != null)
                {
                    moveInfo.CapturedPiecePos = (ChessPositionIndex)Util.fastBitScanForward(capturePos);
                }

                // PP 2012-12-24: when a rook is captured, castling is no longer possible.
                if ((capturePos & Precomputed.IndexToBitBoard[(int)ChessPositionIndex.A1]) != 0)
                {
                    whiteBoardState.QueensideCastlingPossible = false;
                }
                else if ((capturePos & Precomputed.IndexToBitBoard[(int)ChessPositionIndex.H1]) != 0)
                {
                    whiteBoardState.KingsideCastlingPossible = false;
                }
                else if ((capturePos & Precomputed.IndexToBitBoard[(int)ChessPositionIndex.A8]) != 0)
                {
                    blackBoardState.QueensideCastlingPossible = false;
                }
                else if ((capturePos & Precomputed.IndexToBitBoard[(int)ChessPositionIndex.H8]) != 0)
                {
                    blackBoardState.KingsideCastlingPossible = false;
                }
            }
        }