python写自动脚本_用Python实现FGO自动战斗脚本
我家黑贞!
1. 背景
Fate/Grand Order(非的肝不过欧的)作为索尼为了拯救自己不倒闭而开发的面向月厨的骗氪养成抽卡爆肝游戏,居然没有像隔壁《阴阳师》的自动战斗系统(看看别人现在都自带脚本了)。毕竟是懒得肝,就不妨写一个脚本来肝算了,省时省力。
懒得写新的文章了orz新的版本在这个REPO里,主要实现了完全的自动刷,包括磕苹果OWO,文中的版本在文末。
2. 思路:界面识别
本来以为搞这个的难度不会比《阴阳师》的难太多QAQ,我真的是too young too simple啊QAQ
注意:由于我个人比较懒,所以之前文章提到的就懒得再提了QWQ
所以关于通过ADB对手机进行操作和OpenCV这个库的使用也不再赘述,不过可以参考我之前写的两篇文章:
《用Python实现阴阳师自动结界突破》
《用Python实现阴阳师自动抽卡》
(抽卡那篇文章基本概括了ADB的用法,和要用到的OpenCV的函数的用法了)
2.1 开始
我们这次要做的可不是什么抽卡脚本,而是一个战斗脚本,其实可以算是AI的初步了。虽然只是暴力算出造成最大伤害的方案orz。
我们在这里不考虑释放技能、宝具和暴击星这三样非常重要的东西。。。只单纯考虑克制、抵抗和不同种类卡打出的伤害,目标就就是算出伤害最高的组合。
2.2 指令卡
战斗界面
要开始,我们首先要分析界面的组成。首先下面是一排指令卡,每张指令卡都有卡的种类(黄色框)和“克制”和“抵抗”的标记(黄色圈)之类的东西。那我们可以把每张指令卡视为一个对象,然后把它的特点抽象出来。我们可以知道每张卡都有一个坐标,一个类型(绿蓝红),一种状态(无/克制/抵抗),还有在点按是的顺序(1/2/3)和伤害系数(这个具体有一张表)。
所以我们可以这样做:
class Card:
def __init__(self):
self.crd = [] # the coordinate of the card (x, y)
self.status = 0 # the status of the card "normal(0)" "restraint(1)" "resistance(2)"
self.type = [] # type of the card "Quick(0)" "Arts(1)" "Buster(2)"
self.priority = 0 # the priority of the card
self.atk = 1 # set atk of the card
2.3 识别与匹配
2.3.1 坐标匹配
这个其实就没啥难度的了,无非就是调用OpenCV的库(之前的文章都提到过)用matchTemplate()识别图像然后返回坐标。不过我们倒是要写一个 “过滤系统”来把相近的坐标过滤掉,最后得到5张指令卡的坐标。这个简单来说,也可以用穷举法,设定一个范围,使这个范围里的坐标只保留一个。
2.3.2 标记匹配
另外一个重点就是把“克制”和“抵抗”的标记和其所在的卡匹配在一起。通过多组数据我们就可以观察到指令卡的坐标和标记的坐标的差值总在一个范围里面,简单的话就是设置一个范围如果标记的坐标在这个范围里则标记这张指令卡。
def mark_crd(card, mark):
note = []
for i in range(len(card)):
for j in range(len(mark)):
for p in range_of_x: # 两坐标x差值范围
for q in range_of_y: # 两坐标y差值范围
if (card[i][0] + p == mark[j][0]) and (card[i][1] - q == mark[j][1]): # 如果在范围内
note.append(card[I])
return note
2.3.3 种类匹配
然后我们还有给每张指令卡标记上卡的种类这个和前面匹配标记也是差不多的,就不再赘述了。
总的来说,这样就把每张卡(对象)的属性给匹配了起来,这样子就可以后面的程序调用了。
3. 思路:出卡顺序
整个算法的核心就是这一部分,计算出造成伤害最大的组合。
3.1 计算法则
就是这张图!
分析这张图,可以看到红卡放第一张时后面的卡都有伤害加成(废话),而其他颜色的卡则为原来的伤害,只是后面的卡伤害会略高而已。。。
最简单的办法就是暴力的把它写成一堆if-else语句QWQ
3.2 实现
我们在前面已经初始化了伤害(atk=1),我们只要给克制的伤害乘2,抵抗的乘0.5就好了,然后再加上我们那一大坨if-else语句
def rank_card(): # main algorithm
# 设置 atk total rank这三个数组
for i in range(5):
cards[i].priority = 1
for j in range(5):
if j == I:
continue
else:
cards[j].priority = 2
for k in range(5):
if k == i or k == j:
continue
else:
if cards[i].type == 2: # 第一张是buster的话
# 第二张的伤害 balabala
# 第三张的伤害 balabala
else:
if cards[i].type == 1: # 第一张是arts的话
atk[0] = 1 * cards[i].atk
elif cards[i].type == 0: # 第一张quick的话
atk[0] = 0.8 * cards[i].atk
# 第二张的伤害 balabala
# 第三张的伤害 balabala
if (sum(atk)) > total:
total = sum(atk)
rank[0] = I
rank[1] = j
rank[2] = k
# 返回伤害最高的卡的号码
return rank
反正人懒,给机器做多点事也没关系XD,接下来只要把坐标返回给主程序点按的可以了。
4. 思路:防封
听说FGO会封脚本,所以就特地加入了防封的机制。
其实方法很简单,加入随机的点按,和不同的间隔(等待时间)就可以了,点按每张卡有位置的变化,点每张卡之间有变化的间隔,和一些故意的“误触”应该就没问题,其实还可以加上一些长度不同的滑动也是可以的,简单来说就是一堆随机函数而已233
5. 思路:整合
简单来说就是把上面的一堆代码整合到一起就可以了
开始界面
识别到这个界面然后点按“Attack”
结束界面
识别到“与从者的羁绊”终止脚本
中间就是上面所提到的了。也即是一个不停的循环,直到“结束”界面才终止。有什么其他的就到时候再补充吧OWO
6. 总结
这应该是我搞过最大最复杂的一个项目了,也是第一次接触到一点OOP。然而这个项目还是偏实用性,毕竟没有什么高端的,或者更高效率的算法,这也应该是以后要改进的地方。
然后是惯例,代码在Github上面QWQ
还有Bilibili上的演示视频XD
python写自动脚本_用Python实现FGO自动战斗脚本相关推荐
- python写一个类方法_重写python脚本,在脚本的每个类中注入一个方法 - python
假设我有一个python模块foo.py,其中包含: class Foo(object): def __init__(self): pass 接下来,我想解析此脚本,并在每个类中注入一个方法,然后将其 ...
- python写机器人程序_用Python写的一个多线程机器人聊天程序
本人是从事php开发的, 近来想通过php实现即时通讯(兼容windows).后来发现实现起来特别麻烦, 就想到python.听说这家伙在什么地方都能发挥作用.所以想用python来做通讯模块...所 ...
- python 写一个计算器_用 Python 写个计算器
首页 专栏 python 文章详情 0 用 Python 写个计算器 Python小二 发布于 56 分钟前 我们常见的计算辅助工具有两种,一种是古人发明的算盘,另一种就是我们现代人发明的计算器,与算 ...
- 用python写聊天机器人_用Python 写一个机器人陪你聊天(文尾有彩蛋)
工作一忙,原来秉烛夜谈的好友现在都很少聊天,微信都成了微信群的天下,鲜有微信好友给你发消息,想要主动发却也找不到开题话题,怎么办?用Python写一个机器人陪自己聊聊天吧.以下是源码及解析,小白都看得 ...
- python写爬虫教程_用Python写爬虫程序基础教程(一)
最近身边朋友都在讨论股市是不是牛市要来了吧? 如果想自己做一个股市收盘价前三十名的涨跌幅度,又不用每天去点击网页浏览,用Python写个爬虫程序来做是不是超棒der 环境建置 安装Python 安装P ...
- python写采集程序_用python写的一个wordpress的采集程序
在学习python的过程中,经过不断的尝试及努力,终于完成了第一个像样的python程序,虽然还有很多需要优化的地方,但是目前基本上实现了我所要求的功能,先贴一下程序代码: 具体代码如下: #! /u ...
- python写web自动化_使用Python+selenium实现第一个自动化测试脚本
原标题:使用Python+selenium实现第一个自动化测试脚本 最近在学web自动化,记录一下学习过程. 此处我选用python3.6+selenium3.0,均用最新版本,以适应未来需求. 环境 ...
- python写签到软件_基于Python实现签到脚本过程解析
无聊刷日剧,看到签到断了好久,简单写了个脚本,通过模拟抓包的方式实现 1.先登录到字幕组网站获取token 2.用获取到的token登录到人人活动页面获取cookie 3.用获取到的cookie进行签 ...
- python实现自动上传图片_利用python脚本实现使用typora编写markdown时图片自动上传到chevereto图床...
复制粘贴以下代码 #!/usr/bin/env python3 # -*- encoding: utf-8 -*- # author: guiu # data: 2020.2.28 import re ...
- python写计算机模拟器_用 Python 写出了一个 Gameboy 模拟器
点击上方"编程派",选择设为"设为星标" 优质文章,第一时间送达! 感觉用 Atari 游戏研究人工智能有点「不够接地气」?现在我们可以使用 Gameboy 模 ...
最新文章
- dubbo+zookeeper与提供者、消费者之间端口通信问题(No provider available for the service)
- 医学影像设备学_医学影像技术考研可选的六大院校
- 《认知红利》读书笔记
- 在Kubernetes上部署一个简单的、类PaaS的平台,原来这么容易!
- AVVision Organized Session (IROS'21) 征稿开启
- 微信小程序保存canvas绘制的图片到本地,拒绝图片授权后继续授权
- UILabel显示html文本
- Quartus II文件编译下载和USB-Blaster驱动安装
- 年度盘点和预测:数说汽车互联网市场
- Google Code 开源项目
- 苹果中国官网新增蚂蚁花呗 24 期分期免息服务
- 多个数的最小公倍数求法
- 知识图谱从入门到应用——知识图谱的知识表示:向量表示方法
- 2020李宏毅学习笔记——16.Recurrent Netural Network 下
- Cruise的API简介--Properties篇
- ssh整合:spring+springmvc+hibernate
- Basemap库绘制地图
- RK 7.1 OTA升级提示Not enough free space on /cache to apply patches
- openlayes调用arcgis wms服务跨域问题(arcgis server10.2)
- 最小的K个数(手写大顶堆和用优先级队列比较)