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