Example #1
0
        public Position(int[] Pieces, int ToMove, int CastlingRights, int EnPassant = InvalidSquare)
        {
            if (Pieces.Count() != 64)
            {
                throw new ArgumentException();
            }
            for (int i = 0; i < 64; i++)
            {
                int PieceToAdd = Pieces[i];
                SquarePiece[i] = PieceToAdd;

                if (PieceToAdd == 0)
                {
                    continue;
                }
                PieceBitboard[PieceToAdd] |= (1UL << i);              //Piece array
                PieceBitboard[PieceToAdd & Color.Mask] |= (1UL << i); //Color array
                OccupiedBB |= (1UL << i);                             //All pieces array
            }
            ColorToMove = ToMove;

            CastleShortIndex[White] = CastlingRights & 0b0001;
            CastleShortIndex[Black] = (CastlingRights & 0b0010) >> 1;
            CastleLongIndex[White]  = (CastlingRights & 0b0100) >> 2;
            CastleLongIndex[Black]  = (CastlingRights & 0b1000) >> 3;

            EnPassantHistory.Push(EnPassant);
        }
Example #2
0
        public void UnMake()
        {
            if (!MoveHistory.Any())
            {
                throw new Exception("No move to unmake");
            }
            int MoveToUnmake  = MoveHistory.Pop();
            int ColorMadeMove = 1 - ColorToMove;

            int fromSquare = Move.FromSquare(MoveToUnmake);
            int toSquare   = Move.ToSquare(MoveToUnmake);
            int fromPiece  = Move.FromPiece(MoveToUnmake);
            int toPiece    = Move.ToPiece(MoveToUnmake);

            MovesFiftyHistory.Pop();


            //Moving Back And Cancelling Capturing
            SquarePiece[toSquare]   = toPiece;
            SquarePiece[fromSquare] = fromPiece;

            PieceBitboard[fromPiece] ^= 1UL << fromSquare;              //no changes
            PieceBitboard[fromPiece] ^= 1UL << toSquare;                //no changes

            PieceBitboard[fromPiece & Color.Mask] ^= 1UL << fromSquare; //no changes
            PieceBitboard[fromPiece & Color.Mask] ^= 1UL << toSquare;   //no changes

            OccupiedBB ^= 1UL << fromSquare;                            //no changes
            if (toPiece != 0)
            {
                PieceBitboard[toPiece] ^= 1UL << toSquare;
                PieceBitboard[toPiece & Color.Mask] ^= 1UL << toSquare;

                int EnemyLeftRookIndex = 56 * ColorMadeMove;
                if (toSquare == EnemyLeftRookIndex && toPiece == Piece.Rook && CastleShortIndex[1 - ColorMadeMove] <= 0)
                {
                    CastleShortIndex[1 - ColorMadeMove]++;
                }
                else if (toSquare == EnemyLeftRookIndex + 7 && toPiece == Piece.Rook && CastleLongIndex[1 - ColorMadeMove] <= 0)
                {
                    CastleShortIndex[1 - ColorMadeMove]++;
                }
            }
            else
            {
                OccupiedBB ^= 1UL << toSquare;
            }

            if (CastleShortIndex[ColorMadeMove] <= 0)
            {
                CastleShortIndex[ColorMadeMove]++;
            }
            if (CastleLongIndex[ColorMadeMove] <= 0)
            {
                CastleLongIndex[ColorMadeMove]++;
            }
            if (CastleShortIndex[1 - ColorMadeMove] <= 0)
            {
                CastleShortIndex[1 - ColorMadeMove]++;
            }
            if (CastleLongIndex[1 - ColorMadeMove] <= 0)
            {
                CastleLongIndex[1 - ColorMadeMove]++;
            }

            //Castling Back
            if (Move.Castling(MoveToUnmake))
            {
                int sidePreIndex = 56 * ColorMadeMove;

                int rookSquare, rookToSquare;
                //Short castling (getting rook position)
                if (File(toSquare) == 6)
                {
                    rookSquare   = sidePreIndex + 7;
                    rookToSquare = fromSquare + 1;
                }
                //Long castling (getting rook position)
                else
                {
                    rookSquare   = sidePreIndex;
                    rookToSquare = fromSquare - 1;
                }

                //Moving the rook back
                SquarePiece[rookSquare]   = SquarePiece[rookToSquare];
                SquarePiece[rookToSquare] = 0;

                OccupiedBB ^= 1UL << rookSquare;
                OccupiedBB ^= 1UL << rookToSquare;

                PieceBitboard[Piece.Rook | ColorMadeMove] ^= 1UL << rookSquare;
                PieceBitboard[Piece.Rook | ColorMadeMove] ^= 1UL << rookToSquare;

                PieceBitboard[ColorMadeMove] ^= 1UL << rookSquare;
                PieceBitboard[ColorMadeMove] ^= 1UL << rookToSquare;
            }

            //Promotion
            if (Move.Promotion(MoveToUnmake))
            {
                int PromotedTo = Move.PromotionPiece(MoveToUnmake); //Either queen, knight, bishop or rook
                //SquarePiece[toSquare] = PromotedTo;

                //If we are here, we've just set the PieceBitboard[fromPiece] to 1 at the toSquare thinking of doing the opposite, so we need to cancel that
                PieceBitboard[fromPiece]  ^= 1UL << toSquare;
                PieceBitboard[PromotedTo] ^= 1UL << toSquare;

                //Color maps do not change, as well as occupied (we're just replacing the piece)
            }

            //Enpassant
            if (Move.EnPassant(MoveToUnmake))
            {
                //Restoring the pawn
                int    EnPassantVictimSquare   = toSquare + 16 * ColorMadeMove - 8;
                UInt64 enPassantVictimBitboard = 1UL << EnPassantVictimSquare;

                OccupiedBB ^= enPassantVictimBitboard;
                PieceBitboard[Piece.Pawn | ColorToMove] ^= enPassantVictimBitboard;
                PieceBitboard[ColorToMove]        ^= enPassantVictimBitboard;
                SquarePiece[EnPassantVictimSquare] = Piece.Pawn | ColorToMove;
            }

            ColorToMove = ColorMadeMove;
            EnPassantHistory.Pop();
        }
