예제 #1
0
    /// <summary>
    /// Loads ChessBoard from Forsyth-Edwards Notation<br/>
    /// ex.:<br/>
    /// rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1
    /// </summary>
    /// <param name="fen">FEN string to load</param>
    /// <returns>ChessBoard with according positions</returns>
    /// <exception cref="ChessArgumentException">Given FEN string didn't match the Regex pattern</exception>
    public static ChessBoard LoadFromFen(string fen)
    {
        var(succeeded, exception) = FenBoardBuilder.TryLoad(fen, out var builder);

        if (!succeeded && exception is not null)
        {
            throw exception;
        }

        return(BuildBoardFromFen(builder));
    }
예제 #2
0
    /// <summary>
    /// Tries to load
    /// ChessBoard from Forsyth-Edwards Notation<br/>
    /// ex.:<br/>
    /// rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1
    /// </summary>
    /// <param name="fen">FEN string to load</param>
    /// <param name="board">Result with loaded board</param>
    /// <returns>Whether load is succeeded</returns>
    public static bool TryLoadFromFen(string fen, [NotNullWhen(true)] out ChessBoard?board)
    {
        var(succeeded, _) = FenBoardBuilder.TryLoad(fen, out var builder);

        if (!succeeded)
        {
            board = null;
            return(false);
        }

        board = BuildBoardFromFen(builder);

        return(true);
    }
예제 #3
0
    public static (bool succeeded, ChessException?exception) TryLoad(string pgn, out ChessBoard?board)
    {
        board = new();

        var headersMatches = Regexes.regexHeaders.Matches(pgn);

        if (headersMatches.Count > 0)
        {
            // Extracting headers
            for (int i = 0; i < headersMatches.Count; i++)
            {
                // [Black "Geras1mleo"]
                // Groups[1] = Black
                // Groups[2] = Geras1mleo
                board.headers.Add(headersMatches[i].Groups[1].Value,
                                  headersMatches[i].Groups[2].Value);
            }
        }

        // San move can occur in header ex. in nickname of player => remove headers from string
        pgn = Regexes.regexHeaders.Replace(pgn, "");

        // Loading fen if exist
        if (board.headers.TryGetValue("FEN", out var fen))
        {
            var(succeeded, exception) = FenBoardBuilder.TryLoad(fen, out board.FenBuilder);

            if (!succeeded)
            {
                board = null;
                return(false, exception);
            }

            board.pieces = board.FenBuilder.Pieces;

            board.HandleKingChecked();
            board.HandleEndGame();

            if (board.IsEndGame)
            {
                return(true, null);
            }
        }

        // Remove all alternatives
        pgn = Regexes.regexAlternatives.Replace(pgn, "");

        // Remove all comments
        pgn = Regexes.regexComments.Replace(pgn, "");

        // Todo Save Alternative moves(bracnhes) and Comments for moves

        var movesMatches = Regexes.regexSanMoves.Matches(pgn);

        // Execute all found moves
        for (int i = 0; i < movesMatches.Count; i++)
        {
            var(succeeded, exception) = SanBuilder.TryParse(board, movesMatches[i].Value, out var move, true);

            if (!succeeded)
            {
                board = null;
                return(false, exception);
            }

            // If san parsing succeeded => move is valid

            board.executedMoves.Add(move);
            board.DropPieceToNewPosition(move);
            board.moveIndex = board.executedMoves.Count - 1;
        }


        board.HandleKingChecked();
        board.HandleEndGame();

        // If not actual end game but game is in fact ended => someone resigned
        if (!board.IsEndGame)
        {
            if (pgn.Contains("1-0"))
            {
                board.Resign(PieceColor.Black);
            }

            else if (pgn.Contains("0-1"))
            {
                board.Resign(PieceColor.White);
            }

            else if (pgn.Contains("1/2-1/2"))
            {
                board.Draw();
            }
        }

        return(true, null);
    }