欢乐五子棋辅助

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

欢乐五子棋辅助

沉云   2020-03-29 我要评论
> 苦练技术是不可能的,这辈子不可能好好练习。学技术又学不进去,就只有靠辅助才能维持的生活这样子。 #### 简述 最近玩微信小程序 - 欢乐五子棋,结果老是被虐,好气啊。偶然想到了前段时间网上很火爆的跳一跳辅助。简单想了一想辅助实现的思路,发现目前所需的工具已经足够。 需要的工具主要分为以下三类: 1. Yixin 奕心引擎,这个引擎是国人所作,可以说是非商用版里面最强的五子棋AI 这个是官网 https://www.aiexp.info/pages/yixin-cn.html 一开始我想使用奕心的界面+引擎那款,因为可定制性足够强,结果发现Python 不好与带界面的程序进行交互,所以就选择了引擎。然而尴尬的一点是,我把官方文档翻了个遍都没有找到引擎的使用方法。不过后来在世界五子棋锦标赛 https://gomocup.org/ 找到了参加比赛的AI 必备的两种接口。 http://petr.lastovicka.sweb.cz/protocl2en.htm 使用输入输出流,本文选择的就是这种方式 http://petr.lastovicka.sweb.cz/protocl1en.htm 使用文件 2. Python 简单图片处理 3. Python adb 操作手机 #### 思路 整个思路如下图,我们按照上面的顺序从简到繁,开始介绍每个模块。整个思路顺下来程序其实是比较好写的,就是前期**需要手动的截取匹配图片,查看相应的像素点位置**。 #### 实现 ##### 前期准备 下面的区域参数以我的手机1920*1080为例,不同屏幕请自行适配 ```c++ class mVars: address='C:/Users/EA/Desktop/yixin/' # 使用到的文件所存放地址 boradOne = 67 #一个相邻落子点的像素间隔 borad = (65,480) #用来将图片像素坐标和棋盘坐标互转 confirmBW = (820,1590,820+45,1590+60)#用来确定己方是黑棋还是白棋的区域 confirmWin = (660,1780,660+46,1780+46)#用来确定是否胜利的区域 ``` 这些是前期需要准备好的图片,至于怎么获取这些图片,等后面有时间会在补充在文末,事实上,做好这些准备工作,整个进度就完成了30% ##### Yixin 引擎 从官网上可以下载这个Yixin 引擎 http://gomocup.org/statichttps://img.qb5200.com/download-x/download-ai/YIXIN18.zip 结合 http://petr.lastovicka.sweb.cz/protocl2en.htm 可以知道如何与引擎交互 我使用 subprocess 这个模块让python 与 引擎交互 ```python import subprocess as sub class YiXin: mYixin = sub.Popen(mVars.address+"Yixin.exe", stdin=sub.PIPE, stdout=sub.PIPE, stderr=sub.PIPE) def __init__(self): self.input('START 15') self.input('INFO timeout_match 300000') self.input('INFO timeout_turn 10000') self.output() print("YiXin ready!!") def input(self,str): #向Yixin 输入对手落子指令 print('Human: '+str) self.mYixin.stdin.write((str+'\n').encode()) self.mYixin.stdin.flush() def output(self): #获取Yixin 的输出 #一直获取Yixin 输出,直到落子的指令或其它 while True: str = bytes.decode(self.mYixin.stdout.readline()) print('YiXin: '+ str,end='') if ((',' in str) or ('OK' in str)): break; self.mYixin.stdout.flush() if(',' in str): return str def restart(self): self.input('RESTART 15') self.output() ``` ##### 图片处理 这个模块需要做的事就是处理跟图片相关的,包括比较图片,转换坐标等 起初有两种思路,1.每隔一段时间获取截一张图,对比两张图不同的地方,从而获取对手落点位置。2.没隔一段时间截一张图,识别图上的所有有棋的位置并保存,然后通过比较,得到对手落子位置。出于效率考虑,我选择了第一种方法。 ```python class ImageProcess: #如果匹配成功,则返回中心像素点 def matchImg(self,imgsrc,imgobj,confidence=0.8): coord = None res = ac.find_template(imgsrc,imgobj,confidence) if res != None: coord = (int(res['result'][0]),int(res['result'][1])) return coord #将像素坐标转化为棋盘坐标 def transformBoard(self,coord): x = coord[0] y = coord[1] xcoord = ycoord = 0 while x>=mVars.borad[0]: x-=mVars.boradOne xcoord+=1 while y>=mVars.borad[1]: y-=mVars.boradOne ycoord+=1 return xcoord-1,ycoord-1 #将棋盘坐标转化为像素坐标 def transfromScreen(self,coord): return (coord[0]*mVars.boradOne+mVars.borad[0],coord[1]*mVars.boradOne+mVars.borad[1]) #对比两张图片的差异 def difference(self,img1,img2): return img1-img2 ``` ##### ADB 模块 这个模块与手机交互,这块我用的是无线ADB连接,当然也可以有线连接,关于ADB连接教程见https://github.com/mzlogin/awesome-adb ```python import os import time class Adb: #无线连接手机 def __init__(self): os.system('adb connect 1.1.1.1:5555')#ip 示例 os.system('adb devices') #捕获截图 def capture(self): os.system('adb exec-out screencap -p > '+mVars.address+'sc.jpg') return ac.imread(mVars.address+'sc.jpg') #点击特定位置 def click(self,piexl): os.system('adb shell input tap %d %d'%(piexl[0],piexl[1])) time.sleep(0.1) os.system('adb shell input tap %d %d'%(piexl[0],piexl[1])) ``` ##### 游戏系统模块 ```python class System: Yixin = YiXin() ImageP = ImageProcess() Adb = Adb() imgobj = None #用来检测对手落子的图片 certain = 0 #1表示己方为白,2表示己方为黑 #确认是否胜利 def confirmWin(self,imgsrc): x0,y0,x1,y1 = mVars.confirmWin imgsrc = imgsrc[y0:y1,x0:x1] imgobj = ac.imread(mVars.address+'confirmwin.jpg') return self.ImageP.matchImg(imgsrc,imgobj,0.9) #确认己方是黑棋还是白棋 def confirmBW(self,imgsrc): x0,y0,x1,y1 = mVars.confirmBW imgsrc = imgsrc[y0:y1,x0:x1] imgobjw = ac.imread(mVars.address+'confirmw.jpg') imgobjb = ac.imread(mVars.address+'confirmb.jpg') if (self.ImageP.matchImg(imgsrc,imgobjw,0.8) != None): self.certain = 1 self.imgobj=ac.imread(mVars.address+'objb.jpg') elif (self.ImageP.matchImg(imgsrc,imgobjb,0.8)!= None): self.certain = 2 self.imgobj=ac.imread(mVars.address+'objw.jpg') #做好比赛前准备, def ready(self): while True: imgsrc = self.Adb.capture() self.confirmBW(imgsrc) if(self.certain != 0): break; print('UnCertain') time.sleep(1) if self.certain == 2: self.runCommand('BEGIN') return imgsrc elif self.certain == 1: return ac.imread(mVars.address+'None.jpg') #向Yixin 输入对方落点,获得Yixin 落点并点击屏幕 def runCommand(self,COMMAND): self.Yixin.input(COMMAND) str = self.Yixin.output() a = str.find(',') b = str.find('\r') piexl = self.ImageP.transfromScreen((int(str[0:a]),int(str[a+1:b]))) # print(piexl) self.Adb.click(piexl) #开始游戏 def play(self,imgsrc): flag=False imagep = self.ImageP oldimg = newimg = imgsrc while self.confirmWin(newimg) == None: imgdif = imagep.difference(oldimg,newimg) ac.cv2.imwrite(mVars.address+'diff.jpg',imgdif) coord = imagep.matchImg(imgdif,self.imgobj) # print(coord) if(coord != None): x, y = imagep.transformBoard(coord) COMMAND = "TURN %d,%d"%(x,y) self.runCommand(COMMAND) oldimg,newimg = newimg,self.Adb.capture() time.sleep(0.8) #新一轮游戏 def newGame(self): time.sleep(4) os.system('cls') os.system('adb shell input tap %d %d'%(100,1820)) time.sleep(0.5) os.system('adb shell input tap %d %d'%(540,940)) self.Yixin.restart() self.certain = 0 self.imgobj = None ``` ##### 主函数 ```python msys = System() # n = input("请输入你想玩的局数:") # for i in range(1,int(n)+1): while True: imgBegin = msys.ready() msys.play(imgBegin) print("You Win !! Next Game Will Begin After 4sec") msys.newGame() ``` #### 后记 所有代码到这里就结束了,后面将用到的资源整理一下再上传

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们