Nous écrivons l'IA pour Vindinium sur des ordinateurs à carte unique. Partie 2: logique de décision

Une série d'articles sur l'écriture de l'IA pour un jeu multijoueur en ligne du genre roguelike.


Partie 1
3e partie


Dans cette partie de l'article, nous examinerons les approches pour créer une logique pour l'IA, parlerons un peu de la définition des objectifs de chaque bot respectueux des lois, et déterminerons également le choix d'un langage de programmation et rédigerons du code.


image


Vindinium Game World


Pour créer une IA, vous devez comprendre la structure du monde du jeu.


Traduction gratuite de la documentation du jeu

La description


Vindinium est un bagel multijoueur au tour par tour. Chacun des quatre joueurs a un héros qui peut se déplacer sur la carte. L'objectif est que les joueurs collectent la quantité maximale d'or dans un nombre donné de coups (chaque joueur fait 300 coups par partie, donc la partie entière se compose de 1200 coups). Les joueurs doivent prendre le contrôle des mines d'or pour produire de l'or; cependant, les mines sont protégées par des gobelins. Lorsqu'un joueur bat un gobelin, il devient le propriétaire de la mine et reçoit un or par tour. De plus, le gobelin protège désormais la mine des autres joueurs.


Les héros peuvent se battre. Un survivant au combat prend le contrôle de toutes les mines d'or de son adversaire. Le héros tué renaît immédiatement avec tout son or, cependant, toutes les mines passent entre les mains du tueur.


En se dirigeant vers la taverne, les héros peuvent acheter de la bière pour 2 unités d'or, rétablissant ainsi leurs points de vie.


Le but est de créer un programme informatique (bot) qui joue le jeu Vindinium aussi raisonnablement que possible. Il est recommandé d'utiliser comme point de départ l' un des kits de démarrage pour un grand nombre de langages de programmation .


La carte


Les cartes sont créées de manière aléatoire. Chaque objet de jeu sur la carte est codé à l'aide de deux caractères. Exemple de carte:


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

Légende


## - Forêt irrésistible
@1 - Le premier héros
[] - Tavernes
$- - Mine d'or (dessinée)
$1 - Mine d'or (appartenant au premier héros)


Les cartes générées sont symétriques et contiennent toujours 4 tavernes et 4 héros.


Héros


Les héros peuvent déplacer une cellule pour chaque tour et avoir les indicateurs suivants:


  • Points de vie (HP): Chaque joueur "frais" commence avec une valeur maximale = 100. Si les HP tombent Ă  zĂ©ro, le hĂ©ros meurt (voir la section "La mort du hĂ©ros").
  • Or: Ă  partir de zĂ©ro, c'est un indicateur de la rĂ©ussite du hĂ©ros. Ă€ la fin du jeu, les hĂ©ros seront Ă©valuĂ©s en fonction de leur quantitĂ© d'or.
  • Le nombre de mines d'or.

Direction du voyage


Le bot doit émettre une commande par tour. Ordres possibles: ( Stay ), ( North ), ( South ), ( East ) ou ( West ). Dès que l'ordre est exécuté, le héros reste à sa place ou déplace une cellule dans une direction donnée.


Déplacement des héros

Si le héros:


  • En essayant d'aller au-delĂ  de la carte ou de traverser des arbres, rien ne se passe.
  • Il entre dans la mine d'or, il reste en place et:
    • Si la mine appartient dĂ©jĂ  au hĂ©ros, rien ne se passe.
    • Si la mine n'est pas la terre d'un homme ou appartient Ă  un autre hĂ©ros, une bataille a lieu avec le garde gobelin qui garde la mine. Le hĂ©ros perd 20 points de vie. S'il survit, le mien.
  • Il marche sur un autre hĂ©ros, il reste en place et rien ne se passe. Les combats de hĂ©ros sont dĂ©cidĂ©s Ă  la fin du tour.
  • Il entre dans la taverne, il reste en place et se donne l'ordre de manger. Le hĂ©ros paie 2 pièces d'or et redonne 50 points de vie. Veuillez noter que le nombre de points de vie ne peut pas dĂ©passer 100 unitĂ©s.
  • Il n'envoie pas d'ordre dans le temps qui lui est imparti pour prendre une dĂ©cision (1 seconde), il reste en place jusqu'Ă  la fin de la partie, il devient impossible d'envoyer de nouveaux ordres. Veuillez noter qu'il peut toujours gagner s'il a plus d'or Ă  la fin du jeu que les autres joueurs.

