Artesania del control de exploradores en juegos de estrategia.

No comments »

Una de las tareas principales que un jugador o un sistema de estrategia en tiempo real debe llevar a cabo es la de conocer su entorno para poder plantear un desarrollo adecuado.

En este artículo vamos a ver en detalle algunos de los conceptos que tienen que ver con el descubrimiento y la observación del terreno incluyendo las tácticas de exploración más comunes. Dado que trataremos la mayor parte de las técnicas necesarias, empezamos a nivel conceptual por aquellas que tienen lugar primero: las de scouting.

Explorador Nathan Drake

En primer lugar tendremos que decidir si queremos que nuestro sistema de inteligencia artificial sea piratilla y trabaje basado en trampas o si por el contrario queremos desarrollar un sistema realista. De antemano ya os digo que muchos de los juegos que se comercializan actualmente hacen trampas y saben exactamente a donde dirigirse, tanto en materia de recursos como en posiciones de enemigos. Muchos hacen la trampa de la sorpresa, hasta que no los atacas parece que desconocen tu posición, sin embargo podeis hacer la prueba y ver en cuantos juegos de RTS (real time strategy) podeis permanecer ‘ocultos’ despues de un ataque por sorpresa. Generalmente recibireis un generoso contraataque si la máquina está en condiciones.

De cualquier lugar aqui apostamos por crear sistemas realistas, entendiendo por realistas los que disponen de la información que les proporcionan sus unidades y no de otros parámetros externos al juego. Las dos opciones son válidas puesto que como es lógico, en ocasiones la rigurosidad de los sistemas viene determinada de forma inversamente proporcional al grado de presión que ejerza el game designer. Nosotros nos centraremos ahora en la solución en la que vale la pena discutir el tema, sin trucos.

> Scouting basics.

Sin entrar en detalle de los algoritmos que vayamos a emplear a nivel interno (pathfinding, comandantes, autómatas … etc), trataremos el tema desde un punto de vista mayormente teórico. La única preocupación que debemos tener es la de generar puntos del mapa bajo determinadas trayectorias.

Scout Age of Empires

El primer elemento a identificar es la unidad de scout. De entre todas las unidades disponibles en el ejercito, lo más probable es que una de ellas sea la más adecuada por su ligereza, su bajo coste, su resistencia moderada y rango de visión. Esta o estas serán las unidades de exploración.

> Objetivos

Lo que buscamos con el explorador no es solo descubrir el terreno sino mantenerlo libre de enemigos y disponer de información precisa de lo que pasa. Se identifican algunos de las metas a alcanzar.

>> Encontrar recursos
>> Identificar unidades enemigas en el territorio propio y en el enemigo
>> Encontrar la posición de la base del enemigo
>> Marcar puntos de interés (pasos elevados, cuellos de botella, etc.)
>> Táctica del oponente. Preveer movimientos y ataques en camino.
>> Llevar a cabo ataques estratégicos.

Algunos de estos objetivos son únicos en el tiempo puesto que el mapa no variará respecto al tiempo. Otros requerirán de un monitorizado constante y de ajustes continuos.

De cualquier modo no se presenta como una solución absoluta sino como un primer enfoque más profundo de lo que es necesario en materia de exploración y sobre el que añadir nuevas tácticas y varias objetivos.

> Fase I. La puesta en marcha

Nos ponemos en la piel de un jugador de RTS y vamos a poner de ejemplo una partida de Age of Empires. En ella nuestro explorador es un jinete a caballo rápido y con puntos de defensa y ataque limitados.

Nuestros objetivos principales son, identificar fuentes cercanas de abastecimiento y descubrimiento radial del entorno. Fijaremos con punto inicial de referencia el de la base propia y generaremos trayectorias radiales de diámetro creciente hasta un cierto punto que fijaremos en función del mapa.

Age of Empires fog of war

Una vez identificadas las fuentes de suministros mínimas fijadas desde el planificador o el comandante de exploración segun el control de comportamiento que llevemos, pasaremos a seguir con las tácticas de medio juego.

> Fase II. El desarrollo de la partida.

Una vez hemos identificado las fuentes de recursos y descubierto el entorno más próximo. El siguiente nivel es ampliar el rango de exploración para detectar el resto de elementos relevantes: recursos, enemigos y puntos de interés.

Seguiremos una estrategia radial del mismo modo. Iremos marcando posiciones al explorador siguiendo un radio creciente y marcaremos cada fuente de recursos encontrada y la posición de los enemigos así como la de su base en caso de encontrarla.

Foto base enemiga

Los puntos de interés son zonas elevadas y pasos estrechos. Estos los conoceremos por nuestro grafo de claridad que se ha visto en detalle anteriormente. Como resumen, llevamos un estado de los espacios de cada posición del mapa al obstáculo más cercano, lo que nos permite saber si determinadas unidades pasarán o guiar los algoritmos de pathfinding. Nos interesa por tanto los puntos en los que pasan pocas y los marcaremos como cuellos de botella. En estrategia de combate que veremos más adelante veremos como nos pueden ser de ayuda.

En lo referente a las bases enemigas, una vez localizadas intentaremos dirigir la búsqueda o exploración hacia áreas alejadas con la finalidad de reducir la probabilidad de que el scout reciba un ataque.

Una vez localizado el enemigo y algunos grupos de recursos adicionales, la exploración toma otro matiz.

>Fase III. La fase de convergencia

Esta fase se alcanza una vez conocemos suficiente sobre el entorno estático (para simplificar recursos, enemigo y puntos de interés) Una vez disponemos de esa información los exploradores pasan a tener otro cometido, el de estudiar el avance del enemigo y el de garantizar la integridad del territoriio. Eventualmente pueden colaborar en la estrategia de combate pero eso lo veremos más adelante. No tengas prisa pequeño saltamontes, todo lo bueno llega.

–> El Patrullado es una de las tareas principales de los exploradores en esta fase de desarrollo del juego. No podemos simplemente asignar y distribuir los exploradores por el territorio sin más y substituirlos cada vez que son eliminados ya que esto representaria un comportamiento predecible y el usuario podría detectar un comportamiento repetitivo y por lo tant aburrido en muy poco tiempo.

La estrategia en este caso varía. A priori se deben tener en cuenta dos temas básicos dentro del patrullado. El primero de ellos es  el posicionamiento de los exploradores. En este caso la distribución óptima vuelve a ser radial, sin embargo el ángulo de colocación de los exploradores no tiene porqué ser el de máxima difusión, de otro modo, el usuario puede detectarlo y acabar regularmente con todos ellos. Es más apropiado generalmente distribuirlos de forma semialeatoria en un rango que varie de la máxima difusión en pequeños porcentajes. Por ejemplo, si desde la estrategia general se asignan recursos como para disponer de 6 exploradores, la máxima difusión suponiendo que estamos emplazados en el centro inferior y tomando como ángulo 0 la linea inferior que delimita la pantalla, colocariamos de forma de máxima difusión los 6 exploradores para abarcar un sector de 180 grados por lo que estarán en los ángulos 0, 30, 60, 90, 120, 150 y 180 respectivamente con un radio de patrullado determinado (pongamos 20 grados). Una posible colocación y comportamiento sería inicialmente definir un radio de patrullado aleatorio y una colocación +- un 20%, de este modo la distribución es menos predecible. La distancia del radio a la base será definida de forma dinámica calculando la distancia al edificio más lejano como medida de simplificación y añadiendo un determinado factor. Soluciones más complejas darán lugar a una mejor distribución y adaptación al terreo, utilizando mapas de influencia por ejemplo describiremos con mayor precisión el area en la que debemos situar los exploradores. De cualquier modo se trata de tener en cuenta estos conceptos cuando abordemos un trabajo del estilo.

