All Downloads are FREE. Search and download functionalities are using the official Maven repository.

squidpony.Thesaurus Maven / Gradle / Ivy

Go to download

SquidLib platform-independent logic and utility code. Please refer to https://github.com/SquidPony/SquidLib .

There is a newer version: 3.0.6
Show newest version
package squidpony;

import regexodus.*;
import squidpony.squidmath.*;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;

import static squidpony.Maker.makeList;
import static squidpony.Maker.makeOM;

/**
 * A text processing class that can swap out occurrences of words and replace them with their synonyms.
 * Created by Tommy Ettinger on 5/23/2016.
 */
public class Thesaurus implements Serializable{
    private static final long serialVersionUID = 3387639905758074640L;
    protected static final Pattern wordMatch = Pattern.compile("([\\pL`]+)"),
            similarFinder = Pattern.compile(".*?\\b(\\w\\w\\w\\w).*?{\\@1}.*$", "ui");
    public OrderedMap> mappings;
    public ArrayList alterations = new ArrayList<>(4);
    protected GWTRNG rng;
    public transient ArrayList randomLanguages = new ArrayList<>(2);
    public transient String latestGenerated = "Nationia";
    /**
     * Constructs a new Thesaurus with an unseeded RNG used to shuffle word order.
     */
    public Thesaurus()
    {
        mappings = new OrderedMap<>(256, Hashers.caseInsensitiveStringHasher);
        rng = new GWTRNG();
    }

    /**
     * Constructs a new Thesaurus, seeding its RNG (used to shuffle word order) with the next long from the given RNG.
     * @param rng an RNG that will only be used to get one long (for seeding this class' RNG)
     */
    public Thesaurus(IRNG rng)
    {
        mappings = new OrderedMap<>(256, Hashers.caseInsensitiveStringHasher);
        this.rng = new GWTRNG(rng.nextLong());
    }

    /**
     * Constructs a new Thesaurus, seeding its RNG (used to shuffle word order) with shuffleSeed.
     * @param shuffleSeed a long for seeding this class' RNG
     */
    public Thesaurus(long shuffleSeed)
    {
        mappings = new OrderedMap<>(256, Hashers.caseInsensitiveStringHasher);
        this.rng = new GWTRNG(shuffleSeed);
    }


    /**
     * Constructs a new Thesaurus, seeding its RNG (used to shuffle word order) with shuffleSeed.
     * @param shuffleSeed a String for seeding this class' RNG
     */
    public Thesaurus(String shuffleSeed)
    {
        mappings = new OrderedMap<>(256, Hashers.caseInsensitiveStringHasher);
        this.rng = new GWTRNG(CrossHash.hash64(shuffleSeed));
    }

    /**
     * Allows this Thesaurus to find the exact words in synonyms and, when requested, replace each occurrence with a
     * different word from the same Collection. Each word in synonyms should have the same part of speech, so "demon"
     * and "devils" should not be in the same list of synonyms (singular noun and plural noun), but "demon" and "devil"
     * could be (each is a singular noun). The Strings in synonyms should all be lower-case, since case is picked up
     * from the text as it is being replaced and not from the words themselves. Proper nouns should normally not be used
     * as synonyms, since this could get very confusing if it changed occurrences of "Germany" to "France" at random and
     * a character's name, like "Dorothy", to "Anne", "Emily", "Cynthia", etc. in the middle of a section about Dorothy.
     * The word matching pattern this uses only matches all-letter words, not words that contain hyphens, apostrophes,
     * or other punctuation.
     * @param synonyms a Collection of lower-case Strings with similar meaning and the same part of speech
     * @return this for chaining
     */
    public Thesaurus addSynonyms(Collection synonyms)
    {
        if(synonyms.isEmpty())
            return this;
        long prevState = rng.getState();
        rng.setState(CrossHash.hash64(synonyms));
        GapShuffler shuffler = new GapShuffler<>(synonyms, rng);
        for(String syn : synonyms)
        {
            mappings.put(syn, shuffler);
        }
        rng.setState(prevState);
        return this;
    }

    public Thesaurus addReplacement(CharSequence before, String after)
    {
        mappings.put(before, new GapShuffler(after));
        return this;
    }

    /**
     * Allows this Thesaurus to replace a specific keyword, typically containing multiple backtick characters ('`') so
     * it can't be confused with a "real word," with one of the words in synonyms (chosen in shuffled order). The
     * backtick is the only punctuation character that this class' word matcher considers part of a word, both for this
     * reason and because it is rarely used in English text.
     * @param keyword a word (typically containing backticks, '`') that will be replaced by a word from synonyms
     * @param synonyms a Collection of lower-case Strings with similar meaning and the same part of speech
     * @return this for chaining
     */
    public Thesaurus addCategory(String keyword, Collection synonyms)
    {
        if(synonyms.isEmpty())
            return this;
        long prevState = rng.getState();
        rng.setState(CrossHash.hash64(synonyms));
        GapShuffler shuffler = new GapShuffler<>(synonyms, rng);
        mappings.put(keyword, shuffler);
        rng.setState(prevState);
        return this;
    }

