/// <summary> /// Parses Move object into Standard Algebraic Notation move-string /// </summary> /// <param name="move">Move to parse</param> /// <returns>Parsed Move in SAN</returns> /// <exception cref="ArgumentNullException">Given move was null or didn't have valid positions values</exception> public string ParseToSan(Move move) { var(succeeded, exception) = SanBuilder.TryParse(this, move, out var san); if (!succeeded && exception is not null) { throw exception; } return(san !); }
/// <summary> /// Parses San-notated move into Move object<br/> /// Long algebraic notation is also acceptable /// </summary> /// <param name="san">San-notated move to parse</param> /// <param name="resetSan">Whether SAN needs to be regenerated</param> /// <returns>Parsed Move object</returns> /// <exception cref="ChessArgumentException">Given San-notated move didn't match the Regex pattern</exception> /// <exception cref="ChessSanNotFoundException">Given San-notated move is not valid for current board positions</exception> /// <exception cref="ChessSanTooAmbiguousException">Given San-notated move is too ambiguous between multiple moves</exception> public Move ParseFromSan(string san, bool resetSan = false) { var(succeeded, exception) = SanBuilder.TryParse(this, san, out var move, resetSan); if (!succeeded && exception is not null) { throw exception; } return(move !); }
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); }
/// <summary> /// Tries to /// parse Move object into Standard Algebraic Notation move-string /// </summary> /// <param name="move">Move to parse</param> /// <param name="san">Result with parsed SAN-string</param> /// <returns>Whether convertion succeeded</returns> public bool TryParseToSan(Move move, [NotNullWhen(true)] out string?san) { return(SanBuilder.TryParse(this, move, out san).succeeded); }
/// <summary> /// Tries to /// parse San-notated move into Move object<br/> /// Long algebraic notation is also acceptable /// </summary> /// <param name="san">San-notated move to parse</param> /// <param name="move">Result with parsed Move object</param> /// <param name="resetSan">Whether SAN needs to be regenerated</param> /// <returns>Whether convert succeeded</returns> public bool TryParseFromSan(string san, [NotNullWhen(true)] out Move?move, bool resetSan = false) { return(SanBuilder.TryParse(this, san, out move, resetSan).succeeded); }