Beispiel #1
0
        public void SubmitNullMove()
        {
            states.Push(new BoardState
            {
                lastMove            = null,
                positionKey         = positionKey,
                enPassentSquare     = EnPassentSquare,
                castelingRights     = CastelingRights,
                materialKey         = materialKey,
                WhitePawnBitboard   = WhitePawnBitboard,
                BlackPawnBitboard   = BlackPawnBitboard,
                WhitePiecesBitboard = WhitePiecesBitboard,
                BlackPiecesBitboard = BlackPiecesBitboard
            });

            //No EnPassent in NullMovePruning
            EnPassentSquare = -1;
            Ply++;

            Us   = Them;
            Them = Piece.OtherColor(Us);
            ZobristKey.ColorChanged(ref positionKey);
        }
Beispiel #2
0
        //We assume the submitted move is legal
        public void SubmitMove(Move move)
        {
            states.Push(new BoardState //Save the current state to the history
            {
                lastMove            = move,
                positionKey         = positionKey,
                materialKey         = materialKey,
                enPassentSquare     = EnPassentSquare,
                castelingRights     = CastelingRights,
                WhitePawnBitboard   = WhitePawnBitboard,
                BlackPawnBitboard   = BlackPawnBitboard,
                WhitePiecesBitboard = WhitePiecesBitboard,
                BlackPiecesBitboard = BlackPiecesBitboard
            });
            Ply++;
            board[move.Start] = Piece.NONE;
            pieceList[move.MovedPiece].Remove(move.Start);
            if (move.Promotion != Piece.NONE)
            {
                var promotedPiece = (Piece.COLOR_MASK & move.MovedPiece) | move.Promotion;
                board[move.Target] = promotedPiece;
                pieceList[promotedPiece].Add(move.Target);

                //Update material key
                MaterialKey.RemovePiece(move.MovedPiece, ref materialKey);
                MaterialKey.AddPiece(promotedPiece, ref materialKey);

                //Update Zobrist key
                ZobristKey.PieceMoved(move.MovedPiece, move.Start, -1, ref positionKey);
                ZobristKey.PieceMoved(promotedPiece, move.Target, -1, ref positionKey);

                //Update piece and pawn Bitboards
                if (Us == Piece.WHITE)
                {
                    WhitePawnBitboard   &= ~(1ul << move.Start);
                    WhitePiecesBitboard |= 1ul << move.Target;
                }
                else // Us == Piece.BLACK
                {
                    BlackPawnBitboard   &= ~(1ul << move.Start);
                    BlackPiecesBitboard |= 1ul << move.Target;
                }
            }
            else
            {
                board[move.Target] = move.MovedPiece;
                pieceList[move.MovedPiece].Add(move.Target);

                //material key need not be updated, piece just moved

                //Update Zobrist key
                ZobristKey.PieceMoved(move.MovedPiece, move.Start, move.Target, ref positionKey);

                //Update Pawn and pieces Bitboards
                if (move.MovedPiece == (Piece.WHITE | Piece.PAWN))
                {
                    WhitePawnBitboard &= ~(1ul << move.Start);
                    WhitePawnBitboard |= 1ul << move.Target;
                }
                else if (move.MovedPiece == (Piece.BLACK | Piece.PAWN))
                {
                    BlackPawnBitboard &= ~(1ul << move.Start);
                    BlackPawnBitboard |= 1ul << move.Target;
                }
                else if (Us == Piece.WHITE)
                {
                    WhitePiecesBitboard &= ~(1ul << move.Start);
                    WhitePiecesBitboard |= 1ul << move.Target;
                }
                else
                {
                    BlackPiecesBitboard &= ~(1ul << move.Start);
                    BlackPiecesBitboard |= 1ul << move.Target;
                }
            }

            if (move.CapturedPiece != Piece.NONE)
            {
                pieceList[move.CapturedPiece].Remove(move.Target);
                //Update material key
                MaterialKey.RemovePiece(move.CapturedPiece, ref materialKey);
                //Update Zobrist Key
                ZobristKey.PieceMoved(move.CapturedPiece, move.Target, -1, ref positionKey);

                //Update pawn bitboards
                if (move.CapturedPiece == (Piece.BLACK | Piece.PAWN))
                {
                    BlackPawnBitboard &= ~(1ul << move.Target);
                }
                else if (move.CapturedPiece == (Piece.WHITE | Piece.PAWN))
                {
                    WhitePawnBitboard &= ~(1ul << move.Target);
                }
                else if (Us == Piece.WHITE)
                {
                    BlackPiecesBitboard &= ~(1ul << move.Target);
                }
                else
                {
                    WhitePiecesBitboard &= ~(1ul << move.Target);
                }
            }

            //EnPassent related stuff
            if (move.IsDoublePawnMove)
            {
                //set the enPassent square to the square behind the target
                EnPassentSquare = Us == Piece.WHITE ? move.Target - 8 : move.Target + 8;
            }
            else
            {
                //reset the enPassent square
                EnPassentSquare = -1;
            }
            if (move.IsEnPassent)
            {
                //Remove the pawn on the advanced square
                var captureSquare = Us == Piece.WHITE ? move.Target - 8 : move.Target + 8; //rank of start + file of target
                pieceList[Piece.PAWN | Them].Remove(captureSquare);
                board[captureSquare] = Piece.NONE;

                //Update material key
                MaterialKey.RemovePiece(Piece.PAWN | Them, ref materialKey);

                //Update Zobrist key
                ZobristKey.PieceMoved(Piece.PAWN | Them, captureSquare, -1, ref positionKey);

                //Update pawn bitboards
                if (Us == Piece.WHITE)
                {
                    BlackPawnBitboard &= ~(1ul << captureSquare);
                }
                else //Us == BLACK
                {
                    WhitePawnBitboard &= ~(1ul << captureSquare);
                }
            }

            //Casteling related stuff
            if (move.MovedPiece == (Piece.WHITE | Piece.KING))
            {
                //Revoke whites casteling rights after a king move
                CastelingRights &= BLACK_KINGSIDE_CASTLE | BLACK_QUEENSIDE_CASTLE;
            }
            else if (move.MovedPiece == (Piece.BLACK | Piece.KING))
            {
                //Revoke blacks casteling rights after a king move
                CastelingRights &= WHITE_KINGSIDE_CASTLE | WHITE_QUEENSIDE_CASTLE;
            }
            else
            {
                //Revoke whites casteling rights if the correpsonding rook moved or was captured
                if (move.Start == 0 || move.Target == 0) //A1
                {
                    CastelingRights &= ~WHITE_QUEENSIDE_CASTLE;
                }
                if (move.Start == 7 || move.Target == 7) //H1
                {
                    CastelingRights &= ~WHITE_KINGSIDE_CASTLE;
                }
                //Revoke blacks casteling rights if the correpsonding rook moved or was captured
                if (move.Start == 7 * 8 || move.Target == 7 * 8) //A8
                {
                    CastelingRights &= ~BLACK_QUEENSIDE_CASTLE;
                }
                if (move.Start == 7 * 8 + 7 || move.Target == 7 * 8 + 7) //H8
                {
                    CastelingRights &= ~BLACK_KINGSIDE_CASTLE;
                }
            }
            if (move.IsCasteling)
            {
                //We need not revoke casteling rights after castle, this has already happend
                //We only need to move the rook

                int rookStart, rookEnd;
                switch (move.Target)
                {
                case 2:            //C1
                    rookStart = 0; //A1
                    rookEnd   = 3; //D1
                    break;

                case 6:            //G1
                    rookStart = 7; //H1
                    rookEnd   = 5; //F1
                    break;

                case 7 * 8 + 2:            //C8
                    rookStart = 7 * 8;     //A8
                    rookEnd   = 7 * 8 + 3; //D8
                    break;

                case 7 * 8 + 6:            //G8
                    rookStart = 7 * 8 + 7; //H8
                    rookEnd   = 7 * 8 + 5; //F8
                    break;

                default:
                    throw new Exception("Illegal casteling move: " + move.ToAlgebraicNotation());
                }
                var pieceType = Piece.ROOK | Us;
                board[rookStart] = Piece.NONE;
                board[rookEnd]   = pieceType;
                pieceList[pieceType].Remove(rookStart);
                pieceList[pieceType].Add(rookEnd);
                ZobristKey.PieceMoved(pieceType, rookStart, rookEnd, ref positionKey);

                if (Us == Piece.WHITE)
                {
                    WhitePiecesBitboard &= ~(1ul << rookStart);
                    WhitePiecesBitboard |= 1ul << rookEnd;
                }
                else
                {
                    BlackPiecesBitboard &= ~(1ul << rookStart);
                    BlackPiecesBitboard |= 1ul << rookEnd;
                }
            }

            Us   = Them;
            Them = Piece.OtherColor(Us);
            ZobristKey.ColorChanged(ref positionKey);
        }