I have a set of values, and an associated percentage for each:
a: 70% chance
b: 20% chance
c: 10% chance
I want to select a value (a, b, c) based
I've my own solution for this:
public class Randomizator3000
{
public class Item
{
public T value;
public float weight;
public static float GetTotalWeight(Item[] p_itens)
{
float __toReturn = 0;
foreach(var item in p_itens)
{
__toReturn += item.weight;
}
return __toReturn;
}
}
private static System.Random _randHolder;
private static System.Random _random
{
get
{
if(_randHolder == null)
_randHolder = new System.Random();
return _randHolder;
}
}
public static T PickOne(Item[] p_itens)
{
if(p_itens == null || p_itens.Length == 0)
{
return default(T);
}
float __randomizedValue = (float)_random.NextDouble() * (Item.GetTotalWeight(p_itens));
float __adding = 0;
for(int i = 0; i < p_itens.Length; i ++)
{
float __cacheValue = p_itens[i].weight + __adding;
if(__randomizedValue <= __cacheValue)
{
return p_itens[i].value;
}
__adding = __cacheValue;
}
return p_itens[p_itens.Length - 1].value;
}
}
And using it should be something like that (thats in Unity3d)
using UnityEngine;
using System.Collections;
public class teste : MonoBehaviour
{
Randomizator3000.Item[] lista;
void Start()
{
lista = new Randomizator3000.Item[10];
lista[0] = new Randomizator3000.Item();
lista[0].weight = 10;
lista[0].value = "a";
lista[1] = new Randomizator3000.Item();
lista[1].weight = 10;
lista[1].value = "b";
lista[2] = new Randomizator3000.Item();
lista[2].weight = 10;
lista[2].value = "c";
lista[3] = new Randomizator3000.Item();
lista[3].weight = 10;
lista[3].value = "d";
lista[4] = new Randomizator3000.Item();
lista[4].weight = 10;
lista[4].value = "e";
lista[5] = new Randomizator3000.Item();
lista[5].weight = 10;
lista[5].value = "f";
lista[6] = new Randomizator3000.Item();
lista[6].weight = 10;
lista[6].value = "g";
lista[7] = new Randomizator3000.Item();
lista[7].weight = 10;
lista[7].value = "h";
lista[8] = new Randomizator3000.Item();
lista[8].weight = 10;
lista[8].value = "i";
lista[9] = new Randomizator3000.Item();
lista[9].weight = 10;
lista[9].value = "j";
}
void Update ()
{
Debug.Log(Randomizator3000.PickOne(lista));
}
}
In this example each value has a 10% chance do be displayed as a debug =3