如何创建一个 JavaScript 精英行星名称生成器

How do I create a javascript elite planet name generator?

本文关键字:行星 精英 一个 何创建 创建 JavaScript      更新时间:2023-09-26

我尝试在这里将Tricky的脚本(从精英中生成一个名称)转换为javascript:

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

但是我被Tricky的这个LPC代码卡住了:

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

我找不到可以解释此语法的 LPC 手册。

最后,我想创建一个javascript,从旧的C64游戏Elite创建一个随机的星球名称。

我还找到了一个python版本,(但这对我来说似乎有点复杂)

好的,

我设法移植了代码,但我不得不调整一些算法。由于某种原因,Tricky 提供的那个会产生非唯一名称。我使用调整种子函数来调整种子以生成随机名称列表。

要回答上面的问题,@MattBurland是正确的。您将替换以下代码:

pairs = digrams[24..<1];

pairs = digrams.substring(24);

但是,以下代码实际上是打印出名称列表。所以你正在索引一个数组 - 在这种情况下:

names[0..<2]

成为

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

分析

只是为了给它更多的深度。我分析了代码,意识到rotateltwisttweakseednext只是用来创建随机数的。我对LPC不够了解,但我认为当时它可能没有伪随机数生成器。

很多这样的代码可以删除,只是用Math.random替换。整个程序的关键部分是 变量digram .这一系列角色产生了类似外星人的名字。我想这可能与辅音和元音的交替有关。随机成对抓取它们几乎总是会产生某种辅音 + 元音配对。有一个奇怪的时间,你最终会得到一个像"Rmrirqeg"这样的名字,但在大多数情况下,这些名字看起来像外星人。

港口

下面是代码的直接端口。您可以使用此jsFiddle来查看它的实际效果,但是它使用AngularJS来打印出名称,而不是像提供的代码那样打印出列表。genNames 将生成一个名称数组,您可以出于任何原因使用这些名称。

请注意,此端口仅适用于 IE9+,因为它使用 map、reduce 和 forEach。如果您计划在 IE8 或更低版本上使用它,请将它们替换为循环。

您可以调整此设置以生成更长或更短的名称。但是,名称的长度取决于对数组。要么使用Math.random,要么使用其他东西来使其完全狂野。

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;
}

对于 LPC 中的范围运算符,此链接有助于:

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.

所以我猜:

pairs = digrams[24..<1];

意味着让子字符串从索引24开始到字符串的末尾?