Fin de tour


Une fois que le héros a déménagé (ou décidé de rester immobile), les choses suivantes se produisent:


Batailles

Les héros sont un peu nerveux et ne manquent jamais l'occasion de se frapper avec de grosses épées. À la fin du tour du héros, s'il y a un ennemi à une distance d'une case dans n'importe quelle direction, le héros l'attaque. Par exemple, dans cette situation, à la fin du tour du premier héros ( @1 ):


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

Le joueur 1 attaque le deuxième joueur, mais ne touche pas le troisième, car le troisième est à une distance de deux cases de lui.
L'attaquant ne perd pas d'unités de santé, le défenseur perd 20 unités.
Si le défenseur meurt (voir: Mort d'un héros), l'attaquant prend le contrôle de toutes les mines d'or du perdant.


Extraction d'or

Après son tour et ses combats avec d'autres héros (le cas échéant), le joueur reçoit une unité d'or pour chaque mine contrôlée.


La soif

Le héros perd alors une unité de santé, car toute action lui donne soif.
Veuillez noter que les héros ne peuvent pas mourir de soif. Dans le pire des cas, la valeur de leur santé tombe à l'unité.


La mort du héros


Lorsque la santé du héros tombe à zéro, il meurt. Le héros apparaît immédiatement sur la carte à son point de renaissance, avec une réserve de santé complète (100 unités). Le héros perd le contrôle de toutes ses mines d'or, mais conserve tout son or accumulé. Soyez prudent lorsque le héros revient au point de renaître, tout adversaire qui se trouve dans cette cellule meurt automatiquement. Par conséquent, vous devez éviter de rester dans la cellule d'apparition d'un des héros ...


Un héros ne peut pas mourir de soif. La soif peut laisser un héros avec une unité de santé, mais pas le tuer.


La fin du jeu


Le jeu se termine lorsque le nombre maximum de coups (généralement 300) est atteint. Le gagnant est le héros avec le plus d'or. Si deux joueurs ont la même quantité d'or, il n'y a pas de gagnant.


Évaluation


Le système de classement de la force relative du joueur utilise le classement Elo . L'idée est: il vaut mieux être premier que deuxième, mieux vaut deuxième que troisième, et ainsi de suite. J'espère que le principe est clair.


Utiliser plusieurs bots Ă  la fois


Vous pouvez lancer simultanément plusieurs instances de vos bots et, en général, utiliser toutes les mesures qui, à votre avis, conviennent pour atteindre un leadership dominant. Combattez!


Lien vers l'original


Il convient de noter quelques autres aspects qui n'étaient pas décrits dans les règles, mais identifiés empiriquement:


  • Si nous avons moins de 21 unitĂ©s de santĂ©, mais que vous attaquez une mine qui ne vous appartient pas, alors vous mourrez. Oui, oui, il n'y a pas de protection contre le fou, tout est sĂ©rieux ici, comme dans les vraies batailles. Si vous attaquez un no man's mine, toutes vos mines deviennent no man's land, et si vous attaquez l'un de vos ennemis, vos mines passent entre les mains du joueur qui possède cette mine.
  • Le jeu dĂ©crit la procĂ©dure suivante: - - Nous 1 . Et que se passe-t-il si nous mourons pendant l'exĂ©cution de l'ordre (dans le jeu, vous ne pouvez le faire qu'en mourant dans la bataille avec le gobelin)? Nous renaissons (et tuons instantanĂ©ment le joueur qui est maintenant Ă  notre point de rĂ©apparition), mais nous perdons la capacitĂ© de frapper les ennemis Ă  proximitĂ© et nous ne perdons pas non plus 1 point de vie Ă  cause de la soif.
  • Après avoir tuĂ© l'ennemi qui se tenait Ă  notre point d'apparition lors de notre renaissance, nous capturons ses mines, hehe.
  • La carte a une apparence carrĂ©e, la longueur de la carte prend des valeurs paires sur le segment [8, 28].

"Apprenez de vos ennemis et vous comprendrez leurs forces"


Vindinium est un jeu public, son côté utile est que nous pouvons regarder le profil de n'importe quel joueur et voir les cent derniers combats avec sa participation. "Excellent! Il est temps d'utiliser les réseaux de neurones, parce que nous avons 50 meilleurs joueurs, prenons le top 10 d'entre eux, chacun des 100 derniers combats contient ~ 300 moments où le joueur a dû prendre une décision, totalisant environ 200-300 mille unités Et vous pouvez faire pivoter chaque situation dans le sens horaire, miroir, etc., pour obtenir encore plus de matériel pour la formation et consolider le résultat, cela nous donnera jusqu'à 4,8 à 7,2 millions d'unités de matériel "- la voix de la raison est sortie. Oui, en effet, une telle idée a le droit d'exister. De plus, les réseaux de neurones présentent de nombreux avantages.


  • Tout le matĂ©riel de formation est facilement analysĂ© Ă  partir d'une source ouverte.
  • Un large champ est ouvert Ă  la rĂ©flexion sur la vision par ordinateur:
    • Vous pouvez tout laisser tel quel, il y aura 28 * 28 neurones d'entrĂ©e (si la carte est plus petite, remplissez-la d'arbres);
    • Vous pouvez centrer chaque fois en fonction de la position du hĂ©ros (cela apportera peut-ĂŞtre un rĂ©sultat Ă©tonnant);
    • Vous pouvez prĂ©senter la carte sous forme de graphique, facilitant ainsi grandement le travail du rĂ©seau neuronal dans la recherche de modèles; Cette option permettra au neurone de trouver rapidement des schĂ©mas de comportement complexe et de comprendre rapidement pourquoi, si nous avons peu de santĂ©, nous allons dans une taverne Ă©loignĂ©e, s'il n'y a qu'une autre taverne dans quelques cellules de nous, mĂŞme si l'ennemi est juste Ă  cĂ´tĂ©;
  • Un rĂ©seau de neurones dĂ©jĂ  formĂ©, Ă©tant donnĂ© la tâche de consommer des ressources Ă  l'avance, peut ĂŞtre placĂ© de manière compacte dans 512 mĂ©gaoctets de RAM qui nous sont allouĂ©s (en fait, il s'avère environ 480 mĂ©gaoctets), Ă  tel point que la puissance d'un ordinateur monocarte est suffisante pour les calculs.

