利用Python实现自动扫雷小脚本 扫雷脚本代码
bigegpt 2024-10-12 05:02 60 浏览
自动扫雷一般分为两种,一种是读取内存数据,而另一种是通过分析图片获得数据,并通过模拟鼠标操作,这里我用的是第二种方式。
代码已上传至GitHub:
https://github.com/chestnut-egg/GoMine
作者:chestnut_egg
源自:
https://www.cnblogs.com/chestnut-egg/p/9302238.html
入门Python其实很容易,但是我们要去坚持学习,每一天坚持很困难,我相信很多人学了一个星期就放弃了,为什么呢?其实没有好的学习资料给你去学习,你们是很难坚持的,这是小编收集的Python入门学习资料关注,转发,私信小编“01”,即可免费领取!希望对你们有帮助
一、准备工作
1.扫雷游戏
我是win10,没有默认的扫雷,所以去扫雷网下载
http://www.saolei.net/BBS/
2.python 3
我的版本是 python 3.6.1
3.python的第三方库
win32api,win32gui,win32con,Pillow,numpy,opencv
可通过 pip install --upgrade SomePackage 来进行安装
注意:有的版本是下载pywin32,但是有的要把pywin32升级到最高并自动下载了pypiwin32,具体情况每个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()
相关推荐
- 或者这些Joplin插件也可以帮助你的笔记应用再一次强大
-
写在前面距离上次分享《搭建私有全平台多端同步笔记,群晖NAS自建JoplinServer服务》已过去一段时间,大家是否开始使用起来了呢?如果你和我一样已经使用过Joplin有一段时间了,那或许你也会...
- Three.JS教程4 threejs中的辅助类
-
一、辅助类简介Three.js提供了一些辅助类(Helpers)以帮助我们更容易地调试、可视化场景中的元素。ArrowHelepr:创建箭头辅助器;AxisHelper:创建坐标轴辅助器;BoxH...
- 第2章 还记得点、线、面吗(二)(第二章还能敲钟吗)
-
glbgltf模型(webvrmodel)-gltf模型下载定制,glb模型下载定制,三维项目电商网站在线三维展示,usdz格式,vr模型网,网页VR模型下载,三维模型下载,webgl网页模型下载我...
- 如何检查Linux系统硬件信息?从CPU到显卡,一网打尽!
-
你可能会问:“我为什么要关心硬件信息?”答案很简单:硬件是Linux系统的根基,了解它可以帮你解决很多实际问题。比如:性能调优:知道CPU核心数和内存大小,才能更好地调整程序运行参数。故障排查:系统卡...
- SpriteJS:图形库造轮子的那些事儿
-
从2017年到2020年,我花了大约4年的时间,从零到一,实现了一个可切换WebGL和Canvas2D渲染的,跨平台支持浏览器、SSR、小程序,基于DOM结构和支持响应式的,高...
- 平时积累的FPGA知识点(6)(fpga经典应用100例)
-
平时在FPGA群聊等积累的FPGA知识点,第六期:1万兆网接口,发三十万包,会出现掉几包的情况,为什么?原因:没做时钟约束,万兆网接口的实现,本质上都是高速serdes,用IP的话,IP会自带约束。...
- 芯片逻辑调度框架设计 都需要那些那些软件工具
-
设计芯片逻辑调度框架通常需要使用以下软件工具:1.逻辑设计工具:例如Vivado、Quartus、SynopsysDesignCompiler等,用于设计和实现逻辑电路。2.仿真工具:例如Mo...
- ZYNQ与DSP之间EMIF16通信(正点原子领航者zynq之fpga开发指南v3)
-
本文主要介绍说明XQ6657Z35-EVM高速数据处理评估板ZYNQ与DSP之间EMIF16通信的功能、使用步骤以及各个例程的运行效果。[基于TIKeyStone架构C6000系列TMS320C6...
- 好课推荐:从零开始大战FPGA(从零开始的冒险4399)
-
从零开始大战FPGA引子:本课程为“从零开始大战FPGA”系列课程的基础篇。课程通俗易懂、逻辑性强、示例丰富,课程中尤其强调在设计过程中对“时序”和“逻辑”的把控,以及硬件描述语言与硬件电路相对应的“...
- 业界第一个真正意义上开源100 Gbps NIC Corundum介绍
-
来源:内容由「网络交换FPGA」编译自「FCCM2020」,谢谢。FCCM2020在5月4日开始线上举行,对外免费。我们有幸聆听了其中一个有关100G开源NIC的介绍,我们对该文章进行了翻译,并对其中...
- 高层次综合:解锁FPGA广阔应用的最后一块拼图
-
我们为什么需要高层次综合高层次综合(High-levelSynthesis)简称HLS,指的是将高层次语言描述的逻辑结构,自动转换成低抽象级语言描述的电路模型的过程。所谓的高层次语言,包括C、C++...
- Xilinx文档编号及其内容索引(部分)
-
Xilinx文档的数量非常多。即使全职从事FPGA相关工作,没有几年时间不可能对器件特性、应用、注意事项等等有较为全面的了解。本文记录了我自使用Xilinx系列FPGA以来或精读、或翻阅、或查询过的文...
- Xilinx Vivado联合Modelsim软件仿真
-
引言:Xilinx公司Vivado开发软件自带仿真工具,可以实现一般性能的FPGA软件仿真测试,其测试执行效率以及性能都不如第三方专用仿真软件Modelsim强。本文我们介绍下如何进行Vivado20...
- 体育动画直播是怎么做出来的?从数据到虚拟赛场的科技魔法!
-
你是否见过这样的比赛直播?没有真实球员,却能看梅西带球突破?足球比赛变成动画版,但数据100%真实?电竞比赛用虚拟形象直播,选手操作实时同步?这就是体育动画直播——一种融合实时数据、游戏引擎和AI的...
- Dialogue between CPC and political parties of neighboring countries held in Beijing
-
BEIJING,May26(Xinhua)--TheCommunistPartyofChina(CPC)inDialoguewithPoliticalPartiesof...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- mysql授权 (74)
- 下载测试 (70)
- linuxlink (65)
- pythonwget (67)
- androidinclude (65)
- libcrypto.so (74)
- logstashinput (65)
- hadoop端口 (65)
- vue阻止冒泡 (67)
- jquery跨域 (68)
- php写入文件 (73)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)