Noticias

Importante: ¡Si quieres publicar tu juego no olvides leer este tema!

* Sponsor

Comunidad Game Maker

Bienvenid@ a la comunidad hispana de Game Maker. Nuestro objetivo es crear videojuegos y dar soporte en castellano de GM. Para mejorar nuestro servicio hemos implantado, como adicion al reglamento general, algunas normas especificas en los subforos más comunes. ¡No olvides informarte antes de participar!.

Autor Tema: Lista de enteros sin repeticion  (Leído 3645 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Fenris78

en: Enero 15, 2011, 06:51:28 pm
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:

//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
« Última modificación: Enero 15, 2011, 07:02:51 pm por Fenris78 »

 


No Tienes Permisos Para Dar Puntos
point 0 Puntos

Este tema no recibió puntos.


Desconectado PoSvA

Respuesta #1 en: Enero 17, 2011, 05:51:58 pm
También puedes usar un while en vez de 2 bucles for:
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;

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
« Última modificación: Enero 17, 2011, 10:13:30 pm por PoSvA »

 


Desconectado Texic

  • Moderadores globales
  • Legendario
  • *
  • Puntos: 1213
  • Mensajes: 2.158
  • Agradecido: 3 veces
  • Sexo: Masculino
  • I Have The Fire!
    • Ver Perfil
Respuesta #2 en: Enero 17, 2011, 07:56:47 pm
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
if (string_count("|"+string(value)+"|",str)<=0)




 


Desconectado PoSvA

Respuesta #3 en: Enero 17, 2011, 10:12:43 pm
Buena observación ahora corrijo!


Desconectado licshendu

  • Habitual
  • *
  • Puntos: 46
  • Mensajes: 64
  • Sexo: Masculino
  • Sooel de Aries
    • Ver Perfil
Respuesta #4 en: Abril 06, 2011, 05:58:18 pm
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

"Si he llegado a ver más lejos que otros, es porque me subí a hombros de gigantes"  Isaac Newton
 


Desconectado Zeit

  • Okupa
  • *
  • Puntos: 13
  • Mensajes: 697
  • Sexo: Masculino
    • Ver Perfil
Respuesta #5 en: Abril 14, 2011, 07:30:05 pm
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)...

Saludos Cordiales!!!
 


Desconectado correojon

  • El azote de los trollers y
  • Legendario
  • *
  • Puntos: 85
  • Mensajes: 4.112
  • Agradecido: 3 veces
  • No mercy
    • Ver Perfil
Respuesta #6 en: Abril 17, 2011, 11:28:59 am
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:

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;

También podría hacerse con dos listas y la función ds_list_shuffle:
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;
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.


Desconectado slampdesign

  • Adicto
  • *
  • Puntos: 3
  • Mensajes: 495
  • Sexo: Masculino
    • Ver Perfil
Respuesta #7 en: Abril 19, 2011, 02:03:32 am
Que util es este Script!!!  :D Muchiiiisimas gracias, me funciono de maravilla...