コード例 #1
0
        private void MakeCastlingMove(Move move)
        {
            var rookSrcIx = CastlingTables.GetCastlingRookSrcIx(move.DstIx);
            var rookDstIx = CastlingTables.GetCastlingRookDstIx(move.DstIx);

            MovePiece(move.SourceIx, move.DstIx, SideMoving, PieceType.King);
            MovePiece(rookSrcIx, rookDstIx, SideMoving, PieceType.Rook);
        }
コード例 #2
0
        public static Position MakeMove(Position shell, Move move, Position parent)
        {
            // copy data which doesn't depend on performing the move
            parent.CopyPieceBitboards(ref shell._pieceBitboards);
            parent.CopySquares(ref shell._squares);
            shell.ZobristHash      = parent.ZobristHash;
            shell.Parent           = parent;
            shell._inCheckWhite    = null;
            shell._inCheckBlack    = null;
            shell.SideToMove       = parent.SideToMove.Other();
            shell.EnPassant        = 0; // this gets set for double moves
            shell.FiftyMoveCounter = CalculateFiftyMoveCounter(parent, move);
            shell.GamePly          = parent.GamePly + 1;
            shell._historyPly      = parent._historyPly + 1;

            switch (move.MoveType)
            {
            case MoveType.Normal | MoveType.Quiet:
                shell.MakeNormalQuietMove(move);
                break;

            case MoveType.Normal | MoveType.Capture:
                shell.MakeNormalCaptureMove(move);
                break;

            case MoveType.DoubleMove | MoveType.Quiet:
                shell.MakeDoublePawnMove(move);
                break;

            case MoveType.EnPassant | MoveType.Capture:
                shell.MakeEnPassantMove(move);
                break;

            case MoveType.Promotion | MoveType.Quiet:
                shell.MakePromotionQuietMove(move);
                break;

            case MoveType.Promotion | MoveType.Capture:
                shell.MakePromotionCaptureMove(move);
                break;

            case MoveType.Castling | MoveType.Quiet:
                shell.MakeCastlingMove(move);
                break;

            default:
                throw new Exception($"Invalid move type: {move.MoveType}");
            }

            shell.CastlingRights   = parent.CastlingRights & CastlingTables.GetCastlingUpdateMask(move);
            shell._occupiedWhite   = shell.CalculateOccupied(Color.White);
            shell._occupiedBlack   = shell.CalculateOccupied(Color.Black);
            shell._occupied        = shell._occupiedWhite | shell._occupiedBlack;
            shell.ZobristHash     ^= ZobristHashing.OtherHashDiff(parent, shell);
            shell.RepetitionNumber = CalculateRepetitionNumber(shell);

            return(shell);
        }
コード例 #3
0
        private void GenerateKingCastling(List <Move> moves, Position position)
        {
            var castlingDsts = position.CastlingRights & CastlingTables.GetCastlingRightsDstColorMask(position.SideToMove);

            while (Bits.TryPopLsb(ref castlingDsts, out var dstIx))
            {
                if ((position.GetOccupied() & CastlingTables.GetCastlingEmptySquares(dstIx)) > 0)
                {
                    continue;
                }

                if (position.InCheck(position.SideToMove))
                {
                    continue;
                }

                bool attacked = false;
                foreach (var potentiallyAttackedIx in Bits.Enumerate(CastlingTables.GetCastlingAttacks(dstIx)))
                {
                    if (position.IsAttacked(potentiallyAttackedIx, position.SideToMove))
                    {
                        attacked = true;
                        break;
                    }
                }

                if (attacked)
                {
                    continue;
                }

                // if we still have castling rights, the inbetween squares aren't occupied, we aren't in check, and we aren't castling through or into check, then we should be good to go!
                int kingIx = Bits.GetLsb(position.GetPieceBitboard(position.SideToMove, PieceType.King));
                moves.Add(new Move(MoveType.Castling | MoveType.Quiet, kingIx, dstIx));
            }
        }