Cependant, le maximalisme adolescent en moi veut emprunter la voie la plus compliquée - non pas poser la recherche de modèles sur le réseau neuronal, mais faire ce travail par moi-même, le front, en s'appuyant sur la plasticité supérieure intuitive de cette solution.


Alors. Arbres de décision, écrêtage alpha bêta, minimax ... tâches trop exigeantes! Au subreddit Vindinium, plusieurs développeurs, révélant le voile des secrets de leurs bots, ont déjà utilisé cette solution, et probablement pas dans de telles conditions spartiates. Malheureusement, dans ce domaine, il est peu probable que quelque chose puisse être mieux fait que les autres.


Après avoir lu des articles sur les algorithmes génétiques évolutifs, la résolution d'arbres, j'ai déterré des connaissances secrètes - des champs potentiels. Vous pouvez en lire plus ici et ici . Cette idée a semblé très efficace, car le champ potentiel est un graphe planaire, une fonction est placée dans chaque lien, qui dépend des données d'entrée (en particulier, la distance de l'objet, mais personne ne dérange pour créer plus de conditions). Tout cela s'intègre parfaitement dans la réalité de Vindinium - vous n'avez pas besoin de chercher le chemin vers l'objet, s'il est déjà dans l'algorithme.


"Saveurs assez spécifiques"


