private static Bitboard[] InitializeKnightAttacksOrMoves() { var result = new Bitboard[ChessConstants.SquareCount]; for (var squareIndex = 0; squareIndex < ChessConstants.SquareCount; squareIndex++) { var square = new Square(squareIndex); var moveSquares = ChessHelper.GetKnightMoveSquares(square); var bitboard = new Bitboard(moveSquares); result[squareIndex] = bitboard; } return(result); }
private static bool TryCreateInternal( [NotNull] string fen, out string errorDetails, out StandardGamePosition result) { if (fen.IsNullOrWhiteSpace()) { errorDetails = "The FEN cannot be empty."; result = null; return(false); } var fenSnippets = fen .Trim() .Split(ChessConstants.FenSnippetSeparator.AsArray(), StringSplitOptions.None); if (fenSnippets.Length != ChessConstants.FenSnippetCount) { errorDetails = "Invalid FEN format."; result = null; return(false); } var piecePositionFen = fenSnippets[0]; if (!PiecePosition.TryCreate(piecePositionFen, out var piecePosition)) { errorDetails = "Invalid position of pieces."; result = null; return(false); } var activeSideSnippet = fenSnippets[1]; if (!ChessConstants.FenSnippetToGameSideMap.TryGetValue(activeSideSnippet, out var activeSide)) { errorDetails = "Invalid active side."; result = null; return(false); } var castlingOptions = CastlingOptions.None; var castlingOptionsSnippet = fenSnippets[2]; if (castlingOptionsSnippet != ChessConstants.NoneCastlingOptionsFenSnippet) { var castlingOptionsSnippetSet = OmnifactotumCollectionExtensions.ToHashSet(castlingOptionsSnippet); foreach (var optionChar in castlingOptionsSnippetSet) { if (!ChessConstants.FenCharCastlingOptionMap.TryGetValue(optionChar, out var option)) { errorDetails = "Invalid castling options."; result = null; return(false); } castlingOptions |= option; } } EnPassantCaptureInfo2?enPassantCaptureInfo = null; var enPassantCaptureTargetSnippet = fenSnippets[3]; if (enPassantCaptureTargetSnippet != ChessConstants.NoEnPassantCaptureFenSnippet) { const string InvalidEnPassant = "Invalid en-passant."; var captureSquare = Square.TryFromAlgebraic(enPassantCaptureTargetSnippet); if (!captureSquare.HasValue) { errorDetails = InvalidEnPassant; result = null; return(false); } var enPassantInfo = ChessConstants.GameSideToDoublePushInfoMap.Values.SingleOrDefault( obj => obj.CaptureTargetRank == captureSquare.Value.Rank); if (enPassantInfo is null) { errorDetails = InvalidEnPassant; result = null; return(false); } enPassantCaptureInfo = new EnPassantCaptureInfo2( captureSquare.Value, new Square(captureSquare.Value.File, enPassantInfo.EndRank)); } var halfMovesBy50MoveRuleSnippet = fenSnippets[4]; if (!ChessHelper.TryParseInt(halfMovesBy50MoveRuleSnippet, out var halfMovesBy50MoveRule) || halfMovesBy50MoveRule < 0) { errorDetails = "Invalid half move counter for the 50 move rule."; result = null; return(false); } var fullMoveIndexSnippet = fenSnippets[5]; if (!ChessHelper.TryParseInt(fullMoveIndexSnippet, out var fullMoveIndex) || fullMoveIndex <= 0) { errorDetails = "Invalid move index."; result = null; return(false); } result = new StandardGamePosition( piecePosition, activeSide, fullMoveIndex, castlingOptions, enPassantCaptureInfo, halfMovesBy50MoveRule); errorDetails = null; return(true); }