LPMuds.net
February 09, 2010, 02:40:04 PM *
Welcome, Guest. Please login or register.

Login with username, password and session length
News: This is the forum page. For the main LPMuds page, visit http://lpmuds.net
 
   Home   SITE FAQ INTERMUD DOWNLOADS LINKS Help Search Login Register  
Pages: [1]   Go Down
  Print  
Author Topic: Name generator  (Read 2341 times)
Tricky
BFF
***
Offline Offline

Posts: 168


I like what I code and I code what I like!


View Profile
« on: September 23, 2008, 10:28:14 PM »

The other day I decided to code a sefun that created a name that could be pronounced more easily by my self. This is the result.

To use, place the file in the sefun directory and #include it in /secure/sefun/sefun.c (DS lib), update /secure/sefun/sefun. Now it is ready to use.

generate_name(pair, num, ind);

The parameters are all optional.

 * pair - Which of the letter-pair sets to use. (0 - 4)
 * num - Which of the 8 sets of generated names to use. (1 - 8)
 * ind - Which name to use. (0 - 255)

The function returns a capitalized name.

Code:
/* /secure/sefun/names.c
 *
 * A general purpose name generator based on digraphs/letter-pairs.
 *
 * The original concept comes from the space trading game Elite.
 * Ian Bell (one of the original coders of Elite) converted the 6502
 * assembly source code into a C version (minus graphics).
 *
 * This is an LPC conversion that just uses the name generation code.
 *
 * The original source can be found here...
 *   http://www.iancgbell.clara.net/elite/text/index.htm
 *
 * --------------------------------------------------------------------
 * Unless I specify in file headers, all my stuff I release will be
 * Public Domain. Do as you want with it or not. The choice is yours.
 *
 * If I want to be paid for code, then I will pimp myself to a company.
 *
 * Tricky
 */

#define RTH_MAX_NAMES 256

private static string *rth_pairs_arr = ({
/* Planets from the original Elite */
  "..lexegezacebiso" +
  "usesarmaindirea." +
  "eratenberalaveti" +
  "edorquanteisrion",
/* Lorem ipsum */
  "..qupeaudidoliut" +
  "viadaedupasotoa." +
  "loaregelpufridhe" +
  "geimmeneninopier",
/* War and Peace */
  "..hethineranrena" +
  "ouonedneathatoa." +
  "isenitasteesaror" +
  "lenistverineseli",
/* Front page of Boing Boing (including HTML) */
  "..indiennatehaiv" +
  "bonereanasthoia." +
  "celaeterpariryte" +
  "atlehesetaarcoes",
/* The Little Prince (Chapters 1-5, English version) */
  "..thheanerinhaat" +
  "reouisittoonvea." +
  "histedleennamees" +
  "nenoofearoseorar",
});

private static string rth_pairs;

private static mapping rth_seed = ([
  "w0": 0,
  "w1": 0,
  "w2": 0,
]);

private static int rth_rotatel(int x)
{
    x = (x & 255) * 2;
    if(x > 255) x -= 255;
    return x;
}

private static int rth_twist(int x)
{
    return (rth_rotatel(x >> 8) << 8) + rth_rotatel(x & 255);
}

private static void rth_next()
{
    rth_seed["w0"] = rth_twist(rth_seed["w0"]);
    rth_seed["w1"] = rth_twist(rth_seed["w1"]);
    rth_seed["w2"] = rth_twist(rth_seed["w2"]);
}

private static void rth_tweakseed()
{
    int tmp;

    tmp = rth_seed["w0"] + rth_seed["w1"] + rth_seed["w2"];
    tmp &= 65535;

    rth_seed["w0"] = rth_seed["w1"];
    rth_seed["w1"] = rth_seed["w2"];
    rth_seed["w2"] = tmp;
}