–>Otro de los temas a tener en cuenta es el de la evasión. Una vez localizado al enemigo debemos iniciar la táctica de evasión y comunicar al comandante el avistamiento. Si utilizamos cualquier otra forma de control de comportamiento deberemos igualmente incluir una función
que comunique el evento. POdemos o bien iniciar la evasión simple, vuelta a la base y espera de un tiempo concreto o bien iniciar el seguimiento desde la distancia del enemigo localizando el enemigo más cercano y manteniendo una distancia prudencial. Esta última estrategia generalmente dará como lugar la eliminación del explorador pero aportará más información sobre las intenciones del enemigo. En cualquuier caso el explorador
debe estar monitorizado.

–>La inclusión de tácticas de comando en el area enemiga. Estas maniobras irán destinadas a descubrir los avances y las posiciones del enemigo por lo que iniciaremos tareas de acercamiento progresivo al area del enemigo alternando maniobras de exploración con maniobras de evasión. Esta será una táctica arriesgada que dará lugar en muchas ocasiones a la eliminación del scout. En este aspecto se asumen los costes en favor de un bien mayor
ya que con la información obtenida podemos informar a los comandantes de combate, constructor y científico acerca de los progresos y que ellos actuen en consecuencia. Cualquier otro enfoque dará lugar a corregir de algun modo las construcciones, la creación de unidades y el desarrollo científico para el correcto uso de la información que hemos obtenido con el scout.

–>La maniobra Tora Tora Tora! Es la que pretende acercarse al corazón del enemigo en una maniobra kamikace que da lugar a la eliminación prácticamente segura del scout pero aporta mucha información acerca del grado de desarrollo del enemigo. Muchos de los jugones aqui presentes habrán hecho sacrificios similares para ver como va el tema en casa del malo. El caso es que aqui no podemos guardar antes de liarla y volver a cargar una vez sabemos donde estan las defensas y los edificios más importantes.

Hay más elementos tácticos que son importantes en lo referente a esta fase del juego pero para empezar y tener un buen conocimiento de los elementos que
se tienen en cuenta en el juego ya está muy pero que muy bien. Desarrollar a nivel técnico lo que aqui se escribe a nivel conceptual representa un buen
reto para cualquier desarrollador de sistemas de IA por lo que tenemos trabajo que hacer.

> Conceptos matemáticos involucrados.

Hemos hablado aqui bastante de generar trayectorias radiales sobre las que ir explorando o  colocando a los exploradores pero que demonios es una trayectoria radial y cómo la calculo? De eso nos vamos a encargar ahora. Porque aqui y no arriba cuando las necesitabamos? POrque una vez sabemos para que las vamos a utilizar nos podemos poner manos a la obra mucho más agusto.

En primer lugar, una trayectoria radial se refiere al hecho de que un determinado elemento sigue un camino definido en base a un punto que representa el centro de un circulo y un radio concreto de distancia a ese círculo. Pongamos que si quisieramos mover una unidad de forma radial por una rueda de bicicleta, dariamos puntos muestreados que coincidirian en la cubierta. Más sencillo, dibuja un círculo y las unidades se moverán por un sector determinado de ese círculo.

El centro de la trayectoria es generalmente un punto de una malla, no bajamos a nivel de pixel para no complicar nuestros algoritmos
de pathfinding (si esto lo llevas verde dale un vistazo a los artículos de pathfinding, tenemos para todos los públicos). Por lo tanto
tendremos un punto X y otro Y que definen la posición en X y en Y respectivamente. Los llamaremos Xc e Yc a partir de ahora.

Otro elemento será el radio R que definirá la distancia a la que deberán moverse o posicionarse las unidades. Por supuesto que cuando le pasemos las posiciones finales al algoritmo de pathfinding, el mismo buscará las trayectorias más adecuadas. Si queremos un movimiento
claramente radial deberemos obtener muchas muestras y pasarselas a nuestro pathfinder. De cualquier modo no te preocupes de esto porque lo definiremos como Nm (número de muestras).

Otro de los elementos a tener en cuenta son los grados de posicionamiento (Gp). Con este elemento posicionamos en la circunferencia el elemento. Una unidad situada a 10 pasos de radio y a 90 grados se posicionará enfrente. A 0 grados se moverá en linea recta hasta la derecha y a 180 se moverá a la izquierda.

Teniendo todos los elementos ahora, como calculamos la posición X e Y definitiva. Mucho más sencillo de lo que puede parecer a priori, utilizando senos para la componente vertical y cosenos para la horizontal. Dado que nuestra posición en el mapa será arbitraria, simplificaremos suponiendo que al empezar es lógico explorar toda la circumferencia de la base, sin embargo, algoritmos sencillos pueden estimar y determinar que rango de grados deben ser explorados en casos como por ejemplo si aparecemos en una esquina del mapa. Vamos por partes.

Trayectoria radial

En la imagen vemos desde un pun to C los puntos abarcables con un determinado radio.

–> Primero calculamos la posición X e Y donde debe ir la unidad para un grado concreto y un radio determinado. El valor en X será el coseno del ángulo por el radio y el de Y el seno del mismo ángulo por el radio.

Senos cosenos trayectoria radial

Seno coseno
–> Segundo calculamos la correspondencia a nuestra malla de los valores obtenidos. Sabiendo el tamaño en X y en Y de nuestra malla (no siempre igual), el cálculo del elemento al que tenemos que ir se obtendrá dividiendo el valor obtenido por el propio tamaño correspondiente. De este modo si habiamos obtenido en el primer paso
X = 2.2 e Y = 4.6 y tenemos tamaños de malla igual a 1 en X e Y, la posición pasará a ser (x,y) = 2, 4. Y ya se la podemos pasar al algoritmo de pathfinding que para ser eficiente trabajará con la malla.

–> Tercero. Vistas las posiciones absolutas planteamos un muestreo desde un grado inicial de la circumferencia a un grado final de la misma.

Teniendo el parámetro número de muestras (Nm) calcularemos los incrementos de grado que le vamos a pasar a nuestra función de cálculo de posiciones construida a partir de los pasos 1 y 2 asi:

incGrados = (GradoFinal – GradoInicial) / Nm;

Una vez tenemos el incremento de grados para cada paso del algoritmo iteramos.

