CastlingBits CanCastleSwitch(int fromPosition)
        {
            CastlingBits castling = CastlingBits.CAN_ALL;

            switch (fromPosition)
            {
            case BoardStateOffset.A1:
                castling = castling & CastlingBits.CAN_NOT_BQ;
                break;

            case BoardStateOffset.E1:
                castling = castling & CastlingBits.CAN_NOT_B;
                break;

            case BoardStateOffset.H1:
                castling = castling & CastlingBits.CAN_NOT_BK;
                break;

            case BoardStateOffset.A8:
                castling = castling & CastlingBits.CAN_NOT_WQ;
                break;

            case BoardStateOffset.E8:
                castling = castling & CastlingBits.CAN_NOT_W;
                break;

            case BoardStateOffset.H8:
                castling = castling & CastlingBits.CAN_NOT_WK;
                break;
            }
            return(castling);
        }
        CastlingBits CanCastleIf(int fromPosition)
        {
            CastlingBits castling = CastlingBits.CAN_ALL;

            if (fromPosition == BoardStateOffset.A1)
            {
                castling = castling & CastlingBits.CAN_NOT_BQ;
            }
            else if (fromPosition == BoardStateOffset.E1)
            {
                castling = castling & CastlingBits.CAN_NOT_B;
            }
            else if (fromPosition == BoardStateOffset.H1)
            {
                castling = castling & CastlingBits.CAN_NOT_BK;
            }
            else if (fromPosition == BoardStateOffset.A8)
            {
                castling = castling & CastlingBits.CAN_NOT_WQ;
            }
            else if (fromPosition == BoardStateOffset.E8)
            {
                castling = castling & CastlingBits.CAN_NOT_W;
            }
            else if (fromPosition == BoardStateOffset.H8)
            {
                castling = castling & CastlingBits.CAN_NOT_WK;
            }
            return(castling);
        }
        CastlingBits CanCastleLookup(int fromPosition)
        {
            CastlingBits castleBits = CastlingBits.CAN_ALL;

            castleBits = (CastlingBits)((int)castleBits & (int)CastlingHelper.castleLookup[fromPosition]);

            return(castleBits);
        }
Example #4
0
        public bool CanCastleKingSide()
        {
            CastlingBits castlingBits = CastlingBits;

            // TODO bitshift optimize?
            if (IsWhiteTurnBool)
            {
                return((castlingBits & CastlingBits.WHITE_KING_SIDE_CASTLE) == CastlingBits.WHITE_KING_SIDE_CASTLE);
            }
            else
            {
                return((castlingBits & CastlingBits.BLACK_KING_SIDE_CASTLE) == CastlingBits.BLACK_KING_SIDE_CASTLE);
            }
        }
Example #5
0
        public bool CanICastleQueenSide()
        {
            CastlingBits castlingBits = CastlingBits;

            // TODO bitshift optimize?
            if (IsWhiteTurnBool)
            {
                return((castlingBits & CastlingBits.WHITE_QUEEN_SIDE_CASTLE) == CastlingBits.WHITE_QUEEN_SIDE_CASTLE);
            }
            else
            {
                return((castlingBits & CastlingBits.BLACK_QUEEN_SIDE_CASTLE) == CastlingBits.BLACK_QUEEN_SIDE_CASTLE);
            }
        }
Example #6
0
        public void BlackCannotCastleQueenSideAfterH8Moves()
        {
            CastlingBits castling = CastlingBits.CAN_ALL;

            castling = castling & CastlingHelper.castleLookup[BoardStateOffset.H8];

            Assert.IsTrue((castling & CastlingBits.BLACK_QUEEN_SIDE_CASTLE) == CastlingBits.BLACK_QUEEN_SIDE_CASTLE,
                          "Black can still castle queen side after h8 moves");

            Assert.IsFalse((castling & CastlingBits.BLACK_KING_SIDE_CASTLE) == CastlingBits.BLACK_KING_SIDE_CASTLE,
                           "Black cannot castle king side after h8 moves");

            Assert.IsTrue((castling & CastlingBits.WHITE_KING_SIDE_CASTLE) == CastlingBits.WHITE_KING_SIDE_CASTLE,
                          "White can still castle");

            Assert.IsTrue((castling & CastlingBits.WHITE_QUEEN_SIDE_CASTLE) == CastlingBits.WHITE_QUEEN_SIDE_CASTLE,
                          "White can still castle");
        }
