IA com Python - Jogos

Os jogos são jogados com uma estratégia. Cada jogador ou equipe faria uma estratégia antes de iniciar o jogo e eles teriam que mudar ou construir uma nova estratégia de acordo com a (s) situação (ões) atual (is) no jogo.

Algoritmos de Pesquisa

Você terá que considerar os jogos de computador também com a mesma estratégia acima. Observe que os algoritmos de pesquisa são os que descobrem a estratégia em jogos de computador.

Como funciona

O objetivo dos algoritmos de busca é encontrar o conjunto ideal de jogadas para que possam chegar ao destino final e vencer. Esses algoritmos usam o conjunto de condições vencedoras, diferente para cada jogo, para encontrar os melhores movimentos.

Visualize um jogo de computador como uma árvore. Sabemos que essa árvore tem nós. Começando pela raiz, podemos chegar ao nó vencedor final, mas com movimentos ótimos. Esse é o trabalho dos algoritmos de busca. Cada nó dessa árvore representa um estado futuro. Os algoritmos de busca buscam nesta árvore para tomar decisões em cada etapa ou nó do jogo.

Pesquisa Combinacional

A principal desvantagem de usar algoritmos de pesquisa é que eles são exaustivos por natureza, por isso exploram todo o espaço de pesquisa para encontrar a solução que leva ao desperdício de recursos. Seria mais complicado se esses algoritmos precisassem pesquisar todo o espaço de pesquisa para encontrar a solução final.

Para eliminar esse tipo de problema, podemos utilizar a busca combinacional que utiliza a heurística para explorar o espaço de busca e reduz seu tamanho eliminando os possíveis movimentos errados. Conseqüentemente, esses algoritmos podem economizar recursos. Alguns dos algoritmos que usam heurística para pesquisar o espaço e economizar recursos são discutidos aqui -

Algoritmo Minimax

É a estratégia de busca combinacional que utiliza heurística para agilizar a estratégia de busca. O conceito de estratégia Minimax pode ser entendido com o exemplo dos jogos de dois jogadores, em que cada jogador tenta prever o próximo movimento do adversário e tentar minimizar essa função. Além disso, para ganhar, o jogador sempre tenta maximizar sua função com base na situação atual.

A heurística desempenha um papel importante em estratégias como o Minimax. Cada nó da árvore teria uma função heurística associada a ele. Com base nessa heurística, ele tomará a decisão de fazer um movimento em direção ao nó que mais os beneficiaria.

Poda alfa-beta

Um grande problema com o algoritmo Minimax é que ele pode explorar aquelas partes da árvore que são irrelevantes, levando ao desperdício de recursos. Portanto, deve haver uma estratégia para decidir qual parte da árvore é relevante e qual é irrelevante e deixar a parte irrelevante inexplorada. A poda alfa-beta é um desses tipos de estratégia.

O objetivo principal do algoritmo de poda Alfa-Beta é evitar a busca por partes da árvore que não têm solução. O principal conceito da poda alfa-beta é usar dois limites chamadosAlpha, o limite inferior máximo e Beta, o limite superior mínimo. Esses dois parâmetros são os valores que restringem o conjunto de soluções possíveis. Ele compara o valor do nó atual com o valor dos parâmetros alfa e beta, para que ele possa se mover para a parte da árvore que tem a solução e descartar o resto.

Algoritmo Negamax

Este algoritmo não é diferente do algoritmo Minimax, mas tem uma implementação mais elegante. A principal desvantagem de usar o algoritmo Minimax é que precisamos definir duas funções heurísticas diferentes. A conexão entre essas heurísticas é que, quanto melhor for o estado de um jogo para um jogador, pior para o outro jogador. No algoritmo Negamax, o mesmo trabalho de duas funções heurísticas é feito com o auxílio de uma única função heurística.

Construindo Bots para Jogar Jogos

Para construir bots para jogar jogos de dois jogadores na IA, precisamos instalar o easyAIbiblioteca. É uma estrutura de inteligência artificial que fornece todas as funcionalidades para construir jogos para dois jogadores. Você pode baixá-lo com a ajuda do seguinte comando -

pip install easyAI

Um bot para jogar a última moeda em pé

Neste jogo, haveria uma pilha de moedas. Cada jogador deve retirar algumas moedas dessa pilha. O objetivo do jogo é evitar tirar a última moeda da pilha. Estaremos usando a classeLastCoinStanding herdado de TwoPlayersGame classe do easyAIbiblioteca. O código a seguir mostra o código Python para este jogo -

Importe os pacotes necessários conforme mostrado -

from easyAI import TwoPlayersGame, id_solve, Human_Player, AI_Player
from easyAI.AI import TT

Agora, herde a classe do TwoPlayerGame classe para lidar com todas as operações do jogo -

class LastCoin_game(TwoPlayersGame):
   def __init__(self, players):

Agora, defina os jogadores e o jogador que vai iniciar o jogo.

