Escribimos AI para Vindinium en computadoras de una sola placa. Parte 2: lógica de decisión

Una serie de artículos sobre cómo escribir IA para un juego multijugador en línea del género roguelike.


Parte 1
Parte 3


En esta parte del artículo, consideraremos los enfoques para crear lógica para la IA, hablaremos un poco sobre el establecimiento de objetivos de cada bot respetuoso de la ley, y también determinaremos la elección de un lenguaje de programación y escribiremos algo de código.


imagen


Vindinium Game World


Para crear IA, debes comprender la estructura del mundo del juego.


Traducción gratuita de la documentación del juego

Descripción


Vindinium es un bagel multijugador por turnos. Cada uno de los cuatro jugadores tiene un héroe que puede moverse por el mapa. El objetivo es que los jugadores recojan la cantidad máxima de oro dentro de un número determinado de movimientos (cada jugador realiza 300 movimientos por juego, por lo que el juego completo consta de 1200 movimientos). Los jugadores deben tomar el control de las minas de oro para producir oro; sin embargo, las minas están protegidas por duendes. Cuando un jugador derrota a un duende, se convierte en el dueño de la mina y recibe un oro por turno. Además, el duende ahora protege la mina de otros jugadores.


Los héroes pueden luchar entre ellos. Un sobreviviente en la batalla obtiene el control de todas las minas de oro de su oponente. El héroe asesinado renace inmediatamente con todo su oro, sin embargo, todas las minas pasan a manos del asesino.


Al dirigirse a la taberna, los héroes pueden comprar cerveza por 2 unidades de oro, restaurando así sus puntos de salud.


El objetivo es crear un programa de computadora (bot) que juegue el juego Vindinium de la manera más razonable posible. Se recomienda que utilice uno de los kits de inicio para una gran cantidad de lenguajes de programación como punto de partida.


Mapa


Los mapas se crean al azar. Cada objeto del juego en el mapa está codificado con dos personajes. Ejemplo de mapa:


+----------------------------------------+ |######$- $-############$- $-######| |###### ## ## ######| |####[] #### #### []####| |## #### ## ## #### ##| |#### $- $- ####| |########## @1 @4 ##########| |############ #### #### ############| |$-##$- ############ $-##$-| | $- $-################$- $- | | ######################## | | ######################## | | $- $-################$- $- | |$-##$- ############ $-##$-| |############ #### #### ############| |########## @2 @3 ##########| |#### $- $- ####| |## #### ## ## #### ##| |####[] #### #### []####| |###### ## ## ######| |######$- $-############$- $-######| +----------------------------------------+ 

Leyenda


## - Bosque irresistible
@1 - El primer héroe
[] - Tabernas
$- - Mina de oro (dibujada)
$1 - Mina de oro (propiedad del primer héroe)


Los mapas generados son simétricos y siempre contienen 4 tabernas y 4 héroes.


Héroe


Los héroes pueden mover una celda por turno y tener los siguientes indicadores:


  • Puntos de vida (HP): cada jugador "nuevo" comienza con un valor máximo = 100. Si HP cae a cero, el héroe muere (ver la sección "Muerte del héroe").
  • Oro: a partir de cero, este es un indicador del éxito del héroe. Al final del juego, los héroes serán evaluados en función de su cantidad de oro.
  • El número de minas de oro.

Dirección de viaje


El bot debe emitir un pedido por turno. Órdenes posibles: ( Stay ), ( North ), ( South ), ( East ) u ( West ). Tan pronto como se ejecuta la orden, el héroe permanece en su lugar o mueve una celda en una dirección determinada.


Movimiento héroe

Si el heroe:


  • Intentando ir más allá del mapa o atravesar árboles, no pasa nada.
  • Entra en la mina de oro, permanece en su lugar y:
    • Si la mina ya pertenece al héroe, no pasa nada.
    • Si la mina no es tierra de nadie o pertenece a otro héroe, hay una batalla con el guardia goblin, que protege la mina. El héroe pierde 20 puntos de vida. Si sobrevive, míaalo.
  • Él pisa a otro héroe, permanece en su lugar y no pasa nada. Las peleas de héroes se deciden al final del turno.
  • Entra en la taberna, permanece en su lugar y se ordena comer. El héroe paga 2 de oro y restaura 50 de salud. Tenga en cuenta que la cantidad de vida no puede superar las 100 unidades.
  • No envía una orden en el tiempo asignado para tomar una decisión (1 segundo), permanece en su lugar hasta el final del juego, se hace imposible enviar nuevas órdenes. Tenga en cuenta que aún puede ganar si tiene más oro al final del juego que otros jugadores.

Fin de turno


Después de que el héroe se haya movido (o haya decidido quedarse quieto), sucederán las siguientes cosas:


Batallas

