public Move Parse(State ctx) { Location source, destination; PieceKind?promotionKind; bool isKingsideCastle = (_input == "O-O" || _input == "0-0"); bool isQueensideCastle = (_input == "O-O-O" || _input == "0-0-0"); if (isKingsideCastle || isQueensideCastle) { source = StaticInfo.GetStartLocation(ctx.ActiveSide, PieceKind.King); destination = isKingsideCastle ? source.Right(2) : source.Left(2); return(new Move(source, destination)); } var sourceKind = ReadPieceKind() ?? PieceKind.Pawn; if (ReadLocation() is Location dest) { destination = dest; promotionKind = ReadPieceKind(); ReadStatus(); if (!CanRead(1)) { source = InferSource("", ctx, destination, sourceKind, isCapture: false); return(new Move(source, destination, promotionKind)); } } var partialSource = ReadPartialLocation(); bool isCapture = ReadSeparator(); destination = StrictReadLocation(); promotionKind = ReadPieceKind(); ReadStatus(); source = InferSource(partialSource, ctx, destination, sourceKind, isCapture); return(new Move(source, destination, promotionKind)); }