self.players = players
self.nplayer = 1

Agora, defina o número de moedas no jogo, aqui estamos usando 15 moedas para o jogo.

self.num_coins = 15

Defina o número máximo de moedas que um jogador pode pegar em uma jogada.

self.max_coins = 4

Agora, existem algumas coisas para definir, conforme mostrado no código a seguir. Defina movimentos possíveis.

def possible_moves(self):
   return [str(a) for a in range(1, self.max_coins + 1)]

Defina a remoção das moedas

def make_move(self, move):
   self.num_coins -= int(move)

Defina quem pegou a última moeda.

def win_game(self):
   return self.num_coins <= 0

Defina quando parar o jogo, ou seja, quando alguém ganhar.

def is_over(self):
   return self.win()

Defina como calcular a pontuação.

def score(self):
   return 100 if self.win_game() else 0

Defina o número de moedas restantes na pilha.

def show(self):
   print(self.num_coins, 'coins left in the pile')
if __name__ == "__main__":
   tt = TT()
   LastCoin_game.ttentry = lambda self: self.num_coins

Resolvendo o jogo com o seguinte bloco de código -

r, d, m = id_solve(LastCoin_game,
   range(2, 20), win_score=100, tt=tt)
print(r, d, m)

Decidindo quem vai começar o jogo

game = LastCoin_game([AI_Player(tt), Human_Player()])
game.play()

Você pode encontrar a seguinte saída e um jogo simples deste jogo -

d:2, a:0, m:1
d:3, a:0, m:1
d:4, a:0, m:1
d:5, a:0, m:1
d:6, a:100, m:4
1 6 4
15 coins left in the pile
Move #1: player 1 plays 4 :
11 coins left in the pile
Player 2 what do you play ? 2
Move #2: player 2 plays 2 :
9 coins left in the pile
Move #3: player 1 plays 3 :
6 coins left in the pile
Player 2 what do you play ? 1
Move #4: player 2 plays 1 :
5 coins left in the pile
Move #5: player 1 plays 4 :
1 coins left in the pile
Player 2 what do you play ? 1
Move #6: player 2 plays 1 :
0 coins left in the pile

Um bot para jogar jogo da velha

Tic-Tac-Toe é muito familiar e um dos jogos mais populares. Vamos criar este jogo usando oeasyAIbiblioteca em Python. O código a seguir é o código Python deste jogo -

Importe os pacotes como mostrado -

from easyAI import TwoPlayersGame, AI_Player, Negamax
from easyAI.Player import Human_Player

Herdar a classe do TwoPlayerGame classe para lidar com todas as operações do jogo -

class TicTacToe_game(TwoPlayersGame):
   def __init__(self, players):

Agora, defina os jogadores e o jogador que vai iniciar o jogo -

self.players = players
self.nplayer = 1

Defina o tipo de placa -

self.board = [0] * 9

Agora, existem algumas coisas para definir a seguir -

Definir movimentos possíveis

def possible_moves(self):
   return [x + 1 for x, y in enumerate(self.board) if y == 0]

Defina a jogada de um jogador -

def make_move(self, move):
   self.board[int(move) - 1] = self.nplayer

Para aumentar a IA, defina quando um jogador faz um movimento -

def umake_move(self, move):
   self.board[int(move) - 1] = 0

Defina a condição de perda em que um oponente tem três em uma linha

def condition_for_lose(self):
   possible_combinations = [[1,2,3], [4,5,6], [7,8,9],
      [1,4,7], [2,5,8], [3,6,9], [1,5,9], [3,5,7]]
   return any([all([(self.board[z-1] == self.nopponent)
      for z in combination]) for combination in possible_combinations])

Defina uma verificação para o fim do jogo

def is_over(self):
   return (self.possible_moves() == []) or self.condition_for_lose()

Mostra a posição atual dos jogadores no jogo

def show(self):
   print('\n'+'\n'.join([' '.join([['.', 'O', 'X'][self.board[3*j + i]]
      for i in range(3)]) for j in range(3)]))

Calcule as pontuações.

def scoring(self):
   return -100 if self.condition_for_lose() else 0

Defina o método principal para definir o algoritmo e iniciar o jogo -

if __name__ == "__main__":
   algo = Negamax(7)
   TicTacToe_game([Human_Player(), AI_Player(algo)]).play()

Você pode ver a seguinte saída e uma simples execução deste jogo -

. . .
. . .
. . .
Player 1 what do you play ? 1
Move #1: player 1 plays 1 :
O . .
. . .
. . .
Move #2: player 2 plays 5 :
O . .
. X .
121
. . .
Player 1 what do you play ? 3
Move #3: player 1 plays 3 :
O . O
. X .
. . .
Move #4: player 2 plays 2 :
O X O
. X .
. . .
Player 1 what do you play ? 4
Move #5: player 1 plays 4 :
O X O
O X .
. . .
Move #6: player 2 plays 8 :
O X O
O X .
. X .