AI con Python - Gaming

I giochi si giocano con una strategia. Ogni giocatore o squadra farebbe una strategia prima di iniziare il gioco e deve cambiare o costruire una nuova strategia in base alla situazione attuale del gioco.

Algoritmi di ricerca

Dovrai considerare anche i giochi per computer con la stessa strategia di cui sopra. Nota che gli algoritmi di ricerca sono quelli che determinano la strategia nei giochi per computer.

Come funziona

L'obiettivo degli algoritmi di ricerca è trovare l'insieme ottimale di mosse in modo che possano raggiungere la destinazione finale e vincere. Questi algoritmi utilizzano l'insieme di condizioni vincenti, diverse per ogni partita, per trovare le mosse migliori.

Visualizza un gioco per computer come un albero. Sappiamo che l'albero ha nodi. Partendo dalla radice, possiamo arrivare al nodo vincente finale, ma con mosse ottimali. Questo è il lavoro degli algoritmi di ricerca. Ogni nodo in tale albero rappresenta uno stato futuro. Gli algoritmi di ricerca cercano in questo albero per prendere decisioni in ogni fase o nodo del gioco.

Ricerca combinatoria

Il principale svantaggio dell'utilizzo di algoritmi di ricerca è che sono di natura esaustiva, motivo per cui esplorano l'intero spazio di ricerca per trovare la soluzione che porta allo spreco di risorse. Sarebbe più complicato se questi algoritmi dovessero cercare in tutto lo spazio di ricerca per trovare la soluzione finale.

Per eliminare questo tipo di problema, possiamo utilizzare la ricerca combinatoria che utilizza l'euristica per esplorare lo spazio di ricerca e riduce le sue dimensioni eliminando le possibili mosse sbagliate. Quindi, tali algoritmi possono salvare le risorse. Alcuni degli algoritmi che utilizzano l'euristica per cercare lo spazio e salvare le risorse sono discussi qui:

Algoritmo Minimax

È la strategia utilizzata dalla ricerca combinatoria che utilizza l'euristica per accelerare la strategia di ricerca. Il concetto di strategia Minimax può essere compreso con l'esempio di partite a due giocatori, in cui ogni giocatore cerca di prevedere la prossima mossa dell'avversario e cerca di minimizzare quella funzione. Inoltre, per vincere, il giocatore cerca sempre di massimizzare la propria funzione in base alla situazione attuale.

L'euristica gioca un ruolo importante in questo tipo di strategie come Minimax. A ogni nodo dell'albero sarebbe associata una funzione euristica. Sulla base di questa euristica, prenderà la decisione di spostarsi verso il nodo che ne trarrebbe i maggiori benefici.

Potatura alfa-beta

Uno dei problemi principali con l'algoritmo Minimax è che può esplorare quelle parti dell'albero che sono irrilevanti, portando allo spreco di risorse. Quindi deve esserci una strategia per decidere quale parte dell'albero è rilevante e quale è irrilevante e lasciare la parte irrilevante inesplorata. La potatura Alpha-Beta è uno di questi tipi di strategia.

L'obiettivo principale dell'algoritmo di potatura Alpha-Beta è evitare di cercare quelle parti dell'albero che non hanno alcuna soluzione. Il concetto principale della potatura Alpha-Beta è utilizzare due limiti denominatiAlpha, il limite inferiore massimo e Beta, il limite superiore minimo. Questi due parametri sono i valori che restringono l'insieme delle possibili soluzioni. Confronta il valore del nodo corrente con il valore dei parametri alfa e beta, in modo che possa spostarsi nella parte dell'albero che ha la soluzione e scartare il resto.

Algoritmo Negamax

Questo algoritmo non è diverso dall'algoritmo Minimax, ma ha un'implementazione più elegante. Il principale svantaggio dell'utilizzo dell'algoritmo Minimax è che dobbiamo definire due diverse funzioni euristiche. La connessione tra queste euristiche è che, migliore è lo stato di un gioco per un giocatore, peggiore è per l'altro giocatore. Nell'algoritmo Negamax, lo stesso lavoro di due funzioni euristiche viene eseguito con l'aiuto di una singola funzione euristica.

Costruire bot per giocare

Per costruire bot per giocare a giochi a due giocatori in AI, dobbiamo installare il easyAIbiblioteca. È un framework di intelligenza artificiale che fornisce tutte le funzionalità per creare giochi per due giocatori. Puoi scaricarlo con l'aiuto del seguente comando:

pip install easyAI

Un bot per giocare l'ultima moneta rimasta

In questo gioco, ci sarebbe una pila di monete. Ogni giocatore deve prendere un numero di monete da quella pila. L'obiettivo del gioco è evitare di prendere l'ultima moneta della pila. Useremo la classeLastCoinStanding ereditato dal TwoPlayersGame classe di easyAIbiblioteca. Il codice seguente mostra il codice Python per questo gioco:

Importa i pacchetti richiesti come mostrato -

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

Ora eredita la classe da TwoPlayerGame classe per gestire tutte le operazioni del gioco -

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

Ora, definisci i giocatori e il giocatore che inizierà il gioco.

self.players = players
self.nplayer = 1

Ora, definisci il numero di monete nel gioco, qui stiamo usando 15 monete per il gioco.

self.num_coins = 15

Definisci il numero massimo di monete che un giocatore può prendere in una mossa.

self.max_coins = 4

Ora ci sono alcune cose da definire come mostrato nel codice seguente. Definisci le possibili mosse.

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

Definisci la rimozione delle monete

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

Definisci chi ha preso l'ultima moneta.

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

Definisci quando fermare il gioco, cioè quando qualcuno vince.

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

Definisci come calcolare il punteggio.

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

Definisci il numero di monete rimanenti nella pila.

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

Risolvendo il gioco con il seguente blocco di codice -

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

Decidere chi inizierà il gioco

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

Puoi trovare il seguente output e una semplice riproduzione di questo gioco:

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

Un Bot per giocare a Tic Tac Toe

Tic-Tac-Toe è molto familiare e uno dei giochi più popolari. Creiamo questo gioco usando ileasyAIlibreria in Python. Il codice seguente è il codice Python di questo gioco:

Importa i pacchetti come mostrato -

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

Eredita la classe da TwoPlayerGame classe per gestire tutte le operazioni del gioco -

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

Ora, definisci i giocatori e il giocatore che inizierà il gioco -

self.players = players
self.nplayer = 1

Definisci il tipo di tavola -

self.board = [0] * 9

Ora ci sono alcune cose da definire come segue:

Definisci le possibili mosse

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

Definisci la mossa di un giocatore -

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

Per potenziare l'IA, definisci quando un giocatore fa una mossa:

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

Definisci la condizione di sconfitta in cui un avversario ha tre in una linea

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])

Definisci un controllo per la fine del gioco

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

Mostra la posizione attuale dei giocatori nel gioco

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)]))

Calcola i punteggi.

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

Definisci il metodo principale per definire l'algoritmo e avviare il gioco -

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

Puoi vedere il seguente output e una semplice riproduzione di questo gioco:

. . .
. . .
. . .
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 .