Regardons les combats des meilleurs personnages. Avant de commencer, nous choisirons un favori, nous le suivrons, l'encouragerons, châtierons les mauvaises décisions dans le style de "mais j'aurais agi à cet endroit ...". Après une dizaine de combats, vous pouvez déjà faire le premier croquis de ce qu'est une IA respectueuse des lois (les conditions sont vérifiées dans l'ordre):


  1. Vous ne devriez pas vous approcher du point d'apparition de l'ennemi si l'ennemi a une chance de mourir (c'est-Ă -dire si nous pouvons nous attendre Ă  une mort peu glorieuse en se tenant sur le point d'apparition de l'ennemi);
  2. Il est insensé de combattre votre ennemi près de son point de réapparition, car il sera toujours comme un phénix clair en pleine santé et tentera à nouveau de capturer nos mines honnêtement pillées;
  3. Si l'ennemi se tient près de nous, et nous nous tenons près de la taverne - il est temps de se saouler. A en juger par les nombreuses batailles sanglantes près des moyens de subsistance et de relaxation, cette règle est très pertinente;
  4. Si nous ne pouvons pas vaincre l'ennemi / les ennemis, mais que nous parvenons Ă  courir vers la taverne, nous courons;
  5. Si nous ne pouvons pas vaincre l'ennemi / les ennemis et que nous n'avons pas le temps d'atteindre la taverne, alors:
    • Si nous pouvons nous tuer dans une ferme sans homme, nous nous en tuons. Prenez une bouchĂ©e!
    • Si nous pouvons mourir Ă  propos de la plaque de mine d'une personne avec la plus petite quantitĂ© d'or, nous l'avons vu par nous-mĂŞmes;
    • Si une triste fin nous attend, alors nous devons prendre autant de santĂ© que possible de ce reptile, laissez-le se souvenir de son erreur pendant longtemps!
  6. S'il y a un ennemi que nous pouvons tuer en moins de deux coups et qu'il a des lignes de mine, nous attaquons;
  7. S'il y a un ennemi plus éloigné de tous les minilocks que nous, et qu'il a 33% de minilock sous contrôle Et nous pouvons le vaincre - nous allons gagner, sinon nous allons boire de la bière;
  8. Nous capturons des fermes s'il ne reste rien d'autre.