Los héroes están un poco nerviosos y nunca pierden la oportunidad de golpearse con grandes espadas. Al final del turno del héroe, si hay un enemigo a una distancia de una casilla en cualquier dirección, el héroe lo ataca. Por ejemplo, en esta situación, al final del turno del primer héroe ( @1 ):


 ######## ##@1@2## ## @3## ######## 

El jugador 1 ataca al segundo jugador, pero no toca al tercero, porque el tercero está a una distancia de dos casillas de él.
El atacante no pierde unidades de salud, el defensor pierde 20 unidades.
Si el defensor muere (ver: Muerte de un héroe), el atacante obtiene el control de todas las minas de oro del perdedor.


Minería de oro

Después de su turno y batallas con otros héroes (si los hay), el jugador recibe una unidad de oro por cada mina controlada.


Sed

Entonces el héroe pierde una unidad de salud, ya que cualquier acción le da sed.
Tenga en cuenta que los héroes no pueden morir de sed. En el peor de los casos, el valor de su salud cae a la unidad.


Muerte del héroe


Cuando la salud del héroe cae a cero, muere. El héroe aparece inmediatamente en el mapa en su punto de renacimiento, con una reserva de salud completa (100 unidades). El héroe pierde el control de todas sus minas de oro, pero retiene todo su oro acumulado. Ten cuidado cuando el héroe regrese al punto de renacer, cualquier oponente que esté en esta celda muere automáticamente. Por lo tanto, debes evitar quedarte en la celda de generación de uno de los héroes ...


Un héroe no puede morir de sed. La sed puede dejar a un héroe con una unidad de salud, pero no matarlo.


El final del juego


El juego termina cuando se alcanza el número máximo de movimientos (generalmente 300). El ganador es el héroe con más oro. Si dos jugadores tienen la misma cantidad de oro, no hay ganador.


Calificación


El sistema de clasificación de fuerza relativa del jugador usa la Clasificación Elo . La idea es: es mejor ser el primero que el segundo, mejor ser el segundo que el tercero, y así sucesivamente. Espero que el principio sea claro.


Usando múltiples bots a la vez


Puede lanzar simultáneamente varias instancias de sus bots y, en general, utilizar cualquier medida que, en su opinión, sea adecuada para lograr un liderazgo dominante. Pelea


Enlace al original


Vale la pena señalar un par de aspectos más que no se describieron en las reglas, pero se identificaron empíricamente:


  • Si tenemos menos de 21 unidades de salud, pero atacas una mina que no te pertenece, entonces mueres. Sí, sí, no hay protección contra el tonto, aquí todo es serio, como en las batallas reales. Si atacas la mina de nadie, todas tus minas se convierten en tierra de nadie, y si atacas a uno de tus enemigos, tus minas pasan a manos del jugador que posee esta mina.
  • El juego describe el siguiente procedimiento: - - 1 . ¿Y qué sucede si morimos durante la ejecución de la orden (en el juego solo puedes hacerlo muriendo en la batalla con el duende)? Volvemos a nacer (e instantáneamente matamos al jugador que ahora está en nuestro punto de generación), pero perdemos la capacidad de golpear a los enemigos cercanos y tampoco perdemos 1 salud debido a la sed.
  • Habiendo matado al enemigo parado en nuestro punto de generación durante nuestro renacimiento, capturamos sus minas, jeje.
  • El mapa tiene una apariencia cuadrada, la longitud del mapa toma valores pares en el segmento [8, 28].

"Aprende de tus enemigos y entenderás sus puntos fuertes"


Vindinium es un juego público, su lado útil es que podemos mirar el perfil de cualquier jugador y ver las últimas cien peleas con su participación. "¡Excelente! Es hora de usar redes neuronales, porque tenemos 50 jugadores principales, tomemos los 10 primeros, cada una de las últimas 100 peleas contiene ~ 300 momentos en los que el jugador tuvo que tomar una decisión, totalizando alrededor de 200-300 mil unidades ¡material para capacitación! Y puede rotar cada situación en el sentido de las agujas del reloj, espejo, etc., para obtener aún más material para capacitación y consolidar el resultado, esto nos dará hasta 4.8-7.2 millones de unidades de material "- salió la voz de la razón. Sí, de hecho, esa idea tiene derecho a existir. Además, las redes neuronales tienen muchas ventajas.


  • Todo el material de capacitación se analiza fácilmente desde una fuente abierta.
  • Se abre un amplio alcance para la reflexión sobre la visión por computadora:
    • Puede dejar todo como está, habrá 28 * 28 neuronas de entrada (si el mapa es más pequeño, llénelo de árboles);
    • Puede centrarse cada vez de acuerdo con la posición del héroe (tal vez traerá un resultado sorprendente);
    • Puede presentar el mapa en forma de gráfico, lo que facilita enormemente el trabajo de la red neuronal en la búsqueda de patrones; Esta opción permitirá a la neurona encontrar rápidamente patrones de comportamiento complejo y comprender rápidamente por qué, si tenemos poca salud, vamos a una taberna distante, si solo hay otra taberna en un par de células de nosotros, incluso si el enemigo está justo al lado;
  • Una red neuronal ya capacitada, dada la tarea de consumir recursos por adelantado, se puede colocar de manera compacta en 512 megabytes de RAM que se nos asignan (de hecho, resultan unos 480 megabytes), tanto que la potencia de una computadora de placa única es suficiente para los cálculos.

