Construyendo la IA para Athena Crisis

Rate this content
Bookmark
Project website

Esta charla se adentrará en cómo construir una IA para un juego de estrategia por turnos desde cero. Cuando comencé a construir Athena Crisis, no tenía idea de cómo construir una IA. Todos los recursos disponibles eran demasiado complejos o confusos, así que simplemente comencé a construirlo basándome en cómo jugaría el juego. ¡Si quieres aprender cómo construir una IA, no te pierdas esta charla!

Christoph Nakazawa
Christoph Nakazawa
37 min
28 Sep, 2023

Comments

Sign in or register to post your comment.

Video Summary and Transcription

Únete a Christoph de Nakazawa Tech en la construcción de la IA para Athena Crisis, un juego donde la IA realiza acciones como un jugador. Aprende sobre la importancia de las abstracciones, primitivas y algoritmos de búsqueda en la construcción de una IA para un videojuego. Explora la arquitectura de Athena Crisis, que utiliza estructuras de datos persistentes inmutables y actualizaciones optimistas. Descubre cómo implementar comportamientos de IA y crear una clase para la IA. Averigua cómo analizar unidades, asignar pesos y priorizar acciones basadas en el estado del juego. Considera los próximos pasos en la construcción de la IA y explora la posibilidad de construir una IA para un juego de estrategia en tiempo real.

Available in English

1. Introducción a la construcción de IA para Athena Crisis

Short description:

¡Hola! Únete a mí en mi charla sobre la construcción de la IA para Athena Crisis. Soy Christoph de Nakazawa Tech. Si no has oído hablar de Athena Crisis antes, te recomiendo ver mi charla anterior. Tengo experiencia en la gestión de equipos de infraestructura de React Native y JavaScript en Facebook. Ofrecemos coaching de liderazgo y resolución de problemas de JavaScript en Nakazawa Tech. Contáctanos en nakazawa.dev.

¡Oh, hola! Estoy jugando a Athena Crisis en mi Steam deck. Muchas gracias por unirte a mí en mi charla sobre la construcción de la IA para Athena Crisis. Soy Christoph y dirijo una pequeña startup en Tokio llamada Nakazawa Tech. Si no has oído hablar de Athena Crisis antes, recientemente en la React Summit hace unos meses, di una charla que explica cómo se está construyendo el juego, y todo está construido con JavaScript, React y CSS. Recomiendo encarecidamente que si no lo has visto, vuelvas y veas esa charla. Si retrocedemos aún más, si nunca has trabajado conmigo antes o si no me conoces, solía gestionar los equipos de infraestructura de React Native y JavaScript en Facebook, y construí un framework de pruebas llamado JustJavaScript. Hacemos muchas cosas en Nakazawa Tech, incluyendo la construcción de videojuegos, pero también ofrecemos coaching de liderazgo, y podemos ayudarte con tus problemas de JavaScript, con la velocidad de desarrollo, la productividad o ayudarte con cualquier problema que puedas encontrar al construir aplicaciones basadas en JavaScript. Por favor, trabaja con nosotros, contáctanos en nakazawa.dev.

2. Understanding Athena Crisis and Building an AI

Short description:

Antes de sumergirnos en la construcción de una IA para Athena Crisis, comprendamos qué es Athena Crisis. En el juego, puedo entrar en una partida desde el menú y jugar. Después de mi turno, la IA toma el control y realiza todas las acciones necesarias, como un jugador. Puede atacar, moverse y capturar edificios. Ahora, exploremos cómo construir una IA así.

Primero, antes de adentrarnos en la construcción de una IA para Athena Crisis, dediquemos un poco de tiempo a comprender qué es Athena Crisis. Estoy aquí en el juego en el menú, y puedes ver la página de descripción general en este momento, y puedo entrar en una partida desde aquí mismo. Y así, puedo jugar el juego. Aún no todos los ataques tienen sonido, pero algunos sí lo tienen. Pero lo interesante es que, una vez que termino mi turno, déjame construir algunas unidades. Cuando termino mi turno, la IA toma el control y se encarga de su turno. Realiza ataques, se mueve, puede capturar edificios, puede hacer todo lo que un jugador haría.

3. Building an AI with Abstractions

Short description:

Veamos cómo construir una IA así. Hablaremos sobre código, abstracciones, primitivas, algoritmos de búsqueda y matemáticas. Construir una IA para un videojuego puede ser desafiante, pero al tener abstracciones básicas y abordarlo como si estuvieras jugando el juego, se vuelve más manejable.

también puede hacerlo. Apaga la música de nuevo. Así que veamos cómo podríamos construir realmente una IA como esa. La advertencia aquí es que esta es una charla centrada en código. Hablaremos mucho sobre código, pero al mismo tiempo, será apta para principiantes. Así que por favor, acompáñame mientras repaso todas las piezas. Los requisitos previos que encontré para construir una IA son que necesitas tener buenas abstracciones. Necesitas tener primitivas sólidas, necesitas conocer los algoritmos de búsqueda para saber dónde están las cosas en el juego, y necesitas conocer matemáticas para decidir qué acción tomar. La forma en que abordé esto fue que mi problema era que nunca antes había construido una IA para un video juego. Así que no tenía idea de cómo hacerlo. Leía artículos en internet sobre cómo construían una IA para tipos específicos de video juegos, y simplemente no me parecía lógico porque siento que estas cosas son realmente difíciles de entender cuando solo las lees o cuando solo ves a alguien más hacer eso. La mejor forma que encontré para construir una IA es teniendo todas estas abstracciones básicas en su lugar y luego construyéndola como si imaginara qué haría si estuviera jugando el juego.

