class WeightedRandomBag<T>
{
private struct Entry
{
public double accumulatedWeight;
public T item;
}
private List<Entry> entries = new List<Entry>();
private double accumulatedWeight;
private System.Random rand = new System.Random();
public void AddEntry(T item, double weight)
{
accumulatedWeight += weight;
entries.Add(new Entry { item = item, accumulatedWeight = accumulatedWeight });
}
public T GetRandom()
{
double r = rand.NextDouble() * accumulatedWeight;
foreach (Entry entry in entries)
{
if (entry.accumulatedWeight >= r)
{
return entry.item;
}
}
return default(T); //should only happen when there are no entries
}
}
使用
WeightedRandomBag<int> itemDrops = new WeightedRandomBag<int>();
// Setup - a real game would read this information from a configuration file or database
itemDrops.AddEntry(0, 0);
itemDrops.AddEntry(1, 20.0);
itemDrops.AddEntry(2, 45.0);
itemDrops.AddEntry(3, 0);
itemDrops.AddEntry(4, 10.0);
// drawing random entries from it
for (int i = 0; i < 2000; i++)
{
// System.out.println(itemDrops.getRandom());
Debug.LogError("... " + itemDrops.GetRandom());
}