python实战教程之自动扫雷


Posted in Python onJuly 13, 2018

前言

自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式。

一、准备工作

1.扫雷游戏

我是win10,没有默认的扫雷,所以去扫雷网下载

http://www.saolei.net/BBS/

python实战教程之自动扫雷

2.python 3

我的版本是 python 3.6.1

3.python的第三方库

win32api,win32gui,win32con,Pillow,numpy,opencv

可通过 pip install --upgrade SomePackage 来进行安装

注意:有的版本是下载pywin32,但是有的要把pywin32升级到最高并自动下载了pypiwin32,具体情况每个python版本可能都略有不同

我给出我的第三方库和版本仅供参考

python实战教程之自动扫雷 

二、关键代码组成

1.找到游戏窗口与坐标

#扫雷游戏窗口
class_name = "TMain"
title_name = "Minesweeper Arbiter "
hwnd = win32gui.FindWindow(class_name, title_name)

#窗口坐标
left = 0
top = 0
right = 0
bottom = 0

if hwnd:
 print("找到窗口")
 left, top, right, bottom = win32gui.GetWindowRect(hwnd)
 #win32gui.SetForegroundWindow(hwnd)
 print("窗口坐标:")
 print(str(left)+' '+str(right)+' '+str(top)+' '+str(bottom))
else:
 print("未找到窗口")

2.锁定并抓取雷区图像

#锁定雷区坐标#去除周围功能按钮以及多余的界面#具体的像素值是通过QQ的截图来判断的
left += 15
top += 101
right -= 15
bottom -= 42

#抓取雷区图像
rect = (left, top, right, bottom)
img = ImageGrab.grab().crop(rect)

3.各图像的RGBA值

#数字1-8 周围雷数
#0 未被打开
#ed 被打开 空白
#hongqi 红旗
#boom 普通雷#boom_red 踩中的雷
rgba_ed = [(225, (192, 192, 192)), (31, (128, 128, 128))]
rgba_hongqi = [(54, (255, 255, 255)), (17, (255, 0, 0)), (109, (192, 192, 192)), (54, (128, 128, 128)), (22, (0, 0, 0))]
rgba_0 = [(54, (255, 255, 255)), (148, (192, 192, 192)), (54, (128, 128, 128))]
rgba_1 = [(185, (192, 192, 192)), (31, (128, 128, 128)), (40, (0, 0, 255))]
rgba_2 = [(160, (192, 192, 192)), (31, (128, 128, 128)), (65, (0, 128, 0))]
rgba_3 = [(62, (255, 0, 0)), (163, (192, 192, 192)), (31, (128, 128, 128))]
rgba_4 = [(169, (192, 192, 192)), (31, (128, 128, 128)), (56, (0, 0, 128))]
rgba_5 = [(70, (128, 0, 0)), (155, (192, 192, 192)), (31, (128, 128, 128))]
rgba_6 = [(153, (192, 192, 192)), (31, (128, 128, 128)), (72, (0, 128, 128))]
rgba_8 = [(149, (192, 192, 192)), (107, (128, 128, 128))]
rgba_boom = [(4, (255, 255, 255)), (144, (192, 192, 192)), (31, (128, 128, 128)), (77, (0, 0, 0))]
rgba_boom_red = [(4, (255, 255, 255)), (144, (255, 0, 0)), (31, (128, 128, 128)), (77, (0, 0, 0))]

4.扫描雷区图像保存至一个二维数组map

#扫描雷区图像
def showmap():
 img = ImageGrab.grab().crop(rect)
 for y in range(blocks_y):
 for x in range(blocks_x):
  this_image = img.crop((x * block_width, y * block_height, (x + 1) * block_width, (y + 1) * block_height))
  if this_image.getcolors() == rgba_0:
  map[y][x] = 0
  elif this_image.getcolors() == rgba_1:
  map[y][x] = 1
  elif this_image.getcolors() == rgba_2:
  map[y][x] = 2
  elif this_image.getcolors() == rgba_3:
  map[y][x] = 3
  elif this_image.getcolors() == rgba_4:
  map[y][x] = 4
  elif this_image.getcolors() == rgba_5:
  map[y][x] = 5
  elif this_image.getcolors() == rgba_6:
  map[y][x] = 6
  elif this_image.getcolors() == rgba_8:
  map[y][x] = 8
  elif this_image.getcolors() == rgba_ed:
  map[y][x] = -1
  elif this_image.getcolors() == rgba_hongqi:
  map[y][x] = -4
  elif this_image.getcolors() == rgba_boom or this_image.getcolors() == rgba_boom_red:
  global gameover
  gameover = 1
  break
  #sys.exit(0)
  else:
  print("无法识别图像")
  print("坐标")
  print((y,x))
  print("颜色")
  print(this_image.getcolors())
  sys.exit(0)
 #print(map)