4. Supuestos y Abstracciones para Construir una IA

Short description:

Quiero construir una IA que sea rápida, sin estado, determinista y componible. Si estoy construyendo una IA que se comporte como un jugador humano, necesito tener abstracciones en el juego que pueda proporcionar al código de la IA que sean básicamente las mismas que le doy a un jugador.

Y así, los supuestos que hice son que quiero construir una IA que sea rápida, sin estado, determinista y componible. Así que te he lanzado muchas palabras. Y la forma en que lo veo es que si estoy construyendo una IA que se comporte como un jugador humano, de la misma manera que estoy jugando, necesito tener abstracciones en el juego que pueda proporcionar al código de la IA que sean básicamente las mismas que le doy a un jugador. Por supuesto, es un poco diferente porque el jugador ve un mapa, se renderiza en un navegador y todo eso, pero debajo de eso, debe haber un nivel

5. Construyendo una IA sin estado para Athena Crisis

Short description:

Para construir una IA sin estado para Athena Crisis, se necesitan primitivas sólidas como un estado de mapa y acciones. La IA debe ser rápida, sin estado y determinista. La composabilidad también es importante, permitiendo que los módulos sean reutilizables en todo el sistema. La arquitectura de Athena Crisis utiliza estructuras de datos persistentes inmutables, asegurando cambios declarativos en el estado del juego. La IA se ejecuta en el servidor, comportándose como otro jugador, y comunica sus acciones al cliente. Las actualizaciones optimistas garantizan que el cliente y el servidor tomen acciones simultáneamente.

de abstracciones con las que puedes trabajar si eres humano o si eres una IA. Y para eso, necesitas primitivas sólidas, necesitas tener un estado de mapa, necesitas tener acciones. Y luego, si volvemos a la suposición, es que quería que la IA fuera súper rápida. Quería que fuera sin estado. Así que toma una acción, no tiene memoria, descubre cuál es la siguiente acción que puedo tomar para maximizar mis posibilidades de ganar. Obviamente, una IA más inteligente tendría memoria o planificaría y descubriría cuál es la mejor manera de ganar durante todo el tiempo del juego. Pero por ahora y para este ejemplo hoy, solo vamos a pensar en cómo podemos hacer una IA sin estado que solo haga una acción a la vez. En cuanto a hacerla determinista, lo que me importa es que no haya aleatoriedad involucrada. Obviamente, en el juego real de Athena Crisis, hay cierta aleatoriedad en la IA para que las cosas se mezclen. Porque si le dices a la IA, `oye, ve y construye la unidad que creas que es la más útil para construir`, entonces terminas construyendo la misma unidad cada vez, en cada turno, muy probablemente, ¿verdad? Así que quieres tener algo de variedad en el juego. Así que podrías agregar algo de aleatoriedad. No vamos a hacer eso hoy. Y en cuanto a la composabilidad, es realmente útil que la IA... que todos los módulos sean reutilizables en todo el sistema. Entonces, si estás haciendo algo para buscar caminos, o si estás descubriendo cuál es la unidad a la que debo atacar que me aporta más valor como jugador, debes abstraer eso para poder componerlos de otras formas. Y si observamos la arquitectura de Athena Crisis, naturalmente llegué a algo que era una base sólida para construir una IA. En primer lugar, y nuevamente, puedes volver a esa charla en la cumbre de React para aprender más sobre la configuración básica de Athena Crisis. Pero todo utiliza estructuras de datos persistentes inmutables. Entonces tienes un estado de mapa , lo transformas y obtienes un nuevo estado. Por lo tanto, no estás realizando cambios imperativos en el mapa o en el estado del juego. Todo es declarativo. Solo estás diciendo, aquí está el estado del juego que me gustaría ejecutar. Aquí está el cambio que me gustaría ejecutar en un estado del juego, y obtienes un nuevo estado del juego y este tipo de arquitecturas también funcionan muy bien en una relación servidor-cliente porque Athena Crisis será un juego que se puede jugar con muchas personas en Internet. Y naturalmente, gran parte del código se ejecuta en el servidor. Por ejemplo, la IA que te mostré antes se ejecutaba completamente en el backend y no se envía al cliente en absoluto. Solo te dice los comportamientos o las acciones que está tomando la IA. Y en ese sentido, funciona exactamente igual que otro jugador. Porque cuando juegas un juego en Internet contra otra persona, no conoces el proceso de toma de decisiones por el que están pasando mientras toman acciones. Y la IA funciona de la misma manera, excepto que se ejecuta en un servidor y te dice las decisiones que tomó al final. En cuanto a las actualizaciones optimistas, la idea es que el cliente siempre toma

6. Transformadores de acciones y arquitectura

Short description:

Los transformadores de acciones y la arquitectura de acción-respuesta son la pieza central en la que estamos trabajando. Los jugadores realizan acciones, que se ejecutan en el estado del juego. Las acciones visibles se calculan en función de la niebla de guerra y la visibilidad individual de los jugadores. El generador de código automatiza los codificadores y decodificadores de acciones. Ejecutar una acción implica obtener unidades, asegurarse de los oponentes y verificar la elegibilidad para el ataque.