iteracion = 1;
Desde 1 Para cada Nm
(x, y) =CalcularPosición(GradoInicial + (incGrados*iteracion);
pathfinding(x, y);
iteración ++;
Final

Es decir, calculamos, movemos y repetimos el proceso.

> El enfoque hacia objetivos

Se ha tratado un enfoque basado en fases de juego en los que pasar de una fase a otra dependía de la consecución de diferentes metas como encontrar al enemigo o descubrir una parte del terreno. El enfoque hacia objetivos varía respecto a la propuesta anterior por el hecho de que las unidades scout se generan y se comportan exclusivamente para cumplir determinados objetivos.

La diferencia respecto a la anterior propuesta es sutil pero a nivel interno el cambio es más importante. Vemos un ejemplo que lo dejará más claro. Nuestro procedimiento será ahora crear tantos exploradores como sean posibles, encontrar N fuentes de recursos. Una vez encontrados revelar un porcentaje concreto del mapa. Una vez hecho esto buscar al enemigo. Cuando esté localizado determinar 3 puntos de interés, sino pasa un tiempo determinado damos por supuesto que no hay más y seguimos con el revelado del mapa. Hecho esto protegemos y patrullamos la base. La diferencia radica en el enfoque, mientras que en el modelo anterior se va trabajando segun la fase, aqui se motiva este cambio de forma progresiva y secuencial en función del objetivo. En el modelo anterior se cambiará de fase cuando se completen unos determinados puntos, en este último seremos nosotros los que busquemos la consecución inmediata de estos aunque esto no sea la estrategia más adecuada a largo y corto plazo.

> Respuesta a inconvenientes.

–> Es atacado. El scout es detectado y está siendo atacado. En este caso se puede dirigir
a la base o considerar el movimiento alejandonos de ella. En una primera valoración puede parecer lógico llevarlo al abrigo de nuestras unidades, sin embargo puede que no nos sea beneficioso guiar al enemigo a nuestra posición.

Run for your life

Conceptos más laboriosos son los que involucran bases de apoyo secundarias que pueden proteger de forma eventual problemas de este tipo.

–> Encuentra un grupo de aldeanos

En este caso existe la posibilidad de iniciar maniobras de hostigamiento. Mientras el enemigo no ponga vigilancia, será posible golpear y huir a los aldeanos provocando molestias y pérdidas al jugador. Generalmente será contrarrestado con un destacamento de protección. Hecho que también puede ser aprovechado para atacar la base en extremos opuestos, a sabiendas de que hay unidades alejadas que antes defendian y ahora no.

> Pincelada de estrategia de combate usando exploradores.

Como veremos en artículos de estrategia de combate. Una de las tácticas más efectivas es la de la distracción. Desde que los humanos peleábamos con garrote las tácticas de distracción han sido extremadamente útiles. En este caso se trata de mandar al scout a una zona de minado de recursos del enemigo lo más alejada posible y de forma casi simultanea enviar tropas de ataque por el lateral contrario de la base enemiga. Las inteligencias artificiales en su práctica totalidad enviarán unidades y desplazarán algunas de las producidas. Puede ser efectiva o no, en cualquier caso si los aldeanos no se protegen serán menguados y su ritmo de producción caerá, lo que ya es positivo. Si defienden correctamente la protección en la zona se verá disminuida por lo que podremos aprovechar el ataque con más garantías.

Esto es estrategia de combate y de la complejidad y riqueza de las mismas haremos disfrutar y sufrir al jugador dándole un buen nivel al juego.

> En resumen

Hemos visto los elementos más importantes a tener en cuenta en materia de exploración para tener una inteligencia
artificial competitiva. Se han tenido en cuenta los conceptos matemáticos para generar una trayectoria radial respecto
a un punto concreto y definir el grado de precisión a pasarle al pathfinder. Finalmente se han tratado algunos modelos
más sencillos y se ha adelantado un pequeño concepto de combate. Ahora toca ponerlos en práctica.

Algunos de los juegos actuales incluyen unidades espia. La función de éstos es básicamente la del explorador con funcionalidad
añadida como el sabotaje o la contaminación de edificios. Muchas de los conceptos aqui detallados son aplicables a la
unidad espia.

Suerte y ánimo con ello.

El patrón Decorador para añadir detalles a los elementos del juego

3 comments »

Aunque no es tan interesante como el campo de batalla, un Guerrero Informático debe conocer
sus herramientas de combate y dominarlas para poder aplicarlas en un entorno hostil cuando
la cosa se ponga fea. Una de ellas es el Patrón Ninja Decorator (Decorator Pattern). Vamos
a verlo en más detalle.

Muchas veces os va a tocar añadir funcionalidad al juego que no estaba prevista. Un dia
(o varios) os vendrá el game designer, os llevará a un cuarto frio sin casi iluminación,
os ofrecerá un cafe y os dirá: “Pepito (pon aqui tu nombre), tenemos que hablar. Vamos
a tener que añadir/modificar/eliminar una serie de elementos del juego que no estaban
previstos. Sin embargo, los chicos de márqueting opinan que será muy beneficioso.Como
sabrás, tenemos unos tiempos de entrega muy ajustados por lo que vamos a tener que arrimar
el hombro para que todo salga como estaba previsto.” Esto en términos generales y como
tradución menos diplomática como: “Vas a currar nene!”. Otro escenario posible y menos
dramático será que despertareis en medio de la noche con sudores frios y gritando
“Lo tengo! El personaje tendrá habilidades especiales y cada habilidad tendrá diferentes
grados de efectividad”. Lo apuntareis, seguireis durmiendo y a la mañana siguiente os pondreis
manos a la obra. Empezaries a mirar código y direis ¿donde meto esto sin poner todo el diseño
patas arriba?. Y será entonces cuando os acordeis de este humilde post, “Como se llamaba el rollo
aquel que vi en Starco … Patrón decorador!!”.

Patron Decorator

Esta es una herramienta que nos servirá para muchas soluciones en las que es necesario dejar abierta
la inclusión de características, elementos, particularidades … etc en alguna de las clases o
entidades de nuestro sistema. En general cuando queremos dar pinceladas sobre alguno de nuestros elementos
será muy útil este patrón. Un ejemplo es el que, en un juego de rol, teniendo nuestro personaje,
queremos añadir una serie de habilidades donde cada habilidad puede tener un diferente grado de efectividad
respecto a personajes con otras habilidades.

> Elementos del patrón Decorator.

Los elementos del patrón decorador son generalmente 3.
–> Componente Concreto. La clase que define nuestra entidad inicial (un personaje, una roca, un enemigo…etc)
–> Componente Decorador. La clase o clases que definen las nuevas pinceladas (comportamientos, detalles, habilidades…etc)
–> Componente Genérico. Esta clase es la que generaliza los componentes y permite al crear una entidad, disponer
tanto de la clase inicial (El componente concreto) como de las clases decoradoras. Una clase intermedia a modo de
aglutinador de Decoraciones es ‘decorator’ que organiza todos las nuevas pinceladas

Patron Decorador

Como se aprecia en la foto la estructura es muy clara y permite añadir o quitar componentes. ¿QUe diferencia esto de la
jerarquía clásica de clases con mecanismos de herencia? Muy sencillo, que de este modo las decoraciones añadidas son independientes y pueden aplicarse a un objeto concreto. No dependen de una jerarquía sino que pueden aplicarse o no dependiendo de las necesidades del programador y crear nuevos no implica añadir el comportamiento o la ‘decoración’ en todos los nodos o partes de la jerarquía donde deberían figurar. Siempre que puede aplicarse un diseño jerárquico y por herencia es recomendable, pero en la mayoría de los casos pequeños (o grandes) detalles serán más rápidos y sencillos de añadir de esta forma.

Nuestra forma de trabajo será. Necesito un nuevo elemento que complemente a un objeto determinado (pongamos un personaje). Bien, añado una nueva clase de decoración y lo complemento. Si me conviene crear instancias de ese objeto decoradas las crearé y sino seguiré utilizando el objeto con las características iniciales.

> El ejemplo típico. Una ventana de Windows.

Para dejar claros los conceptos de decorador se utiliza generalmente uno de los ejemplos más visuales
y a los que más acostumbrados estamos: las ventanas de windows (léase linux o cualquier otro si procede). Vemos en la
imagen inferior la estructura que tendrá un componente ventana creado de forma que se utilice el patrón decorator.

Ejemplo Patron Decorador

No vas a necesitar mucho que leer despues de ver esta imagen. Como se puede apreciar. La clase Window es el componente genérico, la clase simpleWindow define lo básico de una ventana y la clase WindowDecorator engloba las diferentes instancia de  ventana que podemos encontrar. VerticalScrollBars y HorizontalScrollBarDecorator son pinceladas sobre las diferentes ventanas simples.

> Código de ejemplo para el patrón decorador.

El código asociado seria este:

// the Window interface
interface Window {
    public void draw(); // draws the Window
    public String getDescription(); // returns a description of the Window
}

// implementation of a simple Window without any scrollbars
class SimpleWindow implements Window {
    public void draw() {
        // draw window
    }

    public String getDescription() {
        return "simple window";
    }
}

Las clases de a continuación contienen los decoradores de todas las clases Window ncluyendo los propios decoradores.

// abstract decorator class - note that it implements Window
abstract class WindowDecorator implements Window {
    protected Window decoratedWindow; // the Window being decorated

    public WindowDecorator (Window decoratedWindow) {
        this.decoratedWindow = decoratedWindow;
    }
}

// the first concrete decorator which adds vertical scrollbar functionality
class VerticalScrollBarDecorator extends WindowDecorator {
    public VerticalScrollBarDecorator (Window decoratedWindow) {
        super(decoratedWindow);
    }

    public void draw() {
        drawVerticalScrollBar();
        decoratedWindow.draw();
    }

    private void drawVerticalScrollBar() {
        // draw the vertical scrollbar
    }

    public String getDescription() {
        return decoratedWindow.getDescription() + ", including vertical scrollbars";
    }
}

// the second concrete decorator which adds horizontal scrollbar functionality
class HorizontalScrollBarDecorator extends WindowDecorator {
    public HorizontalScrollBarDecorator (Window decoratedWindow) {
        super(decoratedWindow);
    }

    public void draw() {
        drawHorizontalScrollBar();
        decoratedWindow.draw();
    }

    private void drawHorizontalScrollBar() {
        // draw the horizontal scrollbar
    }

    public String getDescription() {
        return decoratedWindow.getDescription() + ", including horizontal scrollbars";
    }
}

Un ejemplo de programa de test quecrea una instancia de decorador completamente decorada con scrolls verticales y horizontales.

public class DecoratedWindowTest {
    public static void main(String[] args) {
        // create a decorated Window with horizontal and vertical scrollbars
        Window decoratedWindow = new HorizontalScrollBarDecorator (
                new VerticalScrollBarDecorator(new SimpleWindow()));

        // print the Window's description
        System.out.println(decoratedWindow.getDescription());
    }
}

Muy conciso. Más información en el video de a continuación:

> En Resumen

Se ha visto la utilidad del patrón Decorator para el uso en sistemas de entretenimiento. Hemos ganado una nueva herramienta que puede ser útil en cualquier contexto en el que tengamos que ‘decorar’ entidades de nuestro sistema. Este mecanismo permite aprovechar las diferentes pinceladas sobre un mismo objeto de forma que podemos utilizarlas cuando nos sea conveniente sin ceñirnos a una jerarquía concreta o a los mecanismos de herencia tradicionales.

Disfrutadlo.

Sun Tzu 2.0 El Arte de la guerra en los juegos de Estrategia

No comments »

Como creadores de inteligencia artificial orientada a los juegos de estrategia, debereis ser conocedores de las más antiguas técnicas estratégicas. Para ello vamos a echar mano de uno de los mejores generales y estrategas del pasado, Sun Tzu. El aspirante a Samurai Informático deberá conocer las enseñanzas del maestro a través de su célebre libro ‘El arte de la Guerra’.

El Maestro Sun Tzu dijo: “Un ejército victorioso gana primero y entabla la batalla después; un ejército derrotado lucha primero e intenta obtener la victoria después.”. Aqui veremos como crearlo.

PocketSunTzu

En la mayoría de juegos de estrategia estaremos condicionados a conseguir determinados objetivos que se verán por regla general amenazados por uno o varios enemigos de diferente índole. En este artículo vamos a ver en detalle que conceptos intervienen en el enfoque estratégico y táctico de una partida genérica de un juego de estrategia en tiempo real. Muchos de estos conceptos son extrapolables a otro tipo de juegos como los basados en turnos o los que
están orientados al crecimiento del jugador sin oponentes. Sin embargo, serán muy útiles especialmente en los RTS.
Nuestro objetivo como creadores de inteligencia artificial es claro, crear una máquina mortífera capaz de destruir al jugador oponente, ya sea humano u otra máquina. Por otro lado tenemos que garantizar la posibilidad de dominar a la bestia, haciendo que sea todo lo efectiva que queramos, es decir, permitir que diferentes niveles de jugador puedan enfrentarse.

Detallaremos los conceptos que son necesarios para modelar nuestro propio Gengis Kan, tu Napoleon o tu Jerjes, cada uno con sus gustos. Una vez hayamos terminado aqui sereis especialistas estrategas en lo que al mundo virtual se refiere.

> Empezamos.

Un buen sistema de estrategia se focalizará en todos los elementos que toman parte en el desarrollo del juego. Tendremos en cuenta de este modo, tanto recursos como unidades, tecnología o terreno.

En primer lugar hay que marcar el camino que queremos seguir en materia algoritmica. Poemos elegir principalmentedos opciones cada una de ellas apropiada para cada caso. La primera de ellas es usar estrategias preconcebidas.
Esta modalidad implica que tenemos que dotar de un conocimiento previo a nuestro sistema para que responda de forma correcta y se oriente a llevar a cabo una serie de soluciones. Un ejemplo de este modelo será el desarrollo clásico de una partida de estrategia: recoletar, fortificarse, contruir ejército y atacar/defenderse. A un nivel más detallado podemos incluir reglas concretas como favorecer la ocupación de lugares altos o crear una determinada proporción de unidades de diferentes tipos. Estas etrategias vendrán por lo tanto muy ajustadas al entorno en el que estamos creando la inteligencia artificial y serán difícilmente rehusables en otros.

La segunda de nuestras opciones será más compleja e implicará técnicas de Ninja Informático como algoritmos de modelado del jugador mediante machine Learning. Estas soluciones suelen requerir algunas partidas para ajustar los parámetros principales y se adaptan al nivel del jugador. Sin embargo, son más complejas de diseñar y adaptar por lo que en la mayoría de las ocasiones se opta por definir un comportamiento concreto como el fijado en el primer punto
y se crea un autómata de estados finito jerárquico para controlarlo. De cualquier modo, una vez dominados los algoritmos de aprendizaje, pueden utilizarse con mayor sencillez para tipos de juego similares.

Anibal-Alpes

Una vez escogido el modo en el que vamos a llevar a cabo nuestro desarrollo, deberemos profundizar en el uso de estratagemas más propias de táctica y estrategia general que de cuestiones tecnológicas. Vamos a ver ahora en qué áreas y qué tiposd de estrategias vamos a llevar a cabo en cada una.

> Areas a tener en cuenta

Cada área de las que tendremos en cuenta a continuación suele presentarse casi de forma obligatoria en los juegos de estrategia en tiempo real. Añadir complejidad en el comportamiento de nuestra sistema en las mismas hará que el usuario tenga una mejor
experiencia de juego y se le presente una inteligencia artificial no encorsetada en la misma reacción. Esto es lo que realmente añade riqueza a la inteligencia artificial ya que conforme las estratgemas y mecanismos aumentan, más dificil es para el jugador preveer el comportamiento. No se trata de hacer que el sistema sea invencible sino de que sorprenda al usuario. Una regla de
oro en el desarrollo de sistemas de inteligencia artificial para juegos es que la IA nunca debe ser más ‘lista’ que el jugador pero si tanto o más pícara por caracterizarla con una palabra políticamente correcta. Se me ocurren otras palabras para describir el comportamiento que debe tener la IA con más exactitud pero no las diré aqui. Queda a la imaginación de cada uno. Piensa mal y acertarás :p

Vamos a ir viendo en detalle las áreas que siguen a continuación. De la correcta creación y desempeño de cada una de estas áreas dependerá la calidad de nuestro ‘Warlord’ Artificial.

>Inteligencia artificial para la recolección
>Inteligencia artificial para la construcción.
>Inteligencia artificial para la tecnología.
>Inteligencia artificial para la exploración.
>Inteligencia artificial para el ataque.
>Inteligencia artificial para la defensa.

Cada una de ellas es una pieza clave en el correcto desarrollo del juego, Mejorarlas y añadiendo complejidad respetando la regla de oro anterior es hacer que nuestro sistema sea cada vez más rico e interesante. Las veremos en detalle una a una.

Ahora, el general que gana una batalla hace muchos cálculos en su cuartel, considera muchos factores antes de que ésta se libre. El general que pierde una batalla hace pocos cálculos en su cuartel, considera pocos factores antes de que ésta se libre. Muchos cálculos llevan a la victoria, pocos cálculos llevan a la derrota.

> Dificultad exacta

Un factor importante que se ha comentado anteriormente es el de limitar las capacidades de nuestro sistema de IA. Es necesario que de un modo u otro, el usuario pueda desarrollar los objetivos sin desesperarse en exceso. Si bien es bueno que nuestro sistema plantee un reto considerable, no es preferible que el usuario acabe lanzando la consola o el pc por la ventana.

Para definir y acotar el nivel de dificultad tenemos infinidad de mecanismos, sin embargo, unos de los más empleados son los que se comentan a continuación. En primer lugar, al no disponer de un nivel de proceso concreto como el aplicado en algoritmos de teoría de juegos como el minimax, no es sencillo definir de forma numérica el desempeño del algoritmo. Lo que haremos en este caso es relajar los objetivos. Con relajar se entiende ralentizar la obtención de elementos (recursos, tecnologías, unidades), disminuir el grado de desempeño de las unidades y bajar el nivel de coherencia de las acciones (gastos en tecnologías que no ofrecen sinergias, producción de determinados tipos de unidades en exceso o insuficientes…etc). Esto será muy sencillo si definimos los objetivos de forma que en cada estado del juego pueda medirse el grado de consecución de los mismos.

Este es solo un enfoque del estudio del ajuste de la dificultad a los diferentes niveles de juego previstos. Otro enfoque se basa en dificultar el desempeño en las diferentes áreas que hemos visto anteriormente haciendolas más ineficientes. En esta variante intentaremos definir nuestros algoritmos internos (pathfinding, distribución, scouting…etc) de forma que podamos parametrizar lo máximo posible su grado de eficiencia. De este modo creariamos algoritmos flexibles en desempeño, en el caso de los algoritmos de pathfinding la eficiencia máxima corresponde al mínimo camino entre la fuente y el destino. En el caso de un algoritmo de scouting la eficiencia máxima puede darse cuando se busca magnificar el área descubierta con la máxima velocidad.

Visto el ajuste de dificultad por relajación de los objetivos y el ajuste por areas, vamos a ver un concepto diferente, el modelado del jugador.

> Modelar al jugador

Una vez que planteamos el ajuste de la dificultad de forma interna en el juego, podemos hacer dos cosas. O bien permitir que el usuario ajuste la dificultad y a partir de niveles concretos (fácil, medio, dificil…) traduciendo internamente a las diferentes áreas u objetivos.
O bien podemos modelar nosotros mismos a partir del desempeño del jugador y hacer un autoajuste. Existe mucha documentación referente al modelado del jugador, por lo que este tema puede verse con mucho detalle.

Un ejemplo de modelado sería el siguiente. En primer lugar estableceremos una correspondencia entre los elementos que intervienen en el juego
y la dificultad que esto plantea al usuario a nivel medio. Una vez disponemos de esta información el monitorizado será una constante durante el
desarrollo de la partia. Cada cierto tiempo austaremos nuestros valores internos mediante los mecanismos de ajuste de dificultad vistos anteriormente y
en función de los parámetros observados en el usuario. Esto, sin embargo plantea un problema desde el punto de vista en el que necesitamos valores
del usuario a los que teóricamente no tenemos acceso como jugadores y por esto desde el punto de vista de la inteligencia artifical estamos haciendo
trampas. Esto es más que usual en el desarrollo de juegos comerciales, sin embargo, aqui estamos buscando soluciones que impliquen una inteligencia
artificial ‘real’.

una solución al problema anterior es echar mano de algoritmos de aprendizaje. En este caso, los algoritmos irán tomando decisiones y observando la
recompensa o la pérdida que estas decisiones le reportan ajustando los diferentes parámetros. Para ello, será necesario interactuar con el usuario
inicialmente sin conocer sus capacidades y las primeras partidas pueden ser un tanto desastrosas. Solo los Grandes Maestros Ninjas Informáticos se
atreven a ofrecer soluciones comerciales de este tipo. Uno de los pocos ejemplos es el Black And White de LionHead Studios que apostó por algoritmos de este
tipo y salió más que bien parado.

Black and White IA

Para los más interesados podeis profundizar en temas de redes neuronales, algoritmos de computación evolutiva y machine learning en general. De cualquier
modo el tema es tan extenso como interesante por lo que no perdais ni un minuto. Yo diría que entre todos los conceptos de computación, los que están
en estas áreas son los que me han resultado más interesantes.

> Trampas de los creadores de inteligencia artificial

Para terminar el tema de la estrategia es necesario y más que recomendable echar un vistazo a los pequeños trucos de Ninja Informático que utilizan los creadores de inteligencia artificial orientada a los juegos de estrategia. Puede parecer que esto es un insulto a la integridad de vuestro sistema de IA y a vuestras capacidades, sin embargo, cuando los tiempos de entrega aprietan y se hace necesario disponer de un sistema competitivo, os acordareis de esta sección.

Ninja Informatico

La primera de las trampas es jugar con los recursos. La cantidad de recursos y el tipo de los mismos que tu minas por unidad de tiempo con una unidad determinada no siempre tiene que ser igual a la que tiene vuestro oponente artificial. Esto se llama generalmente ‘dopar’ a las unidades.

Otra de las trampas más utilizadas es el monitorizado de la creación de unidades de los oponentes. El sistema observa los tipos de Unidades que se están creando y construye las más apropiadas para combatir el ejército enemigo. La velocidad de construcción y de minado cuando es posible tambien se modifica, haciendo que el desarrollo sea más rápido. El resto de unidades estar tambien dopadas.

Otro truco es modificar los costes de las unidades y del resto de elementos del juego. Con lo que tu obtienes X, el sistema de inteligencia artificial puede obtener 2X, ¿fácil no?.

Uno de los más recurridos es el de la omnipresencia (Disabled fog of war), mediante el que el oponente máquina puede ‘ver’ unidades, edificios y demás elementos en cada momento. Con esto puede percibir y prepararse para ataques o incluso fortificarse para evitar asaltos.

Independientemente de la estrategia de desarrollo tecnológico que se haya establecido, algunos sistemas de inteligencia artificial actualizan la tecnología para que esté acorde con la del jugador, teniendo mayor ventaja y estando mejor preparado frente a los ataques del mismo.

Parecido al anterior sería el conocimiento de los detalles del jugador. Se sabe en todo momento los recursos, las unidades, los edificios y las tecnologías de modo que se trabaja en consecuencia para neutralizar los avances y se inyectan los recursos (y en ocasiones unidades) necesarios.

Si conoces a los demás y te conoces a ti mismo, ni en cien batallas correrás peligro; si no conoces a los demás, pero te conoces a ti mismo, perderás una batalla y ganarás otra; si no conoces a los demás ni te conoces a ti mismo, correrás peligro en cada batalla.

Como veis, los chicos encargados de las inteligencias de cada juego se han aplicado el cuento de 3000 años de antiguedad.

> En Resumen

Hemos visto la profundidad con la que podemos llegar a tratar un tema que aparentemente centra su complejidad en el apartado técnico y que resulta ser más conceptual que otra cosa. Se han visto las diferentes áreas que intervienen en el desarrollo sentando las bases de un estudio más profundo sobre cada área.

Se a establecido la importancia de modelar al usuario y permitir diferentes grados de dificultad. La regla más importante será en este aspecto que la IA nunca puede ser más ‘lista’ que el usuario. Aplicar técnicas de modelado del usuario puede ser muy útil aunque plantea una complejidad importante.

Finalmente hemos comprobado que cuando los tiempos de desarrollo aprietan, independientemente de lo riguroso y comprometido que sea uno con el entorno de la inteligencia artificial en el ámbito científico, las cosas tienen que salir bien y rápido. Por
esto muchos sistemas de entretenimiento recurren al uso de ciertas trampas hacia el usuario, lo que implica que no se puede considerar una inteligencia artificial ‘real’ u honesta. En un conflicto similar con parámetros realistas no tendriamos acceso a estos mecanismos.

Comparte tu conocimiento táctico tanto en este artículo general como en cada una de las áreas que vamos a tocar.

Que lo disfrutes!

Arboles de Comportamiento (Behaviour Trees) para gestionar comportamientos.

2 comments »

Este es el tercer artículo que profundiza sobre las técnicas que utilizan los
programadores de inteligencia artificial para desarrollar comportamientos que
requieren una complejidad importante. Estos son los árboles de comportamiento.

tecnotree

Los árboles de comportamiento son estructuras que se crean con la finalidad de
organizar el comportamiento de nuestro sistema y permitir trabajar con el de
forma sencilla. Saber a que parte de nuestro código ir para modificar ciertos
comportamientos y cuando invocarla es una tarea que se hace mucho más rápido
utilizando estructuras como esta. Me voy a basar en el material de Ricard Pillosu
que ha realizado una muy buena contribución al tema.

> Donde se están utilizando

A primera vista puede parecer que es más apropiado abordar el problema de forma
rápida sin tener que estar pendiente de relaciones en árbol ni de otras estructuras.
Podemos pensar que simplemente agrupando listas de instrucciones será más sencillo
y nos ahorraremos mucho tiempo. Sin embargo, nada más lejos de la realidad ya que
conforme la dificultad del entorno crece, estos mecanismos se hacen cada vez más útiles.

Algunos de los juegos que actualmente estan en el mercado utilizando estos sistemas son el
maravilloso Grand Theft Auto, el Halo o Spore. Todos ellos se basan en el uso de estas
estructuras para gestionar comportamientos y como ya debeis saber son referentes en sus
respectivos campos. De otro modo inmediatamente debeis abandonar la lectura de este material y poneros a jugarlos como locos.

Halo Wars

Spore

GTA IV

Estos modelos se utilizan para hacer más sencilla la inclusión de nuevos comportamientos
que añadan complejidad a las respuestas de nuestros agentes inteligentes, simplificar
el trabajo de creación de los propios comportamientos, permitir el prototipado y la
puesta en escena de nuevas iteraciones y optimizar el rendimiento del sistema.

> Cómo son los árboles de comportamiento:

En estas estructuras se definen varios conceptos. El nodo, que representa cada
una de las partes del árbol y que representan cada uno de los diferentes comportamientos
junto con sus condiciones para ejecutarlos.

Ejemplo árbol de comportamiento

Como se ve en la figura superior, el árbol consta de varios elementos anidados en la estructura
que tiene como condición que cada uno de ellos puede tener varios hijos pero únicamente un padre. Es decir, la estructura crece o se mantiene a medida que descendemos, no a la inversa. Diferenciamos los nodos que están en el interior de la estructura de aquellos que son terminales llamados también nodos ‘hoja’. De este modo las ‘ramas’ serán aquellos nodos que tienen algún hijo o descendiente y las ‘hojas’ aquellos que no lo tienen.

Detalle arbol de comportamiento

Entrando más en detalle, cada nodo tendrá dos componentes inicialmente. El primero de ellos serán las  condiciones, es decir, los requisitos que deben cumplirse para que el comportamiento en cuestión se ponga en marcha. En segundo lugar las acciones, es decir, el propio comportamiento que debe realizar. Este último elemento deberá ser cuanto más abstracto mejor, ya que nos encargaremos de a nivel de código definirlo con detalle.

Por ejemplo: La condición puede ser (Si Veo_Enemigo == 1). La lista de acciones sería (Alertar,
Esconderse). A nivel interno ya definiremos que implica alertar y que esconderse.

Como medida de simplificación las acciones las realizarán generalmente los nodos ‘hoja’, aunque para comportamientos muy bien definidos de los que se puede extraer características comunes podremos lanzar acciones desde nodos ‘rama’. Por ejemplo al controlar el comportamiento de la cabeza de un soldado podemos querer tener un ’supercomportamiento’ como el parpadeo ocular, independiente del estado en el qe nos encontremos  (esto significa no que adquiera superpoderes sino que el comportamiento se manifieste de forma común a los nodos descendientes que pueda tener). Los hijos pueden ser ‘patrullando’ y ’siguiendo objetivo. En el primero estableceremos un comportamiento que haga rotar la cabeza desde el frente a -45 y 45 grados respecto al plano vertical. El segundo podemos definir que la cabeza se oriente a un determinado objetivo. De forma independiente se verá el parpadeo de los ojos que es común a los dos. Comenta el Sr. Pillosu que el 99% de los nodos con acciones serán nodos hoja por lo que será bueno tenerlo en cuenta.

Al mismo tiempo que el arbol anterior podriamos tener uno trabajando en paralelo para controlar el movimiento de la boca o incluso la expresión facial. Ya a partir de este punto empezamos a ver la utilidad que tienen y la facilidad que va a tener añadir nuevos comportamientos, tanto adicionales a los que tenemos como totalmente nuevos.

> Funcionamiento

El funcionamiento, una vez vista la estructura es sencillo. Cuando pasamos por la iteración pertinente de nuestro sistema, evaluaremos las condiciones del árbol empezando por los nodos superiores.

Arbol funcionamiento

Cuando uno de ellos cumple las condiciones, ejecutamos las acciones del nodo (si las hay) y pasamos a evaluar sus descendientes. Si alguna de las condiciones de sus hijos se cumplen en su totalidad, se continua el proceso. Acabamos de procesarlo cuando llegamos al nodo hoja. Podemos permitir que se ejecuten varios comportamientos en un mismo árbol pero será mejor que permitamos solo uno de ellos y englobemos las acciones de forma que con este funcionamiento podamos llevar a cabo la gestión de una forma correcta. De esta forma podemos controlar en cada momento que acciones se estan llevando a cabo y donde ir a buscarlas.

Una vez procesado el árbol continuamos con el siguiente y así hasta que todos los árboles de comportamiento aplicables al agente en cuestión se hayan procesado.

> Ejemplo puesto en escena

Vemos ahora un ejemplo de funcionamiento completo. Supongamos que tenemos que controlar el funcionamiento de un soldado en un entorno virtual. Para ello nos montaremos un árbol que será más o menos complejo pero que permitirá generar un comportamiento adecuado y que podremos ir aumentando en complejidad.

Despues de varias iteraciones llegamos supongamos que llegamos a esta propuesta:

Ejemplo arbol de comportamiento

Una primera respuesta sería:

Arbol de comportamiento primer ejemplo

Por otro lado en una situación diferente podria darse el comportamiento:

Ejemplo de árbol de comportamiento 2

De cualquier forma podremos cambiar cualquier condición y cualquier acción de forma ‘muy’ sencilla o mejor dicho sabremos donde hay que ir a cambiar comportamiento de forma ‘fácil’. Conforme crezca nuestro árbol ya no será tan sencillo, pero seguro que será mucho más que si utilizamos otras porpuestas que no están tan organizadas.

> En Resumen

Una vez que vamos trabajando con árboles cada vez más extensos y complejos se hace
interesante utilizar herramientas de gestión y edición de los mismos.

Es muy interesante la charla de Ricard Pillosu de Crytek que explica las virtudes de
estas estructuras de forma muy amena y desde el punto de vista de uno de los mejores
especialistas del panorama español en materia de inteligencia artificial orientada
a los sistemas de entretenimiento.

> Videos de la Charla y Bio
> Presentación PPT

En definitiva, hemos visto que es un árbol de comportamiento y cuanto mejora la organización del código. Hemos visto que no requiere una complejidad extrema para crear las estructuras necesarias y que representa una gran mejora respecto a tratar comportamientos de forma distribuida y sin orden. A partir de aqui podemos incluir parámetros estadísticos en los
nodos para añadir aleatoriedad o incluso podemos incluir aleatoriedad a nivel de acción, permitiendo que además de cambiar el comportamiento cambie la forma en que lo lleva a cabo nuestra entidad inteligente.

Arboles de comportamiento indeterministas

Planteamientos avanzados nos permitirán llevar a cabo tácticas de grupo y comportamientos más complejos donde intervienen varios agentes haciendo que la experiencia para el jugón sea mucho más divertida y le represente un mayor reto.

A partir de aqui queda en vuestras manos tener en cuenta esta esttructura, de cualquier forma siempre será una buena adquisición para vuestra caja de herramientas del Buen BricoDesarrollador de Inteligencia Artificial, fácil y sencillo amigos!

Autómatas de estados finitos Jerárquicos para el control de comportamientos (HFSM’s)

1 comment »

Una variante de los autómatas finitos son los jerárquicos. Anteriormente se ha hablado
de la versión mas simplificada de estos mecanismos. Los autómatas finitos ’simples’ cubren gran
parte de las necesidades a la hora de controlar el comportamiento de nuestros agentes inteligentes,
sin embargo, se hacen más difíciles de utilizar cuando se ponen en juego muchos estados y se
trabaja con requisitos de rehusabilidad.

Incialmente se encuentran los autómatas de estado finito. Aumentando complejidad sobre las transiciones se
definen los autómatas de estados finitos extendidos. Ofreciendo la capacidad de paralelismo se introducen los
autómatas de estados finitos concurrentes. Finalmente, en lo que respecta a nuestro interés se encuentran los
autómatas de estados finitos jerárquicos.

Los autómatas finitos jerárquicos resuelven gran parte de este problema y permiten agrupar comportamientos
haciendo que sea más sencillo rehusar y mucho más agradable la tarea de ampliar detalles en los estados o
incluso aumentar y variar los que ya tenemos.

Ejemplo de HFSM

La foto superior muestra un ejemplo de autómata finito jerárquico.

> Qué y cómo modela la máquina de estados finitos jerárquicos

Para no marear la perdiz vamos a ver desde el punto de vista del creador de sistemas de inteligencia artificial
complejos con qué propósito se utilizan las máquinas de estado finito jerárquico ya que principalmente es el concepto
lo que va a resultar interesante desde un primer punto de vista y más allá de la tecnología subyacente.

Otro ejemplo de HFSM

Lo que modela una HFSM será una serie de comportamientos que a su vez estarán divididos en una serie de comportamientos.
Por ejemplo, para controlar el movimiento de un soldado modelado con inteligencia artificial podemos tener una serie de estados superiores que indiquen a nivel conceptual los estados por los que va a pasar. Imaginemo un primer estado ‘Llamado reposo’, una transición a un segundo estado llamado ‘Bostezar’ y una tercera transición a un tercer estado que le vamos a poner ‘Patrullar’. Con este primer autómata definimos un comportamiento a grandes rasgos. Si disponemos del conocimiento necesario, usaremos los HFSM’s sobre el segundo estado: ‘Bostezar’ e iniciaremos un nuevo autómata de estados finitos que tendrá dos estados (podrian ser 15 pero dos ya son suficientes). El primero de ellos será ‘Levantar Brazos y Bostezar’, seguido de una transición a un segundo estado que será ‘Incorporarse’. Una vez procesado el segundo subestado se devolverá el cálculo al lugar en el que se dejó en el autómata del estado superior.

Visto un posible ejemplo de aplicación y puestos en escena, podemos pasar a ver que detalles cambian respecto a los autómatas de estados finitos sencillos y que capacidad adicional aportan.

> Cómo funciona la máquina HFSM

Para simplificar supondremos dos niveles jerárquicos y nos referiremos al grupo de los de nivel superior como estados y a los de nivel inferior como subestados. Todo subestado formará parte de un estado de mayor grado jerárquico.

Ejemplo HFSM

Además de los componentes de un autómata de estados finito, encontramos nodos de entrada y nodos de salida. Estos nodos son el destino o la fuente de las transiciones que nos llevan de un superestado a un estado y de un estado a un superestado respectivamente. Supongamos que sería el equivalente a bajar un nivel en la jerarquía y volver a subirlo una vez terminados los estados.

Una transición que quede activa de un superestado a otro interrumpe el proceso que esté actualmente en marcha en grados jerárquicos menores. Respecto al resto de elementos, el funcionamiento es exactamente el mismo a las máquinas de estados finitos definidas en otros artículos.

> En Resumen

Hemos adquirido una nueva herramienta con un alto grado de adecuación a entornos en los que es necesario identificar subestados y se hace común reutilizar estados. Este mecanismo nos ofrece la capacidad de responder a diferentes eventos de una forma sencilla evitando transiciones desde cada uno de los estados, necesitando simplemente transiciones desde los superestados. Actualmente se utiliza en un gran número de propuestas comerciales por lo que ha demostrado con creces su capacidad.

Os ofrezco un documento en el que se detalla de forma muy exhaustiva el funcionamiento de los HFSM’s creado por Rajeev Alur en honor a Zohar Manna Taormina. En el vais a poder aprender de una forma más completa acercade este tipo de autómatas.

> Formal Analysis of Hierarchical State Machines

Disfutadlos!

Gestión del comportamiento mediante Autómatas de estados finitos (FSM’s)

No comments »

Un primer enfoque que podemos abordar cuando la cosa se pone fea en
materia de control de comportamiento son los Autómatas de Estados Finitos o Finite States Machines. Se pone fea cuando el número de comportamientos crece y se pone mucho más fea cuando crecen los diferentes entornos y condiciones bajo los que manifestar estos comportamientos.

Por controlar el comportamiento entendemos la necesidad de que a partir de unos determinados eventos o acciones del usuario, nuestro agente inteligente responda de una forma concreta. De este modo deberemos gestionar el comportamiento de NPCs (Personajes No Jugador), de mascotas, de plantas, puertas …etc. En definitiva, todo lo que requiera un cierto grado de reacción ante determinados
eventos.

Autómata

Una de las propuestas sencillas para llevar un poco la distribución
del comportamiento son los FSMs. Estas herramientas utilizadas inicialmente en informática teórica cobran importancia cuando queremos estructurar el comportamiento. Algunos ingenieros informáticos verán devueltas a la realidad sus peores pesadillas de sus años mozos cuando estudiaban teoría de la computación. Otros,
simplemente pensad que el infierno de Dante era el paraiso al lado de
los estudiantes de este tipo de estructuras. De cualquier modo, lo que en su dia fue una herramienta perfecta de tortura a los alumnos, ahora se torna en una buena manera de trabajar y conseguir resultados aceptables para sistemas que no alcanzan una complejidad extrema.

Pasamos a ver que son y cómo se utilizan. Los FSMs constan de varios elementos: estados, transiciones y acciones. El formalismo matemático será para aquellos interesados, bastante más riguroso. Sin embargo, el objetivo aqui es saber que son y cómo se aplican para resolver este problema.

> Partes de los autómatas FSM

Empezamos identificando cada elemento y lo aplicamos a nuestro propósito, que es utilizarlos como gestores de comportamiento. En un
autómata como el nuestro encontraremos varios elementos: estados, transiciones y comportamientos. Definimos un estado inicial que será a partir del que se procesen los cambios.

El tema es sencillo, los estados representan el momento concreto de la acción, es decir, de entre todos los posibles momentos, cuál es el que está vigente ahora. Un ejemplo claro es el del autómata de las estaciones: Empezando por un esto inicial llamado por ejemplo: ‘Primavera’, el resto de estados serán ‘Verano’,'otoño’ e ‘Invierno’.

Otro elemento es el de las transiciones. En nuestro autómata de las estaciones serán flechas que vinculan un estado con otro y que representan el paso de un estado al siguiente. Tendremos transiciones del estado ‘Primavera’ al estado ‘Verano’ y así sucesivamente para cada uno.

Finalmente tendremos las acciones, que serán propias de cada estado. Por ejemplo en nuestro caso, el autómata tendrá en el estado ‘Primavera’ asociada la acción florecer();, en invierno heladas(); y así sucesivamente. Cada estado tendrá una serie de acciones que definirán el comportamiento.

En nuestro caso un posible autómata aplicado a un juego de estrategia en tiempo real que defina el comportamiento previsto como estrategia general será:

-Estados: ‘Minar recursos’, ‘Crear Ejercito’, ‘Mejorar la tecnología’, ‘Fortificar’ y ‘Atacar’. Con un estado ‘Defender’.

Las transiciones serían las lógicas, una detrás de otra, añadiendo una transición que va al estado ‘Defender’ si ataca el oponente y que retorna al estado del que proviene una vez neutralizado el ataque.

> Funcionamiento

A partir del estado final y en función de las transiciones vamos pasando de un estado a otro ejecutando la lista de acciones que tenemos asignadas a cada estado. Cuanto más alto nivel se aplique a las acciones, más sencillo será interpretar el código. Cuanto mejor estructurado esté el autómata, mayor será la capacidad de incluir nuevos estados o mejorar los actuales.

Si una imagen vale más que mil palabras un video valdrá: “1000*Fotogramas * segundo * segundos de video” veces que una palabra. así que aqui teneis una muy breve pero concisa explicación.

Una herramienta constructora de autómatas se puede ver aqui:

> En resumen

Hemos visto qué son y cómo se utilizan los Autómatas de Estados Finitos para la resolución de problemas en los que es necesario estructurar de una forma aceptable los comportamientos que se darán lugar en nuestro sistema de inteligencia artificial.

Estos son una herramienta muy utilizada ya no solo en entornos de inteligencia artificial sino de ingeniería en general por lo que resulta una buena adquisición de conocimiento y un buen paradigma a la hora de plantear resultados a problemas que requieren de un cierto grado de división en estados.

Aqui teneis una clase rápida (1 hora) del funcionamiento de estos cacharros, cortesia del Instituto Indio de Tecnología Madras.

Y otra muy buena del mismo tipo:

De cualquier forma, vale la pena darle un poco de caña al asunto por lo que os recomiendo a aquellos que no conoceis a fondo estos mecanismos que les echeis un vistazo. La documentación es muy abundante.

Hasta la próxima

Modelos matemáticos ampliamente extendidos para la gestión del comportamiento.

No comments »

Una vez que se conocen los diferentes elementos que toman parte en la escena de
un sistema que requiere inteligencia artificial más compleja y elaborada, llega
el momento de plantearse la forma en la que vamos a gestionar el comportamiento.

Para facilitar las diferentes características que son deseables en la gestión de
entidades dotadas de inteligencia artificial (rehusabilidad de comportamientos, paralelismo,
independencia del agente
, entre otras.) se han propuesto varios modelos
matemáticos y mecanismos que permiten fcilitarnos el trabajo y adquirir muchas de
estas características deseables de un sistema complejo de inteligencia artificial.

En este artículo veremos que áreas se han extendido en mayor grado y cuál es la tendencia de
los desarrolladores en materia de gestión del comportamiento.

En primer lugar se expandieron los sistemas que usaban listas complejas y elaboradas de acciones que aplicadas a determinados contextos producian el comportamiento deseado de los agentes. Este enfoque era válido puesto que en los primeros sistemas de entretenimiento en este caso no era necesario un alto grado de complejidad ni existía un indeterminismo inherente alentorno en el que nos encontrabamos.

Controlador Play 4 (Fake Alert)
Un ejemplo de este comportamiento podía ser el de simuladores de lucha como Street Fighter donde se regian reglas del estilo a: Si (el usuario ataca) Y (Nivel de juego = alto) entonces -> Ejecuta contraataque.

Street Fighter Alpha

Posteriormente a medida que crece la complejidad se introducen elementos que aportan algo de indeterminismo para hacer menos predecible el comportamiento de los agentes. Se introducen parámetros estadísticos y medidas donde las reglas dependen en parte del azar. Un ejemplo sería, al igual que el anterior: Si (el usuario ataca) Y
(Nivel de juego = alto) Y (tiro un dado y sale mayor que 3) entonces -> Ejecuta contraataque.

Como se aprecia, la tendencia era incluir más ‘Y’s a medida que añadiamos dificultad. Conforme avanzan los sistemas de entretenimiento crecen tanto los elementos relativos al entorno como el número de agentes implicados, lo que hace que las reglas de este estilo, en su dia muy válidas y rápidas de computar, sean insuficientes y presenten soluciones de inviabilidad creciente. Un ejemplo sería el sistema de Heavenly Sword donde intervienen muchos agentes sobre entornos
muy diferentes y con habilidades distintas.

Heavenly Sword
Esta complejidad empieza a requerir un grado de organización mayor y requiere estructuras que soporten una rehusabilidad, una escalabilidad y una cambiabilidad acordes a las variaciones de puntos de vista de los departamentos de diseño y de márqueting de las productoras de juegos. El creador de inteligencia artificial debía ahora poder modificar de forma rápida los comportamientos en función de decisiones de diseño o por requisitos de diferentes plataformas. Empiezan a surgir soluciones que tiran del modelo matemático de autómatas de estados finitos (Finite State Machines) donde cada momento queda definido por un estado y a cada estado se puede llegar mediante transiciones (eventos/peticiones del usuario/azar). Cada uno de estos estados tendría asociada una lista de acciones o comportamientos a llevar a cabo por el agente o agentes que tiene asociado.

Automata de Estados Finitos

Conforme la complejidad de los sistemas de entretenimiento aumentan la propuesta de Autómatas de Estados Finitos para modelar el comportamiento deja de ser efectiva. Se hace necesario agrupar comportamientos, definir nuevos cambios de estado y aplicar estructuras más flexibles y complejas al mismo tiempo. Surgen propuestas con lo que llamamos autómatas de estados finitos Jerárquicos (o Hierarchical Finite State Machines HFSM). Con ellos se resuelve en gran parte la rehusabilidad y se añade variabilidad en los comportamientos.

Autómata de Estados Finitos Jerárquico

Los HFSM siguen siendo complejos y requieren un alto grado de comprensión por parte de los desarrolladores de IA. Lo que los hace poco competitivos en un entorno tan cambiante como el de la Industria del Entretenimiento. Si bien cumplen su comentido, les falta un grado de intuitividad que aportan otras soluciones como los Árboles de Comportamiento (Behaviour Trees). En este último enfoque organiza del mismo modo los comportamientos de forma jerárquica pero permitiendo agrupaciones en forma de árbol que permite agrupar comportamientos y hacer efectivos diferentes estructuras de forma mucho más intuitiva cuando el sistema empieza a ser realmente complejo.

Detalle arbol de comportamiento

Cada uno de estos enfoques es válido en su entorno correcto y no se puede decir a priori que uno sea mejor o peor, siempre es necesario aplicarlo al entorno en el que nos vamos a mover y solo la experiencia te permitirá descartar una opción u adoptar otra con un mayor grado de seguridad.

El resultado de cualquier modo, será que cumplirás tus objetivos pero la dificultad será mayor o menor. Y por otro lado cuando tengas que añadir o modificar comportamientos, te será más o menos complejo. Te animo a que le eches un vistazo a los artículos que profundizan un poco
más en cada uno de los enfoques.

Disfrútalo.