Beispiel #1
0
        public ulong Perft(int depth)
        {
            var mg = new MoveGenerator(Position);

            mg.GenerateMoves();
            if (depth == 1)
            {
                return((ulong)mg.Moves.Count);
            }

            var(found, entry) = Table.Probe(Position.State.Key);

            if (found && entry.Key32 == (uint)(Position.State.Key >> 32) && entry.Depth == depth)
            {
                return((ulong)entry.Value);
            }

            var tot = 0ul;

            var move = MoveExtensions.EmptyMove;

            for (var i = 0; i < mg.Moves.Count; ++i)
            {
                move = mg.Moves.GetMove(i);
                MakeMove(move);
                tot += Perft(depth - 1);
                TakeMove();
            }

            if (move != MoveExtensions.EmptyMove)
            {
                Table.Store(Position.State.Key, (int)tot, Bound.Exact, (sbyte)depth, move, 0);
            }

            return(tot);
        }
Beispiel #2
0
        /// <summary>
        /// <para>"Validates" a move using simple logic. For example that the piece actually being moved exists etc.</para>
        /// <para>This is basically only useful while developing and/or debugging</para>
        /// </summary>
        /// <param name="move">The move to check for logical errors</param>
        /// <returns>True if move "appears" to be legal, otherwise false</returns>
        public bool IsPseudoLegal(Move move)
        {
            // Verify that the piece actually exists on the board at the location defined by the move struct
            if ((_bitboardPieces[move.GetMovingPiece().ToInt()] & move.GetFromSquare()).Empty())
            {
                return(false);
            }

            var to = move.GetToSquare();

            if (move.IsCastlelingMove())
            {
                // TODO : Basic castleling verification
                if (CanCastle(move.GetFromSquare() < to ? ECastleling.Short : ECastleling.Long))
                {
                    return(true);
                }

                var mg = new MoveGenerator(Position);
                mg.GenerateMoves();
                return(mg.Moves.Contains(move));
            }
            else if (move.IsEnPassantMove())
            {
                // TODO : En-passant here

                // TODO : Test with unit test
                var opponent = ~move.GetMovingSide();
                if (EnPassantSquare.PawnAttack(opponent) & Position.Pieces(EPieceType.Pawn, opponent))
                {
                    return(true);
                }
            }
            else if (move.IsCaptureMove())
            {
                var opponent = ~move.GetMovingSide();
                if ((_occupiedBySide[opponent.Side] & to).Empty())
                {
                    return(false);
                }

                if ((_bitboardPieces[move.GetCapturedPiece().ToInt()] & to).Empty())
                {
                    return(false);
                }
            }
            else if ((_occupied & to) != 0)
            {
                return(false);
            }

            // ReSharper disable once SwitchStatementMissingSomeCases
            switch (move.GetMovingPiece().Type())
            {
            case EPieceType.Bishop:
            case EPieceType.Rook:
            case EPieceType.Queen:
                if (move.GetFromSquare().BitboardBetween(to) & _occupied)
                {
                    return(false);
                }

                break;
            }

            return(true);
        }