Al mismo tiempo que el servidor, el jugador realiza una acción. Y, como no hay aleatoriedad en ello, eso debería funcionar idealmente y toda la experiencia del usuario debería sentirse bien. Permíteme explicarte los transformadores de acciones y la arquitectura de acción-respuesta, porque esa es la pieza central en la que vamos a trabajar mientras construimos una IA. La forma en que funciona es que cuando un jugador juega el juego, realiza una acción. Por ejemplo, antes estaba moviendo mi unidad. Mover o atacar, esas son acciones. Luego las ejecutamos en el estado del juego y obtenemos una respuesta de acción. Básicamente, eso solo confirma, okay, el jugador quiere mover esta unidad de aquí a allá. Ejecutamos esa acción. Y si obtenemos una respuesta de acción, significa que esa acción realmente es aplicable al estado del juego. Por ejemplo, valida que realmente puedas mover esa unidad. Valida que puedas moverla a ese lugar y si eso es aceptable dentro de las reglas del juego. Y luego, en función de cada jugador, calculamos las acciones visibles. Antes solo te mostré un mapa básico del juego, pero también hay un sistema llamado niebla de guerra, donde cada unidad tiene un rango de visión y no puedes ver más allá de eso. Entonces hay muchas partes del estado del juego que están ocultas para el jugador según lo que tus unidades pueden ver. Y el único lugar que tiene el estado completo del juego es el servidor. ¿Correcto? Y así, puedes mover una unidad de un lugar a otro y otros jugadores solo pueden ver una de esas casillas. Y luego, cuando calculas las acciones visibles, se eliminarán todas las partes del movimiento que el jugador no está autorizado a ver. Después de calcular esas acciones, obtienes respuestas de acción para cada jugador individualmente, luego en el cliente, las animas y luego las aplicas al estado del juego. Permíteme mostrarte el código aquí, en realidad. Como te mostré antes, hay una acción de ataque a una unidad. Si la ejecutas, puedes obtener una respuesta de acción de ataque a una unidad. Y luego esto se comprime en una tupla donde se eliminan todos los elementos innecesarios al enviarlo a través de la red. Hay un generador de código que genera estos codificadores y decodificadores de acciones para todas las acciones del juego. Así que todo es automático. Y esto es lo que parece ejecutar una acción. Por ejemplo, para atacar a una unidad, recibes la estructura de datos del mapa. Obtienes las unidades de esa estructura. Te aseguras de que cuando atacas a una unidad, no sean del mismo jugador y no estén en el mismo equipo. Te aseguras de que la unidad que está atacando realmente pueda ejecutar un ataque y que aún no esté completado.

7. Implementando Comportamientos de IA y Creando una Clase

Short description:

La arquitectura funciona aplicando respuestas de acción al estado del juego, actualizando unidades con nuevos datos. Este enfoque simplifica la construcción de una IA al generar acciones válidas para el estado actual del juego. La arquitectura proporciona una capa de abstracción común, evitando el fraude de la IA y asegurando que todos los jugadores jueguen según las mismas reglas. Implementemos comportamientos de IA describiendo el comportamiento más básico y creando una pequeña clase.

Y luego realizas una serie de cálculos de daño. Y luego devuelves las estadísticas para las nuevas unidades. Y luego, cuando estás buscando, cuando tienes niebla de guerra, tienes que, como dije, calcular si esas acciones son visibles o no. Entonces hay una definición que uso, básicamente dice que si ambos campos son visibles, entonces puedes recibir la respuesta de acción regular de ataque a la unidad. Si solo la fuente, solo la unidad que está atacando es visible, entonces transforma esa respuesta de acción en un ataque a una unidad oculta. Y si solo el objetivo es visible, lo transforma en un ataque de una fuente oculta a una unidad. Obviamente, estos se invierten, porque si solo el objetivo es visible, entonces la fuente del ataque es visible. Así que es un ataque de fuente oculta. Y luego, más adelante, hay muchas animaciones involucradas aquí. No las mostraré hoy porque no son relevantes para construir la IA, pero aplicamos esas respuestas de acción. Así que observamos todas las respuestas de acción y si está atacando a una unidad, recibimos todos los nuevos datos de la unidad. Obtenemos las unidades existentes y luego, según el estado, actualizamos la unidad con los nuevos datos. Todo aquí es inmutable. Y descubrí que esta arquitectura funciona muy bien para construir una IA. Aquí tienes un ejemplo rápido. Simplemente estoy moviendo y atacando al tanque rosa. Primero, aplicamos la respuesta de acción desde esta posición aquí arriba y la movemos al puente, y luego usamos esa unidad que está en el puente para atacar a la unidad que está junto a ella. Y así es como funciona la arquitectura. Entonces, todo lo que realmente necesitamos si estamos construyendo una IA es generar un montón de estas acciones que sean válidas para el estado actual del juego. Esto simplifica significativamente el problema del proyecto. Porque imagina, no tienes una abstracción como esta donde estás aplicando acciones a un estado de juego y para cada acción del jugador, estás modificando manualmente el estado del juego. Dices, OK, atacar, y luego simplemente vas y tienes código imperativo que cambia todo en un solo lugar. Y luego, si intentas construir una IA, tienes que copiar todo eso a tu IA y luego tienes problemas. Pero también proporciona esta capa de abstracción común donde no le das a la IA acceso para hacer cosas como hacer trampa. Si estás realizando un ataque o ejecutando un ataque con este tipo de abstracción, la IA no puede tener un ataque que sea el doble de efectivo o algo así si eso tampoco está permitido para el jugador. Por supuesto, es posible que desees tener un sistema así. Pero en un juego como Athena Crisis, quieres que todos los jugadores jueguen según las mismas reglas. Finalmente, implementemos comportamientos de IA. Lo hacemos simplemente describiendo el comportamiento más básico.

