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; }
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; }
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)); }
private void HandleInputResult(InputResult inputResult) { CommandBuilder builder = new CommandBuilder(inputResult); var commands = builder.Build(); foreach (var command in commands) { ExecuteCommand(command); } }
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; } } }
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; } }); }
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); }
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; }
public CommandBuilder(InputResult inputResult) { this.inputResult = inputResult; }
private void MultipleObjects(InputResult inputResult) { inputResult.ParserResults.Add(L.DidntUnderstandSentence); inputResult.Handled = true; }
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); }
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); }