Noticias

Se ha publicado un nuevo servicio, el Portal de Juegos Online

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: Script que funciona a veces [SOLUCIONADO]  (Leído 316 veces)

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

Desconectado Johann

  • Las cosas como son!
  • Moderadores globales
  • Okupa
  • *
  • Puntos: 720
  • Mensajes: 827
  • Agradecido: 108 veces
  • Sexo: Masculino
  • First Class Soldier... 10 años en CGM, 5 como mod
    • Ver Perfil
en: Noviembre 30, 2018, 03:37:24 am
Hola a todos, les cuento que me enfrento al bug mas "ficticio" del mundo:
Primero el contexto:
Resulta que tengo varias listas que contienen objetos (instancias de un mismo objeto, para ser mas exacto), estos objetos tienen sus propiedades (variables) con diferentes valores, en algún momento requiero juntar todos esos objetos en una única lista y luego redistribuirlos en listas nuevas luego de haberlos ordenado de acuerdo al valor en una de sus propiedades.
Para eso utilizo el algoritmo de ordenamiento burbuja adaptado a las condiciones particulares, ya lo he probado en un proyecto aislado y no ha tenido inconvenientes:

///e_sort(list)
var N = ds_list_size(argument0);
var s = noone;
var j = 0;
for (var i=1; i<N; i++) {
    j = i;
    s = ds_list_find_value(argument0, j);
    while (ds_list_find_value(argument0, j-1).valor > s.valor && j>0) {
        ds_list_replace(argument0, j, ds_list_find_value(argument0, j-1));
        j--;
    }
    ds_list_replace(argument0, j, s);
}

Ahora los casos que se dan luego de juntar todos los objetos en una unica lista:
  • A, B, A, B, B, B
  • B, B, A, B, A, B
Donde A tiene un valor de 3.04 y B tiene un valor de 3.44
En cualquier caso el resultado debería ser A, A, B, B, B, B PERO en el primer caso funciona y en el segundo falla el algoritmo y se cierra la aplicación.
Cuando funciona se crean correctamente dos listas conteniendo A, B, B como se espera que lo haga.

Código: [Seleccionar]
############################################################################################
FATAL ERROR in
action number 1
of Mouse Event for Glob Right Pressed

for object control:


Unable to find any instance for object index '0' name 'table_return'
at gml_Script_e_sort
############################################################################################
--------------------------------------------------------------------------------------------
stack frame is
gml_Script_e_sort (line -1)
gml_Script_sintesis2
gml_Object_control_Mouse_54

Es como si los objetos ya no existieran y hace cualquier cosa como buscar un object_index == 0 con el nombre de cualquier otro objeto.
Ya he verificado que efectivamente los objetos si existen y fue asi como obtuve las listas de los casos que puse arriba como ejemplo.
Las veces que he visto que el "error" se encuentra en la linea -1 es porque no logra iniciar el script.
El script sintesis2 es el que une las listas en una sola, aplica el script de ordenamiento y hace la redistribución en las listas nuevas, eso se ejecuta en un evento Global Right Pressed

Me tocó alargar el post debido a la complejidad del proyecto que postearé a mitad de Diciembre, espero que no se me escape nada para que me puedan ayudar con sus comentarios.
« última modificación: Diciembre 06, 2018, 12:51:13 am por Johann »

Cita de: Fenris78
Si un tema os resulta de interes y veis que hay poca información, la mejor solucion no es quejarse o pedir sin pensar, sino sugerir algo bien planteado o aportarlo vosotros mismos.
Cita de: Calio
Somos desarrolladores independientes y, por lo tanto, no tenemos por qué guiarnos por las tendencias del mercado.
 


No Tienes Permisos Para Dar Puntos
point 0 Puntos

Este tema no recibió puntos.


Desconectado NiuWeb

  • Flota de Justicia Particular.
  • Moderadores globales
  • Okupa
  • *
  • Puntos: 2820
  • Mensajes: 1.701
  • Agradecido: 136 veces
  • Sexo: Masculino
  • Rock anthem for saving the world.
    • Ver Perfil
Respuesta #1 en: Noviembre 30, 2018, 03:48:27 am
No veo nada mal con el script, pero de todas formas yo sugeriría utilizar colas de prioridad para organizar las instancias con mayor facilidad y evitar posibles errores.

Tal vez haya algún problema con el script sintesis2() en el que no te hayas fijado, puede ser buena idea imprimir texto en consola en varias partes del código para ver en qué lugar exactamente se produce el fallo.
« última modificación: Noviembre 30, 2018, 04:06:02 am por NiuWeb »

El tiempo era tu aliado, humano, pero te ha abandonado.
Los Forerunners han regresado, esta tumba ahora es tuya.

-Ur-Didacta.


BA:STFW&RTFM
 


Desconectado Johann

  • Las cosas como son!
  • Moderadores globales
  • Okupa
  • *
  • Puntos: 720
  • Mensajes: 827
  • Agradecido: 108 veces
  • Sexo: Masculino
  • First Class Soldier... 10 años en CGM, 5 como mod
    • Ver Perfil
Respuesta #2 en: Noviembre 30, 2018, 04:13:40 am
tal vez sea buena idea imprimir texto en consola en varias partes del código para ver en qué lugar exactamente se produce el fallo.
Lo he hecho por todas partes, imprimiendo cada cambio en las listas para ver donde muere, una hipótesis que tenía era que el programa dependía del orden que se fueron creadas las instancias, lo cual es ridiculo XD

Me dejas pensando con lo de las colas de prioridad, así no tendría que usar ordenamiento, pero el cambio a esta altura me puede salir un poquito costoso (o no?, ya se me están ocurriendo cosas)

Cita de: Fenris78
Si un tema os resulta de interes y veis que hay poca información, la mejor solucion no es quejarse o pedir sin pensar, sino sugerir algo bien planteado o aportarlo vosotros mismos.
Cita de: Calio
Somos desarrolladores independientes y, por lo tanto, no tenemos por qué guiarnos por las tendencias del mercado.
 


Desconectado NiuWeb

  • Flota de Justicia Particular.
  • Moderadores globales
  • Okupa
  • *
  • Puntos: 2820
  • Mensajes: 1.701
  • Agradecido: 136 veces
  • Sexo: Masculino
  • Rock anthem for saving the world.
    • Ver Perfil
Respuesta #3 en: Noviembre 30, 2018, 04:23:32 am
pero el cambio a esta altura me puede salir un poquito costoso
Ni tanto, unas cuantas líneas (tal vez menos de las que se utiliza en el script actual) bastarían.

Lo que no entiendo es, ¿qué criterio usas para separar las instancias en listas diferentes (después de haberlas organizado en una única lista)?

El tiempo era tu aliado, humano, pero te ha abandonado.
Los Forerunners han regresado, esta tumba ahora es tuya.

-Ur-Didacta.


BA:STFW&RTFM
 


Desconectado Johann

  • Las cosas como son!
  • Moderadores globales
  • Okupa
  • *
  • Puntos: 720
  • Mensajes: 827
  • Agradecido: 108 veces
  • Sexo: Masculino
  • First Class Soldier... 10 años en CGM, 5 como mod
    • Ver Perfil
Respuesta #4 en: Noviembre 30, 2018, 04:03:40 pm
Pues ya estando ordenada, recorro la lista con un for, y como es seguro que habrá un numero par de instancias de cada tipo (sea A o B o incluso C o mas) cuando el indice del for es par (i mod 2 == 0) meto la instancia en la primera lista y cuando es impar, en la segunda, asi se distribuyen en partes iguales y quedan ordenados de una vez, porque necesito que también estén ordenados para crear relaciones entre ellos (dentro de una misma lista) utilizando un grid que contiene esas relaciones.

Cita de: Fenris78
Si un tema os resulta de interes y veis que hay poca información, la mejor solucion no es quejarse o pedir sin pensar, sino sugerir algo bien planteado o aportarlo vosotros mismos.
Cita de: Calio
Somos desarrolladores independientes y, por lo tanto, no tenemos por qué guiarnos por las tendencias del mercado.
 


Desconectado NiuWeb

  • Flota de Justicia Particular.
  • Moderadores globales
  • Okupa
  • *
  • Puntos: 2820
  • Mensajes: 1.701
  • Agradecido: 136 veces
  • Sexo: Masculino
  • Rock anthem for saving the world.
    • Ver Perfil
Respuesta #5 en: Noviembre 30, 2018, 06:44:03 pm
Intenta modificar el script utilizando colas de prioridad, a ver si hay alguna mejora.
///Algún evento que se ejecute una sola vez
globalvar sorted_list;
sorted_list = ds_priority_create();
///e_sort(list)
var N = ds_list_size(argument0);
var i, inst;

//Primer ciclo para añadir los elementos a la cola
for(i = 0; i < N; i++) {
    inst = argument0[| i];
    ds_priority_add( sorted_list, inst, inst.valor);
}
ds_list_clear(argument0);

//Segundo ciclo para obtenerlos organizados
for(i = 0; i < N; i++) {
    inst = ds_priority_delete_min(sorted_list);
    ds_list_add(argument0, inst);
}

Si sigue habiendo errores, sería bueno que imprimeras el contenido de las estructuras de datos (json_encode()) para ver si hay problemas con la información.

También ayudaría ver el contenido del script sintesis2().

El tiempo era tu aliado, humano, pero te ha abandonado.
Los Forerunners han regresado, esta tumba ahora es tuya.

-Ur-Didacta.


BA:STFW&RTFM
 
Los siguientes usuarios dieron las gracias a este tema: Johann


Desconectado Johann

  • Las cosas como son!
  • Moderadores globales
  • Okupa
  • *
  • Puntos: 720
  • Mensajes: 827
  • Agradecido: 108 veces
  • Sexo: Masculino
  • First Class Soldier... 10 años en CGM, 5 como mod
    • Ver Perfil
Respuesta #6 en: Noviembre 30, 2018, 07:56:52 pm
No, lo que me toca hacer es simplificar todo con el uso de las colas de prioridad, así ese algoritmo se vuelve innecesario.
De todas formas comparto el script Sintesis2 que hace lo que explicaba al principio:
Cita de: Johann
... juntar todos esos objetos en una única lista y luego redistribuirlos en listas nuevas luego de haberlos ordenado de acuerdo al valor en una de sus propiedades.
///sintesis2(new1, new2, others)
// argument0: Primera nueva lista
// argument1: Segunda nueva lista
// argument2: lista de objetos que contienen las listas a unir

var mol, elm, i, j;
var elems = ds_list_create();
// primero se meten todos los objetos de las listas en argument2 en una sola lista
for (i=0; i<ds_list_size(argument2); i++) {
    mol = argument2[| i];
    for (var j=0; j<ds_list_size(mol.lista); j++) {
        ds_list_add(elems, mol.lista[| j]);
    }
    ds_list_clear(mol.lista);
}
// luego esa lista se ordena
e_sort(elems); // aquí es donde falla algunas veces, cuando se le da la gana si funciona XD
// los objetos ordenados se distribuyen de manera equitativa en 2 listas nuevas
for (i=0; i<ds_list_size(elems); i++) {
    elm = elems[| i];
    if (i mod 2 == 0) {
        elm.padre = argument0.id;
        ds_list_add(argument0.lista, elm);
    } else {
        elm.padre = argument1.id;
        ds_list_add(argument1.lista, elm);
    }
}

ds_list_clear(elems);
ds_list_destroy(elems);

Alguno dirá que son muchos ciclos for, pero como una lista no va a llegar a tener mas de 10 objetos no le veo problema.
Y bueno, tampoco me voy a cerrar, voy a probar los de la cola de prioridad para ordenar haber que pasa.


Edit pocos minutos después: ha funcionado perfectamente el ordenamiento por medio de colas de prioridad y me ahorra modificar todo el proyecto como habia pensado al principio :D
« última modificación: Noviembre 30, 2018, 08:11:47 pm por Johann »

Cita de: Fenris78
Si un tema os resulta de interes y veis que hay poca información, la mejor solucion no es quejarse o pedir sin pensar, sino sugerir algo bien planteado o aportarlo vosotros mismos.
Cita de: Calio
Somos desarrolladores independientes y, por lo tanto, no tenemos por qué guiarnos por las tendencias del mercado.