代码之家  ›  专栏  ›  技术社区  ›  rubo77

如何创建javascript精英行星名称生成器?[已关闭]

  •  3
  • rubo77  · 技术社区  · 12 年前

    我试图转换 Tricky's script (从elite生成名称)转换为javascript:

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

    但我对此感到困惑 LPC -由Tricky编写的代码:

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

    我找不到LPC手册来解释这种语法。

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

    我还发现了 python version ,(但我觉得这有点复杂)

    2 回复  |  直到 12 年前
        1
  •  3
  •   Pete    12 年前

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

    答复

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

    pairs = digrams[24..<1];
    

    具有

    pairs = digrams.substring(24);
    

    然而,下面的代码实际上是在打印姓名列表。因此,您正在索引一个数组,在这种情况下:

    names[0..<2]
    

    变成

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

    分析

    只是为了让这个更加深入。我分析了代码,意识到 rotatel , twist , tweakseed next 只是用来创建随机数。我对LPC了解不够,但我认为当时它可能没有伪随机数生成器。

    很多代码都可以删除,只需替换为 Math.random 。整个程序的关键部分是变量 digram 。此字符序列产生类似外星人的名称。我想这可能与辅音和元音的交替有关。随机配对几乎总是会产生某种辅音+元音配对。有时你会以“Rmrirqeg”这样的名字结尾,但在大多数情况下,这些名字看起来像外星人。

    港口城市

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

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

    您可以对其进行调整以生成更长或更短的名称。但是,名称的长度取决于pairs数组。使用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;
    }
    
        2
  •  3
  •   Matt Burland    12 年前

    对于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 到底是什么?