Browse Source

initial commit of babble

master
Inderjit Gill 3 years ago
commit
9f0cd03e9e
7 changed files with 864 additions and 0 deletions
  1. +3
    -0
      .gitignore
  2. +6
    -0
      Cargo.toml
  3. +69
    -0
      research/AFTRGrammar.json
  4. +644
    -0
      research/FearlessBakery.cs
  5. +44
    -0
      research/Grammar.json
  6. +91
    -0
      research/StridentNames.json
  7. +7
    -0
      src/lib.rs

+ 3
- 0
.gitignore View File

@ -0,0 +1,3 @@
/target
**/*.rs.bk
Cargo.lock

+ 6
- 0
Cargo.toml View File

@ -0,0 +1,6 @@
[package]
name = "babble"
version = "0.1.0"
authors = ["Inderjit Gill <email@indy.io>"]
[dependencies]

+ 69
- 0
research/AFTRGrammar.json View File

@ -0,0 +1,69 @@
{
"bot-name": ["Model #digit##digit##digit# #bot-n#", "Series #digit# #bot-n#",
"#bot-n# (Revision #digit#)", "#bot-superlative# #bot-n#"],
"bot-prefix": ["Com", "Doom", "Death", "Pain", "Stop", "Gun", "Shoot", "Blast",
"Bang", "Blam", "Scorch", "Slam", "Charge"],
"bot-postfix": ["Man", "Kong", "Nism", "Lord", "Gorilla", "Force", "Pig"],
"bot-childish": ["Robbie", "Robby", "Robbi", "Andy", "Chuck", "Jimmy", "Dave", "Nigel",
"Percival", "Brutus", "Chubb", "Eve", "Molly"],
"bot-inventive": ["Boilerplate", "Anne Droid", "Gunslinger", "Chip", "Bender", "Deep Thought", "HAL"],
"bot-crappy": ["#bot-inventive#", "#bot-childish# The Robot"],
"bot-n": ["#bot-prefix#bot", "#bot-prefix#-A-Tron", "#bot-prefix#-inator", "Robo#bot-postfix#",
"Cyber-#bot-postfix#", "Mecha-#bot-postfix#", "#bot-crappy#"],
"bot-superlative": ["Super", "Mega", "Ultra", "Metal Bastard"],
"digit": ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
"vowel": ["a", "e", "i", "o", "u"],
"ct-named-absinthe": ["Death in the Afternoon", "Earthquake", "Green Russian", "Green Vesper", "Moloko Plus"],
"ct-named-beer": ["Black and Tan", "Black Velvet", "Boilermaker", "Gose", "Hangman's Blood", "Irish Car Bomb", "Michelada", "Porchcrawler", "Sake Bomb", "Shandy", "Snakebite", "U-Boot"],
"ct-named-brandy": ["B & B", "The Blenheim", "Brandy Alexander", "Brandy Manhattan", "Brandy Sour (Cyprus)", "Brandy Sour/Brandy Daisy", "Chicago Cocktail", "Curacao Punch", "Four Score", "French Connection", "Hennchata", "Horse's Neck", "Incredible Hulk", "Jack Rose", "Nikolaschka", "Orgasm", "Panama", "Paradise", "Pisco Sour", "Porto flip", "Savoy Affair", "Savoy Corpse Reviver", "Sazerac", "Sidecar", "Singapore Sling", "Stinger", "Tom and Jerry", "Zombie"],
"ct-named-gin": ["20th Century", "Bramble ", "Alexander", "Angel Face ", "Aviation ", "Bee's Knees", "Bijou", "Bloodhound", "Breakfast martini", "Bronx", "Casino ", "Clover Club Cocktail ", "Corpse Reviver 2", "Damn the Weather", "French 75 ", "Derby ", "Gibson", "Gimlet", "Gin and tonic", "Gin buck", "Gin Fizz ", "Gin pahit", "Gin Sour", "Greyhound", "Hanky-Panky", "John Collins ", "Joker", "The Last Word", "Lime Rickey", "London Fog", "Long Island Iced Tea ", "Lorraine", "Martini ", "Mickey Slim", "Monkey Gland ", "My Fair Lady", "Negroni ", "Old Etonian", "Pall Mall", "Paradise", "Pegu", "Pimm's Cup", "Pink Gin", "Pink Lady", "Ramos Gin Fizz ", "Royal Arrival", "Salty Dog", "Shirley Temple Black", "Singapore Sling ", "Tom Collins", "Tuxedo ", "Vesper Martini ", "White Lady or Delilah", "Wolfram"],
"ct-named-rum": ["Bacardi", "Between the Sheets", "Blue Hawaii", "Brass Monkey", "Bumbo (also called a Bombo or Bumboo)", "Bushwacker", "Caribou Lou", "Cojito", "Corn N' Oil", "Cuba Libre ", "Culto A La Vida", "Daiquiri ", "Dark and Stormy", "El Presidente", "Fish House Punch", "Flaming Dr Pepper", "Flaming Volcano", "Fluffy Critter", "The Goldeneye", "Grog", "Gunfire", "Havana Cooler", "Hot buttered rum", "Hurricane", "Jagertee", "Long Island Iced Tea", "Macua", "Mai-Tai", "Mojito", "Painkiller", "Piña Colada", "Planter's Punch", "Royal Bermuda Cocktail", "Rum Swizzle", "Staten Island Ferry", "Sundowner", "Ti' Punch", "Tom and Jerry", "Tschunk", "Yellow Bird", "Zombie"],
"ct-named-tequila": ["Bananarita", "Bloody Aztec", "Chimayo Cocktail", "El Toro Loco Patron and Redbull", "Juan Collins", "Long Island Iced Tea", "Margarita", "Matador", "Paloma", "Slammer Royale", "Tequila Slammer", "Tequila and Tonic", "Tequila Sour"],
"ct-named-vodka": ["Agent Orange", "Apple Martini or Appletini", "Astro pop", "Batida (traditionally made with cachaça)", "Bay Breeze", "Black Russian", "Bloody Mary", "BLT cocktail", "Blue Lagoon", "Bull Shot", "Caesar", "Caipivodka or Caipiroska", "Cape Cod", "Chi-Chi", "Colombia", "Cosmopolitan", "Fizzy apple cocktail", "Flirtini", "Gimlet", "Glowtini", "Godmother", "The Goldeneye", "Harrogate Nights", "Harvey Wallbanger", "Hi-fi", "Kamikaze", "Kensington Court Special", "Kremlin Colonel", "Lemon Drop", "Lime Rickey", "Link Up", "Long Island Iced Tea", "Moscow Mule", "Mudslide", "Orange Tundra", "Paralyzer", "Red Lotus", "Red Russian", "Rose Kennedy Cocktail", "Salmiakki Koskenkorva", "Salty Dog", "Screwdriver", "Sea Breeze", "Sex on the Beach", "Vesper", "Vodka Gimlet", "Vodka Martini or Kangaroo", "Vodka McGovern", "Vodka Sundowner", "Vodka Sunrise", "White Russian", "Woo Woo", "Yorsh"],
"ct-named-whisky": ["Amber Moon", "A Black Jack", "Blue Blazer", "Bobby Burns", "Bourbon Lancer", "Brooklyn", "Churchill", "Farnell", "Four Horsemen", "Irish Coffee", "Jack and Coke", "Jungle Juice", "Lynchburg Lemonade", "Manhattan", "Mint Julep", "Missouri Mule", "Nixon", "Old Fashioned", "Rob Roy", "Rusty Nail", "Sazerac", "Seven and Seven", "Three Wise Men", "Ward 8", "Whisky Mac", "Whiskey sour"],
"ct-named": ["#ct-named-absinthe#", "#ct-named-beer#", "#ct-named-brandy#", "#ct-named-gin#", "#ct-named-rum#", "#ct-named-tequila#", "#ct-named-vodka#", "#ct-named-whisky#"],
"ct-quantity": ["2", "3", "4"],
"ct-part": ["1 part", "300%#ct-quantity# parts"],
"ct-citrus": ["Lemon", "Lime", "Orange", "Pineapple"],
"ct-citrus-garnish": ["a twist of #ct-citrus#", "a wedge of #ct-citrus#"],
"ct-edible-garnishes": ["500%#ct-citrus-garnish#", "Carrot sticks", "Celery stalks", "Cherries", "Grated Cinnamon", "Cocktail olives", "Cocktail onions", "Mint sprigs", "Mint leaves", "Grated Nutmeg", "Pepper", "Coarse Salt applied to the rim of glasses", "Granulated Sugar", "Powdered Sugar", "Shrimp", "Strawberries", "wedge of Watermelon"],
"ct-inedible-garnishes": ["Plastic animals (attached to the rim of the glass)", "Candles", "Cocktail umbrellas", "Drinking straws (colorful or unusually shaped)", "Flags", "Plastic swords", "Sparklers", "Swizzle sticks"],
"ct-mixer-caffeinated": ["Coffee", "Energy drink", "Red Bull", "Iced tea", "Lipton BRISK", "Nestea"],
"ct-mixer-carbonated": ["Bitter Lemon", "Carbonated Water", "Club Soda", "Soda Water", "Seltzer Water", "Sparkling Water", "Coca-Cola", "Pepsi", "Ginger Ale", "Ginger Beer", "Lemon Sour", "Lemon-Lime Soda", "7 Up", "Sprite", "Root Beer", "Orange Soda", "Grape Soda", "Cherry Soda", "Tonic Water"],
"ct-mixer-dairy": ["Cream", "Eggnog", "Half and half", "Ice cream", "Milk"],
"ct-mixer-juices": ["Apple Cider", "Coconut Milk", "Coconut Water", "Cranberry Juice", "Grape Juice", "Grapefruit Juice", "Lemon Juice", "Lemonade", "Lime Juice, Unsweetened", "Limeade", "Olive Juice", "Orange Juice", "Pineapple Juice", "Tomato Juice", "V-8", "Clamato", "Wheatgrass Juice"],
"ct-mixer-prepared": ["Bloody Mary mix", "Cosmopolitan mix", "Hot Toddy mix", "Margarita mix", "Mojito mix", "Mudslide mix", "Strawberry Daiquiri mix"],
"ct-mixer-sauce": ["Honey", "Hot Sauce", "Tabasco Sauce", "Worcestershire Sauce"],
"ct-mixer-syrup": ["Demerara Syrup", "Falernum", "Grenadine", "Lime Juice", "Orgeat", "Simple Syrup", "Sour Mix", "Squash"],
"ct-mixer-other": ["Egg", "Food coloring", "Gatorade", "SunnyD", "Redbull"],
"ct-alcohol-distilled": ["Absinthe", "Applejack", "Brandy", "Armagnac", "Cognac", "Fruit brandy", "Eau-de-vie", "Schnapps", "Kirsch", "Gin", "Damson gin", "Sloe gin", "Neutral grain spirit", "Ouzo", "Raki", "Rakia", "Slivovitz", "Rum", "Tequila", "Vodka", "Whisky", "Bourbon whiskey", "Canadian whisky", "Irish whiskey", "Japanese whisky", "Rye whiskey", "Scotch whisky", "Tennessee whiskey"],
"ct-alcohol-flamable": ["Amaretto", "Cognac", "Everclear", "Gin", "Grand Marnier", "Kahlua", "Overproof rum", "Rum 151", "Bacardi 151", "Sambucca", "Scotch whisky", "Vodka"],
"ct-cocktail-garnish": ["#ct-edible-garnishes#", "#ct-inedible-garnishes#"],
"ct-cocktail-mixer": ["#ct-mixer-caffeinated#", "#ct-mixer-carbonated#", "#ct-mixer-dairy#", "#ct-mixer-juices#", "#ct-mixer-prepared#", "#ct-mixer-sauce#", "#ct-mixer-syrup#", "#ct-mixer-other#"],
"ct-cocktail-alcohol": ["#ct-alcohol-distilled#", "#ct-alcohol-flamable#"],
"ct-cocktail-recipe": ["#ct-part# #ct-cocktail-alcohol#, #ct-part# #ct-cocktail-alcohol#, #ct-part# #ct-cocktail-mixer#",
"#ct-part# #ct-cocktail-alcohol#, #ct-part# #ct-cocktail-alcohol#, #ct-part# #ct-cocktail-alcohol#",
"#ct-part# #ct-cocktail-alcohol#, #ct-part# #ct-cocktail-alcohol#, #ct-part# #ct-cocktail-alcohol#, #ct-part# #ct-cocktail-mixer#",
"#ct-part# #ct-cocktail-alcohol#, #ct-part# #ct-cocktail-mixer#, #ct-part# #ct-cocktail-mixer#"],
"ct-cocktail-main": ["800%#ct-cocktail-recipe#",
"800%#ct-cocktail-recipe# garnished with #ct-cocktail-garnish#",
"#ct-named-absinthe.a# with the Absinthe replaced by #ct-cocktail-alcohol#",
"#ct-named-beer.a# with the beer replaced by #ct-cocktail-alcohol#",
"#ct-named-brandy.a# with the Brandy replaced by #ct-cocktail-alcohol#",
"#ct-named-gin.a# with the Gin replaced by #ct-cocktail-alcohol#",
"#ct-named-rum.a# with the Rum replaced by #ct-cocktail-alcohol#",
"#ct-named-tequila.a# with the Tequila replaced by #ct-cocktail-alcohol#",
"#ct-named-vodka.a# with the Vodka replaced by #ct-cocktail-alcohol#",
"#ct-named-whisky.a# with the Whisky replaced by #ct-cocktail-alcohol#"]
}

+ 644
- 0
research/FearlessBakery.cs View File

@ -0,0 +1,644 @@
using UnityEngine;
using UnityEngine.Assertions;
using System;
using System.Collections.Generic;
using Common.SimpleJSON;
namespace Common.FearlessBakery
{
public enum NodeType
{
Unknown,
PlainText,
Variable,
Templated
}
public enum ModifierType
{
None,
A, // a monkey
S, // monkeys
Ed // monkeyed
}
public class Grammar
{
public Dictionary<string, List<Node>> rules;
public Dictionary<string, string> bindings;
public UnityEngine.Random.State randomState;
public EnglishModifier modifier;
public Grammar(Dictionary<string, List<string>> spec, int seed)
{
rules = BuildRules(spec);
UnityEngine.Random.InitState(seed);
randomState = UnityEngine.Random.state;
modifier = new EnglishModifier();
}
public static Grammar FromJson(string json, int seed)
{
Dictionary<string, List<string>> spec = ParseSpecFromJson(json);
return new Grammar(spec, seed);
}
public static Grammar FromJsonResource(string resourceName, int seed)
{
TextAsset jsonFile = Resources.Load(resourceName) as TextAsset;
string json = jsonFile.text;
return Grammar.FromJson(json, seed);
}
public List<string> GetRuleKeys()
{
List<string> res = new List<string>();
foreach(var key in rules.Keys)
{
res.Add(key);
}
return res;
}
private static Dictionary<string, List<string>> ParseSpecFromJson(string json)
{
var N = JSON.Parse(json);
Dictionary<string, List<string>> spec = new Dictionary<string, List<string>>();
foreach(KeyValuePair<string, JSONNode> kvp in N.AsObject)
{
string key = kvp.Key;
JSONNode value = kvp.Value;
JSONArray arr = value.AsArray;
List<string> ls;
if (arr == null)
{
// this is a string, so load the referenced json file
ls = ParseReferencedJsonArray(value.Value, key);
}
else
{
ls = ParseJsonArray(arr);
}
spec[key] = ls;
}
return spec;
}
private static List<string> ParseReferencedJsonArray(string resourceName, string key)
{
TextAsset jsonFile = Resources.Load(resourceName) as TextAsset;
if(jsonFile == null)
{
Debug.Log("unable to load resource: " + resourceName);
}
string json = jsonFile.text;
var N = JSON.Parse(json);
JSONArray arr = N[key].AsArray;
return ParseJsonArray(arr);
}
private static List<string> ParseJsonArray(JSONArray arr)
{
List<string> res = new List<string>();
foreach (JSONNode item in arr)
{
res.Add(item.Value);
}
return res;
}
public string GenerateSentence(string input)
{
Node n = new Node(input);
bindings = new Dictionary<string, string>();
// restore the random state
UnityEngine.Random.state = randomState;
string res = GenerateSentenceNode(n);
// save the current state for next time
randomState = UnityEngine.Random.state;
return res;
}
private string GenerateSentenceNode(Node n)
{
switch(n.type)
{
case NodeType.PlainText:
return ConstructFromPlainText(n);
case NodeType.Variable:
return ConstructFromVariable(n);
case NodeType.Templated:
return ConstructFromTemplate(n);
default:
return null;
}
}
private string ConstructFromTemplate(Node n)
{
string res = "";
foreach(var node in n.children)
{
string segment = GenerateSentenceNode(node);
if (segment == null)
{
// log message about failure of node while building template n
return null;
}
res += segment;
}
return res;
}
private string ConstructFromPlainText(Node n)
{
return n.text;
}
private string ConstructFromVariable(Node n)
{
AddInPlaceBindings(n);
string generatedSubSentence = GetBinding(n.text);
return n.ModifyText(generatedSubSentence, modifier);
}
private void AddInPlaceBindings(Node n)
{
if(n.inPlaceBindings == null)
{
return;
}
foreach(KeyValuePair<string, string> kv in n.inPlaceBindings)
{
string key = kv.Key;
Node vNode = new Node(kv.Value);
string value = GenerateSentenceNode(vNode);
bindings[key] = value;
}
}
private string GetBinding(string variable)
{
string bound;
// first check the user made bindings e.g. "#[hero:#name#]story#
if (bindings.TryGetValue(variable, out bound))
{
return bound;
}
// otherwise look at the rules
List<Node> rule;
if (rules.TryGetValue(variable, out rule) == false)
{
//Debug.Log("rules does not contain key: <<" + variable + ">>");
return null;
}
Node subNode = ChooseNodeAtRandom(rule);
return GenerateSentenceNode(subNode);
}
private Node ChooseNodeAtRandom(List<Node> listNodes)
{
int weightSum = 0;
foreach(Node n in listNodes)
{
weightSum += n.weight;
}
int weightValue = UnityEngine.Random.Range(0, weightSum);
// Debug.Log("weightSum: " + weightSum + " weightValue: " + weightValue);
weightSum = 0;
int i = 0;
foreach(Node n in listNodes)
{
if(weightValue >= weightSum && weightValue < weightSum + n.weight)
{
//Debug.Log("chosen index: " + i);
return n;
}
weightSum += n.weight;
i += 1;
}
Assert.IsNotNull(null, "should never get here");
return null;
}
private Dictionary<string, List<Node>> BuildRules(Dictionary<string, List<string>> spec)
{
Dictionary<string, List<Node>> rules = new Dictionary<string, List<Node>>();
foreach(var key in spec.Keys)
{
rules[key] = BuildNodeListFromSpecList(spec[key]);
}
return rules;
}
private List<Node> BuildNodeListFromSpecList(List<string> specList)
{
List<Node> nodeList = new List<Node>();
foreach(var s in specList)
{
Node n = new Node(s);
nodeList.Add(n);
}
return nodeList;
}
}
public class Node
{
public NodeType type;
/*
if type is plaintext: text is the raw text
if type is variable: text is the name of the variable
if type is template: text is unused
*/
public string text;
// for NodeType.Template nodes only
public List<Node> children;
// for NodeType.Variable nodes only:
public ModifierType modifierType;
public List<KeyValuePair<string, string>> inPlaceBindings = null;
// for all node types
public int weight;
public Node(string raw)
{
ParseRaw(raw);
}
public string ModifyText(string input, EnglishModifier modifier)
{
switch(modifierType)
{
case ModifierType.A:
return modifier.A(input);
case ModifierType.S:
return modifier.S(input);
case ModifierType.Ed:
return modifier.Ed(input);
default:
return input;
}
}
private void ParseRaw(string raw)
{
raw = StripWeight(raw);
if (IsPlainText(raw))
{
ParsePlainText(raw);
}
else if (IsVariable(raw))
{
ParseVariable(raw);
}
else
{
ParseTemplated(raw);
}
}
private string StripWeight(string raw)
{
int index = raw.IndexOf('%');
if (index == -1)
{
this.weight = 100;
return raw;
}
// raw contains a %, make sure everything that comes before it is a digit
string digits = raw.Substring(0, index);
int val;
bool parseResult = Int32.TryParse(digits, out val);
if (parseResult == false)
{
// contains a % but the text before it couldn't be parsed as a number
return raw;
}
weight = val;
raw = raw.Substring(index + 1);
return raw;
}
// vast majority of nodes will be plain text
private bool IsPlainText(string raw)
{
int index = raw.IndexOf('#');
return (index == -1);
}
// a pure variable
private bool IsVariable(string raw)
{
if(raw[0] != '#' || raw[raw.Length-1] != '#')
{
return false;
}
bool insideSquareBrackets = false;
for(int i = 1; i < raw.Length - 1; i++)
{
if(raw[i] == '[')
{
insideSquareBrackets = true;
}
if(raw[i] == ']')
{
insideSquareBrackets = false;
}
if(raw[i] == '#' && insideSquareBrackets == false)
{
return false;
}
}
return true;
}
private void ParsePlainText(string raw)
{
this.type = NodeType.PlainText;
this.text = raw;
}
private void ParseVariable(string raw)
{
this.type = NodeType.Variable;
this.text = raw.Substring(1, raw.Length - 2);
// check for in-var definitions
ParseInPlaceBindings();
// check for a modifier
ParseVariableModifier();
}
private void ParseInPlaceBindings()
{
// remove and store variable declarations
// e.g. hero and heroPet in "#[hero:#name#][heroPet:#animal#]story#"
while(this.text[0] == '[')
{
int closeIndex = this.text.IndexOf(']');
// remove the text between square brackets
string decl = this.text.Substring(1, closeIndex - 1);
// split the variable declaration into name and value
int colonIndex = decl.IndexOf(':');
string varName = decl.Substring(0, colonIndex);
string varValue = decl.Substring(colonIndex + 1); // note varValue could be plaintext, variable or a template
AddInPlaceBinding(varName, varValue);
// remove the square bracketed text from this.text
this.text = this.text.Substring(closeIndex + 1);
}
}
private void AddInPlaceBinding(string name, string value)
{
if(inPlaceBindings == null)
{
inPlaceBindings = new List<KeyValuePair<string, string>>();
}
KeyValuePair<string, string> pair = new KeyValuePair<string, string>(name, value);
inPlaceBindings.Add(pair);
}
private void ParseVariableModifier()
{
int dot = text.IndexOf('.');
if (dot == -1)
{
// this variable doesn't have a modifier
return;
}
string modifier = text.Substring(dot + 1, text.Length - (dot + 1));
text = text.Substring(0, dot);
switch (modifier)
{
case "a":
this.modifierType = ModifierType.A;
break;
case "s":
this.modifierType = ModifierType.S;
break;
case "ed":
this.modifierType = ModifierType.Ed;
break;
default:
this.modifierType = ModifierType.None;
break;
}
}
// "this is a #name#"
// "#something# delta"
// "alpha #something# delta"
// "#[heroPet:#pet#]story# #[heroPet:#pet#]story#"
private void ParseTemplated(string raw)
{
int start = 0;
int index = 1;
bool insideVar = raw[0] == '#';
bool insideSquareBrackets = false;
string s;
Node n;
this.type = NodeType.Templated;
this.children = new List<Node>();
while (index < raw.Length)
{
if (raw[index] == '[' && insideVar)
{
insideSquareBrackets = true;
}
if (raw[index] == ']' && insideVar)
{
insideSquareBrackets = false;
}
if (raw[index] == '#' && insideSquareBrackets == false)
{
if (insideVar == true)
{
// end of a var
s = raw.Substring(start, (index - start) + 1);
n = new Node(s);
this.children.Add(n);
start = index + 1;
insideVar = false;
}
else
{
// start of a var, so add the plaintext
s = raw.Substring(start, index - start);
n = new Node(s);
this.children.Add(n);
start = index;
insideVar = true;
}
}
index += 1;
}
// add the end
if (insideVar == true)
{
// end of a var
s = raw.Substring(start, (index - start) + 1);
n = new Node(s);
this.children.Add(n);
}
else if (index != start)
{
// start of a var, so add the plaintext
s = raw.Substring(start, index - start);
n = new Node(s);
this.children.Add(n);
}
}
}
public class EnglishModifier
{
public string A(string input)
{
if (input.Length > 0)
{
if (char.ToLower(input[0]) == 'u')
{
if(input.Length > 2)
{
if (char.ToLower(input[2]) == 'i')
{
return "a " + input;
}
}
}
if (IsVowelAt(input, 0))
{
return "an " + input;
}
return "a " + input;
}
return input;
}
public string S(string input)
{
int len = input.Length;
char c = char.ToLower(input[len - 1]);
switch(c)
{
case 's':
return input + "es";
case 'h':
return input + "es";
case 'x':
return input + "es";
case 'y':
if (IsVowelAt(input, len - 2) == false)
{
return input.Substring(0, len - 1) + "ies";
}
else
{
return input + "s";
}
default:
return input + "s";
}
}
public string Ed(string input)
{
int len = input.Length;
char c = char.ToLower(input[len - 1]);
switch(c)
{
case 'e':
return input + "d";
case 'y':
if (IsVowelAt(input, len - 2) == false)
{
return input.Substring(0, len - 1) + "ied";
}
else
{
return input + "ed";
}
default:
return input + "ed";
}
}
private bool IsVowelAt(string s, int index)
{
char c = char.ToLower(s[index]);
return (c == 'a')
|| (c == 'e')
|| (c == 'i')
|| (c == 'o')
|| (c == 'u');
}
}
}

