Пример #1
0
        private void OneObject(InputResult inputResult)
        {
            var obj = inputResult.Objects.Single();

            inputResult.Grammar = inputResult.Verb.Grammars.FirstOrDefault(x => x.Preposition == inputResult.Preposition);
            string msg = "What do you want to {0} the {1} {2}?".F(inputResult.Verb.Name, obj.Name, inputResult.Preposition);

            Context.Output.Print(msg);

            string reply = Context.CommandPrompt.GetInput();

            if (string.IsNullOrEmpty(reply))
            {
                inputResult.Action = UserInput.ErrorAction(L.DoNotUnderstand);
            }

            var tokenizer = new InputTokenizer();
            var tokens    = tokenizer.Tokenize(reply);

            //TODO: this should fail in some cases
            string input = null;

            if (!tokens.StartsWithVerb())
            {
                input = "{0} {1} {2} {3}".F(inputResult.Verb.Name, obj.Synonyms[0], inputResult.Preposition, reply);
            }
            else
            {
                input = reply;
            }

            inputResult.ParserResults.AddRange(Context.Parser.Parse(input));
            inputResult.Handled = true;
        }
Пример #2
0
        private void NoObject(InputResult inputResult)
        {
            string msg = "What do you want to {0}?".F(inputResult.Verb.Name);

            Context.Output.Print(msg);

            string reply = Context.CommandPrompt.GetInput();

            if (string.IsNullOrEmpty(reply))
            {
                inputResult.Action = UserInput.ErrorAction(L.DoNotUnderstand);
            }

            var tokenizer = new InputTokenizer();
            var tokens    = tokenizer.Tokenize(reply);

            string input = null;

            if (!tokens.StartsWithVerb())
            {
                input = "{0} {1}".F(inputResult.Verb.Name, reply);
            }
            else
            {
                input = reply;
            }

            Context.Parser.Parse(input);
            //inputResult.ParserResults.AddRange();
            inputResult.Handled = true;
        }
Пример #3
0
        private IList <String> Parse(string input, bool showOutput)
        {
            Context.Parser         = this;
            Context.Object         = null;
            Context.IndirectObject = null;

            results = new List <ParserResult>();

            var  L      = new Library();
            bool wasLit = L.IsLit();

            var userInput = new UserInput();

            if (inputResult != null && inputResult.IsAskingQuestion)
            {
                var tokenizer = new InputTokenizer();
                var tokens    = tokenizer.Tokenize(input);

                if (!tokens.StartsWithVerb())
                {
                    string temp = null;
                    if (inputResult.Verb.IsNull == false)
                    {
                        temp += inputResult.Verb.Name + " ";
                    }
                    if (inputResult.Objects.Count > 0)
                    {
                        temp += inputResult.Objects[0].Synonyms[0] + " ";
                    }
                    if (!string.IsNullOrEmpty(inputResult.Preposition))
                    {
                        temp += inputResult.Preposition + " ";
                    }
                    if (inputResult.IndirectObject != null)
                    {
                        temp += inputResult.IndirectObject.Name + " ";
                    }
                    if (temp != null)
                    {
                        input = temp + input;
                    }
                }
            }

            inputResult = userInput.Parse(input);

            if (!inputResult.Handled)
            {
                HandleInputResult();
            }

            if (!wasLit && L.IsLit())
            {
                L.Look(true);
            }

            return(GetResults(showOutput, inputResult.ParserResults));
        }
Пример #4
0
        private void HandleInputResult(InputResult inputResult)
        {
            CommandBuilder builder  = new CommandBuilder(inputResult);
            var            commands = builder.Build();

            foreach (var command in commands)
            {
                ExecuteCommand(command);
            }
        }
Пример #5
0
 private void FindVerb(InputResult result, IEnumerable <Verb> possibleVerbs, IEnumerable <string> grammars)
 {
     foreach (var verb in possibleVerbs)
     {
         if (FindGrammar(result, verb, grammars))
         {
             result.Verb = verb;
             return;
         }
     }
 }
Пример #6
0
        private static InputResult WhatDoYouWantToDo(InputResult result)
        {
            var verb = result.Verb.Name;

            return(new InputResult
            {
                Action = () =>
                {
                    Context.Parser.Print($"What do you want to {verb}?");
                    return true;
                }
            });
        }
Пример #7
0
        private bool FindGrammar(InputResult result, Verb verb, IEnumerable <string> grammars)
        {
            foreach (var possibleGrammar in grammars)
            {
                var matchedGrammar = verb.Grammars.FirstOrDefault(x => x.Format == possibleGrammar);

                if (matchedGrammar != null)
                {
                    result.Grammar = matchedGrammar;
                    return(true);
                }
            }

            return(false);
        }
Пример #8
0
        public void Handle(InputResult inputResult)
        {
            L = new Library();

            if (inputResult.Preposition.HasValue())
            {
                if (inputResult.Objects.Count == 1)
                {
                    OneObject(inputResult);
                }
            }
            else
            {
                inputResult.Grammar = inputResult.Verb.Grammars.First();
                if (inputResult.Preposition.HasValue())
                {
                    // dupe code from block above
                    if (inputResult.Objects.Count == 1)
                    {
                        OneObject(inputResult);
                    }
                    else if (inputResult.Objects.Count > 1)
                    {
                        MultipleObjects(inputResult);
                    }
                    else
                    {
                        NoObject(inputResult);
                    }
                }
            }

            //if (inputResult.Grammar == null)
            //{
            //    throw new Exception("What do we do with no Grammar?");
            //}

            //return false;
        }
Пример #9
0
 public CommandBuilder(InputResult inputResult)
 {
     this.inputResult = inputResult;
 }
Пример #10
0
 private void MultipleObjects(InputResult inputResult)
 {
     inputResult.ParserResults.Add(L.DidntUnderstandSentence);
     inputResult.Handled = true;
 }
