├── .gitattributes ├── LICENSE ├── README.md └── insult_generator.py /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Zack Freedman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Voidstar Stupid Text Generator(s) 2 | *Your infinite supply of procedural stupidity!* 3 | 4 | These* are idiotic, yet worthless algorithms to generate semi-random text. They're useful for... nothing really, but I use them in various projects like the Somatic and Christopher the Robot Quagsire. They're written in Python, but should be trivial to port. The whole may be more offensive than its parts, so don't use this in live demos! 5 | 6 | **insult_generator.py**: Produces *ad hominem* attacks of the form `adjective [...more adjectives] noun [maybe another noun]`, such as 'hairy fart-filled creep weasel' and 'corncob-tugging egg-shaped sleazy son-of-a-boomer.' 7 | 8 | ## How to use: 9 | 1) Ruminate on the poor decisions that led you here 10 | 2) Add the thing to your thing 11 | 3) Import it: `from insult_generator import hit_me` 12 | 4) Run it: `yo_mama = hit_me()` and add optional params `maximum_words`, `odds_of_adding_another_word`, and/or `exclusions`... *if you dare* 13 | 14 | Parameters: 15 | * `maximum_words`: The maximum number of tokens to select. They're not really words per se, since some tokens like `future divorcee` are phrases. Anything less than 1 means you're dumb. Default: 3 16 | * `exclusions`: Tokens that should be rerolled. **One string, not a collection!** For instance, `yo_mama = hit_me(exclusions="mama's boy Bionicle moist")` because yo mama is not cool enough to be a Bionicle, probably not male enough to be a boy, and certainly not moist in my experience, hey-o! Default: Nothing 17 | * `odds_of_adding_another_word`: Probability from 0.0 to 1.0 of adding an additional word - affects variance, basically. A value of 1.0 means every output is `maximum_words` long. A value of 0.75 means there's a 75% chance of getting more than one word, a 75% * 75% = 56% chance of getting more than two words, etc. A value of 0.0 means you're super duper dumb. *Generation always stops when `maximum_words` have been produced!* Default: 0.5 18 | 19 | 20 | \*I'll add more later, I promise! -------------------------------------------------------------------------------- /insult_generator.py: -------------------------------------------------------------------------------- 1 | import math 2 | import random 3 | import time 4 | 5 | insultingAdjectives = [ 6 | "sweaty", 7 | "big", 8 | "fat", 9 | "dumb", 10 | "stupid", 11 | "goddamn", 12 | "moist", 13 | "mega-", 14 | "turbo-", 15 | "hyper-", 16 | "idiotic", 17 | "worthless", 18 | "flesh-covered", 19 | "uptight", 20 | "poop flinging", 21 | "diseased", 22 | "hairy", 23 | "miserable", 24 | "lonely", 25 | "sad", 26 | "brain-damaged", 27 | "stupendous", 28 | "terminally-online", 29 | "millennial", 30 | "broke-ass", 31 | "braindead", 32 | "fetal alcohol", 33 | "underdeveloped", 34 | "talentless", 35 | "ignorant", 36 | "son-of-a-", 37 | "store-brand", 38 | "irrelevant", 39 | "giant", 40 | "deformed", 41 | "wannabe", 42 | "obsolete", 43 | "old", 44 | "infantile", 45 | "unfunny", 46 | "greasy", 47 | "degenerate", 48 | "lazy", 49 | "slovenly", 50 | "buck-toothed", 51 | "pathetic", 52 | "reptilian", 53 | "absolute", 54 | "feeble-minded", 55 | "effeminate", 56 | "lumpy", 57 | "low-IQ", 58 | "sticky", 59 | "cringey", 60 | "stinky", 61 | "phallic", 62 | "second-class", 63 | "corporate", 64 | "anime-watching", 65 | "wrinkly", 66 | "fugly", 67 | "disposable", 68 | "v-tuber simping", 69 | "desperate", 70 | "sleazy", 71 | "lowly", 72 | ] 73 | 74 | adjectivesThatTurnNounsIntoAdjectives = [ 75 | "-obsessed", 76 | "-infested", 77 | "-ass", 78 | "-like", 79 | "-esque", 80 | "-face", 81 | "-bag", 82 | "-sack", 83 | "-shaped", 84 | "-head", 85 | "-smelling", 86 | "-covered", 87 | "-filled", 88 | "-looking-ass", 89 | "less", 90 | "-tuber", 91 | ] 92 | 93 | insultingNouns = [ 94 | "egg", 95 | "glue", 96 | "fart", 97 | "diarrhea", 98 | "hair", 99 | "poop", 100 | "doo-doo", 101 | "mother", 102 | "daddy", 103 | "granny", 104 | "pizza", 105 | "baby", 106 | "sewer", 107 | "keeb", 108 | "crotch", 109 | "frog", 110 | "bong", 111 | "3D-printer", 112 | "puppy", 113 | "Funko Pop", 114 | "diaper", 115 | "moustache", 116 | "octopus", 117 | "kitten", 118 | "banana", 119 | "Quagsire", 120 | "pony", 121 | "garbage", 122 | "finger", 123 | "watermelon", 124 | "Bionicle", 125 | "RGB-LED", 126 | "robot", 127 | "sausage", 128 | "uncle", 129 | "goop", 130 | "hobo", 131 | "cigar", 132 | "vape", 133 | "cat", 134 | "spoon", 135 | "nugget", 136 | "taint", 137 | "beer", 138 | "hamster", 139 | ] 140 | 141 | nouns_for_you = [ 142 | "meat sack", 143 | "millennial", 144 | "loser", 145 | "peasant", 146 | "oxygen thief", 147 | "waste of space", 148 | "dork", 149 | "nerd", 150 | "dweeb", 151 | "ignoramus", 152 | "knucklehead", 153 | "moron", 154 | "hack", 155 | "psychopath", 156 | "mama's boy", 157 | "virgin", 158 | "disappointment", 159 | "wimp", 160 | "so-and-so", 161 | "degenerate", 162 | "charlatan", 163 | "hack", 164 | "drain on society", 165 | "parasite", 166 | "stain", 167 | "weeaboo", 168 | "creep", 169 | "redneck", 170 | "phony", 171 | "future divorcee", 172 | "sellout", 173 | "noob", 174 | ] 175 | 176 | versatile_nouns = [ 177 | "worm", 178 | "douche", 179 | "monkey", 180 | "orangutan", 181 | "wildebeest", 182 | "boomer", 183 | "dog", 184 | "bitch", 185 | "turd", 186 | "booger", 187 | "goblin", 188 | "ass", 189 | "penis", 190 | "hoo-ha", 191 | "sphinchter", 192 | "rodent", 193 | "reptile", 194 | "dipstick", 195 | "neanderthal", 196 | "wiener", 197 | "dingus", 198 | "scum", 199 | "snake", 200 | "weasel", 201 | "donkey", 202 | "bum", 203 | "butt", 204 | "pimple", 205 | "pustule", 206 | "boob", 207 | "amogus", 208 | "corncob", 209 | "nut", 210 | "nozzle", 211 | "redacted", 212 | "donut", 213 | ] 214 | 215 | insultingVerbs = [ 216 | "suck", 217 | "lick", 218 | "kick", 219 | "punch", 220 | "cuddl", 221 | "slapp", 222 | "fapp", 223 | "tugg", 224 | "blast", 225 | "snort", 226 | "defil", 227 | "snuggl", 228 | "hump", 229 | "eat", 230 | "lov", 231 | "sniff", 232 | "touch", 233 | "look", 234 | "slurp", 235 | "ogl", 236 | "fondl", 237 | "huff", 238 | "chew", 239 | "spew", 240 | "punt", 241 | "tast", 242 | "grabb", 243 | "strok", 244 | "pucker", 245 | "smooch", 246 | "disappoint", 247 | "hat", 248 | "hoard", 249 | "guzzl", 250 | "pinch", 251 | ] 252 | 253 | 254 | def pick_candidate(words, exclusions): 255 | if random.random() < 0.02: 256 | # print('hee hee I broke the rules') 257 | return random.choice(words) 258 | 259 | candidates = [word for word in words if word not in exclusions] 260 | 261 | if len(candidates) == 0: 262 | print('Ran out of words! Reusing one.') 263 | return random.choice(words) 264 | 265 | return random.choice(candidates) 266 | 267 | 268 | def gimme_a_verb(exclusions=""): 269 | return pick_candidate(insultingVerbs, exclusions) 270 | 271 | 272 | def noun_yourself(compound_words_allowed=False, exclusions=""): 273 | dice_roll = random.random() 274 | 275 | if not compound_words_allowed or dice_roll < 0.8: 276 | return pick_candidate(nouns_for_you + versatile_nouns, exclusions) 277 | 278 | elif dice_roll < 0.9: 279 | first_noun = pick_candidate(insultingNouns + versatile_nouns, exclusions) 280 | second_noun = pick_candidate(insultingNouns + versatile_nouns, exclusions + first_noun) 281 | 282 | return f'{first_noun} ' f'{second_noun}' 283 | 284 | else: 285 | noun = noun_something_else(exclusions) 286 | verb = gimme_a_verb(exclusions + noun) 287 | return f'{noun}-{verb}er' 288 | 289 | 290 | def noun_something_else(exclusions=""): 291 | return pick_candidate(insultingNouns + versatile_nouns, exclusions) 292 | 293 | 294 | def get_an_adjective(next_word_is_a_noun, exclusions=""): 295 | if random.random() < 0.75: 296 | if next_word_is_a_noun: 297 | return pick_candidate([word for word in insultingAdjectives if word[-1] != '-'], exclusions) 298 | else: 299 | return pick_candidate(insultingAdjectives, exclusions) 300 | 301 | else: 302 | noun = noun_something_else(exclusions) 303 | 304 | dice_roll = random.randint(0, len(insultingVerbs) + len(adjectivesThatTurnNounsIntoAdjectives)) 305 | 306 | if dice_roll < len(insultingVerbs): 307 | verb = pick_candidate(insultingVerbs, exclusions) 308 | return f'{noun}-{verb}ing' 309 | 310 | else: 311 | adjective = pick_candidate(adjectivesThatTurnNounsIntoAdjectives, exclusions) 312 | return noun + adjective 313 | 314 | 315 | def hit_me(maximum_words=math.inf, exclusions="", odds_of_adding_another_word=0.5): 316 | output = '' 317 | word_count = 1 # Includes the noun 318 | 319 | dice_roll = random.random() 320 | 321 | while word_count < maximum_words and dice_roll < odds_of_adding_another_word: 322 | dice_roll = random.random() 323 | 324 | output += get_an_adjective(dice_roll < odds_of_adding_another_word, exclusions=(output + exclusions)) 325 | if output[-1] != '-': 326 | output += ' ' 327 | 328 | word_count += 1 329 | 330 | hyphenated = len(output) > 0 and output[-1] == '-' 331 | output += noun_yourself(compound_words_allowed=(not hyphenated), exclusions=(output + exclusions)) 332 | 333 | return output 334 | 335 | 336 | if __name__ == '__main__': 337 | last_insult = '' 338 | 339 | while True: 340 | last_insult = hit_me(3, exclusions=last_insult, odds_of_adding_another_word=0.75) 341 | print(last_insult) 342 | time.sleep(0.5) 343 | --------------------------------------------------------------------------------