5.扫雷算法

这里我采用的最基础的算法

1.首先点出一个点

2.扫描所有数字,如果周围空白+插旗==数字,则空白均有雷,右键点击空白插旗

3.扫描所有数字,如果周围插旗==数字,则空白均没有雷,左键点击空白

4.循环2、3,如果没有符合条件的,则随机点击一个白块

#插旗
def banner():
 showmap()
 for y in range(blocks_y):
 for x in range(blocks_x):
  if 1 <= map[y][x] and map[y][x] <= 5:
  boom_number = map[y][x]
  block_white = 0
  block_qi = 0
  for yy in range(y-1,y+2):
   for xx in range(x-1,x+2):
   if 0 <= yy and 0 <= xx and yy < blocks_y and xx < blocks_x:
    if not (yy == y and xx == x):if map[yy][xx] == 0:
     block_white += 1
    elif map[yy][xx] == -4:
     block_qi += 1if boom_number == block_white + block_qi:for yy in range(y - 1, y + 2):
   for xx in range(x - 1, x + 2):
    if 0 <= yy and 0 <= xx and yy < blocks_y and xx < blocks_x:
    if not (yy == y and xx == x):
     if map[yy][xx] == 0:
     win32api.SetCursorPos([left+xx*block_width, top+yy*block_height])
     win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTDOWN, 0, 0, 0, 0)
     win32api.mouse_event(win32con.MOUSEEVENTF_RIGHTUP, 0, 0, 0, 0)
     showmap()

#点击白块
def dig():
 showmap()
 iscluck = 0
 for y in range(blocks_y):
 for x in range(blocks_x):
  if 1 <= map[y][x] and map[y][x] <= 5:
  boom_number = map[y][x]
  block_white = 0
  block_qi = 0
  for yy in range(y - 1, y + 2):
   for xx in range(x - 1, x + 2):
   if 0 <= yy and 0 <= xx and yy < blocks_y and xx < blocks_x:
    if not (yy == y and xx == x):
    if map[yy][xx] == 0:
     block_white += 1
    elif map[yy][xx] == -4:
     block_qi += 1if boom_number == block_qi and block_white > 0:for yy in range(y - 1, y + 2):
   for xx in range(x - 1, x + 2):
    if 0 <= yy and 0 <= xx and yy < blocks_y and xx < blocks_x:
    if not(yy == y and xx == x):
     if map[yy][xx] == 0:
     win32api.SetCursorPos([left + xx * block_width, top + yy * block_height])
     win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
     win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
     iscluck = 1
 if iscluck == 0:
 luck()

#随机点击
def luck():
 fl = 1
 while(fl):
 random_x = random.randint(0, blocks_x - 1)
 random_y = random.randint(0, blocks_y - 1)
 if(map[random_y][random_x] == 0):
  win32api.SetCursorPos([left + random_x * block_width, top + random_y * block_height])
  win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)
  win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)
  fl = 0

def gogo(): win32api.SetCursorPos([left, top]) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0) win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0) showmap() global gameover while(1): if(gameover == 0):  banner()  banner()  dig() else:  gameover = 0  win32api.keybd_event(113, 0, 0, 0)  win32api.SetCursorPos([left, top])  win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, 0, 0, 0, 0)  win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, 0, 0, 0, 0)  showmap()

