我尝试将Tricky's script(从精英生成名称)转换为javascript:
https://github.com/rubo77/eliteNameGen/blob/master/elite.js
但是我被这个LPC - 陷入了棘手的代码:
digrams=ABOUSEITILETSTONLONUTHNO..LEXEGEZACEBISOUSESARMAINDIREAERATENBERALAVETIEDORQUANTEISRION
...
pairs = digrams[24..<1];
...
names[0..<2]
我找不到可以解释这种语法的LPC手册。
最后我想创建一个javascript,它会从旧的C64游戏Elite中创建一个随机行星名称。
我还找到了python version,(但这对我来说似乎有点复杂)
答案 0 :(得分:3)
对于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
开始到字符串末尾的子字符串?
答案 1 :(得分:3)
好的,我设法将代码移植过来,但我不得不调整一点算法。 Tricky提供的那个由于某种原因产生了非唯一的名称。我使用tweakseed函数来调整种子以生成随机名称列表。
要回答上述问题,@ 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&#39;这样的名字,但在大多数情况下,这些名字显得像外星人一样。
以下是代码的直接端口。您可以使用此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;
}