Como automatizar jogos com inteligência artificial

Como automatizar jogos com inteligência artificial

I. Introdução

A ideia de deixar a IA jogar já existia desde o século passado, quando estava mais inclinada aos jogos de tabuleiro. Como gamão, xadrez, etc. No século passado, "Deep Blue" derrotou o campeão de xadrez e, em 2016, "Alpha Go" derrotou o campeão humano de Go.

Até agora, a IA está envolvida em mais do que apenas jogos de tabuleiro. Para jogos como Super Mario e King of Glory, a IA também pode ter um desempenho melhor. Hoje usaremos um exemplo prático para discutir o tópico da IA ​​jogando jogos automaticamente. Este artigo usará um algoritmo de aprendizado de máquina muito simples para permitir que a IA jogue automaticamente o jogo Google Dinosaur.

2. Google Dinosaurs e Aprendizagem Supervisionada

2.1. Google Dinossauro

Se você estiver usando o navegador Chrome, acredito que deve ter visto o seguinte dinossauro:

insira a descrição da imagem aqui
Quando usamos o Chrome para desconectar da Internet para acessar a página da web, esse dinossauro será exibido, ou digite diretamente: chrome://dino na barra de endereços para acessar o jogo diretamente.

A jogabilidade é muito simples, basta pressionar a barra de espaço. Por exemplo, na imagem da esquerda abaixo, se você está prestes a encontrar um obstáculo, você precisa pressionar o espaço, enquanto a imagem da direita abaixo não tem nenhum obstáculo (ou está longe do obstáculo), você não precisa apertar o botão.

insira a descrição da imagem aqui
Claro, há também o caso dos pássaros, que também podemos classificar como saltadores. Todos podem jogar.

2.2. Aprendizado supervisionado

Jogar jogos é frequentemente implementado usando um método chamado aprendizado por reforço, e este artigo usa um método de aprendizado supervisionado relativamente simples.

Este artigo usará o algoritmo de regressão logística para implementar, o código é o seguinte:

from sklearn.linear_model import LogisticRegression # 逻辑回归模型
from sklearn.model_selection import train_test_split    # 数据集拆分
# 1、准备数据
X = [
    # 天河区的坐标
    [1, 1],
    [1, 2],
    [2, 0],
    [3, 2],
    [3, 3],
    # 花都区的坐标
    [7, 7],
    [6, 7],
    [7, 6],
    [8, 6],
    [8, 5]
]
y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]
# 2、拆分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 3、定义模型
model = LogisticRegression()
# 4、填充数据并训练
model.fit(X_train, y_train)
# 5、评估模型
score1 = model.score(X_train, y_train)
score2 = model.score(X_test, y_test)
print(score1, score2)
# 6、预测
input = [
    [4, 4]
]
pred = model.predict(input)
print(pred)

Para obter uma explicação da regressão logística, consulte: Python constrói redes neurais rapidamente
.

Podemos pensar em jogar o jogo como um problema de classificação, ou seja, um problema de classificação binária em que a entrada é a imagem do jogo atual e a saída é 0 e 1 (0 significa pular, 1 significa não pular). Para que a IA jogue o jogo automaticamente, precisamos fazer algumas coisas. Eles são os seguintes:

  1. Jogue o jogo e colete algumas fotos que precisam pular e outras que não precisam de barras
  2. Escolha um algoritmo de classificação apropriado e treine um modelo
  3. Capture a tela do jogo atual, preveja o resultado e determine se você precisa pular
  4. Se você precisar pular, use o programa para controlar o teclado e pressione a tecla de salto

Vamos completar o acima por sua vez.

3. Colete dados

Para coletar dados, precisamos continuar fazendo capturas de tela enquanto jogamos. Aqui, podemos usar Pillowmódulos para obter capturas de tela. PillowO módulo precisa ser instalado separadamente. A instrução de instalação é a seguinte:

pip install pillow

O código para a captura de tela é o seguinte:

import time
from PIL import ImageGrab   # 截图
time.sleep(3)
while True:
    # 截图
    img = ImageGrab.grab()
    # print(img.size) # 960 540 480 270
    img = img.resize((960, 540))
    # 保存图片
    img.save(f'imgs/{
      
      str(time.time())}.jpg')
    # 修改name
    time.sleep(0.1)

Depois de executar o programa, você pode alternar para o Chrome para iniciar o jogo. Após um período de tempo, vamos capturar algumas imagens, que são mais ou menos as seguintes:
insira a descrição da imagem aqui
Neste momento, é a vez da inteligência humana jogar. Colocamos manualmente as cenas que decidimos pular para o imgs/jumpdiretório e colocamos as cenas que não achamos que não precisamos pular para o imgs/nonediretório. . Então você pode ir para o próximo passo.As fotos capturadas aqui geralmente não precisam pular muito, e todas podem ser coletadas várias vezes.