+ 44
- 0
research/Grammar.json View File

@ -0,0 +1,44 @@
{
"british-political-party": "Corpora/BritishPoliticalParties",
"english-town": "Corpora/EnglishTowns",
"english-city": "Corpora/EnglishCities",
"occupation": "Corpora/Occupations",
"name-prefix": "Corpora/NamePrefixes",
"name-honorific": "Corpora/NameHonorifics",
"name-first": "Corpora/NameFirsts",
"name-last": "Corpora/NameLasts",
"body-part": "Corpora/BodyParts",
"mood": "Corpora/Moods",
"wrestler": "Corpora/Wrestlers",
"passage": "Corpora/Passages",
"room": "Corpora/Rooms",
"music-genre": "Corpora/MusicGenres",
"netflix-category": "Corpora/NetflixCategories",
"tv-show": "Corpora/TVShows",
"car": "Corpora/Cars",
"fortune-500": "Corpora/Fortune500",
"industry": "Corpora/Industries",
"american-newspaper": "Corpora/AmericanNewspapers",
"beer-style": "Corpora/BeerStyles",
"bread": "Corpora/Breads",
"pastry": "Corpora/Pastries",
"condiment": "Corpora/Condiments",
"fruit": "Corpora/Fruits",
"herb": "Corpora/Herbs",
"spice": "Corpora/Spices",
"food-menu-item": "Corpora/FoodMenuItems",
"pizza-topping": "Corpora/PizzaToppings",
"vegetable": "Corpora/Vegetables",
"wine-description": "Corpora/WineDescriptions",
"packaging": "Corpora/Packaging",
"sculpture-material": "Corpora/SculptureMaterials",
"wrestling-move": "Corpora/WrestlingMoves",
"full-name": ["#name-first# #name-last#",
"#name-prefix# #name-first# #name-last#",
"#name-honorific# #name-first# #name-last#"],
"english-place": ["#english-town#", "#english-city#"],
"move": ["#wine-description#, #mood# #wrestling-move#"],
"full": ["#full-name# from #english-place# voted for #british-political-party#",
"#full-name# drank so much #beer-style# with #full-name# that they made #pizza-topping.a# pizza with extra #spice#, it tasted very #wine-description#",
"'#wine-description#, #mood# #wrestling-move#'"]
}

