generateWordPairs function
Randomly generates nice-sounding combinations of words (compounds).
Will only return word combinations that are maxSyllables
long. This
applies to the joined word, so that, for example, timetime
will not pass
when maxSyllables == 2
because as a single word it would be pronounced
something like "time-ee-time", which is 3 syllables.
By default, this function will generate combinations from all the top
words in the database (adjectives and nouns). You can tighten it by
providing top
. For example, when top
is 10
, then only the top ten
adjectives and nouns will be used for generating the combinations.
By default, the generator will not output possibly offensive compounds,
such as 'ballsack' or anything containing 'Jew'. You can turn this behavior
off by setting safeOnly
to false
.
You can inject Random using the random
parameter.
Implementation
Iterable<WordPair> generateWordPairs(
{int maxSyllables = maxSyllablesDefault,
int top = topDefault,
bool safeOnly = safeOnlyDefault,
Random? random}) sync* {
final rand = random ?? _random;
bool filterWord(String word) {
if (safeOnly && unsafe.contains(word)) return false;
return syllables(word) <= maxSyllables - 1;
}
List<String> shortAdjectives;
List<String> shortNouns;
if (maxSyllables == maxSyllablesDefault &&
top == topDefault &&
safeOnly == safeOnlyDefault) {
// The most common, precomputed case.
shortAdjectives = adjectivesMonosyllabicSafe;
shortNouns = nounsMonosyllabicSafe;
} else {
shortAdjectives =
adjectives.where(filterWord).take(top).toList(growable: false);
shortNouns = nouns.where(filterWord).take(top).toList(growable: false);
}
String pickRandom(List<String> list) => list[rand.nextInt(list.length)];
// We're in a sync* function, so `while (true)` is okay.
// ignore: literal_only_boolean_expressions
while (true) {
String prefix;
if (rand.nextBool()) {
prefix = pickRandom(shortAdjectives);
} else {
prefix = pickRandom(shortNouns);
}
final suffix = pickRandom(shortNouns);
// Skip combinations that clash same letters.
if (prefix.codeUnits.last == suffix.codeUnits.first) continue;
// Skip combinations that create an unsafe combinations.
if (safeOnly && unsafePairs.contains("$prefix$suffix")) continue;
final wordPair = WordPair(prefix, suffix);
// Skip words that don't make a nicely pronounced 2-syllable word
// when combined together.
if (syllables(wordPair.join()) > maxSyllables) continue;
yield wordPair;
}
}