8. Agregando Comportamientos y Movimientos de IA

Short description:

La primera versión de nuestra IA solo puede finalizar el turno. Ejecutamos la acción Fin de Turno en el estado del juego y agregamos un método auxiliar llamado actuar. Usamos la función de acción para encadenar los comportamientos de la IA. Cuando la IA está ejecutando un Fin de Turno, devolvemos nulo. Para agregar un movimiento, intentamos mover una unidad. Si no se pueden mover más unidades, finalizamos el turno. Implementamos la función de movimiento utilizando funciones auxiliares para obtener las unidades disponibles y determinar hacia dónde deben ir según el estado del mapa.

El primer comportamiento que la IA podría tener. Vamos a armar una pequeña clase. No es necesario usar clases aquí, pero es un poco más fácil. La primera versión de nuestra IA solo puede hacer una cosa. Cuando la IA comienza su turno, finaliza el turno. Y esa es una buena manera de asegurarse de que la IA deje de jugar, porque de lo contrario, el juego se bloquea rápidamente. En este caso, simplemente vamos a agregar una única acción llamada Fin de Turno. Ejecutamos la acción Fin de Turno en el estado del juego. Y vamos a agregar aquí un método auxiliar que será útil más adelante. Básicamente, estamos agregando este método, actuar. Si ejecutamos una acción aquí, la agregamos a esta matriz de respuestas, y luego podemos recuperarlas más tarde y enviarlas al jugador. Y luego, lo interesante aquí, usaremos esta función llamada acción para encadenar todos nuestros comportamientos de IA juntos. Y una vez que esta función devuelve nulo, significa que la IA ha terminado. En este caso, cuando la IA está ejecutando un Fin de Turno, simplemente devolvemos nulo. Y así es como podríamos usar esta IA. Así que simplemente creamos una nueva instancia, y mientras el jugador actual sea un bot, simplemente actuamos en el mapa y luego reemplazamos, lo importante es también reemplazar el mapa con el nuevo estado del juego. Y luego, al final, recibimos todas las respuestas y podemos transmitirlas al cliente. Entonces, en este caso, simplemente devolvería una respuesta de acción de Fin de Turno y luego se la enviaría al jugador. Como puedes ver aquí, el juego está en un bucle. Cada vez que termino mi turno, la IA termina el suyo. Entonces, ahora, ¿cómo agregamos un movimiento? Por ejemplo, vimos esta función de acción anteriormente. Entonces, ahora, la forma en que lo estamos ampliando es que, en primer lugar, siempre intentaremos mover una unidad. Y si no hay más unidades que podamos mover, es decir, esta función devuelve nulo, entonces finalizaremos el turno. Y así, la forma en que podemos implementar una función de movimiento es a través de un conjunto de funciones auxiliares diferentes. En primer lugar, simplemente obtendremos la primera unidad disponible que podamos mover. Así que supongamos que hay una función auxiliar aquí que nos permite extraer eso. Y luego, ¿cómo jugaría un humano, verdad? Y así es como pensé en cómo jugaría. Es como si fuera a mirar lo que es interesante en el mapa, como, ya sabes, según la situación actual, según esta unidad, según el estado del mapa, ¿dónde tiene más sentido que vaya esa unidad? Una vez que tengo esta lista de posiciones, averiguo cuáles son los grupos de a dónde debo ir. Entraré en detalles más adelante. Pero básicamente, puedo tener, como, cien posiciones interesantes, pero necesito averiguar a dónde ir realmente. Y así, la forma en que funciona esta función de agrupación es que tomará todas esas posiciones y las reducirá a una cantidad menor de grupos donde tiene más sentido buscar a dónde ir realmente. Y luego, en función de eso, miramos, ya sabes, a qué objetivo deberíamos ir realmente. Entonces,

9. Moviendo Unidades y Comportamientos de las Unidades

Short description:

Solo tenemos unos pocos grupos y encontramos un objetivo. Si tenemos una ubicación, ejecutamos una acción de movimiento; de lo contrario, una acción completa. Cada función debe devolver una acción o modificar el estado del juego. La función de movimiento evita el recomputo cuando no hay a dónde ir. Se utiliza el algoritmo A estrella para optimizar el movimiento en la cuadrícula 2D. Las unidades tienen diferentes comportamientos basados en sus habilidades, como capturar edificios o atacar a otros. El comportamiento de la unidad se determina por las posiciones interesantes en el mapa y sus capacidades.

si observas esto como, como, ya sabes, podríamos tener muchas posiciones. Solo tenemos, como, unos pocos grupos. Y luego solo encontraremos un objetivo. Y luego, si tenemos una ubicación a la que ir, ejecutaremos una acción de movimiento. De lo contrario, y aquí es donde se vuelve realmente importante, ejecutaremos una acción completa. Entonces, lo importante aquí es que cada una de estas funciones siempre debe devolver una acción. O lo siento. Siempre debe modificar el estado del juego. Entonces, ya sea que la unidad se mueva o complete, lo que significa que no tomará ninguna otra acción.