    /**
     * Adds several pre-made categories to this Thesaurus' known categories, but won't cause it to try to replace normal
     * words with synonyms (only categories, which contain backticks in the name). The keywords this currently knows,
     * and the words it will replace those keywords with, are:
     * 
* (THIS IS OUT OF DATE, THERE ARE MORE KNOWN.) *
*
    *
  • "calm`adj`": harmonious, peaceful, pleasant, serene, placid, tranquil, calm
  • *
  • "calm`noun`": harmony, peace, kindness, serenity, tranquility, calm
  • *
  • "org`noun`": fraternity, brotherhood, order, group, foundation, association, guild, fellowship, partnership
  • *
  • "org`nouns`": fraternities, brotherhoods, orders, groups, foundations, associations, guilds, fellowships, partnerships
  • *
  • "empire`adj`": imperial, prince's, king's, sultan's, regal, dynastic, royal, hegemonic, monarchic, ascendant, emir's, lordly
  • *
  • "empire`noun`": empire, emirate, kingdom, sultanate, dominion, dynasty, imperium, hegemony, triumvirate, ascendancy, monarchy, commonwealth
  • *
  • "empire`nouns`": empires, emirates, kingdoms, sultanates, dominions, dynasties, imperia, hegemonies, triumvirates, ascendancies, monarchies, commonwealths
  • *
  • "union`adj`": united, allied, people's, confederated, federated, congressional, independent, associated, unified, democratic
  • *
  • "union`noun`": union, alliance, coalition, confederation, federation, congress, confederacy, league, faction, republic
  • *
  • "union`nouns`": unions, alliances, coalitions, confederations, federations, congresses, confederacies, leagues, factions, republics
  • *
  • "militia`noun`": rebellion, resistance, militia, liberators, warriors, fighters, militants, front, irregulars
  • *
  • "militia`nouns`": rebellions, resistances, militias, liberators, warriors, fighters, militants, fronts, irregulars
  • *
  • "gang`noun`": gang, syndicate, mob, crew, posse, mafia, cartel
  • *
  • "gang`nouns`": gangs, syndicates, mobs, crews, posses, mafias, cartels
  • *
  • "duke`noun`": duke, earl, baron, fief, lord, shogun
  • *
  • "duke`nouns`": dukes, earls, barons, fiefs, lords, shoguns
  • *
  • "duchy`noun`": duchy, earldom, barony, fiefdom, lordship, shogunate
  • *
  • "duchy`nouns`": duchies, earldoms, baronies, fiefdoms, lordships, shogunates
  • *
  • "magical`adj`": arcane, enchanted, sorcerous, ensorcelled, magical, mystical
  • *
  • "holy`adj`": auspicious, divine, holy, sacred, prophetic, blessed, godly
  • *
  • "unholy`adj`": bewitched, occult, unholy, macabre, accursed, profane, vile
  • *
  • "forest`adj`": natural, primal, verdant, lush, fertile, bountiful
  • *
  • "forest`noun`": nature, forest, greenery, jungle, woodland, grove, copse
  • *
  • "fancy`adj`": grand, glorious, magnificent, magnanimous, majestic, great, powerful
  • *
  • "evil`adj`": heinous, scurrilous, terrible, horrible, debased, wicked, evil, malevolent, nefarious, vile
  • *
  • "good`adj`": righteous, moral, good, pure, compassionate, flawless, perfect
  • *
  • "sinister`adj`": shadowy, silent, lethal, deadly, fatal, venomous, cutthroat, murderous, bloodstained, stalking
  • *
  • "sinister`noun`": shadow, silence, assassin, ninja, venom, poison, snake, murder, blood, razor, tiger
  • *
  • "blade`noun`": blade, knife, sword, axe, stiletto, katana, scimitar, hatchet, spear, glaive, halberd, * hammer, maul, flail, mace, sickle, scythe, whip, lance, nunchaku, saber, cutlass, trident
  • *
  • "bow`noun`": bow, longbow, shortbow, crossbow, sling, atlatl, bolas, javelin, net, shuriken, dagger
  • *
  • "weapon`noun`": blade, knife, sword, axe, stiletto, katana, scimitar, hatchet, spear, glaive, halberd, * hammer, maul, flail, mace, sickle, scythe, whip, lance, nunchaku, saber, cutlass, trident, * bow, longbow, shortbow, crossbow, sling, atlatl, bolas, javelin, net, shuriken, dagger
  • *
  • "musket`noun`": arquebus, blunderbuss, musket, matchlock, flintlock, wheellock, cannon
  • *
  • "grenade`noun`": rocket, grenade, missile, bomb, warhead, explosive, flamethrower
  • *
  • "rifle`noun`": pistol, rifle, handgun, firearm, longarm, shotgun
  • *
  • "blade`nouns`": blades, knives, swords, axes, stilettos, katana, scimitars, hatchets, spears, glaives, halberds, * hammers, mauls, flails, maces, sickles, scythes, whips, lances, nunchaku, sabers, cutlasses, tridents
  • *
  • "bow`nouns`": bows, longbows, shortbows, crossbows, slings, atlatls, bolases, javelins, nets, shuriken, daggers
  • *
  • "weapon`nouns`": blades, knives, swords, axes, stilettos, katana, scimitars, hatchets, spears, glaives, halberds, * hammers, mauls, flails, maces, sickles, scythes, whips, lances, nunchaku, sabers, cutlasses, tridents, * bows, longbows, shortbows, crossbows, slings, atlatls, bolases, javelins, nets, shuriken, daggers
  • *
  • "musket`nouns`": arquebusses, blunderbusses, muskets, matchlocks, flintlocks, wheellocks, cannons
  • *
  • "grenade`nouns`": rockets, grenades, missiles, bombs, warheads, explosives, flamethrowers
  • *
  • "rifle`nouns`": pistols, rifles, handguns, firearms, longarms, shotguns
  • *
  • "tech`adj`": cyber, digital, electronic, techno, hacker, crypto, turbo, mechanical, servo
  • *
  • "sole`adj`": sole, true, singular, total, ultimate, final, last
  • *
  • "light`adj`": bright, glowing, solar, stellar, lunar, radiant, luminous, shimmering
  • *
  • "light`noun`": light, glow, sun, star, moon, radiance, dawn, torch
  • *
  • "light`nouns`": lights, glimmers, suns, stars, moons, torches
  • *
  • "smart`adj`": brilliant, smart, genius, wise, clever, cunning, mindful, aware
  • *
  • "smart`noun`": genius, wisdom, cunning, awareness, mindfulness, acumen, smarts, knowledge
  • *
  • "bandit`noun`": thief, raider, bandit, rogue, brigand, highwayman, pirate
  • *
  • "bandit`nouns`": thieves, raiders, bandits, rogues, brigands, highwaymen, pirates
  • *
  • "guard`noun`": protector, guardian, warden, defender, guard, shield, sentinel, watchman, knight
  • *
  • "guard`nouns`": protectors, guardians, wardens, defenders, guards, shields, sentinels, watchmen, knights
  • *
  • "rage`noun`": rage, fury, anger, wrath, frenzy, vengeance
  • *
* Capitalizing the first letter in the keyword where it appears in text you call process() on will capitalize the * first letter of the produced fake word. Capitalizing the second letter will capitalize the whole produced fake * word. This applies only per-instance of each keyword; it won't change the internally-stored list of words. * @return this for chaining */ public Thesaurus addKnownCategories() { for(Map.Entry> kv : categories.entrySet()) { addCategory(kv.getKey(), kv.getValue()); } return this; } /** * Adds a large list of words pre-generated by FakeLanguageGen and hand-picked for fitness, and makes them * accessible with a keyword based on the language and any tweaks made to it. The keywords this currently knows: *
*
    *
  • "jp`gen`": Imitation Japanese
  • *
  • "fr`gen`": Imitation French; contains some accented chars
  • *
  • "gr`gen`": Imitation Greek (romanized)
  • *
  • "ru`gen`": Imitation Russian (romanized)
  • *
  • "sw`gen`": Imitation Swahili
  • *
  • "so`gen`": Imitation Somali
  • *
  • "en`gen`": Imitation English (not very good on its own)
  • *
  • "ar`gen`": Imitation Arabic (better); doesn't have accents and should be more readable
  • *
  • "nr`gen`": Imitation Old Norse (using simpler and easier-to-pronounce spelling)
  • *
  • "nr`acc`gen`": Imitation Old Norse (using the uncommon letters used in modern Icelandic)
  • *
  • "hi`gen`": Imitation Hindi (romanized and with accents removed)
  • *
  • "kr`gen`": Imitation Korean (romanized)
  • *
  • "na`gen`": Imitation Nahuatl (spelled like how Spanish loanwords from Nahuatl are spelled)
  • *
  • "mn`gen`": Imitation Mongolian (the form of the language from medieval times, romanized)
  • *
  • "in`gen`": Imitation Inuktitut (romanized)
  • *
  • "si`gen`": "Simplish" (simplified imitation English, without special word endings like "-ight")
  • *
  • "fn`gen`": Fantasy Names; styled after the possibly-Europe-like names common in fantasy books
  • *
  • "fn`acc`gen`": Fancy Fantasy Names; the same as "fn`gen`", but with lots of accented chars
  • *
  • "lc`gen`": Lovecraft; styled after the names of creatures from H.P. Lovecraft's Cthulhu Mythos
  • *
  • "el`gen`": Elf, modeled after J.R.R. Tolkien's languages for elves
  • *
  • "gb`gen`": Goblin, fantasy language of sneaky species
  • *
  • "if`gen`": Infernal, fantasy language of clever and subtle fiends
  • *
  • "dm`gen`": Demonic, fantasy language of brutish fiends
  • *
  • "al`a`gen`": Alien A, fantasy language with very unusual consonants
  • *
  • "al`e`gen`": Alien E, fantasy language with click sounds but no "lip sounds"
  • *
  • "al`i`gen`": Alien I, fantasy language with many tones and "liquid sounds"
  • *
  • "al`o`gen`": Alien O, fantasy language with long words and lengthy vowel clusters
  • *
  • "al`u`gen`": Alien U, fantasy language with many accented consonants and different suffixes
  • *
  • "ru`so`gen`": Mix of imitation Russian (75%) and Somali (25%)
  • *
  • "gr`hi`gen`": Mix of imitation Greek (50%) and Hindi (accents removed, 50%)
  • *
  • "sw`fr`gen`": Mix of imitation Swahili (70%) and French (30%)
  • *
  • "ar`jp`gen`": Mix of imitation Arabic (accents removed, 60%) and Japanese (40%)
  • *
  • "sw`gr`gen`": Mix of imitation Swahili (60%) and Greek (40%)
  • *
  • "gr`so`gen`": Mix of imitation Greek (60%) and Somali (40%)
  • *
  • "en`hi`gen`": Mix of imitation English (60%) and Hindi (accents removed, 40%)
  • *
  • "en`jp`gen`": Mix of imitation English (60%) and Japanese (40%)
  • *
  • "so`hi`gen`": Mix of imitation Somali (60%) and Hindi (accents removed, 40%)
  • *
  • "ru`gr`gen`": Mix of imitation Russian (60%) and Greek (40%)
  • *
  • "lc`gr`gen`": Mix of Lovecraft-styled names (60%) and imitation Russian (40%)
  • *
  • "fr`mod`gen`": Imitation French; modified to replace doubled consonants like "gg" with "gsh" or similar
  • *
  • "jp`mod`gen`": Imitation Japanese; modified to sometimes double vowels from "a" to "aa" or similar
  • *
  • "so`mod`gen`": Imitation Somali (not really); modified beyond recognition and contains accents
  • *
* Capitalizing the first letter in the keyword where it appears in text you call process() on will capitalize the * first letter of the produced fake word, which is often desirable for things like place names. Capitalizing the * second letter will capitalize the whole produced fake word. This applies only per-instance of each keyword; it * won't change the internally-stored list of words. * @return this for chaining */ public Thesaurus addFakeWords() { long state = rng.getState(); for(Map.Entry kv : languages.entrySet()) { ArrayList words = new ArrayList<>(16); for (int i = 0; i < 16; i++) { words.add(kv.getValue().word(rng, false, rng.between(2, 4))); } addCategory(StringKit.replace(kv.getKey(), "gen", "pre"), words); } rng.setState(state); return this; } private StringBuilder modify(CharSequence text) { Matcher m; StringBuilder sb = new StringBuilder(text); Replacer.StringBuilderBuffer tb, working = Replacer.wrap(sb); StringBuilder tmp; boolean found; FakeLanguageGen.Alteration alt; for (int a = 0; a < alterations.size(); a++) { alt = alterations.get(a); tmp = working.sb; tb = Replacer.wrap(new StringBuilder(tmp.length())); m = alt.replacer.getPattern().matcher(tmp); found = false; while (true) { if (rng.nextDouble() < alt.chance) { if (!Replacer.replaceStep(m, alt.replacer.getSubstitution(), tb)) break; found = true; } else { if (!m.find()) break; found = true; m.getGroup(MatchResult.PREFIX, tb); m.getGroup(MatchResult.MATCH, tb); m.setTarget(m, MatchResult.SUFFIX); } } if (found) { m.getGroup(MatchResult.TARGET, tb); working = tb; } } return working.sb; } /** * Given a String, StringBuilder, or other CharSequence that should contain words this knows synonyms for, this * replaces each occurrence of such a known word with one of its synonyms, leaving unknown words untouched. Words * that were learned together as synonyms with addSynonyms() will be replaced in such a way that an individual * replacement word should not occur too close to a previous occurrence of the same word; that is, replacing the * text "You fiend! You demon! You despoiler of creation; devil made flesh!", where "fiend", "demon", and "devil" * are all synonyms, would never produce a string that contained "fiend" as the replacement for all three of those. * @param text a CharSequence, such as a String, that contains words in the source language * @return a String of the translated text. */ public String process(CharSequence text) { Replacer rep = wordMatch.replacer(new SynonymSubstitution()); if(alterations.isEmpty()) return rep.replace(text); else return modify(rep.replace(text)).toString(); } public String lookup(String word) { if(word.isEmpty()) return word; String word2 = word.toLowerCase(); if(mappings.containsKey(word2)) { String nx = mappings.get(word2).next(); if(nx.isEmpty()) return nx; if(word.length() > 1 && Category.Lu.contains(word.charAt(1))) return nx.toUpperCase(); if(Category.Lu.contains(word.charAt(0))) { return Character.toUpperCase(nx.charAt(0)) + nx.substring(1); } return nx; } else if(languages.containsKey(word2)) { if(word.length() > 1 && Category.Lu.contains(word.charAt(1))) return languages.get(word2).word(rng, false, rng.between(2, 4)).toUpperCase(); if(Category.Lu.contains(word.charAt(0))) { return languages.get(word2).word(rng, true, rng.between(2, 4)); } return languages.get(word2).word(rng, false, rng.between(2, 4)); } return word; } private class SynonymSubstitution implements Substitution { private StringBuilder temp = new StringBuilder(64); @Override public void appendSubstitution(MatchResult match, TextBuffer dest) { //dest.append(lookup(match.group(0))); temp.setLength(0); match.getGroup(0, temp); writeLookup(dest, temp); } } private void writeLookup(TextBuffer dest, StringBuilder word) { if(word.length() <= 0) return; if(mappings.containsKey(word)) { String nx = mappings.get(word).next(); if(nx.isEmpty()) return; if(word.length() > 1 && Category.Lu.contains(word.charAt(1))) { dest.append(nx.toUpperCase()); return; } if(Category.Lu.contains(word.charAt(0))) { dest.append(Character.toUpperCase(nx.charAt(0))); dest.append(nx.substring(1)); return; } dest.append(nx); return; } else if(languages.containsKey(word)) { if(word.length() > 1 && Category.Lu.contains(word.charAt(1))) { dest.append(languages.get(word).word(rng, false, rng.between(2, 4)).toUpperCase()); } else if(Category.Lu.contains(word.charAt(0))) { dest.append(languages.get(word).word(rng, true, rng.between(2, 4))); } else { dest.append(languages.get(word).word(rng, false, rng.between(2, 4))); } return; } else if(numbers.containsKey(word)) { if(word.length() > 1 && Category.Lu.contains(word.charAt(1))) { dest.append(numberWordInRange(2, numbers.get(word)).toUpperCase()); } else if(Category.Lu.contains(word.charAt(0))) { String w = numberWordInRange(2, numbers.get(word)); dest.append(Character.toUpperCase(w.charAt(0))); dest.append(w.substring(1)); } else { dest.append(numberWordInRange(2, numbers.get(word))); } return; } else if(numberAdjectives.containsKey(word)) { if(word.length() > 1 && Category.Lu.contains(word.charAt(1))) { dest.append(numberAdjectiveInRange(2, numberAdjectives.get(word)).toUpperCase()); } else if(Category.Lu.contains(word.charAt(0))) { String w = numberAdjectiveInRange(2, numberAdjectives.get(word)); dest.append(Character.toUpperCase(w.charAt(0))); dest.append(w.substring(1)); } else { dest.append(numberAdjectiveInRange(2, numberAdjectives.get(word))); } return; } if(dest instanceof Replacer.StringBuilderBuffer) { ((Replacer.StringBuilderBuffer)dest).sb.append(word); } else dest.append(word.toString()); } private class RandomLanguageSubstitution implements Substitution { @Override public void appendSubstitution(MatchResult match, TextBuffer dest) { FakeLanguageGen lang = FakeLanguageGen.randomLanguage(rng.nextLong()); randomLanguages.add(lang); if(match.isCaptured(1)) { lang = FakeLanguageGen.randomLanguage(rng.nextLong()); randomLanguages.add(lang); do { latestGenerated = randomLanguages.get(0).word(rng, true, Math.min(rng.between(2, 5), rng.between(1, 5))) + "-" + randomLanguages.get(1).word(rng, true, Math.min(rng.between(2, 5), rng.between(1, 5))); }while (latestGenerated.length() <= 5 || latestGenerated.length() >= 17); dest.append(latestGenerated); } else { do{ latestGenerated = lang.word(rng, true, Math.min(rng.between(2, 5), rng.between(1, 5))); }while (latestGenerated.length() <= 2 || latestGenerated.length() >= 11); dest.append(latestGenerated); } } } private class KnownLanguageSubstitution implements Substitution { public FakeLanguageGen language; public KnownLanguageSubstitution(FakeLanguageGen lang) { language = lang; } @Override public void appendSubstitution(MatchResult match, TextBuffer dest) { if (match.isCaptured(1)) { do { latestGenerated = language.word(rng, true, Math.min(rng.between(2, 5), rng.between(1, 5))) + "-" + language.word(rng, true, Math.min(rng.between(2, 5), rng.between(1, 5))); }while (latestGenerated.length() <= 5 || latestGenerated.length() >= 17); dest.append(latestGenerated); } else { do{ latestGenerated = language.word(rng, true, Math.min(rng.between(2, 5), rng.between(1, 5))); }while (latestGenerated.length() <= 2 || latestGenerated.length() >= 11); dest.append(latestGenerated); } } } /** * Generates a random possible name for a nation, such as "Iond-Gouccief Alliance" or "The Last Drayo Commonwealth". * Needs {@link #addKnownCategories()} to be called on this Thesaurus first. May use accented characters, as in * "Thùdshù-Hyóttiálb Hegemony" or "The Glorious Chô Empire"; if you want to strip these out and replace accented * chars with their un-accented counterparts, you can use {@link FakeLanguageGen#removeAccents(CharSequence)}, which * returns a CharSequence that can be converted to String if needed. Shortly after calling this method, but before * calling it again, you can retrieve the generated random languages, if any were used while making nation names, by * getting the FakeLanguageGen elements of this class' {@link #randomLanguages} field. Using one of these * FakeLanguageGen objects, you can produce many more words with a similar style to the nation name, like "Drayo" in * "The Last Drayo Commonwealth". If more than one language was used in the nation name, as in "Thùdshù-Hyóttiálb * Hegemony", you will have two languages in randomLanguages, so here "Thùdshù" would be generated by the first * language, and "Hyóttiálb" by the second language. Calling this method replaces the current contents of * randomLanguages, so if you want to use those languages, get them while you can. This also assigns the * {@link #latestGenerated} field to contain the part of the nation name without any larger titles; in the case of * "The Glorious Chô Empire", the latestGenerated field would be assigned "Chô" at the same time the longer name * would be returned. This field will be reassigned if this method is called again. * * @return a random name for a nation or a loose equivalent to a nation, as a String */ public String makeNationName() { String working = process(rng.getRandomElement(nationTerms)); int frustration = 0; while (frustration++ < 8 && similarFinder.matches(working)) working = process(rng.getRandomElement(nationTerms)); randomLanguages.clear(); RandomLanguageSubstitution sub = new RandomLanguageSubstitution(); Replacer replacer = Pattern.compile("@(-@)?").replacer(sub); return replacer.replace(working); } /** * Generates a random possible name for a nation, such as "Iond-Gouccief Alliance" or "The Last Drayo Commonwealth", * with the FakeLanguageGen already available instead of randomly created. Needs {@link #addKnownCategories()} to be * called on this Thesaurus first. May use accented characters, as in "Thùdshù Hegemony" or "The Glorious Chô * Empire", if the given language can produce them; if you want to strip these out and replace accented chars * with their un-accented counterparts, you can use {@link FakeLanguageGen#removeAccents(CharSequence)}, which * returns a CharSequence that can be converted to String if needed, or simply get an accent-less language by * calling {@link FakeLanguageGen#removeAccents()} on the FakeLanguageGen you would give this. This assigns the * {@link #latestGenerated} field to contain the part of the nation name without any larger titles; in the case of * "The Glorious Chô Empire", the latestGenerated field would be assigned "Chô" at the same time the longer name * would be returned. This field will be reassigned if this method is called again. *
* Some nation names use a hyphenated pairing of what would normally be names in two different languages; if one of * those names is produced by this it will produce two names in the same linguistic style. The randomLanguages field * is not populated by this method; it is assumed that since you are passing this a FakeLanguageGen, you already * have the one you want to use anyway. * * @param language a FakeLanguageGen that will be used to construct any non-English names * @return a random name for a nation or a loose equivalent to a nation, as a String */ public String makeNationName(FakeLanguageGen language) { String working = process(rng.getRandomElement(nationTerms)); int frustration = 0; while (frustration++ < 8 && similarFinder.matches(working)) working = process(rng.getRandomElement(nationTerms)); randomLanguages.clear(); KnownLanguageSubstitution sub = new KnownLanguageSubstitution(language); Replacer replacer = Pattern.compile("@(-@)?").replacer(sub); return replacer.replace(working); } /** * Gets an English word for a given number, if this knows it. These words are known from 0 ("zero") to 20 * ("twenty"), as well as some higher numbers. If a word isn't known for a number, this returns the number as a * String, such as "537" or "-1". * @param number the number to get a word for * @return the word associated with a number as a String, or if none is known, {@code String.valueOf(number)}. */ public static String numberWord(final int number) { switch (number){ case 0: return "zero"; case 1: return "one"; case 2: return "two"; case 3: return "three"; case 4: return "four"; case 5: return "five"; case 6: return "six"; case 7: return "seven"; case 8: return "eight"; case 9: return "nine"; case 10: return "ten"; case 11: return "eleven"; case 12: return "twelve"; case 13: return "thirteen"; case 14: return "fourteen"; case 15: return "fifteen"; case 16: return "sixteen"; case 17: return "seventeen"; case 18: return "eighteen"; case 19: return "nineteen"; case 20: return "twenty"; case 30: return "thirty"; case 40: return "fourty"; case 50: return "fifty"; case 60: return "sixty"; case 70: return "seventy"; case 80: return "eighty"; case 90: return "ninety"; case 100: return "hundred"; case 1000: return "thousand"; case 1000000: return "million"; case 1000000000: return "billion"; default: return String.valueOf(number); } } /** * Gets an English word that describes a numbered position in some sequence, if this knows it (such as "second" or * "eleventh"). These words are known from 1 ("first") to 20 ("twentieth"), as well as some higher numbers. If a * word isn't known for a number, this appends a suffix based on the last base-10 digit to the number, as with "0th" * or "42nd". * @param number the number to get a position adjective for * @return the word associated with a number as a String, or if none is known, {@code String.valueOf(number)} followed by a two-char suffix from the last digit. */ public static String numberAdjective(final int number) { switch (number){ case 1: return "first"; case 2: return "second"; case 3: return "third"; case 4: return "fourth"; case 5: return "fifth"; case 6: return "sixth"; case 7: return "seventh"; case 8: return "eighth"; case 9: return "ninth"; case 10: return "tenth"; case 11: return "eleventh"; case 12: return "twelfth"; case 13: return "thirteenth"; case 14: return "fourteenth"; case 15: return "fifteenth"; case 16: return "sixteenth"; case 17: return "seventeenth"; case 18: return "eighteenth"; case 19: return "nineteenth"; case 20: return "twentieth"; case 30: return "thirtieth"; case 40: return "fourtieth"; case 50: return "fiftieth"; case 60: return "sixtieth"; case 70: return "seventieth"; case 80: return "eightieth"; case 90: return "ninetieth"; case 100: return "hundredth"; case 1000: return "thousandth"; case 1000000: return "millionth"; case 1000000000: return "billionth"; default: { switch (number % 10){ case 1: return number + "st"; case 2: return number + "nd"; case 3: return number + "rd"; default:return number + "th"; } } } } /** * Gets an English word for a number, if this knows it, where the number is chosen randomly between lowest and * highest, both inclusive. These words are known from 0 ("zero") to 20 ("twenty"), as well as some higher numbers. * If a word isn't known for a number, this returns the number as a String, such as "537" or "-1". * @param lowest the lower bound for numbers this can choose, inclusive * @param highest the upper bound for numbers this can choose, inclusive * @return a String word for a number in the given range, such as "six" or "eleven", if it is known */ public String numberWordInRange(int lowest, int highest) { return numberWord(rng.nextSignedInt(highest + 1 - lowest) + lowest); } /** * Gets an English word that describes a numbered position in some sequence, if this knows it (such as "second" or * "eleventh"), where the number is chosen randomly between lowest and highest, both inclusive. These words are * known from 1 ("first") to 20 ("twentieth"), as well as some output for other numbers (such as "42nd" or "23rd"). * @param lowest the lower bound for numbers this can choose, inclusive * @param highest the upper bound for numbers this can choose, inclusive * @return a String word for a number in the given range, such as "third" or "twelfth", if it is known */ public String numberAdjectiveInRange(int lowest, int highest) { return numberAdjective(rng.nextSignedInt(highest + 1 - lowest) + lowest); } private static final String[] nationTerms = new String[]{ "Union`adj` Union`noun` of @", "Union`adj` @ Union`noun`", "@ Union`noun`", "@ Union`noun`", "@-@ Union`noun`", "Union`adj` Union`noun` of @", "Union`adj` Duchy`nouns` of @", "The @ Duchy`noun`", "The Fancy`adj` @ Duchy`noun`", "The Sole`adj` @ Empire`noun`", "@ Empire`noun`", "@ Empire`noun`", "@ Empire`noun`", "@-@ Empire`noun`", "The Fancy`adj` @ Empire`noun`", "The Fancy`adj` @ Empire`noun`", "The Holy`adj` @ Empire`noun`",}; public static final OrderedMap> categories = makeOM( "calm`adj`", makeList("harmonious", "peaceful", "pleasant", "serene", "placid", "tranquil", "calm"), "calm`noun`", makeList("harmony", "peace", "kindness", "serenity", "tranquility", "calm"), "org`noun`", makeList("fraternity", "brotherhood", "order", "group", "foundation", "association", "guild", "fellowship", "partnership"), "org`nouns`", makeList("fraternities", "brotherhoods", "orders", "groups", "foundations", "associations", "guilds", "fellowships", "partnerships"), "empire`adj`", makeList("imperial", "prince's", "king's", "sultan's", "regal", "dynastic", "royal", "hegemonic", "monarchic", "ascendant", "emir's", "lordly"), "empire`noun`", makeList("empire", "emirate", "kingdom", "sultanate", "dominion", "dynasty", "imperium", "hegemony", "triumvirate", "ascendancy", "monarchy", "commonwealth"), "empire`nouns`", makeList("empires", "emirates", "kingdoms", "sultanates", "dominions", "dynasties", "imperia", "hegemonies", "triumvirates", "ascendancies", "monarchies", "commonwealths"), "emperor`noun`", makeList("emperor", "emir", "king", "sultan", "lord", "ruler", "pharaoh"), "emperor`nouns`", makeList("emperors", "emirs", "kings", "sultans", "lords", "rulers", "pharaohs"), "empress`noun`", makeList("empress", "emira", "queen", "sultana", "lady", "ruler", "pharaoh"), "empress`nouns`", makeList("empresses", "emiras", "queens", "sultanas", "ladies", "rulers", "pharaohs"), "union`adj`", makeList("united", "allied", "people's", "confederated", "federated", "congressional", "independent", "associated", "unified", "democratic"), "union`noun`", makeList("union", "alliance", "coalition", "confederation", "federation", "congress", "confederacy", "league", "faction", "republic"), "union`nouns`", makeList("unions", "alliances", "coalitions", "confederations", "federations", "congresses", "confederacies", "leagues", "factions", "republics"), "militia`noun`", makeList("rebellion", "resistance", "militia", "liberators", "warriors", "fighters", "militants", "front", "irregulars"), "militia`nouns`", makeList("rebellions", "resistances", "militias", "liberators", "warriors", "fighters", "militants", "fronts", "irregulars"), "gang`noun`", makeList("gang", "syndicate", "mob", "crew", "posse", "mafia", "cartel"), "gang`nouns`", makeList("gangs", "syndicates", "mobs", "crews", "posses", "mafias", "cartels"), "duke`noun`", makeList("duke", "earl", "baron", "fief", "lord", "shogun"), "duke`nouns`", makeList("dukes", "earls", "barons", "fiefs", "lords", "shoguns"), "duchy`noun`", makeList("duchy", "earldom", "barony", "fiefdom", "lordship", "shogunate"), "duchy`nouns`", makeList("duchies", "earldoms", "baronies", "fiefdoms", "lordships", "shogunates"), "magical`adj`", makeList("arcane", "enchanted", "sorcerous", "ensorcelled", "magical", "mystical"), "holy`adj`", makeList("auspicious", "divine", "holy", "sacred", "prophetic", "blessed", "godly", "virtuous"), "priest`noun`", makeList("priest", "bishop", "chaplain", "cleric", "cardinal", "preacher"), "priest`nouns`", makeList("priests", "bishops", "chaplains", "clergy", "cardinals", "preachers"), "unholy`adj`", makeList("bewitched", "occult", "unholy", "macabre", "accursed", "profane", "vile"), "witch`noun`", makeList("witch", "warlock", "necromancer", "cultist", "occultist", "defiler"), "witch`nouns`", makeList("witches", "warlocks", "necromancers", "cultists", "occultists", "defilers"), "forest`adj`", makeList("natural", "primal", "verdant", "lush", "fertile", "bountiful"), "forest`noun`", makeList("nature", "forest", "greenery", "jungle", "woodland", "grove", "copse"), "shaman`noun`", makeList("shaman", "druid", "warden", "animist"), "shaman`nouns`", makeList("shamans", "druids", "wardens", "animists"), "fancy`adj`", makeList("grand", "glorious", "magnificent", "magnanimous", "majestic", "great", "powerful"), "evil`adj`", makeList("heinous", "scurrilous", "terrible", "horrible", "debased", "wicked", "evil", "malevolent", "nefarious", "vile", "cruel", "abhorrent"), "villain`noun`", makeList("villain", "knave", "evildoer", "killer", "blasphemer", "monster", "murderer"), "villain`nouns`", makeList("villains", "knaves", "evildoers", "killers", "blasphemers", "monsters", "murderers"), "monster`noun`", makeList("fiend", "abomination", "demon", "devil", "ghoul", "monster", "beast", "creature"), "monsters`nouns`", makeList("fiends", "abominations", "demons", "devils", "ghouls", "monsters", "beasts", "creatures"), "good`adj`", makeList("righteous", "moral", "good", "pure", "compassionate", "flawless", "perfect", "kind"), "lethal`adj`", makeList("silent", "lethal", "deadly", "fatal", "venomous", "cutthroat", "murderous", "bloodstained", "stalking", "poisonous"), "lethal`noun`", makeList("silence", "killer", "assassin", "ninja", "venom", "poison", "snake", "murder", "blood", "razor", "tiger", "slayer"), "blade`noun`", // really any melee weapon makeList("blade", "knife", "sword", "axe", "stiletto", "katana", "scimitar", "hatchet", "spear", "glaive", "halberd", "hammer", "maul", "flail", "mace", "sickle", "scythe", "whip", "lance", "nunchaku", "saber", "cutlass", "trident"), "bow`noun`", // really any medieval or earlier ranged weapon makeList("bow", "longbow", "shortbow", "crossbow", "sling", "atlatl", "bolas", "javelin", "net", "shuriken", "dagger"), "weapon`noun`", // any medieval or earlier weapon (not including firearms or newer) makeList("blade", "knife", "sword", "axe", "stiletto", "katana", "scimitar", "hatchet", "spear", "glaive", "halberd", "hammer", "maul", "flail", "mace", "sickle", "scythe", "whip", "lance", "nunchaku", "saber", "cutlass", "trident", "bow", "longbow", "shortbow", "crossbow", "sling", "atlatl", "bolas", "javelin", "net", "shuriken", "dagger"), "musket`noun`", makeList("arquebus", "blunderbuss", "musket", "matchlock", "flintlock", "wheellock", "cannon"), "grenade`noun`", makeList("rocket", "grenade", "missile", "bomb", "warhead", "explosive", "flamethrower"), "rifle`noun`", makeList("pistol", "rifle", "handgun", "firearm", "longarm", "shotgun"), "blade`nouns`", makeList("blades", "knives", "swords", "axes", "stilettos", "katana", "scimitars", "hatchets", "spears", "glaives", "halberds", "hammers", "mauls", "flails", "maces", "sickles", "scythes", "whips", "lances", "nunchaku", "sabers", "cutlasses", "tridents"), "bow`nouns`", makeList("bows", "longbows", "shortbows", "crossbows", "slings", "atlatls", "bolases", "javelins", "nets", "shuriken", "daggers"), "weapon`nouns`", makeList("blades", "knives", "swords", "axes", "stilettos", "katana", "scimitars", "hatchets", "spears", "glaives", "halberds", "hammers", "mauls", "flails", "maces", "sickles", "scythes", "whips", "lances", "nunchaku", "sabers", "cutlasses", "tridents", "bows", "longbows", "shortbows", "crossbows", "slings", "atlatls", "bolases", "javelins", "nets", "shuriken", "daggers"), "musket`nouns`", makeList("arquebusses", "blunderbusses", "muskets", "matchlocks", "flintlocks", "wheellocks", "cannons"), "grenade`nouns`", makeList("rockets", "grenades", "missiles", "bombs", "warheads", "explosives", "flamethrowers"), "rifle`nouns`", makeList("pistols", "rifles", "handguns", "firearms", "longarms", "shotguns"), "scifi`adj`", makeList("plasma", "warp", "tachyonic", "phase", "gravitational", "photonic", "nanoscale", "laser", "quantum", "genetic"), "tech`adj`", makeList("cyber", "digital", "electronic", "techno", "hacker", "crypto", "turbo", "mechanical", "servo"), "sole`adj`", makeList("sole", "true", "singular", "total", "ultimate", "final", "last"), "light`adj`", makeList("bright", "glowing", "solar", "stellar", "lunar", "radiant", "luminous", "shimmering", "gleaming"), "light`noun`", makeList("light", "glow", "sun", "star", "moon", "radiance", "dawn", "torch", "shimmer", "gleam"), "light`nouns`", makeList("lights", "glimmers", "suns", "stars", "moons", "torches"), "shadow`noun`", makeList("shadow", "darkness", "gloom", "blackness", "murk", "twilight"), "shadow`nouns`", makeList("shadows", "darkness", "gloom", "blackness", "murk", "twilight"), "fire`noun`", makeList("fire", "flame", "inferno", "conflagration", "pyre", "blaze"), "fire`nouns`", makeList("fires", "flames", "infernos", "conflagrations", "pyres", "blazes"), "ice`noun`", makeList("ice", "frost", "snow", "chill", "blizzard", "cold"), "ice`nouns`", makeList("ice", "frosts", "snow", "chills", "blizzards", "cold"), "lightning`noun`", makeList("lightning", "thunder", "thunderbolt", "storm", "spark", "shock"), "lightning`nouns`", makeList("lightning", "thunder", "thunderbolts", "storms", "sparks", "shocks"), "smart`adj`", makeList("brilliant", "smart", "genius", "wise", "clever", "cunning", "mindful", "aware"), "smart`noun`", makeList("genius", "wisdom", "cunning", "awareness", "mindfulness", "acumen", "smarts", "knowledge"), "stupid`adj`", makeList("stupid", "dumb", "idiotic", "foolish", "reckless", "careless", "sloppy", "dull", "moronic", "complacent"), "stupid`noun`", makeList("stupidity", "idiocy", "foolishness", "recklessness", "carelessness", "sloppiness", "complacency"), "bandit`noun`", makeList("thief", "raider", "bandit", "rogue", "brigand", "highwayman", "pirate"), "bandit`nouns`", makeList("thieves", "raiders", "bandits", "rogues", "brigands", "highwaymen", "pirates"), "soldier`noun`", makeList("soldier", "warrior", "fighter", "mercenary", "trooper", "combatant"), "soldier`nouns`", makeList("soldiers", "warriors", "fighters", "mercenaries", "troops", "combatants"), "guard`noun`", makeList("protector", "guardian", "warden", "defender", "guard", "shield", "sentinel", "watchman", "knight", "paladin", "templar"), "guard`nouns`", makeList("protectors", "guardians", "wardens", "defenders", "guards", "shields", "sentinels", "watchmen", "knights", "paladins", "templars"), "hunter`noun`", makeList("hunter", "poacher", "trapper", "warden", "stalker", "tracker"), "explorer`noun`", makeList("explorer", "pathfinder", "seeker", "questant", "wanderer", "nomad"), "hunter`nouns`", makeList("hunters", "poachers", "trappers", "wardens", "stalkers", "trackers"), "explorer`nouns`", makeList("explorers", "pathfinders", "seekers", "questants", "wanderers", "nomads"), "rage`noun`", makeList("rage", "fury", "anger", "wrath", "frenzy", "vengeance"), "ominous`adj`", makeList("ominous", "foreboding", "fateful", "baleful", "portentous"), "many`adj`", makeList("many", "myriad", "thousandfold", "infinite", "countless", "unlimited", "manifold"), "impossible`adj`", makeList("impossible", "forbidden", "incomprehensible", "ineffable", "unearthly", "abominable", "unspeakable", "indescribable"), "gaze`noun`", makeList("eye", "gaze", "stare", "observation", "purveyance", "watch"), "pain`noun`", makeList("pain", "agony", "misery", "excruciation", "torture"), "god`noun`", makeList("god", "deity", "ruler", "king", "father", "lord", "lordship"), "goddess`noun`", makeList("goddess", "deity", "ruler", "queen", "mother", "lady", "ladyship"), "hero`noun`", makeList("hero", "champion", "savior", "crusader", "knight"), "heroes`nouns`", makeList("heroes", "champions", "saviors", "crusaders", "knights"), "heroine`noun`", makeList("heroine", "champion", "savior", "crusader", "knight", "maiden"), "heroines`nouns`", makeList("heroines", "champions", "saviors", "crusaders", "knights", "maidens"), "popular`adj`", makeList("beloved", "adored", "revered", "worshipped"), "unpopular`adj`", makeList("reviled", "despised", "hated", "loathed"), "glyph`noun`", makeList("glyph", "sign", "symbol", "sigil", "seal", "mark"), "glyph`nouns`", makeList("glyphs", "signs", "symbols", "sigils", "seals", "marks"), "power`noun`", makeList("power", "force", "potency", "strength", "authority", "dominance"), "power`adj`", makeList("powerful", "forceful", "potent", "strong", "authoritative", "dominant") ); public static final OrderedMap> adjective = new OrderedMap<>(categories), noun = new OrderedMap<>(categories), nouns = new OrderedMap<>(categories); public static final OrderedMap languages = new OrderedMap( 100, Hashers.caseInsensitiveStringHasher ).putPairs( "lc`gen`", FakeLanguageGen.LOVECRAFT, "jp`gen`", FakeLanguageGen.JAPANESE_ROMANIZED, "fr`gen`", FakeLanguageGen.FRENCH, "gr`gen`", FakeLanguageGen.GREEK_ROMANIZED, "ru`gen`", FakeLanguageGen.RUSSIAN_ROMANIZED, "sw`gen`", FakeLanguageGen.SWAHILI, "so`gen`", FakeLanguageGen.SOMALI, "en`gen`", FakeLanguageGen.ENGLISH, "fn`gen`", FakeLanguageGen.FANTASY_NAME, "fn`acc`gen`", FakeLanguageGen.FANCY_FANTASY_NAME, "ar`gen`", FakeLanguageGen.ARABIC_ROMANIZED, "hi`gen`", FakeLanguageGen.HINDI_ROMANIZED, "in`gen`", FakeLanguageGen.INUKTITUT, "nr`acc`gen`", FakeLanguageGen.NORSE, "nr`gen`", FakeLanguageGen.NORSE_SIMPLIFIED, "na`gen`", FakeLanguageGen.NAHUATL, "mn`gen`", FakeLanguageGen.MONGOLIAN, "kr`gen`", FakeLanguageGen.KOREAN_ROMANIZED, "si`gen`", FakeLanguageGen.SIMPLISH, "el`gen`", FakeLanguageGen.ELF, "gb`gen`", FakeLanguageGen.GOBLIN, "if`gen`", FakeLanguageGen.INFERNAL, "dm`gen`", FakeLanguageGen.DEMONIC, "al`a`gen`", FakeLanguageGen.ALIEN_A, "al`e`gen`", FakeLanguageGen.ALIEN_E, "al`i`gen`", FakeLanguageGen.ALIEN_I, "al`o`gen`", FakeLanguageGen.ALIEN_O, "al`u`gen`", FakeLanguageGen.ALIEN_U, "ru`so`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.RUSSIAN_ROMANIZED, 3, FakeLanguageGen.SOMALI, 2), "gr`hi`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.GREEK_ROMANIZED, 3, FakeLanguageGen.HINDI_ROMANIZED, 2), "sw`fr`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.SWAHILI, 3, FakeLanguageGen.FRENCH, 2), "ar`jp`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.ARABIC_ROMANIZED, 3, FakeLanguageGen.JAPANESE_ROMANIZED, 2), "sw`gr`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.SWAHILI, 3, FakeLanguageGen.GREEK_ROMANIZED, 2), "gr`so`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.GREEK_ROMANIZED, 3, FakeLanguageGen.SOMALI, 2), "en`hi`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.ENGLISH, 3, FakeLanguageGen.HINDI_ROMANIZED, 2), "en`jp`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.ENGLISH, 3, FakeLanguageGen.JAPANESE_ROMANIZED, 2), "so`hi`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.SOMALI, 3, FakeLanguageGen.HINDI_ROMANIZED, 2), "fr`mod`gen`", FakeLanguageGen.FRENCH.addModifiers(FakeLanguageGen.modifier("([^aeiou])\\1", "$1ph", 0.3), FakeLanguageGen.modifier("([^aeiou])\\1", "$1ch", 0.4), FakeLanguageGen.modifier("([^aeiou])\\1", "$1sh", 0.5), FakeLanguageGen.modifier("([^aeiou])\\1", "$1", 0.9)), "jp`mod`gen`", FakeLanguageGen.JAPANESE_ROMANIZED.addModifiers(FakeLanguageGen.Modifier.DOUBLE_VOWELS), "so`mod`gen`", FakeLanguageGen.SOMALI.addModifiers(FakeLanguageGen.modifier("([kd])h", "$1"), FakeLanguageGen.modifier("([pfsgkcb])([aeiouy])", "$1l$2", 0.35), FakeLanguageGen.modifier("ii", "ai"), FakeLanguageGen.modifier("uu", "ia"), FakeLanguageGen.modifier("([aeo])\\1", "$1"), FakeLanguageGen.modifier("^x", "v"), FakeLanguageGen.modifier("([^aeiou]|^)u([^aeiou]|$)", "$1a$2", 0.6), FakeLanguageGen.modifier("([aeiou])[^aeiou]([aeiou])", "$1v$2", 0.06), FakeLanguageGen.modifier("([aeiou])[^aeiou]([aeiou])", "$1l$2", 0.07), FakeLanguageGen.modifier("([aeiou])[^aeiou]([aeiou])", "$1n$2", 0.07), FakeLanguageGen.modifier("([aeiou])[^aeiou]([aeiou])", "$1z$2", 0.08), FakeLanguageGen.modifier("([^aeiou])[aeiou]+$", "$1ia", 0.35), FakeLanguageGen.modifier("([^aeiou])[bpdtkgj]", "$1"), FakeLanguageGen.modifier("[jg]$", "th"), FakeLanguageGen.modifier("g", "c", 0.92), FakeLanguageGen.modifier("([aeiou])[wy]$", "$1l", 0.6), FakeLanguageGen.modifier("([aeiou])[wy]$", "$1n"), FakeLanguageGen.modifier("[qf]$", "l", 0.4), FakeLanguageGen.modifier("[qf]$", "n", 0.65), FakeLanguageGen.modifier("[qf]$", "s"), FakeLanguageGen.modifier("cy", "sp"), FakeLanguageGen.modifier("kl", "sk"), FakeLanguageGen.modifier("qu+", "qui"), FakeLanguageGen.modifier("q([^u])", "qu$1"), FakeLanguageGen.modifier("cc", "ch"), FakeLanguageGen.modifier("[^aeiou]([^aeiou][^aeiou])", "$1"), FakeLanguageGen.Modifier.NO_DOUBLES), "ru`gr`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.RUSSIAN_ROMANIZED, 3, FakeLanguageGen.GREEK_ROMANIZED, 2), "lc`gr`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.LOVECRAFT, 3, FakeLanguageGen.GREEK_ROMANIZED, 2), "in`so`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.INUKTITUT, 3, FakeLanguageGen.SOMALI, 2), "ar`in`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.ARABIC_ROMANIZED, 3, FakeLanguageGen.INUKTITUT, 2), "na`lc`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.NAHUATL, 3, FakeLanguageGen.LOVECRAFT, 2), "na`sw`gen`", FakeLanguageGen.mixAll(FakeLanguageGen.NAHUATL, 3, FakeLanguageGen.SWAHILI, 2), "nr`ru`gen`", FakeLanguageGen.mixAll( FakeLanguageGen.NORSE_SIMPLIFIED, 3, FakeLanguageGen.RUSSIAN_ROMANIZED, 2), "nr`in`gen`", FakeLanguageGen.mixAll( FakeLanguageGen.NORSE_SIMPLIFIED, 3, FakeLanguageGen.INUKTITUT, 2), "mn`so`gen`", FakeLanguageGen.mixAll( FakeLanguageGen.MONGOLIAN, 3, FakeLanguageGen.SOMALI, 2), "dm`gr`gen`", FakeLanguageGen.mixAll( FakeLanguageGen.DEMONIC, 3, FakeLanguageGen.GREEK_ROMANIZED, 2), "if`na`gen`", FakeLanguageGen.mixAll( FakeLanguageGen.INFERNAL, 3, FakeLanguageGen.NAHUATL, 2 ), "el`in`gen`", FakeLanguageGen.mixAll( FakeLanguageGen.ELF, 3, FakeLanguageGen.INUKTITUT, 2 ) ); public static final OrderedMap numbers = new OrderedMap( 100, Hashers.caseInsensitiveStringHasher ).putPairs( "one`noun`", 1, "two`noun`", 2, "three`noun`", 3, "four`noun`", 4, "five`noun`", 5, "six`noun`", 6, "seven`noun`", 7, "eight`noun`", 8, "nine`noun`", 9, "ten`noun`", 10, "eleven`noun`", 11, "twelve`noun`", 12, "thirteen`noun`", 13, "fourteen`noun`", 14, "fifteen`noun`", 15, "sixteen`noun`", 16, "seventeen`noun`", 17, "eighteen`noun`", 18, "nineteen`noun`", 19, "twenty`noun`", 20 ), numberAdjectives = new OrderedMap( 100, Hashers.caseInsensitiveStringHasher ).putPairs( "one`adj`", 1, "two`adj`", 2, "three`adj`", 3, "four`adj`", 4, "five`adj`", 5, "six`adj`", 6, "seven`adj`", 7, "eight`adj`", 8, "nine`adj`", 9, "ten`adj`", 10, "eleven`adj`", 11, "twelve`adj`", 12, "thirteen`adj`", 13, "fourteen`adj`", 14, "fifteen`adj`", 15, "sixteen`adj`", 16, "seventeen`adj`", 17, "eighteen`adj`", 18, "nineteen`adj`", 19, "twenty`adj`", 20 ); /** * Thesaurus preset that changes all text to sound like this speaker: "Desaurus preset dat changez all text to sound * like dis speakah." You may be familiar with a certain sci-fi game that has orks that sound like this. */ public static Thesaurus ORK = new Thesaurus("WAAAAAGH!"); static { ORK.alterations.add(new FakeLanguageGen.Alteration("\\bth", "d")); ORK.alterations.add(new FakeLanguageGen.Alteration("th", "dd")); ORK.alterations.add(new FakeLanguageGen.Alteration("er\\b", "ah")); ORK.alterations.add(new FakeLanguageGen.Alteration("es\\b", "ez")); ORK.addReplacement("the", "da") .addReplacement("their", "deyr") .addReplacement("yes", "ya") .addReplacement("your", "youse") .addReplacement("yours", "youses") .addReplacement("going", "gon'") .addReplacement("and", "an'") .addReplacement("to", "*snort*") .addReplacement("rhythm", "riddim") .addReplacement("get", "git") .addReplacement("good", "gud"); Iterator it = adjective.keySet().iterator(); while (it.hasNext()){ if(!it.next().contains("`adj`")) it.remove(); } it = noun.keySet().iterator(); while (it.hasNext()){ if(!it.next().contains("`noun`")) it.remove(); } it = nouns.keySet().iterator(); while (it.hasNext()){ if(!it.next().contains("`nouns`")) it.remove(); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy