Como usar colas con prioridad en nuestro juego
Ya habíamos hablado de las colas, viendo ejemplos de como podríamos usarlas para nuestros juegos. Ahora aprenderemos como usar colas con prioridad.
Como hemos dicho, una cola con prioridad es una estructura de datos, muy parecida a una lista (porque puedes acceder a cualquier valor, no solo a los extremos), pero tiene una característica especial: cuando añadimos un elemento, debemos asignarle un número de prioridad. Con esta prioridad podremos localizar en la cola el elemento más prioritario.
Ejemplos de uso
Un ejemplo clarísimo sería la típica tabla de puntuación final, dónde los primeros de la tabla son los que tienen más puntos. Aunque Game Maker Studio ya tiene sus propios métodos para gestionar high scores.
Podemos usar el mismo ejemplo de inventario de armas que ya comentamos con las colas, pero le podemos dar un valor de importancia para usar. Por ejemplo, si un cuchillo tiene un 1 de daño, una espada un 5, un hacha un 10 y una alabarda un 20, podría dar un poco igual el orden de como incorporamos estos objetos a nuestro inventario, porque siempre estaríamos usando el más poderoso. Si por algún motivo perdemos el que estamos usando actualmente, lo eliminamos de la cola con prioridad y se elige el siguiente más poderoso.
Otro ejemplo que estamos más acostumbrados a ver: los powerups del Mario. Si cogemos una seta nos hacemos más grandes, con una flor podemos disparar, y también podemos tener el disfraz de mapache, pero solo tenemos un power-up activo. Si hemos adquirido los tres, tenemos el mapache vigente, pero si nos hacen daño pasamos al de la flor.
Funciones para gestionar colas con prioridad
Aquí tendremos un listado más extenso de funciones que podemos usar con nuestro código GML, ya que tenemos más detalle para tratar este tipo de datos. Pensemos en el ejemplo de los powerups. Para crear nuestra cola
power_up = ds_priority_create();
Recuerda que siempre toca eliminar la cola si no queremos usarla más con esta función
ds_priority_destroy(power_up);
Podemos eliminar todos los datos, que no se destruiría de la memoria, con la función
ds_priority_clear(power_up);
Para saber si nuestra variable no contiene ningún elemento
ds_priority_empty(power_up);
El número de elementos se puede averiguar con
ds_priority_size(power_up);
Ahora empezamos a añadir elementos a nuestra cola con prioridad. Por ejemplo, añadimos la seta
ds_priority_add(power_up, "SETA", 1);
Se podría cambiar la prioridad de uno de los elementos que ya tengamos añadidos
ds_priority_change_priority(power_up, "SETA", 5);
Ahora vamos a sacar elementos de la cola. Aquí no tenemos ningún método LIFO, aunque lo llamemos cola. Podemos sacar de la cola el más prioritario
elemento = ds_priority_delete_max(power_up);
¿Y si tenemos varios valores con la misma prioridad? Pues entonces si que importa el orden de inserción, aunque siempre eliminará uno.
Lo mismo para eliminar, y obtener, el elemento menos prioritario
elemento = ds_priority_delete_min(power_up);
También podemos eliminar un elemento cualquiera
ds_priority_delete_value(power_up, "SETA");
También es posible acceder a esos valores sin eliminarlos de la estructura de datos. Para acceder al más prioritario
ds_priority_find_max(power_up);
al menos prioritario
ds_priority_find_min(power_up);
También podemos saber que prioridad tiene un elemento concreto
num_priority = ds_priority_find_priority(power_up, "SETA");
Y hasta aquí todas las funciones para gestionar esta estructura de datos. También tenemos las funciones comunes entre ellos, para copiar una cola a otra variable con ds_priority_copy()
, y para leer y escribir en un fichero con ds_priority_read()
y ds_priority_write()
.
Resumen final
Las colas con prioridad pueden ser las estructuras de datos más raras a la hora de usarlas, pero conocerlas nos puede ayudar a la hora de decidir como usarlas en nuestros juegos. A veces por desconocimiento podríamos usar una array y hacer programación extra que, usando este tipo de datos, lo podríamos hacer mucho más fácil.
Seguramente no es así pero ¿has usado alguna vez una cola con prioridad?