private static string rth_makename()
{
    string name;
    int pair1, pair2, pair3, pair4;
    int longname = rth_seed["w0"] & 64;

    /* Always 4 iterations of random number */
    pair1 = 2 * ((rth_seed["w2"] >> 8) & 31); rth_tweakseed();
    pair2 = 2 * ((rth_seed["w2"] >> 8) & 31); rth_tweakseed();
    pair3 = 2 * ((rth_seed["w2"] >> 8) & 31); rth_tweakseed();
    pair4 = 2 * ((rth_seed["w2"] >> 8) & 31); rth_tweakseed();

    name  = sprintf("%c", rth_pairs[pair1]);
    name += sprintf("%c", rth_pairs[pair1 + 1]);
    name += sprintf("%c", rth_pairs[pair2]);
    name += sprintf("%c", rth_pairs[pair2 + 1]);
    name += sprintf("%c", rth_pairs[pair3]);
    name += sprintf("%c", rth_pairs[pair3 + 1]);

    /* bit 6 of ORIGINAL w0 flags a four-pair name */
    if (longname)
    {
        name += sprintf("%c", rth_pairs[pair4]);
        name += sprintf("%c", rth_pairs[pair4 + 1]);
    }

    /* Remove any '.' in the name and capitalize the result */
    name = capitalize(replace_string(name, ".", ""));

    return name;
}

varargs string generate_name(int pair, int num, int ind)
{
    string array names = allocate(RTH_MAX_NAMES);

    if(undefinedp(pair) || !intp(pair)) pair = random(sizeof(rth_pairs_arr));
    if(pair < 0 || pair >= sizeof(rth_pairs_arr)) pair = 0;

    rth_pairs = rth_pairs_arr[pair];

    if(undefinedp(num) || !intp(num)) num = random(8) + 1;
    if(num < 1 || num > 8) num = 1;

    rth_seed["w0"] = 0x5a4a;
    rth_seed["w1"] = 0x0248;
    rth_seed["w2"] = 0xb753;

    for (int i = 1 ; i < num ; ++i) rth_next();

    for (int i = 0 ; i < RTH_MAX_NAMES ; ++i)
        names[i] = rth_makename();

    if (undefinedp(ind) || !intp(ind)) ind = random(RTH_MAX_NAMES);
    if (ind < 0 || ind >= RTH_MAX_NAMES) ind = 0;

    return names[ind];
}

Tricky
Logged

quixadhal
BFF
***
Offline Offline

Posts: 205



View Profile
« Reply #1 on: September 24, 2008, 06:10:09 PM »

Wow, it's pretty cool that I saw the name iancgbell in the URL before I looked upwards to see the comments, and said "Hey, that's the guy who did Elite!"

While I don't know if he ever plans to do the long-idle Elite 4, the spiritual successor of Elite is about to release their next game, X3: Terran Conflict.

Elite was phenomenal becuase almost all the content was procedurally generated, making it possible to have a huge galaxy with 3D dogfights on the Commodore 64.  Spore is the first commercial game to go down that route in a long time, and I hope to see more.

Good job remembering/finding this, and then doing the work to port it over! Smiley
Logged

Tricky
BFF
***
Offline Offline

Posts: 168


I like what I code and I code what I like!


View Profile
« Reply #2 on: September 24, 2008, 11:26:00 PM »

 Grin NP

In some interviews I've read they could have had over 2 billion galaxies generated on the fly. However, the games company reeled them back into the real world and they cut it down to the 8 we know about.

As for Elite 4, current rumour is that work will begin on it once X3 is launched and selling well for XMas. (Heard it all before Roll Eyes )

Tricky
Logged

chaos
BFF
***
Offline Offline

Posts: 212


Job, school, social life, sleep. Pick 2.5.


View Profile WWW
« Reply #3 on: September 25, 2008, 10:36:59 PM »

LDMud port:

Code:
/* /secure/sefun/names.c
 *
 * A general purpose name generator based on digraphs/letter-pairs.
 *
 * The original concept comes from the space trading game Elite.
 * Ian Bell (one of the original coders of Elite) converted the 6502
 * assembly source code into a C version (minus graphics).
 *
 * This is an LPC conversion that just uses the name generation code.
 *
 * The original source can be found here...
 *   http://www.iancgbell.clara.net/elite/text/index.htm
 *
 * --------------------------------------------------------------------
 * Unless I specify in file headers, all my stuff I release will be
 * Public Domain. Do as you want with it or not. The choice is yours.
 *
 * If I want to be paid for code, then I will pimp myself to a company.
 *
 * Tricky
 */