Porque el problema al que te enfrentas, de lo contrario, si ejecutas esta función de acción en un bucle, entrará en la función de movimiento y luego siempre intentará recomputar todo esto, solo para darse cuenta de que no hay a dónde ir. Entonces, siempre debes asegurarte de que cada una de estas funciones, cuando no haya más acciones que tomar, devuelvan nulo o modifiquen el estado del juego para que puedas volver a esa función para mover la siguiente unidad. Entonces, idealmente, a medida que ejecutas acciones de juego aquí, el número de unidades disponibles disminuye a cero para que puedas ingresar a la función de fin de turno aquí.

Muy bien, ahora, descubramos todo esto sobre cómo moverse realmente. Hay un algoritmo muy común . Hay muchos algoritmos para buscar, buscar en una cuadrícula 2D hacia dónde vas. Me decidí por A estrella, funciona muy bien para este tipo de juego. Y lo único aquí es que básicamente estás haciendo una búsqueda en profundidad en una cuadrícula 2D para averiguar dónde deberías ir y estás tratando de hacerlo de la manera más rápida posible con el menor costo. Si solo miramos el mapa del juego, esta unidad no puede ir a las montañas y cuesta más ir al bosque que quedarse en la calle. Entonces, estamos tratando de optimizar cómo llegar desde esta casilla verde, desde esta unidad hasta aquí. En este caso, solo hay un camino, ¿verdad? Pero aún así necesitamos averiguar, está bien, ¿es este el camino a seguir? o deberíamos pasar por el río. Pero ya sabes, esta unidad no puede pasar por el río, así que una vez que haces esta búsqueda de ruta, tienes paredes o tienes un costo de movimiento más alto que ciertas casillas. Y luego, una vez que tienes este radio y esta capacidad para averiguar dónde puede ir esta unidad, entonces podemos averiguar, está bien, ¿cuáles son las posiciones interesantes en un mapa y luego averiguar si la unidad realmente puede viajar allí. Entonces, esto es obviamente una versión simplificada, pero aquí hay tres cosas en las que podrías fijarte. La implementación real en Athena Crisis es de unas cientos de líneas, dependiendo del estado del juego y la unidad sobre la que estás preguntando qué hacer. Entonces, por ejemplo, las unidades pueden capturar edificios, las unidades pueden atacar a otras, las unidades pueden suministrar combustible y munición a otras unidades. Entonces, por ejemplo, podrías tener un sistema aquí donde una unidad que puede suministrar a otras pensará en otras unidades si tienen poca munición, ¿verdad? O en este caso, si la unidad no tiene un ataque o se queda sin munición, está en peligro. Entonces, si está en la primera línea, realmente pensará que las posiciones interesantes son los edificios de vuelta donde están mis bases. Y a través de eso, si alimentamos eso en el sistema que describí, esa unidad intentará retirarse. Y aquí, por ejemplo, si la unidad tiene la capacidad de capturar otros edificios, entonces el lugar más interesante para ir es a otros edificios que son propiedad del oponente. Y finalmente, si la unidad tiene ataques regulares, lo más probable es que encuentre interesante ir a otras unidades, como unidades oponentes

10. Building AI: Encontrar Objetivos y Agregar Ataques

Short description:

En el lado izquierdo, tenemos todo el mapa con unidades amarillas y rosas. Utilizamos un algoritmo de K-means para encontrar posiciones interesantes y reducirlas a grupos. Luego, encontramos el objetivo más cercano basado en el radio de movimiento y posicionamos la unidad junto a él. Finalmente, ejecutamos una acción de movimiento hacia el puente. Agregar ataques es similar a moverse. Primero analizamos los ataques, luego nos movemos a lugares interesantes y terminamos el turno. Elegimos el mejor ataque basado en el resultado para el jugador actual. Si es necesario, nos acercamos al objetivo antes de atacar.

para ir. Entonces, ahora pensemos en todo esto con los grupos. Entonces, en el lado izquierdo, tenemos todo el mapa, ¿verdad? Y así, tienes las unidades amarillas aquí y tienes las unidades rosas allí. Entonces, una vez que obtenemos las posiciones interesantes a las que esta unidad debe ir, el mapa se verá así para la IA. Será como, okay, creo que hay uno rosa aquí y una unidad rosa allí. ¿A cuál debería ir realmente? Y hay una función muy útil. Esta es una de las pocas veces en las que estoy feliz de usar una biblioteca de terceros porque es un montón de matemáticas que se simplifican al empujarlas hacia otra biblioteca. Básicamente, podrías tener 100 puntos en el mapa. En este caso, sé que solo tenemos dos. Así que este es un ejemplo muy simple. Pero simplemente estamos usando un algoritmo de K-means y hay un paquete de NPM llamado sk-means que es bastante rápido, donde podemos proporcionar un montón de posiciones y luego decirle, aquí está qué algoritmo usar y cuántas iteraciones debes tomar y cuántas ubicaciones o grupos debes devolver como máximo, y luego reducirá esos y los agrupará según su interés. Y luego, finalmente, simplemente alimentaremos esos grupos en una función llamada encontrar ruta hacia objetivos donde en realidad solo vamos a mirar, okay, esta unidad solo puede moverse de un lugar a otro en este turno. Así que simplemente encontremos el objetivo más cercano.

