Thou art a wretched swag-bellied pignut!

By: Nick Hodges

Abstract: With just a little Delphi code, you can soon be spewing insults worthy of the Bard himself.

Thou art a wretched swag-bellied pignut!

Only a few heretics would argue that William Shakespeare's work is not amongst finest use of the English language in its illustrious history. Few could turn a phrase like he did, and no one has had more influence over it. The Bard could create a beautiful image in the mind with just a brief simile. It's too bad he never really turned his attention away from comedy, tragedy and sonnets to the fine art of insults. Now there is an excellent use of the language. Insults are powerful and, when done well, quite a thing of beauty. Even though Shakespeare didn't leave behind a large body of insults, we are not at a total loss. As always, technology comes to the rescue. By culling Shakespeare's body of work and combining the results with a little Delphi code and a dash of irreverence, you, too, can spin insults that are worthy of Shakespeare himself -- not to mention that it is an excellent way to get back at the guy in the next cubicle who never returns your stapler. Some of the resulting insults will even send your victim scurrying to the dictionary. Only the highest quality can make this happen.

Well, to be honest, I don't know where the list of words included in the accompanying code originally came from or who compiled them. I assure you I didn't pour over his works to gather them. (I don't think I've read any Shakespeare since I forced it down the throats of classrooms full of fifteen year old high school students in 1986) They were passed to me by a fellow TeamB member, but they sure look like they were all mined out of Willie's work. The accompanying code was originally written in C (yuck!), but I thought the idea so cool that I decided to make it more readable by moving it over to Object Pascal. The result is ShakesInsult.pas. (If you were the one who gathered these words together and wrote the C code, doesn't it look so much better in Object Pascal?)

unit ShakesInsult;

interface

uses SysUtils;

const
  Adjective1: array[0..100] of string =

(
    'artless', 'bawdy', 'beslubbering', 'bootless', 'churlish',
    'cockered', 'clouted', 'craven', 'currish', 'dankish',
    'dissembling', 'droning', 'errant', 'fawning', 'fobbing',
    'froward', 'frothy', 'gleeking', 'goatish', 'gorbellied',
    'impertinent', 'infectious', 'jarring', 'loggerheaded',
    'lumpish', 'mammering', 'mangled', 'mewling', 'paunchy',
    'pribbling', 'puking', 'puny', 'qualling', 'rank', 'reeky',
    'roguish', 'ruttish', 'saucy', 'spleeny', 'spongy', 'surly',
    'tottering', 'unmuzzled', 'vain', 'venomed', 'villainous',
    'warped', 'wayward', 'weedy', 'yeasty', 'vomiting', 'vulturous',
    'contemptuous', 'groping', 'miniscule', 'quivering', 'shivering',
    'trembling', 'miserable', 'licentious', 'cowering', 'sulking',
    'gloating', 'murmuring', 'audacious', 'befouling', 'insolent',
    'murky', 'pitiable', 'wretched', 'dolorous', 'lamentable',
    'inadequate', 'contemptible', 'paltry', 'measly', 'meager',
    'paltry', 'inadequate', 'insignificant', 'empty', 'inferior',
    'pathetic', 'atrocious', 'execrable', 'damnable', 'repugnant',
    'repulsive', 'revolting', 'repellent', 'offensive', 'disgusting',
    'horrid', 'horrible', 'obscene', 'beastly', 'vile', 'abominable',
    'pitiful', 'wrangled', 'whoring');

const
  Adjective2: array[0..53] of string =
(
    'base-court', 'bat-fowling', 'beef-witted', 'beetle-headed',
    'boil-brained', 'clapper-clawed','clay-brained', 'common-kissing',
    'crook-pated', 'dismal-dreaming', 'dizzy-eyed', 'doghearted',
    'dread-bolted', 'earth-vexing', 'elf-skinned', 'fat-kidneyed',
    'fen-sucked', 'flap-mouthed', 'fly-bitten', 'folly-fallen',
    'fool-born', 'full-gorged', 'guts-griping', 'half-faced',
    'hasty-witted', 'hedge-born', 'hell-hated', 'idle-headed',
    'ill-breeding', 'ill-nurtured', 'knotty-pated', 'milk-livered',
    'motley-minded', 'onion-eyed', 'plume-plucked', 'pottle-deep',
    'pox-marked', 'reeling-ripe', 'rough-hewn', 'rude-growing',
    'rump-fed', 'shard-borne', 'sheep-biting', 'spur-galled',
    'swag-bellied', 'tardy-gaited', 'tickle-brained', 'toad-spotted',
    'unchin-snouted', 'weather-bitten', 'weather-beaten',
    'mutton-eating', 'coffee-nosed', 'malodorous'
);

