Example #1
0
        public void MakeNullMove()
        {
            NullMoves++;
            if (ColorToMove == Color.White)
            {
                MovesCount++;
            }

            _enPassants.Push(EnPassant);
            _hashes.Push(Hash);

            if (EnPassant != 0)
            {
                var enPassantRank = BitOperations.BitScan(EnPassant) % 8;
                Hash      = ZobristHashing.ToggleEnPassant(Hash, enPassantRank);
                EnPassant = 0;
            }

            ColorToMove = ColorOperations.Invert(ColorToMove);
            Hash        = ZobristHashing.ChangeSide(Hash);
        }
Example #2
0
        public void MakeMove(Move move)
        {
            var pieceType  = PieceTable[move.From];
            var enemyColor = ColorOperations.Invert(ColorToMove);

            if (ColorToMove == Color.White)
            {
                MovesCount++;
            }

            _castlings.Push(Castling);
            _hashes.Push(Hash);
            _pawnHashes.Push(PawnHash);
            _enPassants.Push(EnPassant);
            _irreversibleMovesCounts.Push(IrreversibleMovesCount);

            if (pieceType == Piece.Pawn || move.IsCapture() || move.IsCastling())
            {
                IrreversibleMovesCount = 0;
            }
            else
            {
                IrreversibleMovesCount++;
            }

            if (EnPassant != 0)
            {
                var enPassantRank = BitOperations.BitScan(EnPassant) % 8;
                Hash      = ZobristHashing.ToggleEnPassant(Hash, enPassantRank);
                EnPassant = 0;
            }

            if (move.IsSinglePush())
            {
                MovePiece(ColorToMove, pieceType, move.From, move.To);
                Hash = ZobristHashing.MovePiece(Hash, ColorToMove, pieceType, move.From, move.To);

                if (pieceType == Piece.Pawn)
                {
                    PawnHash = ZobristHashing.MovePiece(PawnHash, ColorToMove, pieceType, move.From, move.To);
                }
            }
            else if (move.IsDoublePush())
            {
                MovePiece(ColorToMove, pieceType, move.From, move.To);
                Hash     = ZobristHashing.MovePiece(Hash, ColorToMove, pieceType, move.From, move.To);
                PawnHash = ZobristHashing.MovePiece(PawnHash, ColorToMove, pieceType, move.From, move.To);

                var enPassantField      = ColorToMove == Color.White ? 1ul << move.To - 8 : 1ul << move.To + 8;
                var enPassantFieldIndex = BitOperations.BitScan(enPassantField);

                EnPassant |= enPassantField;
                Hash       = ZobristHashing.ToggleEnPassant(Hash, enPassantFieldIndex % 8);
            }
            else if (move.IsEnPassant())
            {
                var enemyPieceField = ColorToMove == Color.White ? (byte)(move.To - 8) : (byte)(move.To + 8);
                var killedPiece     = PieceTable[enemyPieceField];

                RemovePiece(enemyColor, killedPiece, enemyPieceField);
                Hash     = ZobristHashing.AddOrRemovePiece(Hash, enemyColor, killedPiece, enemyPieceField);
                PawnHash = ZobristHashing.AddOrRemovePiece(PawnHash, enemyColor, killedPiece, enemyPieceField);

                MovePiece(ColorToMove, pieceType, move.From, move.To);
                Hash     = ZobristHashing.MovePiece(Hash, ColorToMove, pieceType, move.From, move.To);
                PawnHash = ZobristHashing.MovePiece(PawnHash, ColorToMove, pieceType, move.From, move.To);

                _killedPieces.Push(killedPiece);
            }
            else if (move.IsCapture())
            {
                var killedPiece = PieceTable[move.To];

                RemovePiece(enemyColor, killedPiece, move.To);
                Hash = ZobristHashing.AddOrRemovePiece(Hash, enemyColor, killedPiece, move.To);

                if (killedPiece == Piece.Pawn)
                {
                    PawnHash = ZobristHashing.AddOrRemovePiece(PawnHash, enemyColor, killedPiece, move.To);
                }
                else if (killedPiece == Piece.Rook)
                {
                    switch (move.To)
                    {
                    case 0:
                    {
                        Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.WhiteShort);
                        Castling &= ~Castling.WhiteShort;
                        break;
                    }

                    case 7:
                    {
                        Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.WhiteLong);
                        Castling &= ~Castling.WhiteLong;
                        break;
                    }

                    case 56:
                    {
                        Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.BlackShort);
                        Castling &= ~Castling.BlackShort;
                        break;
                    }

                    case 63:
                    {
                        Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.BlackLong);
                        Castling &= ~Castling.BlackLong;
                        break;
                    }
                    }
                }

                if (move.IsPromotion())
                {
                    var promotionPiece = GetPromotionPiece(move.Flags);

                    RemovePiece(ColorToMove, pieceType, move.From);
                    Hash     = ZobristHashing.AddOrRemovePiece(Hash, ColorToMove, pieceType, move.From);
                    PawnHash = ZobristHashing.AddOrRemovePiece(PawnHash, ColorToMove, pieceType, move.From);

                    AddPiece(ColorToMove, promotionPiece, move.To);
                    Hash = ZobristHashing.AddOrRemovePiece(Hash, ColorToMove, promotionPiece, move.To);

                    _promotedPieces.Push(promotionPiece);
                }
                else
                {
                    MovePiece(ColorToMove, pieceType, move.From, move.To);
                    Hash = ZobristHashing.MovePiece(Hash, ColorToMove, pieceType, move.From, move.To);

                    if (pieceType == Piece.Pawn)
                    {
                        PawnHash = ZobristHashing.MovePiece(PawnHash, ColorToMove, pieceType, move.From, move.To);
                    }
                }

                _killedPieces.Push(killedPiece);
            }
            else if (move.IsCastling())
            {
                // Short castling
                if (move.IsKingCastling())
                {
                    if (ColorToMove == Color.White)
                    {
                        MovePiece(Color.White, Piece.King, 3, 1);
                        MovePiece(Color.White, Piece.Rook, 0, 2);

                        Hash = ZobristHashing.MovePiece(Hash, Color.White, Piece.King, 3, 1);
                        Hash = ZobristHashing.MovePiece(Hash, Color.White, Piece.Rook, 0, 2);
                    }
                    else
                    {
                        MovePiece(Color.Black, Piece.King, 59, 57);
                        MovePiece(Color.Black, Piece.Rook, 56, 58);

                        Hash = ZobristHashing.MovePiece(Hash, Color.Black, Piece.King, 59, 57);
                        Hash = ZobristHashing.MovePiece(Hash, Color.Black, Piece.Rook, 56, 58);
                    }
                }
                // Long castling
                else
                {
                    if (ColorToMove == Color.White)
                    {
                        MovePiece(Color.White, Piece.King, 3, 5);
                        MovePiece(Color.White, Piece.Rook, 7, 4);

                        Hash = ZobristHashing.MovePiece(Hash, Color.White, Piece.King, 3, 5);
                        Hash = ZobristHashing.MovePiece(Hash, Color.White, Piece.Rook, 7, 4);
                    }
                    else
                    {
                        MovePiece(Color.Black, Piece.King, 59, 61);
                        MovePiece(Color.Black, Piece.Rook, 63, 60);

                        Hash = ZobristHashing.MovePiece(Hash, Color.Black, Piece.King, 59, 61);
                        Hash = ZobristHashing.MovePiece(Hash, Color.Black, Piece.Rook, 63, 60);
                    }
                }

                if (ColorToMove == Color.White)
                {
                    Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.WhiteShort);
                    Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.WhiteLong);
                    Castling &= ~Castling.WhiteCastling;
                }
                else
                {
                    Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.BlackShort);
                    Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.BlackLong);
                    Castling &= ~Castling.BlackCastling;
                }

                CastlingDone[ColorToMove] = true;
            }
            else if (move.IsPromotion())
            {
                var promotionPiece = GetPromotionPiece(move.Flags);

                RemovePiece(ColorToMove, pieceType, move.From);
                Hash     = ZobristHashing.AddOrRemovePiece(Hash, ColorToMove, pieceType, move.From);
                PawnHash = ZobristHashing.AddOrRemovePiece(PawnHash, ColorToMove, pieceType, move.From);

                AddPiece(ColorToMove, promotionPiece, move.To);
                Hash = ZobristHashing.AddOrRemovePiece(Hash, ColorToMove, promotionPiece, move.To);

                _promotedPieces.Push(promotionPiece);
            }

            if (pieceType == Piece.King && !move.IsCastling())
            {
                if (ColorToMove == Color.White)
                {
                    Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.WhiteShort);
                    Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.WhiteLong);
                    Castling &= ~Castling.WhiteCastling;
                }
                else
                {
                    Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.BlackShort);
                    Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.BlackLong);
                    Castling &= ~Castling.BlackCastling;
                }
            }
            else if (pieceType == Piece.Rook && Castling != 0)
            {
                if (move.From == 0)
                {
                    Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.WhiteShort);
                    Castling &= ~Castling.WhiteShort;
                }
                else if (move.From == 7)
                {
                    Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.WhiteLong);
                    Castling &= ~Castling.WhiteLong;
                }
                else if (move.From == 56)
                {
                    Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.BlackShort);
                    Castling &= ~Castling.BlackShort;
                }
                else if (move.From == 63)
                {
                    Hash      = ZobristHashing.RemoveCastlingFlag(Hash, Castling, Castling.BlackLong);
                    Castling &= ~Castling.BlackLong;
                }
            }

            ColorToMove = enemyColor;
            Hash        = ZobristHashing.ChangeSide(Hash);
        }