欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > PPT文档下载  

    综合应用-自动扫雷器.ppt

    • 资源ID:5812042       资源大小:1.20MB        全文页数:77页
    • 资源格式: PPT        下载积分:15金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要15金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    综合应用-自动扫雷器.ppt

    第5讲 综合应用自动扫雷器,知识点,一、Windows扫雷游戏程序二、两个参考程序三、自动扫雷器的原理四、程序界面采用的技术和方法4.1 获取并显示操作系统的版本号4.2 启动扫雷游戏4.3 并排居中显示两个窗口、计算扫雷游戏地图行数和列数4.4 开启新局五、决策前的准备5.1 扫描地图5.2 方格16种状态的表示5.3 获取每个方格第8行16个像素的颜色并与预存的16种状态比对六、决策6.1 普通决策6.2 高级决策,一、Windows扫雷游戏程序,鼠标左右键的作用:鼠标左键单击:点开某个位置;鼠标右键单击:将某个位置标记为地雷;鼠标左右键同时单击:见下一页。在自动扫雷程序中,需要人为地向扫雷程序发送这些鼠标消息,达到自动标记地雷或点开位置的功能。,鼠标左右键同时单击:如果单击的位置周围8个相邻位置中已标记为地雷的个数=该位置显示的数字,则将其他未点开的位置全部点开(如果标记的位置是正确的,则其他位置中不可能有地雷)。思考:鼠标左右键同时单击下图中标注的位置,会有什么效果?,思考,人在玩扫雷游戏时,会采用哪些推理规则。,期末作品参考,模仿Windows扫雷游戏,用VC/MFC设计一个扫雷游戏,其界面和功能可参考Windows扫雷游戏。,二、两个参考程序,软件名称:自动扫雷器:作者:任全。开发工具:VC/MFC。特点:需要人工点开,当算法不能继续时,需要人工介入。说明:该程序为本课件的参考程序,本课件做了简化、并补充了大量的注释。,软件名称:自动扫雷。作者:葛永。开发工具:未知。特点:以猜测替代人工操作。功能更全面,提供了多个选项的设置,甚至可以自定义推理规则。,三、自动扫雷器的原理,启动扫雷游戏后,当用户点击“扫雷”按钮时,扫描扫雷游戏地图,通过提取每个方格(1616)中间第8行16个像素的颜色,跟预存的16种状态的颜色进行比对,从而判断每个方格的状态。,根据每个方格状态的信息进行决策(包括普通决策和高级决策),从而点开某个(或某些)位置,或者将某个(或某些)位置标记为地雷。某次决策后:如果判定出现了踩到地雷的状态,则提示“扫雷失败”。如果所有地雷位置都正确标记出来、其他位置都点开了,则提示“扫雷成功”。如果某次决策无法点开位置或标记地雷,则提示“算法不能继续了”,请求用户手动点开一些位置。,决策例子:请试着根据下图所显示的各方格的状态判断哪些位置可以标记为地雷,哪些位置可以点开。,补充:Windows画图应用程序妙用,将一个bmp位图文件用画图软件打开,然后放大8倍,可以清晰地观察到每个像素。可以显示网格,可以显示缩略图。在状态栏中可以显示当前鼠标光标的位置,所选矩形区域的大小等。,画图程序在分析自动扫雷器代码中的作用:扫雷游戏程序和自动扫雷器窗口大小分别是多少个像素,标题栏和菜单栏高度是多少个像素,边框高度或宽度是多少个像素,等等。每个方格1616区域具体包含了哪些像素。提取每个方格第8行16个像素的颜色,第8行具体是哪一行。等等。,补充:其他工具软件的应用,01 取屏幕上任一点的RGB颜色值(绿色):色值传递员(plsread)。02 中英文颜色RGB代码对照表(绿色)。03 YUV、RGB转换并带颜色显示(绿色)。04 RGB颜色分析器V40(绿色)。以上软件均已上传到网络课堂(或服务器)中。,补充:像素,位图文件是由像素组成。行和列上的像素序号从0开始计起。在Windows绘图应用程序中打开一幅位图文件(*.bmp),然后放大8倍,并显示网格,可以清晰地观察到位图的每个像素。显示器屏幕分辨率为1280800,则意味着水平方向上为1280个像素,竖直方向上为800个像素。许多GDI绘图函数的绘图单位也是像素。,补充:坐标系,屏幕坐标系:坐标系原点在屏幕左上角。客户区坐标系:坐标系原点在客户区左上角。坐标系转换函数:API函数:ClientToScreen。,x,x,y,y,扫雷游戏窗口中某一个点的客户区坐标为(20,20),其屏幕坐标可能为(277,282)。,补充:屏幕坐标和区域,屏幕坐标:CPoint类(MFC中的类)表示屏幕上一个点的坐标。与Windows中的结构体POINT(即API中的结构体)类似,增加了很多成员函数。区域:CRect(MFC中的类)表示屏幕上一个矩形区域。与Windows中的结构体RECT(即API中的结构体)类似,增加了很多成员函数。,typedef struct tagPOINTLONG x;LONG y;POINT;,typedef struct tagRECTLONG left;LONG top;LONG right;LONG bottom;RECT;,补充:MFC/SDK的数据类型与C/C+的数据类型,MFC,Microsoft Foundation Class Library。SDK,Windows Software Development Kit。在SDK应用程序中,采用API函数来实现程序功能。所以SDK应用程序也就是基于API函数的应用程序。在MFC/SDK中定义了很多数据类型,为了跟其他计算机语言中的数据类型相区别,特意采用大写字母。BOOL、BSTR、BYTE、COLORREF、DWORD、LONG、LPARAM、LPCSTR、LPSTR、LPCTSTR、LPTSTR、LPVOID、LRESULT、UINT、WNDPROC、WORD、WPARAM、POSITION、LPCRECT等等。每种数据类型的含义及所占字节数请查阅MSDN。在MFC/SDK中仍然支持C/C+的数据类型。,补充:颜色在计算机中的表示,在计算机中,颜色是用R(红)、G(绿)、B(蓝)3个分量来表示的,每个分量取值为0255,可以用一个字节来存储。因此,RGB一共可以表示255255255种颜色。在Windows操作系统中,使用COLORREF数据类型来表示RGB颜色。COLORREF占4个字节、32位,用16进制来表示是0 x00bbggrr,即最高字节不用,次高字节表示B分量、次低字节表示G分量,最低字节表示R分量。在有的时候(比如在调试状态下),COLORREF是以十进制形式显示的,比如白色(0 x00FFFFFF)的值为16777215。API函数GetPixel可以获得屏幕上指定位置的颜色值,返回的是COLORREF类型的值。,常用颜色列表:RGB值COLORREF颜色中文名称RGB(0,0,0)0 x00000000黑色RGB(128,0,0)0 x00000080栗色RGB(0,128,0)0 x00008000深绿色RGB(128,128,0)0 x00008080橄榄色RGB(0,0,128)0 x00800000海军蓝色RGB(128,0,128)0 x00800080紫色RGB(0,128,128)0 x00808000水鸭色RGB(128,128,128)0 x00808080灰色RGB(192,192,192)0 x00C0C0C0银白色RGB(255,0,0)0 x000000FF红色RGB(0,255,0)0 x0000FF00绿色RGB(255,255,0)0 x0000FFFF黄色RGB(0,0,255)0 x00FF0000蓝色RGB(255,0,255)0 x00FF00FF洋红色RGB(0,255,255)0 x00FFFF00青色RGB(255,255,255)0 x00FFFFFF白色注意,在COLORREF数据中,是按BGR的顺序从高位到低位存放的。这16种颜色也是扫雷程序各方格中可能出现的16种颜色。,四、程序界面采用的技术和方法,自动扫雷器界面:基于对话框的应用程序。界面很简单。,CMineCrackDlg类自定义数据成员和函数成员含义及功能。数据成员:,BOOL m_bWin98;/操作系统是否为Win98、Win2003的标志变量CStringwinMineClassName;/扫雷游戏程序窗口类名HWND hWinMineWnd;/扫雷游戏窗口句柄CRect rectWinMine;/扫雷游戏窗口区域CRect rectMe;/本程序窗口区域BOOL m_bStart;/扫雷游戏是否启动的标志int m_nWidth;/扫雷游戏水平方向上方格的数目(即列数),高级是16行30列int m_nHeight;/扫雷游戏竖直方向上方格的数目(即行数)int m_nMineNum;/地雷的个数int m_nMineCurNum;/当前已标记出的地雷数目/申请m_nWidthm_nHeight大小的存储空间/每个元素代表一个位置,取值为0FF,分别代表一种状态BYTE*m_map;BYTE m_ColorSample168;/预先存储的扫雷游戏方格16种状态的颜色,4.0 数据成员和函数成员说明,数据成员m_bWin98说明:Win98、Win2003和Win2000、WinXP中的扫雷应用窗口有一些细微差别:Win98、Win2003中的扫雷程序窗口宽度多4个像素、高度多4个像素。在通过窗口大小来计算扫雷游戏的行数和列数时要区分Win98、Win2003系统和其他系统。,BOOL m_bWin98;CStringwinMineClassName;HWND hWinMineWnd;CRect rectWinMine;CRect rectMe;BOOL m_bStart;int m_nWidth;int m_nHeight;int m_nMineNum;int m_nMineCurNum;BYTE*m_map;BYTE m_ColorSample168;,数据成员m_nWidth、m_nHeight说明:m_nWidth:扫雷游戏水平方向上有多少个方格。m_nHeight:扫雷游戏竖直方向上有多少个方格。数数高级模式水平和竖直方向上分别有多少个方格。,BOOL m_bWin98;CStringwinMineClassName;HWND hWinMineWnd;CRect rectWinMine;CRect rectMe;BOOL m_bStart;int m_nWidth;int m_nHeight;int m_nMineNum;int m_nMineCurNum;BYTE*m_map;BYTE m_ColorSample168;,BOOL m_bWin98;CStringwinMineClassName;HWND hWinMineWnd;CRect rectWinMine;CRect rectMe;BOOL m_bStart;int m_nWidth;int m_nHeight;int m_nMineNum;int m_nMineCurNum;BYTE*m_map;BYTE m_ColorSample168;,数据成员m_map数组说明:在启动(含重新开具)扫雷游戏时,申请一维数组存储空间,并用m_map指向这段存储空间。一维数组存储空间当作二维数组存储空间使用。m_map数组元素取值含义:,#define UNKNOW0 x00/未知#define NOMINE0 xFF/确定没有地雷#define ISMINE0 x0F/确定为地雷#define NEIGHBOR_10 x01/数字1/即该位置没有地雷,但周围8个方向上有1颗地雷(以下同)#define NEIGHBOR_20 x02/数字2#define NEIGHBOR_30 x03/数字3#define NEIGHBOR_40 x04/数字4#define NEIGHBOR_50 x05/数字5#define NEIGHBOR_60 x06/数字6#define NEIGHBOR_70 x07/数字7#define NEIGHBOR_80 x08/数字8,m_map=new BYTE m_nWidth*m_nHeight;ZeroMemory(m_map,m_nWidth*m_nHeight);/系统函数,清零内存空间,BOOL m_bWin98;CStringwinMineClassName;HWND hWinMineWnd;CRect rectWinMine;CRect rectMe;BOOL m_bStart;int m_nWidth;int m_nHeight;int m_nMineNum;int m_nMineCurNum;BYTE*m_map;BYTE m_ColorSample168;,数据成员m_ColorSample数组说明:数组大小是168,数据类型是BYTE(字节);预存16种状态中间第8行16个像素的“颜色”。不是真正意义上的颜色,而是将每种颜色转换成16种自定义颜色的编号,并取编号的低4位二进制位,且将两个颜色编号压缩成1个字节。所以存储16个像素的“颜色”只需8个字节即可。,m_ColorSample 1 0=0 x78;/NEIGHBOR_1m_ColorSample 1 1=0 x88;m_ColorSample 1 2=0 x88;m_ColorSample 1 3=0 x8c;m_ColorSample 1 4=0 xcc;m_ColorSample 1 5=0 x88;m_ColorSample 1 6=0 x88;m_ColorSample 1 7=0 x88;,/自定义函数:RGB颜色到16种颜色编号的转换BYTE CMineCrackDlg:Color256To16(COLORREF colorref)BYTE ret;switch(colorref)case RGB(0,0,0):ret=0 x00;break;/黑色-0case RGB(128,0,0):ret=0 x01;break;/栗色-1case RGB(0,128,0):ret=0 x02;break;/深绿色-2case RGB(128,128,0):ret=0 x03;break;/橄榄色-3case RGB(0,0,128):ret=0 x04;break;/海军蓝色-4case RGB(128,0,128):ret=0 x05;break;/紫色-5case RGB(0,128,128):ret=0 x06;break;/水鸭色-6case RGB(128,128,128):ret=0 x07;break;/灰色-7case RGB(192,192,192):ret=0 x08;break;/银白色-8case RGB(255,0,0):ret=0 x09;break;/红色-9case RGB(0,255,0):ret=0 x0A;break;/绿色-10case RGB(255,255,0):ret=0 x0B;break;/黄色-11case RGB(0,0,255):ret=0 x0C;break;/蓝色-12case RGB(255,0,255):ret=0 x0D;break;/洋红色-13case RGB(0,255,255):ret=0 x0E;break;/青色-14case RGB(255,255,255):ret=0 x0F;break;/白色-15return ret;,颜色的压缩(以NEIGHBOR_1这种状态为例解释),m_ColorSample 1 0=0 x78;/NEIGHBOR_1m_ColorSample 1 1=0 x88;m_ColorSample 1 2=0 x88;m_ColorSample 1 3=0 x8c;m_ColorSample 1 4=0 xcc;m_ColorSample 1 5=0 x88;m_ColorSample 1 6=0 x88;m_ColorSample 1 7=0 x88;,RGB(0,0,0)0RGB(128,0,0)1RGB(0,128,0)2RGB(128,128,0)3RGB(0,0,128)4RGB(128,0,128)5RGB(0,128,128)6RGB(128,128,128)7RGB(192,192,192)8RGB(255,0,0)9RGB(0,255,0)ARGB(255,255,0)BRGB(0,0,255)CRGB(255,0,255)DRGB(0,255,255)ERGB(255,255,255)F,函数成员:,void StartGame();/启动扫雷游戏BOOL ScanTheMap();/扫雷游戏地图,标记每个位置的状态BOOL ScanTheMap98();/Win98、Win2003系统下扫描游戏地图(没有实现)/在m_ColorSample中查找与位置pt(开始的16个像素)颜色匹配的状态int GetColorSample(CPoint pt);BYTE Color256To16(COLORREF colorref);/RGB颜色到16种颜色编号的转换BOOL MakeDecision(BOOL*,BOOL*);/普通决策,返回:1,成功;0:继续BOOL AdvanceDecision(BOOL*,BOOL*);/高级决策/统计(i,j)位置周围8个位置上已标记为地雷的位置个数/并将8个相邻位置中未标记为地雷的位置放入数组ptrarr中void LookAroundDot(int,int,void*,int*);/从位置数组ptrarr中查找位置pt,找到返回其下标,找不到则返回-1int LookUpFromArray(const void*,CPoint);,系统流程图:消息和事件驱动机制。,4.1 获取并显示操作系统的版本号OnInitDialog()函数,API函数GetVersion用于获取操作系统的版本。GetVersion函数的用法及例子请参考MSDN。将操作系统版本信息显示在对话框的静态文本控件中。,如果想实现某个功能,但不知道该调用哪个API函数或MFC中的函数,该怎么办?,通过google等搜索引擎查找网友发布的类似问题、解决方法、例子等。关键字:获取操作系统版本号 函数。通过MSDN查找函数的功能及使用方法。查阅书籍。经验积累。,4.2 启动扫雷游戏StartGame()函数,通过API函数FindWindow来检测是否存在窗口类名为“扫雷”(或“Minesweeper”)的窗口。如果扫雷游戏未启动,则:获得系统路径;获得扫雷程序的完整路径;通过API函数CreateProcess来启动扫雷游戏。,程序界面采用的其他技术:判断窗口是否是最小化状态,如果是,则正常显示。(如果扫雷游戏窗口被其他窗口遮住了,则)将扫雷游戏窗口调到最前面来。激活扫雷游戏窗口,使之为当前活动窗口。,4.3 并排居中显示两个窗口 StartGame()函数 计算扫雷游戏地图行数和列数,效果:,屏幕及程序界面尺寸参数:屏幕大小为:1280800(取决于系统设置)。扫雷游戏窗口大小为:506371。扫雷游戏边框宽度(或高度)为:3个像素。(Win2000和WinXP系统)标题栏和菜单栏高度为:48个像素。每个方格大小为:1616像素。扫雷游戏客户区(去掉标题栏和菜单栏,以及边框)大小为:500320。客户区中,480256大小的区域用来显示30列16行方格(高级扫雷模式);这个区域左边有12个像素宽度的空余区域,右边有8个像素宽度的空余区域,上面56个像素高度的区域用来显示剩余地雷数和时间等信息,下面有8个像素高度的空余区域。,窗口位置、区域大小、参数值等。两个坐标系。,扫雷游戏地图的行数为:m_nHeight=(客户区.bottom-客户区.top-63)/16列数为:m_nWidth=(客户区.right-客户区.left-20)/16,4.4 开启新局 StartGame()函数,在扫雷程序中,可以通过鼠标左键点击“笑脸”按钮、执行“开局”菜单命令、按F2键3种方式来开启新局。本程序通过API函数PostMessage向扫雷程序人为发送键盘按键F2的键盘消息,开启新局。,五、决策前的准备,准备工作:扫描游戏地图,记录每个方格的状态。在后续的决策阶段需要根据这些方格的状态信息进行普通决策和高级决策。,经过扫描后,每个方格在m_map数组中的值为以下11种情形:UNKNOW、NOMINE、ISMINE、NEIGHBOR_1、NEIGHBOR_2、NEIGHBOR_3、NEIGHBOR_4、NEIGHBOR_5、NEIGHBOR_6、NEIGHBOR_7、NEIGHBOR_8。,#define UNKNOW0 x00/未知#define NOMINE0 xFF/确定没有地雷#define ISMINE0 x0F/确定为地雷#define NEIGHBOR_10 x01/数字1/即该位置没有地雷,但周围8个方向上有1颗地雷(以下同)#define NEIGHBOR_20 x02/数字2#define NEIGHBOR_30 x03/数字3#define NEIGHBOR_40 x04/数字4#define NEIGHBOR_50 x05/数字5#define NEIGHBOR_60 x06/数字6#define NEIGHBOR_70 x07/数字7#define NEIGHBOR_80 x08/数字8,在自动扫雷之前,将扫描结果写入到记事本文件中:思考:怎么实现?,5.1 扫描地图,对每行、每列上的每个方格,提取第8行16个像素的颜色,并跟预存的16种状态的颜色进行比对,从而判定每个方格的状态。3个函数:ScanTheMapGetColorSampleColor256To16ScanTheMap函数:,BOOL CMineCrackDlg:ScanTheMap()/扫雷游戏地图,标记每个位置的状态int i,j,ret;CPoint pt;BOOL finish=FALSE;/游戏是否结束(踩到了地雷)的标志for(i=0;im_nHeight;i+)/行for(j=0;jm_nWidth;j+)/列,if(m_map i*m_nWidth+j!=0)continue;pt=CPoint(12+j*BMPWIDTH,55+i*BMPHEIGHT+7);ret=GetColorSample(pt);switch(ret)case 0:m_map i*m_nWidth+j=NOMINE;break;case 1:m_map i*m_nWidth+j=NEIGHBOR_1;break;case 2:m_map i*m_nWidth+j=NEIGHBOR_2;break;case 3:m_map i*m_nWidth+j=NEIGHBOR_3;break;case 4:m_map i*m_nWidth+j=NEIGHBOR_4;break;case 5:m_map i*m_nWidth+j=NEIGHBOR_5;break;case 6:m_map i*m_nWidth+j=NEIGHBOR_6;break;case 7:m_map i*m_nWidth+j=NEIGHBOR_7;break;case 8:m_map i*m_nWidth+j=NEIGHBOR_8;break;case 9:m_map i*m_nWidth+j=NOMINE;break;case 10:finish=TRUE;break;/这3种情况均表示踩到地雷case 11:finish=TRUE;break;case 12:finish=TRUE;break;case 13:m_map i*m_nWidth+j=UNKNOW;break;case 14:m_map i*m_nWidth+j=ISMINE;break;case 15:m_map i*m_nWidth+j=UNKNOW;break;if(finish)return FALSE;else return TRUE;,/在m_ColorSample中查找与位置pt(开始的16个像素)颜色匹配的状态/通过这种方法来辨别pt位置是没有地雷、显示数字18等等情况,详见位图Sign.bmpint CMineCrackDlg:GetColorSample(CPoint pt)BYTE ptrColor8;COLORREF colorref1,colorref2;int i;HDChDC=:GetDC(NULL);memset(ptrColor,0,8);:ClientToScreen(hWinMineWnd,GetColorSample函数,ptrColori=tmp14|tmp2说明:注意:tmp1和tmp2均为BYTE,且取值为0F,即只有低4位有数据、高4位全为0。tmp14:把tmp1左移4位,空出的低4位补0。|tmp2:将前面的结果“与”上tmp2,实际上是把tmp1低4位+tmp2低4位凑成1个字节。,:ReleaseDC(NULL,hDC);/与预存的16种状态比对,从而判断该位置处于什么状态for(i=0;i16;i+)if(m_ColorSamplei0=ptrColor0/没有匹配,为什么要将客户区坐标转换为屏幕坐标?实现获取扫雷游戏窗口某个像素的颜色,有两种方法:获取扫雷游戏窗口设备描述表的句柄hDC,然后通过hDC利用客户区坐标获取扫雷游戏窗口该坐标对应像素的颜色 不需要转换坐标。获取整个屏幕窗口设备描述表的句柄hDC,然后通过hDC获取屏幕上某个坐标对应像素的颜色(如果这个坐标刚好位于扫雷游戏窗口,则实际上就是获得扫雷游戏窗口某个像素的颜色)需要将客户区坐标转换成屏幕坐标,然后通过API函数GetPixel来获取某个像素的颜色。,/自定义函数:RGB颜色到16种颜色编号的转换BYTE CMineCrackDlg:Color256To16(COLORREF colorref)BYTE ret;switch(colorref)case RGB(0,0,0):ret=0 x00;break;/黑色-0case RGB(128,0,0):ret=0 x01;break;/栗色-1case RGB(0,128,0):ret=0 x02;break;/深绿色-2case RGB(128,128,0):ret=0 x03;break;/橄榄色-3case RGB(0,0,128):ret=0 x04;break;/海军蓝色-4case RGB(128,0,128):ret=0 x05;break;/紫色-5case RGB(0,128,128):ret=0 x06;break;/水鸭色-6case RGB(128,128,128):ret=0 x07;break;/灰色-7case RGB(192,192,192):ret=0 x08;break;/银白色-8case RGB(255,0,0):ret=0 x09;break;/红色-9case RGB(0,255,0):ret=0 x0A;break;/绿色-10case RGB(255,255,0):ret=0 x0B;break;/黄色-11case RGB(0,0,255):ret=0 x0C;break;/蓝色-12case RGB(255,0,255):ret=0 x0D;break;/洋红色-13case RGB(0,255,255):ret=0 x0E;break;/青色-14case RGB(255,255,255):ret=0 x0F;break;/白色-15return ret;,Color256To16函数,RGB(0,0,0)0RGB(128,0,0)1RGB(0,128,0)2RGB(128,128,0)3RGB(0,0,128)4RGB(128,0,128)5RGB(0,128,128)6RGB(128,128,128)7RGB(192,192,192)8RGB(255,0,0)9RGB(0,255,0)ARGB(255,255,0)BRGB(0,0,255)CRGB(255,0,255)DRGB(0,255,255)ERGB(255,255,255)F,颜色的编号(以NEIGHBOR_1这种状态为例解释),m_ColorSample 1 0=0 x78;/NEIGHBOR_1m_ColorSample 1 1=0 x88;m_ColorSample 1 2=0 x88;m_ColorSample 1 3=0 x8c;m_ColorSample 1 4=0 xcc;m_ColorSample 1 5=0 x88;m_ColorSample 1 6=0 x88;m_ColorSample 1 7=0 x88;,RGB(0,0,0)0RGB(128,0,0)1RGB(0,128,0)2RGB(128,128,0)3RGB(0,0,128)4RGB(128,0,128)5RGB(0,128,128)6RGB(128,128,128)7RGB(192,192,192)8RGB(255,0,0)9RGB(0,255,0)ARGB(255,255,0)BRGB(0,0,255)CRGB(255,0,255)DRGB(0,255,255)ERGB(255,255,255)F,5.2 扫雷游戏方格16种状态的表示,状态0:被点开了,但没有地雷、且周围8个位置上也没有地雷。在map数组中存储的值为NOMINE(0 xFF)。状态1:数字1,即周围8个位置上有1颗地雷。在map数组中存储的值为NEIGHBOR_1(0 x01)。状态2:数字2,即周围8个位置上有2颗地雷。在map数组中存储的值为NEIGHBOR_1(0 x02)。状态3:数字3,即周围8个位置上有3颗地雷。在map数组中存储的值为NEIGHBOR_1(0 x03)。,状态4:数字1,即周围8个位置上有4颗地雷。在map数组中存储的值为NEIGHBOR_4(0 x04)。状态5:数字2,即周围8个位置上有5颗地雷。在map数组中存储的值为NEIGHBOR_5(0 x05)。状态6:数字3,即周围8个位置上有6颗地雷。在map数组中存储的值为NEIGHBOR_6(0 x06)。,状态7:数字2,即周围8个位置上有7颗地雷。在map数组中存储的值为NEIGHBOR_7(0 x07)。状态8:数字3,即周围8个位置上有8颗地雷。在map数组中存储的值为NEIGHBOR_8(0 x08)。状态9:做了“?”标记,但经过决策后判定该位置上没有地雷,所以将被点开。在自动求解过程中不会出现这种状态。在map数组中存储的值为NOMINE(0 xFF)。,第9种状态说明:如下图所示,“?”左下角位置为(6,12)。将该位置的右边标记为地雷,右上角标记为“?”,这时如果鼠标光标位于(6,12)位置,此时如果鼠标左右键同时按下(未松开),则右上角的“?”显示为第9种状态。如果松开鼠标左右键,则右上角位置将会被点开。,踩到了地雷的3种状态:状态10:踩到地雷时所有未标记为地雷的位置都显示出来。在map数组中不会存储新值(其值为初始值0),但会将状态变量finish的值设置为TRUE,从而结束自动求解。状态11:踩到地雷时,不是地雷但被错误地标记为地雷的位置。其他同上。状态12:踩到地雷的位置。其他同上。,状态13:做了?标记。在map数组中存储的值为UNKNOW(0 x00)。状态14:被标记为地雷。在map数组中存储的值为ISMINE(0 x0F)。状态15:未知,即没有做任何标记。在map数组中存储的值为UNKNOW(0 x00)。,16种状态在m_map数组中对应的值:,/ScanTheMap函数switch(ret)case 0:m_map i*m_nWidth+j=NOMINE;break;case 1:m_map i*m_nWidth+j=NEIGHBOR_1;break;case 2:m_map i*m_nWidth+j=NEIGHBOR_2;break;case 3:m_map i*m_nWidth+j=NEIGHBOR_3;break;case 4:m_map i*m_nWidth+j=NEIGHBOR_4;break;case 5:m_map i*m_nWidth+j=NEIGHBOR_5;break;case 6:m_map i*m_nWidth+j=NEIGHBOR_6;break;case 7:m_map i*m_nWidth+j=NEIGHBOR_7;break;case 8:m_map i*m_nWidth+j=NEIGHBOR_8;break;case 9:m_map i*m_nWidth+j=NOMINE;break;case 10:finish=TRUE;break;/这3种情况均表示踩到地雷case 11:finish=TRUE;break;case 12:finish=TRUE;break;case 13:m_map i*m_nWidth+j=UNKNOW;break;case 14:m_map i*m_nWidth+j=ISMINE;break;case 15:m_map i*m_nWidth+j=UNKNOW;break;,#define UNKNOW0 x00/未知#define NOMINE0 xFF/确定没有地雷#define ISMINE0 x0F/确定为地雷#define NEIGHBOR_10 x01/数字1/即该位置没有地雷,但周围8个方向上有1颗地雷(以下同)#define NEIGHBOR_20 x02/数字2#define NEIGHBOR_30 x03/数字3#define NEIGHBOR_40 x04/数字4#define NEIGHBOR_50 x05/数字5#define NEIGHBOR_60 x06/数字6#define NEIGHBOR_70 x07/数字7#define NEIGHBOR_80 x08/数字8,5.3 获取每个方格第8行16个像素的颜色 并与预存的16种状态比对,获取每个方格(1616)的第8行16个像素的颜色,转换成16种颜色的编号;然后压缩成8个字节(每个位置的颜色用4位二进制表示);最后与预存的16种状态的颜色进行比对,从而判断每个位置处于什么状态。GetColorSample函数。Color256To16函数。,/GetColorSample函数for(i=0;i8;i+)colorref1=:GetPixel(hDC,pt.x+i*2,pt.y);colorref2=:GetPixel(hDC,pt.x+i*2+1,pt.y);BYTE tmp1=Color256To16(colorref1);/转换成16色后只有低4位有效BYTE tmp2=Color256To16(colorref2);ptrColori=tmp14|tmp2;/取colorref1低4位+colorref2低4位凑成1个字节,例如,以下3种状态第8行16个像素的颜色分别为:状态10:78、88、00、ff、00、00、08、88。状态11:78、88、00、99、09、90、08、88。状态12:79、99、00、ff、00、00、09、99。,RGB(0,0,0)0RGB(128,0,0)1RGB(0,128,0)2RGB(128,128,0)3RGB(0,0,128)4RGB(128,0,128)5RGB(0,128,128)6RGB(128,128,128)7RGB(192,192,192)8RGB(255,0,0)9RGB(0,255,0)ARGB(255,255,0)BRGB(0,0,255)CRGB(255,0,255)DRGB(0,255,255)ERGB(255,255,255)F,六、决策,在获取每个方格的状态信息后,需要根据这些信息来做决策:将某些位置标记为地雷或将某些位置点开。如果扫描到某个位置为踩到地雷的状态,则提示“扫雷失败了”。如果判断出所有地雷位置都正确标记了,则提示“扫雷成功”。如果无法决策,则提示“算法不能继续了”。,6.1 普通决策,策略1:如果方格(i,j)周围8个位置中未标记方格数0,且=方格(i,j)本身显示雷数值-

    注意事项

    本文(综合应用-自动扫雷器.ppt)为本站会员(牧羊曲112)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开