Example #1
0
        public void SetDefaultState()
        {
            Pieces[Color.White][Piece.Pawn]   = 65280;
            Pieces[Color.White][Piece.Rook]   = 129;
            Pieces[Color.White][Piece.Knight] = 66;
            Pieces[Color.White][Piece.Bishop] = 36;
            Pieces[Color.White][Piece.Queen]  = 16;
            Pieces[Color.White][Piece.King]   = 8;

            Pieces[Color.Black][Piece.Pawn]   = 71776119061217280;
            Pieces[Color.Black][Piece.Rook]   = 9295429630892703744;
            Pieces[Color.Black][Piece.Knight] = 4755801206503243776;
            Pieces[Color.Black][Piece.Bishop] = 2594073385365405696;
            Pieces[Color.Black][Piece.Queen]  = 1152921504606846976;
            Pieces[Color.Black][Piece.King]   = 576460752303423488;

            Occupancy[Color.White] = 65535;
            Occupancy[Color.Black] = 18446462598732840960;
            OccupancySummary       = Occupancy[Color.White] | Occupancy[Color.Black];

            EnPassant              = 0;
            Castling               = Castling.Everything;
            ColorToMove            = Color.White;
            MovesCount             = 0;
            IrreversibleMovesCount = 0;
            NullMoves              = 0;

            CastlingDone[Color.White] = false;
            CastlingDone[Color.Black] = false;

            Material[Color.White] = CalculateMaterial(Color.White);
            Material[Color.Black] = CalculateMaterial(Color.Black);

            Position[Color.White][GamePhase.Opening] = CalculatePosition(Color.White, GamePhase.Opening);
            Position[Color.White][GamePhase.Ending]  = CalculatePosition(Color.White, GamePhase.Ending);
            Position[Color.Black][GamePhase.Opening] = CalculatePosition(Color.Black, GamePhase.Opening);
            Position[Color.Black][GamePhase.Ending]  = CalculatePosition(Color.Black, GamePhase.Ending);

            Array.Fill(PieceTable, -1);

            CalculatePieceTable(PieceTable);

            Hash     = ZobristHashing.CalculateHash(this);
            PawnHash = ZobristHashing.CalculatePawnHash(this);

            MaterialAtOpening = CalculateMaterialAtOpening();

            _killedPieces.Clear();
            _enPassants.Clear();
            _castlings.Clear();
            _promotedPieces.Clear();
            _hashes.Clear();
            _pawnHashes.Clear();
            _irreversibleMovesCounts.Clear();
        }
Example #2
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 #3
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);
        }