Пример #11
0
        public InputResult Parse(string input)
        {
            var result = new InputResult();

            var tokenizer = new InputTokenizer();
            var tokens    = tokenizer.Tokenize(input);

            if (tokens.Count == 0)
            {
                result.Action = () =>
                {
                    Context.Parser.Print(L.DoNotUnderstand);
                    return(true);
                };
                return(result);
            }

            // there can be more than one match for verbs like "switch"
            // which has one class that handles "switch on" and another
            // class that handles "switch off"
            var possibleVerbs = VerbList.GetVerbsByName(tokens[0]);

            if (possibleVerbs.Count == 0)
            {
                result.Verb   = new NullVerb();
                result.Action = ErrorAction(L.VerbNotRecognized);
                return(result);
            }

            if (possibleVerbs.Count == 1)
            {
                result.Verb = possibleVerbs.First();
            }

            // remove verb token
            tokens.RemoveAt(0);

            var  grammarTokens  = new List <string>();
            bool hasPreposition = false;

            foreach (string token in tokens)
            {
                // var objects = Objects.WithName(token);
                var objects = (
                    from o in Objects.WithName(token)
                    where L.ObjectsInScope().Contains(o)
                    select o
                    ).ToList();

                bool hasObject = result.Objects.Count > 0;

                if (!hasObject)
                {
                    var rooms = Rooms.WithName(token);
                    foreach (var room in rooms)
                    {
                        objects.Add(room);
                    }
                }

                if (objects.Count == 0)
                {
                    bool isDirection = possibleVerbs.Count == 1 &&
                                       Compass.Directions.Contains(token) &&
                                       result.Objects.Count == 0;
                    bool isPreposition = Prepositions.Contains(token);

                    if (isDirection)
                    {
                        possibleVerbs.Clear();
                        possibleVerbs.Add(VerbList.GetVerbByName(token));
                    }
                    else if (isPreposition)
                    {
                        hasPreposition = true;
                        grammarTokens.Add(token);
                        result.Preposition = token;
                    }
                    else if (token == K.ALL)
                    {
                        grammarTokens.Add(token);
                        result.IsAll = true;
                    }
                    else if (token == K.EXCEPT)
                    {
                        if (!result.IsAll && !result.Objects.Any())
                        {
                            result.Action = ErrorAction(L.CantSeeObject);
                            return(result);
                        }
                        result.IsExcept = true;
                    }
                    else
                    {
                        result.Action = ErrorAction(L.CantSeeObject);
                        return(result);
                    }
                }
                else
                {
                    // need to implement "Which do you mean, the red cape or the black cape?" type behavior here
                    Object obj;
                    var    ofInterest = objects.Where(x => x.InScope).ToList();

                    if (ofInterest.Count > 1)
                    {
                        obj = ofInterest.FirstOrDefault(x => x.InInventory);
                    }
                    else
                    {
                        obj = ofInterest.FirstOrDefault();
                    }

                    //-------------------------------------------------------------------------------------

                    bool isIndirectObject = hasPreposition && hasObject;

                    if (obj == null)
                    {
                        result.Action = ErrorAction(L.CantSeeObject);
                        return(result);
                    }

                    if (isIndirectObject)
                    {
                        grammarTokens.Add(K.INDIRECT_OBJECT_TOKEN);
                        result.IndirectObject = obj;
                    }
                    else if (result.IsExcept)
                    {
                        result.Exceptions.Add(obj);
                    }
                    else
                    {
                        if (!grammarTokens.Contains(K.OBJECT_TOKEN))
                        {
                            grammarTokens.Add(K.OBJECT_TOKEN);
                        }
                        if (!result.Objects.Contains(obj))
                        {
                            result.Objects.Add(obj);
                        }
                    }
                }
            }

            result.Pregrammar = string.Join(" ", grammarTokens.ToArray());

            var grammarBuilder = new GrammarBuilder(grammarTokens);
            var grammars       = grammarBuilder.Build();

            FindVerb(result, possibleVerbs, grammars);

            if ((result.IsAll || result.Objects.Count > 1) && !result.Verb.AllowsMulti)
            {
                return(DoesNotAllowMulti());
            }

            if (result.Grammar == null)
            {
                var incomplete = new IncompleteInput();
                incomplete.Handle(result);
            }

            if (result.IsAll)
            {
                if (result.ObjectsMustBeHeld)
                {
                    result.Objects = Inventory.Items.Reverse().ToList();
                }
                else
                {
                    // This is different from Inform 6 which will include scenery and static
                    // objects (resulting in the generation of ridiculous messages like
                    // "well house: that's hardly portable"
                    result.Objects = (
                        from o in L.ObjectsInScope()
                        where o != L.CurrentLocation && !o.IsScenery && !o.IsStatic &&
                        !Inventory.Contains(o)
                        select o
                        ).ToList();
                }
            }

            if (result.IsExcept)
            {
                if (!result.Exceptions.Any())
                {
                    return(WhatDoYouWantToDo(result));
                }

                result.Exceptions.ForEach(x => result.Objects.Remove(x));
            }

            return(result);
        }
