Vážená náhoda

Sem vkládejte editovatelné kusy kódu a tutoriály.
Odpovědět
Uživatelský avatar
D-Sheep
Příspěvky: 768
Registrován: září 7, 2011, 10:17 pm
Facebook: http://facebook.com/sheepdave
Bydliště: Praha, CZE
Kontaktovat uživatele:

Vážená náhoda

Příspěvek od D-Sheep » květen 31, 2014, 1:30 am

Ahoj lidi,
za prvé se trochu nudím a za druhé chci trochu rozvířit stojaté vody polomrtvého fóra. I když tímhle asi moc nezvládnu... Rozhodl jsem se sepsat malý návod, jak vybírat náhodné hodnoty s určitou váhou.

Dejme tomu, že chci vybrat náhodně jedničku s šancí 1:4, v ostatních případech nulu. Můžu to zapsat několika způsoby:

Kód: Vybrat vše

//1.
a = choose(1, 0, 0, 0);

//2.
if (floor(random(4)) == 0)
    a = 1;
else
    a = 0;

//3. (pro úchyláky)
a = !sign(irandom(3));
a docela mi to stačí, jenže až si budu chtít vybírat z deseti hodnot, každou nejlépe s nějakou prvočíselnou pravděpodobností, začnu brečet.

Já jsem si na to vyrobil malou trojdimenzionální datovou strukturu složenou z ds_listů, která mi to celkem hodně zjednoduší. Složitě to jen zní, když řeknu, že jsou to listy v listu v listu...

Vyhledávání je primitivní. Představte si knihu. Chci zjistit v jaké kapitole je náhodná stránka. Otevřu si tedy obsah, kde jsou uvedeny první stránky kapitol a jdu shora dolů, dokud je mnou vybraná stránka moc nízká. Když už je další kapitola moc daleko, tak jsem právě teď na té správné. A přesně to dělá i moje listové monstrum. Vybere číslo a skáče po všech vložených hodnotách a odečítá jejich váhu.

Kód: Vybrat vše

r = wrandom_create(); //Vytvořím seznam
wrandom_add(r, 0, 1); //Vložím nulu s váhou 1
wrandom_add(r, 1, 2); //Vložím jedničku s váhou 2
wrandom_add(r, 2, 5); //Vložím dvojku s váhou 5
n = wrandom_get(r); //Získám náhodné číslo
  //0 s šancí 1:8
  //1 s šancí 1:4
  //2 s šancí 5:8
wrandom_destroy(r); //Seznam už nepotřebuju
Ohromné využití se najde např. v RPG hrách, kde z monster padají náhodné, různě vzácné dropy.

Ke stažení:
-------------------------
.gmres (602 B): https://dl.dropboxusercontent.com/u/241 ... ndom.gmres

kód ke zkopírování:
Spoiler: ukázat

Kód: Vybrat vše

//wrandom_create();
var l;
l = ds_list_create();
ds_list_add(l, ds_list_create());
ds_list_add(l, 0);
return l;

Kód: Vybrat vše

//wrandom_add(id, value, weight);
if (argument2 <= 0)
    return false;
var elm;
elm = ds_list_create();
ds_list_add(elm, argument1);
ds_list_add(elm, argument2);
ds_list_add(ds_list_find_value(argument0, 0), elm);
ds_list_replace(argument0, 1, ds_list_find_value(argument0, 1) + argument2);
return true;

Kód: Vybrat vše

//wrandom_get(id);
var list, total, target, i, elm;
list = ds_list_find_value(argument0, 0);
if (ds_list_empty(list))
    return 0;
total = ds_list_find_value(argument0, 1);
target = irandom(total - 1) + 1;
show_debug_message("wrandom target: " + string(target));
i = 0;
elm = ds_list_find_value(list, i);
while (target > ds_list_find_value(elm, 1)) {
    target -= ds_list_find_value(elm, 1);
    i += 1;
    elm = ds_list_find_value(list, i);
}
return ds_list_find_value(elm, 0);

Kód: Vybrat vše

//wrandom_destroy(id);
var i, list, size;
list = ds_list_find_value(argument0, 0);
size = ds_list_size(list);
for (i = 0; i < size; i += 1)
    ds_list_destroy(ds_list_find_value(list, i));
ds_list_destroy(list);
ds_list_destroy(argument0);
return true;
Naposledy upravil(a) D-Sheep dne duben 12, 2015, 10:26 pm, celkem upraveno 3 x.

bildo
Příspěvky: 144
Registrován: srpen 6, 2011, 7:30 am

Re: Vážená náhoda

Příspěvek od bildo » červen 4, 2014, 10:59 pm

Parada, pekne !
Obrázek

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 2 hosti