Estou desenvolvendo uma IA de jogo de estratégia (pense em Final Fantasy Tactics), e estou tendo problemas para chegar ao design da IA. Meu principal problema é determinar qual é a melhor coisa para fazer.
Primeiro, deixe-me descrever a prioridade de quais ações eu gostaria que a IA executasse:
Mate a unidade de jogador mais próxima
Cumprir a diretiva principal (matar todas as unidades de jogador, matar a unidade alvo, sobreviver por x turnos)
- Unidade de cura aliada / buffer de conjuração
Agora a IA pode fazer o seguinte por sua vez:
Mover -> {Ataque / Habilidade / Item} (ataque ou habilidade ou item)
{Ataque / Habilidade / Item} -> Mover
Aproxime-se (se os alvos não estiverem dentro do alcance)
- {Ataque / Habilidade / Item} (se a movimentação não estiver disponível)
Notas
As habilidades têm vários intervalos / efeitos / custos / efeitos. Cada unidade ai tem talvez de 5 a 10 habilidades para escolher. A IA priorizará a matança sobre a segurança, a menos que sua diretiva seja sobreviver por x turnos. Também não se preocupa com a capacidade que custa muito. Embora um jogador queira salvar um grande feitiço para mais tarde, a IA provavelmente o usará o mais rápido possível.
O movimento está em uma grade (hex)
número de unidades de jogador: 3-6
num de unidades ai: 3-7 ou mais. Provavelmente no máximo 10.
A IA e o jogador se revezam no controle de UMA unidade, em vez de todos ao mesmo tempo.
A plataforma é Android (se o programa não responder depois de algum tempo, haverá um pop-up dizendo Forçar Quit ou Esperar - o que parece muito ruim!).
Agora vem as perguntas:
A melhor habilidade de usar seria obviamente aquela que atingir mais alvos e causar mais danos. Mas como cada habilidade tem diferentes intervalos, não saberei se eles estão dentro do alcance sem explorar cada lugar possível para onde posso me mudar.
Uma solução seria percorrer todos os lugares possíveis para onde ir, determinar o ataque ideal naquele local - o que me fornece uma lista dos movimentos ideais para cada local. Em seguida, escolha o ideal da lista e execute-o. Mas isso levará muito tempo de CPU. Existe uma solução melhor?
Minha idéia atual é mover o mais próximo possível para o maior grupo de pessoas mais próximo e determinar o ataque / habilidade ideal a partir daí. Eu acho que isso seria muito menos trabalhoso para a CPU e ainda permitir ataques de grande alcance. Está abaixo do ideal, mas a IA ainda parecerá 'inteligente'.
Outras notas / perguntas:
- Estou pensando demais / complicando demais? Melhor solução? Estou aberto a todos os tipos de sugestões
- Dei uma olhada na pergunta de lançamento de feitiços , mas ela não leva em conta o movimento - então talvez use esse algo para cada local de movimento possível? A resposta principal mencionou que não era ótimo para lutas por área de efeito e grupo - então talvez exija mais ajustes?
- Por favor , se você mencionar um gráfico / árvore, deixe-me saber basicamente como usá-lo. Por exemplo, Nó significa habilidade, o nível corresponde ao dano e, em seguida, procure o nó mais profundo.
Ao longo dos anos, escrevi três IAs de jogos, que jogaram um jogo respeitável.
Dois dos casos tinham opções limitadas por turno, então eu explorei todas as possibilidades e avaliei as posições resultantes - alterei a profundidade que pesquisei com base na dificuldade e não foram necessárias muitas camadas para formar um oponente bastante respeitável. Eu poderia obter algumas camadas e ainda ter uma resposta em um ou dois segundos, e isso foi em alguns processadores bastante antigos. (Tudo isso foi antes do Windows entrar em cena.) A qualidade da análise de posição é MUITO importante ao usar essa abordagem.
O terceiro caso não permitiu essa análise, já que o número de possíveis movimentos por turno poderia facilmente exceder as partículas do universo. Era uma situação parecida com um território de risco, com vários exércitos, mas era possível fazer qualquer número de movimentos por turno, o fator principal sendo os movimentos levavam tempo. Uma província ao lado geralmente fazia uma curva, uma do outro lado do mapa poderia levar 9.
Eu usei uma abordagem totalmente diferente aqui. Decidi o percentual de forças a serem alocadas em defesa e as alocadas com base no valor do território e na ameaça inimiga estimada (embora você pudesse ver quais forças seu oponente se movia, você não podia ver para onde estavam indo - assumiu o os humanos concentrariam suas forças em algum lugar e imaginaram que era muito mais provável que chegassem a todos de uma vez, em vez de aos poucos.) Tudo o que não era necessário para a defesa ficava disponível para o ataque. Eu olhei para cada objetivo possível e calculei o que seria necessário para ter uma boa chance de levá-lo rapidamente (uma batalha prolongada destruiria basicamente toda a sua produção) e gerou um conjunto de ordens de ataque para ele. O valor do pedido era o valor da província, o custo foi o número de exército / turnos comprometidos com o ataque. Escolha o valor mais alto e execute as ordens, repita até que as forças disponíveis não aguentem nada. O tempo de execução foi trivial.
Espero ter lhe dado algumas idéias aqui.
fonte
Sua observação sobre desistência / espera sugere que você esteja fazendo todo o trabalho de processamento no thread principal do aplicativo. Você poderia, supondo que exista suporte de encadeamento suficiente no SDK do Android (o que eu suponho que deva existir), descarregar a parte "pensante" da sua IA para um encadeamento de trabalho, enquanto o encadeamento principal exibe um "AI do jogo" está considerando. "UI, mas é processado normalmente.
É claro que existem boas razões para não querer fazer isso, como não querer que a IA demore tanto tempo, porque o jogador ficará entediado.
Quanto à sua pergunta real, embora sua "ideia atual" seja viável, é muito simples. É um bom ponto de partida, no entanto. É um sistema em que a IA é puramente focada em resultados - tentando no máximo um valor (dano). Outras opções incluem uma abordagem focada no alvo, na qual você escolhe um alvo da equipe adversária (aleatoriamente, um com mais HP, alguma combinação deles, etc.), e se move para esse alvo, tentando danificá-lo.
Uma coisa que você pode querer considerar é atribuir a cada habilidade um status de 'poder' ou 'eficácia' escondido do jogador e usado apenas internamente pela sua IA. Você mesmo determina os valores dessa estatística, com base no seu próprio conhecimento das habilidades como programador do jogo.
Sua IA selecionaria sua capacidade mais alta e tentaria usá-la, se não puder, por qualquer motivo, escolher a próxima, etc. Se construído de maneira suficientemente geral, você poderá começar a unir esses dois sistemas, para que, depois de estabelecer um alvo, tenha heurísticas para os melhores tipos de ataques a esse alvo (por exemplo, avalie um ataque que cause dano de MP como mais eficaz se o alvo tem MP alto).
fonte