Q & R:


  • Quels sont ses avantages par rapport aux rĂ©seaux de neurones qui peuvent accomplir cette tâche cent fois mieux, ou les arbres que tous vos n prochains pas en avant connaissent et ont dĂ©veloppĂ© des contre-mesures, il ne reste plus qu'Ă  bien utiliser la fonction d'Ă©valuation?
  • (1) MultifonctionnalitĂ©. Il est plus facile de modifier les paramètres, d'ajouter de nouvelles fonctions. Vous suivez un tel personnage, rĂ©jouissez-vous, puis bam - et vous voyez qu'Ă  un certain moment vous auriez pu agir complètement diffĂ©remment, plus prudemment - nous Ă©crivons une nouvelle règle ou changeons l'ancienne. (2) Nous savons Ă©galement exactement quelle dĂ©cision a guidĂ© le programme lors du choix d'un mouvement particulier. (3) Les champs potentiels se sont bien rĂ©vĂ©lĂ©s dans les bagels comme base de l'intelligence artificielle des robots.


  • Prouvez que votre approche est valable, que vos intentions valent quelque chose.
  • Dans le classement, Zaraza 0.1 est en 27e position - l'IA sur les champs potentiels, qui est guidĂ©e par seulement trois instincts - saisit sans rĂ©flĂ©chir tout ce qui se met en travers de son chemin, ne se dessèche pas dans les bars et se comporte avec prudence avec les ennemis. Si vous suivez ses mouvements, vous verrez Ă  quel point il se bat, bien que ce soit tout simplement incroyable pour l'IA, qui est basĂ©e sur trois règles simples et qu'il ne rĂŞvera mĂŞme pas d'un comportement compliquĂ©. De plus, maintenant je travaille sur Zonko 0.11 , qui est une version grandement amĂ©liorĂ©e de l'alcool de Zaraz, vous pouvez y intĂ©grer un comportement beaucoup plus complexe en raison d'une meilleure interaction avec les champs - tout comme dans un GPS de nouvelle gĂ©nĂ©ration. Mais, comme il s'est avĂ©rĂ©, il est vorace sur les ressources, donc le processus de son optimisation se dĂ©roule maintenant ... Mais je m'Ă©gare, maintenant nous parlons de restrictions strictes, de règles strictes strictes (...).


  • Vos croyances sont ridicules, votre foi est trop faible! Je peux crĂ©er une IA sur nom_mĂ©thode et cela vous dĂ©chirera!
  • Il sera très agrĂ©able d'Ă©couter les rĂ©flexions d'autres personnes sur ce sujet. De plus, pour vous, j'ai dĂ©jĂ  rassemblĂ© tous les combats des 10 meilleurs joueurs, seulement 1000 combats et environ 1 000 000 de coups - link (.zip - 33MB, RAW - 1,68GB). J'offre les conditions du jeu:
    • Enregistrez des bots sous vos surnoms dans les geektimes.
    • Aux cinq joueurs qui ont marquĂ© le plus de points avant le 30 septembre que moi ou quiconque ayant indiquĂ© jouer, j'enverrai une carte postale de Moscou).

Donc, maintenant le langage de programmation ... Personnellement, je me précipite maintenant entre Python3 (développement rapide, facile à lire, familier depuis longtemps, il y a pypy3 (interprète optimisé rapidement), jupyter ("cahiers" dans lesquels vous pouvez écrire en toute sécurité des morceaux de code et les optimiser pour infini); mais pypy / pypy3 ne fonctionne pas sous ARM 64 bits, et en fait ARM n'est plus pris en charge, et le langage lui-même est inférieur aux compilés par sa nature) et Golang (également développement rapide, il est facile à comprendre, un grand biais vers le backend, le multithreading et le multiprocessing, s'exécute plus rapidement que python; mais avec etsya pour se habituer à l'absence d'un environnement interactif pour le typage statique).


La fonction principale qui communique avec le serveur peut être représentée comme suit:


Code
 #     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 

Mais il est recommandé d'utiliser des développements standard, dont les liens peuvent être trouvés sur le site officiel de Vindinium.


Extra 1: Je veux vraiment lire sur le développement de l'intelligence artificielle basée sur Vindinium d'autres personnes, car de cette façon, vous pouvez comprendre la nature multiforme de la résolution de ce problème. Afin d'obtenir le résumé de la bataille au format json (cela peut être utile pour le débogage des combats), vous devez convertir le lien vers la bataille du formulaire http://vindinium.org/fd96vc2z en lien du formulaire http://vindinium.org/events/fd96vc2z . Mais je ne conseille pas de tourmenter le serveur de jeu, d'essayer d'obtenir des centaines de combats de meilleurs joueurs, utilisez le lien ci-dessus.


Extra 2: Si quelqu'un veut essayer d'exécuter son temps de fonctionnement dans Vindinium dans les limites de NanoPi Neo2 ou Orange Pi Zero, je peux offrir la possibilité de travailler avec ces ordinateurs à carte unique.


→ Lien vers Vindinium
→ Le lien vers le subreddit Vindinium est une chose très utile, là vous pouvez suivre mes mouvements dans Vindinium
→ Lien vers mon github avec un peu de travail sur Vindinium


Dans la prochaine partie, nous allons mettre en place des champs potentiels, travailler avec des cartes potentielles, écrire des conditions et imposer tout cela aux réalités modernes.

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


All Articles