+ 91
- 0
research/StridentNames.json View File

@ -0,0 +1,91 @@
{
"army-name": ["#low-army-rank# #male-full-name#"],
"police-name": ["#low-police-rank# #male-full-name#"],
"civilian-name": ["#male-full-name#"],
"bot-name": ["Model #digit##digit##digit# #bot-n#", "Series #digit# #bot-n#",
"#bot-n# (Revision #digit#)", "#bot-superlative# #bot-n#"],
"alien-name": ["#alien-n#", "#alien-n# #alien-postfix#"],
"alien-eye-name": ["#alien-eye-prefix# #alien-n#", "#alien-eye-prefix# #alien-n# #alien-eye-postfix#",
"#alien-n# #alien-eye-postfix#"],
"bot-prefix": ["Com", "Doom", "Death", "Pain", "Stop", "Gun", "Shoot", "Blast",
"Bang", "Blam", "Scorch", "Slam", "Charge"],
"bot-postfix": ["Man", "Kong", "Nism", "Lord", "Gorilla", "Force", "Pig"],
"bot-childish": ["Robbie", "Robby", "Robbi", "Andy", "Chuck", "Jimmy", "Dave", "Nigel",
"Percival", "Brutus", "Chubb", "Eve", "Molly"],
"bot-inventive": ["Boilerplate", "Anne Droid", "Gunslinger", "Chip", "Bender", "Deep Thought", "HAL"],
"bot-crappy": ["#bot-inventive#", "#bot-childish# The Robot"],
"bot-n": ["#bot-prefix#bot", "#bot-prefix#-A-Tron", "#bot-prefix#-inator", "Robo#bot-postfix#",
"Cyber-#bot-postfix#", "Mecha-#bot-postfix#", "#bot-crappy#"],
"bot-superlative": ["Super", "Mega", "Ultra", "Metal Bastard"],
"alien-n-prefix": ["B", "C", "K", "M", "N", "Q", "R", "V", "X", "Z"],
"alien-n-postfix": ["d", "n", "t", "k", "z", "x"],
"alien-n": ["#alien-n-prefix##vowel##alien-n-postfix#", "#alien-n-prefix##vowel##alien-n-postfix#"],
"alien-house-name": ["Alcaatraan", "Korano", "Ecaz", "Feunrig", "Haegal", "Ginaz", "Moratani",
"Novebruns", "Erdos", "Vernius"],
"alien-postfix": ["#digit#", "spawn of #alien-n#, #alien-n# and #alien-n#",
"clone #digit# of #alien-n#"],
"alien-eye-prefix": ["Admiral", "Captain", "Duke", "Officer"],
"alien-eye-postfix": ["of House #alien-house-name#", "Prime"],
"low-army-rank": ["Private", "Corporal", "1st Sergeant", "Major"],
"low-police-rank": ["Captain", "Lieutenant", "Sergeant", "Corporal", "Senior Deputy Sheriff",
"Senior Deputy", "Deputy Sheriff", "Deputy", "Cadet"],
"digit": ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"],
"vowel": ["a", "e", "i", "o", "u"],
"male-full-name": ["#male-first-name# #name-last#",
"10%#male-first-name# #name-last# Jr.",
"10%#male-first-name# #name-last# III"],
"male-first-name": ["Aaron", "Abraham", "Adam", "Adrian", "Aidan", "Aiden", "Alan", "Alejandro",
"Alex", "Alexander", "Andrew", "Anthony", "Antonio", "Ashton", "Austin",
"Benjamin", "Blake", "Bradley", "Brady", "Brandon", "Brian", "Brody", "Brooklyn",
"Bryan", "Caleb", "Cameron", "Carlos", "Carson", "Carter", "Cassidy", "Cesar",
"Charles", "Chase", "Christian", "Christopher", "Cody", "Cole", "Colin",
"Collin", "Colton", "Conner", "Connor", "Cooper", "Cristian", "Dalton", "Damian",
"Daniel", "David", "Delaney", "Derek", "Diego", "Dominic", "Donovan", "Dylan",
"Edgar", "Eduardo", "Edward", "Edwin", "Eli", "Elias", "Elijah", "Emmanuel",
"Eric", "Erick", "Erik", "Ethan", "Evan", "Fernando", "Francisco", "Gabriel",
"Gage", "Garrett", "Gavin", "George", "Giovanni", "Grant", "Gregory", "Hayden",
"Hector", "Henry", "Hunter", "Ian", "Isaac", "Isaiah", "Ivan", "Jack", "Jackson",
"Jacob", "Jaden", "Jake", "James", "Jared", "Jason", "Javier", "Jayden", "Jeffrey",
"Jeremiah", "Jeremy", "Jesus", "Joel", "John", "Johnathan", "Jonah", "Jonathan",
"Jordan", "Jordyn", "Jorge", "Jose", "Joseph", "Joshua", "Josiah", "Juan", "Julian",
"Justin", "Kaden", "Kaleb", "Kelsey", "Kennedy", "Kenneth", "Kevin", "Kimberly",
"Kyle", "Landon", "Leonardo", "Leslie", "Levi", "Liam", "Logan", "Lucas", "Luis",
"Luke", "Mackenzie", "Malachi", "Manuel", "Marco", "Marcus", "Margaret", "Mario",
"Mark", "Martin", "Mason", "Matthew", "Max", "Maxwell", "Michael", "Miguel", "Morgan",
"Nathan", "Nathaniel", "Nevaeh", "Nicholas", "Nicolas", "Noah", "Nolan", "Oliver",
"Omar", "Oscar", "Owen", "Parker", "Patrick", "Paul", "Payton", "Peter", "Peyton",
"Preston", "Raymond", "Reagan", "Ricardo", "Richard", "Robert", "Ryan", "Rylee",
"Samuel", "Sean", "Sebastian", "Sergio", "Seth", "Shane", "Shawn", "Shelby",
"Spencer", "Stephen", "Steven", "Sydney", "Taylor", "Thomas", "Timothy", "Travis",
"Trenton", "Trevor", "Tristan", "Tyler", "Victor", "Vincent", "Wesley", "William",
"Wyatt", "Xavier", "Zachary"],
"name-last": ["Smith", "Johnson", "Williams", "Brown", "Jones", "Miller", "Davis", "Garcia", "Rodriguez",
"Wilson", "Martinez", "Anderson", "Taylor", "Thomas", "Hernandez", "Moore", "Martin",
"Jackson", "Thompson", "White", "Lopez", "Lee", "Gonzalez", "Harris", "Clark", "Lewis",
"Robinson", "Walker", "Perez", "Hall", "Young", "Allen", "Sanchez", "Wright", "King",
"Scott", "Green", "Baker", "Adams", "Nelson", "Hill", "Ramirez", "Campbell", "Mitchell",
"Roberts", "Carter", "Phillips", "Evans", "Turner", "Torres", "Parker", "Collins", "Edwards",
"Stewart", "Flores", "Morris", "Nguyen", "Murphy", "Rivera", "Cook", "Rogers", "Morgan",
"Peterson", "Cooper", "Reed", "Bailey", "Bell", "Gomez", "Kelly", "Howard", "Ward", "Cox",
"Diaz", "Richardson", "Wood", "Watson", "Brooks", "Bennett", "Gray", "James", "Reyes",
"Cruz", "Hughes", "Price", "Myers", "Long", "Foster", "Sanders", "Ross", "Morales",
"Powell", "Sullivan", "Russell", "Ortiz", "Jenkins", "Gutierrez", "Perry", "Butler",
"Barnes", "Fisher", "Henderson", "Coleman", "Simmons", "Patterson", "Jordan", "Reynolds",
"Hamilton", "Graham", "Kim", "Gonzales", "Alexander", "Ramos", "Wallace", "Griffin",
"West", "Cole", "Hayes", "Chavez", "Gibson", "Bryant", "Ellis", "Stevens", "Murray",
"Ford", "Marshall", "Owens", "Mcdonald", "Harrison", "Ruiz", "Kennedy", "Wells", "Alvarez",
"Woods", "Mendoza", "Castillo", "Olson", "Webb", "Washington", "Tucker", "Freeman", "Burns",
"Henry", "Vasquez", "Snyder", "Simpson", "Crawford", "Jimenez", "Porter", "Mason", "Shaw",
"Gordon", "Wagner", "Hunter", "Romero", "Hicks", "Dixon", "Hunt", "Palmer", "Robertson",
"Black", "Holmes", "Stone", "Meyer", "Boyd", "Mills", "Warren", "Fox", "Rose", "Rice",
"Moreno", "Schmidt", "Patel", "Ferguson", "Nichols", "Herrera", "Medina", "Ryan",
"Fernandez", "Weaver", "Daniels", "Stephens", "Gardner", "Payne", "Kelley", "Dunn",
"Pierce", "Arnold", "Tran", "Spencer", "Peters", "Hawkins", "Grant", "Hansen", "Castro",
"Hoffman", "Hart", "Elliott", "Cunningham", "Knight", "Bradley"]
}

+ 7
- 0
src/lib.rs View File

@ -0,0 +1,7 @@
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}

Loading…
Cancel
Save