Y luego simplemente podemos, tal vez en este caso, usar la distancia en la cuadrícula. Pero la implementación real, la forma en que funciona, es que en realidad se verá el radio de movimiento, porque es posible que tengas una unidad que esté muy cerca de otra, pero hay una montaña en medio, por lo que no puede acceder a esa unidad. Entonces, en realidad debes mirar el radio, el radio de movimiento de esa unidad para ver cuál es el más fácil de alcanzar. Y una vez que sepamos cuál es la unidad más cercana, averiguaremos cómo llegar allí realmente. Y luego intentaremos posicionar la unidad justo al lado del objetivo. Entonces, en este caso, objetivo.padre, esta función devuelve una lista de rutas donde cada... lo siento, una lista de campos y donde cada campo tiene un padre, para que puedas navegarlo. Y no podemos mover la unidad encima de otra, así que tenemos que moverla al padre de esa unidad. Y finalmente, podemos unirlo todo y nuestra unidad se mueve hacia el puente. Como dije, buscamos las posiciones interesantes, las reducimos a grupos, encontramos una ruta hacia un objetivo y luego ejecutamos una acción de movimiento. Una vez que hemos terminado con la acción de movimiento, terminamos el turno. Muy bien, y luego lo otro que quiero mostrar es cómo construir un ataque. Por ahora, todo lo que hacemos es que la unidad se mueve, pero ¿cómo agregamos ataques? Y en realidad es muy similar a moverse. Entonces, ¿qué tal si cada vez que la IA comienza, primero miramos los ataques? Si no hay ataques para hacer, entonces nos movemos a lugares interesantes, y finalmente terminamos el turno. La forma en que he implementado esto es que en cada punto del juego, miro cuál es el mejor ataque que tiene el mejor resultado para el jugador actual. Y si hay un ataque disponible, entonces nos aseguramos de que debemos movernos allí. Y si es así, si la distancia es mayor que uno, entonces primero nos acercamos a esa unidad y luego atacamos a esa unidad. Muy bien, ¿cómo averiguamos cuál es el mejor ataque? Aquí hay una implementación básica para averiguar el mejor ataque.

11. Analizando Unidades y Asignando Pesos

Short description:

Analizamos las unidades y sus capacidades de ataque, asignando pesos al daño probable. Priorizamos las acciones en función del estado del juego y la importancia de derrotar ciertas unidades. En lugar de maximizar el daño, consideramos la cantidad mínima de daño necesaria para eliminar una unidad del campo. Evitamos acciones de bajo daño para prevenir contraataques. Priorizamos la defensa de edificios y unidades con habilidades especiales. Finalmente, observamos cómo nuestra unidad se mueve y ataca al objetivo.

En primer lugar, analizamos todas las unidades que tiene el jugador. Luego, determinamos, okay, anteriormente les mostré el algoritmo A estrella, y podemos extenderlo para no solo proporcionar el radio de movimiento, sino también el radio de ataque, que generalmente es el radio de movimiento más un campo a cada lado, algo así. Luego, para cada unidad a la que esa otra unidad puede atacar, determinamos cuál es el daño probable que podemos infligir, y luego le asignamos un peso. Y, ya saben, acompáñenme por un momento, suponemos que el daño máximo tiene el peso más alto. Luego, lo agregamos a una lista de posibles ataques. Y luego simplemente devolvemos el que tiene el peso más alto. En este caso, el daño más alto. Pero puede que no sea ideal pensar siempre en hacer la mayor cantidad de daño. Por lo tanto, es necesario introducir pesos. Y en este caso, dependiendo del estado del juego, puede ser más valioso atacar ciertas unidades en cierto estado que atacar otras unidades. Por ejemplo, si estás derrotando a esa unidad, es mucho más importante ejecutar esa acción que si solo estás reduciendo un poco su salud. Y este es un cálculo ligeramente más complejo porque lo que he descubierto es que no quieres tener el daño máximo a una unidad que ya está dañada. En realidad, quieres encontrar la unidad que puede hacer la menor cantidad de daño a una cierta unidad para sacarla del campo porque eso reserva otras unidades más fuertes para hacer ataques más fuertes a otras unidades más adelante. Y otra cosa que he descubierto es que, quieres evitar acciones de muy bajo daño porque puede que solo tengas una unidad que se encuentre con otra unidad y no haga ningún daño pero luego el contraataque es tan fuerte que esa unidad es eliminada del campo. Por lo tanto, es posible que desees evitar eso también. Y luego se vuelve mucho más interesante aquí en este lado también dice, okay, ¿qué pasa si hay un edificio aquí y luego hay una unidad oponente en ese campo y esa unidad está tratando de tomar tu edificio eso probablemente es mucho más importante que eliminar una unidad aleatoria que está en otro lugar del campo. Y luego, hay varios casos en los que, si esta unidad está transportando otras unidades o si el edificio en cuestión es el... Si el edificio donde se encuentra esa unidad es tu propia sede, es muy probable que pierdas. Por lo tanto, le daremos prioridad. O en algunos casos, algunas unidades tienen la capacidad de atacar y otras solo tienen otras habilidades especiales. La mayoría de las veces, es más importante atacar esas unidades. Y luego, juntamos todo eso y luego, veremos cómo nuestra unidad se mueve y ataca a esa otra unidad. Muy bien.

12. Building AI: Next Steps and Conclusion

