static InformationExtraction() { TERMS_CLASSIFICATION = new Dictionary <WeaponType, string[]>(); TERMS_CLASSIFICATION.Add(WeaponType.Dagger, new string[] { "dagger", "Dagger", "knives", "Knives", "knife", "Knife" }); TERMS_CLASSIFICATION.Add(WeaponType.Sword, new string[] { "sword", "Sword", "cut", "cutting" }); TERMS_CLASSIFICATION.Add(WeaponType.Axe, new string[] { "axe", "Axe", "ax", "Ax" }); TERMS_CLASSIFICATION.Add(WeaponType.PoleWeapon, new string[] { "pole", "Pole", "staff", "Staff", "spear", "Spear" }); TERMS_CLASSIFICATION.Add(WeaponType.Bow, new string[] { "bow", "Bow" }); TERMS_CLASSIFICATION.Add(WeaponType.Ranged, new string[] { "throw", "Throw", "projectile", "Projectile", "dart", "Dart", "missile", "Missile", "javelin", "Javelin", "throwing", "Throwing" }); TERMS_CLASSIFICATION.Add(WeaponType.Club, new string[] { "club", "Club", "blunt", "Blunt", "flail", "Flail", "chain", "Chain" }); TERMS_CLASSIFICATION.Add(WeaponType.Siege, new string[] { "siege", "Siege", "artillery", "Artillery" }); TERMS_CLASSIFICATION_ALL = TERMS_CLASSIFICATION.SelectMany(kvp => kvp.Value).ToArray(); // Unlike weapon classification, where we defined the terms we were looking for from beforehand, we cannot manually define the terms needed to represent Attack and Defense. // Our chosen solution picks a few root words and searches for similar words. string[] attackRoots = { "powerful", "vicious" }; string[] defenseRoots = { "sturdy", "defensive", "protective", "fortified" }; // For each root word, we scan through the linked words that are presented by WordNet and add them to a list, leaving out words that are marked as Antonyms, or opposites. We then check out root words and keep adding the results to the list. WordNetEngine wordnet = new WordNetEngine(WeaponGeneratorConstants.FOLDER_WORDNET, true); Func <string[], List <string> > scanAndAdd = roots => { List <string> terms = new List <string>(); terms.AddRange(roots); // go 3 levels for (int i = 3; i > 0; --i) { List <string> newRoots = new List <string>(); foreach (string root in roots) { Set <SynSet> synonims = wordnet.GetSynSets(root, WordNetEngine.POS.Adjective, WordNetEngine.POS.Adverb, WordNetEngine.POS.Noun); foreach (SynSet synonim in synonims) { if (synonim.LexicalRelations.Any(r => r == WordNetEngine.SynSetRelation.Antonym)) { continue; } Debug.Assert(synonim.SemanticRelations.All(r => r != WordNetEngine.SynSetRelation.Antonym)); newRoots.AddRange(synonim.Words.Where(w => !terms.Contains(w))); terms.AddRange(synonim.Words); } } roots = newRoots.ToArray(); } return(terms.Distinct().ToList()); }; TERMS_ATTACK = scanAndAdd(attackRoots); TERMS_DEFENSE = scanAndAdd(defenseRoots); wordnet.Close(); GC.Collect(); }