예제 #1
0
        /// <summary>
        /// Updates the hash key depending on a move
        /// </summary>
        /// <param name="move">The move the hash key is depending on</param>
        private void UpdateKey(Move move)
        {
            // TODO : Merge with MakeMove to avoid duplicate ifs

            var pawnKey = State.PawnStructureKey;
            var key     = State.Key ^ pawnKey;

            pawnKey ^= Zobrist.GetZobristSide();

            if (_stateList[PositionIndex - 1].EnPassantSquare != ESquare.none)
            {
                key ^= Zobrist.GetZobristEnPessant(_stateList[PositionIndex - 1].EnPassantSquare.File().AsInt());
            }

            if (State.EnPassantSquare != ESquare.none)
            {
                key ^= Zobrist.GetZobristEnPessant(State.EnPassantSquare.File().AsInt());
            }

            if (move.IsNullMove())
            {
                key      ^= pawnKey;
                State.Key = key;
                State.PawnStructureKey = pawnKey;
                return;
            }

            var pawnPiece = move.GetMovingPieceType() == EPieceType.Pawn;

            if (pawnPiece)
            {
                pawnKey ^= Zobrist.GetZobristPst(move.GetMovingPiece(), move.GetFromSquare());
            }
            else
            {
                key ^= Zobrist.GetZobristPst(move.GetMovingPiece(), move.GetFromSquare());
            }

            var squareTo = move.GetToSquare();

            if (move.IsPromotionMove())
            {
                key ^= Zobrist.GetZobristPst(move.GetPromotedPiece(), squareTo);
            }
            else
            {
                if (pawnPiece)
                {
                    pawnKey ^= Zobrist.GetZobristPst(move.GetMovingPiece(), squareTo);
                }
                else
                {
                    key ^= Zobrist.GetZobristPst(move.GetMovingPiece(), squareTo);
                }
            }

            if (pawnPiece && move.IsEnPassantMove())
            {
                pawnKey ^= Zobrist.GetZobristPst(move.GetCapturedPiece().Type() + (State.SideToMove << 3), squareTo + (State.SideToMove.Side == 0 ? 8 : -8));
            }
            else if (move.IsCaptureMove())
            {
                if (pawnPiece)
                {
                    pawnKey ^= Zobrist.GetZobristPst(move.GetCapturedPiece(), squareTo);
                }
                else
                {
                    key ^= Zobrist.GetZobristPst(move.GetCapturedPiece(), squareTo);
                }
            }
            else if (move.IsCastlelingMove())
            {
                var piece = (EPieces)(EPieceType.Rook + move.GetSideMask());
                key ^= Zobrist.GetZobristPst(piece, Position.GetRookCastleFrom(squareTo));
                key ^= Zobrist.GetZobristPst(piece, squareTo.GetRookCastleTo());
            }

            // castleling
            // castling rights
            if (State.CastlelingRights != _stateList[PositionIndex - 1].CastlelingRights)
            {
                key ^= Zobrist.GetZobristCastleling(_stateList[PositionIndex - 1].CastlelingRights);
                key ^= Zobrist.GetZobristCastleling(State.CastlelingRights);
            }

            key      ^= pawnKey;
            State.Key = key;
            State.PawnStructureKey = pawnKey;
        }