Depois que a coleção estiver completa, podemos ler a imagem e convertê-la em um array unidimensional. Esta parte do código é a seguinte:

import os
import cv2
# 所有图片的全路径
files = [os.path.join(jump_path, jump) for jump in os.listdir(jump_path)] + \
        [os.path.join(none_path, none) for none in os.listdir(none_path)]
X = []
y = [0] * len(os.listdir(jump_path)) + [1] * len(os.listdir(none_path))
# 遍历jump目录下的图片
for idx, file in enumerate(files):
    filepath = os.path.join(none_path, file)
    x = cv2.imread(filepath, 0).reshape(-1)
    X.append(x)

Agora Xe ysão nossas características e objetivos. Com Xe y, você pode começar a treinar o modelo.

4. Treinamento do modelo de classificação

O código para a parte de treinamento é muito simples e podemos salvar o modelo após a conclusão do treinamento. código mostrar como abaixo:

import os
import cv2
import joblib
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
jump_path = os.path.join('imgs', 'jump')    # 需要跳的图片的根目录
none_path = os.path.join('imgs', 'none')    # 不需要跳的图片的根目录
# 所有图片的全路径
files = [os.path.join(jump_path, jump) for jump in os.listdir(jump_path)] + \
        [os.path.join(none_path, none) for none in os.listdir(none_path)]
X = []
y = [0] * len(os.listdir(jump_path)) + [1] * len(os.listdir(none_path))
# 遍历jump目录下的图片
for file in files:
    x = cv2.imread(file, 0).reshape(-1)
    X.append(x)

# 2、拆分数据集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
# 3、定义模型
model = LogisticRegression(max_iter=500)
# 4、训练模型
model.fit(X_train, y_train)
# 5、评估模型
train_score = model.score(X_train, y_train)
test_score = model.score(X_test, y_test)
print(train_score, test_score)
# 保存模型
joblib.dump(model, 'auto_play.m')

A taxa de precisão do treinamento no meu computador está acima de 90% e o efeito geral ainda é bom. Existem algumas áreas para melhoria embora. Aqui estão alguns pontos:

  1. Apenas a parte central da imagem afetará a próxima operação, então você pode optar por fazer algum processamento na imagem de treinamento. Defina as partes superior e inferior para 0. Se este processamento for feito, o mesmo processamento deverá ser feito na aplicação real.
  2. Essas imagens podem não ser adequadas para portabilidade para outros computadores devido à resolução e outros motivos. Todos podem optar por usar um modelo mais complexo, como uma rede CNN.
  3. Como é complicado coletar dados manualmente, você pode optar por fazer algum aprimoramento de dados.

Aqui não fazemos essas melhorias e usamos diretamente o modelo mais simples.

5. Jogue o jogo automaticamente

Jogar jogos automaticamente requer a ajuda do módulo pynput, que é instalado da seguinte forma:

pip install pynput

Podemos usar o seguinte código para conseguir pressionar a barra de espaço do teclado:

from pynput import keyboard
from pynput.keyboard import Key
# 创建键盘
kb = keyboard.Controller()
# 按下空格键
kb.press(Key.space)

Depois de saber como controlar o teclado, podemos usar o modelo para interceptar a previsão, como julgar se deve pressionar o espaço, o código é o seguinte:

import time
import cv2
import joblib
import numpy as np
from PIL import ImageGrab
from pynput import keyboard
from pynput.keyboard import Key

time.sleep(3)
# 0、创建键盘
kb = keyboard.Controller()
# 1、加载模型
model = joblib.load('auto_play.m')
while True:
    # 2、准备数据
    ImageGrab.grab().resize((960, 540)).save('current.jpg')  # 保存当前屏幕截屏
    x = cv2.imread('current.jpg', 0).reshape(-1)
    x = [x]
    # 3、预测
    pred = model.predict(x)
    print(pred)
    # 如果需要跳,则按下空格
    if pred[0] == 0:
        kb.press(Key.space)

Depois de executar o programa acima, abra o navegador para iniciar o jogo. Código do programa e arquivos de imagem: https://download.csdn.net/download/ZackSock/86543410
Endereço do GitHub: https://github.com/IronSpiderMan/AutoPlayGoogleDino

おすすめ

転載: blog.csdn.net/ZackSock/article/details/126908649