Example #1
0
        public void UndoNullMove()
        {
            PopHistoryValues();
            ChangeSideToMove();

            if (EngineConstants.Assert)
            {
                ChessBoardTestUtil.TestValues(this);
            }
        }
Example #2
0
        public void DoNullMove()
        {
            PushHistoryValues();

            ZobristKey ^= Zobrist.SideToMove;
            if (EpIndex != 0)
            {
                ZobristKey ^= Zobrist.EpIndex[EpIndex];
                EpIndex     = 0;
            }

            ChangeSideToMove();

            if (EngineConstants.Assert)
            {
                ChessBoardTestUtil.TestValues(this);
            }
        }
Example #3
0
        public void UndoMove(int move)
        {
            var fromIndex          = MoveUtil.GetFromIndex(move);
            var toIndex            = MoveUtil.GetToIndex(move);
            var toMask             = 1L << toIndex;
            var fromToMask         = (1L << fromIndex) ^ toMask;
            var sourcePieceIndex   = MoveUtil.GetSourcePieceIndex(move);
            var attackedPieceIndex = MoveUtil.GetAttackedPieceIndex(move);

            PopHistoryValues();

            // undo move
            Pieces[ColorToMoveInverse][All] ^= fromToMask;
            Pieces[ColorToMoveInverse][sourcePieceIndex] ^= fromToMask;
            PieceIndexes[fromIndex] = sourcePieceIndex;
            PsqtScore += EvalConstants.Psqt[sourcePieceIndex][ColorToMoveInverse][fromIndex] -
                         EvalConstants.Psqt[sourcePieceIndex][ColorToMoveInverse][toIndex];

            switch (sourcePieceIndex)
            {
            case Empty:
                // not necessary but provides a table-index
                break;

            case Pawn:
                PawnZobristKey ^= Zobrist.Piece[ColorToMoveInverse][Pawn][fromIndex];
                if (MoveUtil.IsPromotion(move))
                {
                    Phase       += EvalConstants.Phase[MoveUtil.GetMoveType(move)];
                    MaterialKey -= MaterialUtil.Values[ColorToMoveInverse][MoveUtil.GetMoveType(move)] -
                                   MaterialUtil.Values[ColorToMoveInverse][Pawn];
                    Pieces[ColorToMoveInverse][Pawn] ^= toMask;
                    Pieces[ColorToMoveInverse][MoveUtil.GetMoveType(move)] ^= toMask;
                    PsqtScore += EvalConstants.Psqt[Pawn][ColorToMoveInverse][toIndex]
                                 - EvalConstants.Psqt[MoveUtil.GetMoveType(move)][ColorToMoveInverse][toIndex];
                }
                else
                {
                    PawnZobristKey ^= Zobrist.Piece[ColorToMoveInverse][Pawn][toIndex];
                }

                break;

            case King:
                if (MoveUtil.IsCastlingMove(move))
                {
                    CastlingUtil.UncastleRookUpdatePsqt(this, toIndex);
                }

                KingIndex[ColorToMoveInverse] = fromIndex;
                break;
            }

            // undo hit
            switch (attackedPieceIndex)
            {
            case Empty:
                break;

            case Pawn:
                if (MoveUtil.IsEpMove(move))
                {
                    PieceIndexes[toIndex] = Empty;
                    toIndex += ColorFactor8[ColorToMove];
                    toMask   = Util.PowerLookup[toIndex];
                }

                PawnZobristKey ^= Zobrist.Piece[ColorToMove][Pawn][toIndex];
                goto default;

            // fall-through
            default:
                PsqtScore   += EvalConstants.Psqt[attackedPieceIndex][ColorToMove][toIndex];
                Phase       -= EvalConstants.Phase[attackedPieceIndex];
                MaterialKey += MaterialUtil.Values[ColorToMove][attackedPieceIndex];
                Pieces[ColorToMove][All] |= toMask;
                Pieces[ColorToMove][attackedPieceIndex] |= toMask;
                break;
            }

            PieceIndexes[toIndex] = attackedPieceIndex;
            AllPieces             = Pieces[ColorToMove][All] | Pieces[ColorToMoveInverse][All];
            EmptySpaces           = ~AllPieces;
            ChangeSideToMove();
            SetCheckingPinnedAndDiscoPieces();

            if (EngineConstants.Assert)
            {
                ChessBoardTestUtil.TestValues(this);
            }
        }