Sin embargo, el maximalismo adolescente en mí quiere ir por el camino más complicado: no establecer la búsqueda de patrones en la red neuronal, sino hacer este trabajo por mi cuenta, confiando en la mayor plasticidad intuitiva de esta solución.


Entonces Árboles de decisión, recorte alfa beta, minimaxes ... ¡tareas demasiado exigentes! En el subreddit Vindinium, varios desarrolladores, revelando el velo de los secretos de sus bots, ya han utilizado esta solución, y probablemente no en tales condiciones espartanas. Desafortunadamente, en esta área es poco probable que se pueda hacer algo mejor que el resto.


Después de leer artículos sobre algoritmos genéticos evolutivos, resolver árboles, desenterré conocimiento secreto - campos potenciales. Puedes leer más sobre ellos aquí y aquí . Esta idea parecía muy funcional, porque el campo potencial es un gráfico plano, se coloca una función en cada enlace, que depende de los datos de entrada (en particular, la distancia desde el objeto, pero nadie se molesta en hacer más condiciones). Todo esto encaja perfectamente en la realidad de Vindinium: no es necesario buscar la ruta al objeto, si ya está en el algoritmo.


"Sabores bastante específicos"


Veamos las peleas de los personajes principales. Antes de comenzar, elegiremos un favorito, lo seguiremos, lo animaremos, castigaremos las decisiones equivocadas al estilo de "pero habría actuado en este lugar ...". Después de una docena de peleas, ya puedes hacer el primer boceto de lo que es una IA respetuosa de la ley (las condiciones se verifican en orden):


  1. No debes acercarte al punto de generación del enemigo si el enemigo tiene la posibilidad de morir (es decir, si podemos esperar una muerte sin gloria mientras estamos parados en el punto de generación del enemigo);
  2. Es una tontería luchar contra tu enemigo cerca de su punto de generación, ya que seguirá siendo como un fénix claro con plena salud e intentará capturar nuestras minas honestamente saqueadas;
  3. Si el enemigo está cerca de nosotros y nosotros estamos cerca de la taberna, es hora de emborracharse. A juzgar por las numerosas batallas sangrientas cerca de los medios de subsistencia y relajación, esta regla es muy relevante;
  4. Si no podemos vencer al enemigo / enemigos, pero logramos correr a la taberna, corremos;
  5. Si no podemos derrotar al enemigo / enemigos Y no tenemos tiempo para llegar a la taberna, entonces:
    • Si podemos matarnos en una granja de nadie, nos matamos al respecto. ¡Dale un mordisco!
    • Si podemos morir por la placa de mina de una persona con la menor cantidad de oro, nos damos cuenta de ello;
    • Si nos espera un triste final, entonces debemos tener la mayor salud posible de este reptil, ¡que recuerde su error durante mucho tiempo!
  6. Si hay un enemigo al que podemos matar dentro de dos de nuestros movimientos y él tiene Mine-Lines, atacamos;
  7. Si hay un enemigo que está más alejado de todos los minilocks que nosotros, y él tiene un 33% de minilock bajo control Y podemos derrotarlo: vamos a ganar, de lo contrario vamos a beber cerveza;
  8. Capturamos granjas si no queda nada más.