Short description:

Para continuar construyendo la IA, debemos admitir todas las capacidades de las unidades y edificios, eliminar la información no visible para la IA y considerar comportamientos de IA personalizables. Las IA reales en los videojuegos se optimizan para predecir acciones futuras, pero esto puede ralentizar la IA. Esta visión general es útil para construir una IA de juego de estrategia por turnos en 2D. A continuación, consideremos construir una IA para un juego de estrategia en tiempo real. La charla fue diseñada con React y MDX, y el código fuente está disponible en GitHub. Si estás interesado, ponte en contacto con Nakazawa Tech para colaborar.

Entonces les mostré cómo agregar una IA a un juego de video, cómo moverla, cómo ejecutar ataques. ¿Cuál sería el siguiente paso? En primer lugar, debes admitir todas las capacidades de las unidades y edificios que tiene el juego, para que la IA tenga las mismas capacidades que un jugador humano. No hemos pensado en la niebla de guerra en absoluto en esta IA. De hecho, debemos asegurarnos de que la IA no obtenga información que el jugador no tenga. Por lo tanto, debemos eliminar toda la información que no sea visible para la IA.

Una cosa que encontré muy divertida y que pensé que iba a ser muy difícil, pero resultó ser relativamente fácil, es agregar comportamientos de IA personalizables. Puedes hacer que una IA sea más agresiva, defensiva o pasiva, o puedes adaptar su estilo según el estado del juego, cuando es atacada, cambiará de defensiva a agresiva, algo así. Si has estado siguiendo esto y estás interesado en construir una IA, te recomiendo encarecidamente que construyas tu primera versión y luego pienses en cómo hacerla defensiva o más agresiva. Es realmente divertido experimentar con eso y ver qué tipo de resultados tiene al ajustar el pequeño peso de priorizar una cosa sobre otra.

Finalmente, como dije al principio, solo queremos que esta IA sea rápida, sin estado y componible, y no haga ningún tipo de planificación. No mira hacia atrás. No tiene memoria. No piensa en cinco turnos adelante, en cuál es el movimiento más inteligente que podría hacer ahora que me preparará para el éxito más adelante. Las IA reales en los videojuegos probablemente hagan algún tipo de optimización para predecir lo que va a suceder en el futuro. Planifican cuál es la mejor acción, no solo ahora, sino también si pensamos en el futuro, según cómo pueda evolucionar el juego. El problema con eso es que tiende a volverse muy lento porque la IA tiene que pensar mucho. Por ejemplo, ¿qué pasa si me muevo de esta manera y luego el jugador contrario tiene cinco opciones y puede tomar una de esas cinco, lo que luego genera siete opciones para mí y luego tienes esta explosión en términos de toma de decisiones? Por lo tanto, se vuelve muy lento. Pero espero que esta visión general te haya sido útil si nunca has construido una IA desde cero para entender cómo construir una IA para un juego de estrategia por turnos en 2D. Ahora, el siguiente paso podría ser, ¿cómo construir una IA para un juego de estrategia en tiempo real que tal vez también esté construido en una cuadrícula o algo así?

Otra cosa que quería compartir es que toda esta charla fue diseñada con React y MDX. Construí un sistema llamado reMDX que puedes usar para hacer presentaciones de diapositivas y puedes encontrar el código fuente de toda esta presentación en GitHub también. Y nuevamente, trabajo en Nakazawa Tech, una pequeña startup en Tokio. Si te gustaría trabajar con nosotros, por favor ponte en contacto. Muchas gracias.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Compiler - Understanding Idiomatic React (React Forget)
React Advanced Conference 2023React Advanced Conference 2023
33 min
React Compiler - Understanding Idiomatic React (React Forget)
Top Content
React provides a contract to developers- uphold certain rules, and React can efficiently and correctly update the UI. In this talk we'll explore these rules in depth, understanding the reasoning behind them and how they unlock new directions such as automatic memoization. 
Speeding Up Your React App With Less JavaScript
React Summit 2023React Summit 2023
32 min
Speeding Up Your React App With Less JavaScript
Top Content
Too much JavaScript is getting you down? New frameworks promising no JavaScript look interesting, but you have an existing React application to maintain. What if Qwik React is your answer for faster applications startup and better user experience? Qwik React allows you to easily turn your React application into a collection of islands, which can be SSRed and delayed hydrated, and in some instances, hydration skipped altogether. And all of this in an incremental way without a rewrite.
From GraphQL Zero to GraphQL Hero with RedwoodJS
GraphQL Galaxy 2021GraphQL Galaxy 2021
32 min
From GraphQL Zero to GraphQL Hero with RedwoodJS
Top Content
We all love GraphQL, but it can be daunting to get a server up and running and keep your code organized, maintainable, and testable over the long term. No more! Come watch as I go from an empty directory to a fully fledged GraphQL API in minutes flat. Plus, see how easy it is to use and create directives to clean up your code even more. You're gonna love GraphQL even more once you make things Redwood Easy!
SolidJS: Why All the Suspense?
JSNation 2023JSNation 2023
28 min
SolidJS: Why All the Suspense?
Top Content
Solid caught the eye of the frontend community by re-popularizing reactive programming with its compelling use of Signals to render without re-renders. We've seen them adopted in the past year in everything from Preact to Angular. Signals offer a powerful set of primitives that ensure that your UI is in sync with your state independent of components. A universal language for the frontend user interface.
But what about Async? How do we manage to orchestrate data loading and mutation, server rendering, and streaming? Ryan Carniato, creator of SolidJS, takes a look at a different primitive. One that is often misunderstood but is as powerful in its use. Join him as he shows what all the Suspense is about.
Jotai Atoms Are Just Functions
React Day Berlin 2022React Day Berlin 2022
22 min
Jotai Atoms Are Just Functions
Top Content
Jotai is a state management library. We have been developing it primarily for React, but it's conceptually not tied to React. It this talk, we will see how Jotai atoms work and learn about the mental model we should have. Atoms are framework-agnostic abstraction to represent states, and they are basically just functions. Understanding the atom abstraction will help designing and implementing states in your applications with Jotai
A Framework for Managing Technical Debt
TechLead Conference 2023TechLead Conference 2023
35 min
A Framework for Managing Technical Debt
Top Content
Let’s face it: technical debt is inevitable and rewriting your code every 6 months is not an option. Refactoring is a complex topic that doesn't have a one-size-fits-all solution. Frontend applications are particularly sensitive because of frequent requirements and user flows changes. New abstractions, updated patterns and cleaning up those old functions - it all sounds great on paper, but it often fails in practice: todos accumulate, tickets end up rotting in the backlog and legacy code crops up in every corner of your codebase. So a process of continuous refactoring is the only weapon you have against tech debt.In the past three years, I’ve been exploring different strategies and processes for refactoring code. In this talk I will describe the key components of a framework for tackling refactoring and I will share some of the learnings accumulated along the way. Hopefully, this will help you in your quest of improving the code quality of your codebases.

