基于MATLAB图像处理的自动QQ小游戏(一)自动扫雷篇

基于MATLAB图像处理的自动QQ小游戏(一)自动扫雷篇(挖金子)

  学了那么一些数字图像处理之后,就用MATLAB实现了一直心心念念的自动扫雷,同时也做了QQ游戏上另外两款热门游戏的自动化——连连看和找不同。对的,你没有看错,是连连看和找不同。虽然已经2021年了,在舍友的推荐下我打开了QQ游戏这个世界,里面最热门的游戏连连看必须占一份。
  本篇主要是自动扫雷篇,另外两个游戏会后续更新。此外,虽然这个自动化看起来很像是外挂,但是我们本着的是极客精神(~~),写这个程序的最大享受就是写他的过程和成功的喜悦,用它来和玩家竞争是绝对不支持的。


一、关于QQ小游戏

  虽然电脑版的QQ小游戏已经淡出了人们的视野,但是上面每天依旧有不少玩家在线,而且基本都是高手。相继在连连看和找不同区被高手秒杀,特别是在我一直觉得自己还比较擅长的扫雷的被打压之后,我含泪企图用所学知识帮我找回一些自信。
QQ游戏

二、实现思路

  简单来讲就是:截屏-识别-排雷-点击。那么这四个方面具体的实现如下:

1.MATLAB实现桌面截屏和控制鼠标

  在MATLAB中调用java的方法来实现截屏和控制鼠标。具体的调用的是java.awt.Robot这一用于测试自动化的类。具体的代码如下:

robot = java.awt.Robot;%创建robot对象
rec= java.awt.Rectangle(); %创建矩形对象
rec.x=1;rec.y=1;%设置矩形的左上角坐标(屏幕像素)
rec.width=1360;rec.height=768;%设置矩形的长宽
image = robo.createScreenCapture(rec);%按矩形截取屏
filehandle = java.io.File('xxx.png');
javax.imageio.ImageIO.write(image,'png',filehandle);%保存截图


%%下面是制鼠标的三个函数
robot .mouseMove(x,y);%移动鼠标到x,y
robo.mousePress  (java.awt.event.InputEvent.BUTTON1_MASK);%按下左键
%按下和放开中间需要加入一些延时才可以实现一次点击。
robo.mouseRelease(java.awt.event.InputEvent.BUTTON1_MASK);%松开左键

截取的屏幕

2.识别——将截图内容识别为矩阵

  因为游戏窗口的位置一般都是固定的,所以人为的设置具体的参数以获取挖掘界面。
  采用一些常见的图像处理方式识别图片内容,首先取恰当的阈值将图片二值化,去除背景,保留数字和方块。得到如下结果:
二值化
  每个方块和数字的的位置都非常具有规律,很容易分割出每一个数字和方块。至于识别具体的数字、方块、空白,我采用的是非常直白的两个矩阵相减的方法。先获取模板,将分割出来的部分轮流和模板相减,差值最小的一个模板就是该部分代表的内容。因为数字都十分的规范,每个像素点的位置都不会改变,一般相减为0则可以判断该方块的内容。虽然这样做有很多缺陷,但是MATLAB适合矩阵操作,在这里足够实用,没有出现过识别错误的情况。当然也可以尝试一些其他识别方法如贝叶斯公式等。
模板
  因为QQ小游戏的雷比较少,所以不会出现5以上的数字,没有挖开的方块和任何一个模板相减都不会为0,所以不需要为其单独准备一个模板。这样就可以将上面的二值图识别为一个矩阵,方便后续的排雷算法。
在这里插入图片描述

3.排雷

  我使用的排雷方法是总结我多年的扫雷经验得到的(狗头)。总的来说,我在扫雷的时候确定一个方块有雷还是没有雷一共有四种方式:
(1)最直白,也是扫雷的规则:数字周围的方块数等于数字的值,这样就可以确定这些方块就是雷。比如最常见到的1周围有一个方块。
在这里插入图片描述
(2)进一步,属于(1)的拓展:数字周围的方块含有雷的个数等于数字,这样就可以确定其余的方块都不是雷;雷的个数加剩余方块数等于数字,那么剩余方块都是雷。当然确定的雷是依靠上一条得出的。依靠这两个规则可以排除绝大多数的方块,如下图:
在这里插入图片描述
在这里插入图片描述

(3)绕一点,属于(2)的延伸:数字周围的一部分方块一定包含确定数量的雷,若这个数量加确定的雷数等于数字那么剩下的方块都不是雷,如果这个数量加剩余方块数加已确定的雷数等于数字,那么剩余方块都是雷。这和(2)非常相似,只不过变成了一组方块包含的雷。对于一组的理解如下图:因为第二行的数字2,可以确定第三行的两个方块内必定含有一个雷,这就是一组方块。则对于第三行的数字2而言,这个数量加确定的雷数等于数字 1+1=2所以第四行的方块(剩余的方块)都不是雷,可以挖开。这样就可以不用确定这一组方块中雷的具体位置就可以排雷。
在这里插入图片描述
(4)再绕一点,属于(3)的延伸:数字周围的一部分方块只能包含一定数量的雷(不确定是否包含),如果这个数量+已确定的雷数+剩余的方块数等于数字,那么剩余的方块都是雷。单独使用这个方法只可以用来确定雷,不能用来排除雷,因为不确定是否含有雷。如下图,因为数字2,可以确定其下面的三个方块包含一个雷。对于数字3而言,其下面的前两个方块就是属于只能包含一个雷的一组方块,那么就可以确定剩余的方块是雷(椭圆)。
在这里插入图片描述
  组合使用上述4种方法基本上可以排除所有能排除的方块,只留下需要猜测的部分,基本上可以拿下高级扫雷(doge)。当然,这只是我自己的总结,如果还有更全面的方法欢迎大神在评论区指出。
  花费一些心思把这四种方法实现为代码,(1)(2)的实现比较容易,(3)我采用数组和子集的方式多次遍历矩阵实现。对于QQ扫雷使用前3种方式基本上就可以扫出所有雷,所以方法(4)就没有实现(并不是偷懒)。

三、效果测试

  参照上面的原理,用MATLAB使用大量的if和else写了大概200行就达成了自动扫雷的成就。
  首先手动点击,点开一块区域后再运行程序。因为是截屏,处理完之后再操纵鼠标点击,所以当出现大片空白的之后鼠标还是会去点击,看起来就很奇怪。但是速度绝对杠杠的,控制时长在30s左右基本可以无敌手,当然可以更快,但是那样就不像人操作的了。
在这里插入图片描述
  最后,写这个是为了体会用知识解决问题的喜悦,可不是用来作弊开挂的,所以我并没有继续写GUI和完善使用。想进一步研究和改进的同仁可以点击这里下载所有文件。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值