Q & A:


  • ¿Cuáles son sus ventajas sobre las redes neuronales que pueden hacer esta tarea cien veces mejor, o los árboles que todos sus próximos pasos conocen y ya han desarrollado contramedidas, todo lo que queda es usar una buena función de evaluación?
  • (1) Multifuncionalidad. Es más fácil cambiar los parámetros, agregar nuevas funciones. Sigue a un personaje así, se regocija y luego bam, y ve que en un momento dado podría haber actuado de manera completamente diferente, más prudente, estamos escribiendo una nueva regla o cambiando la anterior. (2) También sabemos exactamente qué decisión guió el programa al elegir un movimiento en particular. (3) Los campos potenciales se han mostrado bien en bagels como la base para la inteligencia artificial de los bots.


  • Demuestre que su enfoque es válido, que sus intenciones valen algo.
  • En la tabla de clasificación, Zaraza 0.1 cuelga en el lugar 27: IA en campos potenciales, que se guía solo por tres instintos: agarra sin pensar todo lo que se interpone en su camino, no se seque en barras y se comporte con cuidado con los enemigos. Si sigues sus movimientos, verás qué tan bien pelea, aunque esto es simplemente increíble para la IA, que se basa en tres reglas simples y ni siquiera soñará con un comportamiento complicado. Además, ahora estoy trabajando en Zonko 0.11 , que es una versión muy mejorada de la bebida de Zaraz, puede integrar un comportamiento mucho más complejo debido a una mejor interacción con los campos, al igual que en un GPS novedoso. Pero, como resultó, es voraz sobre los recursos, por lo que el proceso de optimización está sucediendo ahora ... Pero estoy divagando, ahora estamos hablando de restricciones estrictas, reglas estrictas estrictas (...).


  • ¡Tus creencias son ridículas, tu fe es demasiado débil! ¡Puedo crear una IA en nombre_método y te destrozará!
  • Será muy agradable escuchar los pensamientos de otras personas sobre este tema. Además, para ti, ya he reunido todas las peleas de los 10 mejores jugadores, solo 1000 peleas y alrededor de 1,000,000 de movimientos - enlace (.zip - 33MB, RAW - 1.68GB). Ofrezco las condiciones del juego:
    • Registre bots bajo sus apodos en geektimes.
    • A los cinco jugadores que anotaron más puntos antes del 30 de septiembre que yo o cualquier otra persona que haya indicado jugar, les enviaré una postal desde Moscú).

Entonces, ahora el lenguaje de programación ... Personalmente, ahora me estoy apresurando entre Python3 (desarrollo rápido, fácil de leer, familiarizado con él durante mucho tiempo, hay pypy3 (intérprete optimizado rápido), jupyter ("cuadernos" en los que puede escribir con seguridad piezas de código y optimizarlas para infinito); pero pypy / pypy3 no funciona bajo ARM de 64 bits, y de hecho ARM ya no es compatible, y el lenguaje en sí es inferior a los compilados por su naturaleza) y Golang (también desarrollo rápido, es fácil de entender, un gran sesgo hacia el backend, multiproceso y multiprocesamiento, corre más rápido que python; pero con etsya para acostumbrarse a la ausencia de un entorno interactivo para tipos estáticos).


La función principal que se comunica con el servidor se puede representar de la siguiente manera:


Código
 #     train_url, arena_url, userkey,   config.py from config import train_url, arena_url, userkey import requests, random, json, time def start(is_train = True, debug = True, show_decision = True): #   if is_train: r = requests.post(train_url, data={"key":userkey}) else: r = requests.post(arena_url, data={"key":userkey}) timer = time.time() data = json.loads(r.text) if debug or show_decision: print('viewUrl:', data['viewUrl']) print(' :', data['game']['board']['size']) # while True: if debug: print('Turn', data['game']['turn']) #     direction = random.choice(['North', 'South', 'East', 'West', 'Stay']) if show_decision or debug: print(' ',str(data['game']['turn'])+':', direction) #    ,   ,  . if debug: print(':',time.time()-timer) r = requests.post(data['playUrl'], data={'key': userkey, 'dir': direction}) timer = time.time() if r.status_code != 200: print('Request code :', r.status_code) print('Reason:', r.reason) break data = json.loads(r.text) if data['game']['finished']: print('Game finished.') break 

Pero se recomienda utilizar desarrollos estándar, cuyos enlaces se pueden encontrar en el sitio web oficial de Vindinium.


Extra 1: Realmente quiero leer sobre el desarrollo de la inteligencia artificial basada en Vindinium de otras personas, porque de esta manera puedes entender la naturaleza multifacética de resolver este problema. Para obtener el resumen de la batalla en formato json (esto puede ser útil para depurar peleas), debe convertir el enlace a la batalla del formulario http://vindinium.org/fd96vc2z al enlace del formulario http://vindinium.org/events/fd96vc2z . Pero no aconsejo atormentar el servidor del juego, tratar de obtener cientos de peleas de los mejores jugadores, use el enlace de arriba.


Extra 2: si alguien quiere intentar ejecutar su tiempo de funcionamiento en Vindinium con las limitaciones de NanoPi Neo2 o Orange Pi Zero, puedo brindarle la oportunidad de trabajar con estas computadoras de placa única.


Enlace a Vindinium
→ El enlace al subreddit de Vindinium es algo muy útil, allí puedes seguir mis movimientos en Vindinium
Enlace a mi github con una pequeña cantidad de trabajo en Vindinium


En la siguiente parte, estableceremos campos potenciales, trabajaremos con mapas potenciales, escribiremos condiciones e impondremos todo esto a las realidades modernas.

Source: https://habr.com/ru/post/es405849/


All Articles