Olá pessoal. Penso que, a partir do cabeçalho, fica claro que falaremos sobre a criação de inteligência artificial (daqui em diante simplesmente AI), sobre quais decisões foram tomadas e o que acabou acontecendo. Mas primeiro você precisa se atualizar.
O jogo está escrito na linguagem de programação Lua, então darei exemplos de código nessa linguagem.
Vou descrever alguns detalhes do jogo que são importantes para a IA:
- O jogo é uma estratégia baseada em turnos. Primeiro, o jogador caminha, depois a IA faz suas ações para cada país. O AI só funciona quando você clica em Avançar e não faz ideia do que acontece em outro momento.
- O jogo tem um mapa no qual você pode recrutar / mover / implantar tropas. A IA deve analisá-lo e tomar as decisões necessárias.
- No jogo, você pode fazer a paz / declarar guerra / assinar um pacto de não agressão / firmar e encerrar alianças. A IA deve ser capaz de lidar com isso.
- As instituições políticas e de tecnologia estão disponíveis apenas para o jogador. Os bônus de IA não mudam desde o início do jogo, diferentemente do jogador.
A função responsável por iniciar a próxima jogada é assim:
function next_step()
Você deve ter notado a função mágica
calc_ai
, responsável por todas as ações dos bots. Você ainda pode ver um detalhe interessante: a função é executada alternadamente para cada país.
Agora, respondemos à pergunta, o que acontece no
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
Até entendermos profundamente como a IA toma decisões na política, observamos o seguinte:
- Há uma verificação de que a IA não vai acidentalmente para o jogador ou para o incompreensível Undeveloped_land. Esta é apenas uma terra sem país (de fato, uma província deve sempre ter um país que a possui; portanto, Undeveloped_land é a designação principalmente para o jogo).
- O AI seleciona tabelas diferentes para interagir com o país, dependendo se o jogador o controla ou não.
- A IA primeiro move o exército e só depois contrata.
fixed_ai_data
- a própria tabela. É nomeado assim porque não muda (mais precisamente, a variável sempre se refere à tabela raiz).
ai_data
- a tabela em si, que muda dependendo se o bot lida com o jogador ou não (a variável se refere simplesmente à tabela desejada).
Na verdade, o jogo tem apenas uma tabela relacionada à IA e fica assim:
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
- nível de dificuldade. Existem vários níveis de dificuldade, e os valores em tabelas diferentes variam.
peace
,
war
- estado do país. A tabela de
peace
é usada para qualquer ação, a tabela de
war
é apenas para ações com o inimigo.
A tabela do terceiro
player
contém as tabelas de
peace
e
war
com os valores alterados. Como você já sabe, em um jogo de IA pode ter uma atitude diferente em relação ao jogador e ao bot.
Os valores nas tabelas, eu acho, são claros por nome. Mas, de qualquer forma, consideraremos alguns deles.
Enquanto isso, precisamos descobrir como a IA funciona no jogo. Tudo é simples aqui, dependendo do estado, o bot pode selecionar qualquer valor da lista. Os números acima são a probabilidade de ocorrência de cada evento. Considere um exemplo:
pact = 0.005
- significa que, com uma chance de 0,005, um país oferecerá outro país para concluir um pacto de não agressão. Sim, tudo é simples. Você pode dizer: "Como então você pode jogar, sabendo que a IA faz tudo aleatoriamente?" Na verdade, não é bem assim, e analisaremos isso um pouco mais tarde.
Enquanto isso, observe a seguinte função:
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
- número aleatório de 0 a 1
state
- estado do país
A função
get_answer
simplesmente retorna uma ação aleatória. Por que é necessário e por que você não pode apenas marcar a
option
<chance de ação, acho que não é necessário explicar.
Esta função está marcada em todas as ações possíveis para o AI:
if __ and get_answer(option, ai_data.peace) == "pact" then _ end
Tudo é simples. Parece, isso pode ser terminado, mas não.
Vamos esclarecer alguns pontos:
- A AI declara guerra a vizinhos e não vizinhos com chances diferentes (
war
, war_neighbour
) - Os países pequenos são mais propensos a ingressar em sindicatos do que os grandes (
alliance
, alliance_small
) - A IA tem inveja. O nome não é totalmente claro, mas é uma chance com a qual o país declarará guerra forte demais pelos padrões do poder do jogo.
- Esquecemos a tabela de bônus. Ele armazena valores que não estão relacionados à atitude em relação a outros países, por exemplo, um bônus ao crescimento da população ou uma chance de melhorar a província.
Isso não terminou aí (a menos que você estivesse interessado, é claro). É estranho quando um país declara guerra sem motivo, e ainda mais estranho quando não está pronto para esta guerra. Portanto, a IA no jogo tem estratégias. Vou explicar que, em vez de um ataque surpresa, na maioria dos casos o país inicia uma estratégia.
Cada país no arquivo salvo possui os seguintes campos:
strategy
- identificador da estratégia. Acontece:
retreat
- um país reduz seu exército para economizar dinheiro.recruit
- o país emprega o exército máximo.
target
é o alvo. Este é qualquer país pelo qual nossa IA decidiu declarar guerra, mas iniciou uma estratégia.ultimatum
- nulo, se não houver ultimato, dados sobre o ultimato, se houver.value
- o número de movimentos antes da declaração de guerra. Não consegui criar um nome de variável melhor, desculpe.
Ou seja, se a IA inicia uma estratégia, ele:
- Reduz seu exército e economiza dinheiro.
- Contrata o exército mais alto possível.
- Declara guerra ao jogador.

Com uma certa chance, um país pode propor um ultimato, em cuja implementação a guerra é cancelada. Por exemplo:
Reduza seu exército na província de lipetsk para 5.000; caso contrário, declararemos guerra a você.Do engraçado: há um bug interessante ou até uma falha quando o país exige reduzir o exército na província, e o jogador consegue perder o ultimato até que ele expire. A IA não leva em conta a província e, se o ultimato não for respeitado, declara guerra.

Existem duas variáveis responsáveis pela chance de apoiar o jogador (transferir ouro para o jogador). O primeiro sempre funciona, exceto o estado de guerra com o país para o qual é calculado. E o segundo, com grande significado, é levado em consideração quando existe um inimigo comum.
Várias variáveis também foram adicionadas, por exemplo, o medo (quanto o exército inimigo deve exceder o seu próprio para que a IA comece a pensar no mundo). Tudo isso é feito para tornar as ações da IA mais lógicas e compreensíveis. Mas enfim, agora sabemos que esse é realmente um acidente disfarçado comum.
Também notei que os jogadores realmente dotam a IA de alguns recursos incomuns para ele. Por exemplo, se em um determinado momento um jogador declarar guerra a vários países, ele pensará antes de tudo que isso é uma conspiração contra ele, e não apenas uma coincidência. E se o jogador receber uma proposta para concluir um pacto de não agressão, ele pensará que o vizinho tem medo de suas terras. Mas, infelizmente, não é assim. A realidade está cheia de decepções.