利用Python编写一个AI脚本自动控制2048网页小游戏

前言

本文将使用python+selenium自动控制游戏运行。当然采用的是伪随机数进行键盘控制。只作为一个抛砖迎玉的参考,不涉及专业算法。

一、前期准备(必须有)

1、在安装好的pyCharm中导入相应的库

打开pyCharm,点击终端,依次输入:
  1. pip install win32gui
  2. pip install PyUserInput
  3. pip install PyKeyboard
  4. pip install selenium(注意要配合相应的webdriver驱动使用,webdriver的安装下载请自行到网上搜索学习)

2、新建一个python项目文件

3、下载准备好的2048小游戏将其解压到文件目录下

链接:https://pan.baidu.com/s/1y7Kosl20Fw1Xbu8tMI4-zw
提取码:aicg
–来自百度网盘超级会员V5的分享
文件的总体目录如下:
在这里插入图片描述
其中index.html就是2048小游戏html文件,双击之后可以运行。

二、使用步骤

1.引入库

代码如下(示例):

import random
import time
import os

from pykeyboard import PyKeyboard  # 键盘实例
from selenium import webdriver  # web驱动
from selenium.webdriver import ActionChains  # 鼠标模拟
from selenium.webdriver.common.by import By

2.用相对路径来获取绝对路径

我们用driver.get(url)方法来跳转到游戏界面,但是url为本地资源的时候,只能通过绝对路径来打开(个人理解,因为本人直接用相对路径打开没有用),所以需要使用os里面的库函数来进行转化。代码片段如下(其中url就是绝对路径了):

# 通过相对路径来得到 绝对路径=os.path.abspath(相对路径)
path = r'../2048Game/index.html'
file_open = open(path, mode='r')
# print(os.path.abspath(path))

url = os.path.abspath(path)

3.获取webdriver驱动

# 获取webdriver驱动,这里用的是谷歌
driver = webdriver.Chrome()
# 用浏览器打开
driver.get(url)
# 设置隐式等待时间为3秒
driver.implicitly_wait(3)

4.定义一些可能会有用的变量

# 定义一些变量
now_number = []  # 存储现在的界面数字数组,在以后的算法之中可能会用到,当前可不写
k = PyKeyboard()  # 键盘对象

5.主要的函数代码块

# 获取当前页面的状态数组,返回的是一个一维列表
def get_now_numbers(driver):
    global now_number  # 声明使用的是全局变量
    now_number.clear()  # 对列表进行清空,防止有脏数据
    for i in range(4):
        for j in range(4):
            # 用CSS选择器查找每一个小方格里面的数字,并且添加到数组中
            cell_span = driver.find_element(By.CSS_SELECTOR, '#number-cell-{}-{}'.format(i, j))
            num = cell_span.text
            if num == "":
                now_number.append(0)
            else:
                now_number.append(int(num))


# 开始新游戏
def new_game(driver):
    # 查找开始游戏按钮
    new_game_button = driver.find_element(By.CSS_SELECTOR, '#new_game_button')
    time.sleep(2)
    # 实例化鼠标方法
    actions = ActionChains(driver)
    # 开始一个新游戏
    actions.click(new_game_button)
    # 调用点击方法
    actions.perform()


# 随机按键按键效果
def press_key_r(num):
    if num == 0:
        # 按左移键
        k.tap_key(k.left_key)
    elif num == 1:
        # 按右移键
        k.tap_key(k.right_key)
    elif num == 2:
        # 按上移键
        k.tap_key(k.up_key)
    else:
        # 按下移键
        k.tap_key(k.down_key)

6.开始一局游戏,和结束游戏判断

# 开始新游戏
new_game(driver=driver)
# 获取初始游戏界面
get_now_numbers(driver=driver)
time.sleep(2)

