Nombre del creador:
Fenris78
Breve descripci?n de su funci?n:
Devuelve una lista de n valores enteros aleatorios, escogidos del 1 al vmaximo sin repeticion. El ID de la lista se puede usar despues para acceder a cualquiera de sus valores.
Ej: milista=scliale(10,30);
Versi?n GM utilizada:
:GM8:
C?digo del Script:
[gml]
//sc_liale(nvalores,vmaximo); Ej: milista=scliale(10,30);
var lista,ntotal,nmax,nvalido,numero;
lista=ds_list_create(); //Creo una lista
ntotal=0; nvalores=argument0; nmax=argument1; nvalido=false;
for(i=1;ntotal<nvalores;i+=1)
{
numero=irandom(nmax)+1;
for(i=1; i<nvalores; i+=1){ if(ds_list_find_value(lista,i)=numero){ nvalido=false; } else { nvalido=true; } } //verifico si esta seleccionado
if(nvalido=true) { ntotal+=1; ds_list_add(lista,numero); }
}
return lista; //Devuelvo su ID[/gml]
Tambi?n puedes usar un while en vez de 2 bucles for:
[gml]
var l,i,str,value;
l=ds_list_create();
i=0;
str="|";
while (i<argument0)
{
value=irandom_range(0,argument1);
if (string_count("|"+string(value)+"|",str)<=0)
{
i+=1;
str+=string(value)+"|";
ds_list_add(l,value);
}
}
return l;
[/gml]
No lo he testeado, ni s? si es m?s optimizado, pero siempre est? bien tener otra opini?n! :D
Por cierto no conoc?a la funci?n irandom, gracias por ense??rmela xD
Aha, pero si yo por ejemplo ya agregu? el 10 en random y luego toca el 1 dar? como que el 1 ya est? seleccionado por estar dentro del 10, deber?as inicializar el str="|" y chequear asi
[gml]if (string_count("|"+string(value)+"|",str)<=0)[/gml]
Buena observaci?n ahora corrijo!
Solo agregaria que se utilice un break una vez que se haya encontrado el valor como invalido para no tener que revisar el resto de valores pues ya no es necesario, y asi nos ahorramos algo de tiempo.Con listas mas grandes este ahorro sera mas evidente :D
Hola, tambien puedes usar 2 listas y hace el proceso mas simple, principalmente cuando son numeros muy grandes (por la tasa de rechazo), hice un ejemplo (adjunto)...
Para este tipo de cosas creo que lo mejor es usar una cola de prioridad, meter los valores en orden y asignarles una prioridad aleatoria, as? te ahorras anidar los dos bucles y el script ser? m?s r?pido:
[gml]var priO, lstD, iN, maxN, maxV;
maxN = argument0;//N?mero de elementos
maxV = argument1;//Valor m?ximo
priO = ds_priority_create();
lstD = ds_list_create();
for (iN=0; iN<=maxV; iN+=1) ds_priority_add(priO, iN, random(maxV));//A?ado los valores en orden pero con prioridad aleatoria
repeat (maxN) ds_list_add(lstD, ds_priority_delete_max(priO));//Voy cogiendo los valores finales seg?n la prioridad
return lstD;[/gml]
Tambi?n podr?a hacerse con dos listas y la funci?n ds_list_shuffle:
[gml]var lstO, lstD, iN, maxN, maxV;
maxN = argument0;//N?mero de elementos
maxV = argument1;//Valor m?ximo
lstO = ds_list_create();
lstD = ds_list_create();
for (iN=0; iN<=maxV; iN+=1) ds_list_add(lstO, iN);//A?ado los valores en orden
ds_list_shuffle(lstO);//Desordeno la lista
for (iN=0; iN<maxN; iN+=1) ds_list_add(lstD, ds_list_find_value(lstO, iN));
return lstD;[/gml]
Este caso ser? un pel?n m?s lento que con las colas de prioridad pues necesitamos dos bucles for en lugar un for y un repeat.
Que util es este Script!!! :D Muchiiiisimas gracias, me funciono de maravilla...