Example #3
0
        public void Make(int Move)
        {
            MoveHistory.Push(Move);

            int fromSquare = PerfectChess.Move.FromSquare(Move);
            int toSquare   = PerfectChess.Move.ToSquare(Move);
            int fromPiece  = PerfectChess.Move.FromPiece(Move);
            int toPiece    = PerfectChess.Move.ToPiece(Move);

            //Fifty move rule
            if (toPiece != 0 || (fromPiece & Piece.Mask) == Piece.Pawn)
            {
                MovesFiftyHistory.Push(0);
            }
            else
            {
                MovesFiftyHistory.Push(MovesFiftyRuleCount + 1);
            }

            //Moving
            SquarePiece[toSquare]   = SquarePiece[fromSquare];
            SquarePiece[fromSquare] = 0;

            OccupiedBB ^= 1UL << fromSquare;
            OccupiedBB |= 1UL << toSquare;

            PieceBitboard[fromPiece] ^= 1UL << fromSquare;
            PieceBitboard[fromPiece] ^= 1UL << toSquare;

            PieceBitboard[fromPiece & Color.Mask] ^= 1UL << fromSquare;
            PieceBitboard[fromPiece & Color.Mask] ^= 1UL << toSquare;

            if (CastleShortIndex[ColorToMove] <= 0)
            {
                CastleShortIndex[ColorToMove]--;
            }
            if (CastleLongIndex[ColorToMove] <= 0)
            {
                CastleLongIndex[ColorToMove]--;
            }
            if (CastleShortIndex[1 - ColorToMove] <= 0)
            {
                CastleShortIndex[1 - ColorToMove]--;
            }
            if (CastleLongIndex[1 - ColorToMove] <= 0)
            {
                CastleLongIndex[1 - ColorToMove]--;
            }

            //Resetting castling rights if king or rook moves
            if ((fromPiece & Piece.Mask) == Piece.King)
            {
                //CanCastleLong[ColorToMove] = false;
                //CanCastleShort[ColorToMove] = false;

                if (CastleShortIndex[ColorToMove] == 1)
                {
                    CastleShortIndex[ColorToMove]--;
                }
                if (CastleLongIndex[ColorToMove] == 1)
                {
                    CastleLongIndex[ColorToMove]--;
                }
            }
            else if ((fromPiece & Piece.Mask) == Piece.Rook)
            {
                if (fromSquare == 56 * ColorToMove + 7)
                {
                    //CanCastleShort[ColorToMove] = false;
                    if (CastleShortIndex[ColorToMove] == 1)
                    {
                        CastleShortIndex[ColorToMove]--;
                    }
                }
                else if (fromSquare == 56 * ColorToMove)
                {
                    //CanCastleLong[ColorToMove] = false;
                    if (CastleLongIndex[ColorToMove] == 1)
                    {
                        CastleLongIndex[ColorToMove]--;
                    }
                }
            }
            //Setting enpassant square if double pawn push
            else if ((fromPiece & Piece.Mask) == Piece.Pawn && Rank(fromSquare) == 1 + 5 * ColorToMove && Math.Abs(toSquare - fromSquare) == 16)
            {
                //EnPassantSquare = fromSquare + 8 - 16 * ColorToMove;
                EnPassantHistory.Push(fromSquare + 8 - 16 * ColorToMove);

                ColorToMove = 1 - ColorToMove;
                return;
            }

            //Capturing
            if (toPiece != 0)
            {
                PieceBitboard[toPiece] ^= 1UL << toSquare;
                PieceBitboard[toPiece & Color.Mask] ^= 1UL << toSquare;

                int EnemyLeftRookIndex = 56 * (1 - ColorToMove);
                if (toSquare == EnemyLeftRookIndex + 7 && (toPiece & Piece.Mask) == Piece.Rook && CastleShortIndex[1 - ColorToMove] == 1)
                {
                    CastleShortIndex[1 - ColorToMove]--;
                }
                else if (toSquare == EnemyLeftRookIndex &&
                         (toPiece & Piece.Mask) == Piece.Rook && CastleLongIndex[1 - ColorToMove] == 1)
                {
                    CastleLongIndex[1 - ColorToMove]--;
                }
            }

            //Castling
            if (PerfectChess.Move.Castling(Move))
            {
                int sidePreIndex = 56 * ColorToMove;

                int rookSquare, rookToSquare;
                //Short castling (getting rook position)
                if (Position.File(toSquare) == 6)
                {
                    rookSquare   = sidePreIndex + 7;
                    rookToSquare = fromSquare + 1;
                }
                //Long castling (getting rook position)
                else
                {
                    rookSquare   = sidePreIndex;
                    rookToSquare = fromSquare - 1;
                }

                //Moving the rook
                SquarePiece[rookToSquare] = SquarePiece[rookSquare];
                SquarePiece[rookSquare]   = 0;

                OccupiedBB ^= 1UL << rookSquare;
                OccupiedBB |= 1UL << rookToSquare;

                PieceBitboard[Piece.Rook | ColorToMove] ^= 1UL << rookSquare;
                PieceBitboard[Piece.Rook | ColorToMove] ^= 1UL << rookToSquare;

                PieceBitboard[ColorToMove] ^= 1UL << rookSquare; //Assuming there is a rook of our colour :)
                PieceBitboard[ColorToMove] ^= 1UL << rookToSquare;
            }

            //Promotion
            if (PerfectChess.Move.Promotion(Move))
            {
                int PromotedTo = PerfectChess.Move.PromotionPiece(Move); //Either queen, knight, bishop or rook
                SquarePiece[toSquare] = PromotedTo;

                PieceBitboard[fromPiece]  ^= 1UL << toSquare; //Our pawn is not gonna exist anymore, so delete it from table of pawns
                PieceBitboard[PromotedTo] ^= 1UL << toSquare; //There is no piece on that square, so we put our PromotedTo piece there

                //Color maps do not change, as well as occupied (we're just replacing the piece)
            }

            //Enpassant
            if (PerfectChess.Move.EnPassant(Move))
            {
                //Deleting the pawn
                int    EnPassantVictimSquare   = (EnPassantSquare + 16 * ColorToMove - 8);
                UInt64 enPassantVictimBitboard = 1UL << EnPassantVictimSquare;

                OccupiedBB ^= enPassantVictimBitboard;
                PieceBitboard[Piece.Pawn | 1 - ColorToMove] ^= enPassantVictimBitboard;
                PieceBitboard[1 - ColorToMove]    ^= enPassantVictimBitboard;
                SquarePiece[EnPassantVictimSquare] = 0;
            }
            ColorToMove = 1 - ColorToMove;

            //EnPassantSquare = InvalidSquare;
            EnPassantHistory.Push(InvalidSquare);
        }