Example #7
0
        public static String BoardToFen(Board board, int move = 0)
        {
            StringBuilder fen = new StringBuilder();

            for (int row = 7; row >= 0; row--)
            {
                int count = 0;
                for (int column = 0; column < 8; column++)
                {
                    var position = row * BoardStateOffset.ROW_OFFSET + column;
                    var piece    = board.GetPiece(position);
                    //var piece = Board.GetPiece(board, position);
                    char c = PieceParser.ToChar(piece);
                    if (c == '_')
                    {
                        count++;
                    }
                    else
                    {
                        if (count != 0)
                        {
                            fen.Append(count);
                            count = 0;
                        }
                        fen.Append(c);
                    }
                }
                if (count != 0)
                {
                    fen.Append(count);
                }

                if (row != 0)
                {
                    fen.Append("/");
                }
            }
            fen.Append(" ");
            fen.Append(board.IsWhiteTurnBool ? "w" : "b");
            fen.Append(" ");
            CastlingBits castlingBits = board.CastlingBits;

            if (castlingBits == CastlingBits.EMPTY)
            {
                fen.Append("-");
            }
            else
            {
                if ((castlingBits & CastlingBits.WHITE_KING_SIDE_CASTLE) != CastlingBits.EMPTY)
                {
                    fen.Append("K");
                }
                if ((castlingBits & CastlingBits.WHITE_QUEEN_SIDE_CASTLE) != CastlingBits.EMPTY)
                {
                    fen.Append("Q");
                }
                if ((castlingBits & CastlingBits.BLACK_KING_SIDE_CASTLE) != CastlingBits.EMPTY)
                {
                    fen.Append("k");
                }
                if ((castlingBits & CastlingBits.BLACK_QUEEN_SIDE_CASTLE) != CastlingBits.EMPTY)
                {
                    fen.Append("q");
                }
            }
            fen.Append(" ");
            fen.Append(board.EnPassantTarget != EnPassant.NO_ENPASSANT ? BoardPosition.ReadablePosition(board.EnPassantTarget) : "-");
            fen.Append(" ");
            fen.Append(board.HalfTurnCounter);
            fen.Append(" ");
            fen.Append(move);

            return(fen.ToString());
        }
Example #8
0
        public void UndoMove(Move move)
        {
            int targetPosition = move.targetPosition;
            int fromPosition   = move.fromPosition;
            int theirColor     = IsWhiteTurn;
            int ourColor       = IsWhiteTurn ^ 1;

            bytes[fromPosition] = bytes[targetPosition];

            bytes[targetPosition] = move.capturedPiece;

            Piece movedPiece = GetPiece(fromPosition);

            CastlingBits previous = (CastlingBits)move.previousCastlingBits;

            bytes[BoardStateOffset.HALF_TURN_COUNTER] = move.previousHalfMove;
            bytes[BoardStateOffset.CASTLING]          = move.previousCastlingBits;
            bytes[BoardStateOffset.EN_PASSANT_FIELD]  = move.previousEnpassant;
            MoveFlags moveFlags = (MoveFlags)move.moveFlags;

            if ((moveFlags & MoveFlags.ENPASSANT) == MoveFlags.ENPASSANT)
            {
                // when undoing a enpassant move spawn their pawn back
                // we abuse that isWhite is a integer which is 1 on whites turn and 0 and blacks turn
                // if it was black move then we have to spawn it one row above
                // if it was whites move we spawn it one move below
                // keep in mind the IsWhiteTurn is currently opposite of who made the move
                int enpassantSpawnPosition = targetPosition - BoardStateOffset.ROW_OFFSET + 2 * BoardStateOffset.ROW_OFFSET * IsWhiteTurn;
                SetPiece(enpassantSpawnPosition, Piece.PAWN | (Piece)theirColor);

                // when capturing with enpassant don't place the captured piece back since it was taken from another square
                bytes[targetPosition] = (byte)Piece.EMPTY;
            }
            if (move.promotion != 0)
            {
                bytes[fromPosition] = (byte)(Piece.PAWN | (Piece)ourColor);
            }

            // if black made a move decrement the turn counter
            // we abuse that isWhite is a integer which is 1 on whites turn and 0 and blacks turn
            //TurnCounter -= IsWhiteTurn;

            if ((movedPiece & Piece.PIECE_MASK) == Piece.KING)
            {
                if ((moveFlags & MoveFlags.CASTLING) == MoveFlags.CASTLING)
                {
                    // if the target move is less than the kingsposition it is queenside castling,
                    // otherwise it is kingside castle
                    if (targetPosition < fromPosition)
                    {
                        // copy the rook back to its starting position
                        bytes[fromPosition - 4] = bytes[fromPosition - 1];
                        bytes[fromPosition - 1] = 0;
                    }
                    else
                    {
                        bytes[fromPosition + 3] = bytes[fromPosition + 1];
                        bytes[fromPosition + 1] = 0;
                    }
                }
                SetKingPosition(ourColor, (byte)fromPosition);
            }

            // switch turn back to whites turn
            IsWhiteTurn = (byte)ourColor;
        }