flag = 0 #游戏停止标志
# 定义一个死循环一直按键
while flag == 0:
    # 是否弹出gameover警告框
    # 因为alert是在js里面定义的,所以可以直接用driver.switch_to.alert获取
    try:
        alert = driver.switch_to.alert
        print(alert.text)
        # 游戏结束
        if alert.text == "gameover!":
            alert.accept()
            flag = 1
            break

    except Exception:
        # 产生一个随机数,随机上下左右移
        num = random.randint(0, 3)
        press_key_r(num)
        # print("继续操作...")
        time.sleep(0.2)

# 获取分数
score = driver.find_element(By.ID, "score").text
print("本次得分为:{}".format(score))

7.总体代码如下:

import random
import time
import os

from pykeyboard import PyKeyboard  # 键盘实例
from selenium import webdriver  # web驱动
from selenium.webdriver import ActionChains  # 鼠标模拟
from selenium.webdriver.common.by import By

# 通过相对路径来得到 绝对路径=os.path.abspath(相对路径)
path = r'../2048Game/index.html'
file_open = open(path, mode='r')
# print(os.path.abspath(path))

url = os.path.abspath(path)

# 获取webdriver驱动,这里用的是谷歌
driver = webdriver.Chrome()
# 用浏览器打开
driver.get(url)
# 设置隐式等待时间为3秒
driver.implicitly_wait(3)

# 定义一些变量
now_number = []  # 存储现在的界面数字数组,在以后的算法之中可能会用到,当前可不写
k = PyKeyboard()  # 键盘对象


# 获取当前页面的状态数组,返回的是一个一维列表
def get_now_numbers(driver):
    global now_number  # 声明使用的是全局变量
    now_number.clear()  # 对列表进行清空,防止有脏数据
    for i in range(4):
        for j in range(4):
            # 用CSS选择器查找每一个小方格里面的数字,并且添加到数组中
            cell_span = driver.find_element(By.CSS_SELECTOR, '#number-cell-{}-{}'.format(i, j))
            num = cell_span.text
            if num == "":
                now_number.append(0)
            else:
                now_number.append(int(num))


# 开始新游戏
def new_game(driver):
    # 查找开始游戏按钮
    new_game_button = driver.find_element(By.CSS_SELECTOR, '#new_game_button')
    time.sleep(2)
    # 实例化鼠标方法
    actions = ActionChains(driver)
    # 开始一个新游戏
    actions.click(new_game_button)
    # 调用点击方法
    actions.perform()


# 随机按键按键效果
def press_key_r(num):
    if num == 0:
        # 按左移键
        k.tap_key(k.left_key)
    elif num == 1:
        # 按右移键
        k.tap_key(k.right_key)
    elif num == 2:
        # 按上移键
        k.tap_key(k.up_key)
    else:
        # 按下移键
        k.tap_key(k.down_key)


# 开始新游戏
new_game(driver=driver)
# 获取初始游戏界面
get_now_numbers(driver=driver)
time.sleep(2)

flag = 0
# 定义一个死循环一直按键
while flag == 0:
    # 是否弹出gameover警告框
    # 因为alert是在js里面定义的,所以可以直接用driver.switch_to.alert获取
    try:
        alert = driver.switch_to.alert
        print(alert.text)
        # 游戏结束
        if alert.text == "gameover!":
            alert.accept()
            flag = 1
            break

    except Exception:
        # 产生一个随机数,随机上下左右移
        num = random.randint(0, 3)
        press_key_r(num)
        # print("继续操作...")
        time.sleep(0.2)

# 获取分数
score = driver.find_element(By.ID, "score").text
print("本次得分为:{}".format(score))


总结

以上就是本次项目的所有代码块,本次分享只是起一个抛砖引玉的作用,之后可能会增加一些算法来代替伪随机数进行游戏控制。可能的思路如下:
1、再设置四个变量来记录“上下左右”移动的权重,
2、每次移动之前先用get_now_numbers()函数来获取now_number数组,
3、然后再根据其数组计算出移动之后消去数字对最多的方向(权重最大),进行移动控制。

  • 5
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值