2017-01-01 4 views
0

Ich habe eine Reihe von Objekten, die Kreaturen in einem Spiel darstellen, das ich zu entwickeln versuche. Diese Objekte haben (unter anderem) eine eindeutige Kennung und ein Gewicht (oder eine Wahrscheinlichkeit), um zu spawnen.Erhalte zufälliges Element aus einem Array mit gewichteten Elementen

Ich versuche, einen Algorithmus zu entwickeln, um Kreaturen nach dem Zufallsprinzip zu spawnen, aber ich komme nicht mit einer Möglichkeit, die Gewichte zu verwenden (ich weiß wirklich nicht, wie es geht).

Kann jemand helfen?

Ein Beispiel für Kreaturen Array sein könnte:

var creatures = [ 
    {id: 1, weight: 25}, 
    {id: 2, weight: 15}, 
    {id: 3, weight: 5}, 
    {id: 4, weight: 45}, 
    {id: 5, weight: 10} 
] 
+1

Welche Logik verfolgen Sie? –

+0

was meinst du mit Logik? Ich möchte ein Kreaturobjekt (dieses Objekt hat einen Verweis auf den Konstruktor der Kreatur) abrufen, um es in einigen Szenarien zu erstellen. – btt

+0

Willst du eine zufällige Kreatur rausbringen? Wie kommt "Gewicht" hier ins Spiel? –

Antwort

5

fand ich diese schöne Algorithmus in PHP in diesem blog implementiert, die ich denke, migth Ihre Bedürfnisse.

Ich habe es gerade zu JS angenommen.

var creatures = [{ 
 
    id: 1, 
 
    weight: 25 
 
    }, { 
 
    id: 2, 
 
    weight: 15 
 
    }, { 
 
    id: 3, 
 
    weight: 5 
 
    }, { 
 
    id: 4, 
 
    weight: 45 
 
    }, { 
 
    id: 5, 
 
    weight: 10 
 
    }], 
 
    sumOfWeights = creatures.reduce(function(memo, creature) { 
 
    return memo + creature.weight; 
 
    }, 0), 
 
    selectedWeigths = {}; 
 

 
function getRandom(sumOfWeights) { 
 
    var random = Math.floor(Math.random() * (sumOfWeights + 1)); 
 

 
    return function(creature) { 
 
    random -= creature.weight; 
 
    return random <= 0; 
 
    }; 
 
} 
 

 
for (var i = 0; i < 1000; i++) { 
 
    var creature = creatures.find(getRandom(sumOfWeights)); 
 
    selectedWeigths[creature.weight] = (selectedWeigths[creature.weight] || 0) + 1; 
 
} 
 

 
console.log(selectedWeigths);

Hoffe, es hilft.

+0

Können Sie eine Erklärung geben, was das bedeutet? – evolutionxbox

+0

@evolutionxbox Der Algorithmus basiert auf der diskreten kumulativen Dichtefunktion (CDF), die die Summe der Gewichte darstellt. Die Idee besteht darin, eine Zufallszahl zwischen 0 und dieser Summe zu erzeugen und das Gewicht der Elemente des Arrays von dieser Zufallszahl subtrahieren zu lassen. Wenn es kleiner als Null (oder Null) ist, bedeutet das, dass Sie das Element gefunden haben. Es ist ein bisschen schwierig, in nur einem Absatz zu erklären, ich schlage vor, "diskrete kumulative Dichtefunktion" auf Wikipedia nachzuschlagen, es gibt eine viel bessere Erklärung. – acontell

+0

Diese Lösung ist vielversprechend. Danke – btt

0

Erstellen Sie ein neues Array und fügen Sie die ID für jede Kreatur dem Array hinzu, wie oft es gewichtet wird. Erhalte dann eine Zufallszahl zwischen 0 und der Größe des Arrays und gib die ID-Nummer an dieser Position zurück.

var creatureIds = []; 
for(var i=0;i<creatures.length;i++){ 
    for(var x=0;x<creatures[i].weight;x++){ 
     creatureIds.push(creatures[i].id); 
    } 
} 

// get a random index between 0 and the ids length. 
var min = 0; 
var max = creatureIds.length; 
var index = Math.floor(Math.random() * (max - min + 1)) + min; 

var randomWeightedCreatureId = creatureIds[index]; 
+0

Das einzige Problem bei dieser Lösung ist, dass Sie mit einem großen Array enden, wenn es nicht nötig ist ... aber trotzdem danke! – btt

Verwandte Themen