예제 #1
0
    /// <summary>
    /// Initializes new Piece by given color and type as:<br/>
    /// "wp" => White Pawn<br/>
    /// "br" => Black Rook<br/>
    /// See: piece.ToString()<br/>
    /// </summary>
    public Piece(string piece)
    {
        if (!Regexes.regexPiece.IsMatch(piece))
        {
            throw new ChessArgumentException(null, "Piece should match pattern: " + Regexes.PiecePattern);
        }

        Color = PieceColor.FromChar(piece[0]);
        Type  = PieceType.FromChar(piece[1]);
    }
예제 #2
0
    internal static (bool succeeded, ChessException?exception) TryLoad(string fen, out FenBoardBuilder?builder)
    {
        builder = null;

        var matches = Regexes.regexFen.Matches(fen);

        if (matches.Count == 0)
        {
            return(false, new ChessArgumentException(null, "FEN board string should match pattern: " + Regexes.FenPattern));
        }

        builder = new FenBoardBuilder();

        foreach (var group in matches[0].Groups.Values)
        {
            switch (group.Name)
            {
            case "1":
                // Set pieces to given positions
                int x = 0, y = 7;
                for (int i = 0; i < group.Length; i++)
                {
                    if (group.Value[i] == '/')
                    {
                        y--;
                        x = 0;
                        continue;
                    }
                    if (x < 8)
                    {
                        if (char.IsLetter(group.Value[i]))
                        {
                            builder.pieces[y, x] = new Piece(group.Value[i]);
                            x++;
                        }
                        else if (char.IsDigit(group.Value[i]))
                        {
                            x += int.Parse(group.Value[i].ToString());
                        }
                    }
                }
                break;

            case "3":
                builder.Turn = PieceColor.FromChar(group.Value[0]);
                break;

            case "4":
                if (group.Value != "-")
                {
                    if (group.Value.Contains('K'))
                    {
                        builder.CastleWK = true;
                    }
                    if (group.Value.Contains('Q'))
                    {
                        builder.CastleWQ = true;
                    }
                    if (group.Value.Contains('k'))
                    {
                        builder.CastleBK = true;
                    }
                    if (group.Value.Contains('q'))
                    {
                        builder.CastleBQ = true;
                    }
                }
                break;

            case "5":
                if (group.Value == "-")
                {
                    builder.EnPassant = new();
                }
                else
                {
                    builder.EnPassant = new Position(group.Value);
                }
                break;

            case "6":
                (builder.HalfMoves, builder.FullMoves) = group.Value.Split(' ').Select(s => int.Parse(s)).ToArray();
                break;
            }
        }

        var wcap = new List <Piece>();
        var bcap = new List <Piece>();

        var fpieces = builder.pieces.Cast <Piece>().Where(p => p is not null);

        // Calculating missing pieces on according begin pieces in fen
        // Math.Clamp() for get max/min taken figures (2 queens possible)
        wcap.AddRange(Enumerable.Range(0, Math.Clamp(8 - fpieces.Where(p => p.Type == PieceType.Pawn && p.Color == PieceColor.White).Count(), 0, 8)).Select(_ => new Piece(PieceColor.White, PieceType.Pawn)));
        wcap.AddRange(Enumerable.Range(0, Math.Clamp(2 - fpieces.Where(p => p.Type == PieceType.Rook && p.Color == PieceColor.White).Count(), 0, 2)).Select(_ => new Piece(PieceColor.White, PieceType.Rook)));
        wcap.AddRange(Enumerable.Range(0, Math.Clamp(2 - fpieces.Where(p => p.Type == PieceType.Bishop && p.Color == PieceColor.White).Count(), 0, 2)).Select(_ => new Piece(PieceColor.White, PieceType.Bishop)));
        wcap.AddRange(Enumerable.Range(0, Math.Clamp(2 - fpieces.Where(p => p.Type == PieceType.Knight && p.Color == PieceColor.White).Count(), 0, 2)).Select(_ => new Piece(PieceColor.White, PieceType.Knight)));
        wcap.AddRange(Enumerable.Range(0, Math.Clamp(1 - fpieces.Where(p => p.Type == PieceType.Queen && p.Color == PieceColor.White).Count(), 0, 1)).Select(_ => new Piece(PieceColor.White, PieceType.Queen)));

        bcap.AddRange(Enumerable.Range(0, Math.Clamp(8 - fpieces.Where(p => p.Type == PieceType.Pawn && p.Color == PieceColor.Black).Count(), 0, 8)).Select(_ => new Piece(PieceColor.Black, PieceType.Pawn)));
        bcap.AddRange(Enumerable.Range(0, Math.Clamp(2 - fpieces.Where(p => p.Type == PieceType.Rook && p.Color == PieceColor.Black).Count(), 0, 2)).Select(_ => new Piece(PieceColor.Black, PieceType.Rook)));
        bcap.AddRange(Enumerable.Range(0, Math.Clamp(2 - fpieces.Where(p => p.Type == PieceType.Bishop && p.Color == PieceColor.Black).Count(), 0, 2)).Select(_ => new Piece(PieceColor.Black, PieceType.Bishop)));
        bcap.AddRange(Enumerable.Range(0, Math.Clamp(2 - fpieces.Where(p => p.Type == PieceType.Knight && p.Color == PieceColor.Black).Count(), 0, 2)).Select(_ => new Piece(PieceColor.Black, PieceType.Knight)));
        bcap.AddRange(Enumerable.Range(0, Math.Clamp(1 - fpieces.Where(p => p.Type == PieceType.Queen && p.Color == PieceColor.Black).Count(), 0, 1)).Select(_ => new Piece(PieceColor.Black, PieceType.Queen)));

        builder.WhiteCaptured = wcap.ToArray();
        builder.BlackCaptured = bcap.ToArray();

        return(true, null);
    }