Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a javascript elite planet name generator? [closed]

Tags:

javascript

I try to convert Tricky's script (that generates a name from elite) to javascript here:

https://github.com/rubo77/eliteNameGen/blob/master/elite.js

But I get stuck at this LPC-code by Tricky:

digrams=ABOUSEITILETSTONLONUTHNO..LEXEGEZACEBISOUSESARMAINDIREAERATENBERALAVETIEDORQUANTEISRION
...
pairs = digrams[24..<1];
...
names[0..<2]

I couldn't find a manual to LPC that would explain this syntax.

In the End I want to create a javascript, that creates a random planet name from the old C64 game Elite.

I also found a python version, (but that seems a bit more complicated to me)

like image 952
rubo77 Avatar asked Mar 06 '26 06:03

rubo77


2 Answers

Ok I managed to port the code over, but I had to tweak a bit of the algorithm. The one that is provide by Tricky, for some reason, produces non-unique names. I used the tweakseed function to tweak the seeds to generate a list of random names.

Answer

To answer the question above, @MattBurland is correct. You would replace the following code:

pairs = digrams[24..<1];

with

pairs = digrams.substring(24);

The following code, however, is actually printing out the list of names. So you're indexing an array - in which case:

names[0..<2]

becomes

for (var i = 0; i < (names.length - 2); i++) {
  names[i]
}

Analysis

Just to give this some more depth. I've analyzed the code and realized that rotatel, twist, tweakseed, and next were just used to create random numbers. I don't know enough about LPC, but I think that at the time it probably didn't have a pseudo-random number generator.

A lot of this code can be removed and just replaced with Math.random. The key part of this entire program is the variable digram. This sequence of characters produces Alien-like names. I figure it probably has something to do with alternation of consonants and vowels. Grabbing them in pairs randomly will almost always produce some sort of consonant + vowel pairing. There is the odd time where you'll end up with a name like 'Rmrirqeg', but in most cases, the names appear Alien-like.

Port

Below is a direct port of the code. You can use this jsFiddle to see it in action, but it uses AngularJS to print out the names instead of printing out a list like the code provided. genNames will produce an array of names, which you can use for whatever reason you want.

Note this port only works on IE9+, since it uses map, reduce, and forEach. Replace these with loops if you plan on using this on IE8 or below.

You can tweak this to produce names longer or shorter. However, the length of the names is dependent on the pairs array. Either use Math.random or something to make it completely wild.

var digrams = "ABOUSEITILETSTONLONUTHNO" +
    "..LEXEGEZACEBISOUSESARMAINDIREA.ERATENBERALAVETIEDORQUANTEISRION";

function rotatel(x) {
    var tmp = (x & 255) * 2;
    if (tmp > 255) tmp -= 255;
    return tmp;
}

function twist(x) {
    return (256 * rotatel(x / 256)) + rotatel(x & 255);   
}

function next(seeds) {
    return seeds.map(function(seed) {
        return twist(seed);
    });
}

function tweakseed(seeds) {
    var tmp;

    tmp = seeds.reduce(function(total, seed) {
        return total += seed;        
    }, 0);

    return seeds.map( function ( seed, index, arr ) {
        return arr[index + 1] || (tmp & 65535)
    });
};


function makename(pairs, seeds)
{
    var name = [];
    /* Modify pair if you want to have names shorter or longer than 8 chars */
    /* I'll leave that as an exercise for you. */
    var pair = [0, 0, 0, 0];
    var longname = seeds[0] & 64;

    pair = pair.map(function() {
       seeds = tweakseed(seeds);
       return 2 * ((seeds[2] / 256) & 31);  
    });

    pair.forEach(function(value, index, arr) {
        if (longname || ( index < (arr.length - 1))) {
            name.push(pairs[value]);
            name.push(pairs[value + 1]);
        }
    });

    return name.join('').toLowerCase()
            .replace(/^\w/,  function(letter) {
                return letter.toUpperCase(); 
            });
}

function genNames()
{
    var names = [];
    var pairs;
    var num = 256;
    var seeds = [23114, 584, 46931];
    pairs = digrams.substring(24);

    while (--num) {
        names.push( makename(pairs, seeds) );
        seeds = tweakseed(next(seeds));
    }

    return names;
}
like image 69
Pete Avatar answered Mar 08 '26 20:03

Pete


For the range operator in LPC, this link helps:

http://www.unitopia.de/doc/LPC/operators.html

    expr1[expr2..expr3] Extracts a
                    piece from an array or string.
                    expr2 or expr3 may be omitted, default is the begin
                    or end of expr1.
                    Negative numbers for expr2 or expr3
                    mean ``count from before the beginning'', i.e.
                    foo[-2..-1] is an empty array or string.
                    foo[<2..<1] gives the 2nd and last element of
                    the array resp. chars of the string.

So I'm guessing that:

pairs = digrams[24..<1];

Means get the substring starting at index 24 to the end of the string?

like image 42
Matt Burland Avatar answered Mar 08 '26 18:03

Matt Burland



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!