Workshops on related topic

AI on Demand: Serverless AI
DevOps.js Conf 2024DevOps.js Conf 2024
163 min
AI on Demand: Serverless AI
Top Content
Featured WorkshopFree
Nathan Disidore
Nathan Disidore
In this workshop, we discuss the merits of serverless architecture and how it can be applied to the AI space. We'll explore options around building serverless RAG applications for a more lambda-esque approach to AI. Next, we'll get hands on and build a sample CRUD app that allows you to store information and query it using an LLM with Workers AI, Vectorize, D1, and Cloudflare Workers.
Make a Game With PlayCanvas in 2 Hours
JSNation 2023JSNation 2023
116 min
Make a Game With PlayCanvas in 2 Hours
Featured WorkshopFree
Steven Yau
Steven Yau
In this workshop, we’ll build a game using the PlayCanvas WebGL engine from start to finish. From development to publishing, we’ll cover the most crucial features such as scripting, UI creation and much more.
Table of the content:- Introduction- Intro to PlayCanvas- What we will be building- Adding a character model and animation- Making the character move with scripts- 'Fake' running- Adding obstacles- Detecting collisions- Adding a score counter- Game over and restarting- Wrap up!- Questions
Workshop levelFamiliarity with game engines and game development aspects is recommended, but not required.
Working With OpenAI and Prompt Engineering for React Developers
React Advanced Conference 2023React Advanced Conference 2023
98 min
Working With OpenAI and Prompt Engineering for React Developers
Top Content
Workshop
Richard Moss
Richard Moss
In this workshop we'll take a tour of applied AI from the perspective of front end developers, zooming in on the emerging best practices when it comes to working with LLMs to build great products. This workshop is based on learnings from working with the OpenAI API from its debut last November to build out a working MVP which became PowerModeAI (A customer facing ideation and slide creation tool).
In the workshop they'll be a mix of presentation and hands on exercises to cover topics including:
- GPT fundamentals- Pitfalls of LLMs- Prompt engineering best practices and techniques- Using the playground effectively- Installing and configuring the OpenAI SDK- Approaches to working with the API and prompt management- Implementing the API to build an AI powered customer facing application- Fine tuning and embeddings- Emerging best practice on LLMOps
Building a Shopify App with React & Node
React Summit Remote Edition 2021React Summit Remote Edition 2021
87 min
Building a Shopify App with React & Node
Top Content
WorkshopFree
Jennifer Gray
Hanna Chen
2 authors
Shopify merchants have a diverse set of needs, and developers have a unique opportunity to meet those needs building apps. Building an app can be tough work but Shopify has created a set of tools and resources to help you build out a seamless app experience as quickly as possible. Get hands on experience building an embedded Shopify app using the Shopify App CLI, Polaris and Shopify App Bridge.We’ll show you how to create an app that accesses information from a development store and can run in your local environment.
PlayCanvas End-to-End : the quick version
JS GameDev Summit 2022JS GameDev Summit 2022
121 min
PlayCanvas End-to-End : the quick version
Top Content
WorkshopFree
João Ruschel
João Ruschel
In this workshop, we’ll build a complete game using the PlayCanvas engine while learning the best practices for project management. From development to publishing, we’ll cover the most crucial features such as asset management, scripting, audio, debugging, and much more.
Build a chat room with Appwrite and React
JSNation 2022JSNation 2022
41 min
Build a chat room with Appwrite and React
WorkshopFree
Wess Cope
Wess Cope
API's/Backends are difficult and we need websockets. You will be using VS Code as your editor, Parcel.js, Chakra-ui, React, React Icons, and Appwrite. By the end of this workshop, you will have the knowledge to build a real-time app using Appwrite and zero API development. Follow along and you'll have an awesome chat app to show off!