Comme j'ai écrit l'IA pour la stratégie au tour par tour

Bonjour à tous. Je pense qu'à partir de la rubrique, il est clair que nous parlerons de la création de l'intelligence artificielle (ci-après simplement l'IA), des décisions qui ont été prises et de ce qui s'est finalement produit. Mais vous devez d'abord vous mettre au courant.

Le jeu est écrit dans le langage de programmation Lua, je vais donc donner des exemples de code dans ce langage.

Je vais décrire quelques détails du jeu qui sont importants pour l'IA:

  1. Le jeu est une stratégie au tour par tour. D'abord, le joueur marche, puis l'IA fait ses actions pour chaque pays. L'IA ne fonctionne que lorsque vous cliquez sur Next move et n'a aucune idée de ce qui se passe à un autre moment.
  2. Le jeu a une carte sur laquelle vous pouvez recruter / déplacer / déployer des troupes. L'IA doit l'analyser et prendre les décisions nécessaires.
  3. Dans le jeu, vous pouvez faire la paix / déclarer la guerre / signer un pacte de non-agression / faire et mettre fin aux alliances. L'IA doit pouvoir y faire face.
  4. La technologie et les institutions politiques ne sont disponibles que pour le joueur. Les bonus d'IA ne changent pas depuis le début du jeu, contrairement au joueur.

La fonction responsable du démarrage du prochain mouvement ressemble à ceci:

function next_step() --     --   ,    for k, v in pairs(game_data.lands) do calc_ai(k) end --  End 

Vous devez avoir remarqué la fonction magique calc_ai , qui est responsable de toutes les actions des bots. Vous pouvez toujours voir un détail intéressant: la fonction est exécutée alternativement pour chaque pays.

Maintenant, nous répondons à la question, que se passe-t-il dans calc_ai .

 function calc_ai(land) if land == game_data.player_land or land == "Undeveloped_land" or not game_data.lands[land] then return end --    ,     for k, v in pairs(game_data.lands) do local option = math.random() --  ,       . if k == game_data.player_land then ai_data = fixed_ai_data[game_data.difficulty].player else ai_data = fixed_ai_data[game_data.difficulty] end end move_army( math.random(), land) --  balance_army( math.random(), land) --   end 

Jusqu'à ce que nous comprenions profondément comment l'IA prend des décisions en politique, nous notons ce qui suit:

  1. Il y a une vérification que l'IA ne va pas accidentellement pour le joueur ou pour l'incompréhensible Undeveloped_land. C'est juste une terre sans pays (En fait, une province devrait toujours avoir un pays qui la possède, donc Undeveloped_land est la désignation principalement pour le jeu).
  2. L'IA sélectionne différentes tables pour interagir avec le pays, selon que le joueur le contrôle ou non.
  3. L'IA déplace d'abord l'armée, puis embauche.

fixed_ai_data - la table elle-même. Il est nommé ainsi car il ne change pas (plus précisément, la variable fait toujours référence à la table racine).
ai_data - la table elle-même, qui change selon que le bot traite avec le joueur ou non (la variable se réfère simplement à la table souhaitée).

En fait, le jeu n'a qu'une seule table liée à l'IA, et elle ressemble à ceci:

 local ai = { standard = { peace = { conquer = 0.0001, war = 0.0002, war_neighbour = 0.004, pact = 0.005, agree_pact = 0.018, alliance = 0.001, alliance_small = 0.002, agree_alliance = 0.002, kick = 0.0005, envy = 0.02 }, war = { agree_peace = 0.005, }, player = { peace = { war = 0.0002, war_neighbour = 0.002, pact = 0.008, agree_pact = 0.08, alliance = 0.001, alliance_small = 0.002, agree_alliance = 0.002, kick = 0.0005, support = 0.005, voluntary_support = 0.002, envy = 0.01 }, war = { agree_peace = 0.02, } }, bonuses = { population_increase = 1.4, money_increase = 1.5, upgrade_province = 0.005 } }, } 

standard - niveau de difficulté. Il existe plusieurs niveaux de difficulté et les valeurs des différents tableaux varient.

peace , war - état du pays. La table de peace est utilisée pour toute action, la table de war est uniquement pour les actions avec l'ennemi.

La troisième table des player contient les tables de peace et de war avec les valeurs modifiées. Comme vous le savez déjà, dans un jeu d'IA peut avoir une attitude différente envers le joueur et le bot.

Je pense que les valeurs dans les tableaux sont claires par leur nom. Mais en tout cas, nous en considérerons certains.

En attendant, nous devons comprendre comment fonctionne l'IA dans le jeu. Tout est simple ici, selon l'état, le bot peut sélectionner n'importe quelle valeur dans la liste. Les nombres ci-dessus sont la probabilité d'occurrence de chaque événement. Prenons un exemple:
pact = 0.005 - signifie qu'avec une chance de 0,005, un pays offrira à un autre pays de conclure un pacte de non-agression. Oui, tout est simple. Vous pouvez dire: "Comment alors jouer, sachant que l'IA fait tout au hasard?" En fait, ce n'est pas tout à fait le cas, et nous analyserons cela un peu plus tard.

En attendant, regardez la fonction suivante:

 function get_answer(option,state) local sum_option = 0 for k, v in pairs(state) do sum_option = sum_option + v if option < sum_option then return k end end if sum_option > 1 then print("AI Error, sum_option > 1") end end 

option - Nombre aléatoire de 0 à 1
state - État du pays
La fonction get_answer renvoie simplement une action aléatoire. Pourquoi est-il nécessaire et pourquoi vous ne pouvez pas simplement cocher l' option <chance d'action, je pense qu'il n'est pas nécessaire d'expliquer.

Cette fonction est cochée dans toutes les actions possibles pour l'IA:

 if __ and get_answer(option, ai_data.peace) == "pact" then _ end 

Tout est simple. Il semblerait que cela puisse être terminé, mais non.

Clarifions quelques points:

  1. AI déclare la guerre aux voisins et aux non-voisins avec des chances différentes ( war , war_neighbour )
  2. Les petits pays sont plus susceptibles d'adhérer à des syndicats que les grands ( alliance , alliance_small )
  3. L'IA a envie. Le nom n'est pas tout à fait clair, mais c'est une chance avec laquelle le pays déclarera la guerre trop forte selon les normes de la puissance du jeu.
  4. Nous avons oublié le tableau des bonus. Il stocke des valeurs qui ne sont aucunement liées à l'attitude envers les autres pays, par exemple, un bonus à la croissance démographique ou une chance d'améliorer la province.

Cela ne s'est pas arrêté là (sauf si vous étiez intéressé, bien sûr). C'est étrange quand un pays déclare la guerre sans raison, et encore plus étrange quand il n'est pas prêt pour cette guerre. Par conséquent, l'IA dans le jeu a des stratégies. Je vais expliquer qu'au lieu d'une attaque surprise, dans la plupart des cas, le pays commence une stratégie.

Chaque pays du fichier de sauvegarde comporte les champs suivants:

  • strategy - identifiant de la stratégie. Ça arrive:
    1. retreat - un pays réduit son armée afin d'économiser de l'argent.
    2. recruit - le pays emploie le maximum d'armée.
  • target est la cible. C'est n'importe quel pays par lequel notre IA a décidé de déclarer la guerre, mais a commencé une stratégie.
  • ultimatum - néant, s'il n'y a pas d'ultimatum, données sur l'ultimatum, le cas échéant.
  • value - le nombre de coups avant la déclaration de guerre. Je ne pourrais pas trouver un meilleur nom de variable, désolé.

Autrement dit, si l'IA commence une stratégie, alors il:

  1. Réduit son armée et économise de l'argent.
  2. Embauche la plus haute armée possible.
  3. Déclare la guerre au joueur.



Avec une certaine chance, un pays peut lancer un ultimatum, dans le cadre duquel la guerre est annulée. Par exemple:
Réduisez votre armée dans la province de Lipetsk à 5 000, sinon nous vous déclarerons la guerre.

Du drôle: il y a un bug intéressant ou même une faille lorsque le pays demande de réduire l'armée dans la province, et le joueur parvient à perdre l'ultimatum jusqu'à son expiration. AI ne prend pas en compte la province et, si l'ultimatum n'est pas respecté, déclare la guerre.



Il y a deux variables qui sont responsables de la chance de soutenir le joueur (transférer de l'or au joueur). Le premier fonctionne toujours, sauf l'état de guerre avec le pays pour lequel il est calculé. Et le second, d'une grande importance, est pris en compte lorsqu'il y a un ennemi commun.

Diverses variables ont également été ajoutées, par exemple, la peur (combien l'armée ennemie devrait dépasser la sienne pour que l'IA commence à penser au monde). Tout cela est fait pour rendre les actions de l'IA plus logiques et compréhensibles. Mais de toute façon, maintenant nous savons qu'il s'agit en fait d'un accident déguisé ordinaire.

J'ai également remarqué que les joueurs dotent vraiment l'IA de fonctionnalités inhabituelles pour lui. Par exemple, si à un certain moment un joueur déclare la guerre à plusieurs pays, alors il pensera d'abord que c'est une conspiration contre lui, et pas seulement une coïncidence. Et si le joueur reçoit une proposition de conclure un pacte de non-agression, il pensera que le voisin a peur pour ses terres. Mais, malheureusement, ce n'est pas le cas. La réalité est pleine de déceptions.

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


All Articles