Vážená náhoda

Sem vkládejte editovatelné kusy kódu a tutoriály.
Post Reply
D-Sheep
Posts: 768
Joined: September 7, 2011, 10:17 pm
Facebook: http://facebook.com/sheepdave
Location: Praha, CZE
Contact:

Vážená náhoda

Post by D-Sheep »

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:

Code: Select all

//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.

Code: Select all

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

Code: Select all

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

Code: Select all

//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;

Code: Select all

//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);

Code: Select all

//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;
Last edited by D-Sheep on April 12, 2015, 10:26 pm, edited 3 times in total.
bildo
Posts: 147
Joined: August 6, 2011, 7:30 am

Re: Vážená náhoda

Post by bildo »

Parada, pekne !
Image
Post Reply