// Ported to LDMud by Chaos of Lost Souls.  Changes are also public
// domain.

#define RTH_MAX_NAMES 256

private static string *rth_pairs_arr = ({
/* Planets from the original Elite */
  "..lexegezacebiso" +
  "usesarmaindirea." +
  "eratenberalaveti" +
  "edorquanteisrion",
/* Lorem ipsum */
  "..qupeaudidoliut" +
  "viadaedupasotoa." +
  "loaregelpufridhe" +
  "geimmeneninopier",
/* War and Peace */
  "..hethineranrena" +
  "ouonedneathatoa." +
  "isenitasteesaror" +
  "lenistverineseli",
/* Front page of Boing Boing (including HTML) */
  "..indiennatehaiv" +
  "bonereanasthoia." +
  "celaeterpariryte" +
  "atlehesetaarcoes",
/* The Little Prince (Chapters 1-5, English version) */
  "..thheanerinhaat" +
  "reouisittoonvea." +
  "histedleennamees" +
  "nenoofearoseorar",
});

private static string rth_pairs;

private static mapping rth_seed;

void create() {
    rth_seed = ([
        "w0"    : 0,
        "w1"    : 0,
        "w2"    : 0,
    ]);
}

private static int rth_rotatel(int x) {
    x = (x & 255) * 2;
    if(x > 255) x -= 255;
    return x;
}

private static int rth_twist(int x) {
    return (rth_rotatel(x >> 8) << 8) + rth_rotatel(x & 255);
}

private static void rth_next() {
    rth_seed["w0"] = rth_twist(rth_seed["w0"]);
    rth_seed["w1"] = rth_twist(rth_seed["w1"]);
    rth_seed["w2"] = rth_twist(rth_seed["w2"]);
}

private static void rth_tweakseed() {
    int tmp = rth_seed["w0"] + rth_seed["w1"] + rth_seed["w2"];
    tmp &= 65535;
    rth_seed["w0"] = rth_seed["w1"];
    rth_seed["w1"] = rth_seed["w2"];
    rth_seed["w2"] = tmp;
}

private static string rth_makename() {
    string name;
    int pair1, pair2, pair3, pair4;
    int longname = rth_seed["w0"] & 64;
    /* Always 4 iterations of random number */
    pair1 = 2 * ((rth_seed["w2"] >> 8) & 31); rth_tweakseed();
    pair2 = 2 * ((rth_seed["w2"] >> 8) & 31); rth_tweakseed();
    pair3 = 2 * ((rth_seed["w2"] >> 8) & 31); rth_tweakseed();
    pair4 = 2 * ((rth_seed["w2"] >> 8) & 31); rth_tweakseed();
    name  = sprintf("%c", rth_pairs[pair1]);
    name += sprintf("%c", rth_pairs[pair1 + 1]);
    name += sprintf("%c", rth_pairs[pair2]);
    name += sprintf("%c", rth_pairs[pair2 + 1]);
    name += sprintf("%c", rth_pairs[pair3]);
    name += sprintf("%c", rth_pairs[pair3 + 1]);
    /* bit 6 of ORIGINAL w0 flags a four-pair name */
    if(longname) {
        name += sprintf("%c", rth_pairs[pair4]);
        name += sprintf("%c", rth_pairs[pair4 + 1]);
    }
    /* Remove any '.' in the name and capitalize the result */
    name = capitalize(replace(name, ".", ""));
    return name;
}

