任务奖励/通行证
这部分用到了 颜色匹配(ColorMatch)
,文档暂时写的还不全,故这里简单讲一下。
1 | "一键领取": { |
method
默认 4,选择 RGB
。
找到颜色所在界面,截图,然后放到 ps
等工具里取色,获取RBG值。
设置合理的范围,这里lower和upper分别设置为RBG值-25和+25。
这部分用到了 颜色匹配(ColorMatch)
,文档暂时写的还不全,故这里简单讲一下。
1 | "一键领取": { |
method
默认 4,选择 RGB
。
找到颜色所在界面,截图,然后放到 ps
等工具里取色,获取RBG值。
设置合理的范围,这里lower和upper分别设置为RBG值-25和+25。
没啥新东西,自己到 canteen.json
看吧。
注意 roi
填的 string (任务名):填写任务名,在之前执行过的某任务识别到的目标范围内识别。这里是任务匹配上的范围,不是其 roi
范围。
然后是一个 replace
的样例,文档里没写,我来补充一下。
现欲识别目标串“空白区域”,由于ocr模型等原因,会将 白
识别为 自
、目
,期望的 pipeline 写法为:
1 | "recognition": "OCR", |
可用正则匹配。正则相关可以查询 [菜鸟教程](Python3 正则表达式 | 菜鸟教程 (runoob.com)) 。
大致思路前面已经展示过两、三遍了,故重复的不再赘述,只讲讲新东西。
首先判定进到补给礼包的界面并加载完毕,用的是一号位的 “每日剩余:x/1”
的 “剩余”
。
1 | "进入补给礼包界面": { |
领取的步骤为:检测体力溢出——检测补给存在——检测免费字段——下一位/返回主页面。
1 | "1号补给无": { |
2号除了出口和1号不一样,其他都按1号做一遍。
和前面签到的实现一样,我们先在程序入口判断页面并返回主页面,然后再开始一系列操作。
1 | // interface.json |
1 | // mail.json |
这样就可以在返回主页面以后 领取邮件开始
开始领取了。
1 | "领取邮件开始": { |
这里分两种情况:
在点击 "邮件领取按键"
后:
第一种情况下,会跳出领取窗口,此时会运行 "override_点击空白区域"
并退回到主页面。
第二种情况下,会显示 无可领取附件
,脚本识别到后执行 退出邮件
并返回主页面
1 | "邮件领取完毕": { |
本篇采用模块化说明重构过程。
由于签到逻辑由 1.x 的和游戏启动绑定变为独立执行,所以整体都需要重写。
首先判断是否在主页面,不在则尝试返回主页面,不行则重启。
确认在主页面,点击右上角区域进入签到页面,然后签到。
签到完成,返回主页面。
参照 startup.json
完成,后续可能做成 custom recognition。
这里用到了新的功能 pipeline_override
,做一个简单说明。
1 | "位于主界面": { |
global.json
中,完成了 “位于主界面” (判断当前处于主界面)功能,但是只有判断的功能,现在想让该功能的next 列表变为想要执行的签到任务,方法如下。
1 | // interface.json |
1 | "签到事件开始": { |
整体采取状态+动作的方式设计,确保不会出问题。
在 MST 1.x
中,本人完成了基于maafw 1.7.x
的 pipeline 实现。
本次需要完成游戏启动、关闭的重构。
用到了首先用到了StartApp
,这里会根据package name
确定启动的 APP。
经过在网上的大量搜寻、下载并安装,获取到对应包名:
1 | "package": "com.glkj.lhcx.gf", # 官网、TapTap |
修改 interface.json
中的resource
,按文件夹放置不同渠道需要覆盖 base (官网、TapTap )的 json 代码,以实现不同渠道的游戏启动。
简单说一下写的逻辑。
1 | "启动游戏": { |
与之前 1.x
的代码不同,这次代码重构跟随 maafw
的更新,舍弃使用 is_sub
字段,改用 interrupt
代替,可以明显感受到逻辑的简洁以及代码量可阅读性的提升。(也有可能是本人的水平比较小杯)
interrupt
中的任务是在前面 next
数组都没匹配上时,匹配上便执行其与本身 next
数组后,再重新执行前面 next
数组,可能说的有点绕口, interrupt
具体相关说明还得到 maafw
文档中 3.1-任务流水线协议 查看。
特别的,这里 interrupt
先根据识别优先级排序,"热更新判断"
在测试时发现必须先于"启动页面等待"
进行判断,否则若有更新,便会陷入死循环;"sub_启动游戏"
由于无判断条件,必然匹配,优先级最低,放在最后;其他无明显优先级的任务为了节省资源,选择按匹配频率排序。
这里,"启动游戏"
的唯一出口便是 "位于主界面"
。
再贴一下 “启动界面点击任意区域"
的逻辑。
1 | "启动界面点击任意区域": { |
这里 "位于主界面"
"加载中"
"关闭悬浮窗"
由于其他模块会复用,放到 global.json
方便日后管理。
这次推翻重写,由于框架本身升级,以及个人对框架、项目及pipeline的更进一步理解,程序的健壮性有所提升,开发逻辑也更加清晰,期待接下来的蜕变。
2.0 第一次提交的代码用到了 post_delay
,会增加延迟,并且当前任务 "灵魂潮汐"
下的三种界面无法识别到,处理方式为匹配 "interrupt"
中最后一个无条件执行任务 "sub_启动游戏"
。当前的处理准确识别每一个界面保证返回到主页面。
优化逻辑,避免了窗口关闭不完全的情况。
修改”启动界面等待”逻辑,从OCR改为匹配右下角少量图标模板。
增加热更新任务OCR识别范围。
停服处理
如正在游戏中,但不处于 "启动游戏"
除无条件匹配任务 sub_启动游戏
外所有任务的可匹配范围,则会陷入死循环,如何处理。
如在执行脚本过程中,遇见模拟器卡死等相关问题,如何处理?
几个月前尝试使用MaaFramework(下称maafw
)的pipeline完成MST的基本实现,现趁maafw
更新到2.0之际,决定实现部分功能自行集成,并配上简单的 gui 界面。
在之前的工作中,由于本人对maafw
的了解不够充分,有部分内容(如:interface.json
)编写稍有瑕疵,现在需要在更新过程中完成修改。
另一个重要任务便是实现集成。本人当前对翻阅使用文档和各个相关项目后依旧是一头雾水,maafw 1.8
之前的集成实现有所了解,但2.0后废除 ExecAgent
功能及相关接口,需重新实现集成。
当前预计采用pyqt
设计界面,期望实现:
以上三点是较重要较急的任务,其他暂时想到的还有识别的优化(训练模型)、资源更新。
以下为1/22洛谷blog搬运
第一天刷题,本次题目来源题单:【入门1】顺序结构。挑了几个觉得可以稍微记录下的题。
1 | c = input() |
简单的循环输出。
1 | c = input() |
利用upper()转换。
1 | num = input().strip() |
本来是很简单的,但是之前一直WA…看了眼讨论区,发现是读入时没用strip()删除结尾的’/r’。
1 | t,n = map(float,input().split()) |
格式化输出。
1 | lst=list(map(float,input().split())) |
列表输入,sum()函数。
1 | import math |
做的有点久,但思路其实很简单。主要注意要用到math.ceil()向上取整,才能符合题意。小时数用总分钟数地板除60以后再和24取余,负数取余可得到正数。最后格式化输出02代表输出两位,不足补0。
1/23
完成了第二个题单,有一两道卡了下。
本次题目来源题单:【入门2】分支结构
1 | m,t,s=map(int,input().split()) |
注意除零问题。
1 | n = int(input()) |
三目运算符。
1 | m,h = map(float,input().split()) |
6g表示保留6位有效数字
1 | lst = list(map(int,input().split())) |
用sort()排序。
1 | yy,mm=map(int,input().split()) |
没啥可说的。
1 | arr = [] |
注意考虑小于8小时的情况。
1 | import math |
1 | side = list(map(int, input().split())) |
做的时候想着三边都比一次多麻烦,想起自己判断三角形的时候都是先排序再计算,就优化了一下过程。
1 | n = int(input()) |
1 | x ,n = map(int, input().split()) |
思路是弄明白游泳的天数,整一周肯定游5天。如果有剩余天数,和起始天数组合看看中间有没有休息。
1 | side = list(map(int, input().split())) |
辗转相除法。
1 | lst = list(map(int, input().split())) |
注意转换。
1 | # 读入 |
做的时候遗漏了checksum为10(X)的情况
1/28
1 | n,k=map(int,input().split()) |
1 | length = int(input()) |
1 | n = int(input()) |
1 | n = int(input()) |
将1到n的阶乘存储到lst[1:n+1]中,每一项可以由前一项求得,避免了重复计算。最后再将阶乘加起来
1 | n,x = map(int,input().split()) |
利用str()list()range()转化成字符串,再用count()计数
1 | s = input() |
嗯?斐波那契
1 | n = int(input()) |
1 | # 递归方法 |
1 | n = int(input()) |
可能优化就是先挑出质数再遍历。
1 | n = int(input()) |
1 | n = int(input()) |
1 | # 52*(7x+21k)=52*7(x+3k) |
1 | save,mum_save = 0,0 |
1 | a,b = map(int,input().split()) |
tle了,需要改进算法。
1 | def is_prime(num): |
稍微变动了一下,判断完2以后,不再判断偶数。少了一个tle。
学习一下素数筛
1 | # 埃式筛 |
然鹅还是不行,先放这里吧。
1 | L = int(input()) |
这题倒是简单。
1/29
不到一天的时间完成,不过收获颇多,像是用python创建多维数组,异或的应用,不同的输入方式什么的…
1 | n = int(input()) |
1 | a = list(map(int,input().split())) |
1 | n = int(input()) |
1 | l, m = map(int,input().split()) |
1 | n = int(input()) |
1 | n = int(input()) |
1 | w, x, h = map(int,input().split()) |
校门外的树升级版,一维数组变三维数组,注意数组边界。
Magic Odd Square 代码同本题。
1 | n = int(input()) |
1 |
|
看着就痛苦,直接找大佬题解copy了。
1 | m, n = map(int,input().split()) |
1 | n = int(input()) |
1 | n, m = map(int, input().split()) |
1 | s1, s2, s3 = map(int, input().split()) |
1 | # 模拟法 |
1 | # 利用异或,从开始一个灯没亮经过n次操作到只剩一个灯亮着,故每次与ans异或,到最后便为答案 |
1 | n = int(input()) |
又一道模拟题,开始没想到加个方向变量,后面想到了却又因为被绕进去了就调了半天…
1 | n = int(input()) |
1 | # 边长,火把,萤石 |
注意坐标表示,容易出错。
1 | lst = list(map(int, input().split())) |
1 | # 由输入为N*N矩阵,可以从第一行输入获取N |
1 | # create_graph() |
emmmm这是目前这周写的最长的代码了,不过写的很开心。
本题重点可能在找转90度后的坐标关系。
转180和270也有对应关系,不过直接偷懒摆了。
1/31
字符串掌握的明显不熟,需加强。
1 | s = input() |
?
1 | n,s = int(input()),input() |
1 | s, cnt = input(), [0]*25 |
1 | i = int(input()) |
注意join()和+用法不一样,刚刚在这里卡了半天…
用到了eval()
求表达式值
1 | print(len(''.join(input().split()))) |
一行解决~
1 | q, str = int(input()),input().strip() |
本卡了半天,晕晕
以后注意在接受没用split()字符串的时候记得加个strip()
1 | # 因为空格也算数,又要保证数的是整个词,所以单词与文章前后加上空格,方便查找位置。 |
之前就被坑过,读字符串的时候加了strip(),但是还是WA了,翻了翻评论区,试了下replace(),就全过了
1 | # 错误示范1: |
1 | # AC code: |
开始的思路是:
存在3个V或3个k相连时,一次可以多一个VK
在开头和结尾只有两个V或者K的情况没有统计进去,故给前后都添加一个字符
但是这样做还是没全AC,剩下没过的全是多统计了一个
1 | for add in ['V','K']: |
s = “VVK” 情况下,下面这种判断不正确
1 | if 'VV' in s or 'KK' in s: |
最终还是选择先遍历一遍字符串,统计“VK”数量并修改为XX,然后再查找是否还存在“VV”或“KK”
1 | n, s = int(input()), input().strip() |
1 | s = input().strip() |
没想到代码这么简单…想了半天都想不出来,实在不行看了题解
1 | s, ans = input().strip(), '' |
1 | s, tar, value, res, ans = list(input().replace('\r','').split()), [], [], [], '' |
1 | s1, s2 = input().strip(), input().strip() |
1 | a,b,c = 0,0,0 |
我真是个小机灵鬼
1 | rec, cnt = '', [0]*26 |
2/3
1 | points, c = [], 0.0 |
1 | n, lst = input().strip(), list(map(int,input().split())) |
1 | a, b = map(int, input().strip().split()) |
1 | n, m = map(int, input().strip().split()) |
1 | n = int(input()) |
1 | n = int(input()) |
被坐标卡了半天,难绷。最后还是带入例子验证了一遍。
1 | stu, n, idx, max_i, max_s = [], int(input()), 0, 0, 0 |
1 | # class Student: |
试图用类,无果。
1 | stu, n, idx= [], int(input()), 0 |
1 | n = int(input()) |
1 | n = int(input()) |
1 | lst = list(map(int,input().split())) |
1 | n, now = int(input()), 1 |
1 | n = int(input()) |
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.
1 | $ hexo new "My New Post" |
More info: Writing
1 | $ hexo server |
More info: Server
1 | $ hexo generate |
More info: Generating
1 | $ hexo deploy |
More info: Deployment