1use rand::distributions::WeightedIndex;
2use rand::prelude::*;
3use rand::Rng;
4
5#[rustfmt::skip]
6const ADJECTIVES: &[&str] = &[
7 "Blue", "Bronze", "Brown", "Burgundy", "Driven", "Enchanted", "Gold", "Green", "Grey",
8 "Grouchy", "Hallowed", "Happy", "Hidden", "Hungry", "Jovial", "Lone", "Lost", "Lucky",
9 "Merry", "Moody", "Morose", "Orange", "Purple", "Red", "Silent", "Silver", "Thirsty",
10 "Wasted", "Wild",
11];
12
13#[rustfmt::skip]
14const LAND_ANIMALS: &[&str] = &[
15 "Antelope", "Ape", "Baboon", "Badger", "Bat", "Bear", "Beaver", "Bee", "Beetle", "Boar",
16 "Camel", "Cat", "Cow", "Deer", "Dog", "Donkey", "Dove", "Dragonfly", "Duck", "Eagle",
17 "Elephant", "Elk", "Ermine", "Fox", "Frog", "Goat", "Goose", "Hare", "Hart", "Hawk",
18 "Hedgehog", "Heron", "Herring", "Horse", "Hound", "Hyena", "Jackal", "Lamb", "Leopard",
19 "Lion", "Magpie", "Mole", "Owl", "Panther", "Peacock", "Phoenix", "Pony", "Porcupine",
20 "Rabbit", "Ram", "Rat", "Raven", "Salamander", "Scorpion", "Sheep", "Snake", "Spider",
21 "Squirrel", "Stag", "Stoat", "Stork", "Swan", "Tiger", "Toad", "Tortoise",
22 "Turkey", "Turtle", "Unicorn", "Vulture", "Weasel", "Wolf",
23];
24
25#[rustfmt::skip]
26const COASTAL_ANIMALS: &[&str] = &[
27 "Cormorant", "Crab", "Dolphin", "Herring", "Mermaid", "Octopus", "Osprey", "Otter",
28 "Pelican", "Perch", "Salmon", "Seagull", "Seal", "Shark", "Starfish", "Squid", "Whale",
29 "Whelk"
30];
31
32#[rustfmt::skip]
33const ENEMIES: &[&str] = &[
34 "Angel", "Bandit", "Brigand", "Centaur", "Chimera", "Demon", "Devil", "Dragon", "Fairy",
35 "Ghost", "Giant", "Goblin", "Gorgon", "Gremlin", "Hag", "Harpy", "Hydra", "Imp", "Kappa",
36 "Lich", "Manticore", "Minotaur", "Necromancer", "Oni", "Orc", "Peryton", "Pirate", "Roc",
37 "Satyr", "Seraph", "Siren", "Sorcerer", "Sphinx", "Thief", "Trickster", "Troll", "Unicorn",
38 "Vampire", "Werewolf", "Witch", "Wyvern", "Zombie",
39];
40
41#[rustfmt::skip]
42const FOOD: &[&str] = &[
43 "Barley", "Barrel", "Beef", "Beer", "Bread", "Cask", "Cheese", "Hop", "Keg", "Malt",
44 "Mead", "Meat", "Mutton", "Pint", "Pork", "Potatoes", "Rye", "Tun", "Veal", "Venison",
45 "Vine",
46];
47
48#[rustfmt::skip]
49const GEMS: &[&str] = &[
50 "Amber", "Agate", "Amethyst", "Aquamarine", "Beryl", "Citrine", "Diamond", "Emerald",
51 "Opal", "Quartz", "Sapphire", "Topaz"
52];
53
54#[rustfmt::skip]
55const PEOPLE: &[&str] = &[
56 "Father", "Mother", "Parent", "Sibling", "Hunter", "Emperor", "Empress", "Warrior",
57 "Sage", "Ancestor"
58];
59
60#[rustfmt::skip]
61const PROFESSIONS: &[&str] = &[
62 "Adventurer", "Baker", "Beggar", "Blacksmith", "Brewer", "Bricklayer", "Builder",
63 "Butcher", "Carpenter", "Conjurer", "Cooper", "Diviner", "Enchanter", "Evoker", "Farrier",
64 "Ferryman", "Fisherman", "Glazier", "Illusionist", "Knight", "Mage", "Magician", "Mason",
65 "Miller", "Plumber", "Porter", "Printer", "Roper", "Sailor", "Shipwright", "Smith",
66 "Soldier", "Waterman", "Warrior", "Wizard",
67];
68
69#[rustfmt::skip]
70const SYMBOLS: &[&str] = &[
71 "Abbey", "Anchor", "Anvil", "Arrow", "Axe", "Belfry", "Bell", "Book", "Buckle", "Cap",
72 "Castle", "Column", "Crescent", "Crown", "Drum", "Feather", "Foil", "Hammer", "Harp",
73 "Harrow", "Helmet", "Horseshoe", "Key", "Lance", "Lance", "Locket", "Mace", "Mill",
74 "Mitre", "Moon", "Nail", "Oar", "Phalactary", "Rake", "Rook", "Scale", "Sceptre", "Scythe",
75 "Ship", "Shovel", "Spear", "Spur", "Star", "Steeple", "Sun", "Sword", "Thunderbolt",
76 "Tower", "Trumpet", "Wand", "Wheel",
77];
78
79pub fn adjective(rng: &mut impl Rng) -> &'static str {
80 ListGenerator(ADJECTIVES).gen(rng)
81}
82
83pub fn cardinal_direction(rng: &mut impl Rng) -> &'static str {
84 ListGenerator(&["North", "South", "East", "West"]).gen(rng)
85}
86
87pub fn enemy(rng: &mut impl Rng) -> &'static str {
88 ListGenerator(ENEMIES).gen(rng)
89}
90
91pub fn food(rng: &mut impl Rng) -> &'static str {
92 ListGenerator(FOOD).gen(rng)
93}
94
95pub fn gem(rng: &mut impl Rng) -> &'static str {
96 ListGenerator(GEMS).gen(rng)
97}
98
99pub fn person(rng: &mut impl Rng) -> &'static str {
100 ListGenerator(PEOPLE).gen(rng)
101}
102
103pub fn profession(rng: &mut impl Rng) -> &'static str {
104 ListGenerator(PROFESSIONS).gen(rng)
105}
106
107pub fn symbol(rng: &mut impl Rng) -> &'static str {
108 ListGenerator(SYMBOLS).gen(rng)
109}
110
111pub fn animal(rng: &mut impl Rng) -> &'static str {
112 let dist = WeightedIndex::new([LAND_ANIMALS.len(), COASTAL_ANIMALS.len()]).unwrap();
113 match dist.sample(rng) {
114 0 => land_animal(rng),
115 1 => coastal_animal(rng),
116 _ => unreachable!(),
117 }
118}
119
120pub fn land_animal(rng: &mut impl Rng) -> &'static str {
121 ListGenerator(LAND_ANIMALS).gen(rng)
122}
123
124pub fn coastal_animal(rng: &mut impl Rng) -> &'static str {
125 ListGenerator(COASTAL_ANIMALS).gen(rng)
126}
127
128pub struct ListGenerator(pub &'static [&'static str]);
129
130impl ListGenerator {
131 pub fn gen(&self, rng: &mut impl Rng) -> &'static str {
132 self.0[rng.gen_range(0..self.0.len())]
133 }
134}