varargs string generate_name(varargs int array args) {
    int pair = sizeof(args) >= 1 && args[0];
    int num = sizeof(args) >= 2 && args[1];
    int ind = sizeof(args) >= 3 && args[2];
    string array names = allocate(RTH_MAX_NAMES);
    if(!sizeof(args) || !intp(pair))
        pair = random(sizeof(rth_pairs_arr));
    if(pair < 0 || pair >= sizeof(rth_pairs_arr)) pair = 0;
    rth_pairs = rth_pairs_arr[pair];
    if(sizeof(args) < 2 || !intp(num))
        num = random(8) + 1;
    if(num < 1 || num > 8) num = 1;
    rth_seed["w0"] = 0x5a4a;
    rth_seed["w1"] = 0x0248;
    rth_seed["w2"] = 0xb753;
    for(int i = 1 ; i < num ; ++i)
        rth_next();
    for(int i = 0 ; i < RTH_MAX_NAMES ; ++i)
        names[i] = rth_makename();
    if(sizeof(args) < 3 || !intp(ind))
        ind = random(RTH_MAX_NAMES);
    if(ind < 0 || ind >= RTH_MAX_NAMES)
        ind = 0;
    return names[ind];
}
Logged

Xzystance
Acquaintance
*
Offline Offline

Posts: 29


View Profile
« Reply #4 on: September 26, 2008, 01:15:47 AM »

so um, i've included it, and updated it....... now how do i use it? :-P

X
Logged
chaos
BFF
***
Offline Offline

Posts: 212


Job, school, social life, sleep. Pick 2.5.


View Profile WWW
« Reply #5 on: September 26, 2008, 01:18:23 AM »

You call generate_name() in it.
Logged

Xzystance
Acquaintance
*
Offline Offline

Posts: 29


View Profile
« Reply #6 on: September 26, 2008, 02:14:09 AM »

Ok, i'm feelin kinda noobish, could you give an example of usage? :-P
Logged
Tricky
BFF
***
Offline Offline

Posts: 168


I like what I code and I code what I like!


View Profile
« Reply #7 on: September 26, 2008, 02:44:27 AM »

Ok, i'm feelin kinda noobish, could you give an example of usage? :-P

I currently use it in the file /secure/obj/robot.c

Instead of...

Code:
    if(!name) name = alpha_crypt(random(10)+2);

I have...

Code:
    if(!name) name = generate_name(2);

This gives me a random name from the whole of the War and Peace set. (8 banks of 256 names)

The following will show a set of names familiar to all the oldbies here...

Code:
write(generate_name(0, 1, 7) + "\n");
write(generate_name(0, 1, 129) + "\n");
write(generate_name(0, 1, 147) + "\n");

The 1st arg is the pair set to use, 0 is Elite names, 1 is Lorem ipsum (made up Latin script), 2 is War and Peace, 3 is Boing Boing front page, 4 is The Little Prince (Chapters 1-5, English version).

The 2nd arg is the name space to use, in the range of 1 to 8.

The 3rd arg is a specific name (0 to 255).

All the arguments are optional so you can call it like this, generate_name(), which would return a random name from a random name space from a random pair set. generate_name(0, 1) would return a random name from the 1st galaxy of the Elite space trading game.

I hope that gave some clue as to how to call it.

Tricky
Logged

Xzystance
Acquaintance
*
Offline Offline

Posts: 29


View Profile
« Reply #8 on: September 26, 2008, 03:00:19 AM »

Yeah, thanks Smiley
Logged
daelaskai
BFF
***
Offline Offline

Posts: 164


View Profile
« Reply #9 on: September 27, 2008, 06:39:03 AM »

I like the name generator.  Anyone know how to add your own custom name possibilities?
For instance, I'd like to use the name generator to make a bunch of Elven, Dwarven or
Draconic names.  How does someone create the:

Code:
  "..hethineranrena" +
  "ouonedneathatoa." +
  "isenitasteesaror" +
  "lenistverineseli",

The names need to make sense for what it is being used for.  Any suggestions?

Daelas
Logged
chaos
BFF
***
Offline Offline

Posts: 212


Job, school, social life, sleep. Pick 2.5.


View Profile WWW
« Reply #10 on: September 27, 2008, 06:54:17 AM »

