public static T ChooseWord <T>(this WordDictionary dict, Random.RandomSourceBase randomness, IEnumerable <Word> alreadyChosen, Func <T, bool> wordPredicate) where T : Word { _ = dict ?? throw new ArgumentNullException(nameof(dict)); _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = alreadyChosen ?? throw new ArgumentNullException(nameof(alreadyChosen)); _ = wordPredicate ?? throw new ArgumentNullException(nameof(wordPredicate)); var count = dict.CountOf <T>(); T result; int attempts = 0; const int maxAttempts = 5; do { var idx = randomness.Next(count); result = dict.GetWordAtIndex <T>(idx); attempts++; if (attempts >= maxAttempts) { // This way is much slower when lots of words match the predicate, but faster if few do. return(ChooseWordAlternate <T>(dict, randomness, alreadyChosen, wordPredicate)); } } while (alreadyChosen.Contains(result) || !wordPredicate(result)); return(result); }
public override void AddWordTemplate(Random.RandomSourceBase randomness, WordDictionary dictionary, IList <WordTemplate.Template> currentTemplate) { _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = dictionary ?? throw new ArgumentNullException(nameof(dictionary)); _ = currentTemplate ?? throw new ArgumentNullException(nameof(currentTemplate)); // Conjunctions are very simple: they either join noun clauses or entire phrases (which will require another verb clause). // I'm not allowing a conjunction to be either though. if (JoiningNounFactor > 0 && JoiningPhraseFactor > 0) { throw new Exception("Conjunctions may join noun clauses or entire phrases, but not both. Set one of JoinsNoun and JoinsPhrase to 0."); } if (JoiningNounFactor <= 0 && JoiningPhraseFactor <= 0) { throw new Exception("Conjunctions may join noun clauses or entire phrases. Set one of JoinsNoun and JoinsPhrase to greater than 0."); } // Common or proper noun? if (JoiningNounFactor > 0) { currentTemplate.Add(new NounConjunctionTemplate()); } if (JoiningPhraseFactor > 0) { currentTemplate.Add(new PhraseConjunctionTemplate()); } }
public override void AddWordTemplate(Random.RandomSourceBase randomness, WordDictionary dictionary, IList <WordTemplate.Template> currentTemplate) { _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = dictionary ?? throw new ArgumentNullException(nameof(dictionary)); _ = currentTemplate ?? throw new ArgumentNullException(nameof(currentTemplate)); if (CommonNounFactor + ProperNounFactor + NounFromAdjectiveFactor <= 0) { // No noun clause at all! return; } // How do we form the noun? // - Common noun. // - Proper noun. // - Adjective with indefinite pronoun? if (randomness.WeightedCoinFlip(CommonNounFactor, ProperNounFactor + NounFromAdjectiveFactor)) { this.AddCommonNoun(randomness, dictionary, currentTemplate); } else if (randomness.WeightedCoinFlip(ProperNounFactor, NounFromAdjectiveFactor)) { this.AddProperNoun(randomness, dictionary, currentTemplate); } else if (NounFromAdjectiveFactor != 0) { this.AddAdjectiveAsNoun(randomness, dictionary, currentTemplate); } else { throw new Exception("Unexpected state."); } }
public override void AddWordTemplate(Random.RandomSourceBase randomness, WordDictionary dictionary, IList <WordTemplate.Template> currentTemplate) { _ = currentTemplate ?? throw new ArgumentNullException(nameof(currentTemplate)); // Simply select an AnyTemplate. // No fancy logic here at all. currentTemplate.Add(new AnyTemplate()); }
public override WordAndString ChooseWord(WordDictionary words, Random.RandomSourceBase randomness, IEnumerable <Word> alreadyChosen) { _ = words ?? throw new ArgumentNullException(nameof(words)); _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = alreadyChosen ?? throw new ArgumentNullException(nameof(alreadyChosen)); var word = words.ChooseWord <Interrogative>(randomness, alreadyChosen); return(new WordAndString(word, SubjectIsPlural ? word.Plural : word.Singular)); }
public override WordAndString ChooseWord(WordDictionary words, Random.RandomSourceBase randomness, IEnumerable <Word> alreadyChosen) { _ = words ?? throw new ArgumentNullException(nameof(words)); _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = alreadyChosen ?? throw new ArgumentNullException(nameof(alreadyChosen)); var word = words.ChooseWord <Verb>(randomness, alreadyChosen, w => w.HasForm(this.Tense, this.SubjectIsPlural) && w.IsTransitive == this.SelectTransitive); return(new WordAndString(word, word.GetForm(this.Tense, this.SubjectIsPlural))); }
public override WordAndString ChooseWord(WordDictionary words, Random.RandomSourceBase randomness, IEnumerable <Word> alreadyChosen) { _ = words ?? throw new ArgumentNullException(nameof(words)); _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = alreadyChosen ?? throw new ArgumentNullException(nameof(alreadyChosen)); var word = words.ChooseWord <Conjunction>(randomness, alreadyChosen, w => w.SeparatesNouns); return(new WordAndString(word, word.Value)); }
public override WordAndString ChooseWord(WordDictionary words, Random.RandomSourceBase randomness, IEnumerable <Word> alreadyChosen) { _ = words ?? throw new ArgumentNullException(nameof(words)); _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = alreadyChosen ?? throw new ArgumentNullException(nameof(alreadyChosen)); var word = words.ChooseWord <SpeechVerb>(randomness, alreadyChosen); return(new WordAndString(word, word.Past)); }
private static T ChooseWordAlternate <T>(this WordDictionary dict, Random.RandomSourceBase randomness, IEnumerable <Word> alreadyChosen, Func <T, bool> wordPredicate) where T : Word { var possibleWords = dict.OfType <T>().Where(w => wordPredicate(w) && !alreadyChosen.Contains(w)).ToList(); var matchingWordCount = possibleWords.Count; if (matchingWordCount == 0) { throw new Exception(String.Format("Unable to choose a {0} at random. There are no words which match the specified predicate which are not already chosen.", typeof(T).Name)); } var idx = randomness.Next(matchingWordCount); var result = possibleWords[idx]; return(result); }
public override void SecondPassOfWordTemplate(Random.RandomSourceBase randomness, WordDictionary dictionary, IList <WordTemplate.Template> currentTemplate) { _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = dictionary ?? throw new ArgumentNullException(nameof(dictionary)); _ = currentTemplate ?? throw new ArgumentNullException(nameof(currentTemplate)); // If we deal with intransitive by having no object, remove the object! if (this._LastVerbTemplateIndex >= 0) { while (currentTemplate.Count > this._LastVerbTemplateIndex + 1) { currentTemplate.RemoveAt(this._LastVerbTemplateIndex + 1); } } }
public override WordAndString ChooseWord(WordDictionary words, Random.RandomSourceBase randomness, IEnumerable <Word> alreadyChosen) { _ = words ?? throw new ArgumentNullException(nameof(words)); _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = alreadyChosen ?? throw new ArgumentNullException(nameof(alreadyChosen)); // This won't always produce the correct result. if (this.IsDefinite) { return(new WordAndString(words.TheArticle, words.TheArticle.Definite)); } else { return(new WordAndString(words.TheArticle, words.TheArticle.Indefinite)); } }
public override WordAndString ChooseWord(WordDictionary words, Random.RandomSourceBase randomness, IEnumerable <Word> alreadyChosen) { _ = words ?? throw new ArgumentNullException(nameof(words)); _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = alreadyChosen ?? throw new ArgumentNullException(nameof(alreadyChosen)); if (this._NounIsSingular) { var w = (Number)words.First(x => x is Number n && n.RequiresSingularNoun); return(new WordAndString(w, w.Value)); } else { var word = words.ChooseWord <Number>(randomness, alreadyChosen, w => !w.RequiresSingularNoun); return(new WordAndString(word, word.Value)); } }
public override WordAndString ChooseWord(WordDictionary words, Random.RandomSourceBase randomness, IEnumerable <Word> alreadyChosen) { _ = words ?? throw new ArgumentNullException(nameof(words)); _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = alreadyChosen ?? throw new ArgumentNullException(nameof(alreadyChosen)); var word = words.ChooseWord <PersonalPronoun>(randomness, alreadyChosen); if (!this._IsPlural) { return(new WordAndString(word, word.Singular)); } else { return(new WordAndString(word, word.Plural)); } }
public override void AddWordTemplate(Random.RandomSourceBase randomness, WordDictionary dictionary, IList <WordTemplate.Template> currentTemplate) { _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = dictionary ?? throw new ArgumentNullException(nameof(dictionary)); _ = currentTemplate ?? throw new ArgumentNullException(nameof(currentTemplate)); // Direct speech verbs are very simple cases of verbs. They rely on a preceeding noun clause to make sense. var chosenDirectSpeech = (DirectSpeechFactor + NoDirectSpeechFactor > 0) && // Case where neither is specified: assume no direct speech. randomness.WeightedCoinFlip(DirectSpeechFactor, NoDirectSpeechFactor); if (chosenDirectSpeech) { currentTemplate.Add(new SpeechVerbTemplate()); } else { // No direct speech: remove any preceeding noun templates. var nounClauseTemplates = new HashSet <Type>() { typeof(NounTemplate), typeof(AdjectiveTemplate), typeof(ProperNounTemplate), typeof(ArticleTemplate), typeof(DemonstrativeTemplate), typeof(PersonalPronounTemplate), typeof(PrepositionTemplate) }; var toRemove = currentTemplate.Reverse().TakeWhile(wt => nounClauseTemplates.Contains(wt.GetType())).ToList(); if (toRemove.Count == currentTemplate.Count) { currentTemplate.Clear(); } else { foreach (var x in toRemove) { currentTemplate.Remove(x); } } } }
public override WordAndString ChooseWord(WordDictionary words, Random.RandomSourceBase randomness, IEnumerable <Word> alreadyChosen) { _ = words ?? throw new ArgumentNullException(nameof(words)); _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = alreadyChosen ?? throw new ArgumentNullException(nameof(alreadyChosen)); // Select a word. Word word; do { var idx = randomness.Next(words.Count); word = words[idx]; } while (word == null || alreadyChosen.Contains(word)); // Select a form. var forms = word.AllForms().ToList(); var form = forms[randomness.Next(forms.Count)]; return(new WordAndString(word, form)); }
private void AddCommonNoun(Random.RandomSourceBase randomness, WordDictionary dictionary, IList <WordTemplate.Template> currentTemplate) { // Common nouns allow for the full range of extra stuff. bool isPlural; AddNounPrelude(randomness, dictionary, currentTemplate, out isPlural); // Add a number? Only for plurals, if they are choosable. if (NumberFactor + NoNumberFactor > 0 && (isPlural || PluralityFactor == 0)) { if (!isPlural && !(currentTemplate.Any() && currentTemplate.Last() is ArticleTemplate at && !at.IsDefinite) && randomness.WeightedCoinFlip(NumberFactor, NoNumberFactor)) { // Singulars cannot have an indifinite article. currentTemplate.Add(new NumberTemplate(!isPlural)); } else if (isPlural && randomness.WeightedCoinFlip(NumberFactor, NoNumberFactor)) { currentTemplate.Add(new NumberTemplate(!isPlural)); } }
public abstract WordAndString ChooseWord(WordDictionary words, Random.RandomSourceBase randomness, IEnumerable <Word> alreadyChosen);
public override void SecondPassOfWordTemplate(Random.RandomSourceBase randomness, WordDictionary dictionary, IList <WordTemplate.Template> currentTemplate) { // No-op. }
public override void AddWordTemplate(Random.RandomSourceBase randomness, WordDictionary dictionary, IList <WordTemplate.Template> currentTemplate) { _ = randomness ?? throw new ArgumentNullException(nameof(randomness)); _ = dictionary ?? throw new ArgumentNullException(nameof(dictionary)); _ = currentTemplate ?? throw new ArgumentNullException(nameof(currentTemplate)); this._LastVerbTemplateIndex = -1; // Figuring out if the verb will be plural or not is... well... complicated. bool subjectIsPlural; int speechVerbIdx = -1, indefiniteNounIdx = -1; bool containsDirectSpeech = currentTemplate.OfType <SpeechVerbTemplate>().Any(); bool containsIndefiniteNoun = currentTemplate.OfType <IndefinitePronounTemplate>().Any(); if (containsDirectSpeech) { speechVerbIdx = CollectionHelper.IndexOfType(currentTemplate, typeof(SpeechVerbTemplate)); } if (containsIndefiniteNoun) { indefiniteNounIdx = CollectionHelper.IndexOfType(currentTemplate, typeof(IndefinitePronounTemplate)); } var ntemp = !containsDirectSpeech?currentTemplate.OfType <NounTemplate>().FirstOrDefault() : currentTemplate.Skip(speechVerbIdx).OfType <NounTemplate>().FirstOrDefault(); var ptemp = containsIndefiniteNoun ? (currentTemplate[indefiniteNounIdx] as IndefinitePronounTemplate) : null; if (ptemp == null && ntemp == null) { subjectIsPlural = false; // Proper nouns are never plural. } else if (ptemp == null && ntemp != null) { subjectIsPlural = ntemp.IsPlural; } else if (ptemp != null && ntemp == null) { subjectIsPlural = ptemp.IsPlural; } else if (ptemp != null && ntemp != null) { // This probably shouldn't happen, but if it does, we'll take the noun. subjectIsPlural = ntemp.IsPlural; } else { throw new Exception("Unexpected state."); } var verbFormToBePlural = subjectIsPlural; // Choose how to handle intransitive verbs. bool selectTransitive = true; bool removeAccusativeNoun = false; bool addPreposition = false; int choice = 0; if (IntransitiveByNoNounClauseFactor > 0 || IntransitiveByPrepositionFactor > 0) { choice = randomness.Next(dictionary.CountOf <Verb>()); // Choose between transitive or not by the number of trans/intrans verbs in dictionary. selectTransitive = choice < dictionary.CountOfTransitiveVerbs(); if (!selectTransitive) { // OK, so we chose an intransitive verb, how will we handle that? // Note that we've established either IntransitiveByNoNounClauseFactor or IntransitiveByPrepositionFactor is greater than zero, so WeightedCoinFlip() will never throw. bool handleIntransByNoObjectNoun = randomness.WeightedCoinFlip(IntransitiveByNoNounClauseFactor, IntransitiveByPrepositionFactor); if (handleIntransByNoObjectNoun) { // Remove the noun clause. removeAccusativeNoun = true; } else { // Add a preposition. addPreposition = true; } } } bool makeInterrogative = (InterrogativeFactor + NoInterrogativeFactor > 0) && // Case where neither is specified: assume no interrogative. randomness.WeightedCoinFlip(InterrogativeFactor, NoInterrogativeFactor); if (makeInterrogative && containsDirectSpeech) { // Insert an interrogative template after the direct speech verb. currentTemplate.Insert(speechVerbIdx + 1, new InterrogativeTemplate(subjectIsPlural)); } else if (makeInterrogative && !containsDirectSpeech) { // Insert an interrogative template at the start of the phrase. currentTemplate.Insert(0, new InterrogativeTemplate(subjectIsPlural)); } // Include adverb? bool includeAdverb = (AdverbFactor + NoAdverbFactor > 0) && // Case where neither is specified: assume no adverb. randomness.WeightedCoinFlip(AdverbFactor, NoAdverbFactor); bool includeAdverbBeforeVerb = randomness.CoinFlip(); if (includeAdverb && includeAdverbBeforeVerb) { currentTemplate.Add(new AdverbTemplate()); } // Select a verb tense form. this.BuildTable(); choice = randomness.Next(this.DistributionMax); var tense = VerbTense.Present; if (!makeInterrogative) { // The the verb form becomes present plural whenever an interrogative is used. tense = this.LookupTenseFromChoice(choice); } if (makeInterrogative) { verbFormToBePlural = true; } currentTemplate.Add(new VerbTemplate(tense, verbFormToBePlural, selectTransitive)); // Include adverb after the verb. if (includeAdverb && !includeAdverbBeforeVerb) { currentTemplate.Add(new AdverbTemplate()); } // Add a preposition to make the intransitive verb work? if (addPreposition) { currentTemplate.Add(new PrepositionTemplate()); } // Signal to the second pass we're going to remove the accusative noun clause. if (removeAccusativeNoun) { _LastVerbTemplateIndex = currentTemplate.Count - 1; } }
public static T ChooseWord <T>(this WordDictionary dict, Random.RandomSourceBase randomness, IEnumerable <Word> alreadyChosen) where T : Word { return(ChooseWord <T>(dict, randomness, alreadyChosen, (w) => true)); }