Example #1
0
    /// <summary>
    /// Initalizes new Move from long move notation
    /// </summary>
    /// <param name="move">
    /// Move as long string<br/>
    /// ex.:{wr - a1 - h8 - bq - e.p. - +}<br/>
    /// Or: {a1 - h8}<br/>
    /// See: move.ToString()
    /// </param>
    /// <exception cref="ChessArgumentException">Move didn't match regex pattern</exception>
    public Move(string move)
    {
        move = move.ToLower();

        var matches = Regexes.regexMove.Matches(move.ToLower());

        if (matches.Count < 1)
        {
            throw new ChessArgumentException(null, "Move should match pattern: " + Regexes.MovePattern);
        }

        foreach (var group in matches[0].Groups.Values)
        {
            if (!group.Success)
            {
                continue;
            }

            switch (group.Name)
            {
            case "2":
                Piece = new(group.Value);
                break;

            case "3":
                OriginalPosition = new(group.Value);
                break;

            case "4":
                NewPosition = new(group.Value);
                break;

            case "6":
                CapturedPiece = new(group.Value);
                break;

            case "8":
                Parameter = IMoveParameter.FromString(group.Value);
                break;

            case "10":
                if (group.Value == "+")
                {
                    IsCheck = true;
                }
                else if (group.Value == "#")
                {
                    IsCheck = true;
                    IsMate  = true;
                }
                else if (group.Value == "$")
                {
                    IsMate = true;
                }
                break;
            }
        }
    }
Example #2
0
    public static (bool succeeded, ChessException?exception) TryParse(ChessBoard board, string san, out Move?move, bool resetSan = false)
    {
        move = null;

        var matches = Regexes.regexSanOneMove.Matches(san);

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

        Move     moveOut     = new();
        Position originalPos = new();
        bool     isCapture   = false;

        foreach (var group in matches[0].Groups.Values)
        {
            if (!group.Success)
            {
                continue;
            }

            switch (group.Name)
            {
            case "1":
                if (group.Value == "O-O" || group.Value == "O-O-O")
                {
                    moveOut.Parameter = IMoveParameter.FromString(group.Value);
                    if (board.Turn == PieceColor.White)
                    {
                        originalPos = new("e1");
                        if (group.Value == "O-O")
                        {
                            moveOut.NewPosition = new("h1");
                        }
                        else if (group.Value == "O-O-O")
                        {
                            moveOut.NewPosition = new("a1");
                        }
                    }
                    else if (board.Turn == PieceColor.Black)
                    {
                        originalPos = new("e8");
                        if (group.Value == "O-O")
                        {
                            moveOut.NewPosition = new("h8");
                        }
                        else if (group.Value == "O-O-O")
                        {
                            moveOut.NewPosition = new("a8");
                        }
                    }
                    // not realy needed
                    //if (!IsValidMove(new Move(originalPos, moveOut.NewPosition)))
                    //    throw new ChessSanNotFoundException(this, move);
                }
                break;

            case "2":
                moveOut.Piece = new Piece(board.Turn, PieceType.FromChar(group.Value[0]));
                break;

            case "3":
                originalPos.X = Position.FromFile(group.Value[0]);
                break;

            case "4":
                originalPos.Y = Position.FromRank(group.Value[0]);
                break;

            case "5":
                if (group.Value == "x" || group.Value == "X")
                {
                    isCapture = true;
                }
                break;

            case "6":
                moveOut.NewPosition = new Position(group.Value);
                break;

            case "7":
                moveOut.Parameter = IMoveParameter.FromString(group.Value.Trim());
                break;

            case "9":
                switch (group.Value)
                {
                case "+":
                    moveOut.IsCheck = true;
                    break;

                case "#":
                    moveOut.IsCheck = true;
                    moveOut.IsMate  = true;
                    break;

                case "$":
                    moveOut.IsMate = true;
                    break;
                }
                break;
            }
        }

        // If piece is not specified => Pawn
        moveOut.Piece ??= new Piece(board.Turn, PieceType.Pawn);

        if (isCapture && board[moveOut.NewPosition] is not null)
        {
            moveOut.CapturedPiece = board[moveOut.NewPosition];
        }

        if (!originalPos.HasValue)
        {
            var amb = GetMovesOfPieceOnPosition(moveOut.Piece, moveOut.NewPosition, board).ToList();

            if (originalPos.HasValueX)
            {
                amb = amb.Where(m => m.OriginalPosition.X == originalPos.X).ToList();

                if (amb.Count != 1)
                {
                    return(false, ThrowException(amb.Count, amb));
                }

                originalPos.Y = amb.ElementAt(0).OriginalPosition.Y;
            }
            else if (originalPos.HasValueY)
            {
                amb = amb.Where(m => m.OriginalPosition.Y == originalPos.Y).ToList();

                if (amb.Count != 1)
                {
                    return(false, ThrowException(amb.Count, amb));
                }

                originalPos.X = amb.ElementAt(0).OriginalPosition.X;
            }
            else
            {
                if (amb.Count != 1)
                {
                    return(false, ThrowException(amb.Count, amb));
                }

                originalPos.X = amb.ElementAt(0).OriginalPosition.X;
                originalPos.Y = amb.ElementAt(0).OriginalPosition.Y;
            }
            ChessException?ThrowException(int count, List <Move> moves)
            {
                if (count < 1)
                {
                    return(new ChessSanNotFoundException(board, san));
                }

                else if (count > 1)
                {
                    return(new ChessSanTooAmbiguousException(board, san, moves.ToArray()));
                }

                return(null);
            }
        }

        moveOut.OriginalPosition = originalPos;

        if (resetSan)
        {
            TryParse(board, moveOut, out var _);
        }

        move = moveOut;

        return(true, null);
    }