Example #1
0
        private static Location InferSource(
            string partialSource,
            State ctx,
            Location destination,
            PieceKind sourceKind,
            bool isCapture)
        {
            Debug.Assert(partialSource.Length >= 0 && partialSource.Length <= 2);

            bool realIsCapture = ctx[destination].HasPiece || (sourceKind == PieceKind.Pawn && destination == ctx.EnPassantTarget);

            if (isCapture != realIsCapture)
            {
                throw new InvalidMoveException(InvalidMoveReason.BadCaptureNotation);
            }

            var  possibleSources = ctx.ActivePlayer.GetOccupiedTiles();
            char?fileChar        = (partialSource.Length == 1 && partialSource[0] >= 'a' && partialSource[0] <= 'h') ? partialSource[0] : (char?)null;
            char?rankChar        = (partialSource.Length == 1 && partialSource[0] >= '1' && partialSource[0] <= '8') ? partialSource[0] : (char?)null;

            if (partialSource.Length == 2)
            {
                var sourceLocation = Location.Parse(partialSource);
                possibleSources = new[] { ctx[sourceLocation] };
            }
            else if (fileChar != null)
            {
                var sourceFile = FileHelpers.FromChar(fileChar.Value);
                possibleSources = possibleSources.Where(t => t.Location.File == sourceFile);
            }
            else if (rankChar != null)
            {
                var sourceRank = RankHelpers.FromChar(rankChar.Value);
                possibleSources = possibleSources.Where(t => t.Location.Rank == sourceRank);
            }

            try
            {
                var sourceTile = possibleSources.Single(t => t.Piece.Kind == sourceKind
                                                        // Castling should be denoted with the special notation O-O / O-O-O, we don't want to accept Kg1 / Kc1
                                                        && ctx.Inner.IsMovePseudoLegal(t.Location, destination, allowCastling: false));
                return(sourceTile.Location);
            }
            catch (InvalidOperationException e)
            {
                throw new InvalidMoveException(InvalidMoveReason.CouldNotInferSource, e);
            }
        }
Example #2
0
        private Location?ReadLocation()
        {
            if (!CanRead(2))
            {
                return(null);
            }

            var(fileChar, rankChar) = (Peek(), Peek(1));
            if (fileChar < 'a' || fileChar > 'h')
            {
                return(null);
            }
            if (rankChar < '1' || rankChar > '8')
            {
                return(null);
            }

            return(FileHelpers.FromChar(Pop()), RankHelpers.FromChar(Pop()));
        }