Пример #12
0
        public InputResult Parse(string input)
        {
            var result = new InputResult();

            var tokenizer = new InputTokenizer();
            var tokens    = tokenizer.Tokenize(input);

            Action removeVerbToken = () => tokens.RemoveAt(0);

            if (tokens.Count == 0)
            {
                result.Action = () =>
                {
                    Context.Parser.Print(L.DoNotUnderstand);
                    return(true);
                };
                return(result);
            }

            // there can be more than one match for verbs like "switch"
            // which has one class that handles "switch on" and another
            // class that handles "switch off"
            var possibleVerbs = VerbList.GetVerbsByName(tokens[0]);

            if (possibleVerbs.Count == 0)
            {
                result.Verb   = new NullVerb();
                result.Action = ErrorAction(L.VerbNotRecognized);
                return(result);
            }

            if (possibleVerbs.Count == 1)
            {
                result.Verb = possibleVerbs.First();
            }
            //else { NOT sure what to do about multiple possible verbs here}


            // remove verb token
            removeVerbToken();

            var  grammarTokens  = new List <string>();
            bool hasPreposition = false;

            foreach (string token in tokens)
            {
                bool hasObject = result.Objects.Count > 0;

                var objects = Objects.WithName(token);

                if (!hasObject)
                {
                    var rooms = Rooms.WithName(token);
                    foreach (var room in rooms)
                    {
                        objects.Add(room);
                    }
                }

                if (objects.Count == 0)
                {
                    bool isDirection = possibleVerbs.Count == 1 &&
                                       Compass.Directions.Contains(token) &&
                                       result.Objects.Count == 0;
                    bool isPreposition = Prepositions.Contains(token);

                    if (isDirection)
                    {
                        possibleVerbs.Clear();
                        possibleVerbs.Add(VerbList.GetVerbByName(token));
                    }
                    else if (isPreposition)
                    {
                        hasPreposition = true;
                        grammarTokens.Add(token);
                        result.Preposition = token;
                    }
                    else if (token == K.ALL)
                    {
                        // result.Objects.AddRange(L.ObjectsInScope());
                        grammarTokens.Add(token);
                        result.IsAll = true;
                    }
                    else if (token == K.EXCEPT)
                    {
                        if (!result.IsAll && !result.Objects.Any())
                        {
                            result.Action = ErrorAction(L.CantSeeObject);
                            return(result);
                        }
                        result.IsExcept = true;
                    }
                    else
                    {
                        if (result.IsPartial)
                        {
                            string partial = String.Format("I only understood you as far as wanting to {0} the {1}.", possibleVerbs[0].Name, result.Objects[0].Name);
                            result.Action = ErrorAction(partial);
                            return(result);
                        }

                        result.Action = ErrorAction(L.CantSeeObject);
                        return(result);
                    }
                }
                else
                {
                    // need to implement "Which do you mean, the red cape or the black cape?" type behavior here
                    Object obj;
                    var    ofInterest = objects.Where(x => x.InScope).ToList();
                    if (ofInterest.Count > 1)
                    {
                        obj = ofInterest.FirstOrDefault(x => x.InInventory);
                    }
                    else
                    {
                        obj = ofInterest.FirstOrDefault();
                    }
                    //-------------------------------------------------------------------------------------

                    bool isIndirectObject = hasPreposition && hasObject;

                    if (obj == null)
                    {
                        result.Action = ErrorAction(L.CantSeeObject);
                        return(result);
                    }

                    if (isIndirectObject)
                    {
                        grammarTokens.Add(K.INDIRECT_OBJECT_TOKEN);
                        result.IndirectObject = obj;
                    }
                    else if (result.IsExcept)
                    {
                        //result.Objects.Remove(obj);
                        result.Exceptions.Add(obj);
                    }
                    else
                    {
                        if (!grammarTokens.Contains(K.OBJECT_TOKEN))
                        {
                            grammarTokens.Add(K.OBJECT_TOKEN);
                        }
                        if (!result.Objects.Contains(obj))
                        {
                            result.Objects.Add(obj);
                        }
                        result.IsPartial = true;
                    }
                }
            }

            result.Pregrammar = string.Join(" ", grammarTokens.ToArray());

            var grammarBuilder = new GrammarBuilder(grammarTokens);
            var grammars       = grammarBuilder.Build();

            FindVerb(result, possibleVerbs, grammars);

            if (result.Grammar == null)
            {
                var incomplete = new IncompleteInput();
                incomplete.Handle(result);
            }

            if (result.IsAll)
            {
                if (result.ObjectsMustBeHeld)
                {
                    result.Objects = result.Objects.Where(x => x.InInventory).ToList();
                }
                else
                {
                    result.Objects = L.ObjectsInScope();
                }
            }

            if (result.IsExcept)
            {
                result.Exceptions.ForEach(x => result.Objects.Remove(x));
            }

            return(result);
        }