0.说明
脚本仅供娱乐。
昨天玩了会羊了个羊,感觉设计还蛮不错的。把难度隐藏起来,让玩家感觉只差一点点。以此让人不愿放弃。
不过自己多玩几次之后,感觉羊了个羊是个大部分靠运气,少部分靠技术的活,重复刷的过程中,大部分时候是在做简单的操作(找三个一样的),这看起来非常适合靠脚本来帮忙。
于是基于 python 写了个逻辑比较简单的脚本去自动刷(包括用道具和看广告)
如果单纯为了通关,网上有修改文件,使道具无限之类更直接的通关手段。
写这个脚本主要想探索规则以内,用电力+策略完成的可能性。
0.1 脚本策略概述
当前脚本循环下方逻辑:
- 检查是否已经结束,如果已经结束但有重生机会,则看广告或转发重生,否则结束重来。如果没有结束则去 2
- 检查桌面上是否有牌能和手牌一起凑出 3 个,如果有,则点他们凑起来,并回到 1 重新循环,否则 3
- 检查是否需要使用随机道具,个人判断条件为手牌有 6 张以上,要用则获得并使用,并回到 1。不用或用不了则 4
- 检查手牌空位是否只剩下 1 个,如果是且还没有用过移出道具,则看广告或转发获得道具并使用,并且回到 1 重新循环
- 找桌面上是否有和手牌相同的牌(避免手牌太花),如果有拿一张并且回到 1,否则 6
- 找桌面上重复 2 次的牌,拿 1 张(似乎更有可能能快速消去),拿到则回 1,否则7
- 拿桌面上任意一张牌,回 1
由于策略上极度贪心,且并没有考虑桌面上被压住的牌,所以目前而言,策略上会弱于人。
但强在可以一直跑,不累。
多次跑的情况下,运气好还是有可能通关的。
0.2 脚本实现方式概述
实现方式:
- 用 python 控制 adb 去截图(手机、模拟器都可以)
- opencv 识别图像得到当前游戏信息(用opencv直接模版匹配)
- 基于脚本逻辑结合信息得到当前操作
- 再控制 adb 去进行点击操作
adb 说明:个人之所以使用adb控制模拟器,而非直接操作鼠标去点击,主要好处在于脚本运行时无须占用整个电脑。并且模拟器天生的虚拟机环境让环境更可控,避免不同机器导致的奇奇怪怪问题。
1. 演示录屏
https://www.bilibili.com/video/BV1aP411H7a5/?vd_source=7ffad06122799551b43206476b6a5d90
从录屏还是可以看出,当前脚本并不够聪明,但如此策略也能轻松消掉 120 张左右,目前还需要长期运行靠运气(个人尝试下脚本最高一次 260 左右,已经很接近完成)。
也可以修改一下代码,让在接近完成时停止逻辑,等手动操作,让代码成为辅助器(筛初始号一般 哈哈哈)
未来可能看心情考虑优化加强逻辑
2. 脚本下载
链接:https://pan.baidu.com/s/1CbcddOEw3Lfe_MILpBihPw?pwd=pppp
提取码:pppp
–来自百度网盘超级会员V3的分享
3. 脚本使用说明
3.1 配置准备
3.1.1 解压
3.1.2 安装Python3.8
已装可忽略。3.8版本主要是为了用 easyocr 包。
运行目录下的 pre_1_install_python.bat
已安装 Python3.8 会进入 Python 控制台:
否则 win10 和 win11 下会自动打开微软商店对应 Python 页面:
如果没有安装,应该会有一个“获取”按钮(我已经装了),点击自动安装即可。
如果跳转的不是Python 3.8,则需要主动搜索一下。
3.1.3 安装库
脚本有用到 opencv 进行图像匹配,需要安装相关库。
双击运行 pre_2_install_packages.bat 。会自动安装相关库
下载可能比较慢,需等待一会,受不了就关掉重来,可能就快了。(如果有梯子速度应该没问题的)
下载安装的过程可能有些报错,一般可以忽略
3.1.4 夜神模拟器配置
建议使用夜神模拟器,其自带 adb 比较方便,且我测试时是用的夜神模拟器。
再将模拟器的分辨率设置为 1600*900
运行脚本前,先保持模拟器的运行
3.2 脚本设置
用文本编辑器打开脚本路径下的 settings.py
3.2.1 adb_path
由于脚本使用 adb 控制模拟器。需修改 adb 相关的配置:
使用夜神模拟器的话,可以直接在夜神安装路径下的 bin 文件夹下找到 adb.exe
将其路径修改进去就行(允许有空格和括号,但最好没中文,因为没测过)
注意保留双引号
3.2.2 device_address
Win+R 运行 cmd
cmd 命令行进到夜神 adb.exe 所在文件夹
(不熟悉 cmd 命令的话,也可以把夜神的 adb.exe 复制到 cmd 打开后的默认文件夹)
输入命令 adb.exe devices 查看各个设备的地址:
如果没有多开模拟器,应只会看到一个 127 开头的本地地址
把 IP带冒号加端口 一起复制到 settings.txt 中的 device_address
3.2.3 微信转发配置
由于偶尔获得道具需要转发,需设置一下你想转发给谁。配置方式:
进游戏并触发一次转发,到这个页面:
截一下你想转发的人或群的头像(截中间部分,用修改好分辨率的模拟器截,以方便未来更容易图像匹配)
截图后替换 template_images 下 resend.png 图片。
4. 使用
模拟器中登录微信,开羊了个羊,进第一关。
双击 run.bat 运行
顺利的话就能看到模拟器被脚本控制着运行了
当完全消除后,脚本不会进行额外操作
5. 问题处理
5.1 识别问题
如果有卡住,或者有明显的三个相同牌但没拿。很可能是由于羊了个羊替换了字体或者图片资源,可以尝试重新截图,替换 template_images 中对应模板即可。
了解 python 的也可以尝试修改对应代码,去新增模板图,或适当调整匹配阈值,增加匹配成功率。
6. 代码逻辑简介
6.1 image_processor.py
用于封装一些基本的图片处理方法
6.2 adb_controller.py
封装一些 adb 控制相关的基本操作(个人的其他游戏脚本也经常通用)
如
def swipe(from_loc,to_loc,use_time):
print("AdbController:Swipe from "+str(from_loc)+" to "+str(to_loc)+" by "+str(use_time)+" millisecond")
process = os.system("\""+settings.adb_path+"\""+" -s "+settings.device_address+" shell input swipe "
+str(from_loc[0])+" "+str(from_loc[1])+" "+str(to_loc[0])+" "+str(to_loc[1])+" "+str(use_time))
time.sleep(use_time/1000)
time.sleep(2)
用于控制进行一次滑动操作(羊了个羊用不到)
wait_till_match_any 用于重复匹配某图片,直到匹配成功
def wait_till_match_any(template_paths,thresholds,return_center,max_time,step_time,accidents=None,scope = None,except_locs = None):
print("AdbController: Start to wait till match screenshot by any "+str(template_paths)+" for up to "+str(max_time)+" seconds ....")
time_start = time.time()
match_loc = None
while(True):
screenshot(settings.screenshot_path)
for index in range(0,len(template_paths)):
match_loc = image_processor.match_template(
settings.screenshot_path,template_paths[index],thresholds[index],return_center,scope = scope,except_locs = except_locs)
if(match_loc != None):
return match_loc
if(time.time() - time_start > max_time):
print("AdbController: Reach max_time but failed to match")
return None
if(accidents != None):
re = check_if_accidents(accidents)
if(re == "restart"):return "restart"
time.sleep(step_time)
return None
6.3 yang_processor.py
用于封装羊了个羊脚本特殊的逻辑,会用到 adb_controller 和 image_processor,整体逻辑及脚本策略前文已有提到