i needed a way the get a random idx from a array based on weights and i found this blog post by some random dude:
https://blog.bruce-hill.com/a-faster...-random-choice
and ported the alias method to sourcepawn
include:
https://github.com/arthurdead/sm-plu...liasrandom.inc
seems to work good enough for me:
Code:
#include <sourcemod>
#include <aliasrandom>
public void OnPluginStart()
{
ArrayList randomnames = new ArrayList(ByteCountToCells(64));
randomnames.PushString("test0");
randomnames.PushString("test1");
randomnames.PushString("test3");
randomnames.PushString("test4");
randomnames.PushString("test5");
int len = randomnames.Length;
ArrayList weights = new ArrayList(1, len);
weights.Set(0, 15.0);
weights.Set(1, 2.0);
weights.Set(2, 70.5);
weights.Set(3, 40.0);
weights.Set(4, 5.0);
AliasRandom test = new AliasRandom(weights);
int attempts = 500;
len = randomnames.Length;
ArrayList nums = new ArrayList(1, len);
for(int i = 0; i < len; ++i) {
nums.Set(i, 0);
}
int fail = 0;
char name[64];
if(test != null) {
for(int i = 0; i < attempts; ++i) {
int idx = test.Get();
if(idx == -1) {
++fail;
continue;
}
int num = nums.Get(idx);
++num;
nums.Set(idx, num);
}
}
PrintToServer("ran %i times %i failed:", attempts, fail);
for(int i = 0; i < len; ++i) {
int num = nums.Get(i);
randomnames.GetString(i, name, sizeof(name));
float weight = weights.Get(i);
PrintToServer(" got %s %i times (weight was %.1f)", name, num, weight);
}
delete nums;
delete test;
delete weights;
}