Septiembre 29, 2014, 04:38:11 PM Ultima modificación: Septiembre 29, 2014, 04:43:28 PM por fab62
Hola Makeros! ultimamente he estado realizando varios ejemplos de utilidades para el game maker, y como hace tiempo que no me adentraba al sitio estaba olvidando subirlos para que ustedes los usen en sus proyectos.

Estos scripts sirven para crear listas con elementos que se escojen con probabilidad, mientras mayor sea la probabilidad de un elemento, mayor serán las veces que se escoja ese elemento de la lista.

Creador: Fab62


Version de GM:  :GMS:


Descripcion: Elije un elemento al azar, dependiendo de una probabilidad dada por la formula:
probabilidad = factor de probabilidad * 100 / suma total de los factores probables
El factor de probabilidad es el numero que los usuarios pueden dar a la probabilidad en la lista.


Scripts:
Para iniciar el sistema, se necesita un contador de listas probables, aunque sea un script de una sola linea, es necesaria.
Su uso debe ser en el evento create, antes de todo script que de a conocer aqui.

probable_iniciar()
prob_count = -1;


Para crear una lista probable, que en si son dos listas del mismo tamaño, solo basta agregar este script:

probable_crear()

prob_count++;
prob_elements[prob_count] = ds_list_create();
prob_factors[prob_count]  = ds_list_create();
   
return prob_count;


para usarlo debe guardarse en una variable, para su uso posterior, esto tambien debe estar en el evento create:

lista = probable_crear();



despues de haber creado la lista, es necesario agregar los elementos:

probable_elemento(elemento, factor de probabilidad)

ds_list_add(prob_elements[prob_count],argument0);
ds_list_add(prob_factors[prob_count],argument1);


Como se puede ver, este script no necesita la variable que se guardo anteriormente, que es para guardar un identificador de la lista, ya que el contador nos proporciona esto por ahora.


Ya tenemos la lista creada, por lo que ahora se puede elegir un elemento al azar con la probabilidad que se le dio a cada elemento:

probable_elegir(id de la lista, comienzo, fin)
elige un elemento entre comienzo y fin
probable_elegir(id de la lista, fin)
elige un elemento entre 0 y fin
probable_elegir(id de la lista)
elige un elemento de toda la lista


// elegimos el intervalo
var pstart, pend;
if (argument_count == 1) {pstart = 0; pend = ds_list_size(prob_factors[argument[0]])-1}
else if (argument_count == 2) {pstart = 0; pend = argument[1]}
else {pstart = argument[1]; pend = argument[2]}

// para saber cual es el total de la probabilidad en el intervalo
var ptotal = 0;
for (var i=pstart; i<=pend; i++) ptotal += ds_list_find_value(prob_factors[argument[0]],i);

// semilla
randomize();

// valor aleatorio y suma parcial
var prand = irandom(ptotal);
var pparcial = 0;

// encontrando el valor
for (var i=pstart; i<=pend; i++)
{
    // reseteamos suma parcial
    pparcial = 0;
   
    // sumamos todas las probabilidades hasta la i
    for (var j=pstart; j<i; j++) pparcial += ds_list_find_value(prob_factors[argument[0]],j);
   
    // chequeamos si estamos en el rango
    if (prand >= pparcial && prand <= pparcial+ds_list_find_value(prob_factors[argument[0]],i))
        return ds_list_find_value(prob_elements[argument[0]],i);
}



Ya cuando no se necesiten las listas las destruimos para liberar memoria:

probable_destruir()

for (var i=0; i<=prob_count; i++)
{
    ds_list_destroy(prob_elements[i]);
    ds_list_destroy(prob_factors[i]);
}



Un ejemplo puede ser lo siguiente:
Evento create

probable_iniciar()

objeto = probable_crear()
probable_elemento(obj_enemigo00, 100)
probable_elemento(obj_enemigo01, 50)
probable_elemento(obj_enemigo02, 35)
...

tipo = probable_crear()
probable_elemento("normal", 50)
probable_elemento("medio", 38)
probable_elemento("dificil", 20)


Evento del click izquierdo del mouse (cuando se presiona)

var mi_objeto = probable_elegir(objeto, global.nivel);
var mi_tipo    = probable_elegir(tipo);

var instancia = instance_create(mouse_x, mouse_y, mi_objeto)
with (instancia) {tipo = other.mi_tipo}


En este ejemplo se muestra la creacion de 2 listas probables, una de objetos, y otra de sus tipos, en donde la creacion de objetos depende de una variable global.nivel


Bueno... eso es todo espero que les sea de utilidad para sus proyectos, no olviden darme credito si lo usan, les estaria muy agradecido.

Les agrego un .gml adjunto para que tengan todos los scripts rapidamente  ;)

Saludos y que tengan un buen dia!
El ayer es un recuerdo, el mañana un pensamiento, es el ahora en donde existo y vivo para ser feliz :D

#1 Octubre 29, 2014, 12:22:33 AM Ultima modificación: Octubre 29, 2014, 12:25:37 AM por brunoxzx
Es interesante como lo haz resuelto!. Tuve el mismo problema hace un tiempo y lo resolví de un modo mucho más simplón, limitado y que necesita de mucha más memoria, pero a cambio es muy rápido escoger (no tiene ningún loop), así que de momento la prefiero.

Creo que sé como optimizar tu solución para dejar la mía a un lado, pero de momento tengo otras cosas que hacer. Escribo aquí si hago algo.

Gracias y Suerte!