这个算法在初级和中级通过率都不错,但是在高级成功率惨不忍睹,主要是没有考虑逻辑组合以及白块是雷的概率问题,可以对这两个点进行改进,提高成功率

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
python实现监控windows服务并自动启动服务示例
Apr 17 Python
Python程序设计入门(5)类的使用简介
Jun 16 Python
Python兔子毒药问题实例分析
Mar 05 Python
Python实现将doc转化pdf格式文档的方法
Jan 19 Python
Python cookbook(字符串与文本)针对任意多的分隔符拆分字符串操作示例
Apr 19 Python
PyTorch 1.0 正式版已经发布了
Dec 13 Python
python for 循环获取index索引的方法
Feb 01 Python
浅析pandas 数据结构中的DataFrame
Oct 12 Python
python库skimage给灰度图像染色的方法示例
Apr 27 Python
golang/python实现归并排序实例代码
Aug 30 Python
Selenium结合BeautifulSoup4编写简单的python爬虫
Nov 06 Python
Pytorch如何切换 cpu和gpu的使用详解
Mar 01 Python
详解Python3.6的py文件打包生成exe
Jul 13 #Python
python2 与 python3 实现共存的方法
Jul 12 #Python
Python3单行定义多个变量或赋值方法
Jul 12 #Python
Python读取数据集并消除数据中的空行方法
Jul 12 #Python
Python实现曲线拟合操作示例【基于numpy,scipy,matplotlib库】
Jul 12 #Python
python跳过第一行快速读取文件内容的实例
Jul 12 #Python
python 读取文本文件的行数据,文件.splitlines()的方法
Jul 12 #Python
You might like
使用PHP和XSL stylesheets转换XML文档
2006/10/09 PHP
浅析PHP 按位与或 (^ 、&amp;)
2013/06/21 PHP
PHP和javascript常用正则表达式及用法实例
2014/07/01 PHP
Win2003+apache+PHP+SqlServer2008 配置生产环境
2014/07/29 PHP
PHP与SQL语句写一句话木马总结
2019/10/11 PHP
JS 遮照层实现代码
2010/03/31 Javascript
js 字符串转换成数字的三种方法
2013/03/23 Javascript
解决javascript:window.close()在chrome,Firefox下失效的问题
2013/05/07 Javascript
js调试系列 初识控制台
2014/06/18 Javascript
jquery中show()、hide()和toggle()用法实例
2015/01/15 Javascript
JQuery实现DIV其他动画效果的简单实例
2016/09/18 Javascript
js实现贪吃蛇小游戏(容易理解)
2017/01/22 Javascript
微信小程序之绑定点击事件实例详解
2017/07/07 Javascript
基于vue.js中事件修饰符.self的用法(详解)
2018/02/23 Javascript
angularjs获取到My97DatePicker选中的值方法
2018/10/02 Javascript
Nuxt升级2.0.0时出现的问题(小结)
2018/10/08 Javascript
javaScript 实现重复输出给定的字符串的常用方法小结
2020/02/20 Javascript
Vue使用预渲染代替SSR的方法
2020/07/02 Javascript
vue+elementUI动态增加表单项并添加验证的代码详解
2020/12/17 Vue.js
python基础教程之字典操作详解
2014/03/25 Python
听歌识曲--用python实现一个音乐检索器的功能
2016/11/15 Python
itchat和matplotlib的结合使用爬取微信信息的实例
2017/08/25 Python
朴素贝叶斯分类算法原理与Python实现与使用方法案例
2018/06/26 Python
python生成随机红包的实例写法
2019/09/02 Python
在django中自定义字段Field详解
2019/12/03 Python
python 实现查询Neo4j多节点的多层关系
2019/12/23 Python
Pytest参数化parametrize使用代码实例
2020/02/22 Python
Python迭代器Iterable判断方法解析
2020/03/16 Python
Python基于爬虫实现全网搜索并下载音乐
2021/02/14 Python
HTML5 文件域+FileReader 分段读取文件并上传到服务器
2017/10/23 HTML / CSS
汽车检测与维修个人求职信
2013/09/24 职场文书
小学生开学感言
2014/02/28 职场文书
优质服务活动实施方案
2014/05/02 职场文书
缅怀先烈演讲稿
2014/09/03 职场文书
研究生简历自我评价范文
2014/09/13 职场文书
初中美术教学反思
2016/02/17 职场文书