const
  Noun: array [0..55] of string =
(
    'apple-john', 'baggage', 'barnacle', 'bladder', 'boar-pig',
    'bugbear', 'bum-bailey', 'canker-blossom', 'clack-dish',
    'clotpole', 'coxcomb', 'codpiece', 'death-token', 'dewberry',
    'flap-dragon', 'flax-wench', 'flirt-gill', 'foot-licker',
    'fustilarian', 'giglet', 'gudgeon', 'haggard', 'harpy',
    'hedge-pig', 'horn-beast', 'hugger-mugger', 'joithead', 'lewdster',
    'lout', 'maggot-pie', 'malt-worm', 'mammet', 'measle', 'minnow',
    'miscreant', 'moldwarp', 'mumble-news', 'nut-hook',
    'pigeon-egg', 'pignut', 'puttock', 'pumpion', 'ratsbane', 'scut',
    'skainsmate', 'strumpet', 'varlet', 'vassal', 'whey-face',
    'wagtail', 'phlegm-barrel', 'numb-skull',
    'lip-infection', 'blood-clot', 'boar-tick', 'pervert'
);

const
 PrefixA: array[0..2] of string =
  ( 'Thou art a %s',
    'Thy Mother is a %s',
    'Thou %s'
  );

const
  PrefixAn: array[0..2] of string =
  ( 'Thou art an %s',
    'Thy Mother is an %s',
    'Thou %s'
  );
  
function RandomShakespeareanInsult: string;

implementation

function RandomShakespeareanInsult: string;
var
  FormatStr: string;
  Insult: string;
  FirstLetterIsVowel: Boolean;
begin
  FormatStr := '%s %s %s!';
  Insult := Format(FormatStr, [Adjective1[Random(High(Adjective1))],
    Adjective2[Random(High(Adjective2))], 
    Noun[Random(High(Noun))]]);
  FirstLetterIsVowel := Insult[1] in ['a', 'e', 'i', 'o', 'u'];

  if FirstLetterIsVowel then
  begin
    FormatStr := PrefixAn[Random(High(PrefixAn))];
  end else
  begin
    FormatStr := PrefixA[Random(High(PrefixA))];
  end;
  Result := Format(FormatStr, [Insult]);
end;

end.     
Now this isn't the most elegant code, and I am always willing to entertain suggestions for improvement, but it gets the job done, and it is fairly easy to add new items to the list, if you are so inclined. There is one function to call, RandomShakespeareanInsult, that returns a prefix, followed by two adjectives, and ending with a noun. The result is a resoundingly inspired insult that sounds as though it could have come from the Bard himself. (And for you real propeller heads, this code will produce 907,200 separate insults, so put your calculator away.)

The code is simple, really. It merely sets up a series of arrays of strings, and then randomly picks out an item from each array and pieces the whole thing together using the all-powerful Format function. The only hitch was making sure that the article agreed with the ensuing noun. (For you non-Classical Languages majors, that means it uses 'a' and 'an' when it should. Or at least it almost always does. Want to watch a fight break out at an English Department faculty meeting? Get them started about whether 'a' or 'an' belongs before an aspirated 'h'.)

If you want to add words to the list, just change the high value of the array and add your words as strings to the array declaration. The generation code doesn't need to be changed, as it checks the High values for each of the constant arrays.

One further thing to note -- if you use this code in a CGI project, you'll need to call Randomize somewhere in the application. CGI applications run once for every request, and if you don't seed the Random function, your application will always return the same insult each time it runs. (Don't ask me how many compiles it took my slow, weak brain to realize this.) Delphi's random function uses a linear congruential sequence to select random numbers, and it starts with the RandSeed value. RandSeed in itializes to 0. You can set it to another hard-coded value, and you will get the same sequence of numbers everytime. If you call Randomize, Delphi will select a RandSeed for you based on your system clock setting at the moment the call was made. This is probably not good enough for the National Security agency, but it certainly is good enough for making sure that we do not always get the same quote when we ask for one.

The above unit can also be downloaded from Code Central.

You can see the insult generator at work here, down in the lower right corner. Be sure to visit the other goofy stuff I have posted there. Maybe I should add this article to the "Geeks With Too Much Time on Their Hands" section.


Nick Hodges is the Senior Codeslinger at Xapware Technologies, Inc. He lives in Swansea, IL with his family. Nick is also a member of Borland's TeamB and has vowed never to get another haircut.

Server Response from: SC1