Example #4
0
        public void DoMove(int move)
        {
            MoveCount++;

            var fromIndex          = MoveUtil.GetFromIndex(move);
            var toIndex            = MoveUtil.GetToIndex(move);
            var toMask             = 1L << toIndex;
            var fromToMask         = (1L << fromIndex) ^ toMask;
            var sourcePieceIndex   = MoveUtil.GetSourcePieceIndex(move);
            var attackedPieceIndex = MoveUtil.GetAttackedPieceIndex(move);

            if (EngineConstants.Assert)
            {
                Assert.IsTrue(move != 0);
                Assert.IsTrue(attackedPieceIndex != King);
                Assert.IsTrue(attackedPieceIndex == 0 || (Util.PowerLookup[toIndex] & Pieces[ColorToMove][All]) == 0);
                Assert.IsTrue(IsValidMove(move));
            }

            PushHistoryValues();

            ZobristKey ^= Zobrist.Piece[ColorToMove][sourcePieceIndex][fromIndex] ^
                          Zobrist.Piece[ColorToMove][sourcePieceIndex][toIndex] ^ Zobrist.SideToMove;
            if (EpIndex != 0)
            {
                ZobristKey ^= Zobrist.EpIndex[EpIndex];
                EpIndex     = 0;
            }

            Pieces[ColorToMove][All] ^= fromToMask;
            Pieces[ColorToMove][sourcePieceIndex] ^= fromToMask;
            PieceIndexes[fromIndex] = Empty;
            PieceIndexes[toIndex]   = sourcePieceIndex;
            PsqtScore += EvalConstants.Psqt[sourcePieceIndex][ColorToMove][toIndex] -
                         EvalConstants.Psqt[sourcePieceIndex][ColorToMove][fromIndex];

            switch (sourcePieceIndex)
            {
            case Pawn:
                PawnZobristKey ^= Zobrist.Piece[ColorToMove][Pawn][fromIndex];
                if (MoveUtil.IsPromotion(move))
                {
                    Phase       -= EvalConstants.Phase[MoveUtil.GetMoveType(move)];
                    MaterialKey += MaterialUtil.Values[ColorToMove][MoveUtil.GetMoveType(move)] -
                                   MaterialUtil.Values[ColorToMove][Pawn];
                    Pieces[ColorToMove][Pawn] ^= toMask;
                    Pieces[ColorToMove][MoveUtil.GetMoveType(move)] |= toMask;
                    PieceIndexes[toIndex] = MoveUtil.GetMoveType(move);
                    ZobristKey           ^= Zobrist.Piece[ColorToMove][Pawn][toIndex] ^
                                            Zobrist.Piece[ColorToMove][MoveUtil.GetMoveType(move)][toIndex];
                    PsqtScore += EvalConstants.Psqt[MoveUtil.GetMoveType(move)][ColorToMove][toIndex] -
                                 EvalConstants.Psqt[Pawn][ColorToMove][toIndex];
                }
                else
                {
                    PawnZobristKey ^= Zobrist.Piece[ColorToMove][Pawn][toIndex];
                    // 2-move
                    if (InBetween[fromIndex][toIndex] != 0)
                    {
                        if ((StaticMoves.PawnAttacks[ColorToMove][
                                 BitOperations.TrailingZeroCount(InBetween[fromIndex][toIndex])]
                             & Pieces[ColorToMoveInverse][Pawn]) != 0)
                        {
                            EpIndex     = BitOperations.TrailingZeroCount(InBetween[fromIndex][toIndex]);
                            ZobristKey ^= Zobrist.EpIndex[EpIndex];
                        }
                    }
                }

                break;

            case Rook:
                if (CastlingRights != 0)
                {
                    ZobristKey    ^= Zobrist.Castling[CastlingRights];
                    CastlingRights = CastlingUtil.GetRookMovedOrAttackedCastlingRights(CastlingRights, fromIndex);
                    ZobristKey    ^= Zobrist.Castling[CastlingRights];
                }

                break;

            case King:
                KingIndex[ColorToMove] = toIndex;
                if (CastlingRights != 0)
                {
                    if (MoveUtil.IsCastlingMove(move))
                    {
                        CastlingUtil.CastleRookUpdateKeyAndPsqt(this, toIndex);
                    }

                    ZobristKey    ^= Zobrist.Castling[CastlingRights];
                    CastlingRights = CastlingUtil.GetKingMovedCastlingRights(CastlingRights, fromIndex);
                    ZobristKey    ^= Zobrist.Castling[CastlingRights];
                }

                break;
            }

            // piece hit?
            switch (attackedPieceIndex)
            {
            case Empty:
                break;

            case Pawn:
                if (MoveUtil.IsEpMove(move))
                {
                    toIndex += ColorFactor8[ColorToMoveInverse];
                    toMask   = Util.PowerLookup[toIndex];
                    PieceIndexes[toIndex] = Empty;
                }

                PawnZobristKey ^= Zobrist.Piece[ColorToMoveInverse][Pawn][toIndex];
                PsqtScore      -= EvalConstants.Psqt[Pawn][ColorToMoveInverse][toIndex];
                Pieces[ColorToMoveInverse][All]  ^= toMask;
                Pieces[ColorToMoveInverse][Pawn] ^= toMask;
                ZobristKey  ^= Zobrist.Piece[ColorToMoveInverse][Pawn][toIndex];
                MaterialKey -= MaterialUtil.Values[ColorToMoveInverse][Pawn];
                break;

            case Rook:
                if (CastlingRights != 0)
                {
                    ZobristKey    ^= Zobrist.Castling[CastlingRights];
                    CastlingRights = CastlingUtil.GetRookMovedOrAttackedCastlingRights(CastlingRights, toIndex);
                    ZobristKey    ^= Zobrist.Castling[CastlingRights];
                }

                goto default;

            // fall-through
            default:
                Phase     += EvalConstants.Phase[attackedPieceIndex];
                PsqtScore -= EvalConstants.Psqt[attackedPieceIndex][ColorToMoveInverse][toIndex];
                Pieces[ColorToMoveInverse][All] ^= toMask;
                Pieces[ColorToMoveInverse][attackedPieceIndex] ^= toMask;
                ZobristKey  ^= Zobrist.Piece[ColorToMoveInverse][attackedPieceIndex][toIndex];
                MaterialKey -= MaterialUtil.Values[ColorToMoveInverse][attackedPieceIndex];
                break;
            }

            AllPieces   = Pieces[ColorToMove][All] | Pieces[ColorToMoveInverse][All];
            EmptySpaces = ~AllPieces;
            ChangeSideToMove();
            SetCheckingPinnedAndDiscoPieces();

            if (EngineConstants.Assert)
            {
                ChessBoardTestUtil.TestValues(this);
            }
        }