На JavaScript: Взвешенный Случайный Генератор


Я пытаюсь создать функцию, которая даст мне "рыбу" на авось, хотя уклон случайным образом в зависимости от значения веса для "рыбы".

var FISH = {
    "level1": [
          //["name",      xp, weight] 
            ["Shrimp",    10, 95],
            ["Sardine",   20, 85],
            ["Herring",   30, 75],
            ["Anchovies", 40, 65],
            ["Mackerel",  40, 55]
        ]
};

function randomRange(min, max) {
    return Math.random() * (max - min) + min;
}

function getRandomFish(level) {
    var fishForLevel = FISH[level],
        numberOfFish = fishForLevel.length,
        chance = randomRange(0, 100);

    if (numberOfFish > 1) {

        var fish = fishForLevel[Math.floor(randomRange(0, numberOfFish))];

        if (chance <= fish[2]) {
            return fish;
        } else {
            return getRandomFish(level);
        }

    } else {
        return fishForLevel[0];
    }
}

Пример результата: http://jsfiddle.net/qAvAs/

Если это может быть сделано более эффективно, как бы это сделать?



3061
2
задан 20 августа 2011 в 05:08 Источник Поделиться
Комментарии
1 ответ

Я предлагаю вам выбрать случайное число, которое от 0 до общего веса рыбы. Тогда каждая рыба может иметь кусок, что случайный выбор в соответствии с его весом, который придает ему вес, который вы хотите. Это заканчивается давая каждой рыбы количество сегментов, что соответствует это взвешенное значение, а затем вы выбираете случайное число от 0 до общего количества сегментов и выяснить, кто ведро случайных чисел приземлился.

Это та же идея, как превратить каждое число взвешивания в процентах изменить, а затем выбрать случайное число от 0 до 99.

Этот код должен делать:

var FISH = {
"level1": [
//["name", xp, weight]
["Shrimp", 10, 95],
["Sardine", 20, 85],
["Herring", 30, 75],
["Anchovies", 40, 65],
["Mackerel", 40, 55]
]
};

function getRandomFish(level) {
var fishForLevel = FISH[level];
var fishTotalWeight = 0, fishCumWeight = 0, i;
// sum up the weights
for (i = 0; i < fishForLevel.length; i++) {
fishTotalWeight += fishForLevel[i][2];
}
var random = Math.floor(Math.random() * fishTotalWeight);
// now find which bucket out random value is in

for (i = 0; i < fishForLevel.length; i++) {
fishCumWeight += fishForLevel[i][2];
if (random < fishCumWeight) {
return(fishForLevel[i]);
}
}
}

4
ответ дан 20 августа 2011 в 05:08 Источник Поделиться