home *** CD-ROM | disk | FTP | other *** search
- From: lee@sq.sq.com (Liam R. E. Quin)
- Newsgroups: alt.sources,rec.games.frp
- Subject: Generating Random Names -- source included!
- Message-ID: <1990Sep7.214707.13852@sq.sq.com>
- Date: 7 Sep 90 21:47:07 GMT
-
- After I posted my ancient, horrible, gunky Rolemaster Non-Player-Character
- gnerating program (for fantasy rolepaying games), I got mail asking for
- the program it references to generate names for characters.
-
- I have several programs. I'm posting two here. The first one I wrote
- in 1983 or 1984 (I forget the exact date) at Warwick University, and Kay
- Dekker hacked it mercilessly to make it read a file.
-
- The second one I wrote a couple of weeks ago in awk in an hour or so...
-
- If I find more, I'll post them.
-
- These programs want data files, so I'll include two of those. I'll
- also post an article (to rec.games.frp only) talking a little more about
- the philosophy behind these, and about strategies for choosing names.
- Unless I forget.
- These programs both make a name out of
- A start syllable
- 0 or more middle syllable [the awk program uses 1 here I think]
- An ending syllable
-
- Here are some sample names made by the C program:
- Valayngar Jestuny Darorn Klabere Ostdy
- Ryleyn Chiesartsene Jastgethen Valcheanastar Caiam
- Tocydeas Jararyr Kolain Geyne Laracy
- Lararyr Harar Klabain Moldyddney Harlyarn
- Starluth Elazer Darzane Drassa Queranayn
- Cracy Calorn Perisant Kaern Tydor
-
- Here are some names made by the awk program:
- [Plag-art-ar] [Jar-carth-bin] [Klab-art-a] [Cal-len-ayne]
- [Kor-is-ydd] [El-quent-arne] [Jar-reth-yne] [Ob-quent-el]
- [Kor-aver-sume] [Cal-erry-an] [Vart-lin-yne] [Chies-arne-ane]
- [Win-ime-y] [Odas-zane-un] [Est-end-aryn] [Nor-mel-art]
- [Shot-cath-art] [Pas-aldy-azer] [Ob-yd-tyne] [Pan-yne-oller]
- [Wearn-arth-yn] [In-asc-gayn] [Zol-valer-varn] [Bae-y-art]
-
- Here are some names made by the C program using the "dragon-oe" list
- of syllables (see _Dragon_ No. 72, p.56):
- aldwini healfberct theodgeofu hrethwealch aldsige
- beomonfled sexwuduwiv quicwict aelfweald dryhtbrand
- erconwic beohard earcongisllid earngyd ceonhelm
- leofgyd ceonflaed hrothmon tunward ealdhathu
- cuthgifu grimfrid cenebrand healffled cwicraed
- maegengeld selefridcyn breguthryd bregubeald fordlindwiw
-
- The C ones seem the best. The awk ones retain the - so you can see how
- they're made --- this lets you work out meanings easily if each syllable
- is a real word root. A fairly simple modification would be to have the
- "meaning" for each syllable in the file listing syllables. Then you
- could generate (for example)
- Cuth-brand [Known, famous -- sword]
- Aelf-wic [Elf -- dwelling-place]
- but I'll leave this to enthusiasts.
-
- The rolemaster "npc" program uses "names -i" to generate an "infinite"
- stream of names.
-
- Have fun...
-
- Lee
-
-
- : To unbundle, sh this file
- echo x - names.c 1>&2
- sed 's/^X//' >names.c <<'@@@End of names.c'
- X#include <stdio.h>
- X#define MAXSYLLNUM 1024
- X#define GETSYLL() fscanf (dfile, "%s", linebuf);
- X#define USAGE "Usage: names [-f file] [-n number-of-names] [-i]\n"
- Xchar *progname;
- X
- X#ifndef NAMEFILE
- X# define NAMEFILE "/userpk/etc/req/lib/names/default"
- X /* default file for names */
- X#endif
- X
- Xmain(argc, argv)
- Xint argc;
- Xchar **argv;
- X
- X{
- X extern char *optarg;
- X extern int optind, getopt();
- X
- X int how_many, /* number of names to generate */
- X num_mids, /* " " middle syllables (0-2) */
- X seed = getpid (); /* for random number generator */
- X int max_start = 0, /* maximum numbers of start, middle and */
- X max_mid = 0, /* end syllables read (subject to */
- X max_end = 0; /* ceiling of MAXSYLLNUM) */
- X
- X char *name_start[MAXSYLLNUM];
- X char *name_middle[MAXSYLLNUM];
- X char *name_end[MAXSYLLNUM];
- X char linebuf[BUFSIZ];
- X
- X char *name_file = NAMEFILE;
- X FILE *dfile = NULL; /* file pointer for data file */
- X int infinity = 0; /* give an infinite number of names if set */
- X int option;
- X
- X progname = argv[0];
- X
- X /* parse args */
- X
- X while ( (option = getopt(argc, argv, "f:in:") ) != EOF) {
- X switch(option) {
- X case '?' : /* no-such-option, getopt has printed a message */
- X fprintf(stderr, "%s", USAGE);
- X exit(1);
- X case 'f': { /* -f file-of-syllables */
- X name_file = optarg;
- X break;
- X }
- X case 'n': { /* how many names to do */
- X if ( (how_many = atoi(optarg)) < 0 ) {
- X err("number of names invalid (-n %d)\n", optarg);
- X exit(2);
- X }
- X break;
- X }
- X case 'i': { /* infinite number of names */
- X infinity = 1;
- X break;
- X }
- X
- X default: {
- X fprintf(stderr, USAGE);
- X exit(2);
- X }
- X }
- X }
- X if (optind != argc) {
- X fprintf(stderr, USAGE);
- X exit(2);
- X }
- X if ((dfile = fopen (name_file, "r")) == NULL) {
- X err("cannot read database %s\n", name_file);
- X exit (2);
- X }
- X
- X /* read the data file */
- X
- X GETSYLL();
- X while (strcmp(linebuf, "%") != NULL && *linebuf) {
- X name_start[max_start] = (char *) malloc (strlen (linebuf) + 1);
- X strcpy (name_start[max_start++], linebuf);
- X if (max_start == MAXSYLLNUM) {
- X err("too many initial syllables - but continuing\n");
- X while (strcmp (linebuf, "%")) GETSYLL();
- X break;
- X } else GETSYLL();
- X }
- X
- X max_mid = 0; /* initialise medial syllables */
- X GETSYLL();
- X while (strcmp (linebuf, "%") != NULL) {
- X name_middle[max_mid] = (char *) malloc (strlen (linebuf) + 1);
- X strcpy (name_middle[max_mid++], linebuf);
- X if (max_mid == MAXSYLLNUM) {
- X err("too many medial syllables - but continuing\n");
- X while (strcmp (linebuf, "%"))
- X GETSYLL();
- X break;
- X } else GETSYLL();
- X }
- X
- X max_end = 0;
- X GETSYLL();
- X while (strcmp (linebuf, "%") != NULL) {
- X name_end[max_end] = (char *) malloc (strlen (linebuf) + 1);
- X strcpy (name_end[max_end++], linebuf);
- X if (max_end == MAXSYLLNUM) {
- X err("too many final syllables - but continuing\n");
- X while (strcmp (linebuf, "%"))
- X GETSYLL();
- X break;
- X } else GETSYLL();
- X }
- X
- X /* now print the names out */
- X
- X if (!(max_start && max_mid && max_end)) {
- X err("zero-length section in datafile\n");
- X exit (3);
- X }
- X
- X srand (seed);
- X
- X while (infinity || how_many-- > 0) {
- X printf ("%s", name_start[rand_int () % max_start]);
- X for (num_mids = (rand_int () % 3) / 2; num_mids > 0; num_mids--)
- X printf ("%s", name_middle[rand_int () % max_mid]);
- X printf ("%s\n", name_end[rand_int () % max_end]);
- X }
- X}
- X
- Xrand_int() {
- X return ((int) (rand() / 37));
- X}
- X
- Xerr(s, a1, a2, a3)
- X char *s;
- X{
- X fputs(progname, stderr);
- X fputs(": ", stderr);
- X fprintf (stderr, s, a1, a2, a3);
- X}
- @@@End of names.c
- echo x - default "(put this in $HOME/lib/names, for example)" 1>&2
- sed 's/^X//' >default <<'@@@End of default'
- XRal
- XNa
- XArd
- XVald
- XCal
- XHy
- XPan
- XChies
- XPer
- XEr
- XHob
- XHarg
- XWin
- XMar
- XQuarne
- XBa
- XEr
- XOdas
- XKa
- XMold
- XSyn
- XRo
- XJast
- XYal
- XNap
- XVard
- XAs
- XBinthe
- XZald
- XDez
- XLas
- XUld
- XNev
- XHaur
- XBar
- XDas
- XTy
- XDar
- XOst
- XTral
- XGrave
- XEth
- XFlar
- XYal
- XKlab
- XHarab
- XJar
- XNor
- XDain
- XToc
- XBay
- XHaith
- XCal
- XLar
- XNaut
- XDruc
- XBar
- XArt
- XFor
- XMart
- XYar
- XHa
- XNy
- XYar
- XVerd
- XWy
- XPlag
- XTer
- XHaur
- XVar
- XAr
- XDar
- XVal
- XMar
- XCar
- XLoc
- XWearn
- XDras
- XBel
- XHar
- XJar
- XFor
- XKil
- XOc
- XAl
- XSkal
- XNun
- XAz
- XKop
- XHoul
- XLab
- XJar
- XVast
- XClaune
- XTes
- XOb
- XNist
- XEl
- XEst
- XZol
- XBrow
- XPulg
- XStar
- XKren
- XCrac
- XScaun
- XWal
- XQuer
- XRy
- XCyn
- XRusk
- XDel
- XLab
- XMel
- XSep
- XLor
- XRos
- XJar
- XDaf
- XHal
- XKol
- XIn
- XAel
- XSald
- XKuv
- XYm
- XCa
- XKeld
- XBar
- XTarl
- XShot
- XPes
- XQuer
- XLor
- XGeld
- XAr
- XHar
- XBae
- XVad
- XPas
- XUr
- XNor
- XKir
- XVar
- XMel
- XAr
- XShy
- XI
- XRald
- XCor
- XSar
- XKor
- XRol
- XHar
- XAsh
- XDir
- XLas
- XVab
- XAld
- XPar
- XOb
- XHor
- XChy
- XJar
- XRyle
- XChar
- XHab
- XSar
- XVart
- XNist
- XObr
- XJar
- XGe
- XYas
- XPav
- XJes
- XShot
- XMar
- XHor
- XEr
- XKi
- XHar
- XCal
- XAnd
- X%
- Xgur
- Xcarn
- Xaz
- Xacy
- Xayn
- Xasc
- Xgary
- Xhen
- Xtan
- Xarny
- Xalen
- Xcarth
- Xgant
- Xrath
- Xcam
- Xart
- Xron
- Xarth
- Xarth
- Xcarad
- Xere
- Xgeth
- Xaldy
- Xyn
- Xvaler
- Xarne
- Xaller
- Xvarn
- Xar
- Xan
- Xnal
- Xtyne
- Xar
- Xart
- Xont
- Xaur
- Xaver
- Xlyn
- Xas
- Xgar
- Xcuth
- Xarry
- Xor
- Xquine
- Xastar
- Xmel
- Xaryn
- Xart
- Xwar
- Xasty
- Xzane
- Xarik
- Xayne
- Xloc
- Xoller
- Xwarty
- Xaryne
- Xchean
- Xquin
- Xtar
- Xdar
- Xreth
- Xant
- Xan
- Xyne
- Xax
- Xtuny
- Xwat
- Xjuin
- Xa
- Xgayn
- Xon
- Xan
- Xcar
- Xgine
- Xcodd
- Xquent
- Xeas
- Xew
- Xazer
- Xam
- Xly
- Xstead
- Xorn
- Xar
- Xcath
- Xiera
- Xque
- Xair
- Xla
- Xart
- Xerry
- Xend
- Xom
- Xast
- Xet
- Xarty
- Xdoth
- Xcath
- Xert
- Xdy
- Xorn
- Xont
- Xtak
- Xar
- Xart
- Xwarne
- Xarn
- Xin
- Xian
- Xel
- Xak
- Xil
- Xydd
- Xime
- Xyn
- Xen
- Xin
- Xim
- Xel
- Xar
- Xro
- Xis
- Xis
- Xro
- Xera
- Xene
- Xin
- Xane
- Xiam
- Xain
- Xir
- Xun
- Xil
- Xbin
- Xlin
- Xis
- Xsene
- Xbin
- Xlir
- Xame
- Xa
- Xfyn
- Xy
- Xin
- Xyd
- Xien
- Xain
- Xyn
- Xar
- Xer
- Xin
- Xsume
- Xras
- Xid
- Xmel
- Xluth
- Xance
- Xer
- Xyn
- Xan
- Xar
- Xayne
- Xeth
- Xlen
- Xter
- Xrik
- Xer
- Xro
- Xtin
- Xmel
- Xyn
- Xris
- Xlene
- Xane
- Xas
- X%
- Xty
- Xcarn
- Xar
- Xacy
- Xer
- Xal
- Xgary
- Xy
- Xar
- Xarny
- Xalen
- Xcarth
- Xgant
- Xy
- Xber
- Xart
- Xdal
- Xarth
- Xarth
- Xan
- Xere
- Xgeth
- Xaldy
- Xyn
- Xvaler
- Xarne
- Xaller
- Xvarn
- Xayne
- Xan
- Xnal
- Xtyne
- Xayne
- Xart
- Xont
- Xney
- Xaver
- Xlyn
- Xiel
- Xgar
- Xy
- Xarry
- Xor
- Xquine
- Xastar
- Xer
- Xaryn
- Xart
- Xwar
- Xasty
- Xzane
- Xarik
- Xayne
- Xan
- Xoller
- Xwarty
- Xaryne
- Xchean
- Xta
- Xun
- Xtha
- Xreth
- Xant
- Xel
- Xyne
- Xel
- Xtuny
- Xwat
- Xjuin
- Xdor
- Xgayn
- Xtyn
- Xdar
- Xcar
- Xgine
- Xcodd
- Xquent
- Xeas
- Xew
- Xazer
- Xont
- Xly
- Xstead
- Xorn
- Xen
- Xcath
- Xiera
- Xque
- Xair
- Xla
- Xart
- Xerry
- Xsa
- Xar
- Xer
- Xern
- Xarty
- Xdoth
- Xy
- Xert
- Xdy
- Xorn
- Xont
- Xern
- Xayn
- Xart
- Xwarne
- Xarn
- Xin
- Xian
- Xel
- Xak
- Xil
- Xydd
- Xime
- Xyn
- Xen
- Xin
- Xim
- Xel
- Xar
- Xro
- Xis
- Xis
- Xro
- Xera
- Xene
- Xin
- Xane
- Xiam
- Xain
- Xir
- Xun
- Xil
- Xbin
- Xlin
- Xis
- Xsene
- Xbin
- Xlir
- Xame
- Xa
- Xfyn
- Xse
- Xin
- Xyd
- Xien
- Xain
- Xyn
- Xar
- Xer
- Xin
- Xsume
- Xras
- Xon
- Xmel
- Xluth
- Xance
- Xer
- Xyn
- Xan
- Xar
- Xayne
- Xeth
- Xnyd
- Xter
- Xrik
- Xnik
- Xro
- Xa
- Xmel
- Xyn
- Xris
- Xlene
- Xane
- Xyr
- X%
- @@@End of default
- echo x - newnames.awk 1>&2
- sed 's/^X//' >newnames.awk <<'@@@End of newnames.awk'
- X#! /usr/local/bin/nawk -f
- X
- XBEGIN {
- X srand()
- X Count[0] = 0
- X Section = 0
- X}
- X
- X/^%[ ]*$/ {
- X Section++;
- X Count[Section] = 0
- X next
- X}
- X
- X/^#.*$/ { next } # ignore comments
- X
- X/^[ ]*$/ { next } # ignore blank lines
- X
- X{
- X Syllables[Section, Count[Section] ] = $0
- X Count[Section]++
- X}
- X
- XEND {
- X for (;;) {
- X # random from first section
- X printf "[%s", Syllables[0, Rand(0, Count[0] - 1)]
- X
- X for (i = 1; i <= Section && i in Count; i++) {
- X if (Count[i]) {
- X printf "-%s", Syllables[i, Rand(0, Count[i] - 1)]
- X }
- X }
- X
- X printf "]\n"
- X }
- X}
- X
- Xfunction Rand(min, max)
- X{
- X return int((max + 1 - min) * rand()) + min
- X}
- @@@End of newnames.awk
- echo x - dragonOEnames 1>&2
- sed 's/^X//' >dragonOEnames <<'@@@End of dragonOEnames'
- Xaelf
- Xaelb
- Xaethel
- Xaedil
- Xbadu
- Xbeado
- Xbeo
- Xblith
- Xbregu
- Xceol
- Xceon
- Xcoin
- Xcene
- Xcuth
- Xcud
- Xcwic
- Xcuic
- Xquic
- Xdryct
- Xdryht
- Xead
- Xed
- Xaead
- Xeald
- Xald
- Xealh
- Xalh
- Xearcon
- Xercon
- Xearn
- Xecg
- Xec
- Xeofor
- Xeorcon
- Xeormen
- Xyrmen
- Xfolc
- Xford
- Xfri
- Xgold
- Xgrim
- Xhaem
- Xhaeth
- Xheah
- Xhealf
- Xhreth
- Xhroth
- Xhuaet
- Xhyg
- Xhugu
- Xiaru
- Xleof
- Xmaegen
- Xoidil
- Xongen
- Xos
- Xrath
- Xsaex
- Xsax
- Xsex
- Xsele
- Xtat
- Xtheod
- Xtil
- Xtorct
- Xtrum
- Xtun
- Xwaeg
- Xwig
- Xwil
- X%
- Xbald
- Xbeald
- Xbalt
- Xbalth
- Xbeorht
- Xberct
- Xberict
- Xbeorn
- Xbern
- Xbrand
- Xbroad
- Xburg
- Xburh
- Xcyni
- Xcyn
- Xdegn
- Xferth
- Xflaed
- Xfled
- Xfor
- Xfrith
- Xfrit
- Xfrid
- Xgar
- Xgeld
- Xgifu
- Xgeofu
- Xgisl
- Xgund
- Xgunn
- Xgyth
- Xgyd
- Xhaed
- Xhathu
- Xheard
- Xhard
- Xhere
- Xheri
- Xhelm
- Xhild
- Xhun
- Xlac
- Xlaf
- Xlid
- Xlind
- Xlinda
- Xmaer
- Xman
- Xmon
- Xmund
- Xnoth
- Xraed
- Xred
- Xrefu
- Xric
- Xsig
- Xsige
- Xstan
- Xswith
- Xswid
- Xtheof
- Xtheow
- Xthryth
- Xthryd
- Xwealch
- Xwalh
- Xweald
- Xwald
- Xweard
- Xward
- Xwic
- Xwict
- Xwiht
- Xwine
- Xwini
- Xwiw
- Xwiv
- Xwuda
- Xwida
- Xwudu
- Xwulf
- Xulf
- Xwyn
- Xwynn
- X%
- X%
- Xbald
- Xbeald
- Xbalt
- Xbalth
- Xbeorht
- Xberct
- Xberict
- Xbeorn
- Xbern
- Xbrand
- Xbroad
- Xburg
- Xburh
- Xcyni
- Xcyn
- Xdegn
- Xferth
- Xflaed
- Xfled
- Xfor
- Xfrith
- Xfrit
- Xfrid
- Xgar
- Xgeld
- Xgifu
- Xgeofu
- Xgisl
- Xgund
- Xgunn
- Xgyth
- Xgyd
- Xhaed
- Xhathu
- Xheard
- Xhard
- Xhere
- Xheri
- Xhelm
- Xhild
- Xhun
- Xlac
- Xlaf
- Xlid
- Xlind
- Xlinda
- Xmaer
- Xman
- Xmon
- Xmund
- Xnoth
- Xraed
- Xred
- Xrefu
- Xric
- Xsig
- Xsige
- Xstan
- Xswith
- Xswid
- Xtheof
- Xtheow
- Xthryth
- Xthryd
- Xwealch
- Xwalh
- Xweald
- Xwald
- Xweard
- Xward
- Xwic
- Xwict
- Xwiht
- Xwine
- Xwini
- Xwiw
- Xwiv
- Xwuda
- Xwida
- Xwudu
- Xwulf
- Xulf
- Xwyn
- Xwynn
- X%
- @@@dragonOEnames
- echo "Congratulations. You've unpacked the entire archive." 1>&2
- exit 0
-
-
- --
- Liam R. E. Quin, lee@sq.com, SoftQuad Inc., Toronto, +1 (416) 963-8337
-