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); }
/// <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); }