It's a lot easier to get 'elfy', 'dwarfy' etc. style names, and see what you're doing, with a simple system where you have a list of 1st, 2nd, and 3rd name 'chunks', and randomly pick one from each column.  The Elite generator is neat, but it's not really the best system for an LPmud, largely because much of what it's doing is to work around constraints that C has and LPC doesn't.
Logged

shadyman
Friend
**
Offline Offline

Posts: 50


View Profile
« Reply #11 on: November 24, 2008, 07:16:32 PM »

Woo! That's hot. Thanks for sharing!
Logged
wick
Acquaintance
*
Offline Offline

Posts: 1


View Profile
« Reply #12 on: August 13, 2009, 07:18:36 AM »

This is custom lib so it may not work with any of yours, but this is a neat toy I've used
Code:
#include <defines.h>

#define VOW ({\
  "e", "e", "e", "e", "e", "a", "a", "a", "a", "i", "i", "i", "o", "o", "u", \
  "e", "e", "e", "e", "e", "a", "a", "a", "a", "i", "i", "i", "o", "o", "u", \
  "e", "e", "e", "e", "e", "a", "a", "a", "a", "i", "i", "i", "o", "o", "u", \
  "e", "e", "e", "e", "e", "a", "a", "a", "a", "i", "i", "i", "o", "o", "u", \
  "y", "ie", "aa", "oo", "ee", "ea", "ia", "io", "ou", "ou", \
})

#define SVOW ({ \
  "e", "e", "e", "e", "e", "a", "a", "a", "a", "i", "i", "i", "o", "o", "u", \
})

#define EVOW ({ \
  "e", "e", "e", "e", "e", "a", "a", "a", "a", "i", "i", "i", "y", "y", "o", \
})

#define CON ({\
  "b", "bl", "br", "c", "ch", "ck", "cl", "cr", "d", "dl", "dr", "f", "fl", \
  "fr", "g", "h", "j", "k", "kl", "kr", "l", "m", "n", "p", "pl", "pr", "ps", \
  "qu", "r", "rn", "rt", "rth", "s", "sch", "scr", "sh", "shr", "sk", "sm", \
  "sn", "sp", "spr", "st", "str", "sw", "t", "th", "tr", "ts", "v", "vr", \
  "w", "wr", "x", "z", "zl", "zr", \
})

#define SCON ({ \
  "b", "bl", "br", "c", "ch", "cl", "cr", "d", "dr", "f", "fl", "fr", "g", \
  "h", "j", "k", "kr", "l", "m", "n", "p", "pl", "pr", "qu", "r", "s", "scr", \
  "sh", "shr", "sk", "sm", "sn", "sp", "spr", "st", "str", "sw", "t", "th", \
  "tr", "v", "w", "x", "z", \
})

#define ECON ({ \
  "b", "ch", "ck", "d", "f", "g", "l", "m", "n", "ng", "p", "ps", "r", \
  "rn", "rt", "rth", "s", "sch", "sh", "st", "t", "th", "ts", "w", "z", \
})

#define RVOW VOW[random(sizeof(VOW))]
#define RSVOW SVOW[random(sizeof(SVOW))]
#define REVOW EVOW[random(sizeof(EVOW))]
#define RCON CON[random(sizeof(CON))]
#define RSCON SCON[random(sizeof(SCON))]
#define RECON ECON[random(sizeof(ECON))]

inherit COMMAND;

int main(string arg) {
  string name;
  int num;

  sscanf(arg, "%d", num);
  if (!num)
    num = 1 + random(3);
  if (num < 1)
    return notify_fail("Less than 1 syllable... aborting.\n");
  if (num > 10)
    return notify_fail("Too many syllables... aborting.\n");

  name = (random(5) ? RSCON+RVOW : RSVOW);
  if (num-- > 0) {
    while (num--) {
      name += RCON;
      name += RVOW;
    }
  }
  if (random(5))
    name += RECON;
  else
    name += RCON + REVOW;

  printf("%s\n", capitalize(name));

  return 1;
}
Logged
Pages: [1]   Go Up
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!